Showing results for 
Show  only  | Search instead for 
Did you mean: 
Registered: ‎01-20-2014

Block RAM simulation issue



Here is my setup:


Windows 10

Vivado 2016.1

Modelsim PE 10.5b


Here is what I am trying to do:

I am instantiating a native simple dual port block RAM with common clock. The part is generated from the IP catalog. Bit width is 64 and depth is 1024. The way I am writing to the RAM is from address 511 downto 0 and then address 1023 down to 512. The way I am reading it is from 0 to 1023.


The problem:

Based on my simulation outputs, I am writing correctly to addresses 511 and 1023. However, when I read addresses 511 and 1023, I am getting the output from addresses 510 and 1022. Eventually, at a later point, when I read address 512 and 0 I get the correct output from addresses 511 and 1023 albiet not at the expected latency. The IP states a read latency of 2 clock cycles. However, when address 512 and 0 are read, I get the output from address 511 and 1023 after one clock cycle.


Simulation outputs:


Address 511 write

This image shows the writing of the block ram addresses 511 and 510. As can be seen, we are writing a real value of -17860 and imaginary value of 1690 into address 511 (chan_mem_wr_addr) with m_axis_data_tvalid acting as the wea on the memory. The ena is tied to '1'.



Address 510 Write


For address 510, we are writing a real value of -2296 and imaginary value of -37512. Connections to write port on memory is same as above.



We wait until we have filled 512 locations in the memory (from address 511 downto 0) before we start the read. All the read outputs match expected except the last one where we are reading address 511.


Address 510 and 511 Read


Per the documentation, the read latency is 2 clock cycles. So, we simply shift register the chan_mem_rd_en (tied to Block RAM's enb) by two clock cycles to generate the "valid" for the output. The two buses mem_real and mem_imag represent the output data from the memory. As can be seen in the image, chan_mem_rd_en is high only until address 511. The outputs that come out for address 510 and 511 are identical and they match the data written to memory location 510 from image above. This is the case despite showing in the write address part above that we are writing values, addresses and enables correctly to the memory.



Address 512 Read


We wait until we are done writing addresses 1023 down to 512 before we start reading from address 512 up to 1023. The image below shows the read of address 512. As can be seen, one clock cycle (first marker is on rising edge of clock and second is on when the data changes. Clock period is 1ns. We see 1.1ns because of delay between read enable and data output from memory) after chan_mem_rd_en is asserted, we see output that belonged to address 511 show up.




This sort of discrepancy lasts all the way through repeating every 512 reads.


I simulated just the memory, and of course things work well. However, in that simulation, I simply connected read and write addresses to straight counters with some wait between them. It was not a one to one check vs. my design's methodology of reading and writing.


I also read in the answer records that the write enable on the memory MUST be tied to either '1' or '0' but they got around it by using a when else. So, I did the same. I tried to simulate so that


chan_mem_rd_en <= '1' when m_axis_data_tvalid = '1' else '0';


To no avail. I see the same behavior as shown in the simulation outputs above.


Any help/light you can shed on this will be extremely helpful.


Thank you.

0 Kudos
3 Replies
Registered: ‎01-20-2014

Another data point - After I posted this, I went to IP generator and disabled output register on Port B of the memory leading to a read latency of one clock. The simulation works properly.


Question is if the problem I see when I do enable the output register a simulation issue or a real issue when I build the chip?


Thank you.

0 Kudos
Registered: ‎03-27-2014

I guess this is only for simulation purposes, but if you do something like

@parth_vakil wrote:

chan_mem_rd_en <= '1' when m_axis_data_tvalid = '1' else '0';

that means your read_tvalid has the exact same waveform than m_axis_data_tvalid,

you should have at least a one clock cycle latency between the two (in real life it will probably be a lot more) because the core sets the read-data bus according to what happened on the write-data bus (m_axis_data_tvalid) in previous clock cycles

Embedded Systems, DSP, cyber
0 Kudos
Registered: ‎01-20-2014



Thanks for the reply. This is my bad. I mis-wrote what I intended. The answer records indicated that the write enable on the memory ought to be a '1' or a '0' and they got around it by using when else. I tried that out too and the way I did it is


wea <= '1' when m_axis_data_tvalid = '1' else 0;


This wea is connected to the wea on the memory. The read enable is controlled separately and goes high later.


So, this is a correction to my original post only in the sense that i did not write the correct signal name in the post. I am using the correct signal name in my simulation and the problem still stands.


Thank you.



0 Kudos