|
@@ -147,7 +147,7 @@ module spirom (
|
|
|
|
|
|
.wrclk ( rom_clk ),
|
|
|
.data ( spi_in_data ),
|
|
|
- .wrreq ( spi_in_req_q ),
|
|
|
+ .wrreq ( spi_in_req_q & is_spi ),
|
|
|
.wrusedw ( wrusedw ),
|
|
|
|
|
|
.rdclk ( ram_clk ),
|
|
@@ -238,6 +238,7 @@ module spirom (
|
|
|
reg spi_more_q;
|
|
|
reg spi_active;
|
|
|
reg [3:0] spi_cs_ctr;
|
|
|
+ reg [31:0] spi_out_shr;
|
|
|
|
|
|
// Explicit synchronizers for handshake signals
|
|
|
synchronizer #(.width(1)) go_spi_synchro
|
|
@@ -255,11 +256,15 @@ module spirom (
|
|
|
.q ( spi_active_s )
|
|
|
);
|
|
|
|
|
|
+ // 64/4 = 16 bytes min space
|
|
|
+ wire dma_queue_space = (~wrusedw) >= 12'd128;
|
|
|
+
|
|
|
always @(negedge rst_n or posedge rom_clk)
|
|
|
if (~rst_n)
|
|
|
begin
|
|
|
spi_cmd_ctr <= 6'b0;
|
|
|
spi_clk_en <= 1'b0;
|
|
|
+ spi_clk_en_q <= 1'b0;
|
|
|
spi_data_ctr <= 27'b0;
|
|
|
spi_cs_n <= 1'b1;
|
|
|
spi_cs_ctr <= 'b0;
|
|
@@ -270,12 +275,17 @@ module spirom (
|
|
|
spi_in_shr <= 32'b0;
|
|
|
spi_active <= 1'b0;
|
|
|
spi_more_q <= 1'b0;
|
|
|
+ spi_out_shr <= 32'b0;
|
|
|
end
|
|
|
else
|
|
|
begin
|
|
|
spi_in_req <= 1'b0;
|
|
|
spi_in_req_q <= spi_in_req;
|
|
|
spi_clk_en <= 1'b0;
|
|
|
+ spi_clk_en_q <= spi_clk_en;
|
|
|
+
|
|
|
+ // Bit to start transmitting on the next clock down transition
|
|
|
+ spi_out_shr <= spi_out_shr << spi_clk_en;
|
|
|
|
|
|
// After asserting CS#, wait 16 SPI clock times
|
|
|
if (spi_cs_n)
|
|
@@ -292,6 +302,7 @@ module spirom (
|
|
|
spi_active <= 1'b1;
|
|
|
spi_cs_n <= 1'b0;
|
|
|
spi_more_q <= spi_more;
|
|
|
+ spi_out_shr <= romcmd;
|
|
|
end
|
|
|
else if ( ~|{spi_data_ctr, spi_cmd_ctr} )
|
|
|
begin
|
|
@@ -308,8 +319,10 @@ module spirom (
|
|
|
|
|
|
if ( spi_active )
|
|
|
begin
|
|
|
- // 64/4 = 16 bytes min space
|
|
|
- spi_clk_en <= (~wrusedw) >= 12'd128;
|
|
|
+ // This will block unnecessarily if the DMA queue
|
|
|
+ // is full from a previous transaction, but that doesn't
|
|
|
+ // matter in practice... just let it drain.
|
|
|
+ spi_clk_en <= dma_queue_space;
|
|
|
|
|
|
if ( spi_clk_en )
|
|
|
begin
|
|
@@ -336,30 +349,15 @@ module spirom (
|
|
|
end // else: !if(~rst_n)
|
|
|
|
|
|
// SPI output data is shifted on the negative edge
|
|
|
- reg [31:0] spi_out_shr;
|
|
|
- reg spi_clk_en_q;
|
|
|
+ reg spi_out_q;
|
|
|
+ always @(negedge rom_clk)
|
|
|
+ spi_out_q <= spi_out_shr[31];
|
|
|
|
|
|
- assign spi_io[0] = spi_mosi_en ? spi_out_shr[31] : 1'bz;
|
|
|
+ assign spi_io[0] = spi_mosi_en ? spi_out_q : 1'bz;
|
|
|
assign spi_io[1] = 1'bz;
|
|
|
|
|
|
- always @(negedge rst_n or negedge rom_clk)
|
|
|
- if (~rst_n)
|
|
|
- begin
|
|
|
- spi_out_shr <= 32'b0;
|
|
|
- spi_clk_en_q <= 1'b0;
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- spi_clk_en_q <= spi_clk_en;
|
|
|
-
|
|
|
- if (~spi_active)
|
|
|
- spi_out_shr <= romcmd;
|
|
|
- else if ( spi_clk_en_q )
|
|
|
- spi_out_shr <= { spi_out_shr[30:0], 1'b0 };
|
|
|
- end
|
|
|
-
|
|
|
//
|
|
|
- // SPI_SCK output buffer
|
|
|
+ // SPI_SCK output buffer: emit a clock pulse iff spi_clk_en_q is high
|
|
|
//
|
|
|
ddio_out spi_clk_buf (
|
|
|
.aclr ( ~rst_n ),
|