Transcript
Clocked Sequential Circuits inputs
Sequential Circuits – Part 1
next state logic
current state
async output logic
next state
sync output logic
Flip-flops
clock signal
asynchronous outputs synchronous outputs
In
sequential circuits, output values may depend on both current inputs and stored information
Clocked
sequential circuits and state machines From circuit description to state diagram From state diagram to VHDL specification Verifying state machines
» clocked sequential circuits store information in flip flops » stored information referred to as state of the circuit Next
state logic determines new stored values outputs depend only on stored values and change following clock edge Asynchronous outputs can change as inputs change Synchronous
State Tables and State Diagrams client 1
resource
access to a shared resource
client 0
Fair Arbiter Controls
» inputs: request0, request1 r1 r0 » outputs: grant0, grant1 arb g0 g1 » grants asserted in response to inputs » if requests from both clients, favor least-recently-served 00 CLK
idle0/00
01
x0
busy1/01
x1
fair arbiter is example of a state machine behavior of a state machine can be conveniently specified using a state diagram A state table is an equivalent representation The
00
1x r0 r1
busy0/10
10
x1 g0 g1
Current State
idle0
busy0/10
r0 r1
01
x0
0x
10
busy0
0x
idle1 busy1/01
idle1/00
00
1x 1x
idle0/00
g0 g1
The
1x
r0 r1
‹#›
‹#›
VHDL for Fair Arbiter entity fairArbiter is port( defining clk, reset, request0, request1: in std_logic; symbolic grant0, grant1: out std_logic); states next end fairArbiter; architecture a1 of fairArbiter is state type stateType is (idle0, idle1, busy0, busy1); logic signal state: stateType; begin process(clk) begin if rising_edge(clk) then if reset = '1' then state <= idle0; else case state is when idle0 => if request0 = '1' then state <= busy0; elsif request1 = '1' then state <= busy1; end if; when busy0 => if request0 = '0' then state <= idle1; end if; ... end case; end if; end if; end process; output logic grant0 <= '1' when state = busy0 else '0'; grant1 <= '1' when state = busy1 else '0'; (synchronous) end a1; ‹#›
idle1/00
x1 g0 g1
x1
busy1
00
Input r0 r1
0 1 0 1 0 0 x 1 x x
0 x 1 x x 0 1 0 1 0
Output g0 g1
0 0 0 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1
Next State
idle0 busy0 busy1 busy0 idle1 idle1 busy1 busy0 busy1 idle0 ‹#›
Circuit Implementing VHDL Spec “busy0” “busy1”
1
1 0
next state logic
0
state= req1 req0 “idle0”
“idle1”
1
“busy0”
0
n
state= “busy0” req0
output logic (synchronous)
D
Q
>C n
clk
=
grant0
=
grant1
“busy1” state ‹#›
1
Review Questions 1.
2.
3.
State Diagrams for Asynchronous Outputs
Referring to the diagram on page 2, explain how changes to input signals can cause immediate changes to asynchronous outputs. Explain why the so-called synchronous outputs cannot immediately change, in response to an input signal change. The design for the arbiter circuit on page 3, requires that busy periods be separated by idle periods. This adds delay, when one client is waiting for the other to finish. Draw an alternate state diagram that eliminates this delay, by allowing direct transitions between the busy0 and busy1 states. What is the smallest possible number of flip flops needed to implement the arbiter circuit? Assuming the circuit is implemented using this number of flip flops, determine the total number of simple gates required to implement the next-state logic (where a simple gate is a 2 input AND gate or a 2 input OR gate; inverters count as ½ of a gate).
State machines often have outputs that depend directly on inputs
idle0
» such outputs may change when inputs changes, not just on clock
Alternate form of state diagram
00/00
1x/10 1x/10
busy0
r0r1 x0/00
» output values attached to arrows » output has specified value when in “from state” and inputs have specified value
01/01
busy1
x1/01
idle1
g0g1
x1/01
0x/00
10/10
00
In example
Circuits with all synchronous outputs called Moore-mode Circuits with ≥1 asynchronous outputs called Mealy-mode
» g0 = (state=idle0)·r0 or (state=idle1)·r0r1’ or (state=busy0)·r0
‹#›
From State Diagrams to VHDL
‹#›
Procedure for Designing State Machines
State
diagram is often used to specify the behavior of a state machine Easy to construct VHDL code from state diagram
Make
» note, no code needed for “self-loops” begin initialization process(clk) begin if rising_edge(clk) then next state if reset = '1' then logic state <= desired initial value else case state is when state0 => logic for transitions from state0 when state1 => ... outputs assigned within scope ... output end case; of synchronization condition logic end if; are delayed until next tick end if; end process; out0 <= logic specifying out0 for complex output logic, use out1 <= logic specifying out1 separate combinational process end a1;
sure you understand specification
» read description carefully and rephrase in your own words » if no interface timing diagram given, make one » determine if outputs are synchronous or asynchronous » ask questions Determine
what the circuit must “remember”
» choose state names and write down what they mean Construct
appropriate state diagram VHDL module implementing state diagram Simulate circuit to verify operation Write
» construct inputs to visit every state, follow each transition
‹#›
State Machine for Garage Door Opener
Designing a Garage Door Opener 4
‹#›
input signals
» open/close, obstruction, at top, at bottom 2
xx00
output signals
0x1x
» raise door, lower door Desired
behavior 0x0x
» if obstruction detected when closing, reverse direction » if open/close signal is received while opening or closing the door, it should pause; next open/close reverses What
opening /10
x1xx,00xx opened /00 0xxx
10xx
openClose obstruction atTop atBot
pauseDown /00 x1xx
closing /01
pauseUp /00
must the circuit remember?
» is door open, closed, opening, closing or paused? » if door is paused, did it pause on way up, or way down? » how many states?
xx1x
reset State
1xxx xx01
‹#›
0xxx,11xx
00x0
goUp,goDown 00x1
closed /00 0xxx ‹#›
2
VHDL for Garage Door Opener entity opener is port ( clk, reset: in std_logic; openClose: in std_logic; obstruction: in std_logic; atTop: in std_logic atBot: in std_logic; goUp: out std_logic; goDown: out std_logic); end opener;
-------
signal to open or close door obstruction detected door at the top (fully open) door at the bottom (fully closed) raise door lower door
architecture a1 of opener is interface type stateType is (opened, closed, opening, closing, pauseUp, pauseDown, resetState); signal state: stateType; state begin definitions process (clk) begin if rising_edge(clk) then if reset = '1' then enter reset state state <= resetState; whenever reset
input is high
‹#›
Simulation of Garage Door Opener enter opened state from resetState
elsif state = resetState then if atTop = '1' then state <= opened; transitions from elsif atBot = '1' then state <= closed; resetState else state <= pauseDown; transitions from end if; opened else case state is when opened => if openClose = '1' and obstruction = '0' then state <= closing; end if; when closing => if openClose = '0' and obstruction = ’0 and atBot = '1’ then state <= closed; elsif obstruction = '1’ then state <= opening; elsif openClose = '1' then state <= pauseDown; end if; ... when others => transitions from end case; closing end if; end if; end process; output goUp <= '1' when state = opening else '0'; signals goDown <= '1' when state = closing else '0'; ‹#› end a1;
Simulation of Garage Door Opener
typical open/close cycle
typical pause operations
‹#›
Testbench for Garage Door Opener
-- now check out the inputs<="1000"; wait inputs<="1000"; wait inputs<="1000"; wait inputs<="1000"; wait inputs<="1000"; wait inputs<="0100"; wait inputs<="0010"; wait
wait wait wait wait
for for for for
‹#›
Exercises
reset <= '1'; inputs <= "0010"; wait for pause; reset <= '0'; wait for pause; -- first do a "normal" close/open cycle inputs<="1000"; wait for clk_period; inputs<="0000"; inputs<="0001"; wait for clk_period; inputs<="0000"; inputs<="1000"; wait for clk_period; inputs<="0000"; inputs<="0010"; wait for clk_period; inputs<="0000";
obstruction detection
clk_period; clk_period; clk_period; pause;
1. Write a version of the fair arbiter that supports three clients instead of two. Your module should have a third request signal (request2) and a third grant (grant2). 2. Draw a state transition diagram for the 3-way fair arbiter from the previous problem. 3. Make state tables corresponding to the state diagram on page 8 and 12.
typical pause cases, and obstruction-detected for clk_period; inputs<="0000"; wait for clk_period; for clk_period; inputs<="0000"; wait for clk_period; for clk_period; inputs<="0000"; wait for clk_period; for clk_period; inputs<="0000"; wait for clk_period; for clk_period; inputs<="0000"; wait for clk_period; for clk_period; inputs<="0000"; wait for clk_period; for clk_period; inputs<="0000"; wait for pause; ‹#›
‹#›
3
Solutions
when idle2 =>
1. entity fairArbiter is port( clk, reset: in std_logic; request0, request1, request2: in std_logic; grant0, grant1, grant2: out std_logic); end fairArbiter; architecture a1 of fairArbiter is type stateType is (idle0, idle1, idle2, busy0, busy1, signal state: stateType; begin process(clk) begin if rising_edge(clk) then if reset = '1' then state <= idle0; else case state is when idle0 => if request0 = '1' then state elsif request1 = '1' then state elsif request2 = '1' then state end if; when idle1 => if request1 = '1' then state elsif request2 = '1' then state elsif request0 = '1' then state end if;
if request2 = '1' then state elsif request0 = '1' then state elsif request1 = '1' then state end if; if request0 = '0' then state <= if request1 = '0' then state <= if request2 = '0' then state <=
when busy0 => when busy1 => when busy2 => when others => end case; end if; end if; end process; grant0 <= '1' when state = busy0 else '0'; grant1 <= '1' when state = busy1 else '0'; grant2 <= '1' when state = busy2 else '0'; end a1;
busy2);
<= busy2; <= busy0; <= busy1; idle1; end if; idle2; end if; idle0; end if;
<= busy0; <= busy1; <= busy2; <= busy1; <= busy2; <= busy0; ‹#›
2.
000
idle0/000
1xx
busy0/100
01x
1xx
xx0
‹#›
current state
inputs
outputs
opened
10xx
00
closing
00xx,x1xx
00
opened
00x1
01
closed
10xx
01
pauseDown opening
100
000
idle1/000
x1x
010
x01
idle2/000
x0x xx1
3.
Current State
idle0 busy0 idle1 busy1
Input r0 r1
0 1 0 1 0 0 x 1 x x
0 x 1 x x 0 1 0 1 0
closing
x1x
x1xx
01
00x0
01
closing
closed
1xxx
00
opening
0xxx
00
closed
opening
0x1x
10
opened
001
1x0
000
busy1/010
Output g0 g1
0 1 0 1 0 0 0 1 0 0
0 0 1 0 0 0 1 0 1 0
busy2/001
xx1
Next State
idle0 busy0 busy1 busy0 idle1 idle1 busy1 busy0 busy1 idle0
pauseUp pauseDown ‹#›
next state
10xx
10
pauseUp
00x1
10
opening
10xx
00
closing
0xxx,11xx
00
pauseUp
1xxx
00
opening
0xxx
00
pauseDown ‹#›
4