COMP 211 Computer Logic Design Lecture 6 Verilog

  • Slides: 45
Download presentation
COMP 211 Computer Logic Design Lecture 6. Verilog HDL – Sequential Logic Prof. Taeweon

COMP 211 Computer Logic Design Lecture 6. Verilog HDL – Sequential Logic Prof. Taeweon Suh Computer Science Education Korea University

Sequential Logic • Verilog provides certain syntax, which turns into sequential circuits § In

Sequential Logic • Verilog provides certain syntax, which turns into sequential circuits § In always statements, signals keep their old value until an event in the sensitivity list takes place § Statement inside always is executed only when the event specified in the sensitivity list occurs § Note that always statement could generate combinational logic, depending on your description always @ (sensitivity list) begin statement; … end 2 Korea Univ

D Flip-Flop • As studied, flip-flop samples input at the edge of the clock

D Flip-Flop • As studied, flip-flop samples input at the edge of the clock • Any output assigned in an always statement must be declared reg § always @(posedge clk) samples the input at the rising edge of the clock (clk) § always @(negedge clk) samples the input at the falling edge of the clock (clk) • Note that a variable declared reg is not necessarily to be a registered output • We’ll see it later… • <= or = can be used inside the always statement • • • <= is called nonblocking assignment = is called blocking assignment We are going to discuss about this later module flipflop(input clk, input [3: 0] d, output reg [3: 0] q); always @ (posedge clk) begin q <= d; // pronounced “q gets d” endmodule 3 Korea Univ

