Lecture 9 A Design Example
Based on personal experience in S15
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
Based on personal experience in S15
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
1 2 3 4 5 6 7 1 2 3 4 5 6 7 Master Slave MOSI MISO SS_L SCK
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
Tmin=1uS SCK SS_L MOSI >15uS >10uS MISO
ShiftReg_PISO(RIGHT) ShiftReg_SIPO(LEFT) led[1:0] load clear D[1:0] Q[1:0] CLK_100M load CLK_100M LED_REG D[39:0] serial_out CLK_100M serial_in Q[39:0] D[39:0] Q[39:0] load clear 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
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];
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
module fsm (input logic start_transaction, done_15uS, CLK_390K, done_10uS, done_5Bytes, input logic done_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;
`default_nettype none module JoystickPmod (input logic [1:0] led, input logic CLK_100M, reset, (* mark_debug = "true" *) input logic miso,
(* mark_debug = "true" *) output logic mosi, ss, sck,
(* mark_debug = "true" *) logic [39:0] interrim_results; assign interrim_results = results;