290 likes | 407 Views
EE434 ASIC & Digital Systems. Jacob Murray School of EECS Washington State University jmurray@eecs.wsu.edu. Digital Design with Verilog. Lecture 20. System Tasks and Functions. Built in tasks contained in a library $display. System Tasks and Functions (cont’d). $finish. $ monitor.
E N D
EE434ASIC & Digital Systems Jacob Murray School of EECS Washington State University jmurray@eecs.wsu.edu
Digital Design with Verilog Lecture 20
System Tasks and Functions • Built in tasks contained in a library $display
System Tasks and Functions (cont’d) $finish $ monitor The $monitorsystem task provides the ability to monitor and display the values of any variable or expression specified as parameters to the task. The parameters are specified in exactly the same manner as the $displaysystem task.
System Tasks and Functions (cont’d) $stop The $stopsystem task puts the simulator into a halt mode, issues an interactive command prompt and passes control to the user. $time The $timesystem function returns the current simulation time as a 64-bit integer. $timemust be used in an expression.
Test Benches Module under test module adder (a, b, y); input [31 : 0] a, b; output [31 : 0] y; assign y = a + b; endmodule;
Test Benches module testbench () reg [31 : 0] testvectors [1000 : 0]; reg clk; reg [10 : 0] vectornum, errors; reg [31 : 0] a, b, expected_y; wire [31 : 0] y; // instantiate device under test adder dut (a, b, y);
Test Benches // read the test vector file and initialize test initial begin $readmemh (“testvectors.tv”, testvectors); vectornum = 0; errors = ‘0’; end • The initial statement defines a block that is executed only on startup of simulation. • The $readmemh reads a file in hexadecimal form, into an array in memory.
Test Benches (cont’d) //generate a clock to sequence tests always begin clk = 0; #50; clk = 1; #50; end
Test Benches (cont’d) //on each clock step, apply the test vector always @ (posedge clk) begin a = testvectors [vectornum]; b = testvectors [vectornum + 1]; expected_y = testvectors [vectornum + 2]; end
Test Benches (cont’d) //check for correct results always @ (negedge clk) begin vectornum = vectornum + 1; if (y !==expected_y) begin $display (“inputs were %h, %h, a, b); $display (“expected %h but actual %h”, expected_y, y); errors = errors + 1; end end
Test Benches (cont’d) // halt at the end of file always @ (vectornum) begin if (vectornum = = 100 || testvectors [vectornum] == 32 ‘bx) begin $display (“completed %d tests with %d errors.”, vectornum, errors); $finish; end end endmodule
Synthesis Issues Incorrect stimulus list moduleincorrect_latch (input clk, input [3 : 0] d, output reg [3 : 0] q); always @ (clk) if (clk) q <= d; endmodule When synthesized it still produces a latch, with a warning. When simulated, q will change on the rising edge of the clk but not on a change in d while clk is stable high.
Synthesis Issues (cont’d) module badmux (input [3 : 0] d_0, d_1, input s, output reg [3 : 0] y); always @ (posedge s) if (s) y <= d_1; else y <= d_0; endmodule Instead of a MUX this circuit will behave as a flip-flop. At the positive edge of s it captures d_1, and ignores d_0
Missing begin/end block Two variables are supposed to be assigned in the always block. The begin / end block is missing. This is a syntax error. This circuit model is not synthesizable. module example (input clk, input [1 : 0] d, output reg [1 : 0] q ); always @ (posedge clk) q [1] = d [1]; q [0] = d [0]; endmodule
Undefined Outputs always @ (*) if (state == 0) out1 <= 1; else out2 <= 1; // never set out1/out2 to 0 // need a reset endmodule
Undefined Outputs (Remedy) always @ (*) if (state == 0) begin out1 <= 1; out2 <= 0; end else begin out2 <= 1; out1 <= 0; end endmodule
Multiple Drivers module mux_2 (input [3 : 0] d0, d1, input s, output [3 : 0] y); tristate t0 (d0, s, y); tristate t1 (d1, s, y); endmodule
Multiple Drivers (cont’d) A reg is assigned in two different always blocks always @(posedgeclk, posedge reset) if (reset) q <= 0; else q <= d; always @(set) if (set) q <= 1;
Comparisons Comparisons with X and Z are always ignored always @ (b) begin if ((b == 1'bz) || (b == 1'bx)) a = 1; end
Example: ALU • ALU computes a variety of logical and arithmetic functions based on opcode. • May offer complete set of functions of two variables or a subset. • ALU built around adder, since carry chain determines delay.
ALU as multiplexer Compute functions then select desired one: opcode AND OR NOT SUM
Verilog for Simple ALU ‘define PLUS 0 ‘define MINUS 1 ‘define AND 2 ‘define OR 3 ‘define NOT 4 module alu(fcode,op0,op1,result,oflo); parameter n=16, flen=3; input [flen-1:0] fcode; input [n-1:0] op0, op1; output [n-1:0] result; output oflo; assign {oflo,result} = (fcode == ‘PLUS) ? (op0 + op1) : (fcode == ‘MINUS) ? (op0 - op1) : (fcode == ‘AND) ? (op0 & op1) : (fcode == ‘OR) ? (op0 | op1) : (fcode == ‘NOT) ? (~op0) : 0; endmodule
Verilog for barrel shifter module shifter (data, b ,result); parameter Nminus1 = 31; /* 32-bit shifter */ input [Nminus1:0] data; input [3:0] b; /* amount to shift */ output [Nminus1:0] result; /* shift result */ assign result = data << b; endmodule
Full adder • Computes one-bit sum, carry: • si = ai XOR bi XOR ci • ci+1 = aibi + aici + bici • Half adder computes two-bit sum. • Ripple-carry adder: n-bit adder built from full adders. • Delay of ripple-carry adder goes through all carry bits.
Verilog for full adder module fulladd (a, b, carryin, sum,carryout); input a, b, carryin; /* add these bits*/ output sum, carryout; /* results */ assign {carryout, sum} = a + b + carryin; /* compute the sum and carry */ endmodule
Verilog for ripple-carry adder module nbitfulladd (a,b,carryin,sum,carryout) input [7:0] a, b; /* add these bits */ input carryin; /* carry in*/ output [7:0] sum; /* result */ output carryout; wire [7:1] carry; /* transfers the carry between bits */ fulladd a0(a[0],b[0],carryin,sum[0],carry[1]); fulladd a1(a[1],b[1],carry[1],sum[1],carry[2]); … fulladd a7(a[7],b[7],carry[7],sum[7],carryout]); endmodule