Verilog with Icarus
This tutorial shows how to generate waveforms from Verilog using Icarus Verilog and view them in NovyWave.
Prerequisites
Section titled “Prerequisites”- Icarus Verilog installed
- NovyWave installed (Installation Guide)
Installing Icarus Verilog
Section titled “Installing Icarus Verilog”Ubuntu/Debian:
sudo apt-get install iverilogmacOS:
brew install icarus-verilogWindows: Download from Icarus Verilog website
Step 1: Create a Simple Design
Section titled “Step 1: Create a Simple Design”Create counter.v — an 8-bit counter with enable and overflow detection:
module counter ( input wire clk, input wire reset, input wire enable, output reg [7:0] count, output reg overflow);
always @(posedge clk or posedge reset) begin if (reset) begin count <= 8'b0; overflow <= 1'b0; end else if (enable) begin if (count == 8'hFF) begin count <= 8'b0; overflow <= 1'b1; end else begin count <= count + 1'b1; overflow <= 1'b0; end end end
endmoduleStep 2: Create a Testbench
Section titled “Step 2: Create a Testbench”Create counter_tb.v:
`timescale 1ns/1ps
module counter_tb; parameter CLK_PERIOD = 10;
reg clk; reg reset; reg enable; wire [7:0] count; wire overflow;
counter uut ( .clk(clk), .reset(reset), .enable(enable), .count(count), .overflow(overflow) );
// Clock generation initial begin clk = 0; forever #(CLK_PERIOD/2) clk = ~clk; end
// VCD dump for waveform viewing initial begin $dumpfile("counter.vcd"); $dumpvars(0, counter_tb); end
// Stimulus initial begin // Initial reset reset = 1; enable = 0; #50;
// Release reset, enable counting reset = 0; enable = 1; #300;
// Disable counting briefly enable = 0; #50;
// Resume counting enable = 1; #200;
// Apply reset while counting reset = 1; #30; reset = 0; #200;
// Continue until overflow #3000;
$finish; end
endmoduleStep 3: Compile and Run
Section titled “Step 3: Compile and Run”# Compile the designiverilog -o counter_sim counter.v counter_tb.v
# Run simulationvvp counter_simThis creates counter.vcd with all signal transitions.
Step 4: View in NovyWave
Section titled “Step 4: View in NovyWave”- Open NovyWave
- Click Load Files
- Select
counter.vcd - Click Load
The file appears in Files & Scopes:
counter.vcd (0-3830ns) └── counter_tb └── uutStep 5: Explore the Waveform
Section titled “Step 5: Explore the Waveform”- Click the checkbox next to
counter_tb - In the Variables panel, click
clk,reset,enable,count, andoverflow - Press
Rfor full view - Zoom in with
Wto see the reset release at 50ns - Use
Shift+Eto jump between counter transitions - Change
countformat to UInt to see decimal values
Verilog Waveform Commands
Section titled “Verilog Waveform Commands”Basic Dump
Section titled “Basic Dump”initial begin $dumpfile("output.vcd"); $dumpvars(0, testbench_name); // Dump all signalsendSelective Dump
Section titled “Selective Dump”initial begin $dumpfile("output.vcd"); $dumpvars(1, testbench_name); // Only top level $dumpvars(0, testbench_name.dut); // All signals in dutendDump Control
Section titled “Dump Control”initial begin $dumpfile("output.vcd"); $dumpvars(0, testbench_name);
#1000; $dumpoff; // Stop dumping #500; $dumpon; // Resume dumpingendUsing FST Format (Verilator)
Section titled “Using FST Format (Verilator)”For better performance with large designs, use Verilator with FST output:
#include "verilated_fst_c.h"
int main() { Verilated::traceEverOn(true);
VerilatedFstC* tfp = new VerilatedFstC; top->trace(tfp, 99); tfp->open("output.fst");
// ... simulation loop ...
tfp->close();}FST files are 10-100x smaller and faster to load in NovyWave.
Next Steps
Section titled “Next Steps”- Add assertions to your testbench
- Create parameterized tests
- Compare multiple test runs with the multi-file tutorial
- Explore the complete example project in examples/verilog/counter/
Troubleshooting
Section titled “Troubleshooting”No VCD file created
Section titled “No VCD file created”Ensure $dumpfile and $dumpvars are called before signals change. Check that the simulation runs to completion (look for $finish).
Missing signals
Section titled “Missing signals”Verify the module hierarchy in the $dumpvars call. Use depth 0 to dump all signals: $dumpvars(0, top_module).
Large VCD files
Section titled “Large VCD files”Use selective dumping with $dumpvars(0, specific_module), use $dumpoff/$dumpon to skip uninteresting periods, or consider FST format with Verilator.