# Strange behavior of Altera FIFO

Status
Not open for further replies.

#### shaiko

Hello,

Using Active HDL - I've been simulating a synchronous FIFO created by Altera's IP Catalog.

This is the instantiation of the FIFO:

Code:
LIBRARY ieee;
USE ieee.std_logic_1164.all;

LIBRARY altera_mf;
USE altera_mf.all;

ENTITY altera_fifo IS
PORT
(
clock		: IN STD_LOGIC ;
data		: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
rdreq		: IN STD_LOGIC ;
wrreq		: IN STD_LOGIC ;
empty		: OUT STD_LOGIC ;
full		: OUT STD_LOGIC ;
q		: OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
usedw		: OUT STD_LOGIC_VECTOR (3 DOWNTO 0)
);
END altera_fifo;

ARCHITECTURE SYN OF altera_fifo IS

SIGNAL sub_wire0	: STD_LOGIC ;
SIGNAL sub_wire1	: STD_LOGIC ;
SIGNAL sub_wire2	: STD_LOGIC_VECTOR (7 DOWNTO 0);
SIGNAL sub_wire3	: STD_LOGIC_VECTOR (3 DOWNTO 0);

COMPONENT scfifo
GENERIC (
intended_device_family		: STRING;
lpm_numwords		: NATURAL;
lpm_type		: STRING;
lpm_width		: NATURAL;
lpm_widthu		: NATURAL;
overflow_checking		: STRING;
underflow_checking		: STRING;
use_eab		: STRING
);
PORT (
clock	: IN STD_LOGIC ;
data	: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
rdreq	: IN STD_LOGIC ;
wrreq	: IN STD_LOGIC ;
empty	: OUT STD_LOGIC ;
full	: OUT STD_LOGIC ;
q	: OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
usedw	: OUT STD_LOGIC_VECTOR (3 DOWNTO 0)
);
END COMPONENT;

BEGIN
empty    <= sub_wire0;
full    <= sub_wire1;
q    <= sub_wire2(7 DOWNTO 0);
usedw    <= sub_wire3(3 DOWNTO 0);

scfifo_component : scfifo
GENERIC MAP (
intended_device_family => "Stratix V",
lpm_numwords => 16,
lpm_type => "scfifo",
lpm_width => 8,
lpm_widthu => 4,
overflow_checking => "ON",
underflow_checking => "ON",
use_eab => "ON"
)
PORT MAP (
clock => clock,
data => data,
rdreq => rdreq,
wrreq => wrreq,
empty => sub_wire0,
full => sub_wire1,
q => sub_wire2,
usedw => sub_wire3
);

END SYN;

I simulated the design by applying stimuli to clock , wrreq and rdreq.
When wrreq = '1' - "usedw" and "empty" get updated on the rising egdge as expected. However, the actual content of the FIFO's memory matrix gets updated only on the falling edge of the clock...

Why is that?

#### Attachments

• Untitled.png
12.5 KB · Views: 113

#### TrickyDicky

Because thats how their memory model works. What you're simulating is not the chip, its an HDL model - doing updates on the falling edge is a way to understand the waves a little better

shaiko

### shaiko

Points: 2

#### shaiko

doing updates on the falling edge is a way to understand the waves a little better
Yet they find fit to update the control flags on the rising edge - Why the difference??

##### Super Moderator
Staff member
Shaiko,

More likely the model was written by some junior engineer or new grad.

e.g. Xilinx used to have an ODDR model that was written like an ASIC ODDR model. There wasn't any kind of # delays (Verilog) in the code and it worked great. Some where between the 9.x version and 10.x version of the Xilinx tools they replaced the model with a new (improved?) model that looked like it was written by a new grad. # delays were strew all over the model and the only way to make it work in your design was to add something like a #5 delay to the data inputs of the ODDR in your synthesizable RTL to compensate for the stacked delays in the model! Needless to say I never complied the new ODDR model I always used the old one, which was written correctly.

I originally discovered this, because my design didn't work the same way in hardware as it did in the simulation. When I added # delays to the ODDR data inputs then the simulation matched the hardware. The thing was I'd used the ODDR registers before in designs so I was wondering why the hardware behaved the same as the simulation previously, that's when I discovered they changed the Verilog simulation models for the ODDR.

shaiko

### shaiko

Points: 2

#### shaiko

Another strange behavior I encountered...

I set the FIFO as "show-ahead".
And disabled the RAM output register.
It seems like the above has no effect - the output still comes registered ( Written data appears at the output a full clock after the write operation )

This is the FIFO's instantiation:

Code:
	scfifo_component : scfifo
