From 8c350eed911532253128ec2dca22260ad8c1e192 Mon Sep 17 00:00:00 2001 From: Andreas Olofsson Date: Wed, 9 Mar 2016 22:46:24 -0500 Subject: [PATCH] Debugged most of SPI -Changed to FIFO on TX path (cleaner) -No good solution on RX with CDC since clock can stop, so you can't use an async fifo. -Slave needs cleanup, rethink... -Using commong par2ser and ser2par blocks --- common/hdl/oh_ser2par.v | 92 +++++++++++++++------- spi/dv/tests/test_basic.emf | 19 +++-- spi/hdl/spi.v | 2 +- spi/hdl/spi_master.v | 69 +++++++++++----- spi/hdl/spi_master_fifo.v | 133 +++++++++++++++++++++++++++++++ spi/hdl/spi_master_io.v | 152 ++++++++++++++++++++++++------------ spi/hdl/spi_master_regs.v | 98 ++++++----------------- spi/hdl/spi_regmap.vh | 14 ++-- spi/hdl/spi_slave_io.v | 64 +++++++++++---- spi/hdl/spi_slave_regs.v | 21 +---- 10 files changed, 445 insertions(+), 219 deletions(-) create mode 100644 spi/hdl/spi_master_fifo.v diff --git a/common/hdl/oh_ser2par.v b/common/hdl/oh_ser2par.v index 045830b..14547b8 100644 --- a/common/hdl/oh_ser2par.v +++ b/common/hdl/oh_ser2par.v @@ -1,37 +1,75 @@ +//############################################################################# +//# Purpose: Serial to Parallel Converter # +//############################################################################# +//# Author: Andreas Olofsson # +//# License: MIT (see below) # +//############################################################################# -//convert serial stream to parallel module oh_ser2par (/*AUTOARG*/ + // Outputs + dout, // Inputs - clk, din, dout + clk, din, lsbfirst, shift ); - //############################################################### - //# Interface - //############################################################### + //########################### + //# INTERFACE + //########################### - input clk; //sampling clock - input din; //serial data - output [DW-1:0] dout; //parallel data - - parameter DW = 64; //width of converter - parameter TYPE = "MSB"; //MSB first or LSB first - - //############################################################### + // parameters + parameter PW = 64; // parallel packet width + parameter SW = 1; // serial packet width + localparam CW = $clog2(PW/SW); // serialization factor (for counter) + + // reset, clk + input clk; // sampling clock + + //data interface + input [SW-1:0] din; // serial data + output [PW-1:0] dout; // parallel data + + // control interface + input lsbfirst; // lsb first order + input shift; // shift the shifter + + //############################## //# BODY - //############################################################### - reg [DW-1:0] dout; - generate - if(TYPE=="MSB") - begin - always @ (posedge clk) - dout[DW-1:0] = {dout[DW-2:0],din}; - end - else - begin - always @ (posedge clk) - dout[DW-1:0] = {din,dout[DW-1:1]}; - end - endgenerate + //############################## + + reg [PW-1:0] dout; + reg [CW-1:0] count; + wire [PW-1:0] shiftdata; + + always @ (posedge clk) + if(shift & lsbfirst) + dout[PW-1:0] <= {din[SW-1:0],dout[PW-1:SW]}; + else if(shift) + dout[PW-1:0] <= {dout[PW-SW-1:0],din[SW-1:0]}; endmodule // oh_ser2par +/////////////////////////////////////////////////////////////////////////////// +// The MIT License (MIT) // +// // +// Copyright (c) 2015-2016, Adapteva, Inc. // +// // +// Permission is hereby granted, free of charge, to any person obtaining a // +// copy of this software and associated documentation files (the "Software") // +// to deal in the Software without restriction, including without limitation // +// the rights to use, copy, modify, merge, publish, distribute, sublicense, // +// and/or sell copies of the Software, and to permit persons to whom the // +// Software is furnished to do so, subject to the following conditions: // +// // +// The above copyright notice and this permission notice shall be included // +// in all copies or substantial portions of the Software. // +// // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT // +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR // +// THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +// // +/////////////////////////////////////////////////////////////////////////////// + diff --git a/spi/dv/tests/test_basic.emf b/spi/dv/tests/test_basic.emf index 3a0654f..cf0a7cf 100644 --- a/spi/dv/tests/test_basic.emf +++ b/spi/dv/tests/test_basic.emf @@ -1,11 +1,14 @@ -DEADBEEF_99999999_00000000_05_0010 //write gpio_oen -DEADBEEF_FFFFFFFF_00000008_05_0010 //write gpio_out -DEADBEEF_BBBBBBBB_00000010_05_0010 //write gpio_ien -DEADBEEF_CCCCCCCC_00000018_05_0010 //write gpio_in -DEADBEEF_11111111_00000020_05_0010 //write gpio_outand -DEADBEEF_22222222_00000028_05_0010 //write gpio_outorr -DEADBEEF_FFFFFFFF_00000030_05_0010 //write gpio_outxor -DEADBEEF_55555555_00000038_05_0010 //write gpio_irqmask +DEADBEEF_00000000_00000000_01_0000 //CONFIG (DEFAULT) +DEADBEEF_00000000_00000004_01_0000 //STATUS (CLEAR) +DEADBEEF_00000003_00000008_01_0020 //CLKDIV (BAUDRATE, DIVIDE by 8) +DEADBEEF_00000021_00000020_01_0000 //TX DATA (B0) +DEADBEEF_00000043_00000020_01_0000 //TX DATA (B1) +DEADBEEF_00000065_00000020_01_0000 //TX DATA (B2) +DEADBEEF_00000087_00000020_01_0000 //TX DATA (B3) + + + + diff --git a/spi/hdl/spi.v b/spi/hdl/spi.v index a3cc108..5e13910 100644 --- a/spi/hdl/spi.v +++ b/spi/hdl/spi.v @@ -1,5 +1,5 @@ //############################################################################# -//# Purpose: SPI top (configuravbe as master or slave) # +//# Purpose: SPI top (configurable as master or slave) # //############################################################################# //# Author: Andreas Olofsson # //# License: MIT (see below) # diff --git a/spi/hdl/spi_master.v b/spi/hdl/spi_master.v index 0717713..198d8f7 100644 --- a/spi/hdl/spi_master.v +++ b/spi/hdl/spi_master.v @@ -13,6 +13,7 @@ module spi_master(/*AUTOARG*/ ); //parameters + parameter DEPTH = 16; // fifo depth parameter REGS = 16; // total regs parameter AW = 32; // addresss width localparam PW = (2*AW+40); // packet width @@ -43,28 +44,32 @@ module spi_master(/*AUTOARG*/ /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [7:0] clkdiv_reg; // From spi_master_regs of spi_master_regs.v - wire [7:0] cmd_reg; // From spi_master_regs of spi_master_regs.v wire cpha; // From spi_master_regs of spi_master_regs.v wire cpol; // From spi_master_regs of spi_master_regs.v - wire [7:0] psize_reg; // From spi_master_regs of spi_master_regs.v + wire emode; // From spi_master_regs of spi_master_regs.v + wire [7:0] fifo_dout; // From spi_master_fifo of spi_master_fifo.v + wire fifo_empty; // From spi_master_fifo of spi_master_fifo.v + wire fifo_read; // From spi_master_io of spi_master_io.v + wire lsbfirst; // From spi_master_regs of spi_master_regs.v wire rx_access; // From spi_master_io of spi_master_io.v wire [7:0] rx_data; // From spi_master_io of spi_master_io.v wire spi_en; // From spi_master_regs of spi_master_regs.v - wire [2:0] spi_state; // From spi_master_io of spi_master_io.v - wire tx_access; // From spi_master_regs of spi_master_regs.v - wire [PW-1:0] tx_data; // From spi_master_regs of spi_master_regs.v + wire [1:0] spi_state; // From spi_master_io of spi_master_io.v // End of automatics + + + //##################################################### + //# Master control registers + //##################################################### spi_master_regs #(.AW(AW)) spi_master_regs (/*AUTOINST*/ // Outputs - .tx_access (tx_access), - .cmd_reg (cmd_reg[7:0]), - .tx_data (tx_data[PW-1:0]), .cpol (cpol), .cpha (cpha), + .lsbfirst (lsbfirst), + .emode (emode), .spi_en (spi_en), - .psize_reg (psize_reg[7:0]), .clkdiv_reg (clkdiv_reg[7:0]), .wait_out (wait_out), .access_out (access_out), @@ -74,16 +79,44 @@ module spi_master(/*AUTOARG*/ .nreset (nreset), .rx_data (rx_data[PW-1:0]), .rx_access (rx_access), - .spi_state (spi_state[2:0]), + .spi_state (spi_state[1:0]), .access_in (access_in), .packet_in (packet_in[PW-1:0]), .wait_in (wait_in)); - spi_master_io #(.AW(AW) - ) + //##################################################### + //# Transmit FIFO (SPI_TX) + //##################################################### + + /* spi_master_fifo AUTO_TEMPLATE (.fifo_dout (fifo_dout[7:0]), + ); + */ + + spi_master_fifo #(.AW(AW), + .DEPTH(DEPTH)) + + spi_master_fifo(/*AUTOINST*/ + // Outputs + .wait_out (wait_out), + .fifo_empty (fifo_empty), + .fifo_dout (fifo_dout[7:0]), // Templated + // Inputs + .clk (clk), + .nreset (nreset), + .emode (emode), + .access_in (access_in), + .packet_in (packet_in[PW-1:0]), + .fifo_read (fifo_read)); + + //##################################################### + //# SPI IO (8 bit) + //##################################################### + + spi_master_io #(.AW(AW)) spi_master_io (/*AUTOINST*/ // Outputs - .spi_state (spi_state[2:0]), + .spi_state (spi_state[1:0]), + .fifo_read (fifo_read), .rx_data (rx_data[7:0]), .rx_access (rx_access), .sclk (sclk), @@ -95,16 +128,14 @@ module spi_master(/*AUTOARG*/ .spi_en (spi_en), .cpol (cpol), .cpha (cpha), + .lsbfirst (lsbfirst), .clkdiv_reg (clkdiv_reg[7:0]), - .psize_reg (psize_reg[7:0]), - .cmd_reg (cmd_reg[7:0]), - .tx_data (tx_data[PW-1:0]), - .tx_access (tx_access), + .fifo_dout (fifo_dout[7:0]), + .fifo_empty (fifo_empty), .miso (miso)); -endmodule // spi_slave - +endmodule // spi_master ////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // diff --git a/spi/hdl/spi_master_fifo.v b/spi/hdl/spi_master_fifo.v new file mode 100644 index 0000000..4f6a53e --- /dev/null +++ b/spi/hdl/spi_master_fifo.v @@ -0,0 +1,133 @@ +`include "spi_regmap.vh" +module spi_master_fifo (/*AUTOARG*/ + // Outputs + wait_out, fifo_empty, fifo_dout, + // Inputs + clk, nreset, emode, access_in, packet_in, fifo_read + ); + //##################################################################### + //# INTERFACE + //##################################################################### + + //parameters + parameter DEPTH = 16; // fifo entries + parameter AW = 32; // architecture address width + parameter SW = 8; // output packet width + localparam PW = 2*AW+40; // input packet width + localparam FAW = $clog2(DEPTH); // fifo address width + localparam SRW = $clog2(PW/SW); // serializer cycle count width + + //clk,reset, cfg + input clk; // clk + input nreset; // async active low reset + input emode; // epiphany transfer mode + + // Incoming interface + input access_in; // access by core + input [PW-1:0] packet_in; + output wait_out; + + // IO interface + input fifo_read; + output fifo_empty; + output [SW-1:0] fifo_dout; + + //################################## + //# BODY + //################################## + + wire [SRW-1:0] datasize; + wire [PW-1:0] tx_data; + wire [SW-1:0] fifo_din; + + /*AUTOWIRE*/ + // Beginning of automatic wires (for undeclared instantiated-module outputs) + wire [4:0] ctrlmode_in; // From p2e of packet2emesh.v + wire [AW-1:0] data_in; // From p2e of packet2emesh.v + wire [1:0] datamode_in; // From p2e of packet2emesh.v + wire [AW-1:0] dstaddr_in; // From p2e of packet2emesh.v + wire [AW-1:0] srcaddr_in; // From p2e of packet2emesh.v + wire write_in; // From p2e of packet2emesh.v + // End of automatics + + //################################## + //# DECODE + //################################### + + packet2emesh p2e (/*AUTOINST*/ + // Outputs + .write_in (write_in), + .datamode_in (datamode_in[1:0]), + .ctrlmode_in (ctrlmode_in[4:0]), + .dstaddr_in (dstaddr_in[AW-1:0]), + .srcaddr_in (srcaddr_in[AW-1:0]), + .data_in (data_in[AW-1:0]), + // Inputs + .packet_in (packet_in[PW-1:0])); + + + assign datasize[SRW-1:0] = emode ? (PW/SW) : + (1<>1)); + assign baud_match = (baud_counter[7:0]==((1 << clkdiv_reg[7:0]) - 1'b1)); + assign phase_match = (baud_counter[7:0]==((1 << (clkdiv_reg[7:0]) >> 1) - 1'b1)); //################################# //# CHIP SELECT //################################# - assign ss = (spi_state==`SPI_IDLE); + assign ss = (spi_state[1:0]==`SPI_IDLE); //################################# //# SCLK GENERATOR //################################# - //TODO!! + //TODO: implement cpol/cpha (cpha=0 for now) + always @ (posedge clk) + if(spi_state[1:0]!=`SPI_DATA) + sclk <= 1'b0; + else if(phase_match) + sclk <= 1'b1; + else if(baud_match) + sclk <= 1'b0; + //################################# //# RX/TX SHIFT REGISTER //################################# - - always @ (posedge clk) - if (tx_access) - tx_shiftreg[PW-1:0] <= tx_data[PW-1:0]; - else if(baud_match) - tx_shiftreg[PW-1:0] <= {tx_shiftreg[PW-2:0],miso}; - assign mosi = tx_shiftreg[PW-1]; - - assign rx_data[7:0] = tx_shiftreg[7:0]; - - + oh_par2ser #(.PW(8), + .SW(1)) + par2ser (// Outputs + .dout (mosi), // serial output + .access_out (), + .wait_out (), + // Inputs + .clk (clk), + .nreset (nreset), // async active low reset + .din (fifo_dout[7:0]), // 8 bit data from fifo + .shift (shift), // shift on neg edge + .datasize (3'b111), // 8 bits + .load (load_byte), // load data from fifo + .lsbfirst (lsbfirst), // serializer direction + .fill (miso), // fill with slave data + .wait_in (1'b0) // no wait + ); + endmodule // spi_slave_io // Local Variables: // verilog-library-directories:("." "../../common/hdl" "../../emesh/hdl") // End: + +/////////////////////////////////////////////////////////////////////////////// +// The MIT License (MIT) // +// // +// Copyright (c) 2015-2016, Adapteva, Inc. // +// // +// Permission is hereby granted, free of charge, to any person obtaining a // +// copy of this software and associated documentation files (the "Software") // +// to deal in the Software without restriction, including without limitation // +// the rights to use, copy, modify, merge, publish, distribute, sublicense, // +// and/or sell copies of the Software, and to permit persons to whom the // +// Software is furnished to do so, subject to the following conditions: // +// // +// The above copyright notice and this permission notice shall be included // +// in all copies or substantial portions of the Software. // +// // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT // +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR // +// THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +// // +/////////////////////////////////////////////////////////////////////////////// + + diff --git a/spi/hdl/spi_master_regs.v b/spi/hdl/spi_master_regs.v index 55c7464..0335d17 100644 --- a/spi/hdl/spi_master_regs.v +++ b/spi/hdl/spi_master_regs.v @@ -7,16 +7,16 @@ `include "spi_regmap.vh" module spi_master_regs (/*AUTOARG*/ // Outputs - tx_access, cmd_reg, tx_data, cpol, cpha, spi_en, psize_reg, - clkdiv_reg, wait_out, access_out, packet_out, + cpol, cpha, lsbfirst, emode, spi_en, clkdiv_reg, wait_out, + access_out, packet_out, // Inputs clk, nreset, rx_data, rx_access, spi_state, access_in, packet_in, wait_in ); //parameters - parameter CLKDIV = 16; // default clkdiv - parameter PSIZE = 32; // default is 32 bits + parameter CLKDIV = 1; // default clkdiv + parameter PSIZE = 0; // default is 32 bits parameter AW = 32; // addresss width localparam PW = (2*AW+40); // packet width @@ -25,20 +25,17 @@ module spi_master_regs (/*AUTOARG*/ input nreset; // async active low reset //io interface - output tx_access; // start the transfer - output [7:0] cmd_reg; // first 8 bites to send - output [PW-1:0] tx_data; // data payload - input [PW-1:0] rx_data; // rx data input rx_access; // rx access pulse //control output cpol; - output cpha; + output cpha; + output lsbfirst; // send lsbfirst + output emode; // send emesh transaction output spi_en; // enable transmitter - output [7:0] psize_reg; // packet size output [7:0] clkdiv_reg; // baud rate setting - input [2:0] spi_state; // transmit state + input [1:0] spi_state; // transmit state //packet to transmit input access_in; // access from core @@ -57,7 +54,7 @@ module spi_master_regs (/*AUTOARG*/ reg [7:0] config_reg; reg [7:0] status_reg; reg [7:0] cmd_reg; - reg [7:0] psize_reg; + reg [31:0] psize_reg; reg [7:0] clkdiv_reg; reg [63:0] tx_reg[3:0]; reg [7:0] rx_reg; @@ -100,14 +97,7 @@ module spi_master_regs (/*AUTOARG*/ assign config_write = reg_write & (dstaddr_in[7:2]==`SPI_CONFIG); assign status_write = reg_write & (dstaddr_in[7:2]==`SPI_STATUS); - assign cmd_write = reg_write & (dstaddr_in[7:2]==`SPI_CMD); - assign psize_write = reg_write & (dstaddr_in[7:2]==`SPI_PSIZE); assign clkdiv_write = reg_write & (dstaddr_in[7:2]==`SPI_CLKDIV); - assign tx_write = reg_write & (dstaddr_in[7:2]==`SPI_TX); - assign tx_manualstart = reg_write & (dstaddr_in[7:2]==`SPI_START); - - //autostart on write to lowest tx register - assign tx_autostart = tx_write & (dstaddr_in[4:3]==2'b00); //#################################### //# CONFIG @@ -119,15 +109,15 @@ module spi_master_regs (/*AUTOARG*/ else if(config_write) config_reg[7:0] <= data_in[7:0]; - assign spi_en = config_reg[0]; // enable spi - assign irq_en = config_reg[1]; // enable interrupt - assign cpol = config_reg[2]; // cpol - assign cpha = config_reg[3]; // cpha - assign auto_mode = config_reg[4]; // auto starts transfer on tx write - - assign tx_access = auto_mode ? tx_autostart : - tx_manualstart; - + assign spi_en = config_reg[0]; // enable spi + assign irq_en = config_reg[1]; // enable interrupt + assign cpol = config_reg[2]; // cpol + assign cpha = config_reg[3]; // cpha + assign lsbfirst = config_reg[4]; // send lsb first + assign manual_ss = config_reg[5]; // manually control ss pin + assign rxauto_mode = config_reg[6]; // rx auto return mode + assign emode = config_reg[7]; // emesh transfer mode + //#################################### //# STATUS //#################################### @@ -138,21 +128,10 @@ module spi_master_regs (/*AUTOARG*/ else if(status_write) status_reg[7:0] <= reg_wdata[7:0]; else - status_reg[7:0] <= {4'b0, //7:4 - spi_state[2:0], //3:1 + status_reg[7:0] <= {4'b0, //7:3 + spi_state[1:0], //2:1 (rx_access | status_reg[0])};//0 - - - //#################################### - //# PSIZE (packet size) - //#################################### - - always @ (posedge clk or negedge nreset) - if (~nreset) - psize_reg[7:0] <= PSIZE; - else if(psize_write) - psize_reg[7:0] <= reg_wdata[7:0]; - + //#################################### //# CLKDIV //#################################### @@ -160,16 +139,9 @@ module spi_master_regs (/*AUTOARG*/ always @ (posedge clk or negedge nreset) if (~nreset) clkdiv_reg[7:0] <= CLKDIV; - else if(psize_write) + else if(clkdiv_write) clkdiv_reg[7:0] <= reg_wdata[7:0]; - - //#################################### - //# COMMAND REG - //#################################### - always @ (posedge clk or negedge nreset) - if(cmd_write) - cmd_reg[7:0] <= reg_wdata[7:0]; - + //#################################### //# RX REG //#################################### @@ -177,30 +149,6 @@ module spi_master_regs (/*AUTOARG*/ if(rx_access) rx_reg[7:0] <= rx_data[7:0]; - //#################################### - //# TX REGS - //#################################### - - //auto start on writing to lowest tx data register - - - assign write_mask[63:0] = (datamode_in[1:0]==2'b00) ? 64'h00000000000000FF : - (datamode_in[1:0]==2'b01) ? 64'h000000000000FFFF : - (datamode_in[1:0]==2'b10) ? 64'h00000000FFFFFFFF : - 64'hFFFFFFFFFFFFFFFF; - - always @ (posedge clk) - for(i=0;i<64;i=i+1) - if(tx_write & write_mask[i]) - tx_reg[dstaddr_in[4:3]][i] <= reg_wdata[i]; - - assign tx_vector[255:0]= {tx_reg[3], - tx_reg[2], - tx_reg[1], - tx_reg[0]}; - //only taking - assign tx_data[PW-1:0] = tx_vector[PW-1:0]; - endmodule // spi_master_regs // Local Variables: diff --git a/spi/hdl/spi_regmap.vh b/spi/hdl/spi_regmap.vh index c3cc81f..610b330 100644 --- a/spi/hdl/spi_regmap.vh +++ b/spi/hdl/spi_regmap.vh @@ -3,14 +3,12 @@ `define GPIO_REGMAP_V_ `define SPI_CONFIG 6'd0 // config register `define SPI_STATUS 6'd1 // status register - `define SPI_CMD 6'd2 // command register (first byte) - `define SPI_PSIZE 6'd3 // package size (32 bits) - `define SPI_CLKDIV 6'd4 // baud rate (master) - `define SPI_START 6'd5 // manual transfer (master) - `define SPI_JUNK 6'd6 // reserved - `define SPI_JUNK 6'd7 // reserved - `define SPI_TX 6'd8 // 4 regs for tx x 32 - `define SPI_RX 6'd12 // 4 regs for rx x 32 + `define SPI_CLKDIV 6'd2 // baud rate (master) + `define SPI_CMD 6'd3 // manual ss control (master) + `define SPI_RXADDR0 6'd4 // auto return address (31:0) + `define SPI_RXADDR1 6'd6 // auto return address (63:32) + `define SPI_TX 6'd8 // TX FIFO + `define SPI_RX 6'd12 // RX FIFO `endif // `ifndef GPIO_REGMAP_V_ diff --git a/spi/hdl/spi_slave_io.v b/spi/hdl/spi_slave_io.v index 20e4fa6..a1a7cc3 100644 --- a/spi/hdl/spi_slave_io.v +++ b/spi/hdl/spi_slave_io.v @@ -46,23 +46,31 @@ module spi_slave_io(/*AUTOARG*/ //################################# reg [2:0] spi_state; - reg [7:0] bit_count; - reg [PW-1:0] spi_rx; + reg [7:0] bit_count; reg [PW-1:0] spi_tx; reg spi_access; reg packet_done_reg; reg spi_request; reg [PW-1:0] packet_out; wire [7:0] psize; - + wire [PW-1:0] rx_data; + //################################# //# RX SHIFT REGISTER //################################# - - always @ (posedge sclk) - if(~ss) - spi_rx[PW-1:0] <= {spi_rx[PW-2:0],mosi}; + + oh_ser2par #(.PW(PW), + .SW(1)) + ser2par (// Outputs + .dout (rx_data[PW-1:0]), + // Inputs + .clk (sclk), + .din (mosi), + .lsbfirst (1'b0), //msb first + .shift (~ss) + ); + //################################# //# STATE MACHINE //################################# @@ -106,17 +114,18 @@ module spi_slave_io(/*AUTOARG*/ else bit_count[7:0] <= bit_count[7:0] + 1'b1; - assign read_cmd = (spi_rx[7:6]==2'b10) & + assign read_cmd = (rx_data[7:6]==2'b10) & (spi_state[2:0]==`SPI_CMD); - assign write_cmd = (spi_rx[7:6]==2'b00) & + assign write_cmd = (rx_data[7:6]==2'b00) & (spi_state[2:0]==`SPI_CMD); - assign remote_cmd = (spi_rx[7:6]==2'b11) & + assign remote_cmd = (rx_data[7:6]==2'b11) & (spi_state[2:0]==`SPI_CMD); assign byte_done = &bit_count[2:0]; + //change to sl? assign packet_done = (bit_count[7:0]==psize[7:0]); //################################# @@ -127,7 +136,7 @@ module spi_slave_io(/*AUTOARG*/ always @ (posedge sclk) if(load_tx) - spi_tx[7:0] <= spi_regs[spi_rx[6:0]]; // + spi_tx[7:0] <= spi_regs[rx_data[6:0]]; // else if(~ss) spi_tx[7:0] <= {spi_tx[6:0],1'b0}; @@ -137,10 +146,10 @@ module spi_slave_io(/*AUTOARG*/ //# REGISTER FILE INTERFACE //################################# assign spi_clk = sclk; - assign spi_addr[5:0] = spi_rx[5:0]; + assign spi_addr[5:0] = rx_data[5:0]; assign spi_write = byte_done & (spi_state[2:0]==`SPI_WRITE); assign spi_read = byte_done & (spi_state[2:0]==`SPI_READ); - assign spi_data[7:0] = spi_rx[7:0]; + assign spi_data[7:0] = rx_data[7:0]; //################################# //# CLOCK SYNCHRONIZATION @@ -173,9 +182,34 @@ module spi_slave_io(/*AUTOARG*/ //sample rx data always @ (posedge clk) if(spi_access_pulse) - packet_out[PW-1:0] <= spi_rx[PW-1:0]; + packet_out[PW-1:0] <= rx_data[PW-1:0]; endmodule // spi_slave_io // Local Variables: // verilog-library-directories:("." "../../common/hdl") -// +// End: + +/////////////////////////////////////////////////////////////////////////////// +// The MIT License (MIT) // +// // +// Copyright (c) 2015-2016, Adapteva, Inc. // +// // +// Permission is hereby granted, free of charge, to any person obtaining a // +// copy of this software and associated documentation files (the "Software") // +// to deal in the Software without restriction, including without limitation // +// the rights to use, copy, modify, merge, publish, distribute, sublicense, // +// and/or sell copies of the Software, and to permit persons to whom the // +// Software is furnished to do so, subject to the following conditions: // +// // +// The above copyright notice and this permission notice shall be included // +// in all copies or substantial portions of the Software. // +// // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT // +// OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR // +// THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +// // +/////////////////////////////////////////////////////////////////////////////// diff --git a/spi/hdl/spi_slave_regs.v b/spi/hdl/spi_slave_regs.v index 3e25aa5..46bfc38 100644 --- a/spi/hdl/spi_slave_regs.v +++ b/spi/hdl/spi_slave_regs.v @@ -61,7 +61,6 @@ module spi_slave_regs (/*AUTOARG*/ //##################################### assign spi_config_write = spi_write & (spi_addr[5:0]==`SPI_CONFIG); - assign spi_psize_write = spi_write & (spi_addr[5:0]==`SPI_PSIZE); assign spi_user_write = spi_write & (|spi_addr[5:4]); //##################################### @@ -108,17 +107,7 @@ module spi_slave_regs (/*AUTOARG*/ //##################################### //TBD - - //##################################### - //# PACKET SIZE [3] - //##################################### - - always @ (posedge spi_clk or negedge nreset) - if(!nreset) - spi_psize[7:0] <= PW; - else if(spi_psize_write) - spi_psize[7:0] <= spi_data[7:0]; - + //##################################### //# CORE DATA [15:8] //##################################### @@ -147,10 +136,10 @@ module spi_slave_regs (/*AUTOARG*/ //8 standard regs spi_vector[7:0] = spi_config[7:0]; //0 spi_vector[15:8] = spi_status[7:0]; //1 - spi_vector[23:16] = spi_cmd[7:0]; //2 - spi_vector[31:24] = spi_psize[7:0]; //3 + spi_vector[23:16] = 8'b0; //2 + spi_vector[31:24] = spi_cmd[7:0]; //3 spi_vector[63:32] = 32'b0; //7:4 - spi_vector[127:64] = 64'b0; //15:8 + spi_vector[127:64] = 64'b0; //15:8 //16 core data tx vector spi_vector[255:128] = core_regs[63:0]; //16 core data rx vector @@ -160,8 +149,6 @@ module spi_slave_regs (/*AUTOARG*/ spi_vector[512+i*8 +:8] = user_regs[i]; end - - endmodule // spi_slave_regs // Local Variables: