SLIDE 1 CENG 342 – Digital Systems
Finite State Machine with Datapath (FSMD) Larry Pyeatt
SDSM&T
SLIDE 2
Finite State Machine with Datapath (FSMD)
A Finite State Machine with Datapath (FSMD) is a mathematical abstraction that is sometimes used to design complex digital logic devices or computer programs. An FSMD is a digital system composed of
a finite-state machine, which controls the order of operations, and a datapath, which performs data processing operations.
FSMDs are algorithms in which statements have been scheduled into states. A program is converted into a state diagram in which states and arcs may include arithmetic expressions, and those expressions may use external inputs and outputs as well as variables. A simple FSM does not use variables or arithmetic operations/conditions, thus FSMDs are more powerful than FSMs. The FSMD level of abstraction is often referred to as the register-transfer level (RTL). The FSMD abstraction is equivalent to the Turing machine in power, which means that any computable function can be implemented by the appropriate FSMD.
SLIDE 3
FSMD
In the FSM (controller), each state assigns values to a set of datapath control signals which completely specifies the behavior of the datapath. However, when there are too many control signals it is difficult to realize what and how the datapath will operate. To improve on the FSM model, we use variable assignment statements to indicate changes in variable values stored in the datapath. An FSMD (FSM with datapath) can be viewed as a FSM model with assignment statements added to each state.
SLIDE 4
Formal Definition of FSMD
Formally, a finite-state machine with datapath is a 6-tuple defined as follows: P =< S, s0, I ∪ STAT, O ∪ A, f, h > where S = {s0, . . . , sm} is a finite set of states s0 is the reset state. I = {ij} is a set of primary input values. O = {ok} is a set of primary output values. A = {x ⇐ e : x ∈ VAR, e ∈ EXP} is a set of storage assignments. VAR is a set of storage variables. EXP = {f(x, y, z, ...) : x, y, z, ... ∈ VAR} is a set of expressions. STAT = {Rel(a, b) : a, b ∈ EXP} is a set of status signals as logical relations between two expressions from the set EXP. f is a state transition function that maps a cross product of S and I ∪ STAT into S. For Moore models, h is the output function that maps S into O ∪ A. For Mealy models, h is the output function that maps a cross product of S and I ∪ STAT into O ∪ A
SLIDE 5
Informal Definition of FSMD
Basically it is a finite state machine, which has states, inputs and ouputs, controlling a datapath, which has data inputs, storage elements (variables), and operations that can be performed on the data. Consider the algorithm for counting the number of ’1’ bits in a data word. Data ← Input ⊲ Load the input data into Data Count ← 0 ⊲ Initialize counter while Data = 0 do ⊲ Examine each bit in Data if LSB(Data) = 1 then ⊲ If the current least significant bit is 1 Count ← Count + 1 ⊲ Increment count end if Data ← LSR(Data, 1) ⊲ Logical shift Data right by 1 bit end while How many variables are there?
SLIDE 6
Informal Definition of FSMD
Basically it is a finite state machine, which has states, inputs and ouputs, controlling a datapath, which has data inputs, storage elements (variables), and operations that can be performed on the data. Consider the algorithm for counting the number of ’1’ bits in a data word. Data ← Input ⊲ Load the input data into Data Count ← 0 ⊲ Initialize counter while Data = 0 do ⊲ Examine each bit in Data if LSB(Data) = 1 then ⊲ If the current least significant bit is 1 Count ← Count + 1 ⊲ Increment count end if Data ← LSR(Data, 1) ⊲ Logical shift Data right by 1 bit end while How many variables are there? Two Variables: Data and Count (the input is not a variable).
SLIDE 7
Informal Definition of FSMD
Basically it is a finite state machine, which has states, inputs and ouputs, controlling a datapath, which has data inputs, storage elements (variables), and operations that can be performed on the data. Consider the algorithm for counting the number of ’1’ bits in a data word. Data ← Input ⊲ Load the input data into Data Count ← 0 ⊲ Initialize counter while Data = 0 do ⊲ Examine each bit in Data if LSB(Data) = 1 then ⊲ If the current least significant bit is 1 Count ← Count + 1 ⊲ Increment count end if Data ← LSR(Data, 1) ⊲ Logical shift Data right by 1 bit end while How many variables are there? Two Variables: Data and Count (the input is not a variable). Each variable requires a register in the datapath.
SLIDE 8
Informal Definition of FSMD
Basically it is a finite state machine, which has states, inputs and ouputs, controlling a datapath, which has data inputs, storage elements (variables), and operations that can be performed on the data. Consider the algorithm for counting the number of ’1’ bits in a data word. Data ← Input ⊲ Load the input data into Data Count ← 0 ⊲ Initialize counter while Data = 0 do ⊲ Examine each bit in Data if LSB(Data) = 1 then ⊲ If the current least significant bit is 1 Count ← Count + 1 ⊲ Increment count end if Data ← LSR(Data, 1) ⊲ Logical shift Data right by 1 bit end while How many variables are there? Two Variables: Data and Count (the input is not a variable). Each variable requires a register in the datapath. What operations must be performed?
SLIDE 9
Informal Definition of FSMD
Basically it is a finite state machine, which has states, inputs and ouputs, controlling a datapath, which has data inputs, storage elements (variables), and operations that can be performed on the data. Consider the algorithm for counting the number of ’1’ bits in a data word. Data ← Input ⊲ Load the input data into Data Count ← 0 ⊲ Initialize counter while Data = 0 do ⊲ Examine each bit in Data if LSB(Data) = 1 then ⊲ If the current least significant bit is 1 Count ← Count + 1 ⊲ Increment count end if Data ← LSR(Data, 1) ⊲ Logical shift Data right by 1 bit end while How many variables are there? Two Variables: Data and Count (the input is not a variable). Each variable requires a register in the datapath. What operations must be performed? Four operations: Data ← Input, Count ← 0, Count ← Count+1, and Data ← LSR(Data, 1).
SLIDE 10
One’s Counter – The Datapath
We usually co-design the datapath and controller, refining each incrementally. But let’s just jump to the end in this case. We will load a number into a shifter. If the least significant bit (LSB) is one, then increment the counter. Shift right, and repeat.
Right Shifter with Parallel Load Load E Data !=0 LSB Output Eanable Counter E Reset Count Reset_Counter Load_Shifter Shift
SLIDE 11
Specifying the FSM
Our initial design is a literal translation of the algorithm. We can use a “next-state and output table with variable assignments.” Next State Control Datapath Current Start, Data Outputs Outputs State 00 01 10 11 Done Output Datapath Actions s0 s0 s0 s1 s1 Z s1 s2 s2 s2 s2 Z Data ← Input s2 s3 s3 s3 s3 Z Count ← 0 s3 s4 s4 s4 s4 Z Mask ← 1 s4 s5 s5 s5 s5 Z Temp ← Data ∧ Mask s5 s6 s6 s6 s6 Z Count ← Count + Temp s6 s4 s7 s4 s7 Z Data ← Data ≫ 1 s7 s0 s0 s0 s0 1 Count
SLIDE 12 Specifying the FSM – Part 2
From the above observations, we obtain a reduced table called a state-action table for specifying FSMDs. Current Next State Control and Datapath Actions State Condition, State Condition, Actions s0
s0 Start = 1 s1
Done ← 0
s2 Data ← Input s2 s3 Count ← 0 s3 s4 Mask ← 1 s4 s5 Temp ← Data ∧ Mask s5 s6 Count ← Count + Temp s6
s4 Data = 0 s7
s7 s0
Output ← Count
SLIDE 13 Specifying the FSM – Part 3
From the above observations, we find that we can combine some states, and simplify some
- calculations. This is a Moore design, because none of the outputs are conditional (They
- nly depend on the current state).
Current Next State Control and Datapath Actions State Condition, State Condition, Actions s0
s0 Start = 1 s1
Done ← 0
s5
Count ← 0
s6 Count ← Count + Data[0] s6
s5 Data = 0 s7
s7 s0
Output ← Count
SLIDE 14 Example: One’s Counter
In a Moore version of the FSMD:
all the variable assignments (register loads) must be executed unconditionally in a state and
- nly next states are to be selected conditionally.
has five states
- utput logic is simple since it is dependent only on the present state.
In a Mealy version of the FSMD:
the variable assignments (register loads) can be executed conditionally together with the conditional selection of next states. has four states
- utput logic is more complex since it includes external and internal conditions.
SLIDE 15 One’s Counter – Final State-Action Table
Current Next State Control and Datapath Actions State Condition, State Condition, Actions s0
s0 Start = 1 s1
Output ← Z Done ← 0 Data ← Input Count ← 0 s1 DataLSB = 1 s2 Data = 0 ∧ DataLSB=0 s3 Data = 0 s4 s2 s3 Count ← Count + 1 s3 DataLSB = 1 s2 Data = 0 ∧ DataLSB=0 s3 Data = 0 s4 Data ← Data ≫ 1 s4 s0
Output ← Count
SLIDE 16 One’s Counter VHDL – Part 1
1
entity datapath is
2
port(
3
Input : in std_logic_vector(7 downto 0);
4
Output: out std_logic_vector(7 downto 0);
5
Load_shifter : in std_logic;
6
Shift : in std_logic;
7
Reset_counter : in std_logic;
8
Count : in std_logic;
9
Output_enable:in std_logic;
10
LSB : out std_logic;
11
NotZero : out std_logic;
12
clk : in std_logic
13
);
14
end datapath;
SLIDE 17 One’s Counter VHDL – Part 2
1
entity sequencer is
2
Load_shifter : out std_logic;
3
Shift : out std_logic;
4
Reset_counter : out std_logic;
5
Count : out std_logic;
6
Output_enable:out std_logic;
7
LSB : in std_logic;
8
NotZero : in std_logic;
9
Start : in std_logic;
10
Done : out std_logic;
11
clk : in std_logic
12
end sequencer;
SLIDE 18 Entity One’s Counter VHDL – Part 3
1
entity ones_counter is
2
Start : in std_logic;
3
Input : in std_logic_vector(7 downto 0);
4
Output: out std_logic_vector(7 downto 0);
5
Done : out std_logic_vector;
6
clk : in std_logic
7
end ones_counter;
8 9
architecture behavioral of ones_counter is
10
signal ls, shft, rst, incr, oen, lsb, nz, clock : std_logic;
11
begin
12
dp: entity work.datapath(my_arch)
13
port map( Input => Input, Output => Output, Load_shifter => ls,
14
Shift => shft, Reset_Counter => rst, Count => incr,
15
Output_enable => oen, LSB => lsb, NotZero => nz,
16
clk => clock; );
17
control: entity work.sequencer(my_arch)
18
port map( Load_Shifter => ls, Shift => shft, Reset_counter => rst,
19
Count => incr, Output_enable => oen, LSB => lsb,
20
NotZero => nz, Start => Start, Done => Done, clk => clock );
21
end;
SLIDE 19
Multiplication Algorithm
For this algorithm, the right shift is a logical shift. I.e. the most significant bit is always zero after a shift. x ← ext(A) ⊲ Sign or zero exntend A as appropriate. y ← ext(B) ⊲ Sign or zero exntend B as appropriate. R ← 0 ⊲ Initialize result. while y = 0 do ⊲ Repeat until y is zero. if LSB(y) = 1 then ⊲ If least significant bit is ’1’ then R ← R + x ⊲ Perform the addition. end if x ← x shifted left 1 bit ⊲ Shift x left. y ← y shifted right 1 bit ⊲ Shift y right. end while How many variables are there?
SLIDE 20
Multiplication Algorithm
For this algorithm, the right shift is a logical shift. I.e. the most significant bit is always zero after a shift. x ← ext(A) ⊲ Sign or zero exntend A as appropriate. y ← ext(B) ⊲ Sign or zero exntend B as appropriate. R ← 0 ⊲ Initialize result. while y = 0 do ⊲ Repeat until y is zero. if LSB(y) = 1 then ⊲ If least significant bit is ’1’ then R ← R + x ⊲ Perform the addition. end if x ← x shifted left 1 bit ⊲ Shift x left. y ← y shifted right 1 bit ⊲ Shift y right. end while How many variables are there? Each variable requires a register in the datapath.
SLIDE 21
Multiplication Algorithm
For this algorithm, the right shift is a logical shift. I.e. the most significant bit is always zero after a shift. x ← ext(A) ⊲ Sign or zero exntend A as appropriate. y ← ext(B) ⊲ Sign or zero exntend B as appropriate. R ← 0 ⊲ Initialize result. while y = 0 do ⊲ Repeat until y is zero. if LSB(y) = 1 then ⊲ If least significant bit is ’1’ then R ← R + x ⊲ Perform the addition. end if x ← x shifted left 1 bit ⊲ Shift x left. y ← y shifted right 1 bit ⊲ Shift y right. end while How many variables are there? Each variable requires a register in the datapath. What operations must be performed?
SLIDE 22
Multiplication Algorithm
Assume we wish to multiply two numbers, x = 01101001 and y = 01011010. We could get a long result, so extend x and y. R x y Next operation 0000000000000000 0000000001101001 0000000001011010 shift only 0000000000000000 0000000011010010 0000000000101101 add, then shift 0000000011010010 0000000110100100 0000000000010110 shift only 0000000011010010 0000001101001000 0000000000001011 add, then shift 0000010000011010 0000011010010000 0000000000000101 add, then shift 0000101010101010 0000110100100000 0000000000000010 shift only 0000101010101010 0001101001000000 0000000000000001 add, then shift 0010010011101010 0011010010000000 0000000000000000 return result 105 × 90 = 9450 For signed multiply, we would sign-extend x and y instead of zero-extending them.
SLIDE 23 Multiplier Circuit
Sequencer
Done add
DONE
load shift
LSB
load shift
=0?
LSB shift
z
start
CLOCK
reset reset load reset
16-bit adder
B A Sum
16-bit register
R
left shifte register right shift register
A
signed signed
LOAD B SIGNED
NOTE: When the shift registers are loaded, A and B are extended from n bits to 2n bits. If the SIGNED signal is 0, then they are sign extended. Otherwise, they are zero extended.
SLIDE 24 Separate the Data Path from the Sequencer (FSM)
Sequencer
Done add
DONE
load shift
LSB
load shift
=0?
LSB shift
z
start
CLOCK
reset reset load reset
16-bit adder
B A Sum
16-bit register
R
left shifte register right shift register
A
signed signed
LOAD B SIGNED
SLIDE 25 Easier to See Inputs and the Control Word
Sequencer
DataPath
Done load/reset shift add shift add LSB
z
LSB
z A B LOAD SIGNED
start reset reset
CLOCK DONE R
SLIDE 26 Define the FSM
Reset Done Run
z’/add=LSB’ shift=0 shift=1 shift=1 z/add=1
start=1/add=1 start=0/add=1 reset=0/add=1 reset=0/add=1 reset=0/add=1 DONE=0 DONE=1 DONE=1
SLIDE 27
The FSM expressed as a Table
Current INPUTS Next Moore Outputs Mealy Ouputs State LOAD Z LSB RESET State DONE shift add Reset x x x Reset 1 1 1 x x x 1 Done 1 1 1 Done x x x Reset 1 1 1 x x 1 Done 1 1 x x 1 Run 1 1 Run x x x Reset 1 1 x x 1 Run 1 LSB x 1 x 1 Done 1 1
SLIDE 28 Multiplier VHDL - Part 1
1 entity datapath is 2 port{ 3
clk : in std_logic, -- Clock signal
4
start : in std_logic, -- Active low load data
5
signed: in std_logic, -- Active low sign extend on load
6
shift : in std_logic, -- Active low enable x and y to shift
7
add : in std_logic, -- Active low enable R to load
8
z : out std_logic, -- Active high y is zero
9
lsb : out std_logic, -- Least significant bit of y
10
A,B : in std_logic_vector(7 downto 0),
11
R : out std_logic_vector(15 downto 0)
12 } 13 end entity datapath;
SLIDE 29 Multiplier VHDL - Part 2
1 architecture behavioral of datapath is 2
signal x_bus : std_logic_vector(15 downto 0);
3
signal y_bus : std_logic_vector(15 downto 0);
4
signal r_bus : std_logic_vector(15 downto 0);
5
signal s_bus : std_logic_vector(15 downto 0);
6 begin 7
x: entity work.extending_left_shift_register(behavioral)
8
port map(data_in => A, data_out => x_bus, signed => signed,
9
load => start, shift => shift, clk => clk);
10
y: entity work.extending_right_shift_register(behavioral)
11
port map(data_in => B, data_out => y_bus, signed => signed,
12
load => start, shift => shift, clk => clk);
13
adder: entiity work.adder16(behavioral)
14
port map(A => r_bus, B => x_bus, sum => s_bus,
15
cin=>’0’);
16
sum: entity work.register16(behavioral)
17
port map(d => s_bus, q => r_bus, reset => start,
18
load => add, clk => clk);
19
z <= ’1’ when y_bus = "0000000000000000", else ’0’;
20
lsb <= y_bus(0);
21
R <= r_bus;
22 end architecture behavioral;
SLIDE 30 Multiplier VHDL - Part 3
1 entity sequencer is 2 port{ 3
clk : in std_logic, -- Clock signal
4
reset : in std_logic, -- Active low reset
5
start : in std_logic, -- Active low start signal
6
shift : out std_logic, -- Active low enable x and y to shift
7
add : out std_logic, -- Active low enable R to load
8
z : in std_logic, -- Active high y is zero
9
lsb : in std_logic, -- Least significant bit of y
10
done : out std_logic
11 } 12 end entity sequencer;
SLIDE 31 Multiplier VHDL - Part 4
1 architecture behavioral of sequencer is 2
type seq_state_t is (RESET, DONE, RUN);
3
signal curr_state : seq_state_t;
4
signal next_state : seq_state_t;
5 begin 6
7
st: process (clk)
8
begin
9
if rising_edge(clk) then
10
curr_state <= next_state;
11
end if;
12
end process;
13
14
next_state <= RESET when reset = ’0’, else
15
DONE when curr_state = DONE and start = ’1’, else
16
RUN when curr_state = DONE and start = ’0’, else
17
DONE when curr_state = RUN and z = ’1’, else
18
RUN when curr_state = RUN and z = ’0’, else
19
curr_state;
20
21
done <= ’0’ when curr_state = DONE, else ’1’;
22
shift <= ’0’ when curr_state = RUN else ’1’;
23
add <= (not lsb) when curr_state = RUN and z = 0, else 1; -- Mealy output
24 architecture behavioral;
SLIDE 32 Multiplier VHDL - Part 5
1 entity multiplier is 2 port{ 3
clk : in std_logic, -- Clock signal
4
reset : in std_logic, -- Active low reset
5
load : in std_logic, -- Active low start signal
6
signed: in std_logic, -- Active low sign extend on load
7
done : out std_logic
8
A,B : in std_logic_vector(7 downto 0),
9
R : out std_logic_vector(15 downto 0)
10 } 11 end entity multiplier; 12 13 architecture behavioral of multiplier is 14
signal shift,add,z,lsb: std_logic; -- connections between seq and dp.
15 begin 16
dp: entity work.datapath(behavioral)
17
port map(clk => clk, reset => reset, start => load,
18
signed => signed, shift => shift, add => add,
19
z => z, lsb => lsb, A => A, B => B, R => R);
20
seq: entity work.sequencer(behavioral)
21
port map(clk => clk, reset => reset, start => load,
22
shift => shift, add => add, z => z, lsb => lsb,
23
done => done);
24 end architecture behavioral;