FPGARelated.com
Forums

Block RAM strange behavior, address off by one

Started by M. Hamed April 17, 2007
I am getting a strange error with Block RAM on a Spartan 3 FPGA. Every
time I issue a read, the word at the location previous to the given
address is read. For example if I'm reading from address 5, the word
at address 4 is output instead. The data written to the block seems
correct when I view it in ModelSim so I assume it's something with the
read.

Viewing signals at the BRAM input in ModelSim shows the correct
address at the input of port A and the read clock signal goes high but
the wrong word appear at the output. ENA is always 1 and WEA is always
0. The very most recent Write to this same address (from a different
port) also shows the correct value being written.

The design works correctly in RTL but this problem only occurs with
the post-route netlist.

Did anyone encounter a similar problem like this before and can give
me a hint on what's going on.

Thank you.

On Apr 17, 8:13 pm, "M. Hamed" <mhs...@gmail.com> wrote:
> I am getting a strange error with Block RAM on a Spartan 3 FPGA. Every > time I issue a read, the word at the location previous to the given > address is read. For example if I'm reading from address 5, the word > at address 4 is output instead. The data written to the block seems > correct when I view it in ModelSim so I assume it's something with the > read. >
This does seem strange. Are your writes and reads always made to sequential memory locations (i.e. 1, 2, 3, ... in order)? Perhaps the error is in cycle timing and not address?
> Viewing signals at the BRAM input in ModelSim shows the correct > address at the input of port A and the read clock signal goes high but > the wrong word appear at the output. ENA is always 1 and WEA is always > 0. The very most recent Write to this same address (from a different > port) also shows the correct value being written. > > The design works correctly in RTL but this problem only occurs with > the post-route netlist. > > Did anyone encounter a similar problem like this before and can give > me a hint on what's going on. >
The only time I've seen something similar was with an old version of the BRAM simulation models that needed a slight positive hold time in the address. In effect it was the behavioral simulation that incorrectly gave the read data on the same clock that the address was presented. In fact BRAM's are registered in the Spartan 3 (and Virtex 2) series, so the output data should have changed on the following clock cycle. In the post-PAR timing simulation, the output changed on the following clock cycle as expected.
> Thank you.
A few ideas:
Are you sure about the content of the various locations?
Could the error have happened when you wrote data into the BRAM?

When reading, read twicein sequence from the same address. Then you
will see whether this is a read pipelining problem, or whether you
really are always reading the wrong information.
The error has to somewhere in your timing.

Be a sleuth!
Peter Alfke

