lecture 6. verilog hdl – sequential logic

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

Upload: rana-phelps

Post on 01-Jan-2016

125 views

Category:

Documents


4 download

DESCRIPTION

COMP211 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 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Lecture 6. Verilog HDL – Sequential Logic

Lecture 6. Verilog HDL – Sequential Logic

Prof. Taeweon SuhComputer Science Education

Korea University

COMP211 Computer Logic Design

Page 2: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

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

2

always @ (sensitivity list)

begin

statement;

statement;

end

Page 3: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

D Flip-Flop

• As studied, flip-flop samples input at the edge of the clock 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)

• Any output assigned in an always statement must be declared reg• 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

3

module flipflop(input clk, input [3:0] d, output reg [3:0] q);

always @ (posedge clk) begin q <= d; // pronounced “q gets d” end

endmodule

Page 4: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

D Flip-Flop Simulation

4

`timescale 1ns / 1ns

module Dflipflop_tb();

reg clock; reg [3:0] data; wire [3:0] q;

parameter clk_period = 10;

Dflipflop dut(.clk(clock), .d(data), .q (q) );

always begin clock = 1;

forever #(clk_period/2) clock = ~clock;

end

initial begin data = 4'h0; #3; data = 4'h3; #(clk_period*2); data = 4'h5; #(clk_period*3); data = 4'hA; #(clk_period*3); data = 4'hC; #(clk_period*2); end

endmodule

module Dflipflop(input clk, input [3:0] d, output reg [3:0] q);

always @(posedge clk) begin q <= d; end

endmodule

testbench

Page 5: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

D Flip-Flop with Sync and Async Reset

5

module ff_asyncR(input clk, input reset, input [3:0] d, output reg [3:0] q); // asynchronous reset// sensitivity list has both clk and reset

always @ (posedge clk, posedge reset) begin if (reset) q <= 4'b0; else q <= d; end

endmodule

module ff_syncR(input clk, input reset, input [3:0] d, output reg [3:0] q);

// synchronous reset// sensitively list has only clk

always @(posedge clk) begin if (reset) q <= 4'b0; else q <= d; end

endmodule

DFF with Synchronous Reset

DFF with Asynchronous Reset

Page 6: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

D Flip-Flop with Sync Reset

6

module ff_syncR(input clk, input reset, input [3:0] d, output reg [3:0] q);

// synchronous reset always @(posedge clk) begin if (reset) q <= 4'b0; else q <= d; end

endmodule

`timescale 1ns / 1ns

module ff_syncR_tb( ); reg clk; reg reset; reg [3:0] d; wire [3:0] q;

parameter clk_period = 10;

ff_syncR dut(clk, reset, d, q);

always begin

clk = 1; forever #(clk_period/2) clk =

~clk; end

initial begin

reset = 1; #3;reset = 1; #(clk_period*2);reset = 0; #(clk_period*3);reset = 1; #(clk_period*2);reset = 0; #(clk_period*3);

end

initial begin d = 4'h0; #3;

d = 4'h3; #(clk_period*2);d = 4'h5; #(clk_period*3);d = 4'hA; #(clk_period*3);d = 4'hC; #(clk_period*2);

endendmodule

Page 7: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

D Flip-Flop with Enable

7

module ff_en(input clk, input reset, input en, input [3:0] d, output reg [3:0] q);

// asynchronous reset and enable always @(posedge clk, posedge reset) begin if (reset) q <= 4'b0; else if (en) q <= d; end

endmodule

