1
\$\begingroup\$

What is the best practice or method for synchronizing stimuli input and output with a sequential logic block in VHDL?

I am currently running only behavioral simulations, but I want to make sure my test bench will also work appropriately with timing simulations. I am testing various entities I am writing for handling modular addition/multiplication and a divider before I connect them all together. All sequential logic is written to use the rising edge of the clock.

I was originally providing stimuli at rising edge of the clock at the start of the simulation and waiting for whole multiples of the clock period before checking the results, however, I found that the logic would miss some inputs or take a cycle longer than expected. I've since come to the conclusion that, since inputs need to be stable at the rising edge of the clock, I should be changing stimuli only at the falling edge of the clock. I am now using a wait statement to align with the falling edge of clock and, for logic that take a well-defined number of cycles, wait for the appropriate number of clock periods and check the results. This seems to fix the issues I was having, but is this a recommended practice or should I use a different approach?

Also, when waiting upon output signals such as a ready or ack signal, should I combine that with a wait until rising_edge() and ready = '1', or keep everything, output and input, aligned on the falling edge? Currently, using rising edge for outputs seems to be working.

\$\endgroup\$
  • \$\begingroup\$ Unless the stimulus block you're faking has knowledge about the internal clock of your module, you probably shouldn't be using your own assumptions about that clock when simulating it. \$\endgroup\$ – DonFusili Jun 8 '18 at 9:10
  • \$\begingroup\$ Do you want the resulting VHDL to be synthesizeable? \$\endgroup\$ – crj11 Jun 8 '18 at 11:27
  • \$\begingroup\$ @crj11 no, this is just in the test bench. Everything in the synthesizable code uses riding edge. \$\endgroup\$ – penguin359 Jun 8 '18 at 15:32
  • \$\begingroup\$ Then why not use rising edge of the same clock in the testbench? \$\endgroup\$ – Dave Tweed Jun 8 '18 at 15:56
  • \$\begingroup\$ Sheesh, I had a great answer for the wrong question :/ (Deleted it). I answered in terms of the TB ending before you wanted. \$\endgroup\$ – CapnJJ Jun 8 '18 at 17:26
0
\$\begingroup\$

I've since come to the conclusion that, since inputs need to be stable at the rising edge of the clock, I should be changing stimuli only at the falling edge of the clock

This is not a preferred approach. You want your TB to represent the system you will be operating within. In your system you will have a clock that goes to your FPGA, and you will have clocks that go to BFMs with which you interface. If you are not modeling the BFMs (e.g. DSP, microprocessor, etc.) you are not modeling, and thus verifying, the bus operation/protocol, only that you can apply data to the interface and that your FPGA will interpret that data once received. This is typical in a rudimentary TB that uses FileIO methods to read a sequential set of values and drive those values on the pins. This is ok, for sanity check maybe, but falls short of what should be considered "verification".

Sadly, VHDL is not a verification language like Vera, Specman, or SystemVerilog's OOP-space. VHDL, via Jim Lewis' efforts (Synthworks), has made strides in terms of OSVVM and, as such, greatly helps one model (arguably verify) designs using VHDL. If you don't have access to SV or the knowledge to employ it, and are strictly VHDL, OSVVM is probably about as good as it gets, and certainly better than using "test case files" via FileIO methods.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.