mirror of https://github.com/efabless/caravel.git
Update to the back-door wishbone access to housekeeping to better
implement the arbitration between SPI and back-door. The back-door access flags when it is going to do a read or write, and the SPI can have an invalid read or fail a write if the SPI is too fast, but the wishbone access should be valid. As long as the SPI is much slower than the core clock (say, 1MHz) then there should be no contention, which means that contention can always be avoided simply by slowing the SPI signaling down.
This commit is contained in:
parent
e6a94449ce
commit
a7fec91c4c
|
@ -316,6 +316,7 @@ module housekeeping #(
|
|||
reg [7:0] wbbd_data; /* SPI data translated from WB */
|
||||
reg wbbd_sck; /* wishbone access trigger (back-door clock) */
|
||||
reg wbbd_write; /* wishbone write trigger (back-door strobe) */
|
||||
reg wbbd_busy; /* Raised during a wishbone read or write */
|
||||
reg wb_ack_o; /* acknowledge signal back to wishbone bus */
|
||||
reg [31:0] wb_dat_o; /* data output to wishbone bus */
|
||||
|
||||
|
@ -636,11 +637,13 @@ module housekeeping #(
|
|||
wbbd_write <= 1'b0;
|
||||
wbbd_addr <= 8'd0;
|
||||
wbbd_data <= 8'd0;
|
||||
wbbd_busy <= 1'b0;
|
||||
wb_ack_o <= 1'b0;
|
||||
wbbd_state <= `WBBD_IDLE;
|
||||
end else begin
|
||||
case (wbbd_state)
|
||||
`WBBD_IDLE: begin
|
||||
wbbd_busy <= 1'b0;
|
||||
if (wb_cyc_i && (sys_select | gpio_select | spi_select)) begin
|
||||
wb_ack_o <= 1'b0;
|
||||
wbbd_state <= `WBBD_SETUP0;
|
||||
|
@ -653,6 +656,7 @@ module housekeeping #(
|
|||
wbbd_data <= wb_dat_i[7:0];
|
||||
end
|
||||
wbbd_write <= wb_sel_i[0] & wb_we_i;
|
||||
wbbd_busy <= 1'b1;
|
||||
|
||||
// If the SPI is being accessed and about to read or
|
||||
// write a byte, then stall until the SPI is ready.
|
||||
|
@ -661,11 +665,13 @@ module housekeeping #(
|
|||
end
|
||||
end
|
||||
`WBBD_RW0: begin
|
||||
wbbd_busy <= 1'b1;
|
||||
wbbd_sck <= 1'b1;
|
||||
wb_dat_o[7:0] <= odata;
|
||||
wbbd_state <= `WBBD_SETUP1;
|
||||
end
|
||||
`WBBD_SETUP1: begin
|
||||
wbbd_busy <= 1'b1;
|
||||
wbbd_sck <= 1'b0;
|
||||
wbbd_addr <= spiaddr(wb_adr_i + 1);
|
||||
if (wb_sel_i[1] & wb_we_i) begin
|
||||
|
@ -677,11 +683,13 @@ module housekeeping #(
|
|||
end
|
||||
end
|
||||
`WBBD_RW1: begin
|
||||
wbbd_busy <= 1'b1;
|
||||
wbbd_sck <= 1'b1;
|
||||
wb_dat_o[15:8] <= odata;
|
||||
wbbd_state <= `WBBD_SETUP2;
|
||||
end
|
||||
`WBBD_SETUP2: begin
|
||||
wbbd_busy <= 1'b1;
|
||||
wbbd_sck <= 1'b0;
|
||||
wbbd_addr <= spiaddr(wb_adr_i + 2);
|
||||
if (wb_sel_i[2] & wb_we_i) begin
|
||||
|
@ -693,11 +701,13 @@ module housekeeping #(
|
|||
end
|
||||
end
|
||||
`WBBD_RW2: begin
|
||||
wbbd_busy <= 1'b1;
|
||||
wbbd_sck <= 1'b1;
|
||||
wb_dat_o[23:16] <= odata;
|
||||
wbbd_state <= `WBBD_SETUP3;
|
||||
end
|
||||
`WBBD_SETUP3: begin
|
||||
wbbd_busy <= 1'b1;
|
||||
wbbd_sck <= 1'b0;
|
||||
wbbd_addr <= spiaddr(wb_adr_i + 3);
|
||||
if (wb_sel_i[3] & wb_we_i) begin
|
||||
|
@ -709,12 +719,14 @@ module housekeeping #(
|
|||
end
|
||||
end
|
||||
`WBBD_RW3: begin
|
||||
wbbd_busy <= 1'b1;
|
||||
wbbd_sck <= 1'b1;
|
||||
wb_dat_o[31:24] <= odata;
|
||||
wb_ack_o <= 1'b1; // Release hold on wishbone bus
|
||||
wbbd_state <= `WBBD_DONE;
|
||||
end
|
||||
`WBBD_DONE: begin
|
||||
wbbd_busy <= 1'b1;
|
||||
wbbd_sck <= 1'b0;
|
||||
wb_ack_o <= 1'b0; // Reset for next access
|
||||
wbbd_write <= 1'b0;
|
||||
|
@ -964,13 +976,15 @@ module housekeeping #(
|
|||
|
||||
// SPI Data transfer protocol. The wishbone back door may only be
|
||||
// used if the front door is closed (CSB is high or the CSB pin is
|
||||
// not an input). To do: Provide an independent way to disable
|
||||
// the SPI.
|
||||
// not an input). The time to apply values for the back door access
|
||||
// is limited to the clock cycle around the read or write from the
|
||||
// wbbd state machine (see below).
|
||||
|
||||
assign caddr = (wbbd_busy) ? wbbd_addr : iaddr;
|
||||
assign csclk = (wbbd_busy) ? wbbd_sck : ((spi_is_active) ? mgmt_gpio_in[4] : 1'b0);
|
||||
assign cdata = (wbbd_busy) ? wbbd_data : idata;
|
||||
assign cwstb = (wbbd_busy) ? wbbd_write : wrstb;
|
||||
|
||||
assign caddr = (spi_is_busy) ? iaddr : wbbd_addr;
|
||||
assign csclk = (spi_is_busy) ? mgmt_gpio_in[4] : wbbd_sck;
|
||||
assign cdata = (spi_is_busy) ? idata : wbbd_data;
|
||||
assign cwstb = (spi_is_busy) ? wrstb : wbbd_write;
|
||||
assign odata = fdata(caddr);
|
||||
|
||||
// Register mapping and I/O to SPI interface module
|
||||
|
|
Loading…
Reference in New Issue