ALuPin wrote:
> I have written some little code for a FIFO and I want
> to know whether the signals "l_fifo_full" / "l_fifo_empty" are
> correct generated.
If I understand your code correctly, then I'd say: no. From what I
understand you have a FIFO with one clock, and a read/write enable. You use
the FIFO as an elastic store, running the read/write addresses from 0 to
ROW-1, and round.
Ok, before I dive into your code: please, please, please, please don't use
asynchronous resets. Ok, now that I got that off my chest I can comment on
your code without hurting myself.
> process(Reset, Clk)
> begin
<snip>
> if (l_fifo_full='1')) then
> l_write_pointer <= 0;
> end if;
Ok, I don't understand why you'd want to put your write pointer to 0 when
your fifo is full. Do you just want a reset situation whenever your fifo is
full? Or do you want to do this when you cause an overflow, which would
mean writing into the FIFO when it is full. In that case it should be moved
inside the write if.
> process(Reset, Clk)
> begin
<snip>
> if (l_fifo_full='1')) then
> l_read_pointer <= 0;
> end if;
Something similar here, though I'd expect you to reset the FIFO if you try
to read from an empty FIFO. In this case you should be checking for empty,
and place it within the read if construction.
> process(Reset, Clk)
> begin
<snip>
> elsif rising_edge(Clk) then
> l_fifo_full <= next_l_fifo_full;
> l_fifo_empty <= next_l_fifo_empty;
Why do you wish to delay these indications for 1 clock cycle? Wouldn't you
want to use this information as soon as it is available? The next signals
are already clocked as far as I could see.
> process(l_fifo_full, l_fifo_empty, l_wp_turn_around, l_write_pointer,
> l_read_pointer, l_rp_reg)
> begin
<snip>
> if ((l_wp_turn_around='1') and (l_write_pointer=l_read_pointer) and
> (l_read_pointer=l_rp_reg)) then
> next_l_fifo_full <= '1';
> end if;
You define the FIFO as full if you have a wrap around (why is this a
prerequisite?), your write pointer equals your read pointer, and you didn't
do a read action this time. What if you didn't have a read action nor a
write action? It could be that the FIFO was and still is empty?
> if ((l_read_pointer=l_write_pointer) and (l_read_pointer>0)) then
> next_l_fifo_empty <= '1';
> end if;
Why would the read pointer have to be > 0?
> process(Reset, Clk)
> begin
<snip>
> elsif (Erase='1') then
> l_wp_turn_around <= '0';
> end if;
This is the first time I see the erase used. Wouldn't you want to reset the
read and write pointers at such a time as well?
Regards,
Pieter Hulshoff