820 likes | 1.01k Views
ECE 551 Digital Design And Synthesis. Lecture 04 Features of Behavioral Verilog. Topics. Flip-flops and direct set/reset (preset/clear) Variable data types Memories Procedural assignments Blocking vs. nonblocking Simulation and the Verilog stratified event queue Interacting behaviors
E N D
ECE 551Digital Design And Synthesis Lecture 04 Features of Behavioral Verilog
Topics • Flip-flops and direct set/reset (preset/clear) • Variable data types • Memories • Procedural assignments • Blocking vs. nonblocking • Simulation and the Verilog stratified event queue • Interacting behaviors • Procedural assignments with delay • Behavioral Control Statements • if/else • case/casex/casez
Flip-Flop Exercise 1 • Implement the following flip-flops: • Basic DFF • DFF with enable input module dff(outputreg Q, input D, clk); endmodule module dffe(outputreg Q, input D, clk, en); endmodule
Flip-Flop Exercise 2 • Implement the following flip-flops: • Synchronous reset: triggered by clock signal • Asynchronous clear: not dependent on clock edge module dff_sync(outputreg Q, input D, clk, rst); endmodule module dff_async(outputreg Q, input D, clk, clr); endmodule
What Happens Here? • clk is edge triggered, but clr is not edge triggered… module dff_BAD(outputreg Q, input D, clk, clr); always @(posedge clk, clr) begin if (clr) Q <= 1’b0; else Q <= D; end endmodule
Topics • Flip-flops and direct set/reset (preset/clear) • Variable data types • Memories • Procedural assignments • Blocking vs. nonblocking • Simulation and the Verilog stratified event queue • Interacting behaviors • Procedural assignments with delay • Behavioral Control Statements • if/else • case/casex/casez
Datatype Categories • Net • Represents a physical wire • Describes structural connectivity • Assigned to in continuous assignment statements • Outputs of primitives and instantiated sub-modules • Variables • Used in behavioral procedural blocks • Depending on how used, can represent either synchronous registers or wires in combinational logic
Variable Datatypes • reg – scalar or vector binary values • integer – 32 or more bits • time – time values represented in 64 bits (unsigned) • real – double precision values in 64 or more bits • realtime - stores time as real (64-bit +) • Assigned value only within a behavioral block • CANNOT USE AS: • Output of primitive gate or instantiated submodule • LHS of continuous assignment • Input or inout port within a module Not necessarily a “register”!!!
Examples Of Variables regsigned [7:0] A_reg; // 8-bit signed vector register reg Reg_Array[7:0]; // array of eight 1-bit registers integer Int_Array[1:100]; // array of 100 integers real B, Real_Array[0:5]; // scalar & array of 6 reals time Time_Array[1:100]; // array of 100 times realtime D, Real_Time[1:5]; // scalar & array of 5 realtimes initial begin A_reg = 8’ha6; // Assigns all eight bits Reg_Array[7] = 1; // Assigns one bit Int_Array[3] = -1; // Assign integer -1 B = 1.23e-4; // Assign real Time_Array[20] = $time; // Assigned by system call D = 1.25; // Assign real time end
wire vs. reg • Same “value” used both as ‘wire’ and as ‘reg’ module dff (q, d, clk); output reg q; // reg declaration, input wire d, clk; // wire declarations, since module inputs always @(posedge clk) q <= d; // why is q reg and d wire? endmodule module t_dff; wire q, clk; // now declared as wire reg d; // now declared as reg dff FF(q, d, clk); // why is d reg and q wire? clockgen myclk(clk); initial begin d = 0; #5 d = 1; end endmodule
Signed vs. Unsigned • Net types and reg variables unsigned by default • Have to declare them as signed if desired!regsigned [7:0] signedreg;wiresigned [3:0] signedwire; • All bit-selects and part-selects are unsigned • A[6], B[5:2], etc. • integer, real, realtime are signed • System calls can force values to be signed or unsigned reg [5:0] A = $unsigned(-4); reg signed [5:0] B = $signed(4’b1101); See the Supplemental Reading for more info
Strings • Strings are stored using properly sized registers reg [12*8: 1] stringvar; // 12 character string, 8 bits/charstringvar = “Hello World”; // string assignment • Uses ASCII values • Unused characters are filled with zeros • Strings can be copied, compared, concatenated • Most common use of strings is in testbenches
Memories & Multi-Dimensional Arrays • A memory is an array of n-bit registers reg [15:0] mem_name [0:127]; // 128 16-bit words reg array_2D [15:0] [0:127]; // 2D array of 1-bit regs • Can only access full word of memory mem_name[122] = 35; // assigns word mem_name[13][5] = 1; // illegal – works in simulation array_2D[122] = 35; // illegal – causes compiler error array_2D[13][5] = 1; // assigns bit • Can use continuous assign to read bitsassign mem_val = mem[13]; // get word in slot 13assign out = mem_val[5]; // get value in bit 5 of wordassign dataout = mem[addr];assign databit = dataout[bitpos];
Array Interfaces – SystemVerilog • Verilog doesn’t support the use of arrays as module ports • SystemVerilog allows multi-dimensional arrays to be used as vectors module(input [7:0] pixel[640:1][480:1], output b);
Example: Memory module memory(output reg [7:0] out, input [7:0] in, input [7:0] addr,input wr, clk, rst); reg [7:0] mem [0:255]; reg [8:0] initaddr; always @ (posedge clk) begin if (rst) begin for (initaddr = 0; initaddr < 256; initaddr = initaddr + 1) begin mem[initaddr] <= 8’d0; end end else if (wr) mem[addr] <= in; end always @(posedge clk) out <= mem[addr]; endmodule
Example: Memory module memory(output reg [7:0] out, input [7:0] in, input [7:0] addr,input wr, clk, rst); reg [7:0] mem [0:255]; reg [8:0] initaddr; always @ (posedge clk) begin if (rst) begin for (initaddr = 0; initaddr < 256; initaddr = initaddr + 1) begin mem[initaddr] <= 8’d0; end end else if (wr) mem[addr] <= in; end always @(posedge clk) out <= mem[addr]; endmodule synchronous reset! synchronous write synchronous read
Topics • Flip-flops and direct set/reset (preset/clear) • Variable data types • Memories • Procedural assignments • Blocking vs. nonblocking • Simulation and the Verilog stratified event queue • Interacting behaviors • Procedural assignments with delay • Behavioral Control Statements • if/else • case/casex/casez
Procedural Assignments • Used within a behavioral block (initial, always) • Types • = // blocking assignment • <= // nonblocking assignment • Assignments to variables: • reg • integer • real • realtime • time
Blocking Assignments • “Evaluated” sequentially • Works a lot like software (danger!) • Used for combinational logic module addtree(output reg [9:0] out, input [7:0] in1, in2, in3, in4); reg [8:0] part1, part2; always @(in1, in2, in3, in4) begin part1 = in1 + in2; part2 = in3 + in4; out = part1 + part2; end endmodule in1 in2 in3 in4 + + part1 part2 + out
Nonblocking Assignments • “Updated” simultaneously if no delays given • Used for sequential logic module swap(output reg out0, out1, input rst, clk); always @(posedge clk) begin if (rst) begin out0 <= 1’b0; out1 <= 1’b1; end else begin out0 <= out1; out1 <= out0; end end endmodule D Q rst to 0 out0 rst clk D Q rst to 1 out1
Swapping – Ugly version • In blocking, sometime use a “temporary” variable module swap(output reg out0, out1, input in0, in1, swap); reg temp; always @(*) begin out0 = in0; out1 = in1; if (swap) begin temp = out0; out0 = out1; out1 = temp; end end endmodule Which values get included on the sensitivity list from *? We can write this module in a better way in0 out0 in1 swap out1
Swapping - Better module swap(output reg out0, out1, input in0, in1, swap); always @(*) begin if (swap) begin out0 = in1; out1 = in0; end else begin out0 = in1; out1 = in0; end end endmodule Easier to do the sensitivity list in this case! in0 out0 in1 swap out1
Blocking & Nonblocking Example • Assume initially that A=1, B=2, C=3, and D=4 • Note: Shouldn’t use blocking when describing sequential logic! Why? reg [7:0] A, B, C, D; always @(posedge clk) begin A = B + C; B = A + D; C = A + B; D = B + D; end reg [7:0] A, B, C, D; always @(posedge clk) begin A <= B + C; B <= A + D; C <= A + B; D <= B + D; end
Blocking & Nonblocking Example • Say we wanted to get the same output as the blocking statement version, but wanted to use non-blocking statements • How can we do it?
Using Non-blocking Statements reg [7:0] A, B, C, D; reg [7:0] newA, newB, newC, newD; always @(posedge clk) begin A <= newA; B <= newB; C <= newC; D <= newD; end always @(*) begin newA = B + C; newB = newA + D; newC = newA + newB; newD = newB + D; end reg [7:0] A, B, C, D; always @(posedge clk) begin A <= B + C; B <= B + C + D; C <= B + C + B + C + D; D <= B + C + D + D; end Depending on the synthesizer, this one may create a lot of hardware!
Why Not ‘=‘ In Sequential Logic? • Yes, it can “work”, but… • Flip-Flops are meant to update simultaneously, not in fixed order • Order of statements is important with = • = make ordering can complicated when using multiple blocks • Easy to describe behavior that is un-synthesizable • Use these style guidelines for better success • <= for sequential blocks • = for combinational blocks • Never mix assignment types in the same block! • Read Cummings SNUG paper for more details • See examples later in lecture
Shift Register: Blocking moduleshiftreg(E, A, clk, rst); output A; input E; inputclk, rst; reg A, B, C, D; always @ (posedgeclkorposedgerst) begin if (rst) begin A = 0; B = 0; C = 0; D = 0; end elsebegin A = B; B = C; C = D; D = E; end // option 1 // elsebegin D = E; C = D; B = C; A = B; end // option 2 end endmodule • What are we describing with each option?
Shift Register: Blocking 2 A E D Q A = B; B = C; C = D; D = E; // option 1 D = E; C = D; B = C; A = B; // option 2 R clk rst the order matters! D C B E A D D D D Q Q Q Q R R R R clk 1 rst
Shift Register: Nonblocking module shiftreg(E, A, clk, rst); output A; input E; input clk, rst; reg A, B, C, D; always @ (posedge clk orposedge rst) begin if (rst) begin A <= 0; B <= 0; C <= 0; D <= 0; end elsebegin A <= B; B <= C; C <= D; D <= E; end // opt. 1 // elsebegin D <= E; C <= D; B <= C; A <= B; end // opt. 2 end endmodule • What do we get with each option?
Shift Register: Nonblocking D C B E A D D D D Q Q Q Q R R R R clk the order doesn’t matter! rst D C B E A D D D D Q Q Q Q R R R R clk rst
Combinational/Sequential Verilog • Can describe many circuits several ways • Even within “good practice”! • Sometimes all equally good • Circuit complexity can affect this choice • Simple circuit • More likely to be able to use 0-2 always blocks • Complex circuit (big FSM, etc) • Can be good to separate comb/seq logic
Multiply-Accumulate [1] module mac(outputreg [15:0] out, input [7:0] a, b, input clk, rst); always @(posedge clk) begin if (rst) out <= 16’d0; else out <= out + (a*b); end endmodule
Multiply-Accumulate [2] module mac(outputreg [15:0] out, input [7:0] a, b, input clk, rst); reg [15:0] product; always @(*) begin product = a * b; end always @(posedge clk) begin if (rst) out <= 16’d0; else out <= out + product; end endmodule
Multiply-Accumulate [3] module mac(outputreg [15:0] out, input [7:0] a, b, input clk, rst); reg [15:0] sum; reg [15:0] product; always @(*) begin product = a * b; sum = product + out; end always @(posedge clk) begin if (rst) out <= 16’d0; else out <= sum; end endmodule
Multiply-Accumulate [4] module mac(outputreg [15:0] out, input [7:0] a, b, input clk, rst); reg [15:0] sum; reg [15:0] product; always @(*) product = a * b; always @(*) sum = product + out; always @(posedge clk) begin if (rst) out <= 16’d0; else out <= sum; end endmodule
Multiply-Accumulate [5] module mac(outputreg [15:0] out, input [7:0] a, b, input clk, rst); wire [15:0] sum; wire [15:0] product; assign product = a * b; assign sum = product + out; always @(posedge clk) begin if (rst) out <= 16’d0; else out <= sum; end endmodule
Topics • Flip-flops and direct set/reset (preset/clear) • Variable data types • Memories • Procedural assignments • Blocking vs. nonblocking • Simulation & Verilog stratified event queue • Interacting behaviors • Procedural assignments with delay • Behavioral Control Statements • if/else • case/casex/casez
Understanding Statement Ordering • In Behavioral Verilog, we describe the behavior of a circuit and the synthesizer creates hardware to try to match that behavior. • The “behavior” is the input/output and timing relationships we see when simulating our HDL. • Therefore, to understand the behavior we are describing, we must understand the our statements will be executed in Simulation • Because the language is designed to express parallelism, the most challenging concept is figuring out the order that Verilog statements will occur in and how this will impact the behavior.
Verilog Stratified Event Queue • Need to be able to model both parallel and sequential logic • Need to make sure simulation matches hardware • Verilog defines how ordering of statements is interpreted by both simulator and synthesis tools • Simulation matches hardware if code well-written • Can have some differences with “bad” code • Simulator is sequential • Hardware is parallel • Race conditions can occur • Important to remember that “making it work” in SIMULATION doesn’t mean it works in SYNTHESIS
Simulation Terminology [1] • These only apply to SIMULATION • Processes • Objects that can be evaluated • Includes primitives, modules, initial and always blocks, continuous assignments, and tasks • Update event • Change in the value of a net or register • Evaluation event • Computing the RHS of a statement and saving the result value for a later Update Event • Scheduling an event • Putting an event on the event queue
Simulation Terminology [2] • Simulation time • Time value used by simulator to model actual time. • Simulation cycle • Complete processing of all currently active events • Can be multiple simulation cycles per simulation time • Explicit zero delay (#0) • Described in detail in SNUG paper • Simulation trick to change order of statements • #0 doesn’t synthesize! Don’t use it.
Determinism vs. Non-Determinism • Standard guarantees some scheduling order • Statements in same begin-end block “executed” in the order in which they appear • Statements in different begin-end blocks in same simulation time have no order guarantee modulerace(outputreg f, input b, c); always @(*) begin f = b & c; end always @(*) begin f = b | c; end endmodule Race condition – which assignment to f will occur first vs. last in simulation is not known Note that in hardware this actually models a SHORT CIRCUIT
Verilog Stratified Event Queue [1] • Region 1: Active Events • Most events except those explicitly in other regions • Includes $display system tasks • Region 2: Inactive Events • Processed after all active events • #0 delay events (evil !) • Region 3: Non-blocking Assignment Update Events • Evaluation previously performed • Update is after all active and inactive events complete • Region 4: Monitor Events • Caused by $monitor and $strobe system tasks • Region 5: Future Events • Occurs at some future simulation time • Includes future events of other regions • Other regions only contain events for CURRENT simulation time
Verilog Stratified Event Queue [2] simulation “race condition” with $display can cause confusion within a Behavioral block, events of the same class are in order Between different blocks events of the same class can occur in any order
Simulation Model Let T be current simulation time while (there are events scheduled at T) { if (no active events) { if (inactive events) activate inactive events else if (n.b. update events) activate n.b. update events else if (monitor events) activate monitor events else { advance T to the next event time activate all inactive events for time T } } // can cause non-determinism! E = next active event in any block, primitive, or continuous assignment; if (E is an update event) { // in y = a | b, the assigning of value to y update the modified object add evaluation events for sensitive processes to the event queue } else { // evaluation event: in y = a | b, the evaluation of a | b evaluate the process add update event(s) for LHS to the event queue } }
How Much Do We Need To Know? • Don’t need to memorize • Exact Simulation model • The process of activating events from a region • Do need to understand • Order statements are evaluated • Whether there is a guaranteed order of evaluation • i.e. cases of non-determinism • Active, Non-Blocking, and Monitor regions • $display vs. $strobe vs. $monitor • Separation of evaluation and update of nonblocking • How this relates to hardware synthesis
Race Conditions assign p = q; initialbegin q = 1; #1 q = 0; $display(p); end • What is displayed? • What if $strobe(p) were used instead?
Understanding Statement Ordering • In Behavioral Verilog, we describe the behavior of a circuit and the synthesizer creates hardware to try to match that behavior. • The “behavior” is the input/output and timing relationships we see when simulating our HDL. • Therefore, to understand the behavior we are describing, we must understand the our statements will be executed in Simulation • Because the language is designed to express parallelism, the most challenging concept is figuring out the order that Verilog statements will occur in and how this will impact the behavior.
Topics • Flip-flops and direct set/reset (preset/clear) • Variable data types • Memories • Procedural assignments • Blocking vs. nonblocking • Simulation & Verilog stratified event queue • Interacting behaviors • Procedural assignments with delay • Behavioral Control Statements • if/else • case/casex/casez
Interacting Behaviors [1] • Assignments can trigger other assignments • Nonblocking assignments (Region 3) CAN trigger blocking assignments (Region 1) • In hardware, reflects that the output of the A flip flop or register can be the input to combinational logic • When the FF changes value, that change must propagate through the combinational logic it feeds into always @ (posedge clk) begin … A <= B; … end always @ (A, C) begin … D = A & C; … end