`timescale 1ns / 1ns

module ff_en_tb(); reg clk; reg reset; reg en; reg [3:0] d; wire [3:0] q;

parameter clk_period = 10;

ff_en dut(clk, reset, en, d, q);

always begin clk = 1; forever #(clk_period/2) clk = ~clk; end

initial begin reset = 1; #3; reset = 1; #(clk_period*2); reset = 0; end

initial begin en = 1; #3; en = 1; #(clk_period*5); en = 0; #(clk_period); en = 1; end

initial begin d = 4'h0; #3; d = 4'h3; #(clk_period*2); d = 4'h5; #(clk_period*3); d = 4'hA; #(clk_period*3); d = 4'hC; #(clk_period*2); end

endmodule

Page 8: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

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

8

module latch(input clk, input [3:0] d, output reg [3:0] q);

always @ (clk, d) begin if (clk) q <= d; end

endmodule

Page 9: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

D Latch Simulation

9

`timescale 1ns / 1ns

module latch_tb( ); reg clk; reg [3:0] d; wire [3:0] q;

parameter clk_period = 10;

latch latch_dut(clk, d, q);

always begin clk = 1; forever #(clk_period/2) clk = ~clk; end

initial begin d = 4'h0; #3; d = 4'h3; #(clk_period*2); d = 4'h4; #(clk_period/5); d = 4'h5; #(clk_period/5); d = 4'h6; #(clk_period/5); d = 4'h7; #(clk_period/5); d = 4'h8; #(clk_period/5); d = 4'h9; #(clk_period*3); d = 4'hA; #(clk_period*3); d = 4'hC; #(clk_period*2); end

endmodule

module latch(input clk, input [3:0] d, output reg [3:0] q);

always @(clk, d) begin if (clk) q <= d; end

endmodule

Page 10: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

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

Page 11: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Combinational Logic using always

• The always statement can also describe combinational logic (not generating flip-flops)

11

// combinational logic using an always statementmodule gates(input [3:0] a, b, output reg [3:0] y1, y2, y3, y4, y5);

always @ (*) // need begin/end because there is begin // more than one statement in always y1 = a & b; // AND y2 = a | b; // OR y3 = a ^ b; // XOR y4 = ~(a & b); // NAND y5 = ~(a | b); // NOR end

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.

Page 12: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Combinational Logic using case

12

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

always @(*) begin case (data) // abc_defg 0: segments = 7'b111_1110; 1: segments = 7'b011_0000; 2: segments = 7'b110_1101; 3: segments = 7'b111_1001; 4: segments = 7'b011_0011; 5: segments = 7'b101_1011; 6: segments = 7'b101_1111; 7: segments = 7'b111_0000; 8: segments = 7'b111_1111; 9: segments = 7'b111_1011; default: segments <= 7'b000_0000; // required endcase end

endmodule

What kind of circuit would it generate?

Page 13: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

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

Page 14: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

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

14

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

always @(*) begin casez(a) 4'b1???: y = 4'b1000; // ? = don’t care 4'b01??: y = 4'b0100; 4'b001?: y = 4'b0010; 4'b0001: y = 4'b0001; default: y = 4'b0000; endcase end

endmodule

Page 15: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Priority Circuit Simulation

15

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

always @(*) begin casez(a) 4'b1???: y = 4'b1000; 4'b01??: y = 4'b0100; 4'b001?: y = 4'b0010; 4'b0001: y = 4'b0001; default: y = 4'b0000; endcase end

endmodule

