Lecture 7 - 2/12/19 - Homework 2 Review, Homework 3 5:00 The story so far: - Design of Moore and Mealy Finite State Machine - Mapping of FSM in Verilog (synthesizable) - always @(posedge), always @(*) - registers map in two reg variables - default assignment for every assignment in always @(*) - default case for case statement - instantiate modules with positional port assignment - Extensions on FSM - Hierarchical FSM: How to interconnect multiple FSM - FSM with Datapath: How to combine expressions and FSM - Data Clocks: How to handle data clocks (assuming fclk >> fdataclock) - Repositories - heartbeatde1soc (simple DE1SoC application) - bitserial (canonical FSM example) - fsmd (FSM with datapath example) - pattern (data clock example) - bitxmit (i2c transmitter example) 5:05 Today 1/ Review the solution for Homework 2 2/ Discuss implementation aspects of Homework 3 3/ (if time left) Continue HDL Simulation slides 5:06 Homework 2 statistics 42 students 25 working solutions (60%) 17 non-working solutions - FSM design errors - Does not compile Sample solution Discussion - bitxmit.h - bitxmit.v - i2cgenerator.v - i2cmasterwrite.v - i2ctb.v - slave/* * Block Diagram * Starting point: bitxmit Study the testbench bitxmittb (which is on a separate repo, https://github.com/vt-ece4514-s19/bitxmit) Testbench: command = `CMDSTART; @(posedge clk); @(posedge ready); command = `CMDWAIT; @(posedge clk); command = `CMDBIT0; @(posedge clk); @(posedge ready); command = `CMDWAIT; @(posedge clk); ... command = `CMDRBIT; @(posedge clk); @(posedge ready); command = `CMDWAIT; @(posedge clk); This testbench first defines the command input value, then waits for a clock edge, then waits for ready to go high, then issues the WAIT command, then waits for a clock edge (then the next command can start) Let's trace the activities in the FSM state S0 - idle state, waiting for a command state PRE - before the rising edge of SCL state BIT - when SCL is high state POST - after the falling edge of SCL state END - I2C bitxmit complete, wait for CMDWAIT - ready is high in this state (and low eveywhere else) -> draw FSM of bitxmit -> meaning of the commands SDA PRE BIT POST CMDIDLE -------------------(read)----------------- CMDBIT1 1 1 ----(read)- CMDBIT0 0 0 ----(read)- CMDSTART 1 0 0 CMDSTOP 0 1 1 CMDRBIT ------------------(read)----------------- SCL PRE BIT POST CMDIDLE 1 1 1 CMDBIT1 0 1 0 CMDBIT0 0 1 0 CMDSTART 1 1 0 CMDSTOP 1 1 1 CMDRBIT 0 1 0 5:20 How does the I2C generator work? 8-state diagram. Depends on the I2C sequence. Let's say you need to write the value 0xAA to slave register 0x5 Here's what needs to happen: - Initiate an I2C write to I2C slave 0x1A - Send the byte 0x05 - Send the byte 0xAA In terms of I2C sequence: - Send I2C start - Send 7 bits, MSB to LSB: 0x1A = 0011010 - Send 1 bit with value 0 - Wait for ACK - Send 8 bits, MSB to LSB: 0x05 = 0x00000101 - Wait for ACK - Send 8 bits, MSB to LSB: 0xAA = 0x10101010 - Wait for ACK - Send I2C stop - This will be broken down into bitxmit commands: CMDSTART CMDSTOP CMDBIT0 CMDBIT1 CMDRBIT (for ACK) CMDIDLE CMDWAIT Each of them follows the same sequence as the testbench: For example: command = `CMDSTART; @(posedge clk); @(posedge ready); command = `CMDWAIT; @(posedge clk); becomes: START : begin rcommand = `CMDSTART; if (bitready) begin statenext = ADR; rcommand = `CMDWAIT; ... end end ADR : begin ... end - How do we deal with repetitive data, eg Send 8 bits, MSB to LSB: 0x05 = 0x00000101 Wait for ACK ? We make use of two 8-bit registers: shift worddata shift is a control register. As long as it is non-zero, there are more bits to shift. worddata contains the bits to transmit When we have to transmit a byte, eg. 0x5 then we initialize worddata with the byte, and shift with 1. Then, we transmit the MSB of worddata by running the CMDBIT0 or CMDBIT1 Then, we shift up worddata and shift and repeat the previous as long as shift is nonzero In code: // previous state ... shiftnext = 1'b1; worddatanext = data[15:8]; MSB : begin if (shift == 8'b0) begin rcommand = `CMDWAIT; statenext = READ2; end else begin rcommand = worddata[7] ? `CMDBIT1 : `CMDBIT0; if (bitready) begin rcommand = `CMDWAIT; worddatanext = worddata << 1; shiftnext = shift << 1; end end end 5:30 How does the i2cmasterwrite work? Basically you instantiate i2cgenerator and bitxmit and you apply repeated commands. This can be done with a simple FSMD (draw FSMD) that sequences the requrest I2C slave register write (check code) 5:32 HOMEWORK 3 Setup: - I2C bus - Audio bus - Consider writeup and block diagram, data sheet - Consider note of TA on piazza 5:40 HW3 - I2C Programming Format - Data sheet page 46 - What does it mean? - Consider DE1SoC schematics for wiring of CSB state - Waveform on Figure 34 - What does it mean? - i2C programming of CODEC uses 7-bit register address 9-bit register data So your program has to break this down - Look at table 29 for the i2c register data - there are 11 programmable registers which fulfill various functions - example: Power-Down Register: R6 (06h) To turn on the power of the CODEC we work as follows: - Find the definition of the power down register - Identify the programmable bits Select the ones you want: LINEPD Line Input MICPD Microphone ADCPD A/D converter DACPD D/A converter OUTPD Line Output OSCPD Oscillator CLKOUTPD CLKOUT POWEROFF overall power To turn on everything except OUTPD we would have the byte: 00010000 = 0x10 To program this in I2C we write the following data: Slave address (1A) Byte 1: 7-bit regaddr + '0' = 00001100 = 0xC Byte 2: 8-bit data = 00010000 = 0x10 5:50 Clock Generation Show Audio Interface: - Need to provide MCLK - CODEC in master will generate BCLK, DACLRCK - data sheet page 38 states: BCLK = 64 x fs (base frequency, 48KHz) and MCLK = 4 x BCLK and LRCK = 256 x fs (called 'industry-standard sampling mode' on p. 20) - We generate our clock as follows: Create 1/4 of the 50MHz clk on the FPGA, provide this as MCLK = 12.5 MHz. Then, BCLK = 3.125 MHz Then, fsclk = 48.828125KHz ('standard' would be 48Khz but needs 12.288MHz, see Table 18) - Wave form: Figure 26 Draw the wave form 5:55 Audio Data Format - CODEC can use 16, 20, 24, 32 bits. We use 16 bits. - The data is two's complement: 0111 1111 1111 1111 most positive 0000 0000 0000 0000 zero 1000 0000 0000 0000 most negative - The data is provided left-justified when the interface is run left justified: In one DACLRCK half period, there are 32 bits: bit0 msb of the data sample bit1 ... bit2 ... ... ... bit15 lsb of the data sample bit16 notused (put 0) ... ... bit31 notused (put 0) 6:00 Audio waveform generation How to generate a 1KHz test tone? The loudest tone alternates between 0x7FFF and 0x8000 Since we run at 1KHz, we can generate 24 samples of 0x7fff followed by 24 samples of 0x8000. The result is a 1 KHz square wave. Our exact frequency is 48.828125KHz/48 = 1017Hz 6:03 Debugging Solution 1 - Use simulation! Only put things on the board when you are close to sure that they are right. For example, simulating BLKC and DACLRCK can be done in a simple testbench always begin AUD_BCLKr = 1'b0; #160; AUD_BCLKr = 1'b1; #160; end always begin AUD_DACLRCKr = 1'b0; #10240; AUD_DACLRCKr = 1'b1; #10240; end assign AUD_BCLK = AUD_BCLKr; assign AUD_DACLRCK = AUD_DACLRCKr; Solution 2 - Wire signals to GPIO pins (this requires an oscilloscope probe or a logic analyzer) We will discuss more sophisticated techniques later. 6:05 Slides on simulation Next Lecture: - Generating more sophisticated audio: Sine waves using CORDIC