Computer Logic Design - PowerPoint PPT Presentation

About This Presentation
Title:

Computer Logic Design

Description:

Title: Slide 1 Subject: Computer Logic Design Author: Taeweon Suh Last modified by: Taeweon Suh Created Date: 8/14/2004 10:46:03 PM Document presentation format – PowerPoint PPT presentation

Number of Views:200
Avg rating:3.0/5.0
Slides: 46
Provided by: Taewe
Category:

less

Transcript and Presenter's Notes

Title: Computer Logic Design


1
COMP211 Computer Logic Design
Lecture 6. Verilog HDL Sequential Logic
Prof. Taeweon Suh Computer Science
Education Korea University
2
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 _at_ (sensitivity list) begin statement sta
tement end
3
D Flip-Flop
  • As studied, flip-flop samples input at the edge
    of the clock
  • always _at_(posedge clk) samples the input at the
    rising edge of the clock (clk)
  • always _at_(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
  • Well see it later
  • lt or can be used inside the always statement
  • lt is called nonblocking assignment
  • is called blocking assignment
  • We are going to discuss about this later
  • module flipflop(input clk,
  • input 30 d,
  • output reg 30 q)
  • always _at_ (posedge clk)
  • begin
  • q lt d // pronounced q gets d
  • end
  • endmodule

4
D Flip-Flop Simulation
testbench
timescale 1ns / 1ns module Dflipflop_tb()
reg clock reg 30 data wire
30 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_period2) data 4'h5
(clk_period3) data 4'hA
(clk_period3) data 4'hC
(clk_period2) end endmodule
module Dflipflop(input clk,
input 30 d,
output reg 30 q) always _at_(posedge clk)
begin q lt d end endmodule
5
D Flip-Flop with Sync and Async Reset
DFF with Synchronous Reset
DFF with Asynchronous Reset
  • module ff_asyncR(input clk,
  • input reset,
  • input 30 d,
  • output reg 30 q)
  • // asynchronous reset
  • // sensitivity list has both clk and reset
  • always _at_ (posedge clk, posedge reset)
  • begin
  • if (reset) q lt 4'b0
  • else q lt d
  • end
  • endmodule

module ff_syncR(input clk,
input reset,
input 30 d, output reg
30 q) // synchronous reset // sensitively
list has only clk always _at_(posedge clk)
begin if (reset) q lt 4'b0 else
q lt d end endmodule
6
D Flip-Flop with Sync Reset
timescale 1ns / 1ns module ff_syncR_tb( )
reg clk reg reset reg
30 d wire 30 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_period2) reset 0 (clk_period3) r
eset 1 (clk_period2) reset 0
(clk_period3) end initial begin d
4'h0 3 d 4'h3 (clk_period2) d
4'h5 (clk_period3) d 4'hA
(clk_period3) d 4'hC (clk_period2)
end endmodule
module ff_syncR(input clk,
input reset, input
30 d, output reg 30
q) // synchronous reset always _at_(posedge
clk) begin if (reset) q lt 4'b0
else q lt d end endmodule
7
D Flip-Flop with Enable
timescale 1ns / 1ns module ff_en_tb() reg
clk reg reset reg en reg
30 d wire 30 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_period2)
reset 0 end initial begin
en 1 3 en 1
(clk_period5) en 0
(clk_period) en 1 end
initial begin d 4'h0 3
d 4'h3 (clk_period2) d
4'h5 (clk_period3) d 4'hA
(clk_period3) d 4'hC
(clk_period2) end endmodule
module ff_en(input clk,
input reset, input
en, input 30 d,
output reg 30 q) // asynchronous
reset and enable always _at_(posedge clk, posedge
reset) begin if (reset) q lt 4'b0 else
if (en) q lt d end endmodule
8
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 30 d,
  • output reg 30 q)
  • always _at_ (clk, d)
  • begin
  • if (clk) q lt d
  • end
  • endmodule

9
D Latch Simulation
timescale 1ns / 1ns module latch_tb( ) reg
clk reg 30 d wire 30
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_period2)
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_period3) d 4'hA
(clk_period3) d 4'hC
(clk_period2) end endmodule
module latch(input clk,
input 30 d, output reg
30 q) always _at_(clk, d) begin if
(clk) q lt d end endmodule
10
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 theyre not
    actually intended to be registers
  • In other words, all signals on the left side of
    lt and inside always should be declared as reg

