Additional corrections, mostly to the housekeeping module. The

top-level simulation now passes the GPIO testbench.
This commit is contained in:
Tim Edwards 2021-10-17 21:38:40 -04:00
parent 1863a7c529
commit 33ca4e11ef
2 changed files with 524 additions and 518 deletions

View File

@ -371,18 +371,18 @@ module caravel (
// Primary SPI flash controller // Primary SPI flash controller
.flash_csb(flash_csb_core), .flash_csb(flash_csb_core),
.flash_clk(flash_clk_core), .flash_clk(flash_clk_core),
.flash_io0_oeb(flash_io0_oeb), .flash_io0_oeb(flash_io0_oeb_core),
.flash_io0_di(flash_io0_di), .flash_io0_di(flash_io0_di_core),
.flash_io0_do(flash_io0_do), .flash_io0_do(flash_io0_do_core),
.flash_io1_oeb(flash_io1_oeb), .flash_io1_oeb(flash_io1_oeb_core),
.flash_io1_di(flash_io1_di), .flash_io1_di(flash_io1_di_core),
.flash_io1_do(flash_io1_do), .flash_io1_do(flash_io1_do_core),
.flash_io2_oeb(flash_io2_oeb), .flash_io2_oeb(flash_io2_oeb_core),
.flash_io2_di(flash_io2_di), .flash_io2_di(flash_io2_di_core),
.flash_io2_do(flash_io2_do), .flash_io2_do(flash_io2_do_core),
.flash_io3_oeb(flash_io3_oeb), .flash_io3_oeb(flash_io3_oeb_core),
.flash_io3_di(flash_io3_di), .flash_io3_di(flash_io3_di_core),
.flash_io3_do(flash_io3_do), .flash_io3_do(flash_io3_do_core),
// Exported Wishbone Bus // Exported Wishbone Bus
.mprj_cyc_o(mprj_cyc_o_core), .mprj_cyc_o(mprj_cyc_o_core),

View File

@ -307,16 +307,16 @@ module housekeeping #(
// made to read 4 bytes from the SPI to fill data on the wishbone bus // made to read 4 bytes from the SPI to fill data on the wishbone bus
// before sending ACK and letting the processor continue. // before sending ACK and letting the processor continue.
`define WBD_IDLE 4'h0 /* Back door access is idle */ `define WBBD_IDLE 4'h0 /* Back door access is idle */
`define WBD_SETUP0 4'h1 /* Apply address and data for byte 1 of 4 */ `define WBBD_SETUP0 4'h1 /* Apply address and data for byte 1 of 4 */
`define WBD_RW0 4'h2 /* Latch data for byte 1 of 4 */ `define WBBD_RW0 4'h2 /* Latch data for byte 1 of 4 */
`define WBD_SETUP1 4'h3 /* Apply address and data for byte 2 of 4 */ `define WBBD_SETUP1 4'h3 /* Apply address and data for byte 2 of 4 */
`define WBD_RW1 4'h4 /* Latch data for byte 2 of 4 */ `define WBBD_RW1 4'h4 /* Latch data for byte 2 of 4 */
`define WBD_SETUP2 4'h5 /* Apply address and data for byte 3 of 4 */ `define WBBD_SETUP2 4'h5 /* Apply address and data for byte 3 of 4 */
`define WBD_RW2 4'h6 /* Latch data for byte 3 of 4 */ `define WBBD_RW2 4'h6 /* Latch data for byte 3 of 4 */
`define WBD_SETUP3 4'h7 /* Apply address and data for byte 4 of 4 */ `define WBBD_SETUP3 4'h7 /* Apply address and data for byte 4 of 4 */
`define WBD_RW3 4'h8 /* Latch data for byte 4 of 4 */ `define WBBD_RW3 4'h8 /* Latch data for byte 4 of 4 */
`define WBD_DONE 4'h9 /* Send ACK back to wishbone */ `define WBBD_DONE 4'h9 /* Send ACK back to wishbone */
assign sys_select = (wb_adr_i[31:8] == SYS_BASE_ADR[31:8]); assign sys_select = (wb_adr_i[31:8] == SYS_BASE_ADR[31:8]);
assign gpio_select = (wb_adr_i[31:8] == GPIO_BASE_ADR[31:8]); assign gpio_select = (wb_adr_i[31:8] == GPIO_BASE_ADR[31:8]);
@ -404,7 +404,7 @@ module housekeeping #(
8'h41 : fdata = gpio_configure[26][7:0]; 8'h41 : fdata = gpio_configure[26][7:0];
8'h42 : fdata = {3'b000, gpio_configure[27][12:8]}; 8'h42 : fdata = {3'b000, gpio_configure[27][12:8]};
8'h43 : fdata = gpio_configure[27][7:0]; 8'h43 : fdata = gpio_configure[27][7:0];
8'h44 : fdata = {3'b000, gpio_configure[27][12:8]}; 8'h44 : fdata = {3'b000, gpio_configure[28][12:8]};
8'h45 : fdata = gpio_configure[28][7:0]; 8'h45 : fdata = gpio_configure[28][7:0];
8'h46 : fdata = {3'b000, gpio_configure[29][12:8]}; 8'h46 : fdata = {3'b000, gpio_configure[29][12:8]};
8'h47 : fdata = gpio_configure[29][7:0]; 8'h47 : fdata = gpio_configure[29][7:0];
@ -436,8 +436,10 @@ module housekeeping #(
8'h5d : fdata = {4'b0000, pwr_ctrl_out}; 8'h5d : fdata = {4'b0000, pwr_ctrl_out};
// GPIO Control (bit bang and automatic) // GPIO Control (bit bang and automatic)
// NOTE: "serial_busy" is the read-back signal occupying the same
// address/bit as "serial_xfer".
8'h5e : fdata = {2'b00, serial_data_2, serial_data_1, serial_bb_clock, 8'h5e : fdata = {2'b00, serial_data_2, serial_data_1, serial_bb_clock,
serial_bb_resetn, serial_bb_enable, serial_xfer}; serial_bb_resetn, serial_bb_enable, serial_busy};
/* Clocking control */ /* Clocking control */
8'h5f : fdata = {6'b000000, pll_dco_ena, pll_ena}; 8'h5f : fdata = {6'b000000, pll_dco_ena, pll_ena};
@ -459,110 +461,118 @@ module housekeeping #(
/* Memory map address to SPI address translation for back door access */ /* Memory map address to SPI address translation for back door access */
/* (see doc/memory_map.txt) */ /* (see doc/memory_map.txt) */
wire [3:0] gpio_adr = GPIO_BASE_ADR[23:20];
wire [3:0] sys_adr = SYS_BASE_ADR[23:20];
wire [3:0] spi_adr = SPI_BASE_ADR[23:20];
function [7:0] spiaddr(input [31:0] wbaddress); function [7:0] spiaddr(input [31:0] wbaddress);
begin begin
case ({wbaddress[27], wbaddress[24], wbaddress[7:0]}) /* Address taken from lower 8 bits and upper 4 bits of the 32-bit */
10'h300 : spiaddr = 8'h09; /* wishbone address. */
10'h304 : spiaddr = 8'h0a; case ({wbaddress[23:20], wbaddress[7:0]})
10'h304 : spiaddr = 8'h0b; sys_adr | 12'h000 : spiaddr = 8'h09;
10'h025 : spiaddr = 8'h0c; sys_adr | 12'h004 : spiaddr = 8'h0a;
10'h024 : spiaddr = 8'h0d; sys_adr | 12'h004 : spiaddr = 8'h0b;
10'h029 : spiaddr = 8'h0e;
10'h028 : spiaddr = 8'h0f; gpio_adr | 12'h025 : spiaddr = 8'h0c;
10'h02d : spiaddr = 8'h10; gpio_adr | 12'h024 : spiaddr = 8'h0d;
10'h02c : spiaddr = 8'h11; gpio_adr | 12'h029 : spiaddr = 8'h0e;
10'h031 : spiaddr = 8'h12; gpio_adr | 12'h028 : spiaddr = 8'h0f;
10'h030 : spiaddr = 8'h13; gpio_adr | 12'h02d : spiaddr = 8'h10;
10'h035 : spiaddr = 8'h14; gpio_adr | 12'h02c : spiaddr = 8'h11;
10'h034 : spiaddr = 8'h15; gpio_adr | 12'h031 : spiaddr = 8'h12;
10'h039 : spiaddr = 8'h16; gpio_adr | 12'h030 : spiaddr = 8'h13;
10'h038 : spiaddr = 8'h17; gpio_adr | 12'h035 : spiaddr = 8'h14;
10'h03d : spiaddr = 8'h18; gpio_adr | 12'h034 : spiaddr = 8'h15;
10'h03c : spiaddr = 8'h19; gpio_adr | 12'h039 : spiaddr = 8'h16;
10'h041 : spiaddr = 8'h1a; gpio_adr | 12'h038 : spiaddr = 8'h17;
10'h040 : spiaddr = 8'h1b; gpio_adr | 12'h03d : spiaddr = 8'h18;
10'h045 : spiaddr = 8'h1c; gpio_adr | 12'h03c : spiaddr = 8'h19;
10'h044 : spiaddr = 8'h1d; gpio_adr | 12'h041 : spiaddr = 8'h1a;
10'h049 : spiaddr = 8'h1e; gpio_adr | 12'h040 : spiaddr = 8'h1b;
10'h048 : spiaddr = 8'h1f; gpio_adr | 12'h045 : spiaddr = 8'h1c;
10'h04d : spiaddr = 8'h20; gpio_adr | 12'h044 : spiaddr = 8'h1d;
10'h04c : spiaddr = 8'h21; gpio_adr | 12'h049 : spiaddr = 8'h1e;
10'h051 : spiaddr = 8'h22; gpio_adr | 12'h048 : spiaddr = 8'h1f;
10'h050 : spiaddr = 8'h23; gpio_adr | 12'h04d : spiaddr = 8'h20;
10'h055 : spiaddr = 8'h24; gpio_adr | 12'h04c : spiaddr = 8'h21;
10'h054 : spiaddr = 8'h25; gpio_adr | 12'h051 : spiaddr = 8'h22;
10'h059 : spiaddr = 8'h26; gpio_adr | 12'h050 : spiaddr = 8'h23;
10'h058 : spiaddr = 8'h27; gpio_adr | 12'h055 : spiaddr = 8'h24;
10'h05d : spiaddr = 8'h28; gpio_adr | 12'h054 : spiaddr = 8'h25;
10'h05c : spiaddr = 8'h29; gpio_adr | 12'h059 : spiaddr = 8'h26;
10'h061 : spiaddr = 8'h2a; gpio_adr | 12'h058 : spiaddr = 8'h27;
10'h060 : spiaddr = 8'h2b; gpio_adr | 12'h05d : spiaddr = 8'h28;
10'h065 : spiaddr = 8'h2c; gpio_adr | 12'h05c : spiaddr = 8'h29;
10'h064 : spiaddr = 8'h2d; gpio_adr | 12'h061 : spiaddr = 8'h2a;
10'h069 : spiaddr = 8'h2e; gpio_adr | 12'h060 : spiaddr = 8'h2b;
10'h068 : spiaddr = 8'h2f; gpio_adr | 12'h065 : spiaddr = 8'h2c;
10'h06d : spiaddr = 8'h30; gpio_adr | 12'h064 : spiaddr = 8'h2d;
10'h06c : spiaddr = 8'h31; gpio_adr | 12'h069 : spiaddr = 8'h2e;
10'h071 : spiaddr = 8'h32; gpio_adr | 12'h068 : spiaddr = 8'h2f;
10'h070 : spiaddr = 8'h33; gpio_adr | 12'h06d : spiaddr = 8'h30;
10'h075 : spiaddr = 8'h34; gpio_adr | 12'h06c : spiaddr = 8'h31;
10'h074 : spiaddr = 8'h35; gpio_adr | 12'h071 : spiaddr = 8'h32;
10'h079 : spiaddr = 8'h36; gpio_adr | 12'h070 : spiaddr = 8'h33;
10'h078 : spiaddr = 8'h37; gpio_adr | 12'h075 : spiaddr = 8'h34;
10'h07d : spiaddr = 8'h38; gpio_adr | 12'h074 : spiaddr = 8'h35;
10'h07c : spiaddr = 8'h39; gpio_adr | 12'h079 : spiaddr = 8'h36;
10'h081 : spiaddr = 8'h3a; gpio_adr | 12'h078 : spiaddr = 8'h37;
10'h080 : spiaddr = 8'h3b; gpio_adr | 12'h07d : spiaddr = 8'h38;
10'h085 : spiaddr = 8'h3c; gpio_adr | 12'h07c : spiaddr = 8'h39;
10'h084 : spiaddr = 8'h3d; gpio_adr | 12'h081 : spiaddr = 8'h3a;
10'h089 : spiaddr = 8'h3e; gpio_adr | 12'h080 : spiaddr = 8'h3b;
10'h088 : spiaddr = 8'h3f; gpio_adr | 12'h085 : spiaddr = 8'h3c;
10'h08d : spiaddr = 8'h40; gpio_adr | 12'h084 : spiaddr = 8'h3d;
10'h08c : spiaddr = 8'h41; gpio_adr | 12'h089 : spiaddr = 8'h3e;
10'h091 : spiaddr = 8'h42; gpio_adr | 12'h088 : spiaddr = 8'h3f;
10'h090 : spiaddr = 8'h43; gpio_adr | 12'h08d : spiaddr = 8'h40;
10'h095 : spiaddr = 8'h44; gpio_adr | 12'h08c : spiaddr = 8'h41;
10'h094 : spiaddr = 8'h45; gpio_adr | 12'h091 : spiaddr = 8'h42;
10'h099 : spiaddr = 8'h46; gpio_adr | 12'h090 : spiaddr = 8'h43;
10'h098 : spiaddr = 8'h47; gpio_adr | 12'h095 : spiaddr = 8'h44;
10'h09d : spiaddr = 8'h48; gpio_adr | 12'h094 : spiaddr = 8'h45;
10'h09c : spiaddr = 8'h49; gpio_adr | 12'h099 : spiaddr = 8'h46;
10'h0a1 : spiaddr = 8'h4a; gpio_adr | 12'h098 : spiaddr = 8'h47;
10'h0a0 : spiaddr = 8'h4b; gpio_adr | 12'h09d : spiaddr = 8'h48;
10'h0a5 : spiaddr = 8'h4c; gpio_adr | 12'h09c : spiaddr = 8'h49;
10'h0a4 : spiaddr = 8'h4d; gpio_adr | 12'h0a1 : spiaddr = 8'h4a;
10'h0a9 : spiaddr = 8'h4e; gpio_adr | 12'h0a0 : spiaddr = 8'h4b;
10'h0a8 : spiaddr = 8'h4f; gpio_adr | 12'h0a5 : spiaddr = 8'h4c;
10'h0ad : spiaddr = 8'h50; gpio_adr | 12'h0a4 : spiaddr = 8'h4d;
10'h0ac : spiaddr = 8'h51; gpio_adr | 12'h0a9 : spiaddr = 8'h4e;
10'h0b1 : spiaddr = 8'h52; gpio_adr | 12'h0a8 : spiaddr = 8'h4f;
10'h0b0 : spiaddr = 8'h53; gpio_adr | 12'h0ad : spiaddr = 8'h50;
10'h0b5 : spiaddr = 8'h54; gpio_adr | 12'h0ac : spiaddr = 8'h51;
10'h0b4 : spiaddr = 8'h55; gpio_adr | 12'h0b1 : spiaddr = 8'h52;
10'h0b9 : spiaddr = 8'h56; gpio_adr | 12'h0b0 : spiaddr = 8'h53;
10'h0b8 : spiaddr = 8'h57; gpio_adr | 12'h0b5 : spiaddr = 8'h54;
10'h010 : spiaddr = 8'h58; gpio_adr | 12'h0b4 : spiaddr = 8'h55;
10'h00f : spiaddr = 8'h59; gpio_adr | 12'h0b9 : spiaddr = 8'h56;
10'h00e : spiaddr = 8'h5a; gpio_adr | 12'h0b8 : spiaddr = 8'h57;
10'h00d : spiaddr = 8'h5b; gpio_adr | 12'h010 : spiaddr = 8'h58;
10'h00c : spiaddr = 8'h5c; gpio_adr | 12'h00f : spiaddr = 8'h59;
10'h000 : spiaddr = 8'h5e; gpio_adr | 12'h00e : spiaddr = 8'h5a;
10'h004 : spiaddr = 8'h5d; gpio_adr | 12'h00d : spiaddr = 8'h5b;
10'h00c : spiaddr = 8'h5c; gpio_adr | 12'h00c : spiaddr = 8'h5c;
10'h00d : spiaddr = 8'h5b; gpio_adr | 12'h000 : spiaddr = 8'h5e;
10'h00e : spiaddr = 8'h5a; gpio_adr | 12'h004 : spiaddr = 8'h5d;
10'h00f : spiaddr = 8'h59; gpio_adr | 12'h00c : spiaddr = 8'h5c;
10'h010 : spiaddr = 8'h58; gpio_adr | 12'h00d : spiaddr = 8'h5b;
10'h20c : spiaddr = 8'h5f; gpio_adr | 12'h00e : spiaddr = 8'h5a;
10'h210 : spiaddr = 8'h60; gpio_adr | 12'h00f : spiaddr = 8'h59;
10'h214 : spiaddr = 8'h61; gpio_adr | 12'h010 : spiaddr = 8'h58;
10'h218 : spiaddr = 8'h62;
10'h21f : spiaddr = 8'h63; spi_adr | 12'h00c : spiaddr = 8'h5f;
10'h21e : spiaddr = 8'h64; spi_adr | 12'h010 : spiaddr = 8'h60;
10'h21d : spiaddr = 8'h65; spi_adr | 12'h014 : spiaddr = 8'h61;
10'h21c : spiaddr = 8'h66; spi_adr | 12'h018 : spiaddr = 8'h62;
10'h220 : spiaddr = 8'h67; spi_adr | 12'h01f : spiaddr = 8'h63;
10'h224 : spiaddr = 8'h68; spi_adr | 12'h01e : spiaddr = 8'h64;
spi_adr | 12'h01d : spiaddr = 8'h65;
spi_adr | 12'h01c : spiaddr = 8'h66;
spi_adr | 12'h020 : spiaddr = 8'h67;
spi_adr | 12'h024 : spiaddr = 8'h68;
default : spiaddr = 8'h00; default : spiaddr = 8'h00;
endcase endcase
end end
@ -577,99 +587,77 @@ module housekeeping #(
wbbd_addr <= 8'd0; wbbd_addr <= 8'd0;
wbbd_data <= 8'd0; wbbd_data <= 8'd0;
wb_ack_o <= 1'b0; wb_ack_o <= 1'b0;
wbbd_state <= `WBBD_IDLE;
end else begin end else begin
case (wbbd_state) case (wbbd_state)
`WBD_IDLE: begin `WBBD_IDLE: begin
if ((|wb_sel_i) && wb_cyc_i && if (wb_cyc_i && (sys_select | gpio_select | spi_select)) begin
(sys_select | gpio_select | spi_select)) begin wb_ack_o <= 1'b0;
wb_ack_o <= 1'b1; wbbd_state <= `WBBD_SETUP0;
wbbd_state <= `WBD_SETUP0;
end end
end end
`WBD_SETUP0: begin `WBBD_SETUP0: begin
wbbd_sck <= 1'b0; wbbd_sck <= 1'b0;
if (sys_select) begin wbbd_addr <= spiaddr(wb_adr_i);
wbbd_addr <= spiaddr(wb_adr_i[7:0]);
end else if (gpio_select) begin
wbbd_addr <= spiaddr(wb_adr_i[7:0]);
end else if (spi_select) begin
wbbd_addr <= spiaddr(wb_adr_i[7:0]);
end
if (wb_sel_i[0] & wb_we_i) begin if (wb_sel_i[0] & wb_we_i) begin
wbbd_data <= wb_dat_i[7:0]; wbbd_data <= wb_dat_i[7:0];
end end
wbbd_write <= wb_sel_i[0] & wb_we_i; wbbd_write <= wb_sel_i[0] & wb_we_i;
wbbd_state <= `WBD_RW0; wbbd_state <= `WBBD_RW0;
end end
`WBD_RW0: begin `WBBD_RW0: begin
wbbd_sck <= 1'b1; wbbd_sck <= 1'b1;
wb_dat_o[7:0] <= odata; wb_dat_o[7:0] <= odata;
wbbd_state <= `WBD_SETUP1; wbbd_state <= `WBBD_SETUP1;
end end
`WBD_SETUP1: begin `WBBD_SETUP1: begin
wbbd_sck <= 1'b0; wbbd_sck <= 1'b0;
if (sys_select) begin wbbd_addr <= spiaddr(wb_adr_i + 1);
wbbd_addr <= spiaddr(wb_adr_i[7:0] + 1);
end else if (gpio_select) begin
wbbd_addr <= spiaddr(wb_adr_i[7:0] + 1);
end else if (spi_select) begin
wbbd_addr <= spiaddr(wb_adr_i[7:0] + 1);
end
if (wb_sel_i[1] & wb_we_i) begin if (wb_sel_i[1] & wb_we_i) begin
wbbd_data <= wb_dat_i[15:8]; wbbd_data <= wb_dat_i[15:8];
end end
wbbd_write <= wb_sel_i[1] & wb_we_i; wbbd_write <= wb_sel_i[1] & wb_we_i;
wbbd_state <= `WBD_RW1; wbbd_state <= `WBBD_RW1;
end end
`WBD_RW1: begin `WBBD_RW1: begin
wbbd_sck <= 1'b1; wbbd_sck <= 1'b1;
wb_dat_o[15:8] <= odata; wb_dat_o[15:8] <= odata;
wbbd_state <= `WBD_SETUP2; wbbd_state <= `WBBD_SETUP2;
end end
`WBD_SETUP2: begin `WBBD_SETUP2: begin
wbbd_sck <= 1'b0; wbbd_sck <= 1'b0;
if (sys_select) begin wbbd_addr <= spiaddr(wb_adr_i + 2);
wbbd_addr <= spiaddr(wb_adr_i[7:0] + 2);
end else if (gpio_select) begin
wbbd_addr <= spiaddr(wb_adr_i[7:0] + 2);
end else if (spi_select) begin
wbbd_addr <= spiaddr(wb_adr_i[7:0] + 2);
end
if (wb_sel_i[2] & wb_we_i) begin if (wb_sel_i[2] & wb_we_i) begin
wbbd_data <= wb_dat_i[23:16]; wbbd_data <= wb_dat_i[23:16];
end end
wbbd_write <= wb_sel_i[2] & wb_we_i; wbbd_write <= wb_sel_i[2] & wb_we_i;
wbbd_state <= `WBD_RW2; wbbd_state <= `WBBD_RW2;
end end
`WBD_RW2: begin `WBBD_RW2: begin
wbbd_sck <= 1'b1; wbbd_sck <= 1'b1;
wb_dat_o[23:16] <= odata; wb_dat_o[23:16] <= odata;
wbbd_state <= `WBD_SETUP3; wbbd_state <= `WBBD_SETUP3;
end end
`WBD_SETUP3: begin `WBBD_SETUP3: begin
wbbd_sck <= 1'b0; wbbd_sck <= 1'b0;
if (sys_select) begin wbbd_addr <= spiaddr(wb_adr_i + 3);
wbbd_addr <= spiaddr(wb_adr_i[7:0] + 3);
end else if (gpio_select) begin
wbbd_addr <= spiaddr(wb_adr_i[7:0] + 3);
end else if (spi_select) begin
wbbd_addr <= spiaddr(wb_adr_i[7:0] + 3);
end
if (wb_sel_i[3] & wb_we_i) begin if (wb_sel_i[3] & wb_we_i) begin
wbbd_data <= wb_dat_i[31:24]; wbbd_data <= wb_dat_i[31:24];
end end
wbbd_write <= wb_sel_i[3] & wb_we_i; wbbd_write <= wb_sel_i[3] & wb_we_i;
wbbd_state <= `WBD_RW3; wbbd_state <= `WBBD_RW3;
end end
`WBD_RW3: begin `WBBD_RW3: begin
wbbd_sck <= 1'b1; wbbd_sck <= 1'b1;
wb_dat_o[31:24] <= odata; wb_dat_o[31:24] <= odata;
wbbd_state <= `WBD_DONE; wb_ack_o <= 1'b1; // Release hold on wishbone bus
wbbd_state <= `WBBD_DONE;
end end
`WBD_DONE: begin `WBBD_DONE: begin
wbbd_sck <= 1'b0; wbbd_sck <= 1'b0;
wb_ack_o <= 1'b0; // Release hold on wishbone bus wb_ack_o <= 1'b0; // Reset for next access
wbbd_state <= `WBD_IDLE; wbbd_write <= 1'b0;
wbbd_state <= `WBBD_IDLE;
end end
endcase endcase
end end
@ -780,11 +768,12 @@ module housekeeping #(
reg [3:0] xfer_count; reg [3:0] xfer_count;
reg [4:0] pad_count_1; reg [4:0] pad_count_1;
reg [4:0] pad_count_2; reg [5:0] pad_count_2;
reg [1:0] xfer_state; reg [1:0] xfer_state;
reg serial_clock; reg serial_clock;
reg serial_resetn; reg serial_resetn;
reg serial_busy;
wire serial_data_1; wire serial_data_1;
wire serial_data_2; wire serial_data_2;
reg [IO_CTRL_BITS-1:0] serial_data_staging_1; reg [IO_CTRL_BITS-1:0] serial_data_staging_1;
@ -807,6 +796,7 @@ module housekeeping #(
serial_clock <= 1'b0; serial_clock <= 1'b0;
serial_data_staging_1 <= 0; serial_data_staging_1 <= 0;
serial_data_staging_2 <= 0; serial_data_staging_2 <= 0;
serial_busy <= 1'b0;
end else begin end else begin
@ -818,6 +808,9 @@ module housekeeping #(
serial_clock <= 1'b0; serial_clock <= 1'b0;
if (serial_xfer == 1'b1) begin if (serial_xfer == 1'b1) begin
xfer_state <= `GPIO_START; xfer_state <= `GPIO_START;
serial_busy <= 1'b1;
end else begin
serial_busy <= 1'b0;
end end
end end
`GPIO_START: begin `GPIO_START: begin
@ -860,14 +853,12 @@ module housekeeping #(
*/ */
if (xfer_count == 4'd0) begin if (xfer_count == 4'd0) begin
serial_clock <= 1'b1; serial_clock <= 1'b1;
serial_resetn <= 1'b1; serial_resetn <= 1'b0;
end else if (xfer_count == 4'd1) begin end else if (xfer_count == 4'd1) begin
serial_clock <= 1'b1;
serial_resetn <= 1'b0;
end else if (xfer_count == 4'd2) begin
serial_clock <= 1'b1; serial_clock <= 1'b1;
serial_resetn <= 1'b1; serial_resetn <= 1'b1;
end else if (xfer_count == 4'd3) begin end else if (xfer_count == 4'd2) begin
serial_busy <= 1'b0;
serial_resetn <= 1'b1; serial_resetn <= 1'b1;
serial_clock <= 1'b0; serial_clock <= 1'b0;
xfer_state <= `GPIO_IDLE; xfer_state <= `GPIO_IDLE;
@ -924,9 +915,22 @@ module housekeeping #(
irq_2_inputsrc <= 1'b0; irq_2_inputsrc <= 1'b0;
// GPIO Configuration, Data, and Control // GPIO Configuration, Data, and Control
// To-do: Get user project pad defaults from external inputs
// to be configured by user or at project generation time.
// Pads 1 to 4 are the SPI and considered critical startup
// infrastructure, and should not be altered from the defaults
// below. NOTE: These are not startup values, but they should
// match the startup values applied to the GPIO, or else the
// GPIO should be always triggered to load at startup.
for (j = 0; j < `MPRJ_IO_PADS; j=j+1) begin for (j = 0; j < `MPRJ_IO_PADS; j=j+1) begin
gpio_configure[j] <= 13'd0; if ((j < 2) || (j >= `MPRJ_IO_PADS - 2)) begin
gpio_configure[j] <= 'h1803;
end else begin
gpio_configure[j] <= 'h0403;
end end
end
mgmt_gpio_data <= 'd0; mgmt_gpio_data <= 'd0;
serial_bb_enable <= 1'b0; serial_bb_enable <= 1'b0;
serial_bb_data_1 <= 1'b0; serial_bb_data_1 <= 1'b0;
@ -935,7 +939,8 @@ module housekeeping #(
serial_bb_resetn <= 1'b0; serial_bb_resetn <= 1'b0;
serial_xfer <= 1'b0; serial_xfer <= 1'b0;
end else if (cwstb == 1'b1) begin end else begin
if (cwstb == 1'b1) begin
case (caddr) case (caddr)
/* Register 8'h00 is reserved for future use */ /* Register 8'h00 is reserved for future use */
/* Registers 8'h01 to 8'h09 are read-only and cannot be written */ /* Registers 8'h01 to 8'h09 are read-only and cannot be written */
@ -1120,7 +1125,7 @@ module housekeeping #(
gpio_configure[28][12:8] <= cdata[4:0]; gpio_configure[28][12:8] <= cdata[4:0];
end end
8'h45: begin 8'h45: begin
gpio_configure[28][7:0] <= idata; gpio_configure[28][7:0] <= cdata;
end end
8'h46: begin 8'h46: begin
gpio_configure[29][12:8] <= cdata[4:0]; gpio_configure[29][12:8] <= cdata[4:0];
@ -1240,6 +1245,7 @@ module housekeeping #(
irq_spi <= 1'b0; // IRQ is self-resetting irq_spi <= 1'b0; // IRQ is self-resetting
end end
end end
end
endmodule // housekeeping endmodule // housekeeping
`default_nettype wire `default_nettype wire