0

I am writing a test bench that I want to be able to have signals go high and low in a certain pattern (something like this):enter image description here Currently I manually type out what I want each time to be like this:

module TestExample;
reg a, b, c;

initial begin
    $dumpfile("test.vcd");
    $dumpvars(0, TestExample);

    # 0 a=0; b=0; c=0;
    # 10 a=1; b=0; c=0;
    # 20 a=0; b=1; c=0;
    # 30 a=1; b=1; c=0;
    # 40 a=0; b=0; c=1;
    # 50 a=1; b=0; c=1;
    # 60 a=0; b=1; c=1;
    # 70 a=1; b=1; c=1;
    # 80 a=0; b=0; c=0;

    # 90 $stop;
end
endmodule

The problem with this is when I get more signals (lets say a-z instead of a-b) it will take a really long time to manually type out each time and the associated value. Because of this I am wondering if there is a way I can automate the signals. For example if I could say switch your state every 10 u-seconds for a, every 20 u-seconds for b, and every 30 u-seconds for c?

Tyler Hilbert
  • 2,107
  • 7
  • 35
  • 55

2 Answers2

1

As Greg says...

module TestExample;
wire a, b, c, d ...
integer i;

initial begin
    $dumpfile("test.vcd");
    $dumpvars(0, TestExample);
    for (i = 0; i < 1<<26; i=i+1)
        #10;
    $stop;
end

assign a = i[0], b = i[1], c = i[2], d = i[3] ... 

endmodule
Matthew Taylor
  • 13,365
  • 3
  • 17
  • 44
  • What does the `1<<26` do? also what is the `a = i[0], b = i[1], c = i[2], d = i[3]` – Tyler Hilbert Jul 05 '17 at 13:47
  • `1 << 26` is [shift left](https://stackoverflow.com/questions/17691265/operator-in-verilog) by 26 places, ie 2 to the power of 26. The `assign` statement assigns elements of the _vector_ `i` to `wire`s `a`, `b`, `c`, `d` etc, as seemed to be the requirement. – Matthew Taylor Jul 05 '17 at 14:23
  • I personally prefer the concatenation approach `{ ... , d, c, b, a} = i;` which can be done as an assign statement or within the for-loop. – Greg Jul 05 '17 at 16:33
  • Ok I wrote the following code: https://gist.github.com/Tyler-Hilbert/296e3576653836b8ac6fbc5afdf232c4 and ran it but got the following error: "TestExample.v:27: error: reg a; cannot be driven by primitives or continuous assignment. TestExample.v:27: error: reg b; cannot be driven by primitives or continuous assignment. TestExample.v:27: error: reg c; cannot be driven by primitives or continuous assignment. 3 error(s) during elaboration." When I went and changed the registers to wires it worked though. What causes this? – Tyler Hilbert Jul 05 '17 at 18:53
  • @user2417339 `assign` statements work on `wire`s not `reg`s. Change a,b,c,... to `wire` type or move the assignment inside the for-loop. – Greg Jul 05 '17 at 19:17
1

for generic patterns, you can use multiple initial blocks, say one per variable:

initial begin
   a = 0;
   forever begin
      #10 a = 1;
      #10 a = 0;
   end
end
initial
   b = 1;
   forever begin
      #30 b = 0;
      #30 b = 1;
   end
end
...
initial begin
    $dumpfile("test.vcd");
    $dumpvars(0, TestExample);

    #1000 $finish;
end
Serge
  • 11,616
  • 3
  • 18
  • 28