`timescale 1ns / 1ns

module priority_casez_tb(); reg [3:0] a; wire [3:0] y;

parameter clk_period = 10;

priority_casez dut(a, y);

initial begin a = 4'b0110; #(clk_period*2); a = 4'b1110; #(clk_period*2); a = 4'b0101; #(clk_period*2); a = 4'b0011; #(clk_period*2); a = 4'b0001; #(clk_period*2); a = 4'b0000; #(clk_period*2); end

endmodule

Page 16: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

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

16

module mux2 #(parameter width = 8) // name and default value (input [width-1:0] d0, d1, input s, output [width-1:0] y); assign y = s ? d1 : d0; endmodule

Instance with 8-bit bus width (uses default): mux2 mux1(d0, d1, s, out);

Instance with 12-bit bus width: mux2 #(12) lowmux(d0, d1, s, out);

Page 17: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

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

Page 18: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Blocking vs Nonblocking Example

18

module sync_nonblocking (input clk, input d, output reg q);

reg n1;

always @(posedge clk) begin n1 <= d; // nonblocking q <= n1; // nonblocking end

endmodule

module sync_blocking (input clk,

input d, output reg q);

reg n1;

always @(posedge clk) begin n1 = d; // blocking q = n1; // blocking end

endmodule

• What kinds of circuit would be generated?

Page 19: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Blocking vs Nonblocking Example

19

1-bit full adder

Cout = AB + (A + B)Cin= G + PCin

+S = A B Cin

Cout = AB + ACin + BCin

+

Let P = A BLet G = AB

+

S = P Cin+

Page 20: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Full Adder with Blocking Statements

20

• 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. p ← 1 ^ 0 = 12. g ← 1 • 0 = 03. s ← 1 ^ 0 = 14. cout ← 0 + 1 • 0 =

0

module fulladder(input a, b, cin, output reg s, cout); reg p, g;

always @(*) begin p = a ^ b; // blocking g = a & b; // blocking

s = p ^ cin; // blocking cout = g | (p & cin); // blocking end

endmodule

Page 21: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Full Adder with Nonblocking Statements

21

• Nonblocking statements are evaluated concurrently Suppose that all the inputs and internal nodes are initially 0 At some time later, a changes to 1

module fulladder(input a, b, cin, output reg s, cout);

reg p, g;

always @(*) begin p <= a ^ b; // nonblocking g <= a & b; // nonblocking

s <= p ^ cin; // nonblocking cout <= g | (p & cin); // nonblocking end

endmodule

1. p ← 1 ^ 0 = 1, g ← 1 • 0 = 0, s ← 0 ^ 0 = 0, cout ← 0 + 0 • 0 = 02. p ← 1 ^ 0 = 1, g ← 1 • 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

Page 22: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

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

Page 23: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

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

Page 24: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

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

CLKM Nk knext

statelogic

outputlogic

Moore FSM

CLKM Nk knext

statelogic

outputlogic

inputs

inputs

outputs

outputsstate

statenextstate

nextstate

Mealy FSM

Page 25: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Traffic Light Revisit

25

S0LA: greenLB: red

S1LA: yellowLB: red

S3LA: redLB: yellow

S2LA: redLB: green

TATA

TB

TB

Reset

TA

LA

TA

LB

TB

TB

LA

LB

Academic Ave.

Bravad

oB

lvd.

Dorms

Fields

DiningHall

Labs

• 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

Page 26: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Moore FSM in Verilog

26

S0LA: greenLB: red

S1LA: yellowLB: red

S3LA: redLB: yellow

S2LA: redLB: green

TATA

TB

TB

Reset // next state logic always @ (*) case (state) S0: if (~TA) nextstate <= S1; else nextstate <= S0; S1: nextstate <= S2; S2: if (~TB) nextstate <= S3; else nextstate <= S2; S3: nextstate <= S0; default: nextstate <= S0; endcase

// output logic always @ (*) if (state == S0) begin LA = green; LB = red; end else if (state == S1) begin LA = yellow; LB = red; end else if (state == S2) begin LA = red; LB = green; end else begin LA = red; LB = yellow; end

endmodule

module moore_traffic_light (input clk, reset, TA, TB, output reg [1:0] LA, LB);

reg [1:0] state, nextstate;

parameter S0 = 2’b00; parameter S1 = 2’b01; parameter S2 = 2’b10; parameter S3 = 2’b11;

parameter green = 2’b00; parameter yellow = 2’b01; parameter red = 2’b10;

// state register always @ (posedge clk, posedge reset) if (reset) state <= S0; else state <= nextstate;

Page 27: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Testbench for Traffic Light FSM

27

`timescale 1ns/1ps

module moore_traffic_light_tb(); reg clk, reset; reg TA, TB; wire [1:0] LA, LB;

parameter clk_period = 10;