11
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 30 a, b,
  • output reg 30 y1, y2, y3, y4,
    y5)
  • always _at_ () // 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 its
    better to use assign statements in this case.

12
Combinational Logic using case
module sevenseg(input 30 data, output reg
60 segments) always _at_() 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 lt 7'b000_0000 // required endcase
end endmodule
  • What kind of circuit would it generate?

13
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?

14
Combinational Logic using casez
  • The casez statement is used to describe truth
    tables with dont cares
  • dont cares are indicated with ? in the casez
    statement
  • module priority_casez(input 30 a,
  • output reg 30 y)
  • always _at_()
  • begin
  • casez(a)
  • 4'b1??? y 4'b1000 // ? dont care
  • 4'b01?? y 4'b0100
  • 4'b001? y 4'b0010
  • 4'b0001 y 4'b0001
  • default y 4'b0000
  • endcase
  • end
  • endmodule

15
Priority Circuit Simulation
module priority_casez(input 30 a,
output reg 30 y) always
_at_() 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 30 a wire 30 y parameter
clk_period 10 priority_casez dut(a, y)
initial begin a 4'b0110
(clk_period2) a 4'b1110
(clk_period2) a 4'b0101
(clk_period2) a 4'b0011
(clk_period2) a 4'b0001
(clk_period2) a 4'b0000
(clk_period2) end endmodule
16
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 mux2 (parameter width 8) // name and
default value (input width-10 d0, d1,
input s, output width-10 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)
17
Blocking and Nonblocking Statements
  • In the always statement,
  • indicates blocking statement
  • lt 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

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

module sync_nonblocking (input
clk, input d,
output reg q) reg n1 always _at_(posedge
clk) begin n1 lt d // nonblocking
q lt n1 // nonblocking end endmodule
module sync_blocking (input clk,
input d, output reg q)
reg n1 always _at_(posedge clk) begin
n1 d // blocking q n1 // blocking
end endmodule
19
Blocking vs Nonblocking Example
  • 1-bit full adder

Cout AB (A B)Cin
G PCin
20
Full Adder with Blocking Statements
module fulladder(input a, b, cin,
output reg s, cout) reg p,
g always _at_() begin p a b
// blocking g a b // blocking
s p cin // blocking cout g
(p cin) // blocking end 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. p ? 1 0 1
  2. g ? 1 0 0
  3. s ? 1 0 1
  4. cout ? 0 1 0 0

21
Full Adder with Nonblocking Statements
module fulladder(input a, b, cin,
output reg s, cout) reg
p, g always _at_() begin p lt a b
// nonblocking g lt a b //
nonblocking s lt p cin //
nonblocking cout lt g (p cin) //
nonblocking end 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
  • p ? 1 0 1, g ? 1 0 0, s ? 0
    0 0, cout ? 0 0 0 0
  • 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

22
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

23
Rules for Signal Assignment
  • Use always _at_(posedge clk) and nonblocking
    assignments to model synchronous sequential logic
  • always _at_(posedge clk)
  • q lt d // nonblocking statement
  • Use continuous assignment statements to model
    simple combinational logic
  • assign y a b
  • Use always _at_() 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

24
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)

25
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

26
Moore FSM in Verilog
// next state logic always _at_ () case
(state) S0 if (TA) nextstate lt S1
else nextstate lt S0 S1
nextstate lt S2 S2 if (TB) nextstate
lt S3 else nextstate lt S2
S3 nextstate lt S0
default nextstate lt S0 endcase //
output logic always _at_ () 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 10 LA,
LB) reg 10 state, nextstate
parameter S0 2b00 parameter S1 2b01
parameter S2 2b10 parameter S3 2b11
parameter green 2b00 parameter yellow
2b01 parameter red 2b10 // state
register always _at_ (posedge clk, posedge
reset) if (reset) state lt S0 else
state lt nextstate
27
Testbench for Traffic Light FSM
timescale 1ns/1ps module moore_traffic_light_tb
() reg clk, reset reg TA, TB wire
10 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_period5) TA 0 TB
1 (clk_period4) TA 0 TB 0
(clk_period4) TA 1 TB 0
end endmodule
28
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 2b00 S0 ,
    2b01 S1 , 2b10 S2 , 2b11 S3
  • radix define mylight 2'b00
    "green , 2'b01 "yellow , 2'b10 "red"
  • Save the display information for the use in the
    future
  • File-gtSave Format, Then click on OK
  • By default, it will save the waveform format to
    wave.do

