520 likes | 966 Views
Verilog II CPSC 321. Andreas Klappenecker. Today’s Menu. Verilog, Verilog, Verilog. Modules. module mod_name (parameters); input … output … reg … …… endmodule. Full Adder. module fulladd(cin, x, y, s, cout) input cin, x, y; output s, cout; assign s = x ^ y ^ cin;
E N D
Verilog IICPSC 321 Andreas Klappenecker
Today’s Menu Verilog, Verilog, Verilog
Modules module mod_name (parameters); input … output … reg … …… endmodule
Full Adder module fulladd(cin, x, y, s, cout) input cin, x, y; output s, cout; assign s = x ^ y ^ cin; assign cout = (x & y) | (cin & x) | (cin & y); endmodule
Full Adder module fulladd(cin, x,y,s, cout); input cin, x, y; output s, cout; assign { cout, s } = x + y + cin; endmodule The assign statement assigns the MSB to cout and the LSB to s.
Hello World module top; initial $display("Hello, world!"); endmodule initialstatements are executed once by the simulator
Vector wires • Range [msb: lsb] wire [3:0] S; S = 4’b0011 The result of this assignment is S[3] = 0, S[2] = 0, S[1] = 1, S[0] = 1 • wire [1:2] A; A = S[2:1]; means A[1] = S[2], A[2] = S[1]
Variables • Variables come in two flavors • reg • integers • reg can model combinatorial or sequential parts of the circuits reg does not necessarily denote a register! • Integers often used as loop control variables useful for describing the behavior of a module
Simple Example module testgate; reg b, c; // variables wire a, d, e; // nets and (d, b, c); // gates or (e, d, c); // nand(a, e, b); // initial begin // simulated once b=1; c=0; // blocking assignments #10 $display("a = %b", a); end endmoduleWhat value will be printed?
Operators • 1’s complement ~A • 2’s complement -A • bitwise AND A&B • reduction &A produces AND of all bits in A • Concatenate {a,b,c} • | {a,b,c} = a | b | c • Replication operators 2{A} = {A,A} • {2{A},3{B}} = {A,A,B,B,B}
Continuous assignments • Single bit assignments assign s = x ^ y ^ cin; assign cout = (x & y) | (cin & x) | (cin &y ) • Multibit assignments wire [1:3] a,b,c; … assign c = a & b;
Always Blocks • An always block contains one or more procedural statements • always @(sensitivity list) always @(x or y) begin s = x ^ y; c = x & y; end
Mux: Structural Verilog module mux(f, a,b,sel); input a,b,sel; output f; wire f1, f2; not(nsel, sel); and(f1, a,nsel); and(f2, b, sel); or (f, f1, f2); endmodule b f a sel
Mux: Dataflow Model module mux2(f, a,b,sel); output f; input a,b,sel; assign f = (a & ~sel) | (b & sel); endmodule
Mux: Behavioral Model module mux2(f, a,b,sel); output f; input a,b,sel; reg f; always @(a or b or sel) if (sel==1) f = b; else f = a; endmodule
Sign extension and addition module adder_sign(x,y,s,ss); input [3:0] x,y; output [7:0] s, ss; assign s = x + y, ss = {{4{x[3]}},x}+{{4{y[3]},y} endmodule x = 0011, y = 1101 s = 0011 + 1101 = 00010000 ss = 0011 + 1101 = 00000011 + 11111101= 00000000
Demux Example 2-to-4 demultiplexer with active low
Demux: Structural Model // 2-to-4 demultiplexer module demux1(z,a,b,enable); input a,b,enable; output [3:0] z; wire abar,bbar; not v0(abar,a), v1(bbar,b); nand (z[0],enable,abar,bbar); nand (z[1],enable,a,bbar); nand (z[2],enable,abar,b); nand (z[3],enable,a,b); endmodule
Demux: Dataflow model // 2-to-4 demux // dataflow model module demux2(z,a,b,enable); input a,b,enable; output [3:0] z; assign z[0] = | {~enable,a,b}; assign z[1] = ~(enable & a & ~b); assign z[2] = ~(enable & ~a & b); assign z[3] = enable ? ~(a & b) : 1'b1; endmodule
Demux: Behavioral Model // 2-to-4 demultiplexer with active-low outputs module demux3(z,a,b,enable); input a,b,enable; output [3:0] z; reg z; // not really a register! always @(a or b or enable) case ({enable,a,b}) default: z = 4'b1111; 3'b100: z = 4'b1110; 3'b110: z = 4'b1101; 3'b101: z = 4'b1011; 3'b111: z = 4'b0111; endcase endmodule
Always Blocks • The sensitivity list @( … ) contains the events triggering an evaluation of the block • @(a or b or c) • @(posedge a) • @(negedge b) • A Verilog compiler evaluates the statements in the always block in the order in which they are written
Assignments • If a variable is assigned a value in a blocking assignment a = b & c; then subsequent references to a contain the new value of a • Non-blocking assignments<= assigns the value that the variables had while entering the always block
D Flip-flop module D_FF(Q,D,clock); output Q; input D, clock; reg Q; always @(negedge clock) Q <= D; endmodule
Clock • A sequential circuit will need a clock • supplied by the testbed • Clock code fragment reg clock; parameter period = 100; initial clock 0; always @(period/2) clock = ~clock;
D-Flipflop with Synchronous Reset module flipflop(D, Clock, Resetn, Q); input D, Clock, Resetn; output Q; reg Q; always @(posedge Clock) if (!Resetn) Q <= 0; else Q <= D; endmodule // 7.46 in [BV]
Gated D-Latch module latch(D, clk, Q) input D, clk; output Q; reg Q; always @(D or clk) if (clk) Q <= D; endmodule Missing else clause => a latch will be synthesized to keep value of Q when clk=0
Shift Register: What is wrong here? module example(D,Clock, Q1, Q2) input D, Clock; output Q1, Q2; reg Q1, Q2; always @(posedge Clock) begin end endmodule Q1 = D; Q2 = Q1; Q1 = D; Q2 = Q1; // D=Q1=Q2
Shift register: Correct Version module example(D,Clock, Q1, Q2) input D, Clock; output Q1, Q2; reg Q1, Q2; always @(posedge Clock) begin Q1 <= D; Q2 <= Q1; end endmodule
Rule of Thumb • Blocking assignments are used to describe combinatorial circuits • Non-blocking assignments are used in sequential circuits
n-bit Ripple Carry Adder module ripple(cin, X, Y, S, cout); parameter n = 4; input cin; input [n-1:0] X, Y; output [n-1:0] S; output cout; reg [n-1:0] S; reg [n:0] C; reg cout; integer k; always @(X or Y or cin) begin C[0] = cin; for(k = 0; k <= n-1; k=k+1) begin S[k] = X[k]^Y[k]^C[k]; C[k+1] = (X[k] & Y[k]) |(C[k]&X[k])|(C[k]&Y[k]); end cout = C[n]; end endmodule
Loops and Integers • The for loop is used to instantiate hardware modules • The integer k simply keeps track of instantiated hardware • Do not confuse integers with reg variables
Bit-Counter • Count the number of bits having value 1 inregister X • Again an example for parameters • Another example of a for loop
Bit Counter module bit_cnt(X,Count); parameter n = 4; parameter logn = 2; input [n-1:0] X; output [logn:0] Count; reg [logn:0] Count; integer k; always @(X) begin Count = 0; for(k=0;k<n;k= k+1) Count=Count+X[k]; end endmodule
Blocks of Procedural Code • initial • executed once at the beginning of simulation • initial $display(“Hello World”); • always • repeatedly executed • begin-end • sequential execution of block statements • delays add up • fork-join blocks • concurrent execution of statements
Concurrency Example module concurrency_example; initial begin #1 $display(“Block 1 stmt 1"); $display(“Block 1 stmt 2"); #2 $display(“Block 1 stmt 3"); end initial begin $display("Block 2 stmt 1"); #2 $display("Block 2 stmt 2"); #2 $display("Block 2 stmt 3"); end endmodule Block 2 stmt 1 Block 1 stmt 1 Block 1 stmt 2 Block 2 stmt 2 Block 1 stmt 3 Block 2 stmt 3
Concurrency Example module concurrency_example; initial begin #1 $display(“Block 1 stmt 1"); $display(“Block 1 stmt 2"); #2 $display(“Block 1 stmt 3"); end initial begin $display("Block 2 stmt 1"); #2 $display("Block 2 stmt 2"); #2 $display("Block 2 stmt 3"); end endmodule Block 2 stmt 1 Block 1 stmt 1 Block 1 stmt 2 Block 2 stmt 2 Block 1 stmt 3 Block 2 stmt 3
Concurrency: fork and join module concurrency_example; initial fork #1 $display(“Block 1 stmt 1"); $display(“Block 1 stmt 2"); #2 $display(“Block 1 stmt 3"); join initial fork $display("Block 2 stmt 1"); #2 $display("Block 2 stmt 2"); #2 $display("Block 2 stmt 3"); join endmodule Block 1 stmt 2 Block 2 stmt 1 Block 1 stmt 1 Block 1 stmt 3 Block 2 stmt 2 Block 2 stmt 3
Displaying Results a = 4’b0011 $display(“The value of a is %b”, a); The value of a is 0011 $display(“The value of a is %0b”, a); The value of a is 11 If you you $display to print a value that is changing during this time step, then you might get the new or the old value; use$strobeto get the new value
Displaying Results • Standard displaying functions • $display, $write, $strobe, $monitor • Writing to a file instead of stdout • $fdisplay, $fwrite, $fstrobe, $fmonitor • Format specifiers • %b, %0b, %d, %0d, %h, %0h, %c, %s,…
Display Example module f1; integer f; initial begin f = $fopen("myFile"); $fdisplay(f, "Hello, bla bla"); end endmodule
Moore Machines The output of a Moore machine depends only on the current state. Output logic and next state logic are sometimes merged. next state logic present state register output logic input
Coding Moore Machines • The logic in the Moore machine can be described by two case statements (one case statement if logic blocks are merged) • Enumerate all possible states of input and current state, and generate the output and next state • Give states meaningful names using define or parameters
Moore Machine Example Automatic food cooker • Has a supply of food • Can load food into the heater when requested • Cooker unloads the food when cooking done
Automated Cooker Outputs from the machine • load = signal that sends food into the cooker • heat = signal that turns on the heater • unload = signal that removes food from cooker • beep = signal that alerts that food is done
Automated Cooker Inputs • clock • start = start the load, cook, unload cycle • temp_ok = temperature sensor detecting when preheating is done • done = signal from timer when done • quiet = Should cooker beep?
Cooker module cooker( clock, start, temp_ok, done, quiet, load, heat, unload, beep ); input clock, start, temp_ok, done, quiet; output load, heat, unload, beep; reg load, heat, unload, beep; reg [2:0] state, next_state;
Defining States `define IDLE 3'b000 `define PREHEAT 3'b001 `define LOAD 3'b010 `define COOK 3'b011 `define EMPTY 3'b100 You can refer to these states as ‘IDLE, ‘PREHEAT, etc.
State Register Block `define REG_DELAY 1 always @(posedge clock) state <= #(`REG_DELAY) next_state;
Next State Logic always @(state or start or temp_ok or done) // whenever there is a change in input begin case (state) `IDLE: if (start) next_state=`PREHEAT; `PREHEAT: if (temp_ok) next_state = `LOAD; `LOAD: next_state = `COOK; `COOK: if (done) next_state=`EMPTY; `EMPTY: next_state = `IDLE; default: next_state = `IDLE; endcase end
Output Logic always @(state) begin if(state == `LOAD) load = 1; else load = 0; if(state == `EMPTY) unload =1; else unload = 0; if(state == `EMPTY && quiet == 0) beep =1; else beep = 0; if(state == `PREHEAT || state == `LOAD || state == `COOK) heat = 1; else heat =0; end