FIFO simultaneous load unload

Begonnen von hence.persson, 15. Mai 2009, 21:21:38

Vorheriges Thema - Nächstes Thema

0 Mitglieder und 2 Gäste betrachten dieses Thema.

hence.persson

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..

hugo

this sounds like a good idea we will look into this

hence.persson

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

hence.persson

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