diff --git a/rtl/perips/spi/spi.hjson b/rtl/perips/spi/spi.hjson index d03cd24..099517f 100644 --- a/rtl/perips/spi/spi.hjson +++ b/rtl/perips/spi/spi.hjson @@ -59,6 +59,16 @@ name: "SS_DELAY", desc: "SPI ss signal active or inactive how many spi clk", } + { bits: "16", + name: "TX_FIFO_RESET", + swaccess: "rw1c", + desc: "reset tx fifo", + } + { bits: "17", + name: "RX_FIFO_RESET", + swaccess: "rw1c", + desc: "reset rx fifo", + } { bits: "31:29", name: "CLK_DIV", desc: "SPI clock divider count", @@ -99,7 +109,7 @@ hwaccess: "hro", hwqe: "true", fields: [ - { bits: "7:0" } + { bits: "31:0" } ] } { name: "RXDATA", @@ -109,7 +119,7 @@ hwext: "true", hwre: "true", fields: [ - { bits: "7:0" } + { bits: "31:0" } ] } ] diff --git a/rtl/perips/spi/spi_core.sv b/rtl/perips/spi/spi_core.sv index 7ac4068..9e1fb35 100644 --- a/rtl/perips/spi/spi_core.sv +++ b/rtl/perips/spi/spi_core.sv @@ -84,12 +84,14 @@ module spi_core #( logic tx_fifo_push; logic [7:0] tx_fifo_data_out; logic tx_fifo_pop; + logic tx_fifo_flush; logic rx_fifo_full; logic rx_fifo_empty; logic [7:0] rx_fifo_data_in; logic rx_fifo_push; logic [7:0] rx_fifo_data_out; logic rx_fifo_pop; + logic rx_fifo_flush; assign master_enable = ~reg2hw.ctrl0.role_mode.q; assign master_start = reg2hw.ctrl0.enable.q && (!tx_fifo_empty); @@ -103,13 +105,15 @@ module spi_core #( assign master_ss_level = reg2hw.ctrl0.ss_level.q; assign tx_fifo_push = reg2hw.txdata.qe; - assign tx_fifo_data_in = reg2hw.txdata.q; + assign tx_fifo_data_in = reg2hw.txdata.q[7:0]; assign tx_fifo_pop = master_data_valid_re | master_ready_fe; + assign tx_fifo_flush = reg2hw.ctrl0.tx_fifo_reset.q && reg2hw.ctrl0.tx_fifo_reset.qe; // 读操作才把接收到的数据压入RX FIFO assign rx_fifo_push = master_data_valid_re & master_read; assign rx_fifo_data_in = master_data_out; assign rx_fifo_pop = reg2hw.rxdata.re; - assign hw2reg.rxdata.d = rx_fifo_data_out; + assign hw2reg.rxdata.d = {24'h0, rx_fifo_data_out}; + assign rx_fifo_flush = reg2hw.ctrl0.rx_fifo_reset.q && reg2hw.ctrl0.rx_fifo_reset.qe; assign hw2reg.status.tx_fifo_full.d = tx_fifo_full; assign hw2reg.status.tx_fifo_empty.d = tx_fifo_empty; @@ -164,7 +168,7 @@ module spi_core #( ) u_tx_fifo ( .clk_i (clk_i), .rst_ni (rst_ni), - .flush_i (1'b0), + .flush_i (tx_fifo_flush), .testmode_i (1'b0), .full_o (tx_fifo_full), .empty_o (tx_fifo_empty), @@ -182,7 +186,7 @@ module spi_core #( ) u_rx_fifo ( .clk_i (clk_i), .rst_ni (rst_ni), - .flush_i (1'b0), + .flush_i (rx_fifo_flush), .testmode_i (1'b0), .full_o (rx_fifo_full), .empty_o (rx_fifo_empty), diff --git a/rtl/perips/spi/spi_reg_pkg.sv b/rtl/perips/spi/spi_reg_pkg.sv index f532a63..042d6b2 100644 --- a/rtl/perips/spi/spi_reg_pkg.sv +++ b/rtl/perips/spi/spi_reg_pkg.sv @@ -58,6 +58,14 @@ package spi_reg_pkg; logic [3:0] q; logic qe; } ss_delay; + struct packed { + logic q; + logic qe; + } tx_fifo_reset; + struct packed { + logic q; + logic qe; + } rx_fifo_reset; struct packed { logic [2:0] q; logic qe; @@ -83,12 +91,12 @@ package spi_reg_pkg; } spi_reg2hw_status_reg_t; typedef struct packed { - logic [7:0] q; + logic [31:0] q; logic qe; } spi_reg2hw_txdata_reg_t; typedef struct packed { - logic [7:0] q; + logic [31:0] q; logic re; } spi_reg2hw_rxdata_reg_t; @@ -137,6 +145,14 @@ package spi_reg_pkg; logic [3:0] d; logic de; } ss_delay; + struct packed { + logic d; + logic de; + } tx_fifo_reset; + struct packed { + logic d; + logic de; + } rx_fifo_reset; struct packed { logic [2:0] d; logic de; @@ -162,22 +178,22 @@ package spi_reg_pkg; } spi_hw2reg_status_reg_t; typedef struct packed { - logic [7:0] d; + logic [31:0] d; } spi_hw2reg_rxdata_reg_t; // Register -> HW type typedef struct packed { - spi_reg2hw_ctrl0_reg_t ctrl0; // [53:23] - spi_reg2hw_status_reg_t status; // [22:18] - spi_reg2hw_txdata_reg_t txdata; // [17:9] - spi_reg2hw_rxdata_reg_t rxdata; // [8:0] + spi_reg2hw_ctrl0_reg_t ctrl0; // [105:71] + spi_reg2hw_status_reg_t status; // [70:66] + spi_reg2hw_txdata_reg_t txdata; // [65:33] + spi_reg2hw_rxdata_reg_t rxdata; // [32:0] } spi_reg2hw_t; // HW -> register type typedef struct packed { - spi_hw2reg_ctrl0_reg_t ctrl0; // [43:13] - spi_hw2reg_status_reg_t status; // [12:8] - spi_hw2reg_rxdata_reg_t rxdata; // [7:0] + spi_hw2reg_ctrl0_reg_t ctrl0; // [71:37] + spi_hw2reg_status_reg_t status; // [36:32] + spi_hw2reg_rxdata_reg_t rxdata; // [31:0] } spi_hw2reg_t; // Register offsets @@ -188,7 +204,7 @@ package spi_reg_pkg; // Reset values for hwext registers and their fields parameter logic [4:0] SPI_STATUS_RESVAL = 5'h0; - parameter logic [7:0] SPI_RXDATA_RESVAL = 8'h0; + parameter logic [31:0] SPI_RXDATA_RESVAL = 32'h0; // Register index typedef enum int { @@ -202,8 +218,8 @@ package spi_reg_pkg; parameter logic [3:0] SPI_PERMIT [4] = '{ 4'b1111, // index[0] SPI_CTRL0 4'b0001, // index[1] SPI_STATUS - 4'b0001, // index[2] SPI_TXDATA - 4'b0001 // index[3] SPI_RXDATA + 4'b1111, // index[2] SPI_TXDATA + 4'b1111 // index[3] SPI_RXDATA }; endpackage diff --git a/rtl/perips/spi/spi_reg_top.sv b/rtl/perips/spi/spi_reg_top.sv index d840fb5..5d55396 100644 --- a/rtl/perips/spi/spi_reg_top.sv +++ b/rtl/perips/spi/spi_reg_top.sv @@ -61,6 +61,10 @@ module spi_reg_top ( logic ctrl0_ss_level_wd; logic [3:0] ctrl0_ss_delay_qs; logic [3:0] ctrl0_ss_delay_wd; + logic ctrl0_tx_fifo_reset_qs; + logic ctrl0_tx_fifo_reset_wd; + logic ctrl0_rx_fifo_reset_qs; + logic ctrl0_rx_fifo_reset_wd; logic [2:0] ctrl0_clk_div_qs; logic [2:0] ctrl0_clk_div_wd; logic status_re; @@ -70,9 +74,9 @@ module spi_reg_top ( logic status_rx_fifo_empty_qs; logic status_busy_qs; logic txdata_we; - logic [7:0] txdata_wd; + logic [31:0] txdata_wd; logic rxdata_re; - logic [7:0] rxdata_qs; + logic [31:0] rxdata_qs; // Register instances // R[ctrl0]: V(False) @@ -363,6 +367,58 @@ module spi_reg_top ( ); + // F[tx_fifo_reset]: 16:16 + prim_subreg #( + .DW (1), + .SWACCESS("W1C"), + .RESVAL (1'h0) + ) u_ctrl0_tx_fifo_reset ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ctrl0_we), + .wd (ctrl0_tx_fifo_reset_wd), + + // from internal hardware + .de (hw2reg.ctrl0.tx_fifo_reset.de), + .d (hw2reg.ctrl0.tx_fifo_reset.d), + + // to internal hardware + .qe (reg2hw.ctrl0.tx_fifo_reset.qe), + .q (reg2hw.ctrl0.tx_fifo_reset.q), + + // to register interface (read) + .qs (ctrl0_tx_fifo_reset_qs) + ); + + + // F[rx_fifo_reset]: 17:17 + prim_subreg #( + .DW (1), + .SWACCESS("W1C"), + .RESVAL (1'h0) + ) u_ctrl0_rx_fifo_reset ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ctrl0_we), + .wd (ctrl0_rx_fifo_reset_wd), + + // from internal hardware + .de (hw2reg.ctrl0.rx_fifo_reset.de), + .d (hw2reg.ctrl0.rx_fifo_reset.d), + + // to internal hardware + .qe (reg2hw.ctrl0.rx_fifo_reset.qe), + .q (reg2hw.ctrl0.rx_fifo_reset.q), + + // to register interface (read) + .qs (ctrl0_rx_fifo_reset_qs) + ); + + // F[clk_div]: 31:29 prim_subreg #( .DW (3), @@ -469,9 +525,9 @@ module spi_reg_top ( // R[txdata]: V(False) prim_subreg #( - .DW (8), + .DW (32), .SWACCESS("WO"), - .RESVAL (8'h0) + .RESVAL (32'h0) ) u_txdata ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -496,7 +552,7 @@ module spi_reg_top ( // R[rxdata]: V(True) prim_subreg_ext #( - .DW (8) + .DW (32) ) u_rxdata ( .re (rxdata_re), .we (1'b0), @@ -553,11 +609,15 @@ module spi_reg_top ( assign ctrl0_ss_delay_wd = reg_wdata[15:12]; + assign ctrl0_tx_fifo_reset_wd = reg_wdata[16]; + + assign ctrl0_rx_fifo_reset_wd = reg_wdata[17]; + assign ctrl0_clk_div_wd = reg_wdata[31:29]; assign status_re = addr_hit[1] & reg_re & !reg_error; assign txdata_we = addr_hit[2] & reg_we & !reg_error; - assign txdata_wd = reg_wdata[7:0]; + assign txdata_wd = reg_wdata[31:0]; assign rxdata_re = addr_hit[3] & reg_re & !reg_error; // Read data return @@ -576,6 +636,8 @@ module spi_reg_top ( reg_rdata_next[10] = ctrl0_ss_sw_ctrl_qs; reg_rdata_next[11] = ctrl0_ss_level_qs; reg_rdata_next[15:12] = ctrl0_ss_delay_qs; + reg_rdata_next[16] = ctrl0_tx_fifo_reset_qs; + reg_rdata_next[17] = ctrl0_rx_fifo_reset_qs; reg_rdata_next[31:29] = ctrl0_clk_div_qs; end @@ -588,11 +650,11 @@ module spi_reg_top ( end addr_hit[2]: begin - reg_rdata_next[7:0] = '0; + reg_rdata_next[31:0] = '0; end addr_hit[3]: begin - reg_rdata_next[7:0] = rxdata_qs; + reg_rdata_next[31:0] = rxdata_qs; end default: begin