Hello everyone, I'm currently having trouble writing to a dual port block memory generated with the IP (Core Generator) from WebPack, I'm using the Spartan 3E development board.
I generated a dual port block memory intending to use one port for write only (no read on write) and the other port for read only. I'm able to read data when loading an init file (I loaded this file just for testing purposes) but I'm unsuccessful trying to write new data into the RAM. The instructions are really basic but I might be missing something trivial. I'd highly appreciate any samples or advise on this issue.
Yes, when i < 16001 writemem is '1', but I don't see where i is ever initialized. Also, there are setup and hold time requirements on the signals into the ram. The way you are generating CLK_A you don't know which edge of CLK_A you are changing the data and address on. Am I reading the code correctly?
Why don't you clock the test code from the same clock as the memory?
Rick, Thanks for responding, First, "i" is initialized to zero at the beginning of the program. I run a test bench simulation of the signals and they looked accurate, I couldn't simulate the memory module so I assumed that if the control signals are good, the memory will work but it didn't. Secondly, I could use the same clock (see below) and change address and data during the falling edge so that when the rising edge of the clock comes in it writes the data to memory. I tried it and didn't work. I'm open and welcomed to any suggestions. Thanks,
---------------this is a test that copies the value "11110000"
---------------into the first 16000 memory locations memo: process (CLOCK) begin if falling_edge (CLOCK) then --memory update if i > 16000 then writemem
That link doesn't work for me. It just takes me to a page where I can do a search.
If you are initializing 'i' in the declaration, that is not considered to be universally synthesizable. It may work for XST or whatever you are using at the moment, but it will not work with all tools.
Block RAM is synchronous, which will work with the input signals changing on the same edge of the clock as the block RAM. If your design did not work, it was not because of that. Look at the data sheet and you will find that the hold time is very small or even negative while output delays are much larger. This is by design to allow same edge clocking without clock delay problems.
When you say "it didn't work", that is not much to go on. Was this in simulation or a real chip? What did it do exactly? What did you see that you didn't expect and what did you see that you did expect?
As Rick wrote, maybe the problem is the initiaziation, because it is possible that Xilinx ISE doesn't initialize CLK_25, even if you write it like this:
signal CLK_25 : std_logic := '0';
This means, CLK_25 could be X and it is possible, that it doesn't change. I had this problem with Quartus: I initialized a state machine to the second state, but the synthezizer simply ignored it and initialized it always to the first state.
Even if it works, it is not a good idea to use the derived CLOCK_25 as a clock signal, because it is a gated clock and can cause problems in larger designs (maybe you can read some warnings about this in ISE while compiling). If you need a slower clock speed, which you don't need for this example, you can use a PLL. For Altera chips it is even possible to generate multiple synchronized clocks with one PLL. I think this is possible with ISE and Xilinx chips, too.
So first initialize any signals in a reset section. Then you can implement an internal reset generator in VHDL: A counter (hopefully initialized to 0) counts to some low value and sets reset to 1 while counting. This works for my designs.
Then simulate the design. Xilinx ISE has a fast simulator integrated, which compiles exe files for a simulation. The simplest form would be to create a waveform file, which simulates the external inputs and take a look at the outputs and internal registers. But it depends on the simulator, if this is possible, e.g. with Quartus you can't see any internal registers in the simulator, but with the free Modelsim for Quartus you can even set breakpoints in the VHDL code. Many simulators simulates BRAM, too and you can read and write it from a testbench or inspect it within the running simulator. For more complex designs it is a good idea to use a VHDL testbench, for better simulation of the input pins and automatic test of the output pins, e.g. see ds2432_testbench.vhd in
. Note: The integrated Altera Quartus simulator can't use testbench like this, because of the "wait for" statements, but it should work with Modelsim and with the integrated Xilinx ISE simulator.
If the simulation works, but you still don't see the expected behaviour, try to route the CLK_25 signal to a pin and scope it. If it works, but the BRAM is still not written, maybe you've found a bug and you can try to submit a webcase to Xilinx. Both, Altera and Xilinx, have a good support, even for the free Web-editions (maybe this is one reason for high price of the non-free editions :-)
Frank Buss, email@example.com