5
votes

I have a VHDL component which implements a DRAM test sequence. It contains a child entity which is the DRAM controller.

I want to simulate (debug) the DRAM test sequence but use a simple fake stub for the DRAM controller rather than the real, complicated thing.

Is there a way I can set this up, perhaps using VHDL configurations to use a simple version of the controller entity for simulation? I'm quite new to simulation, and not hugely experienced with VHDL in general.

This is using Xilinx ISE and ISim targeting Spartan-6, if that makes a difference.

2
Is there a need to have a smaller/faster DRAM controller? Is there a limit in the simulator or lake of compute power? If not, I would not do the effort and/or take the risk.vermaete
Interesting question : this is exactly what configurations are for! However using them in this way - or even at all - is surprisingly rare and therefore prone to odd tool bugs. Whether I answer or not, I'm watching this one with interest!user_1818839
@Vermaete : if the DDR controller is Xilinx MIG : it insists on a calibration sequence lasting 50us before it'll let you run a single useful cycle of simulation. Combine that with another of their cores that they (insanely) only simulate at gate level and you're waiting half an hour per simulation. That may not count as "need" but it's close!user_1818839
@Brian Drummond: okay, that would be a valid reason. However, some of those IP's have generics to speed-up simulations by skipping those phases.vermaete
timings given were WITH those generics!user_1818839

2 Answers

5
votes

One way that doesn't use configurations:

remember that you can create several architectures for each entity.

Therefore you can instantiate a unit in your testbench as

Controller_1 : entity work.DRAM_controller(simple)
               port map ( ...

or

Controller_2 : entity work.DRAM_controller(rtl)
               port map ( ...

where "simple" and " rtl" are two architectures. For this purpose, you may have to have the entity and both architectures in different files; Xilinx tools are not very good at handling uncommon cases (at one time they told me that configurations were not design units!)

Then you can instantiate the DRAM controller with either architecture in a testbench.

As vermaete says, you also have to test the simplified architecture. One way is to run unit tests on it by instantiating both controllers in another testbench, one with each architecture, and comparing their outputs for each operation.

Funnily enough Ashenden's example for direct entity instantiation (Designer's Guide to VHDL ch 5.4, p.136 in my 1996 edition) is a DRAM controller!

EDIT: (this was a comment but it's getting too long)

For the unit test, both controllers can be instantiated in the testbench, and all is well.

For the system test, I did not understand that the DRAM controller was inside the UUT (top level design) - you want one instantiation (the real one) for synth and simple DRAM tests, and another (simple) for the full DRAM tests. Yes, a configuration is the correct and cleanest way to do that. Instantiate the controller ENTITY in the top level design (UUT), and select architectures in a configuration.

However there is a less clean alternative, as a fallback plan in case configurations don't work. Create 2 architectures for the top level entity; differing ONLY in the arch they select for the controller. You can select either architecture when you instantiate the top level entity in the testbench. It's a pain though, because you have to keep the two versions in sync.

4
votes

Another configuration-free way is to use generate to achieve this:

sim:if in_simulation generate
   Controller_1 : entity work.DRAM_controller(simple)
                  port map ...
else
   Controller_1 : entity work.DRAM_controller(rtl)
                  port map ...
end generate;

You can use this answer to create an in_simulation constant.

(If you don't have VHDL2008-compliant tools, you can't do an if...else..end generate and you'll have to do an if in_simulation/if not in_simulation pair instead. Raise a bug report :)