On Apr 17, 7:12 pm, Gabor <g...@alacron.com> wrote:
> On Apr 17, 8:13 pm, "M. Hamed" <mhs...@gmail.com> wrote: > > > I am getting a strange error with Block RAM on a Spartan 3 FPGA. Every > > time I issue a read, the word at the location previous to the given > > address is read. For example if I'm reading from address 5, the word > > at address 4 is output instead. The data written to the block seems > > correct when I view it in ModelSim so I assume it's something with the > > read. > > This does seem strange. Are your writes and reads always made to > sequential memory locations (i.e. 1, 2, 3, ... in order)? Perhaps the > error is in cycle timing and not address? > > > Viewing signals at the BRAM input in ModelSim shows the correct > > address at the input of port A and the read clock signal goes high but > > the wrong word appear at the output. ENA is always 1 and WEA is always > > 0. The very most recent Write to this same address (from a different > > port) also shows the correct value being written. > > > The design works correctly in RTL but this problem only occurs with > > the post-route netlist. > > > Did anyone encounter a similar problem like this before and can give > > me a hint on what's going on. > > The only time I've seen something similar was with an old version of > the > BRAM simulation models that needed a slight positive hold time in the > address. In effect it was the behavioral simulation that incorrectly > gave > the read data on the same clock that the address was presented. In > fact > BRAM's are registered in the Spartan 3 (and Virtex 2) series, so the > output data should have changed on the following clock cycle. In the > post-PAR timing simulation, the output changed on the following clock > cycle as expected. > > > Thank you.
On Apr 17, 11:02 pm, Peter Alfke <a...@sbcglobal.net> wrote:
> A few ideas: > Are you sure about the content of the various locations? > Could the error have happened when you wrote data into the BRAM? > > When reading, read twicein sequence from the same address. Then you > will see whether this is a read pipelining problem, or whether you > really are always reading the wrong information. > The error has to somewhere in your timing. > > Be a sleuth! > Peter Alfke > > On Apr 17, 7:12 pm, Gabor <g...@alacron.com> wrote: > > > > > On Apr 17, 8:13 pm, "M. Hamed" <mhs...@gmail.com> wrote: > > > > I am getting a strange error with Block RAM on a Spartan 3 FPGA. Every > > > time I issue a read, the word at the location previous to the given > > > address is read. For example if I'm reading from address 5, the word > > > at address 4 is output instead. The data written to the block seems > > > correct when I view it in ModelSim so I assume it's something with the > > > read. > > > This does seem strange. Are your writes and reads always made to > > sequential memory locations (i.e. 1, 2, 3, ... in order)? Perhaps the > > error is in cycle timing and not address? > > > > Viewing signals at the BRAM input in ModelSim shows the correct > > > address at the input of port A and the read clock signal goes high but > > > the wrong word appear at the output. ENA is always 1 and WEA is always > > > 0. The very most recent Write to this same address (from a different > > > port) also shows the correct value being written. > > > > The design works correctly in RTL but this problem only occurs with > > > the post-route netlist. > > > > Did anyone encounter a similar problem like this before and can give > > > me a hint on what's going on. > > > The only time I've seen something similar was with an old version of > > the > > BRAM simulation models that needed a slight positive hold time in the > > address. In effect it was the behavioral simulation that incorrectly > > gave > > the read data on the same clock that the address was presented. In > > fact > > BRAM's are registered in the Spartan 3 (and Virtex 2) series, so the > > output data should have changed on the following clock cycle. In the > > post-PAR timing simulation, the output changed on the following clock > > cycle as expected. > > > > Thank you.- Hide quoted text - > > - Show quoted text -
If you generated the block RAM with coregen, there is an option to preload the RAM with a coe file. You can then simulate the block RAM both at the RTL and post P&R level, disable the writes in the code and see if you read the expected data designated by the coe file at the desired addresses. There are some instances when the RTL does not match the post P&R simulation. i.e. (sensitivity list is incomplete in a combinatorial process, improper use of blocking assignments and variables) I don't use the later two items in synthesizable code, so I don't have much experience with them, but then again, I never get an RTL vs post P&R simulation mismatch because of them. Hope this helps, Newman
Thank you for all the suggestions. I am led to suspect it's a timing
problem and I will investigate that. The data sheet and the handbook
barely mentions anything about Setup/Hold/Cycle time requirements or
otherwise I am looking in the wrong places.


