Lecture 9 A Design Example - uidaho.edu · A Design Example Based on personal experience in S15....

Post on 17-Jun-2020

0 views 0 download

Transcript of Lecture 9 A Design Example - uidaho.edu · A Design Example Based on personal experience in S15....

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

4 wire-bus, single master, 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

0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7

Master Slave

MOSI

MISO

SS_L

SCK

Timing Diagram

According to the documentation

Max 1MHz SCK

>15uS after SS_L until first bit shifts

Shift 5 bytes of data per transaction

>10uS between bytes

Issues:

Which bit first?

Clocking phase

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

Tmin=1uS

SCK

SS_L

MOSI

>15uS >10uS

MISO

Datapath Hardware First

ShiftReg_PISO(RIGHT)

ShiftReg_SIPO(LEFT)

led[1:0]

loadclear

D[1:0]

Q[1:0]CLK_100M

load

CLK_100M

LED_REG

D[39:0]

serial_out

CLK_100M serial_inQ[39:0]

D[39:0]

Q[39:0]

loadclear

CLK_100M

1’b0

1’b0

ld_LED_reg

ld_shift

ld_results_reg

RESULTS_REG

MISO

MOSI

38’h3A5A5A5A5A

X, Y, btn

en

en

en_shift

en_shift

+ interval counters for 10uS, 15uS

+ operation counters for 8 bits, 5 bytes

+ divide-by-128 counter to generate

SCK (390KHz)

assign sck = CLK_390K & en_sck;

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), .en(en_piso_shift), .*);

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), .*);

assign X = {results[25:24], results[39:32]}; assign Y = {results[9:8], results[23:16]}; assign btn = results[2:0];

Datapath SV

Control FSM

Inputs

CLK_100M, reset, start_reg, start_shift, end_shift

Outputs

slave select, reg_en, shift_load, reg_en

3 states, Mealy machine

HA!

START

WAIT_CLK_LOW

WAIT_15uS

reset~start_transaction /not_slave_select

start_transaction / ld_LED_reg, ld_15uS

~done_15uS /

done_15uS /

CLK_390K /

CLK_390K / ld_5Bytes, ld_8bits, en_sck, en_sipo_shift

CLOCKING_1 CLK_390K / en_sck

CLOCKING_0

INTRA_BYTE

~CLK_390K / en_sck, en_piso_shift

done_5Bytes / ld_results_reg

~done_5Bytes & ~CLK_390K / en_sck ~done_5Bytes &

CLK_390K & ~done_8bits / en_sck, en_shift, en_8bits, en_sipo_shift

~done_5Bytes & CLK_390K & done_8bits / ld_10uS

~done_10uS /

done_10uS /

WAIT_CLK_HIGH~CLK_390K / ld_shift

~CLK_390 /

INTRA_RESYNC

CLK_390K / ld_8bits, en_sipo_shift, en_5Bytes

~CLK_390K

Selected FSM SVmodule 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 Work (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

Notice, no curly braces if signal isn’t a vector

Config file

Lessons Learned

Process

Documentation, Design, Datapath hardware, FSM

Test, Debug

Documentation is always insufficient

Sometimes because you haven’t read it right