I've been playing around with your great library but now i have a little problem.
What I need is a fifo that can simultonious load and unload values..
Maybe a modification of your block where I would have a Write,Unload input wich will if both true first do the load and then the unload..
Have this been done before so I dont have to do it?
Or if I have to do it is this something you would like to have to? If so I could post my soulution in Siemens SCL.. When done..
this sounds like a good idea we will look into this
Here is an untested soulution with some more modification to fit my need for this project..
Maybe this modificaton isnt what you want for your library but for me it is a must have..
1. IF the FIFO is full and i try to LOAD more into it Then I do unload a value and load a new..
2. I can vary the fifo in lenght shure if I only use 20places i would need more memory than I would use but in my case thats no problem..
3. The E flag is just a enable flag
4. RD or WR is not needed to make the pulses from the outside its done in the FB
Havent tested the code yet shall reboot my computer so i could try it in Windows (STEP7)
FUNCTION_BLOCK FIFO_UPTO_32
VAR_INPUT
Din : DWORD;
WR : BOOL;
RD : BOOL;
E : BOOL;
RST : BOOL;
N : INT;
END_VAR
VAR_OUTPUT
Dout : DWORD;
empty : BOOL := TRUE;
full : BOOL;
END_VAR
VAR
fifo : ARRAY[0..32] OF DWORD;
NW : INT;
NR : INT;
RD_Edge : BOOL;
WR_Edge : BOOL;
END_VAR
IF rst THEN
(* asynchronous reset for the fifo *)
NW := NR := 0;
Dout := 0;
empty := TRUE;
full := FALSE;
ELSIF E THEN
IF WR AND NOT full AND NOT WR_Edge THEN
(* write action *)
fifo[NW] := Din;
NW := INC1(NW, N);
full := NW = NR;
empty := FALSE;
WR_Edge := TRUE;
ELSIF WR AND full AND NOT WR_Edge THEN
(* read from stack *)
Dout := fifo[NR];
NR := INC1(NR, N);
empty := NR = NW;
full := FALSE;
(* write action *)
fifo[NW] := Din;
NW := INC1(NW, N);
full := NW = NR;
empty := FALSE;
WR_Edge := TRUE;
ELSIF NOT WR THEN
WR_Edge := FALSE;
END_IF;
IF RD AND NOT empty AND NOT RD_Edge THEN
(* read from stack *)
Dout := fifo[NR];
NR := INC1(NR, N);
empty := NR = NW;
full := FALSE;
RD_Edge := TRUE;
ELSIF NOT RD THEN
RD_Edge := FALSE;
END_IF
END_IF;
END_FUNCTION_BLOCK
Tested the cod but had made some beginners misstake..
But i noticed something strange:
In your original code it looks like this for FIFO_16:
NW := INC1(N:=NW, X:=16);
This doesnt work for me had to switch places so it look like this:
NW := INC1(N:=16, X:=NW);
Ok but here are my code:
VAR_INPUT
Din : DWORD;
WR : BOOL;
RD : BOOL;
E : BOOL;
RST : BOOL;
N : INT;
END_VAR
VAR_OUTPUT
Dout : DWORD;
empty : BOOL := TRUE;
full : BOOL;
END_VAR
VAR
fifo : ARRAY[0..32] OF DWORD;
NW : INT;
NR : INT;
RD_Edge : BOOL;
WR_Edge : BOOL;
END_VAR
BEGIN
IF rst THEN
(* asynchronous reset for the fifo *)
NW := 0;
NR := 0;
Dout := 0;
empty := TRUE;
full := FALSE;
ELSIF E THEN
IF WR AND NOT full AND NOT WR_Edge THEN
(* write action *)
fifo[NW] := Din;
NW := INC1(N:=N, X:=NW);
full := NW = NR;
empty := FALSE;
WR_Edge := TRUE;
ELSIF WR AND full AND NOT WR_Edge THEN
(* read from stack *)
Dout := fifo[NR];
NR := INC1(N:=N, X:=NR);
empty := NR = NW;
full := FALSE;
(* write action *)
fifo[NW] := Din;
NW := INC1(N:=N, X:=NW);
full := NW = NR;
empty := FALSE;
WR_Edge := TRUE;
ELSIF NOT WR THEN
WR_Edge := FALSE;
END_IF;
IF RD AND NOT empty AND NOT RD_Edge THEN
(* read from stack *)
Dout := fifo[NR];
NR := INC1(N:=N, X:=NR);
empty := NR = NW;
full := FALSE;
RD_Edge := TRUE;
ELSIF NOT RD THEN
RD_Edge := FALSE;
END_IF;
END_IF;
END_FUNCTION_BLOCK