On Apr 17, 10:21 pm, Newman <newman5...@yahoo.com> wrote:
> On Apr 17, 11:02 pm, Peter Alfke <a...@sbcglobal.net> wrote: > > > > > A few ideas: > > Are you sure about the content of the various locations? > > Could the error have happened when you wrote data into the BRAM? > > > When reading, read twicein sequence from the same address. Then you > > will see whether this is a read pipelining problem, or whether you > > really are always reading the wrong information. > > The error has to somewhere in your timing. > > > Be a sleuth! > > Peter Alfke > > > On Apr 17, 7:12 pm, Gabor <g...@alacron.com> wrote: > > > > On Apr 17, 8:13 pm, "M. Hamed" <mhs...@gmail.com> wrote: > > > > > I am getting a strange error with Block RAM on a Spartan 3 FPGA. Every > > > > time I issue a read, the word at the location previous to the given > > > > address is read. For example if I'm reading from address 5, the word > > > > at address 4 is output instead. The data written to the block seems > > > > correct when I view it in ModelSim so I assume it's something with the > > > > read. > > > > This does seem strange. Are your writes and reads always made to > > > sequential memory locations (i.e. 1, 2, 3, ... in order)? Perhaps the > > > error is in cycle timing and not address? > > > > > Viewing signals at the BRAM input in ModelSim shows the correct > > > > address at the input of port A and the read clock signal goes high but > > > > the wrong word appear at the output. ENA is always 1 and WEA is always > > > > 0. The very most recent Write to this same address (from a different > > > > port) also shows the correct value being written. > > > > > The design works correctly in RTL but this problem only occurs with > > > > the post-route netlist. > > > > > Did anyone encounter a similar problem like this before and can give > > > > me a hint on what's going on. > > > > The only time I've seen something similar was with an old version of > > > the > > > BRAM simulation models that needed a slight positive hold time in the > > > address. In effect it was the behavioral simulation that incorrectly > > > gave > > > the read data on the same clock that the address was presented. In > > > fact > > > BRAM's are registered in the Spartan 3 (and Virtex 2) series, so the > > > output data should have changed on the following clock cycle. In the > > > post-PAR timing simulation, the output changed on the following clock > > > cycle as expected. > > > > > Thank you.- Hide quoted text - > > > - Show quoted text - > > If you generated the block RAM with coregen, there is an option to > preload the RAM with a coe file. You can then simulate the block RAM > both at the RTL and post P&R level, disable the writes in the code > and > see if you read the expected data designated by the coe file at the > desired addresses. > > There are some instances when the RTL does not match the post P&R > simulation. i.e. (sensitivity list is incomplete in a combinatorial > process, > improper use of blocking assignments and variables) I don't use the > later two items > in synthesizable code, so I don't have much experience with them, but > then > again, I never get an RTL vs post P&R simulation mismatch because of > them. > > Hope this helps, > Newman
I hope you understand that the BRAM is a synchronous device. When you
read data, you first must apply the address, then you give it a rising
clock edge, and as a result of the clock edge, you get the data that
is stored at the above mentioned address location.
Some people think that the read operation should be just
combinatorial, providing output data when an address is applied. That
is NOT the way the BlockRAM works. It does nothing until you apply a
rising clock edge. From a timing point of view, it behaves like a flip-
flop or register.
Peter Alfke, Xilinx Applications

