Transcript Slide 1

ECE 551
Digital Design And Synthesis
Lecture 05
Behavioral Verilog Examples
Overview

Behavioral Design Examples
 Combinational Logic
 Registers

Finite State Machine Design
 Mealy
 Moore
 Control vs. Datapath
 Implicit FSM Design
2
Bitwidth Problems with Case

Case items must match both the value and bitwidth
wire [1:0] sel = 2;
casex (sel)
0
1
2
3
endcase
:
:
:
:
a
a
a
a
=
=
=
=
8’d1;
8’d2;
8’d3;
8’d4;
What are the size of select signal and the case
items in the example above?
3
Tricks with Case Synthesis


Case statements inherently have priority.
The first case “match” will be taken.
casex (sel)
2’b00 :
2’b01 :
2’b10 :
2’b11 :
endcase
a
a
a
a
=
=
=
=
8’d1;
8’d2;
8’d3;
8’d4;
Using a mux chain is a waste in this case, because
we’re only describing a single 4-to-1 mux.
Fix using “// synopsys parallel_case”
4
Tricks with Case Synthesis
casex (sel) //
2’b00 :
2’b01 :
2’b10 :
2’b11 :
endcase
•
•
•
synopsys parallel_case
a = 8’d1;
a = 8’d2;
a = 8’d3;
a = 8’d4;
Now we get a single 4-to-1 mux rather than a
chain of 3 2-to-1 muxes
Note that this only affects synthesis, not
simulation
This is not part of the Verilog standard; no
guarantees it will be honored
5
Tricks with Case Synthesis
casex (sel) // synopsys full_case
2’b00 : a = 8’d1;
2’b01 : a = 8’d2;
endcase
•
•
•
•
•
Not specifying all cases normally causes latches
Adding “// synopsys full_case” avoids this
Same limitations as parallel_case!
Can achieve the same thing using a default case
• default : a = 8’bx;
Default case is part of the standard, therefore it
is superior to using full_case! Use default case.
6
Mux With if...else if…else
module Mux_4_32_if (output [31:0] mux_out, input [31:0] data_3,
data_2, data_1, data_0, input [1:0] select, input enable);
reg
[31: 0] mux_int;
// add the tri-state enable
assign mux_out = enable ? mux_int : 32'bz;
// choose between the four inputs
always @ ( data_3, data_2, data_1, data_0, select)
if (select == 2’d0)
mux_int = data_0;
else if (select == 2’d1) mux_int = data_1;
else if (select == 2’d2) mux_int = data_2;
else
mux_int = data_3;
endmodule
What happens if we forget “select” in the trigger list?
What happens if select is 2’bxx? (Simulation? Synthesis?)
7
Mux With case
module Mux_4_32_(output [31:0] mux_out, input [31:0] data_3,
data_2, data_1, data_0, input [1:0] select, input enable);
reg
[31: 0] mux_int;
assign
mux_out = enable ? mux_int : 32'bz;
always @ ( data_3, data_2, data_1, data_0, select)
case (select)
// synopsys parallel_case
2’d0:
mux_int = data_0;
2’d1:
mux_int = data_1;
2’d2:
mux_int = data_2;
2’d3:
mux_int = data_3;
endcase
endmodule
Case implies priority unless use parallel_case pragma
What happens if select is 2’bxx? (Simulation? Synthesis?)
8
Mux Synthesis in System Verilog
•
•
•
•
The unique keyword acts like parallel_case
• Only one case will ever be matched, so make
a parallel mux
The priority keyword forces case items to be
checked in order
• This indicates that you should create a chain
of muxes
Works with both IF/ELSE and CASE
Great details on the value of these new
keywords in Supplemental Reading
9
Encoder With if…else if…else
module encoder (output reg [2:0] Code, input [7:0] Data);
always @ (Data)
begin
// encode the data
if (Data == 8'b00000001) Code = 3’d0;
else if (Data == 8'b00000010) Code = 3’d1;
else if (Data == 8'b00000100) Code = 3’d2;
else if (Data == 8'b00001000) Code = 3’d3;
else if (Data == 8'b00010000) Code = 3’d4;
else if (Data == 8'b00100000) Code = 3’d5;
else if (Data == 8'b01000000) Code = 3’d6;
else if (Data == 8'b10000000) Code = 3’d7;
else Code = 3'bxxx; // invalid, so don’t care
end
endmodule
10
Encoder With case
module encoder (output reg [2:0] Code, input [7:0] Data);
always @ (Data)
// encode the data
case (Data) // (* synthesis parallel_case *)
8'b00000001
: Code = 3’d0;
8'b00000010
: Code = 3’d1;
8'b00000100
: Code = 3’d2;
8'b00001000
: Code = 3’d3;
8'b00010000
: Code = 3’d4;
8'b00100000
: Code = 3’d5;
8'b01000000
: Code = 3’d6;
8'b10000000
: Code = 3’d7;
default
: Code = 3‘bxxx; // invalid, so don’t care
endcase
endmodule
Does the order of the cases matter?
Do we need the default case?
11
Priority Encoder With casex
module priority_encoder (output reg [2:0] Code, output valid_data,
input [7:0] Data);
assign valid_data = |Data; // "reduction or" operator
always @ (Data)
// encode the data
casex (Data)
8'b1xxxxxxx : Code = 7;
8'b01xxxxxx : Code = 6;
8'b001xxxxx : Code = 5;
8'b0001xxxx : Code = 4;
8'b00001xxx : Code = 3;
8'b000001xx : Code = 2;
8'b0000001x : Code = 1;
8'b00000001 : Code = 0;
default
: Code = 3'bxxx; // should be at least one 1, don’t care if none
endcase
endmodule
Does the order of the cases matter?
Do we need the default case?
12
Seven Segment Display w/Parameters
module Seven_Seg_Display (Display, BCD, Blanking);
output reg [6:0]
Display;
// abc_defg
input [3:0]
BCD;
input
Blanking;
parameter
BLANK = 7'b111_1111;
// active low
parameter
ZERO
= 7'b000_0001;
// h01
parameter
ONE
= 7'b100_1111;
// h4f
parameter
TWO
= 7'b001_0010;
// h12
parameter
THREE = 7'b000_0110;
// h06
a
parameter
FOUR = 7'b100_1100;
// h4c
parameter
FIVE
= 7'b010_0100;
// h24 f
parameter
SIX
= 7'b010_0000;
// h20
g
parameter
SEVEN = 7'b000_1111;
// h0f e
parameter
EIGHT = 7'b000_0000;
// h00
parameter
NINE
= 7'b000_0100;
// h04
d
b
c
Defined constants – can make code more understandable!
13
Seven Segment Display
always @ (BCD or Blanking)
if (Blanking) Display = BLANK;
else
case (BCD)
4’d0:
Display
4’d1:
Display
4’d2:
Display
4’d3:
Display
4’d4:
Display
4’d5:
Display
4’d6:
Display
4’d7:
Display
4’d8:
Display
4’d9:
Display
default:
Display
endcase
endmodule
=
=
=
=
=
=
=
=
=
=
=
ZERO;
ONE;
TWO;
THREE;
FOUR;
FIVE;
SIX;
SEVEN;
EIGHT;
NINE;
BLANK;
Parameters are
very useful.
We’ll talk about
more uses of
parameters
later.
14
Overview

Behavioral Design Examples
 Combinational Logic
 Registers

Finite State Machine Design
 Mealy
 Moore
 Control vs. Datapath
 Implicit FSM Design
15
Ring Counter
module ring_counter (count, enable, clock, reset);
output reg [7:0] count;
input
enable, clock , reset;
always @ (posedge reset, posedge clock)
if (reset == 1'b1)
count <= 8'b0000_0001;
else if (enable == 1’b1) begin
case (count)
8’b0000_0001: count <= 8’b0000_0010;
8’b0000_0010: count <= 8’b0000_0100;
…
8’b1000_0000: count <= 8’b0000_0001;
default: count <= 8’bxxxx_xxxx;
endcase
end
endmodule
Is there a more elegant way of doing this?
What about the hardware implementation?
16
Ring Counter
module ring_counter (count, enable, clock, reset);
output reg [7:0] count;
input
enable, reset, clock;
always @ (posedge reset or posedge clock)
if (reset == 1'b1)
count <= 8'b0000_0001;
else if (enable == 1'b1) count <= {count[6:0], count[7]};
//else count <= count; Is inferred by lack of an else
endmodule
A shift register instead of a lot of muxes and
comparators!
Does the lack of ELSE infer a latch?
17
Register With Parallel Load
module Par_load_reg4 (Data_out, Data_in, load, clock, reset);
output reg [3:0] Data_out;
input [3:0] Data_in;
input
load, clock, reset;
always @ (posedge reset, posedge clock)
begin
if (reset == 1'b1)
Data_out <= 4'b0;
else if (load == 1'b1)
Data_out <= Data_in;
end
endmodule
18
Rotator with Parallel Load
module rotator (Data_out, Data_in, load, clock, reset);
output reg [7: 0] Data_out;
input [7: 0] Data_in;
input
load, clock, reset;
always @ (posedge reset or posedge clock)
if (reset == 1'b1) Data_out <= 8'b0;
else if (load == 1'b1) Data_out <= Data_in;
else Data_out <= {Data_out[6: 0], Data_out[7]};
endmodule
19
Shift Register – Part 1
module Shift_Reg(Data_Out, MSB_Out, LSB_Out,
Data_In, MSB_In, LSB_In, s1, s0, clk, rst);
output reg [3: 0] Data_Out;
output
MSB_Out, LSB_Out;
input
[3: 0] Data_In;
input
MSB_In, LSB_In;
input
s1, s0, clk, rst;
assign MSB_Out = Data_Out[3];
assign LSB_Out = Data_Out[0];
// continued on next slide
20
Shift Register – Part 2
always @ (posedge clk) begin
if (rst) Data_Out <= 0;
else case ({s1, s0})
2’d0: Data_Out <= Data_Out;
// Hold
2’d1: Data_Out <= {MSB_In, Data_Out[3:1]}; // Shift from MSB
2’d2: Data_Out <= {Data_Out[2: 0], LSB_In}; // Shift from LSB
2’d3: Data_Out <= Data_In;
// Parallel Load
endcase
end
endmodule
Given Verilog code, be able to tell what it does.
Given a high-level description, be able to write Verilog code to
implement it.
21
Register File
module Register_File (Data_Out_1, Data_Out_2, Data_in, Read_Addr_1,
Read_Addr_2, Write_Addr, Write_Enable, Clock);
output [15:0] Data_Out_1, Data_Out_2;
input
[15:0] Data_in;
input
[2:0] Read_Addr_1, Read_Addr_2, Write_Addr;
input
Write, Enable, Clock;
reg
[15:0] Reg_File [0:7]; // 16-bit by 8-word memory declaration
always @ (posedge Clock) begin
if (Write_Enable) Reg_File [Write_Addr] <= Data_in;
Data_Out_1 <= Reg_File[Read_Addr_1];
Data_Out_2 <= Reg_File[Read_Addr_2];
end
endmodule
What kind of read and write capability does this module have?
Are the reads and writes synchronous or asynchronous?
22
Overview

Behavioral Design Examples
 Combinational Logic
 Registers

Finite State Machine Design
 Mealy
 Moore
 Control vs. Datapath
 Implicit FSM Design
23
FSM Models & Types

Explicit
 Declares a state register that stores the FSM state
 May not be called “state” – might be a counter!

Implicit
 Describes state implicitly by using multiple event controls

Moore
 Outputs depend on state only (synchronous)

Mealy
 Outputs depend on inputs and state (asynchronous)
 Outputs can also be registered (synchronous)
24
Generic FSM Diagram
Mealy
Inputs
Next State
Logic
Output
Logic
Outputs
State Register
Current State
Next State
FF
25
State Diagram
Outputs Y and Z are 0,
unless specified otherwise.
a=0
S0
b=0
a = 1/
Z=1
S1
Y=1
We don’t care about the
value of b in S0, or the
value of a in S1, or either a
or b in S2.
• Is this Mealy or Moore?
b = 1/ Z = 1
reset = 1
S2
26
State Diagram: Mealy!
a=0
b = x/
Y = 0,
Z=0
S0
a=1
b = x/
Y = 0,
Z=1
reset = 1
ab = xx/
YZ = 00
a=x
b = 0/
Y = 1,
Z=0
S1
Outputs Y and Z are 0,
unless specified otherwise.
We don’t care about the
value of b in S0, or the
value of a in S1, or either a
or b in S2.
• Is this Mealy or Moore?
a=x
b = 1/
Y = 1,
S2 Z = 1
27
Mealy Verilog [1] – Part 1
module fsm_mealy1 (clk, reset, a, b, Y, Z);
input clk, reset, a, b;
output Y, Z;
reg[1:0] state, next_state;
reg Y, Z;
parameter S0 = 2’b00, S1 = 2’b01, S2 = 2’b10; //state values
always@(posedge clk) begin
if (reset)
state <= S0;
// using non-blocking since sequential
else
state <= next_state;
end
//continued on next slide
28
Mealy Verilog [1] – Part 2
// next state logic
always@(state, a, b)
case (state)
S0: if (a)
next_state = S1;
else
next_state = S0;
S1: if (b)
next_state = S2;
else
next_state = S1;
S2:
next_state = S0;
default: next_state = 2’bx;
endcase
// output logic
always@(state, a, b) begin
Z = 1’b0, Y = 1’b0; //avoids latch
case (state)
S0: if (a) Z = 1;
S1: begin
Y = 1;
if (b) Z = 1;
end
S2: ;
// Z = 0, Y = 0
default: begin
Y = 1’bx; Z = 1’bx; end
endcase
endmodule
What happens when state = S1, b = 1’b0?
29
Mealy FSM
Inputs
Outputs
Next State and
Output Logic
State Register
Current State
FF
What are the advantages and disadvantages of this approach?
30
Mealy Verilog [2] – Part 1
module fsm_mealy2 (clk, reset, a, b, Y, Z);
input clk, reset, a, b;
output Y, Z;
reg[1:0] state, next_state;
reg Y, Z;
parameter S0 = 2’b00, S1 = 2’b01, S2 = 2’b10; //state values
always@(posedge clk) begin
if (reset)
state <= S0;
// using non-blocking since sequential
else
state <= next_state;
end
//continued on next slide
31
Mealy Verilog [2] – Part 2
// next state & output logic
always@(state, a, b)
begin
Y = 0; Z = 0;
case (state)
S0: if (a) begin
next_state = S1;
Z = 1;
else
next_state = S0;
S1: begin
Y = 1;
if (b)
begin
next_state = S2;
Z = 1;
end
else
next_state = S1;
end
S2: next_state = S0;
default: begin
next_state = 2’bx; Y = 1’bx;
Z = 1’bx; end
endcase
endmodule
32
Registered Mealy FSM
Output Register
Inputs
Outputs
Next State and
Output Logic
FF
State Register
Current State
FF
This delays the change in outputs by one cycle
How would this change the previous code?
33
Registered Mealy FSM…
Output Register
Registered
Outputs
Inputs
Next State and
Output Logic
State Register
Current State
FF
Combinational
Outputs
FF
Can be helpful for debugging to also see outputs before registering
34
Overview

Behavioral Design Examples
 Combinational Logic
 Registers

Finite State Machine Design
 Mealy
 Moore
 Control vs. Datapath
 Implicit FSM Design
35
State Diagram: Moore
a=0
S0
b=0
a=1
S1
Y=1
Outputs Y and Z are 0,
unless specified otherwise.
If an input isn’t listed for a
transition, we don’t care
about its value for that
transition
b=1
reset = 1
S2
Z=1
36
Moore FSM
Inputs
Next State
Logic
Output
Logic
Outputs
State Register
Current State
Next State
FF
37
Moore Verilog – Part 1
module fsm_moore (clk, reset, a, b, Y, Z);
input clk, reset, a, b;
output Y, Z;
reg[1:0] state, next_state;
reg Y, Z;
parameter S0 = 2’b00, S1 = 2’b01, S2 = 2’b10; //state values
always@(posedge clk) begin
if (reset)
state <= S0;
// using non-blocking since sequential
else
state <= next_state; //continued on next slide
end
38
Moore Verilog – Part 2
//next state logic
always@(state or a or b)
case (state)
S0: if (a)
next_state = S1;
else
next_state = S0;
S1: if (b)
next_state = S2;
else
next_state = S1;
S2: next_state = S0;
default: next_state = 2’bxx;
endcase
//output logic
always@(state) begin
Z = 0, Y = 0; // avoids latches
case (state)
S0: ;
S1: Y = 1;
S2: Z = 1;
default: begin
Y = 1’bx; Z = 1’bx; end
endcase
end
endmodule
39
Overview

Behavioral Design Examples
 Combinational Logic
 Registers

Finite State Machine Design
 Mealy
 Moore
 Control vs. Datapath
 Implicit FSM Design
40
Multi-Add Example FSM

Specification:
 Inputs [7:0] in, [1:0] more (and clk, rst)
 Output register [7:0] total initialized to 0 on reset
 While more is not 0
 Add in to total more times


(in can change each clock cycle)
 Read a new value of more
If more is 0, go to a final state where no more adding
takes place, and sit there until reset
41
FSM Diagram (Mealy)

Can separate the Control from the Datapath
 Datapath: Accumulator w/ enable (add)
 Control: FSM to generate enable above

Can create combined Control and Datapath
reset = 1
add = 0
SDONE
S0
more = 0
/ add = 0
more = 3 / add = 1
more = 2 / add = 1
add = 1
S1
add = 1
S2
more = 1
/ add = 1
42
Separate Control / Datapath
module multiadd_ctrl(output reg add, input [1:0] more,
input clk, rst); // signals “in” and “total” not included
reg [1:0] state, next;
parameter SDONE=2’b00, S0=2’b01, S1=3’b10, S2=3’b11;
initial state <= S0; // May not synthesize, better to rely on rst
always@(posedge clk or posedge rst)
if (rst) state <= S0;
else state <= next;
43
Separate Control / Datapath
//next state logic
always@(state, more)
case (state)
S0:
case (more)
2’b00: next = SDONE;
2’b01: next = S0;
2’b10: next = S1;
2’b11: next = S2;
default: next = 2’bxx;
endcase
S1: next = S0;
S2: next = S1;
SDONE: next = SDONE;
default: next = 2’bxx;
endcase
//output logic
always@(state,more) begin
case (state)
SDONE: add = 0;
S0:
add = |more;
default: add = 1;
endcase
end
endmodule
44
Separate Control / Datapath
module multiadd(output reg [7:0] total,
input [7:0] in, input [1:0] more, input clk, rst);
wire adden;
// control
multiadd_ctrl ctrl(adden, more, clk, rst);
// datapath
always@(posedge clk) begin
if (rst) total <= 0;
else if (adden) total <= total + in;
end
endmodule
45
Combined Control / Datapath
multiadd(output reg [7:0] total,
input [7:0] in, input [1:0] more, input clk, rst);
reg [1:0] state;
parameter SE=2’b00, S0=2’b01, S1=2’b10, S2=2’b11;
always@(posedge clk) begin
if (rst) begin
state <= S0; total <= 0;
end
else begin
// else block continued on next slide...
46
Combined Control / Datapath
// default to performing the add
total <= total + in;
case (state)
S0: begin
case (more)
2’b00: begin
state <= SDONE;
total <= total; // override default
end
2’b01: state <= S0;
2’b10: state <= S1;
2’b11: state <= S2;
default: state <= 2’bxx;
endcase
end // end state==S0 case
S1: state <= S0;
S2: state <= S1;
SDONE: begin
state <= SDONE;
total <= total; // override default
end
default: state <= 2’bxx;
endcase
end
endmodule
47
Overview

Behavioral Design Examples
 Combinational Logic
 Registers

Finite State Machine Design
 Mealy
 Moore
 Control vs. Datapath
 Implicit FSM Design
48
Implicit FSM Model

More abstract representation
 May not have explicit state register!

Only FSMs with one choice at each state

Does it yield simpler code?
 Maybe *shorter* code…
 But is more confusing!


Description of reset behavior more complex
Much less likely to synthesize than explicit!
 Can confuse some synthesizers
49
Implicit FSM Model

Typically uses series of @(posedge clock)s

Example: Mod 3 counter
IMPLICIT
EXPLICIT
always begin
@(posedge clk) count <= 0;
@(posedge clk) count <= count + 1;
@(posedge clk) count <= count + 1;
end
always @(posedge clk) begin
if (count==2) count <= 0;
else count <= count + 1;
end

Implicit
 Difficult to add reset
 Difficult to read/understand…
50
Review Questions

Why might we want to separate datapath and
control?
 In what situations would we want to combine them?


How do the implementations of a Moore FSM and a
Mealy FSM differ?
How would you implement the multiadd fsm as a
single always block?
 Would a single always block be easier or harder to design

than the presented implementations?
Would a single always block be easier or harder to
understand if you were reading someone else’s design?
51
Review Questions

Design a circuit that
 Inputs a single 8-bit data value, clock, and reset
 Outputs a single 10-bit data value
 At reset the output becomes zero
 Every four cycles after a reset, the output value is

changed to be the sum of the input values over the four
previous cycles
The output should not change more frequently than
every four cycles (unless there is a reset)
52