When I run an RTL simulation, the following types of errors occur for dual-port block RAM:
Message in ISE 6.2i and higher
For both VHDL and Verilog "Memory Collision Error on RAMB16_S36_S36:<instance_name> at simulation time <time> ns A write was requested to the same address simultaneously at both Port A and Port B of the RAM. The contents written to the RAM at address location <address> (hex) of Port A and address location <address> (hex) of Port B are unknown."
Message in ISE releases prior to 6.2i
Verilog "# Timing Violation Error: Setup time ## violated on RAMB instance <instance_name>.display_zero on CLKA port at simulation time ### ns with respect to CLKB port at simulation time ###. Expected setup time is 100."
VHDL "# ** Warning: */RAMB SETUP High VIOLATION ON CLKA WITH RESPECT TO CLKB; # Expected := 0.1 ns; Observed := # ns; At : ### ns # Time: ### ps Iteration: 1 Instance: <instance_name>"
Go to Design Considerations -> Block SelectRAM Memory -> Conflict Resolution.
You should avoid collisions whenever possible. When an address is written to on one port, your design should not allow a read from the same address on the other port. However, this cannot be avoided in certain applications. As long as the value that is read on the second port is not used in your design, you can safely ignore the violations.
NOTE: The collision warnings in the simulation are valid! You should disable the collision checks only if you are sure that the warnings can be safely ignored. It is safe to ignore these warnings only if you are not using the data that is read when the violation occurs. For example, in a FIFO application where the read port is always enabled for timing reasons, a violation occurs every time the FIFO is empty and data is written. The violation is valid in this case, but the value that is read is not used in the design, so you can ignore the violation. Use the following to work around similar situations:
1. Add a configuration statement to your testbench that changes the setup in the block RAM model to "0", as shown in the following example:
Example configuration statement:
configuration my_config of testbench is for behavioral for uut : top for behavioral for ram1, ram2, ram3 : RAMB4_S1_S1 use entity unisim.RAMB4_S1_S1 generic map (SETUP_ALL => 0 ns); end for; end for; end for; end for; end my_config;
This configuration statement sets the setup time to "0" for the ram1, ram2, and ram3 instances. All other BRAM in the design still have a setup time and will flag collision warnings. These three RAM should no longer flag collision warnings.
2. Alter the configuration statement based on your design hierarchy, and the entity, architecture, and instance names in your design. The general format is as follows:
configuration <any_config_name> of <entity name in testbench> is for <architecture name in testbench> for <instance name given to top level in the testbench> : <entity name of top level> for <architecture name of top level> for <instance name for next level of hierarchy> : <entity name in next level of hierarchy> for <architecture name in next level of hierarchy> : : for <BRAM instance name>, <BRAM instance name>, ... : <BRAM model name> use entity unisim.<BRAM model name> generic map (SETUP_ALL => 0 ns); end for; : : end for; end for; end for; end <config name>;
3. When your design is loaded, the configuration statement in the testbench must be loaded, rather than the architecture.
Verilog Work-Around If you are certain that the collision violations can be safely ignored, you can work around this issue by disabling the collision warnings on selected block RAM as described below.
Methodology in ISE 6.1i
Perform one of the following: - Compile the individual RAM models that you are using and define DISABLE_COLLISION_CHECK. - Set a config option so that CompXLib will disable collision checking for the RAM models that it compiles. Use the appropriate method for your simulator as follows:
This disables the setup violations between the clocks on the ram_inst block RAM instance. All other block RAM in the design retain the setup checks between the clocks. (You must change the "uut.ram_inst" based on the hierarchy of the design. To make this change, begin at the testbench and work down through all the levels of hierarchy using instance names: inst.inst.inst.inst.<reg>.)
The ram_inst should match the name of the instantiation of the RAMB in the top-level files.
This change will still produce the messages, but the output of the block RAM will no longer be Xs.