On Apr 18, 9:23 am, "M. Hamed" <mhs...@gmail.com> wrote:
> Thank you for all the suggestions. I am led to suspect it's a timing > problem and I will investigate that. The data sheet and the handbook > barely mentions anything about Setup/Hold/Cycle time requirements or > otherwise I am looking in the wrong places. > > On Apr 17, 10:21 pm, Newman <newman5...@yahoo.com> wrote: > > > On Apr 17, 11:02 pm, Peter Alfke <a...@sbcglobal.net> wrote: > > > > A few ideas: > > > Are you sure about the content of the various locations? > > > Could the error have happened when you wrote data into the BRAM? > > > > When reading, read twicein sequence from the same address. Then you > > > will see whether this is a read pipelining problem, or whether you > > > really are always reading the wrong information. > > > The error has to somewhere in your timing. > > > > Be a sleuth! > > > Peter Alfke > > > > On Apr 17, 7:12 pm, Gabor <g...@alacron.com> wrote: > > > > > On Apr 17, 8:13 pm, "M. Hamed" <mhs...@gmail.com> wrote: > > > > > > I am getting a strange error with Block RAM on a Spartan 3 FPGA. Every > > > > > time I issue a read, the word at the location previous to the given > > > > > address is read. For example if I'm reading from address 5, the word > > > > > at address 4 is output instead. The data written to the block seems > > > > > correct when I view it in ModelSim so I assume it's something with the > > > > > read. > > > > > This does seem strange. Are your writes and reads always made to > > > > sequential memory locations (i.e. 1, 2, 3, ... in order)? Perhaps the > > > > error is in cycle timing and not address? > > > > > > Viewing signals at the BRAM input in ModelSim shows the correct > > > > > address at the input of port A and the read clock signal goes high but > > > > > the wrong word appear at the output. ENA is always 1 and WEA is always > > > > > 0. The very most recent Write to this same address (from a different > > > > > port) also shows the correct value being written. > > > > > > The design works correctly in RTL but this problem only occurs with > > > > > the post-route netlist. > > > > > > Did anyone encounter a similar problem like this before and can give > > > > > me a hint on what's going on. > > > > > The only time I've seen something similar was with an old version of > > > > the > > > > BRAM simulation models that needed a slight positive hold time in the > > > > address. In effect it was the behavioral simulation that incorrectly > > > > gave > > > > the read data on the same clock that the address was presented. In > > > > fact > > > > BRAM's are registered in the Spartan 3 (and Virtex 2) series, so the > > > > output data should have changed on the following clock cycle. In the > > > > post-PAR timing simulation, the output changed on the following clock > > > > cycle as expected. > > > > > > Thank you.- Hide quoted text - > > > > - Show quoted text - > > > If you generated the block RAM with coregen, there is an option to > > preload the RAM with a coe file. You can then simulate the block RAM > > both at the RTL and post P&R level, disable the writes in the code > > and > > see if you read the expected data designated by the coe file at the > > desired addresses. > > > There are some instances when the RTL does not match the post P&R > > simulation. i.e. (sensitivity list is incomplete in a combinatorial > > process, > > improper use of blocking assignments and variables) I don't use the > > later two items > > in synthesizable code, so I don't have much experience with them, but > > then > > again, I never get an RTL vs post P&R simulation mismatch because of > > them. > > > Hope this helps, > > Newman
Thank you Peter for the clarification. I do understand that now. I
realized that for a read, I was outputting the clock and address at
the same time as if it was combinational. My problem now is to figure
out a way to fit an extra cycle in my state machine to issue the clock
one cycle after the address is output.

/MHS

