Introduction
Some of the additional features found in the new VER:
Examples
module paramtest (y, a);
parameter SZ = 3;
output [SZ-1:0] y;
input a;
parameter Y_0 = SZ'b0,
Y_1 = SZ'b1;
assign y = a ? Y_0 : Y_1;
endmodule // paramtest
module bar (q, d, reset, en, scan_in, scan_test, ck);
output q;
input d, reset, en, scan_in, scan_test, ck;
reg q, din;
always @ (posedge ck) // clocked process: q is a flipflop
if (reset)
q = 1'b0;
else if (en)
q = din;
always @ (d
or scan_test
or scan_in) // combinational process: a mux
if (scan_test)
din = scan_in;
else
din = d;
endmodule // bar
module foo (y, a, b, p, q, r);
output [3:0] y;
input [3:0] a, b;
input p, q, r;
reg [3:0] y;
always @ (a or b or p or q or r)
begin
y[3:0] = 4'h0;
if (a == b) // this synthesizes a XOR/NOR comparator
begin
if (p & q)
y[2:1] = 2'b11;
end
else if (a) // interpreted as 'a != 0'
y[0] = r;
end
endmodule // foo
module bar(y, z, a, ck);
output [3:0] y;
reg [3:0] y;
output [3:0] z;
input [3:0] a;
input ck;
always @ (posedge ck)
begin
y[2] = a[3];
casex (a[2:1]) // pragma parallel_case
2'bx0: y[1] = 1'b1;
2'b11:
begin
y[2:1] = 2'b00;
case (a[3:2])
2'b01: y[2] = 1'b0;
default y[2] = a[0];
endcase
if (a[0] != 1'b1)
y[1] = 1'b1;
end
default y[1] = a[3];
endcase
end
assign z = a[3:2] ? 4'b1010
: a[1] ? 4'b0000
: 4'b1100;
endmodule // bar
Non-blocking assigns use the <= symbol instead of = and they have no effect until after the execution of the always block. Blocking assignments take effect immediately. Example:
always @ (ck)
begin
a <= b;
b <= a;
end
swaps the values in register a and b. But ...
always @ (ck)
begin
a = b;
b = a;
end
....copies b to register a, but it also copies b to register b
(i.e. nothing happens to register b itself).
Until now, ver used the = symbol to implement a mix of blocking and non-blocking semantics. (`Non-blocking' because assignment did not take effect immediately, but also `blocking' because the sequential order of the assignments was guaranteed, unlike non-blocking semantics, see your favorite Verilog book, Thomas & Moorby I believe?).
In Thomas & Moorby verilog the following yields unpredictable results:
begin
a <= 1'b1;
a <= 1'b0;
end
The verilog simulator cannot guarantee that the second assignment to a
overrules the first assignment to a. However, in the synopsys semantics
they actually do guarantee that a will be 1'b0. I have taken the
synopsys road for ver, because this is also compatible with T & M. (And
because it is easier to program in ver/behave.c because now I don't have
to randomize the results for non-blocking assignments).
I have tested the new code quite extensively for a change. One thing I discovered was that some big circuit of mine would not run anymore, but that was a problem with the verilog because the semantics of `=' had slightly changed. Replacing it with <= (or changing the order of the blocking assignments inside my always block) fixed the problem.
I believe this is serious step to getting closer to real verilog semantics with ver. Oh yeah, I also added delay control to procedural assignments, i.e. `y <= #1 a'. Its semantics are ignored but it comes in very handy when compiling code that was written for Synopsys or Cadence.
For some funny reason the delay control bumps up the number of shift/reduce conflicts from 2 to 14, but this does not seem to affect the parser in a bad way (it still parses the way it used to do as far as I can tell).
The other thing that I like to add one day is named blocks, as in:
module foo;
reg bar;
always @ (...)
begin: a_new_scope
reg foo_in_a_new_scope;
...
end
endmodule
This is being used liberally in a bunch of verilog example code that I
ftp'ed from the Xilinx web-site. I think it is nice if ver is capable of
compiling all those examples. I believe the named blocks are the only
thing missing from ver to handle the examples.
Enjoy!
For more involved examples, click here or here.
Paul Stravers