1 comp541 state machines – ii: verilog descriptions montek singh sep 24, 2014
TRANSCRIPT
1
COMP541
State Machines – II: Verilog Descriptions
Montek Singh
Sep 24, 2014
Today’s Topics Lab preview:
“Debouncing” a switch Verilog styles for FSM
Don’t forget to check synthesis output and console msgs.
State machine stylesMoore vs. Mealy
2
Lab Preview: Buttons and Debouncing Mechanical switches “bounce”
vibrations cause them to go to 1 and 0 a number of timescalled “chatter”
hundreds of times!
We want to do 2 things:“Debounce”: Any ideas?Synchronize with clock
i.e., only need to look at it at the next +ve edge of clock
Think about (for Wed class):What does it mean to “press the
button”? Think carefully!!What if button is held down for a
long time? 3
Verilog coding styles for FSMs
4
Verilog coding styles First: More on Verilog procedural/behavioral
statementsif-then-elsecase statement
Then: How to specify an FSMUsing two always blocks
Using a single always block??Using three always blocks
5
Verilog procedural statements All variables/signals assigned in an always
statement must be declared as reg
Unfortunately, the language designers made things unnecessarily complicatednot every signal declared as reg is actually registered it is possible to declare reg X, even when X is the output of
a combinational function, and does not need a register!whattt???!!
They thought it would be awesome to let the Verilog compiler figure out if a function is combinational or sequential!a real pain sometimesyou will suffer through it later in the semester if not
careful!
Verilog procedural statements These statements are often convenient:
if / elsecase, casezmore convenient than “? : ” conditional expressions
especially when deeply nested
But: these must be used only inside always blocksagain, some genius decided that
Result:designers often do this:
declare a combinational output as reg Xso they can use if/else/case statements to assign to XHOPE the Verilog compiler will optimize away the
unintended latch/reg
Example: Comb. Logic using casemodule decto7seg(input [3:0] data, output reg [7:0] segments); // reg is optimized away always @(*) case (data) // abcdefgp 0: segments <= 8'b11111100; 1: segments <= 8'b01100000; 2: segments <= 8'b11011010; 3: segments <= 8'b11110010; 4: segments <= 8'b01100110; 5: segments <= 8'b10110110; 6: segments <= 8'b10111110; 7: segments <= 8'b11100000; 8: segments <= 8'b11111110; 9: segments <= 8'b11110110; default: segments <= 8'b0000001; // required endcaseendmodule
Note the *:it means that when any inputs used in the body of the always block change.
This include “data”
Beware the unintended latch! Very easy to unintentionally specify a latch/register in
Verilog! how does it arise?
you forgot to define output for some input combination in order for a case statement to imply combinational logic, all
possible input combinations must be described one of the most common mistakes!
one of the biggest sources of headache!you will do it a gazillion times
this is yet another result of the the hangover of software programmingforgetting everything in hardware runs in parallel, and time
is continuous
Solution good programming practice
remember to use a default statement with cases every if must have a matching else
check synthesizer output / console messages9
Beware the unintended latch! Example: multiplexer
out is output of combinational blockno latch/register is intended in this circuit recommended Verilog:
assign out = select? A : B;
But, an if statement (inside an always block) will incorrectly introduce a reg:
if (select) out <= A;if (!select) out <= B;
reg added to save old value if condition is false to avoid extra reg, cover all cases within one
statement:if (select) out <= A;else out <= B; 10
select
A
Bout
Combinational Logic using casez casez allows case patterns to use don’t cares
module priority_casez(input [3:0] a, output reg [3:0] y);
// reg will be optimized away
always @(*) 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
endmodule
Blocking vs. Nonblocking Assignments (review) <= is a “nonblocking assignment”
Occurs simultaneously with others
= is a “blocking assignment” Occurs in the order it appears in the file
// nonblocking assignmentsmodule syncgood(input clk, input d, output reg q); reg n1; always @(posedge clk) begin n1 <= d; // nonblocking q <= n1; // nonblocking endendmodule
// blocking assignmentsmodule syncbad(input clk, input d, output reg q); reg n1; always @(posedge clk) begin n1 = d; // blocking q = n1; // blocking endendmodule
Cheat Sheet for comb. vs seq. logic Sequential logic:
Use always @(posedge clk)Use nonblocking assignments (<=)Do not make assignments to the same signal in more
than one always block!
e.g.:always @ (posedge clk) q <= d; // nonblocking
Cheat Sheet for comb. vs seq. logic Combinational logic:
Use continuous assignments (assign …) whenever readable
assign y = a & b;
OR
Use always @ (*)All variables must be assigned in every situation!
must have a default case in case statementmust have a closing else in an if statement
do not make assignments to the same signal in more than one always or assign statement
15
Revisit the sequence recognizer(from last lecture)
16
Let’s encode states using localparammodule seq_rec (input CLK, input RESET, input X,output reg Z);
reg [1:0] state;
localparam A = 2'b00, B = 2'b01, C = 2'b10, D = 2'b11;
Notice that we have assigned codes to the states.localparam is more appropriate here than parameter because these constants should be invisible/inaccessible to parent module.
17
Next State logic
reg [1:0] next_state; // optimized awayalways @(*)
begincase (state) A: if (X == 1)
next_state <= B; else
next_state <= A; B: if(X) next_state <= C; else next_state <=
A; C: if(X) next_state <= C; else next_state <=
D; D: if(X) next_state <= B; else next_state <=
A; default: next_state <= A;endcase
end The last 3 cases do same thing.Just sparse syntax.
Register for storing state Register with reset
synchronous reset (Lab 5)reset occurs only at clock transition
always @(posedge CLK)if (RESET == 1) state <= A;else state <= next_state;
prefer synchronous reset
asynchronous resetreset occurs whenever RESET goes high
always @(posedge CLK or posedge RESET)if (RESET == 1) state <= A;else state <= next_state;
use asynchronous reset only if you really need it!
18
Notice that state only gets updatedon posedge of clock (or on reset)
19
Output// Z declared as: output reg Z// reg is optimized away
always @(*)case(state)
A: Z <= 0;B: Z <= 0;C: Z <= 0;D: Z <= X ? 1 : 0;
default: Z <= 0;endcase
Comment on Code Could shorten it somewhat
Don’t need three always clausesAlthough it’s clearer to have combinational code be
separateDon’t need next_state, for example
Can just set state on clock
Template helps synthesizerCheck to see whether your state machines were
recognized
20
Verilog: specifying FSM using 2 blocks Let us divide FSM into two modules
one stores and update stateanother produces outputs
21
Verilog: specifying FSM using 2 blocksreg [1:0] state; reg outp;…
always @(posedge clk) case (state)
s1: if (x1 == 1'b1) state <= s2; else state <= s3; s2: state <= s4; s3: state <= s4; s4: state <= s1; endcase //default not required for seq logic!
always @(*)
case (state) s1: outp <= 1'b1; s2: outp <= 1'b1; s3: outp <= 1'b0; s4: outp <= 1'b0; default: outp <= 1'b0; //default required for comb logic! endcase
22
Synthesis (see console output)Synthesizing Unit <v_fsm_2>. Related source file is "v_fsm_2.v". Found finite state machine <FSM_0> for signal <state>. ----------------------------------------------------------------------- | States | 4 | | Transitions | 5 | | Inputs | 1 | | Outputs | 1 | | Clock | clk (rising_edge) | | Reset | reset (positive) | | Reset type | asynchronous | | Reset State | 00 | | Power Up State | 00 | | Encoding | automatic | | Implementation | LUT | ----------------------------------------------------------------------- Summary:
inferred 1 Finite State Machine(s).Unit <v_fsm_2> synthesized.
23
Incorrect: Putting all in one always Using one always block
generally incorrect! (But may work for Moore FSMs)ends up with unintended registers for outputs!
always@(posedge clk)case (state)s1: if (x1 == 1'b1) begin state <= s2; outp <= 1'b1; end else begin state <= s3; outp <= 1'b0; ends2: begin
state <= s4; outp <= 1'b1; ends3: begin
state <= s4; outp <= 1'b0; ends4: begin
state <= s1; outp <= 1'b0; endendcase
24
Synthesis OutputSynthesizing Unit <v_fsm_1>. Related source file is "v_fsm_1.v". Found finite state machine <FSM_0> for signal <state>. ----------------------------------------------------------------------- | States | 4 | | Transitions | 5 | | Inputs | 1 | | Outputs | 4 | | Clock | clk (rising_edge) | | Reset | reset (positive) | | Reset type | asynchronous | | Reset State | 00 | | Power Up State | 00 | | Encoding | automatic | | Implementation | LUT | ----------------------------------------------------------------------- Found 1-bit register for signal <outp>. Summary:
inferred 1 Finite State Machine(s).inferred 1 D-type flip-flop(s).
25
Textbook Uses 3 always Blocks
26
Three always Blocks reg [1:0] state; reg [1:0] next_state; … … … always @(*) // Process 1 case (state) s1: if (x1==1'b1) next_state <= s2; else next_state <= s3; s2: next_state <= s4; s3: next_state <= s4; s4: next_state <= s1; default: next_state <= s1; endcase
always @(posedge clk) // Process 2
if (RESET == 1) state <= s1;else state <= next_state;
reg outp;………always @(*) // Process 3 case (state) s1: outp <= 1'b1; s2: outp <= 1'b1; s3: outp <= 1'b0; s4: outp <= 1'b0; default: outp <= 1'b0; endcase
27
Synthesis (again, no unintended latch)Synthesizing Unit <v_fsm_3>. Related source file is "v_fsm_3.v". Found finite state machine <FSM_0> for signal <state>. ----------------------------------------------------------------------- | States | 4 | | Transitions | 5 | | Inputs | 1 | | Outputs | 1 | | Clock | clk (rising_edge) | | Reset | reset (positive) | | Reset type | asynchronous | | Reset State | 00 | | Power Up State | 00 | | Encoding | automatic | | Implementation | LUT | ----------------------------------------------------------------------- Summary:
inferred 1 Finite State Machine(s).Unit <v_fsm_3> synthesized.
28
My Preference The one with 3 always blocks
Easy to visualize the state transitionsFor really simple state machines:
2 always blocks is okay tooNever put everything into 1 always block!
Follow my template fsm_3blocktemplate.v (posted on the website)
29
Moore vs. Mealy FSMs? So, is there a practical difference?
30
CLKM Nk knext
statelogic
outputlogic
Moore FSM
CLKM Nk knext
statelogic
outputlogic
inputs
inputs
outputs
outputsstate
statenextstate
nextstate
Mealy FSM
Moore vs. Mealy Recognizer
reset
Moore FSM
S00
S10
S20
S30
S41
0
1 1 0 1
1
01 00
reset
S0 S1 S2 S3
0/0
1/0 1/0 0/01/1
0/01/0
0/0
Mealy FSM
Mealy FSM: arcs indicate input/output
Moore and Mealy Timing Diagram
Mealy Machine
Moore Machine
CLK
Reset
A
S
Y
S
Y
Cycle 1 Cycle 2 Cycle 3 Cycle 4 Cycle 5 Cycle 6 Cycle 7 Cycle 8 Cycle 9 Cycle 10
S0 S3?? S1 S2 S4 S4S2 S3 S0
1 1 0 1 1 0 1 01
S2
S0 S3?? S1 S2 S1 S1S2 S3 S0S2
Moore vs. Mealy FSM Schematic Moore Mealy
S2
S1
S0
S'2
S'1
S'0
Y
CLK
Reset
A
S2
S1
S0
S'1
S'0
CLK
Reset
S1
S0
A
Y
S0S1
Next VGA Displays
timing generationuses 2D xy-counter
34