1
0
mirror of https://github.com/aolofsson/oh.git synced 2025-01-17 20:02:53 +08:00

Fixing epiphany spi fetch

- adding a separate serializer for the remote fetch (cleaner)
- fixing the load signal to load on all bytes while ss low
- removing reset from command register
- review sync for spi...feels ok to use the rising edge of ss to sync to clock
(note, there must be a free running clk for remote fetch)
- adding wait pushback on remote fetch
This commit is contained in:
Andreas Olofsson 2016-04-07 18:39:39 -04:00
parent 42649ef2c1
commit 0a1690de94

View File

@ -5,12 +5,13 @@
//# License: MIT (see below) # //# License: MIT (see below) #
//############################################################################# //#############################################################################
`include "spi_regmap.vh"
module spi_slave_io(/*AUTOARG*/ module spi_slave_io(/*AUTOARG*/
// Outputs // Outputs
miso, spi_clk, spi_write, spi_addr, spi_wdata, spi_rdata, miso, spi_clk, spi_write, spi_addr, spi_wdata, spi_rdata,
access_out, packet_out, access_out, packet_out,
// Inputs // Inputs
sclk, mosi, ss, spi_en, cpol, cpha, lsbfirst, clk sclk, mosi, ss, spi_en, cpol, cpha, lsbfirst, clk, wait_in
); );
//################################# //#################################
@ -18,7 +19,7 @@ module spi_slave_io(/*AUTOARG*/
//################################# //#################################
//parameters //parameters
parameter SREGS = 16; // total regs (16/32/64) parameter SREGS = 16; // total regs (16/32/64)
parameter AW = 32; // address width parameter AW = 32; // address width
localparam PW = (2*AW+40); // packet width localparam PW = (2*AW+40); // packet width
@ -45,6 +46,7 @@ module spi_slave_io(/*AUTOARG*/
input clk; // core clock input clk; // core clock
output access_out; // read or write core command output access_out; // read or write core command
output [PW-1:0] packet_out; // packet output [PW-1:0] packet_out; // packet
input wait_in; // temporary pushback
//################################# //#################################
//# BODY //# BODY
@ -53,11 +55,11 @@ module spi_slave_io(/*AUTOARG*/
reg [1:0] spi_state; reg [1:0] spi_state;
reg [7:0] bit_count; reg [7:0] bit_count;
reg [7:0] command_reg; reg [7:0] command_reg;
reg packet_done_reg; reg access_out;
reg [PW-1:0] packet_out;
wire [7:0] rx_data; wire [7:0] rx_data;
wire [63:0] tx_data; wire [63:0] tx_data;
//################################# //#################################
//# STATE MACHINE //# STATE MACHINE
//################################# //#################################
@ -89,54 +91,64 @@ module spi_slave_io(/*AUTOARG*/
// command/address register // command/address register
// auto increment for every byte // auto increment for every byte
always @ (negedge sclk or posedge ss) always @ (negedge sclk)
if(ss) if((spi_state[1:0]==`SPI_CMD) & byte_done)
command_reg[7:0] <= 'b0;
else if((spi_state[1:0]==`SPI_CMD) & byte_done)
command_reg[7:0] <= rx_data[7:0]; command_reg[7:0] <= rx_data[7:0];
else if(byte_done) else if(byte_done)
command_reg[7:0] <= {command_reg[7:6], command_reg[7:0] <= {command_reg[7:6],
command_reg[5:0] + 1'b1}; command_reg[5:0] + 1'b1};
//################################# //#################################
//# RX SHIFT REGISTER //# SPI RX SHIFT REGISTER
//################################# //#################################
assign rx_shift = ~ss & spi_en; assign rx_shift = ~ss & spi_en;
oh_ser2par #(.PW(8), oh_ser2par #(.PW(8),
.SW(1)) .SW(1))
ser2par (// Outputs rx_ser2par (// Outputs
.dout (rx_data[7:0]), .dout (rx_data[7:0]),
// Inputs // Inputs
.clk (sclk), .clk (sclk),
.din (mosi), .din (mosi),
.lsbfirst (lsbfirst), //msb first .lsbfirst (lsbfirst), //msb first
.shift (rx_shift) .shift (rx_shift));
);
//####################################
//# REMOTE TRANSAXTION SHIFT REGISTER
//####################################
oh_ser2par #(.PW(PW),
.SW(1))
e_ser2par (// Outputs
.dout (packet_out[PW-1:0]),
// Inputs
.clk (sclk),
.din (mosi),
.lsbfirst (lsbfirst), //msb first
.shift (rx_shift));//rx_shift
//################################# //#################################
//# TX SHIFT REGISTER //# TX SHIFT REGISTER
//################################# //#################################
assign tx_load = byte_done & (spi_state[1:0]==`SPI_CMD); assign tx_load = byte_done; // & (spi_state[1:0]==`SPI_CMD);
assign tx_shift = ~ss & spi_en; assign tx_shift = ~ss & spi_en;
oh_par2ser #(.PW(8), oh_par2ser #(.PW(8),
.SW(1)) .SW(1))
par2ser (.dout (miso), tx_par2ser (.dout (miso),
.access_out (), .access_out (),
.wait_out (tx_wait), .wait_out (tx_wait),
.clk (sclk), // shift out on positive edge .clk (sclk), // shift out on positive edge
.nreset (~ss), .nreset (~ss),
.din (spi_rdata[7:0]), .din (spi_rdata[7:0]),
.shift (tx_shift), .shift (tx_shift),
.lsbfirst (lsbfirst), .lsbfirst (lsbfirst),
.load (tx_load), .load (tx_load),
.datasize (8'd7), .datasize (8'd7),
.fill (1'b0), .fill (1'b0),
.wait_in (1'b0) .wait_in (1'b0));
);
//################################# //#################################
//# REGISTER FILE INTERFACE //# REGISTER FILE INTERFACE
@ -146,33 +158,37 @@ module spi_slave_io(/*AUTOARG*/
assign spi_addr[5:0] = command_reg[5:0]; assign spi_addr[5:0] = command_reg[5:0];
assign spi_write = spi_en & assign spi_write = spi_en &
byte_done & byte_done &
(command_reg[7:6]==2'b00) & ~ss &
(command_reg[7:6]==`SPI_WR) &
(spi_state[1:0]==`SPI_DATA); (spi_state[1:0]==`SPI_DATA);
assign spi_remote = spi_en & assign spi_remote = spi_en &
ss & // wait until signal goes high ss & // wait until ss edge
command_reg[7:6]==2'b11; // send remote request command_reg[7:6]==`SPI_FETCH; // send remote request
assign spi_wdata[7:0] = rx_data[7:0]; assign spi_wdata[7:0] = rx_data[7:0];
//################################### //###################################
//# SYNCHRONIZATION TO CORE //# SYNCHRONIZATION SS TO CORE
//################################### //###################################
//sync the ss to free running clk //sync the ss to free running clk
//look for rising edge //look for rising edge
oh_dsync dsync (.dout (ss_sync), oh_dsync dsync (.dout (ss_sync),
.clk (clk), .clk (clk),
.din (spi_remote) .din (spi_remote));
);
//create single cycle pulse //create single cycle pulse
oh_rise2pulse r2p (.out (access_out), oh_rise2pulse r2p (.out (access_pulse),
.clk (clk), .clk (clk),
.in (ss_sync) .in (ss_sync));
);
// pipeleining and holding pulse if there is wait
always @ (posedge clk)
if(~wait_in)
access_out <= access_pulse;
endmodule // spi_slave_io endmodule // spi_slave_io
// Local Variables: // Local Variables: