Hello World Revisited

Earlier I had posted my simple hello_world.sv example. Now I want to dive into a slightly more comprehensive example. This example also communicates to the testbench so I can begin to explore SystemC for testing.

hello_world.sv

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
`timescale 1 ns / 10 ps
module hello_world
  #
  (
   parameter     NUM_CLK = 2
   )
  (
   input  clk,
   input  rst,
   
   output logic done
   );

  logic [NUM_CLK-1:0] delay_reg;

  initial begin
    delay_reg = '0;
    done      = '0;
  end

  always_ff @(posedge clk, posedge rst)
    if (rst) begin
      delay_reg <= '0;
      done      <= '0;
    end else begin
      /* verilator lint_off WIDTH */
      delay_reg <= (delay_reg << 1) | 1'b1;
      /* lint_on */
      if (delay_reg[$left(delay_reg)]) begin
  done <= '1;
      end
    end
endmodule // hello_world

Breaking it down

1
`timescale 1 ns / 10 ps

The timescale directive defines the scale of time (1ns) that is used whenever a delay is called for, i.e. assign a = #10 b; would assign b to a after 10ns. it also defines the precision, 10ps. so you can set delays from 0.01 up in increments of 0.01ns (10ps.)

1
2
3
4
5
6
7
8
9
10
11
module hello_world
  #
  (
   parameter     NUM_CLK = 2
   )
  (
   input  clk,
   input  rst,
   
   output logic done
   );

The module definition is broken up into two pieces. The first is the parameter list. In this particular case, we are defining a parameter called NUM_CLK which we will use to define how many cycles it will take for the done signal to go high after reset. I did this to test changing parameters from verilator which I do in the make file. One thing not demonstrated here is that the parameter can modify the signals in the port list. For instance, done could have been defined:
output logic [NUM_CLK-1:0] done;

One further thing to note is that if I left logic off of the done defintion it would default to a wire type. A wire type cannot be driven from an always block. This would mean defining another signal of type logic within the design and then assigning it to the done signal. I chose this way to minimize intermediate signals.

1
  logic [NUM_CLK-1:0] delay_reg;

One thing to note is I typically use logic for all my signals. logic is a 4 state variable, meaning it can have the values {0, 1, x, z}. X is important for debugging since it’s easier to track down problems. bit type theo, a two state type {0,1} retically simulates faster, but since it doesn’t have a ‘x concept, it becomes harder to find issues and sometimes can mask problems.

1
2
3
4
  initial begin
    delay_reg = '0;
    done      = '0;
  end

A note on initial statements. In FPGAs, initial statements are synthesizable for Flip-Flop and BRAM/MRAM contents. The reason for this is that the FPGA is loaded via the scan chain and the tool can preload the RAM and FFs with values. This is not true for an ASIC design, so you may want to include a generate or ifdef around the construct if targetting one.

Some constraucts can not be preloaded. For example, UltraRAM.

1
2
3
4
5
6
7
8
9
10
11
12
  always_ff @(posedge clk, posedge rst)
    if (rst) begin
      delay_reg <= '0;
      done      <= '0;
    end else begin
      /* verilator lint_off WIDTH */
      delay_reg <= (delay_reg << 1) | 1'b1;
      /* lint_on */
      if (delay_reg[$left(delay_reg)]) begin
  done <= '1;
      end
    end

always_ff defines a FlipFlop, however, it is in actuality only a check that what is implemented is a FF. For example:

always_ff begin
a = b;
if (b) c = d;
end

Would generate a warning or error from the tool since no storage is created for a and c creates a latch. I’ll discuss latches and FFs later.

The flip flop defined has an asynchronous reset and a clock. For future designs I’ll be using a synchronous reset.

I then shift a 1 into the delay_reg every cycle Then when the left most bit is set, it sets the done flag. $left(delay_reg) resturns the value of NUM_CNT-1.

The final endmodule closes out the module definition.

The next post will go into detail on the testbench. The code can be found here: https://github.com/asicguy/book.git

About admin

Check Also

Sorting – Completely parallel approach

The first approach I attempted was a completely parallel approach as shown in the diagram …

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.