Lecture 05 - 2/05/2019 - Finite State Machine with Datapath READING for this lecture and the next: 'RTL Design,' chapter 5 in Vahid's book on 'Digital Design.' 5:00 From FSM to FSMD Last week, we discussed Finite State Machines (FSM), the canonical form of a sequential machine. Finite state machines are perfect for everything related to decisions on discrete sequences. "If such and so happens, then do this." "If this happens after that, then do this." "As long as this input is high, generate a square wave on that output." etc. However, finite state machines have clear limitations, too. Counting to 1000 with a finite state machine is a pain: it requires 1000 states! In general, everything that involves arithmetic becomes a pain when using finite state machines. That is because a finite state machine uses an explicit representation of the state (data). To represent all values of a byte, for example, and FSM must use 256 states. We know, however, that counters and bytes and their operations are very easy to represent as a variable (with implicit state), namely: reg [7:0] count, countnext; always @(posedge clock) count <= reset ? 8'b0 : countnext; always @(*) countnext = count + 1; That is, we can use EXPRESSIONS to represent regular, repetitive state transition logic. Indeed, the single line. countnext = count + 1; means the same as saying case (count) state_000: countnext = state_001; state_001: countnext = state_002; ... endcase It turns out that hardware design uses both forms of hardware description intermixed. Arithmetic expressions belong to the DATAPATH; control decisions belong to the CONTROLLER (or FSM). DATAPATH FSM --------------------------------------------------------- State Implicit State Transition Explicit State Transition Good For Regular Logic Irregular Logic (e.g. Ripple Carry Adder) (e.g. Next-state Logic) Described Expressions State Transition Graph Using Verilog assign expression; (uncommon to use assign) or always @(*) always @(*) expressions; case-statement We are therefore going the extend our design model from FSM to FSMD. The D part will handle computations; the FSM part will handle decisions. Together, they can implement complete algorithms. NOTE: We did not discuss datapath in depth yet; this will come later. For now, the abstraction 'an expression implemented as hardware logic gates' is sufficient. For example: expressions hardware c = a + b; adder c = a * b; multiplier c = a << 2; hardwired shift c = a << b; programmable shifter 5:10 Finite State Machine with Datapath FSMD = Finite State Machine with Datapath = A finite state machine with direct control over hardware performing computations on data Let's define a template for an FSMD. 1. An FSMD uses a Finite State Machine (FSM) that can make a single transition per clock cycle. 2. An FSMD has a datapath D that computes a register transfer (RT) per clock cycle. D can compute a single RT, or D can compute several RT in parallel. 3. The specific RT executed on the datapath D may depend on the FSM state and state transition. The FSM can be thought of as sending a 'command' to the datapath D, thereby influencing the operation of D. 4. The specific state transition taken by the FSM may depend on the current state of the datapath D (i.e., the values stored in registers of D) as well as on the external input. The D can be thought of as sending 'status' information to the FSM, thereby influencing the operation of the FSM. - Diagram 5:20 Design Method for FSMD Design In a nutshell: 1. Capture a high-level state machine (sometimes called an algorithmic state machine). The 'high-level' means that the state transition conditions and the state actions (i.e., outputs) can be much more complicated than single bits. 2. Create a datapath to compute the data operations (expressions) required to implement the high-level state machine 3. Formalize the interface between the controller (finite state machine) and the datapath. This means identifying the command signals (from FSM to D) and the status signals (from D to FSM) 4. Design the controller FSM by converting the high-level state machine into the FSM. 5:25 Example I - Vending Machine Controller Design a vending machine controller Input s (8-bit): Cost of item (e.g. soda) as the value in cents Input c : Coin inserted (single bit, single-cycle) Input a (8-bit): Value of inserted coin Output d : Dispense item (eg soda) (single-bit, single-cycle) High-level design: the machine accepts coins and accumulates their value. when sufficient amount is entered, d becomes high for 1 cycle to dispense soda ============================= Step 1: High Level FSM Design ============================= State Init: d = 0 total = 0 goto Wait State Wait: When a coin is present, go to State Add When no coin is present AND (total >= s), go to State Disp When no coin is present AND (total < s), go to State Wait State Disp: d = 1 goto Init State Add: total = total + a goto Wait Note the difference with a traditional FSM and this 'high-level FSM.' - the data types used by the HL FSM involve words, not just bits - a HL FSM may assume additional registers to store data - The actions of a HL FSM may include expressions on registers The following concepts are identical for HL FSM and FSM - One transition per cycle ====================================================== Step 2: Create a datapath to carry out data operations ====================================================== We have the following registers: total We have the following inputs: s, a We need to implement the following operations: total = 0 total = total + a test (total < s) --> compare(total, s) Here is a hypothetical datapath that could do this: module vendingdp(input wire clk, input wire [7:0] a, input wire [7:0] s, input wire add, input wire clr, output wire compare); reg [7:0] total; wire [7:0] total_next; always @(posedge clk) total <= total_next; assign total_next = clr ? 8'b0 : add ? total + a : total; assign compare = (total < s); endmodule =========================================================== Step 3: Formalize interface between controller and datapath =========================================================== The controller has to generate the following command signals for the datapath: add, clr The controller has to read the following status signals from the datapath: compare The controller has the following system inputs: c The controller has the following system outputs: d The datapath has the following system inputs (8 bit): s, a ================================== Step 4: Detailed design of the FSM ================================== Design the state transition table - CurrentState compare c NextState add clr d Init X X Wait 0 1 0 Wait 1 0 Wait 0 0 0 Wait 0 0 Disp 0 0 0 Wait X 1 Add 0 0 0 Add X X Wait 1 0 0 Disp X X Init 0 0 1 From here, we can design the next-state logic, etc This leads to the detailed realization of the FSMD module vendingfsm(input wire rst, input wire clk, input wire c, input wire compare, output wire add, output wire clr, output wire d); localparm SInit = 2'b00, Wait = 2'b01, Add = 2'b10, Disp = 1'b11; reg [1:0] state, next_state; always @(posedge clk, posedge rst) if (rst) state <= SInit; else state <= next_state; always @(*) begin add = 1'b0; clr = 1'b0; d = 1'b0; case (state) SInit: clr = 1'b1; next_state = Wait; Wait: if (~c & compare) then next_state = Wait; else if (~c & ~compare) then next_state = Disp; else next_state = Add; Add: add = 1'b1; next_state = Wait; Disp: d = 1'b1; next_state = Init; endcase; end endmodule 5:45 FSMD Summary We are designing circuits as a combination of a controller and a datapath. FSMD = FSM + D FSM: at clock_edge: state = state_next; evaluate: state_next = next_state_logic(state, registers, system_inputs); D: at clock_edge: registers = registers_next; evaluate: registers_next = expressions(registers, state, system_inputs) system_outputs = output_encoding(state, registers, system_inputs); The FSM: - takes care of computing the schedule of the algorithm - sends commands to the datapath - observes status from the datapath - reads system inputs, writes system outputs The Datapath: - Computes expressions - sends status to the FSM controller - receives commands from the FSM controller - reads system inputs, writes system outputs (Part 2 of FSMD Design - See Thursday) 5:45 HDL Simulation (Slides) - Cycle based simulation - Event driven simulation (- Simulation of Gate-level concurrency) (- Simulation of Behavioral concurrency) 6:15 Next Lecture - FSMD part 2 - HDL simulation part 2