moore_traffic_light dut(.clk (clk), .reset (reset), .TA (TA), .TB (TB), .LA (LA), .LB (LB) );

initial begin reset = 1; #13 reset = 0; end

always begin clk = 1; forever #(clk_period/2) clk = ~clk; end

initial begin TA = 0; TB = 0; #3 TA = 0; TB = 0; #(clk_period) TA = 1; TB = 1; #(clk_period*5) TA = 0; TB = 1; #(clk_period*4) TA = 0; TB = 0; #(clk_period*4) TA = 1; TB = 0; end

endmodule

Page 28: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Simulation with ModelSim

• Useful tips in using ModelSim To display state information as described in Verilog code

• Format: radix define name { …. }• Example: radix define mystate {2’b00 “S0” , 2’b01 “S1” , 2’b10 “S2” , 2’b11

“S3”}• radix define mylight {2'b00 "green“ , 2'b01 "yellow“ , 2'b10 "red"}

Save the display information for the use in the future• File->Save Format, Then click on “OK”• By default, it will save the waveform format to “wave.do”

28

Page 29: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

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

29

Moore FSM: arcs indicate input

S00

reset

S10

1

0 0

S20

1

1

S30

0

0

S41

1

1

0

Mealy FSM: arcs indicate input/output

S0

reset

S1

1/0

0/0 0/0S2

1/0

1/0

S3

0/0

1/1

0/0

Page 30: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Moore FSM in Verilog

30

module moore_snail(input clk, reset, bnum, output reg smile);

reg [2:0] state, nextstate;

parameter S0 = 3'b000; parameter S1 = 3'b001; parameter S2 = 3'b010; parameter S3 = 3'b011; parameter S4 = 3'b100;

parameter delay = 1;

// state register always @(posedge reset, posedge clk) begin if (reset) #delay state <= S0; else #delay state <= nextstate; end

// Next State Logicalways @(*)begin case (state) S0: if (bnum) #delay nextstate <= S1; else #delay nextstate <= S0; S1: if (bnum) #delay nextstate <= S2; else #delay nextstate <= S0;

S2: if (bnum) #delay nextstate <= S2; else #delay nextstate <= S3;

S3: if (bnum) #delay nextstate <= S4; else #delay nextstate <= S0;

S4: if (bnum) #delay nextstate <= S2; else #delay nextstate <= S0;

default: #delay nextstate <= S0; endcase end

// Output Logic always @(*) begin if (state == S4) smile <= 1'b1 ; else smile <= 1'b0 ; end endmodule

Moore FSM: arcs indicate input

S00

reset

S10

1

0 0

S20

1

1

S30

0

0

S41

1

1

0

Page 31: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Mealy FSM in Verilog

31

module mealy_snail(input clk, reset, bnum, output reg smile);

reg [1:0] state, nextstate;

parameter S0 = 2'b00; parameter S1 = 2'b01; parameter S2 = 2'b10; parameter S3 = 2'b11;

parameter delay = 1;

// state register always @(posedge reset, posedge clk) begin if (reset) #delay state <= S0; else #delay state <= nextstate;

end

// Next State and Output Logicalways @(*)begin case (state) S0: begin #delay smile <= 1'b0; if (bnum) #delay nextstate <= S1; else #delay nextstate <= S0; end

S1: begin #delay smile <= 1'b0; if (bnum) #delay nextstate <= S2; else #delay nextstate <= S0; end

S2: begin #delay smile <= 1'b0; if (bnum) #delay nextstate <= S2; else #delay nextstate <= S3; end

S3: begin if (bnum) #delay smile <= 1'b1; else #delay smile <= 1'b0; if (bnum) #delay nextstate <= S1; else #delay nextstate <= S0; end

default: begin #delay smile <= 1'b0; #delay nextstate <= S0; end endcase end

endmodule

Mealy FSM: arcs indicate input/output

S0

reset

S1

1/0

0/0 0/0S2

1/0

1/0

S3

0/0

1/1

0/0

Page 32: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Testbench for Snail FSM

32

`timescale 1ns/1ps

module fsm_snail_tb( ); reg clk, reset, bnum; wire smile_moore; wire smile_mealy;

parameter clk_period = 10; moore_snail moore_snail_uut (clk, reset, bnum, smile_moore);

mealy_snail mealy_snail_uut (clk, reset, bnum, smile_mealy);

initial begin reset = 1; #13 reset = 0; end

always begin clk = 1; forever #(clk_period/2) clk = ~clk; end

initial begin

bnum = 0; #3; bnum = 0; #clk_period;

bnum = 1; #clk_period;bnum = 0; #clk_period; bnum = 0; #clk_period; bnum = 0; #clk_period; bnum = 1; #clk_period; bnum = 1; #clk_period; bnum = 0; #clk_period; bnum = 1; #clk_period; // Smilebnum = 1; #clk_period; bnum = 0; #clk_period; bnum = 1; #clk_period; // Smilebnum = 0;

end

endmodule

Page 33: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Simulation with ModelSim

• Use radices below for display purpose radix define moore_state {3'b000 "S0” , 3'b001 "S1” , 3'b010 "S2” ,

3'b011 "S3” , 3'b100 "S4"} radix define mealy_state {2'b00 "S0” , 2'b01 "S1” , 2'b10 "S2” , 2'b11

"S3"}

33

Page 34: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Testbench and TestVector

• 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 Self-checking testbench with testvectors

34

Page 35: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Simple Testbench Revisit

35

`timescale 1ns/1ps

module testbench1(); reg a, b, c; wire y;

// instantiate device under test sillyfunction dut(a, b, c, y);

// apply inputs one at a time initial begin a = 0; b = 0; c = 0; #10; c = 1; #10; b = 1; c = 0; #10; c = 1; #10; a = 1; b = 0; c = 0; #10; c = 1; #10; b = 1; c = 0; #10; c = 1; #10; end

endmodule

module sillyfunction (input a, b, c, output y);

assign y = ~a & ~b & ~c | a & ~b & ~c | a & ~b & c;

endmodule

testvectors

testbench

Page 36: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Self-checking Testbench Revisit

36

module testbench2(); reg a, b, c; wire y;

// 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.");

a = 1; b = 0; c = 0; #10; if (y !== 1) $display("100 failed."); c = 1; #10; if (y !== 1) $display("101 failed."); b = 1; c = 0; #10; if (y !== 0) $display("110 failed."); c = 1; #10; if (y !== 0) $display("111 failed."); end

endmodule

testvectors

Page 37: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

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 outputs1. Generate clock for assigning inputs, reading outputs2. Read testvectors file into array3. Assign inputs and expected outputs to signals4. Compare outputs to expected outputs and report errors if

there is discrepancy

37

Page 38: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

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

AssignInputs

CompareOutputs toExpected

CLK

Page 39: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Testvector File Example

39

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 | a & ~b & c;

endmodule

Page 40: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Self-Checking Testbench with Testvectors

40

module testbench3(); 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

1. Generate clock for assigning inputs, reading outputs

2. Read testvectors file into array3. Assign inputs and expected outputs to signals

Page 41: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Self-Checking Testbench with Testvectors

41

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 testvector vectornum = vectornum + 1; if (testvectors[vectornum] === 4'bx) begin $display("%d tests completed with %d errors“, vectornum, errors); $finish; end end

endmodule

// Note: “===“ and “!==“ can compare values that are x or z.

Page 42: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

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

Page 43: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

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

Page 44: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

Backup Slides

44

Page 45: Lecture 6. Verilog HDL – Sequential Logic

Korea Univ

N: 2N Decoder Example

45

module decoder #(parameter N = 3)

(input [N-1:0] a,

output reg [2**N-1:0] y);

always @(*)

begin

y = 0;

y[a] = 1;

end

endmodule