Lecture 9 A Design Example Based on personal experience in S15 - PowerPoint PPT Presentation
Lecture 9 A Design Example Based on personal experience in S15 Design Process Read the documentation Realize it is incomplete make some guesses Design Hardware Thread Datapath + Controlling FSM Interface + Testbench Debug / Test / Repeat
Lecture 9 A Design Example Based on personal experience in S15
Design Process Read the documentation Realize it is incomplete ➙ make some guesses Design Hardware Thread Datapath + Controlling FSM Interface + Testbench Debug / Test / Repeat
NEXYS4 + Pmod Joystick Joystick + 2 LEDs + 3 pBtn Interface: microcontroller SPI communication 4-wire, 2-way interface X, Y position is 10-bits each
SPI Interface Master SS_L Slave SCK MOSI 4 wire-bus, single master, 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 MISO multiple slaves Slave Select: Active low signal to choose a device (SS or SS_L) SCK: clock, generated by the master, <1MHz MOSI: Master-out, slave-in data MISO: Master-in, slave-out data
Timing Diagram According to the Issues: documentation Which bit first? Max 1MHz SCK Clocking phase >15uS after SS_L until first bit shifts Shift 5 bytes of data per transaction >10uS between bytes
>15uS Tmin=1uS >10uS SCK SS_L MISO MOSI Answers I’ve figured out: MOSI sends MSB of LED Control Byte first LED Control Byte’s MSB must be a 1 (easy to overlook) SPI Mode is 1, not 0 (i.e. Docs are WRONG) MISO sends MSB of Byte 1 (X-low) first
Datapath Hardware First led[1:0] LED_REG D[1:0] load ld_LED_reg clear 1’b0 + interval counters CLK_100M Q[1:0] for 10uS, 15uS 38’h3A5A5A5A5A en_shift en D[39:0] load ld_shift + operation counters ShiftReg_PISO(RIGHT) CLK_100M serial_out MOSI for 8 bits, 5 bytes en_shift en ShiftReg_SIPO(LEFT) + divide-by-128 CLK_100M serial_in MISO Q[39:0] counter to generate RESULTS_REG D[39:0] load ld_results_reg clear 1’b0 SCK (390KHz) CLK_100M Q[39:0] X, Y, btn
assign sck = CLK_390K & en_sck; Datapath SV register #(2) LED_REG(.D(led), .Q(led_r), .load(ld_LED_reg), .clear(1'b0), .clock(CLK_100M), .*); logic [7:0] d_piso; assign d_piso = {led_r[0],led_r[1],6'b000001}; shift_PISO #(8) s1(.D(d_piso), .serial_out(mosi), .clock(CLK_100M), .load(ld_shift), assign X = {results[25:24], results[39:32]}; .en(en_piso_shift), assign Y = {results[9:8], results[23:16]}; .*); assign btn = results[2:0]; shift_SIPO #(40) s2(.Q(from_shift), .serial_in(miso), .clock(CLK_100M), .en(en_sipo_shift), .*); register #(40) RESULTS_REG(.D(from_shift), .Q(results), .load(ld_results_reg), .clear(1'b0), .clock(CLK_100M), .*);
Control FSM Inputs CLK_100M, reset, start_reg, start_shift, end_shift HA! Outputs slave select, reg_en, shift_load, reg_en 3 states, Mealy machine
reset ~start_transaction / not_slave_select start_transaction / ld_LED_reg, ld_15uS START ~done_15uS / WAIT_15uS ~CLK_390 / done_15uS / ~CLK_390K / ld_shift CLK_390K / WAIT_CLK_HIGH WAIT_CLK_LOW CLK_390K / ld_5Bytes, ld_8bits, en_sck, en_sipo_shift ~CLK_390K / en_sck, en_piso_shift CLOCKING_1 done_5Bytes / CLK_390K / en_sck ld_results_reg CLK_390K / ld_8bits, en_sipo_shift, en_5Bytes ~done_5Bytes & ~CLK_390K / ~done_5Bytes & CLOCKING_0 en_sck CLK_390K & ~done_8bits / en_sck, en_shift, INTRA_RESYNC en_8bits, en_sipo_shift done_10uS / ~done_5Bytes & ~CLK_390K CLK_390K & done_8bits / INTRA_BYTE ld_10uS ~done_10uS /
Selected FSM SV module fsm (input logic start_transaction, done_15uS, CLK_390K, done_10uS, done_5Bytes, input logic done_8bits, output logic ld_results_reg, ld_shift, ld_LED_reg, slave_select_L, ld_10uS, output logic ld_15uS, ld_5Bytes, ld_8bits, en_sck, en_sipo_shift, output logic en_piso_shift, en_5Bytes, en_8bits, input logic clock, reset); // clk is 100MHz enum logic [2:0] {START, WAIT_15uS, WAIT_CLK_LOW, WAIT_CLK_HIGH, CLOCKING_1, CLOCKING_0, INTRA_BYTE, INTRA_RESYNC} state, next_state; always_ff @(posedge clock, posedge reset) if (reset) state <= START; else state <= next_state;
case (state) START : begin next_state = (start_transaction) ? WAIT_15uS : START; if (start_transaction) begin ld_LED_reg = 1'b1; ld_15uS = 1'b1; end else slave_select_L = 1'b1; // just about all other times it is active end WAIT_15uS : begin next_state = (done_15uS) ? WAIT_CLK_LOW : WAIT_15uS; end WAIT_CLK_LOW : begin next_state = (CLK_390K) ? WAIT_CLK_LOW : WAIT_CLK_HIGH; ld_shift = ~CLK_390K; end WAIT_CLK_HIGH : begin next_state = (CLK_390K) ? CLOCKING_1 : WAIT_CLK_HIGH; if (CLK_390K) begin ld_5Bytes = 1'b1; ld_8bits = 1'b1; en_sck = 1'b1; en_sipo_shift = 1'b1; end end CLOCKING_1 : begin next_state = (CLK_390K) ? CLOCKING_1 : CLOCKING_0; en_piso_shift = ~CLK_390K; en_sck = 1'b1;
Did It W ork (V1.0)? NO! ➙ LD2 turned on, no other response Break out the logic analyzer (and the Test Point Header) SCK looks good. Nothing else does
Integrated Logic Analyzer Step 1: Mark some signals to be debugged In your SV Code `default_nettype none module JoystickPmod (input logic [1:0] led, input logic CLK_100M, reset, (* mark_debug = "true" *) input logic miso, output logic [9:0] X, Y, output logic [2:0] btn, // 2, 1, center (* mark_debug = "true" *) output logic mosi, ss, sck, output logic [3:0] debugger); (* mark_debug = "true" *) logic [39:0] interrim_results; assign interrim_results = results;
Can also mark them in the Debug View ➙ Nets Right click and select “Mark Debug” This is AFTER synthesis There is a way to mark them in the Constraints file I don’t know how
ILA Step 2: Inserting Debug Core In Synthesis Flow (on left), choose Setup Debug A wizard will appear You can add additional nets to debug on page 2 You can setup Trigger and Storage settings (pg 3) I haven’t explored “Advanced Trigger” and “Capture Control” but they look promising
Step 3 Implement and Generate Bitstream This will take significantly longer You are including a complex ILA debug core on your FPGA, so it makes sense it will take longer
Step 4: Use ILA from Hardware Manager And there was much rejoicing!! I needed a lot of storage depth (32K samples), as SPI is rather slow and each sample is at the 100MHz clock rate
Documentation Error PA7 is a NEXYS4 schematic name, as is PA8, PA9, PA10 SS is PA7, MOSI is PA8, MISO is PA9, SCK is PA10
Config file Notice, no curly braces if signal isn’t a vector
Lessons Learned Process Documentation, Design, Datapath hardware, FSM Test, Debug Documentation is always insufficient Sometimes because you haven’t read it right
Recommend
More recommend
Explore More Topics
Stay informed with curated content and fresh updates.