Close

clock divider, makefile, simulations and gtkwave

A project log for FPGA dabbling

I don't need an FPGA for anything but the fun of experimenting with it.

christophChristoph 12/03/2018 at 21:550 Comments

I found a great makefile in the icestorm examples. It can do synthesis, place and route, packing, run a simulation (pre- and post-synthesis) and program your board. Since users and hardware are different, it might need some adjustments here and there. The original file is here: https://github.com/cliffordwolf/icestorm/blob/master/examples/icestick/Makefile

It's actually pretty simple and saves a ton of work on the command line - just like it's supposed to.

I decided to take my simple clock divider code to see what it actually does (because I really don't remember exactly): write a test bench, run a simulation and look at the results in gtkwave.

Again, the clockdivider.v code I used earlier (and we'll see why it might be bad code):

module clockdivider #(
  parameter bits = 32
  )(
  input clkin,
  input[bits-1:0] div,
  output clkout
);

reg [bits-1:0] count = 0;
always @(posedge clkin)
begin
  if(count == 0)
    count = div;
  count = count - {{bits-1{1'b0}},1'b1};
end

assign clkout = (div == 1'b0) ? 1'b0 : 
                (div == 1'b1) ? clkin :
                (count == {bits{1'b0}});

endmodule

Let's put this under test with 4 bits, and divide the clock by 4.

clockdivider_tb

`default_nettype none

module test;

reg clk=0;
wire clkout;

always #1 clk=~clk;

 clockdivider #(.bits(3)) dut0(clk,3'd4,clkout);

initial
    begin
    $dumpfile("dump.vcd");
    $dumpvars(3);
#20 
    $finish;
    end 

endmodule

Now, with the makefile from the icestorm toolchain, getting simulation output is as simple as

make clockdivider_tb.vcd
gtkwave dump.vcd &

The makefile rules used here are:

%_tb: %_tb.v %.v
    iverilog -o $@ $^

%_tb.vcd: %_tb
    vvp -N $< +vcd=$@

The first one will use the %.v and %_tb.v files (where % is "clockdivider") to build the testbench executable (clockdivider_tb), using iverilog. This executable is then run by vvp using the second rule. This second rule is the one we triggered on the command line. I'm not sure what vvp actually *does*, because simply running the testbench executable will also generate the desired vcd file (unless it causes subtle changes that I'm not able to spot).

The testbench dumps values in dump.vcd, which can be viewed using gtkwave. The result:

The signals can be dragged into the waves window for inspection. The first pulse on clkout was a bit unexpected, but that's probably because we don't have a proper reset for the device. Anyway, it seems to divide the clock by 4, which is what I wanted to achieve. There's probably a lot of room for improvement, but I'm a mechanical engineer - cut me some slack.

Discussions