On Apr 18, 9:37 am, Peter Alfke <p...@xilinx.com> wrote:
> I hope you understand that the BRAM is a synchronous device. When you > read data, you first must apply the address, then you give it a rising > clock edge, and as a result of the clock edge, you get the data that > is stored at the above mentioned address location. > Some people think that the read operation should be just > combinatorial, providing output data when an address is applied. That > is NOT the way the BlockRAM works. It does nothing until you apply a > rising clock edge. From a timing point of view, it behaves like a flip- > flop or register. > Peter Alfke, Xilinx Applications > > On Apr 18, 9:23 am, "M. Hamed" <mhs...@gmail.com> wrote: > > > Thank you for all the suggestions. I am led to suspect it's a timing > > problem and I will investigate that. The data sheet and the handbook > > barely mentions anything about Setup/Hold/Cycle time requirements or > > otherwise I am looking in the wrong places. > > > On Apr 17, 10:21 pm, Newman <newman5...@yahoo.com> wrote: > > > > On Apr 17, 11:02 pm, Peter Alfke <a...@sbcglobal.net> wrote: > > > > > A few ideas: > > > > Are you sure about the content of the various locations? > > > > Could the error have happened when you wrote data into the BRAM? > > > > > When reading, read twicein sequence from the same address. Then you > > > > will see whether this is a read pipelining problem, or whether you > > > > really are always reading the wrong information. > > > > The error has to somewhere in your timing. > > > > > Be a sleuth! > > > > Peter Alfke > > > > > On Apr 17, 7:12 pm, Gabor <g...@alacron.com> wrote: > > > > > > On Apr 17, 8:13 pm, "M. Hamed" <mhs...@gmail.com> wrote: > > > > > > > I am getting a strange error with Block RAM on a Spartan 3 FPGA. Every > > > > > > time I issue a read, the word at the location previous to the given > > > > > > address is read. For example if I'm reading from address 5, the word > > > > > > at address 4 is output instead. The data written to the block seems > > > > > > correct when I view it in ModelSim so I assume it's something with the > > > > > > read. > > > > > > This does seem strange. Are your writes and reads always made to > > > > > sequential memory locations (i.e. 1, 2, 3, ... in order)? Perhaps the > > > > > error is in cycle timing and not address? > > > > > > > Viewing signals at the BRAM input in ModelSim shows the correct > > > > > > address at the input of port A and the read clock signal goes high but > > > > > > the wrong word appear at the output. ENA is always 1 and WEA is always > > > > > > 0. The very most recent Write to this same address (from a different > > > > > > port) also shows the correct value being written. > > > > > > > The design works correctly in RTL but this problem only occurs with > > > > > > the post-route netlist. > > > > > > > Did anyone encounter a similar problem like this before and can give > > > > > > me a hint on what's going on. > > > > > > The only time I've seen something similar was with an old version of > > > > > the > > > > > BRAM simulation models that needed a slight positive hold time in the > > > > > address. In effect it was the behavioral simulation that incorrectly > > > > > gave > > > > > the read data on the same clock that the address was presented. In > > > > > fact > > > > > BRAM's are registered in the Spartan 3 (and Virtex 2) series, so the > > > > > output data should have changed on the following clock cycle. In the > > > > > post-PAR timing simulation, the output changed on the following clock > > > > > cycle as expected. > > > > > > > Thank you.- Hide quoted text - > > > > > - Show quoted text - > > > > If you generated the block RAM with coregen, there is an option to > > > preload the RAM with a coe file. You can then simulate the block RAM > > > both at the RTL and post P&R level, disable the writes in the code > > > and > > > see if you read the expected data designated by the coe file at the > > > desired addresses. > > > > There are some instances when the RTL does not match the post P&R > > > simulation. i.e. (sensitivity list is incomplete in a combinatorial > > > process, > > > improper use of blocking assignments and variables) I don't use the > > > later two items > > > in synthesizable code, so I don't have much experience with them, but > > > then > > > again, I never get an RTL vs post P&R simulation mismatch because of > > > them. > > > > Hope this helps, > > > Newman
You don't need a full cycle. You only have to satisfy the set-up time,
which is around 1 or 2 ns prior to the clock edge. Maybe you can use
the opposite-polarity clock edge.
Peter Alfke

