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; endswaps 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; endThe 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 endmoduleThis 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