GENERIC MAP (
intended_device_family => "Cyclone IV E",
lpm_numwords => 256,
lpm_type => "scfifo",
lpm_width => 8,
lpm_widthu => 8,
overflow_checking => "ON",
underflow_checking => "ON",
use_eab => "ON"
)
PORT MAP (
clock => clock,
data => data,
rdreq => rdreq,
wrreq => wrreq,
empty => sub_wire0,
full => sub_wire1,
q => sub_wire2,
usedw => sub_wire3
);

The waveform is attached.

#### TrickyDicky

This is a FIFO - so why do you care?
Look-ahead just means that the q output is aligned with empty.
In non-lookahead mode, the data is valid 1 clock after not empty and rdreq.

In my mind, how the model works internally is immaterial, aslong as the interface behaves as expected.

#### shaiko

In my mind, how the model works internally is immaterial
It isn't just about the model - it's about the setting not taking effect ( add_ram_output_register => "OFF" ).

aslong as the interface behaves as expected.
It doesn't...
The FIFO's RAM is configured to have a non-registered output. Yet the output comes out registered regardless of the configuration in place.

#### TrickyDicky

It isn't just about the model - it's about the setting not taking effect ( add_ram_output_register => "OFF" ).

It doesn't...
The FIFO's RAM is configured to have a non-registered output. Yet the output comes out registered regardless of the configuration in place.

You're using a FIFO - it has extra logic around a ram. No data is valid until empty = '0'. The RAM behaviour is nothing to do with the FIFO.
If you want the ram - instantiate the ram - it will behave correctly.

shaiko

### shaiko

Points: 2

##### Super Moderator
Staff member
Are you changing the altera_fifo.vhd code you posted in #1, by manually changing add_ram_output_register => "ON" to add_ram_output_register => "OFF"?

If so, that is likely why the behavior doesn't change.

If you want to change the behavior of the FIFO you have to change the settings when generating the core as the megafunction wizard will change the underlying simulation code depending on what features you request.

#### TrickyDicky

Are you changing the altera_fifo.vhd code you posted in #1, by manually changing add_ram_output_register => "ON" to add_ram_output_register => "OFF"?

If so, that is likely why the behavior doesn't change.

If you want to change the behavior of the FIFO you have to change the settings when generating the core as the megafunction wizard will change the underlying simulation code depending on what features you request.

Altera cores just create a wrapper to a VHDL library. So modifying the generated wrapper should modify the setup. It means you can easily bypass the wizard and just instantiate these things yourself, unlike the Xilinx controlling philosphy of forcing you to use the coregen.

shaiko

### shaiko

Points: 2

##### Super Moderator
Staff member
Altera cores just create a wrapper to a VHDL library. So modifying the generated wrapper should modify the setup. It means you can easily bypass the wizard and just instantiate these things yourself, unlike the Xilinx controlling philosphy of forcing you to use the coregen.

So I guess that means Altera doesn't auto-generate code using perl scripts in the background, All the simulation code then exists with all the options controlled by the generics?

#### TrickyDicky

So I guess that means Altera doesn't auto-generate code using perl scripts in the background, All the simulation code then exists with all the options controlled by the generics?

Yes - you can even browse the source code for all of the altera_mf library (its 10s of thousands of lines in 1 file!)

#### shaiko

Are you changing the altera_fifo.vhd code you posted in #1, by manually changing add_ram_output_register => "ON" to add_ram_output_register => "OFF"?
Yes,
But TrickyDicky is right, changing the upper hierarchy's generics does effect to the lower hierarchies (without regenerating the core through the wizard).

#### TrickyDicky

Yes - you can even browse the source code for all of the altera_mf library (its 10s of thousands of lines in 1 file!)

At least you used to be able to
It might be when I had modelsim_altera installed - I would just recompile the code when I hit a new modelsim version.

##### Super Moderator
Staff member
Well that is definitely different than what Xilinx does, they typically auto-generate with perl scripts the code used for the design parameters specified, hence they always have warnings about unconnected stuff (unused wires/signals) in their auto-generated files.

I don't think this has anything to do with being "controlling". It's just a different way of approaching the problem of creating IP with multiple options. Either have an enormous piece of code that has every option under the sun with huge ifdef or generate-ifs to decide what options take effect (Altera's method) or write a script that generates the code for the options specified (Xilinx's method). Regardless, which way you go they both have the same results, you can create user modifiable IP.

Regardless whether or not you can hand edit, I normally never hand edit anything that is tool generated, too much of a chance for some clod down the line to regenerate the core, breaking the design. I suppose this would work if the wrapper file is the file that the IP uses to generate the core (is this the case with Altera?).

Status
Not open for further replies.