On Apr 18, 10:44 am, "M. Hamed" <mhs...@gmail.com> wrote:
> Thank you Peter for the clarification. I do understand that now. I > realized that for a read, I was outputting the clock and address at > the same time as if it was combinational. My problem now is to figure > out a way to fit an extra cycle in my state machine to issue the clock > one cycle after the address is output. > > /MHS > > On Apr 18, 9:37 am, Peter Alfke <p...@xilinx.com> wrote: > > > I hope you understand that the BRAM is a synchronous device. When you > > read data, you first must apply the address, then you give it a rising > > clock edge, and as a result of the clock edge, you get the data that > > is stored at the above mentioned address location. > > Some people think that the read operation should be just > > combinatorial, providing output data when an address is applied. That > > is NOT the way the BlockRAM works. It does nothing until you apply a > > rising clock edge. From a timing point of view, it behaves like a flip- > > flop or register. > > Peter Alfke, Xilinx Applications > > > On Apr 18, 9:23 am, "M. Hamed" <mhs...@gmail.com> wrote: > > > > Thank you for all the suggestions. I am led to suspect it's a timing > > > problem and I will investigate that. The data sheet and the handbook > > > barely mentions anything about Setup/Hold/Cycle time requirements or > > > otherwise I am looking in the wrong places. > > > > On Apr 17, 10:21 pm, Newman <newman5...@yahoo.com> wrote: > > > > > On Apr 17, 11:02 pm, Peter Alfke <a...@sbcglobal.net> wrote: > > > > > > A few ideas: > > > > > Are you sure about the content of the various locations? > > > > > Could the error have happened when you wrote data into the BRAM? > > > > > > When reading, read twicein sequence from the same address. Then you > > > > > will see whether this is a read pipelining problem, or whether you > > > > > really are always reading the wrong information. > > > > > The error has to somewhere in your timing. > > > > > > Be a sleuth! > > > > > Peter Alfke > > > > > > On Apr 17, 7:12 pm, Gabor <g...@alacron.com> wrote: > > > > > > > On Apr 17, 8:13 pm, "M. Hamed" <mhs...@gmail.com> wrote: > > > > > > > > I am getting a strange error with Block RAM on a Spartan 3 FPGA. Every > > > > > > > time I issue a read, the word at the location previous to the given > > > > > > > address is read. For example if I'm reading from address 5, the word > > > > > > > at address 4 is output instead. The data written to the block seems > > > > > > > correct when I view it in ModelSim so I assume it's something with the > > > > > > > read. > > > > > > > This does seem strange. Are your writes and reads always made to > > > > > > sequential memory locations (i.e. 1, 2, 3, ... in order)? Perhaps the > > > > > > error is in cycle timing and not address? > > > > > > > > Viewing signals at the BRAM input in ModelSim shows the correct > > > > > > > address at the input of port A and the read clock signal goes high but > > > > > > > the wrong word appear at the output. ENA is always 1 and WEA is always > > > > > > > 0. The very most recent Write to this same address (from a different > > > > > > > port) also shows the correct value being written. > > > > > > > > The design works correctly in RTL but this problem only occurs with > > > > > > > the post-route netlist. > > > > > > > > Did anyone encounter a similar problem like this before and can give > > > > > > > me a hint on what's going on. > > > > > > > The only time I've seen something similar was with an old version of > > > > > > the > > > > > > BRAM simulation models that needed a slight positive hold time in the > > > > > > address. In effect it was the behavioral simulation that incorrectly > > > > > > gave > > > > > > the read data on the same clock that the address was presented. In > > > > > > fact > > > > > > BRAM's are registered in the Spartan 3 (and Virtex 2) series, so the > > > > > > output data should have changed on the following clock cycle. In the > > > > > > post-PAR timing simulation, the output changed on the following clock > > > > > > cycle as expected. > > > > > > > > Thank you.- Hide quoted text - > > > > > > - Show quoted text - > > > > > If you generated the block RAM with coregen, there is an option to > > > > preload the RAM with a coe file. You can then simulate the block RAM > > > > both at the RTL and post P&R level, disable the writes in the code > > > > and > > > > see if you read the expected data designated by the coe file at the > > > > desired addresses. > > > > > There are some instances when the RTL does not match the post P&R > > > > simulation. i.e. (sensitivity list is incomplete in a combinatorial > > > > process, > > > > improper use of blocking assignments and variables) I don't use the > > > > later two items > > > > in synthesizable code, so I don't have much experience with them, but > > > > then > > > > again, I never get an RTL vs post P&R simulation mismatch because of > > > > them. > > > > > Hope this helps, > > > > Newman
> Thank you Peter for the clarification. I do understand that now. I > realized that for a read, I was outputting the clock and address at > the same time as if it was combinational. My problem now is to figure > out a way to fit an extra cycle in my state machine to issue the clock > one cycle after the address is output.
Is the state machine actually issuing the clock to the BRAM? If so, it sounds like it is a gated clock which is to be avoided. Newman
On Apr 18, 12:31 pm, Newman <newman5...@yahoo.com> wrote:
> Is the state machine actually issuing the clock to the BRAM? If so, it > sounds like it is a gated clock which is to be avoided. >
The state machine output changes on a clock edge ( I know some can argue this is bad style). It goes like this: IF RISING_EDGE(clk) THEN CASE state IS <snip> WHEN READ_BKRAM => bram_read <= '1'; state <= WAIT_FOR_DATA; <snip> END CASE; END IF; The BKRAM clock is bram_read, and that should sythesize to the output of a FF. /MHS