Lecture 1/31 Finite State Machines Continued 5:00PM RECAP LECTURE 3 Please refer to the slides Recap Lecture 3 Moore and Mealy State Transition Graph & State Transition Table Writing Synthesizable Verilog 5:15PM Demonstration of Simulation and Synthesis Simulation Commands to simulate ================================================================ vlib work vlog bitserial.v vlog bitserialtb.v vsim -c bitserialtb -do "run -all" ================================================================ Synthesis (online demo) In GUI RTL Viewer FSM Viewer Netlist Viewer In Report or GUI State Assignment Directive State Assignment & impact on logic ================================================================ quartus_sh --flow compile top ================================================================ Selecting state assignment strategy in Verilog: // state register // syn_encoding a synthesis attribute. // It specifies the state encoding to be used for synthesis (* syn_encoding = "one-hot" *) reg [1:0] state, statenext; Other possible values: "default" "sequential" "gray" "johnson" "one-hot" "compact" "user" Gray Code Example 0 0 1 1 2 11 3 10 4 110 5 111 6 101 7 100 8 1100 9 1101 10 1111 11 1110 12 1010 13 1011 14 1001 15 1000 Johnson Code 0 0000 1 1000 2 1100 3 1110 4 1111 5 0111 6 0011 7 0001 5:30PM Homework 2 Audio Codec on DE1SoC I2C Bus Audio Bus Homework 2 - FSM Design, Simulate I2C master Homework 3 - I2C on board, basic square wave generation Homework 4 - Waveform generation Homework 5 - Sound sampling, processing, playback The Audio Codec on DE1SoC Relevant Documents: Wolfson WM 8731 - data sheet Philips I2C Spec DE1 SoC schematics and User Guide The layout of the Audio CODEC +--------------+ +------------+ | FPGA | | WM 8731 | | +--- I2C Bus (SDA, SCL) ---+ -> Line out | | | <- Line in | +--- Audio Bus ------------+ <- Mic in | | | | +--------------+ +------------+ The Audio bus is a real-time serial bus that can transport DAC data (from FPGA to CODEC) or ADC data (from CODEC to FPGA) at the desired sample rate and precision. We will study the audio bus in a later homework. The programming of WM8731 works as follows (see codec data sheet). - The codec has 11 internal programmable (write-only) registers - These registers select the functionality, volume settings, power control - Through I2C, each of these register is configured to the desired setting - Once configured, the audio bus starts transporting audio data for playback of recording. I2C electrical characteristics: - The master drives SCL (we will ignore SCL cycle-extension) - The master drives or reads SDA. SDA is both input and output. In verilog, we will use an inout port for that. An I2C transfer works as follows (See Philips docs or codec data sheet) 1/ Send a start condition 2/ Send the 7-bit I2C device address (fixed at 0x1A for the codec) 3/ Send the r/w bit (will be always low) 4/ Read a bit from SDA (acknowledge) Repeat as many times as needed { 5/ Send an 8-bit data value 6/ Read a bit from SDA (acknowledge) } 7/ Send a stop condition The data transfer proceeds at 100 Kbps. That means, if the FPGA clocks at 50MHz, there will be 500 clock cycles needed to transmit a single I2C bit. For the Audio Coded, each data transfer will contain 16 bits. We will therefore need the I2C master to perform 3-byte transfers: device address, byte 1, byte 2. In homework 2, you have to develop an I2C master module that generates an initialization sequence, i.e. a programming sequence for the codec. The programming sequence is hypothetical; the emphasis is on the design of the I2C master. It is an application of FSM design (and, later, synthesis). 5:45PM Hierarchical FSM Designing a complex FSM such as for an I2C master requires planning. You can see that even simple sequencing of the data is complicated: For every (register, data) pair for the audio codec From the three-byte I2C transmission Send a start bit (at 100kbps) Send a 7-bit address Send the msb (at 100kbps) Count 500 cycles Send the nsb (at 100kbps) ... Send the lsb (at 100kbps) Send a write bit (at 100kbps) Read the ack bit (at 100kbps) Send an 8-bit data value (at 100kbps) Read the ack bit (at 100kbps) Send an 8-bit data value (at 100kbps) Read the ack bit (at 100kbps) Send a stop bit (at 100kbps) Designing a single, flat FSM is almost certainly asking for trouble. Instead, you need hierarchy. In C, you would write a nested for-loop (maybe including function calls). But how can you build 'nested FSM'? The answer is to use start-done signaling: +---------------------+ +--------------------+ | Higher Level FSM | | Lower Level FSM | | (~Outer Loop) +-----> Start ------>+ (~Inner Loop) | | +<----- Done <-------+ | +---------------------+ +--------------------+ Time-wise, it works as follows: +--------------------+ | | Start -------+ +------------------------- +----------------------+ | | Done --------------+ +---------------- I II III IV Time is partitioned in four phases: I: Higher Level FSM starts Lower Level FSM and waits for done. Lower Level FSM performs a number of transitions and sets Done high in reponse. II: Higher Level FSM will reset the start to idle. Lower Level FSM waits for start to be idle. III: Higher Level FSM waits for Done to be idle Lower Level FSM sets Done to idle. IV: Both FSM are ready for the next synchronization. You may wonder why II, III, IV are needed as I seems to do everything we want. However, if we want to execute I repeatedly, we need a structured manner to reset the sequence. This is done in a lockstep fashion to avoid assumptions on the timing of design internals of either FSM. 5:55PM The I2C Sequence Transmitter This leads us to the design for Homework 2. The overall structure of the design for an I2C sequence generator is as follows: +-------------+ +-----------+ +-----------+ | Top FSM | | Mid FSM | | Low FSM |----> SCL | +=====>+ +======>| | | | | | | |<---> SDA +-------------+ +-----------+ +-----------+ Sends a sequence Sends a single Sends individual of (Addr, Value) (Addr, Value) I2C parts: start, bit, stop, ack, (ie. 3-byte I2C Seq) |<-- YOU NEED TO DESIGN THIS IN HW2 -->|<-- YOU WILL RECEIVE THIS -->| 6:00 PM Driving inout signals (SDA). SDA has to be synthesized as a three-state signal: SDA (chip) <-------------------- | SDAOUT (chip) -----> BUFFER -----+----> SDA (pin) ^ | SDAread (chip) There are three signals that control reading/writing of the SDA pin 1. SDAOUT which selects the output value 2. SDA which reads the input value 3. SDAread which selects the direction of the pin When we access an inout signal in Verilog, we need it through these three signals. The synthesis tools can create the proper implementation for FPGA. In Verilog: inout sda reg sdaout; reg sdaread; assign sck = sckout; assign sda = sdaread ? 8'bz : sdaout; always @(*) in an always block, you can then set sdaread to 1 and grab the value from sda OR you can set sdaread to 0 and write a value to sdaout 6:10PM I2C BIT Transmitter Let's design a bit transmitter for I2C. What are relevant commands that the bit transmitter should be able to do? - Send a start condition - Send a stop condition - Read an ACK bit - Send a 0-bit - Send a 1-bit Each of these transmissons needs to proceed at the proper 100Kbit/s speed. Each bit period therefore will need to count until 500 (at 50MHz rate). module bitxmit(input clk, input reset, input [2:0] command, output ready, output sck, inout sda ); We will design the Low FSM as follows. S0: Idle, initial state. Waits for a 'start' (which means, a command listed above: startcondition, stopcondition, bit0, bit1, ack) If received, move to 'PRE' PRE: First 1/3 of the bit period. Count down 1/3 of the cycles, then move to BIT BIT: Second 1/3 of the bit period. Count down 1/3 of the cycles, them move to POST POST: Final 1/3 of the bit period. Count down final 1/3 of the cycles, then move to END END: Set ready to '1' Wait for 'start' command to become idle, then move to S0 We do 1/3 of bit periods so that we can change SDA while SCL is stable, OR change SCL while SDA is stable. Both are needed for the I2C signaling protocol. The output function of the FSM is slightly more complicated, as if drives both SDA and SCL for every possible command. Some examples: E.g. here is the sequence of I2C Start Condition: (- means unchanged) S0 PRE BIT POST END SCL - 1 1 1 1 SDAREAD - 0 0 0 0 SDAOUT - 1 0 0 - E.g. here is the sequence of I2C Bit-0 transmission: S0 PRE BIT POST END SCL - 0 1 0 - SDAREAD - 0 0 1 0 SDAOUT - 0 0 0 0 E.g. here is the sequence of I2C ACK transmission: S0 PRE BIT POST END SCL - 0 1 0 - SDAREAD - 1 1 1 1 SDAOUT - 1 1 1 1 Listing: bitxmit.v, bitxmit.h Simulating the design: ====================================================== vlib work vlog slave/i2cSlave.v vlog slave/registerInterface.v vlog slave/serialInterface.v vlog bitxmit.v vlog bitxmittb.v ====================================================== 6:15 Conclusions - HOMEWORK 2 - GET STARTED SOON! Homework 2 will be posted this evening (before midnight) - Topics for next week: FSMD (extending the FSM with a datapath) HDL Simulators (this topic is shifted forward from this week)