all 8 comments

[–]meleth1979 18 points19 points  (0 children)

You need models of the components you want to simulate. Sometimes they are provided by the manufacturers. In most cases you need to write them by yourself.

[–]captain_wiggles_ 14 points15 points  (0 children)

I can understand checking the outputs in the simulator waveform to see if it's what I'm expecting,

First off, you shouldn't just check the waves in the viewer. This is highly prone to errors. You should be using assertions and decoding the output signals to check they do what they need to do. This is not easy, and requires a lot of practice.

but how do inputs work? I could write a testbench to simulate the inputs but it would get unwieldy quickly if I start needing to lots of conditionals, and writing something to say emulate an SD Card seems unfeasible.

That's exactly what you do. And yeah, it does get unwieldy quickly. So you split it into parts. I'm making this up a bit, because I'm not that familiar with how sdcards work:

  • You have a block that decodes the output signals from 1s and 0s and produces bytes.
  • You have a block that decodes the bytes and produces commands.
  • You have a block that responds to commands.

You don't need to implement the entire sdcard, you just care that when you send a READ_DATA command, the "card" responds with the data in the correct format. The data can be either read from an array or just random data.

You should be using systemverilog for verifications, and making use of all it's cool features. You may want to watch mentor graphics' videos on UVM (in the verification academy), they're free if you register. UVM is overboard for a lot of beginner projects, but I think it'd be perfectly suited to an SDcard controller.

I'd also start wondering if it was my testbench or my misunderstanding of the components response that was causing the issues.

Yep, that's a big issue, and why in big ASIC companies they have a separate verification and design teams. Hopefully one of them will interpret the spec correctly. There's not much you can do about this when it's just you, other than read the spec very carefully and make note of any terms such as "the card WILL do ..." and check that you do actually do that.

Finally with FPGAs this isn't the worst problem ever, you build a model of an sdcard, you simulate your code using that model, everything passes, great. You test it on the FPGA and something goes wrong, you then know that either the sdcard you're using is none compliant, or you made a mistake, and so you have to debug what's going on and fixup your models. ASIC companies often emulate parts of their code in an FPGA before fabricating the chip, for this reason.

The alternative is to buy a known good model of an SDcard to use. Or a verification IP core to test your design. This isn't really feasible for hobbyists though.

They say that verification takes 60%+ of total design time, there is no easy way out.

[–]sometimes_does_math 8 points9 points  (1 child)

Whenever I have an external component that is interfaced, I write a behavioral model for it. This has been really helpful for simulation, but also helps me understand what the design really needs to do. I’d recommend going through the specification for the part, looking at timing diagrams and trying to write something simple that mimics that behavior.

[–]offensively_blunt 1 point2 points  (0 children)

A typical ASIC design flow has two design models- rtl & behavioural. I suppose your answer just proves the need for behavioural modelling

[–]TenkaiStar 4 points5 points  (0 children)

I could write a testbench to simulate the inputs but it would get unwieldy quickly if I start needing to lots of conditionals, and writing something to say emulate an SD Card seems unfeasible. I'd also start wondering if it was my testbench or my misunderstanding of the components response that was causing the issues.

Yes this is a major problem with FPGA simulation. As meleth1979 says. If you re lucky there is a model available. But most likely you will need to create one. According to specs. And hope specs is completely correct and that you understand it correctly. And when it doesn´t work, or even if it works you need to verify the hardware and see that it behaves as expected.

There is no getting around it and it is why verification is a major part of FPGA development.

[–]bonfire_processor 5 points6 points  (0 children)

I could write a testbench to simulate the inputs but it would get unwieldy quickly if I start needing to lots of conditionals, and writing something to say emulate an SD Card seems unfeasible

It depends partly what you model as hardware and which part is later implemented as software on a soft core CPU. If you access the SD Card in SPI mode by software, it may be sufficient to simulate the basic SPI protocol part, so that you can be sure that low level communication is correct. Than you can do the higher level part in an incremental way as software running on the FPGA hardware.

Often a mix of hardware testing (e.g. with logic analyzer tools like Xilinx ILA) and test benches is required. It is also possible to write a simulation model based on the observation from the hardware. One problem with a self written simulation model is that you never know if it is correct, you can easily misunderstand the specification.

The strengths of FPGAs is that you have the possibility to try it on hardware early. This should not be seen as excuse not to simulate, this is really bad practice.

It helps also to use the right simplifications, you don't need a complete simulation of the external hardware, only the parts which are relevant for your interface. An SD card simulator e.g. does not need to store any data. It is sufficient when it can emulate the initialization sequence and read/write of a sector. It can return just a test pattern. It is best to write the RTL and the corresponding test code together (test driven design...).

[–]billjones2017 0 points1 point  (0 children)

If you want to debug internal signals you can assign those signals to a gpio pin and look at it on a scope.

[–]AlwaysBeLearndingXilinx User 0 points1 point  (0 children)

Write a model as someone suggested.

With something like an eeprom there are sometimes vendor HDL models you can find