29
Snail FSM Revisit
  • There is a snail
  • The snail crawls down a paper tape with 1s and
    0s on it
  • The snail smiles whenever the last four digits it
    has crawled over are 1101

30
Moore FSM in Verilog
// Next State Logic always _at_() begin case
(state) S0 if (bnum) delay nextstate lt
S1 else delay nextstate lt S0
S1 if (bnum) delay nextstate lt S2
else delay nextstate lt S0 S2 if
(bnum) delay nextstate lt S2 else
delay nextstate lt S3 S3 if (bnum) delay
nextstate lt S4 else delay
nextstate lt S0 S4 if (bnum) delay
nextstate lt S2 else delay
nextstate lt S0 default delay
nextstate lt S0 endcase end // Output
Logic always _at_() begin if (state
S4) smile lt 1'b1 else smile
lt 1'b0 end endmodule
module moore_snail(input clk, reset, bnum,
output reg smile) reg 20
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 _at_(posedge reset, posedge clk) begin
if (reset) delay state lt S0 else
delay state lt nextstate end
31
Mealy FSM in Verilog
// Next State and Output Logic always
_at_() begin case (state) S0 begin
delay smile lt 1'b0 if (bnum) delay
nextstate lt S1 else delay
nextstate lt S0 end S1 begin
delay smile lt 1'b0 if (bnum) delay
nextstate lt S2 else delay
nextstate lt S0 end S2 begin
delay smile lt 1'b0 if (bnum) delay
nextstate lt S2 else delay
nextstate lt S3 end S3 begin
if (bnum) delay smile lt 1'b1 else
delay smile lt 1'b0 if (bnum) delay
nextstate lt S1 else delay
nextstate lt S0 end default begin
delay smile lt 1'b0 delay
nextstate lt S0 end endcase
end endmodule
Mealy FSM arcs indicate input/output
module mealy_snail(input clk, reset, bnum,
output reg smile) reg
10 state, nextstate parameter S0 2'b00
parameter S1 2'b01 parameter S2 2'b10
parameter S3 2'b11 parameter delay 1
// state register always _at_(posedge reset,
posedge clk) begin if (reset) delay
state lt S0 else delay state lt
nextstate end
32
Testbench for Snail FSM
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 // Smile bnum 1
clk_period bnum 0 clk_period bnum
1 clk_period // Smile bnum 0
end endmodule
33
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"

34
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

35
Simple Testbench Revisit
testbench
  • 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

module sillyfunction (input a, b, c,
output y) assign y a b c
a b c a b c endmodule
testvectors
36
Self-checking Testbench Revisit
  • 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
37
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 DUTs outputs with expected
    outputs
  • 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

38
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

39
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 a b c endmodule
40
Self-Checking Testbench with Testvectors
  • Generate clock for assigning inputs, reading
    outputs
  • Read testvectors file into array
  • Assign inputs and expected outputs to signals

// 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 _at_(posedge
clk) begin 1 a, b, c, yexpected
testvectorsvectornum end
  • module testbench3()
  • reg clk, reset
  • reg a, b, c, yexpected
  • wire y
  • reg 310 vectornum, errors
  • reg 30 testvectors100000
  • // array of testvectors
  • // instantiate device under test
  • sillyfunction dut(a, b, c, y)
  • // generate clock
  • always
  • begin
  • clk 1 5 clk 0 5
  • end

41
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 _at_(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 (testvectorsvectornum 4'bx) begin
  • display("d tests completed with d
    errors, vectornum, errors)
  • finish
  • end
  • end

42
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 dont have a good idea of the
    hardware your code implies

43
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 beginners mistake is to write
    HDL code without thinking about the hardware you
    intend to produce
  • If you dont 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

44
  • Backup Slides

45
N 2N Decoder Example
module decoder (parameter N 3)
(input N-10 a,
output reg 2N-10 y) always _at_()
begin y 0 ya 1 end endmodule
Write a Comment
User Comments (0)
About PowerShow.com