D Flip-Flop Simulation testbench module Dflipflop(input clk, input [3: 0] d, output reg [3:

D Flip-Flop Simulation testbench module Dflipflop(input clk, input [3: 0] d, output reg [3: 0] q); `timescale 1 ns / 1 ns module Dflipflop_tb(); reg clock; reg [3: 0] data; wire [3: 0] q; always @(posedge clk) begin q <= d; end parameter clk_period = 10; Dflipflop dut(. clk(clock), . d(data), . q (q) ); endmodule always begin clock = 1; forever #(clk_period/2) clock = ~clock; end initial begin end data data = = = 4'h 0; #3; 4'h 3; #(clk_period*2); 4'h 5; #(clk_period*3); 4'h. A; #(clk_period*3); 4'h. C; #(clk_period*2); endmodule 4 Korea Univ

D Flip-Flop with Sync and Async Reset DFF with Synchronous Reset DFF with Asynchronous

D Flip-Flop with Sync and Async Reset DFF with Synchronous Reset DFF with Asynchronous Reset module ff_sync. R(input clk, input reset, input [3: 0] d, output reg [3: 0] q); module ff_async. R(input clk, input reset, input [3: 0] d, output reg [3: 0] q); // synchronous reset // sensitively list has only clk // asynchronous reset // sensitivity list has both clk and reset always @(posedge clk) begin if (reset) q <= 4'b 0; else q <= d; endmodule always @ (posedge clk, posedge reset) begin if (reset) q <= 4'b 0; else q <= d; endmodule 5 Korea Univ

D Flip-Flop with Sync Reset module ff_sync. R(input clk, input reset, input [3: 0]

D Flip-Flop with Sync Reset module ff_sync. R(input clk, input reset, input [3: 0] d, output reg [3: 0] q); `timescale 1 ns / 1 ns module ff_sync. R_tb( ); reg clk; reg reset; reg [3: 0] d; wire [3: 0] q; // synchronous reset always @(posedge clk) begin if (reset) q <= 4'b 0; else q <= d; end parameter clk_period = 10; ff_sync. R always begin end initial begin endmodule 6 end dut(clk, reset, d, q); clk = 1; forever #(clk_period/2) clk = ~clk; reset reset d d d = = = = = 1; 1; 0; #3; #(clk_period*2); #(clk_period*3); 4'h 0; #3; 4'h 3; #(clk_period*2); 4'h 5; #(clk_period*3); 4'h. A; #(clk_period*3); 4'h. C; #(clk_period*2); Korea Univ

D Flip-Flop with Enable `timescale 1 ns / 1 ns module ff_en(input clk, input

D Flip-Flop with Enable `timescale 1 ns / 1 ns module ff_en(input clk, input reset, input en, input [3: 0] d, output reg [3: 0] q); module ff_en_tb(); reg clk; reg reg [3: 0] d; wire [3: 0] q; reset; en; parameter clk_period = 10; ff_en dut(clk, reset, en, d, q); // asynchronous reset and enable always @(posedge clk, posedge reset) begin if (reset) q <= 4'b 0; else if (en) q <= d; end always begin clk = 1; forever #(clk_period/2) clk = ~clk; end initial begin endmodule initial begin end reset = 1; #3; reset = 1; #(clk_period*2); reset = 0; en en d d d = = = = = 1; #3; 1; #(clk_period*5); 0; #(clk_period); 1; 4'h 0; #3; 4'h 3; #(clk_period*2); 4'h 5; #(clk_period*3); 4'h. A; #(clk_period*3); 4'h. C; #(clk_period*2); endmodule 7 Korea Univ

D Latch • As studied, a D-latch is • transparent when the clock is

D Latch • As studied, a D-latch is • transparent when the clock is high • opaque when the clock is low (retaining its old value) • Try to avoid using latches unless you have a good reason to use them because latches may transfer unwanted input to output like glitches • Instead, use flip-flops module latch(input clk, input [3: 0] d, output reg [3: 0] q); always @ (clk, d) begin if (clk) q <= d; endmodule 8 Korea Univ

D Latch Simulation `timescale 1 ns / 1 ns module latch(input clk, input [3:

D Latch Simulation `timescale 1 ns / 1 ns module latch(input clk, input [3: 0] d, output reg [3: 0] q); module latch_tb( ); reg clk; reg [3: 0] d; wire [3: 0] q; always @(clk, d) begin if (clk) q <= d; end parameter clk_period = 10; latch_dut(clk, d, q); always begin clk = 1; forever #(clk_period/2) clk = ~clk; endmodule initial begin end d d = = = = = 4'h 0; #3; 4'h 3; #(clk_period*2); 4'h 4; #(clk_period/5); 4'h 5; #(clk_period/5); 4'h 6; #(clk_period/5); 4'h 7; #(clk_period/5); 4'h 8; #(clk_period/5); 4'h 9; #(clk_period*3); 4'h. A; #(clk_period*3); 4'h. C; #(clk_period*2); endmodule 9 Korea Univ

Useful Behavioral Statements • Keywords that must be inside always statements § if /

Useful Behavioral Statements • Keywords that must be inside always statements § if / else § case, casez • Again, variables assigned in an always statement must be declared as reg even if they’re not actually intended to be registers § In other words, all signals on the left side of <= and = inside always should be declared as reg 10 Korea Univ

Combinational Logic using always • The always statement can also describe combinational logic (not

Combinational Logic using always • The always statement can also describe combinational logic (not generating flip-flops) // combinational logic using an always statement module gates(input [3: 0] a, b, output reg [3: 0] y 1, y 2, y 3, y 4, y 5); always @ begin y 1 = y 2 = y 3 = y 4 = y 5 = end (*) a & a | a ^ ~(a // // b; // & b); // | b); // need begin/end because there is more than one statement in always AND OR XOR NAND NOR endmodule This hardware could be described with assign statements using fewer lines of code, so it’s better to use assign statements in this case. 11 Korea Univ

Combinational Logic using case module sevenseg(input [3: 0] data, output reg [6: 0] segments);

Combinational Logic using case module sevenseg(input [3: 0] data, output reg [6: 0] segments); always @(*) begin case (data) // abc_defg 0: segments = 7'b 111_1110; 1: segments = 7'b 011_0000; 2: segments = 7'b 110_1101; 3: segments = 7'b 111_1001; 4: segments = 7'b 011_0011; 5: segments = 7'b 101_1011; 6: segments = 7'b 101_1111; 7: segments = 7'b 111_0000; 8: segments = 7'b 111_1111; 9: segments = 7'b 111_1011; default: segments <= 7'b 000_0000; // required endcase endmodule What kind of circuit would it generate? 12 Korea Univ

Combinational Logic using case • In order for a case statement to imply combinational

Combinational Logic using case • In order for a case statement to imply combinational logic, all possible input combinations must be described by the HDL § Remember to use a default statement when necessary, that is, when all the possible combinations are not listed in the body of the case statement § Otherwise, what kind of circuit do you think the statement would generate? 13 Korea Univ

Combinational Logic using casez • The casez statement is used to describe truth tables

Combinational Logic using casez • The casez statement is used to describe truth tables with don’t cares § ‘don’t cares’ are indicated with ? in the casez statement module priority_casez(input [3: 0] a, output reg [3: 0] y); always @(*) begin casez(a) 4'b 1? ? ? : 4'b 01? ? : 4'b 001? : 4'b 0001: default: endcase end y y y = = = 4'b 1000; 4'b 0100; 4'b 0010; 4'b 0001; 4'b 0000; // ? = don’t care endmodule 14 Korea Univ

Priority Circuit Simulation module priority_casez(input [3: 0] a, output reg [3: 0] y); always

Priority Circuit Simulation module priority_casez(input [3: 0] a, output reg [3: 0] y); always @(*) begin casez(a) 4'b 1? ? ? : 4'b 01? ? : 4'b 001? : 4'b 0001: default: endcase end y y y = = = 4'b 1000; 4'b 0100; 4'b 0010; 4'b 0001; 4'b 0000; `timescale 1 ns / 1 ns module priority_casez_tb(); reg [3: 0] a; wire [3: 0] y; parameter clk_period = 10; priority_casez initial begin a = a = a = endmodule 4'b 0110; 4'b 1110; 4'b 0101; 4'b 0011; 4'b 0000; dut(a, y); #(clk_period*2); #(clk_period*2); endmodule 15 Korea Univ

Parameterized Modules • HDLs permit variable bit widths using parameterized modules § So far,

Parameterized Modules • HDLs permit variable bit widths using parameterized modules § So far, all of our modules have had fixed-width inputs and outputs § Verilog allows a #(parameter …)statement to define parameters before the inputs and outputs module mux 2 #(parameter width = 8) // name and default value (input [width-1: 0] d 0, d 1, input s, output [width-1: 0] y); assign y = s ? d 1 : d 0; endmodule Instance with 8 -bit bus width (uses default): mux 2 mux 1(d 0, d 1, s, out); Instance with 12 -bit bus width: mux 2 #(12) lowmux(d 0, d 1, s, out); 16 Korea Univ

Blocking and Nonblocking Statements • In the always statement, § = indicates blocking statement

Blocking and Nonblocking Statements • In the always statement, § = indicates blocking statement § <= indicates nonblocking statement • Blocking statements are evaluated in the order in which they appear in the code § Like one would expect in a standard programming language such as C language • Nonblocking statements are evaluated concurrently § All of the statements are evaluated concurrently before any of the signals on the left hand sides are updated 17 Korea Univ

Blocking vs Nonblocking Example • What kinds of circuit would be generated? module sync_nonblocking

Blocking vs Nonblocking Example • What kinds of circuit would be generated? module sync_nonblocking (input clk, input d, output reg q); module sync_blocking (input clk, input d, output reg q); reg n 1; always @(posedge clk) begin n 1 <= d; // nonblocking q <= n 1; // nonblocking end always @(posedge clk) begin n 1 = d; // blocking q = n 1; // blocking endmodule 18 Korea Univ

Blocking vs Nonblocking Example 1 -bit full adder S = A + B +

Blocking vs Nonblocking Example 1 -bit full adder S = A + B + Cin Cout = AB + ACin + BCin Let P = A + B Let G = AB S = P + Cin Cout = AB + (A + B)Cin = G + PCin 19 Korea Univ

Full Adder with Blocking Statements module fulladder(input a, b, cin, output reg s, cout);

Full Adder with Blocking Statements module fulladder(input a, b, cin, output reg s, cout); reg p, g; always @(*) begin p = a ^ b; g = a & b; // blocking s = p ^ cin; // blocking cout = g | (p & cin); // blocking endmodule • Like a high-level language, the blocking statements are evaluated in the order they appear in the body of the module § Suppose that all the inputs and internal nodes are initially 0 § At some time later, a changes to 1 1. 2. 3. 4. p ← 1^0 =1 g ← 1 • 0 =0 s ← 1^0 =1 cout ← 0 + 1 • 0 = 0 20 Korea Univ

Full Adder with Nonblocking Statements module fulladder(input a, b, cin, output reg s, cout);

Full Adder with Nonblocking Statements module fulladder(input a, b, cin, output reg s, cout); reg p, g; always @(*) begin p <= a ^ b; g <= a & b; // nonblocking s <= p ^ cin; // nonblocking cout <= g | (p & cin); // nonblocking endmodule • Nonblocking statements are evaluated concurrently § Suppose that all the inputs and internal nodes are initially 0 § At some time later, a changes to 1 1. 2. • • p ← 1 ^ 0 = 1, g ← 1 • 0 = 0, s ← 0 ^ 0 = 0, cout ← 0 + 0 • 0 = 0 s ← 1 ^ 0 = 1, cout ← 0 + 1 • 0 = 0 It makes simulation slow though it synthesizes to the same hardware Also kind of hard to figure out what the circuit is doing… This kinds of coding should be avoided 21 Korea Univ

Blocking and Nonblocking Recap • Some statements implies (generates) completely different logic as shown

Blocking and Nonblocking Recap • Some statements implies (generates) completely different logic as shown in the flip-flop case • Some statements implies (generates) the same logic no matter which statement you use as we have seen in the full-adder case § But, it affects the simulation time • So, choose wisely which statement you have to use 22 Korea Univ

Rules for Signal Assignment • Use always @(posedge clk) and nonblocking assignments to model

Rules for Signal Assignment • Use always @(posedge clk) and nonblocking assignments to model synchronous sequential logic always @(posedge clk) q <= d; // nonblocking statement • Use continuous assignment statements to model simple combinational logic assign y = a & b; • Use always @(*) and blocking assignments to model more complicated combinational logic where the always statement is helpful • Do not make assignments to the same signal in more than one always statement or continuous assignment statement 23 Korea Univ

FSM Revisit • Synchronous sequential circuit can be drawn like below § These are

FSM Revisit • Synchronous sequential circuit can be drawn like below § These are called FSMs § Super-important in digital circuit design and very straightforward to understand • FSM is composed of § State register § Combinational logic that • Computes the next state based on current state and input • Computes the outputs based on current state (and input) 24 Korea Univ

Traffic Light Revisit • A simplified traffic light controller § Traffic sensors: TA, TB

Traffic Light Revisit • A simplified traffic light controller § Traffic sensors: TA, TB • Each sensor becomes TRUE if students are present • Each sensor becomes FALSE if the street is empty § Lights: LA, LB • Each light receives digital inputs specifying whether it should be green, yellow, or red 25 Korea Univ

Moore FSM in Verilog // next state logic always @ (*) case (state) S

Moore FSM in Verilog // next state logic always @ (*) case (state) S 0: if (~TA) nextstate else nextstate S 1: nextstate <= S 2; S 2: if (~TB) nextstate else nextstate S 3: nextstate default: nextstate endcase [1: 0] state, nextstate; parameter S 0 S 1 S 2 S 3 = = <= <= S 3; S 2; S 0; // output logic always @ (*) if (state == S 0) begin LA = green; LB = red; end else if (state == S 1) begin LA = yellow; LB = red; end else if (state == S 2) begin LA = red; LB = green; end else begin LA = red; LB = yellow; end module moore_traffic_light (input clk, reset, TA, TB, output reg [1: 0] LA, LB); reg <= S 1; <= S 0; 2’b 00; 2’b 01; 2’b 10; 2’b 11; parameter green = 2’b 00; parameter yellow = 2’b 01; parameter red = 2’b 10; // state register always @ (posedge clk, posedge reset) if (reset) state <= S 0; else state <= nextstate; endmodule 26 Korea Univ

Testbench for Traffic Light FSM `timescale 1 ns/1 ps always begin clk = 1;

Testbench for Traffic Light FSM `timescale 1 ns/1 ps always begin clk = 1; forever #(clk_period/2) clk = ~clk; end module moore_traffic_light_tb(); reg clk, reset; reg TA, TB; wire [1: 0] LA, LB; initial begin TA = TA = end parameter clk_period = 10; moore_traffic_light dut(. clk (clk), . reset (reset), . TA (TA), . TB (TB), . LA (LA), . LB (LB) ); 0; 0; 1; TB TB TB = = = 0; 0; 1; 1; 0; 0; #3 #(clk_period) #(clk_period*5) #(clk_period*4) endmodule initial begin reset = 1; #13 reset = 0; end 27 Korea Univ

Simulation with Model. Sim • Useful tips in using Model. Sim § To display

Simulation with Model. Sim • Useful tips in using Model. Sim § To display state information as described in Verilog code • Format: radix define name { …. } • Example: radix define mystate {2’b 00 “S 0” , 2’b 01 “S 1” , 2’b 10 “S 2” , 2’b 11 “S 3”} • radix define mylight {2'b 00 "green“ , 2'b 01 "yellow“ , 2'b 10 "red"} § Save the display information for the use in the future • File->Save Format, Then click on “OK” • By default, it will save the waveformat to “wave. do” 28 Korea Univ

Snail FSM Revisit • There is a snail § The snail crawls down a

Snail FSM Revisit • There is a snail § The snail crawls down a paper tape with 1’s and 0’s on it § The snail smiles whenever the last four digits it has crawled over are 1101 Moore FSM: arcs indicate input reset 0 1 S 0 0 1 1 S 1 0 0 0 S 2 0 1 1 S 3 0 S 4 1 0 0 Mealy FSM: arcs indicate input/output reset 1/0 S 1 S 0 0/0 1/1 0/0 S 2 1/0 29 S 3 0/0 Korea Univ

Moore FSM in Verilog Moore FSM: arcs indicate input 1 reset 1 0 S

Moore FSM in Verilog Moore FSM: arcs indicate input 1 reset 1 0 S 0 0 0 1 S 1 0 S 2 0 1 S 3 0 S 4 1 // Next State Logic always @(*) begin case (state) S 0: if (bnum) #delay nextstate <= S 1; else #delay nextstate <= S 0; S 1: if (bnum) #delay nextstate <= S 2; else #delay nextstate <= S 0; 0 0 S 2: if (bnum) #delay nextstate <= S 2; else #delay nextstate <= S 3; module moore_snail(input clk, reset, bnum, output reg smile); S 3: if (bnum) #delay nextstate <= S 4; else #delay nextstate <= S 0; reg [2: 0] state, nextstate; parameter parameter S 0 S 1 S 2 S 3 S 4 = = = S 4: if (bnum) #delay nextstate <= S 2; else #delay nextstate <= S 0; 3'b 000; 3'b 001; 3'b 010; 3'b 011; 3'b 100; parameter delay = 1; // state register always @(posedge reset, posedge clk) begin if (reset) #delay state <= S 0; else #delay state <= nextstate; end default: endcase #delay nextstate <= S 0; end // Output Logic always @(*) begin if (state == S 4) smile <= 1'b 1 ; else smile <= 1'b 0 ; endmodule 30 Korea Univ

Mealy FSM in Verilog // Next State and Output Logic always @(*) begin case

Mealy FSM in Verilog // Next State and Output Logic always @(*) begin case (state) S 0: begin #delay smile <= 1'b 0; if (bnum) #delay nextstate <= S 1; else #delay nextstate <= S 0; end Mealy FSM: arcs indicate input/output 1/1 reset 1/0 S 1 S 0 0/0 0/0 S 2 1/0 module mealy_snail(input output reg S 3 S 1: begin #delay smile <= 1'b 0; if (bnum) #delay nextstate <= S 2; else #delay nextstate <= S 0; end 0/0 S 2: begin #delay smile <= 1'b 0; if (bnum) #delay nextstate <= S 2; else #delay nextstate <= S 3; end clk, reset, bnum, smile); reg [1: 0] state, nextstate; parameter S 0 S 1 S 2 S 3 = = 2'b 00; 2'b 01; 2'b 10; 2'b 11; S 3: begin if (bnum) else end parameter delay = 1; // state register always @(posedge reset, posedge clk) begin if (reset) #delay state <= S 0; else #delay state <= nextstate; #delay smile <= 1'b 1; smile <= 1'b 0; nextstate <= S 1; nextstate <= S 0; default: begin #delay smile <= 1'b 0; #delay nextstate <= S 0; endcase end endmodule 31 Korea Univ

Testbench for Snail FSM initial begin bnum bnum bnum bnum end `timescale 1 ns/1

Testbench for Snail FSM initial begin bnum bnum bnum bnum end `timescale 1 ns/1 ps module fsm_snail_tb( ); reg clk, reset, bnum; wire smile_moore; wire smile_mealy; parameter clk_period = 10; moore_snail_uut (clk, reset, bnum, smile_moore); mealy_snail_uut (clk, reset, bnum, smile_mealy); initial begin reset = 1; #13 reset = 0; end = = = = 0; 0; 1; 0; 0; 0; 1; 1; 0; #3; #clk_period; #clk_period; #clk_period; // Smile endmodule always begin clk = 1; forever #(clk_period/2) clk = ~clk; end 32 Korea Univ

Simulation with Model. Sim • Use radices below for display purpose § radix define

Simulation with Model. Sim • Use radices below for display purpose § radix define moore_state {3'b 000 "S 0” , 3'b 001 "S 1” , 3'b 010 "S 2” , 3'b 011 "S 3” , 3'b 100 "S 4"} § radix define mealy_state {2'b 00 "S 0” , 2'b 01 "S 1” , 2'b 10 "S 2” , 2'b 11 "S 3"} 33 Korea Univ

Testbench and Test. Vector • Testbench § HDL code written to test another HDL

Testbench and Test. Vector • Testbench § HDL code written to test another HDL module, the device under test (dut) (also called the unit under test (uut)) § Testbench contains statements to apply input to the DUT and ideally to check the correct outputs are produced • Testvectors § Inputs to DUT and desired output patterns from DUT • Types of testbenches § Simple testbench § Self-checking testbench with testvectors 34 Korea Univ

Simple Testbench Revisit testbench module sillyfunction (input a, b, c, output y); assign y

Simple Testbench Revisit testbench module sillyfunction (input a, b, c, output y); assign y = ~a & ~b & ~c | a & ~b & c; endmodule testvectors `timescale 1 ns/1 ps module testbench 1(); reg a, b, c; wire y; // instantiate device under test sillyfunction dut(a, b, c, y); // apply inputs initial begin a = 0; b = 0; c = 1; #10; b = 1; c = 0; c = 1; #10; a = 1; b = 0; c = 1; #10; b = 1; c = 0; c = 1; #10; end one at a time c = 0; #10; endmodule 35 Korea Univ

Self-checking Testbench Revisit module testbench 2(); reg a, b, c; wire y; a =

Self-checking Testbench Revisit module testbench 2(); reg a, b, c; wire y; a = 1; b = 0; c = 0; #10; if (y !== 1) $display("100 c = 1; #10; if (y !== 1) $display("101 b = 1; c = 0; #10; if (y !== 0) $display("110 c = 1; #10; if (y !== 0) $display("111 end // instantiate device under test sillyfunction dut(a, b, c, y); // apply inputs one at a time // checking results initial begin a = 0; b = 0; c = 0; #10; if (y !== 1) $display("000 failed. "); c = 1; #10; if (y !== 0) $display("001 failed. "); b = 1; c = 0; #10; if (y !== 0) $display("010 failed. "); c = 1; #10; if (y !== 0) $display("011 failed. "); endmodule testvectors 36 Korea Univ

Self-Checking Testbench with Testvectors • Writing code for each test vector is tedious, especially

Self-Checking Testbench with Testvectors • Writing code for each test vector is tedious, especially for modules that require a large number of vectors • A better approach is to place the test vectors in a separate file • Then, testbench reads the file, applies input to DUT and compares the DUT’s outputs with expected outputs 1. 2. 3. 4. Generate clock for assigning inputs, reading outputs Read testvectors file into array Assign inputs and expected outputs to signals Compare outputs to expected outputs and report errors if there is discrepancy 37 Korea Univ

Testbench with Testvectors • Testbench clock is used to assign inputs (on the rising

Testbench with Testvectors • Testbench clock is used to assign inputs (on the rising edge) and compare outputs with expected outputs (on the falling edge) • The testbench clock may also be used as the clock source for synchronous sequential circuits 38 Korea Univ

Testvector File Example example. tv contains vectors of abc_yexpected 000_1 001_0 010_0 011_0 100_1

Testvector File Example example. tv contains vectors of abc_yexpected 000_1 001_0 010_0 011_0 100_1 101_1 110_0 111_0 module sillyfunction(input a, b, c, output y); assign y = ~a & ~b & ~c | a & ~b & c; endmodule 39 Korea Univ

Self-Checking Testbench with Testvectors 1. Generate clock for assigning inputs, reading outputs 2. Read

Self-Checking Testbench with Testvectors 1. Generate clock for assigning inputs, reading outputs 2. Read testvectors file into array 3. Assign inputs and expected outputs to signals module testbench 3(); reg clk, reset; reg a, b, c, yexpected; wire y; reg [31: 0] vectornum, errors; reg [3: 0] testvectors[10000: 0]; // array of testvectors // instantiate device under test sillyfunction dut(a, b, c, y); // generate clock always begin clk = 1; #5; clk = 0; #5; end // at start of test, load vectors // and pulse reset initial begin $readmemb("example. tv", testvectors); vectornum = 0; errors = 0; reset = 1; #27; reset = 0; end // Note: $readmemh reads testvector files written in // hexadecimal // apply test vectors on rising edge of clk always @(posedge clk) begin #1; {a, b, c, yexpected} = testvectors[vectornum]; end 40 Korea Univ

Self-Checking Testbench with Testvectors 4. Compare outputs to expected outputs and report errors if

Self-Checking Testbench with Testvectors 4. Compare outputs to expected outputs and report errors if there is discrepancy // check results on falling edge of clk always @(negedge clk) begin if (~reset) begin // skip during reset if (y !== yexpected) begin $display("Error: inputs = %b“, {a, b, c}); $display(" outputs = %b (%b expected)“, y, yexpected); errors = errors + 1; end // increment array index and read next testvectornum = vectornum + 1; if (testvectors[vectornum] === 4'bx) begin $display("%d tests completed with %d errors“, vectornum, errors); $finish; end endmodule // Note: “===“ and “!==“ can compare values that are x or z. 41 Korea Univ

HDL Summary • HDLs are extremely important tools for modern digital designers § Once

HDL Summary • HDLs are extremely important tools for modern digital designers § Once you have learned Verilog-HDL or VHDL, you will be able to design digital systems much faster than drawing schematics § Debug cycle is also often much faster because modifications require code changes instead of tedious schematic rewriting § However, the debug cycle can be much longer with HDLs if you don’t have a good idea of the hardware your code implies 42 Korea Univ

HDL Summary • The most important thing to remember when you are writing HDL

HDL Summary • The most important thing to remember when you are writing HDL code is that you are describing real hardware! (not writing a software program) • The most common beginner’s mistake is to write HDL code without thinking about the hardware you intend to produce § If you don’t know what hardware your code is implying, you are almost certain not to get what you want § So, probably sketch a block diagram of your system • Identify which portions are combinational logic, sequential logic, FSMs and so on, so forth • Write HDL code for each portion and then merge together 43 Korea Univ

Backup Slides 44 Korea Univ

Backup Slides 44 Korea Univ

N: 2 N Decoder Example module decoder #(parameter (input output reg N = 3)

N: 2 N Decoder Example module decoder #(parameter (input output reg N = 3) [N-1: 0] a, [2**N-1: 0] y); always @(*) begin y = 0; y[a] = 1; endmodule 45 Korea Univ