An implementation of a stripped-down Verilog simulation event loop.
Written in order to understand verilog scheduling semantics. In other words, how a verilog simulator models the behaviour of a system of parallel processes (AND gates, flip-flops etc.) on the sequential processor of a computer? This explains the verbosity of the simulator
- it reports on everything that it's doing and plans to do.
NOTE This verilog simulator doesn't actually have a verilog codei
parser! Verilog procedural blocks (initial and always) are built up
programmatically before the tiny-verilog-rs simulator is invoked.
Supported:
initialandalwaysblocks- Blocking assignments, e.g
a = 1 - Nonblocking assignments, e.g.
a <= 1 - Delay statements, e.g.
#3 - Wait statments, e.g.
@(a),@(posedge a)&@(negedge a) - And, Or & Not:
a = b | c - VCD file output (single-bit variables)
Has:
- Active event queue
- Nonblocking assignment queue
- Future event minheap
Ideas for future updates:
- Continuous assignments
- Branching and comparasons
- Introduce "inactive" queue, e.g.
#0 - Switch to implement VHDL event loops, for comparason
Implemented using the Rust programming language, compiler version 1.15. No external crates required.
main.rs- build a few procedures and invoke the simulator engineprocedures.rs- datastructure for aninitialoralwaysblock, plus everything below ( statements, assignments, delays etc...)timeheap.rs- future event min-heapengine.rs- the main simulator event loopvcd.rs- VCD waveform dumpertest_procs.rs- the art of verilog without verilog - routines to build up verilog procedures. Has things likebuild_clock()andbuild_bitstream().
To prove nonblockiness, change NonBlockingAssign in build_flop() to
BlockingAssign and compare waveforms of ff3_out before and after!