diff --git a/Bender.yml b/Bender.yml index b94ddb2..f388121 100644 --- a/Bender.yml +++ b/Bender.yml @@ -37,7 +37,6 @@ sources: - hw/rsp_read/crc7_read.sv - hw/sd_clk_generator.sv - hw/sdhci_debounce.sv - - hw/ser_par_shift_reg.sv - hw/sram_shift_reg.sv # tc_sram_impl @@ -46,7 +45,7 @@ sources: - hw/dat_buffer.sv # sram_shift_reg - hw/dat_read/dat_read.sv # crc16_read - hw/dat_write/dat_write.sv # crc16_write - - hw/rsp_read/rsp_read.sv # ser_par_shift_reg, crc7_read, counter + - hw/rsp_read/rsp_read.sv # crc7_read, counter # Level 3 - hw/cmd_logic.sv # cmd_write, rsp_read, counter @@ -59,12 +58,15 @@ sources: - hw/sdhci_top.sv # sdhci_reg_obi, sdhci_reg_logic, sd_clk_generator, cmd_wrap, dat_wrap # Level 6 + - hw/sdhci_obi_to_reg.sv # register_interface to OBI bridge - hw/sdhci_top_obi.sv # sdhci_top, external obi_pkg - target: any(simulation, test) files: # Level 1 - target/sim/src/tb_dat.sv # sd_clk_generator, dat_write, dat_read + - target/sim/src/tb_dat_buffer_sizes.sv # dat_buffer + - target/sim/src/tb_reg_reset.sv # sdhci_top register reset behavior - target/sim/src/tb_driver_crc.sv - target/sim/model/sd_crc_7.v - target/sim/model/sd_crc_16.v diff --git a/Makefile b/Makefile index 8106682..a220e71 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ deepclean: sdhci-deepclean help: @echo "Some available commands" @echo "all: Fetch & compile everything" - @echo "hw: Regenerate generated hardware" + @echo "hw: Hardware source hook; no generated register files" @echo "sw: Compile the software libraries" @echo "sim: Generate simulation scripts and download models." @echo " Note: Some of these models are under other licenses." diff --git a/README.md b/README.md new file mode 100644 index 0000000..8598e5f --- /dev/null +++ b/README.md @@ -0,0 +1,142 @@ +# SDHCI Controller + +This repository contains a synthesizable SD Host Controller Interface (SDHCI) +hardware block with a register interface, SD command/data-line logic, an OBI +wrapper, simulation testbenches, and simple software support files. + +## Current IP Behavior + +The top-level SDHCI controller is `hw/sdhci_top.sv`. It exposes a generic +register request/response interface, SD card pads (`sd_clk`, `sd_cmd`, 4-bit +`sd_dat`, card detect), and one interrupt output. `hw/sdhci_top_obi.sv` wraps +the same controller for OBI integrations. + +The controller currently implements: + +- SD command issue and response capture, including CRC7 handling. +- DAT read/write transfers on the 4-bit SD data bus, including CRC16 handling. +- Single-block and multi-block transfer flow, including block-count updates. +- Auto CMD12 sequencing and Auto CMD12 error status reporting. +- Command and data timeout reporting. +- Card-detect debounce and present-state reporting. +- SD clock generation from `clk_i` with `ClkPreDiv` and the SDHCI clock-control + divider. +- A semi-handwritten SDHCI register file in `hw/reg/sdhci_reg_top.sv`, with + register data structures in `hw/reg/sdhci_reg_pkg.sv` and register-side + behavioral glue in `hw/reg/sdhci_reg_logic.sv`. +- Software reset of the full controller, command path, and data path. +- Write-one-to-clear interrupt/status behavior and interrupt signal generation. + +The DAT buffer size is controlled by `BufferNumWords`, with one 32-bit word per +entry. The default configuration is SDHCI-compliant: + +```systemverilog +parameter int unsigned BufferNumWords = 256; +parameter bit AllowNoncompliantBufferSizes = 1'b0; +``` + +With `AllowNoncompliantBufferSizes == 0`, the buffer must be at least 512 bytes +and data-port ready/status behavior is presented in full-block chunks. With +`AllowNoncompliantBufferSizes == 1`, smaller buffers are allowed as an explicit +integration escape hatch; software can discover the data-port chunk size through +the vendor capabilities register at offset `0x44`. In that mode, bit 31 marks +the noncompliant configuration and bits `[15:0]` report the buffer chunk size in +bytes. + +The implementation intentionally does not include DMA yet. Programmed I/O +through the Buffer Data Port is the current data path. + +## Tool Flow + +Dependencies are managed through Bender. The root `Makefile` includes +`sdhci.mk`, which in turn includes the hardware, software, and simulation +fragments. + +Common entry points: + +```sh +make hw +make sw +make sim +make all +make clean +make deepclean +``` + +`make sim` downloads the external SD card simulation model files and generates +the Questa/ModelSim compile script at `target/sim/vsim/compile.sdhci.tcl`: + +```sh +make sim +cd target/sim/vsim +vsim -c -do "do compile.sdhci.tcl; quit -f" +``` + +The regression testbenches used for this change were: + +```sh +for tb in \ + tb_dat \ + tb_dat_buffer_sizes \ + tb_reg_reset \ + tb_driver_crc \ + tb_acmd12_errorhandling \ + tb_acmd12_interrupts \ + tb_cmd_timeout \ + tb_dat_timeout \ + tb_block_read +do + timeout 300 vsim -c "$tb" -do "run -all; quit -f" +done +``` + +All of the above compiled and ran with zero simulator errors in the latest +local verification run. The previously reported `tb_acmd12_interrupts` hang was +not reproduced after the register/interrupt cleanup; that test completed under +the same timeout as the rest of the suite. + +## Synthesis Snapshot + +The latest synthesis check used Synopsys Design Compiler with the IHP13 target +setup under `target/ihp13/synopsys` and a 10 ns `clk_i` constraint. Two wrapper +variants were synthesized: + +- Minimum-size DAT buffer: `BufferNumWords = 8`, + `AllowNoncompliantBufferSizes = 1'b1`. +- Full compliant DAT buffer: `BufferNumWords = 256`, + `AllowNoncompliantBufferSizes = 1'b0`. + +The generated reports were written under `/tmp/sdhci_syn/{minimal,compliant}`. +The local run used temporary wrapper sources and Tcl scripts in `/tmp/sdhci_syn` +to instantiate the two parameter sets without changing the checked-in RTL. The +commands were run from `target/ihp13/synopsys`: + +```sh +timeout 1800 env LD_LIBRARY_PATH=/usr/lib64 \ + /usr/sepp/bin/synopsys dc_shell \ + -f /tmp/sdhci_syn/run_variant.tcl \ + -x "set argv minimal" + +timeout 1800 env LD_LIBRARY_PATH=/usr/lib64 \ + /usr/sepp/bin/synopsys dc_shell \ + -f /tmp/sdhci_syn/run_variant.tcl \ + -x "set argv compliant" +``` + +The area results were: + +| Variant | Buffer size | Cell area | Comb area | Noncomb area | Seq cells | +| --- | ---: | ---: | ---: | ---: | ---: | +| Minimum | 8 words / 32 B | 73,647.1024 | 38,914.6469 | 34,732.4555 | 1,288 | +| Full compliant | 256 words / 1024 B | 455,444.6491 | 241,100.2964 | 214,344.3527 | 9,239 | + +Timing met in both synthesis runs: + +| Variant | WNS | TNS | Violating paths | Worst reported path slack | +| --- | ---: | ---: | ---: | ---: | +| Minimum | 0.0000 | 0.0000 | 0 | 1.4512 ns | +| Full compliant | 0.0000 | 0.0000 | 0 | 1.3624 ns | + +For the full compliant variant, the DAT buffer dominates the area. The +`i_top/i_dat_wrap/i_dat_buffer` hierarchy accounts for 396,383.9118 area units, +with 392,445.0509 area units under the SRAM implementation. diff --git a/hw/autocmd_wrap.sv b/hw/autocmd_wrap.sv index d12ded2..2b0766a 100644 --- a/hw/autocmd_wrap.sv +++ b/hw/autocmd_wrap.sv @@ -14,6 +14,7 @@ import sdhci_reg_pkg::*; module autocmd_wrap ( input logic clk_i, input logic rst_ni, + input logic clear_i, input logic clk_en_p_i, // high before next sd_clk posedge input logic clk_en_n_i, // high before next sd_clk negedge input logic div_1_i, @@ -55,13 +56,13 @@ module autocmd_wrap ( //////////////// logic driver_cmd_queued_q, driver_cmd_queued_d; - `FF(driver_cmd_queued_q, driver_cmd_queued_d, '0, clk_i, rst_ni); + `FFARNC(driver_cmd_queued_q, driver_cmd_queued_d, clear_i, '0, clk_i, rst_ni); logic autocmd12_queued_q, autocmd12_queued_d; - `FF(autocmd12_queued_q, autocmd12_queued_d, '0, clk_i, rst_ni); + `FFARNC(autocmd12_queued_q, autocmd12_queued_d, clear_i, '0, clk_i, rst_ni); logic running_autocmd12_q, running_autocmd12_d; - `FF(running_autocmd12_q, running_autocmd12_d, '0, clk_i, rst_ni); + `FFARNC(running_autocmd12_q, running_autocmd12_d, clear_i, '0, clk_i, rst_ni); logic command_queued; assign command_queued = driver_cmd_queued_q || autocmd12_queued_q; @@ -88,12 +89,23 @@ module autocmd_wrap ( logic cmd_errors_occured; assign cmd_errors_occured = end_bit_error || crc_error || index_error || timeout_error; + logic active_transfer_direction_q, active_transfer_direction_d; + `FFLARNC(active_transfer_direction_q, active_transfer_direction_d, + command_started && !autocmd12_queued_q && cmd_data_present_o, + clear_i, '0, clk_i, rst_ni); + + // Use running_autocmd12_q (not autocmd12_queued_q) so the mux output + // stays stable throughout command execution, allowing cmd_logic to read + // these directly without re-latching them. + logic is_autocmd12; + assign is_autocmd12 = autocmd12_queued_q | running_autocmd12_q; + sdhci_pkg::cmd_t current_cmd; - assign current_cmd = autocmd12_queued_q ? 6'd12 : + assign current_cmd = is_autocmd12 ? 6'd12 : reg2hw.command.command_index.q; sdhci_pkg::cmd_arg_t current_arg; - assign current_arg = autocmd12_queued_q ? '0 : reg2hw.argument.q; + assign current_arg = is_autocmd12 ? '0 : reg2hw.argument.q; sdhci_pkg::response_type_e current_rsp_type; @@ -101,8 +113,8 @@ module autocmd_wrap ( current_rsp_type = sdhci_pkg::response_type_e'(reg2hw.command.response_type_select.q); // according to electrical spec 7.8.4, CMD12 is R1 on reads and R1b on writes - if (autocmd12_queued_q) begin - if (reg2hw.transfer_mode.data_transfer_direction_select.q == 1'b0) begin + if (is_autocmd12) begin + if (active_transfer_direction_q == 1'b0) begin // write -> R1b current_rsp_type = sdhci_pkg::RESPONSE_LENGTH_48_CHECK_BUSY; end else begin @@ -115,12 +127,25 @@ module autocmd_wrap ( assign cmd_needs_busy_o = current_rsp_type == sdhci_pkg::RESPONSE_LENGTH_48_CHECK_BUSY; assign cmd_transfer_direction_o = reg2hw.transfer_mode.data_transfer_direction_select.q; + sdhci_pkg::cmd_t accepted_cmd_q, accepted_cmd_d; + `FFLARNC(accepted_cmd_q, accepted_cmd_d, command_started, clear_i, '0, clk_i, rst_ni); + + sdhci_pkg::cmd_arg_t accepted_arg_q, accepted_arg_d; + `FFLARNC(accepted_arg_q, accepted_arg_d, command_started, clear_i, '0, clk_i, rst_ni); + + sdhci_pkg::response_type_e accepted_rsp_type_q, accepted_rsp_type_d; + `FFLARNC(accepted_rsp_type_q, accepted_rsp_type_d, command_started, clear_i, sdhci_pkg::NO_RESPONSE, clk_i, rst_ni); + always_comb begin : request_commands driver_cmd_queued_d = driver_cmd_queued_q; autocmd12_queued_d = autocmd12_queued_q; auto_cmd12_errors_o.command_not_issued_by_auto_cmd12_error.de = 1'b0; auto_cmd12_errors_o.auto_cmd12_not_executed.de = 1'b0; running_autocmd12_d = running_autocmd12_q; + active_transfer_direction_d = reg2hw.transfer_mode.data_transfer_direction_select.q; + accepted_cmd_d = current_cmd; + accepted_arg_d = current_arg; + accepted_rsp_type_d = current_rsp_type; if (reg2hw.command.command_index.qe) begin driver_cmd_queued_d = 1'b1; @@ -172,48 +197,29 @@ module autocmd_wrap ( // autocmd12 execution should not inhibit the driver assign command_inhibit_cmd_o.d = driver_cmd_queued_q | (cmd_inhibit_logic && ~running_autocmd12_q); - logic [31:0] rsp0, rsp1, rsp2, rsp3; - logic [119:0] rsp; + logic [31:0] cmd_response0_d, cmd_response1_d, cmd_response2_d, cmd_response3_d; + logic cmd_response0_de, cmd_response1_de, cmd_response2_de, cmd_response3_de; always_comb begin : rsp_assignment - rsp0 = reg2hw.response0.q; - rsp1 = reg2hw.response1.q; - rsp2 = reg2hw.response2.q; - rsp3 = reg2hw.response3.q; - - if (running_autocmd12_q) begin - // auto cmd 12 response goes to upper word of rsp register - rsp3 = rsp [31:0]; - end else begin - unique case (current_rsp_type) - sdhci_pkg::NO_RESPONSE:; - - sdhci_pkg::RESPONSE_LENGTH_136: begin - // long response - rsp0 = rsp[31:0]; - rsp1 = rsp[63:32]; - rsp2 = rsp[95:64]; - rsp3[23:0] = rsp[119:96]; // save bits 31:24 of rsp3 - end - - sdhci_pkg::RESPONSE_LENGTH_48, sdhci_pkg::RESPONSE_LENGTH_48_CHECK_BUSY: begin - rsp0 = rsp[31:0]; - end - - default:; - endcase + response0_d_o = cmd_response0_d; + response1_d_o = cmd_response1_d; + response2_d_o = cmd_response2_d; + response3_d_o = cmd_response3_d; + response0_de_o = cmd_response0_de && !running_autocmd12_q; + response1_de_o = cmd_response1_de && !running_autocmd12_q; + response2_de_o = cmd_response2_de && !running_autocmd12_q; + response3_de_o = cmd_response3_de && !running_autocmd12_q; + + if (cmd_response3_de && accepted_rsp_type_q == sdhci_pkg::RESPONSE_LENGTH_136) begin + response3_d_o = {reg2hw.response3.q[31:24], cmd_response3_d[23:0]}; end - end : rsp_assignment - - assign response0_d_o = rsp0; - assign response1_d_o = rsp1; - assign response2_d_o = rsp2; - assign response3_d_o = rsp3; - assign response0_de_o = cmd_result_valid; - assign response1_de_o = cmd_result_valid; - assign response2_de_o = cmd_result_valid; - assign response3_de_o = cmd_result_valid; + if (running_autocmd12_q && cmd_response0_de) begin + // Auto CMD12 response is stored in RESPONSE3. + response3_d_o = cmd_response0_d; + response3_de_o = 1'b1; + end + end : rsp_assignment //////////////////// // Error Checking // @@ -272,6 +278,7 @@ module autocmd_wrap ( cmd_logic i_cmd_logic ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), .clk_en_p_i (clk_en_p_i), .clk_en_n_i (clk_en_n_i), .div_1_i (div_1_i), @@ -283,14 +290,21 @@ module autocmd_wrap ( .rsp_done_o (sd_rsp_done_o), .cmd_inhibit_cmd_o (cmd_inhibit_logic), - .cmd_i (current_cmd), - .cmd_arg_i (current_arg), - .response_type_i (current_rsp_type), + .cmd_i (accepted_cmd_q), + .cmd_arg_i (accepted_arg_q), + .response_type_i (accepted_rsp_type_q), .cmd_valid_i (command_queued), .cmd_ready_o (command_ready), .cmd_result_valid_o(cmd_result_valid), - .rsp_o (rsp), + .response0_d_o (cmd_response0_d), + .response1_d_o (cmd_response1_d), + .response2_d_o (cmd_response2_d), + .response3_d_o (cmd_response3_d), + .response0_de_o (cmd_response0_de), + .response1_de_o (cmd_response1_de), + .response2_de_o (cmd_response2_de), + .response3_de_o (cmd_response3_de), .end_bit_error_o (end_bit_error), .crc_error_o (crc_error), .index_error_o (index_error), diff --git a/hw/cmd_logic.sv b/hw/cmd_logic.sv index a5608e3..e3ec4c7 100644 --- a/hw/cmd_logic.sv +++ b/hw/cmd_logic.sv @@ -10,6 +10,7 @@ module cmd_logic ( input logic clk_i, input logic rst_ni, + input logic clear_i, input logic clk_en_p_i, input logic clk_en_n_i, input logic div_1_i, @@ -29,7 +30,14 @@ module cmd_logic ( output logic cmd_ready_o, output logic cmd_result_valid_o, - output logic [119:0] rsp_o, + output logic [31:0] response0_d_o, + output logic [31:0] response1_d_o, + output logic [31:0] response2_d_o, + output logic [31:0] response3_d_o, + output logic response0_de_o, + output logic response1_de_o, + output logic response2_de_o, + output logic response3_de_o, output logic index_error_o, output logic end_bit_error_o, output logic crc_error_o, @@ -48,7 +56,7 @@ module cmd_logic ( } cmd_fsm_t; cmd_fsm_t cmd_state_q, cmd_state_d; - `FF(cmd_state_q, cmd_state_d, IDLE, clk_i, rst_ni); + `FFARNC(cmd_state_q, cmd_state_d, clear_i, IDLE, clk_i, rst_ni); // TODO: this forces a sleep cycle in between transactions. This might not // be ideal -> reduce sleep cycles in BUS_COOLDOWN by one @@ -58,17 +66,8 @@ module cmd_logic ( logic start_cmd; assign start_cmd = cmd_ready && cmd_valid_i; - sdhci_pkg::cmd_t cmd_d, cmd_q; - `FFL(cmd_q, cmd_d, cmd_ready && cmd_valid_i, '0, clk_i, rst_ni); - assign cmd_d = cmd_i; - - sdhci_pkg::cmd_arg_t cmd_arg_q, cmd_arg_d; - `FFL(cmd_arg_q, cmd_arg_d, cmd_ready && cmd_valid_i, '0, clk_i, rst_ni); - assign cmd_arg_d = cmd_arg_i; - - sdhci_pkg::response_type_e response_type_q, response_type_d; - `FFL(response_type_q, response_type_d, cmd_ready && cmd_valid_i, sdhci_pkg::NO_RESPONSE, clk_i, rst_ni); - assign response_type_d = response_type_i; + // cmd_i, cmd_arg_i and response_type_i are the accepted command payload + // latched by autocmd_wrap, so no local duplicate latches are needed here. // Electrical spec, 7.13.5; units are number of cycles localparam logic [6:0] N_CR_MIN = 2; // minimum time between command (SDHC) and response (card) @@ -105,7 +104,7 @@ module cmd_logic ( end SEND_CMD: begin if (tx_done) begin - if (response_type_q == sdhci_pkg::NO_RESPONSE) begin + if (response_type_i == sdhci_pkg::NO_RESPONSE) begin cmd_state_d = BUS_COOLDOWN; end else begin cmd_state_d = WAIT_RSP; @@ -118,7 +117,7 @@ module cmd_logic ( end else begin // +2: +1 for being over, +1 as we get tx_done on the end bit cycle, // and thus are one cycle ahead - if ((cmd_q == 'd01 || cmd_q == 'd02) && cycles_waiting == N_ID + 2) begin + if ((cmd_i == 'd01 || cmd_i == 'd02) && cycles_waiting == N_ID + 2) begin // The identification command (CMD2) has a shorter timeout period, // see 7.2.5 cmd_state_d = RSP_TIMEOUT; @@ -133,7 +132,7 @@ module cmd_logic ( end end BUS_COOLDOWN: begin - if (response_type_q == sdhci_pkg::NO_RESPONSE + if (response_type_i == sdhci_pkg::NO_RESPONSE && cycles_waiting == N_CC) begin cmd_state_d = IDLE; end else if (cycles_waiting == N_RC) begin @@ -148,7 +147,7 @@ module cmd_logic ( assign cmd_done_o = cmd_state_d != SEND_CMD && cmd_state_q == SEND_CMD; assign rsp_done_o = cmd_state_d == BUS_COOLDOWN && cmd_state_q != BUS_COOLDOWN && - response_type_q != sdhci_pkg::NO_RESPONSE; + response_type_i != sdhci_pkg::NO_RESPONSE; assign cmd_ready_o = cmd_ready; @@ -159,10 +158,11 @@ module cmd_logic ( assign crc_error_o = ~crc_correct; sdhci_pkg::cmd_t cmd_in_response; - assign cmd_in_response = sdhci_pkg::cmd_t'(rsp_o[37:32]); + logic [5:0] response_index; + assign cmd_in_response = sdhci_pkg::cmd_t'(response_index); // this line could optionally be masked by the valid line, leave it for now - assign index_error_o = (cmd_in_response != cmd_q) & (response_type_q == sdhci_pkg::RESPONSE_LENGTH_48 | - response_type_q == sdhci_pkg::RESPONSE_LENGTH_48_CHECK_BUSY); + assign index_error_o = (cmd_in_response != cmd_i) & (response_type_i == sdhci_pkg::RESPONSE_LENGTH_48 | + response_type_i == sdhci_pkg::RESPONSE_LENGTH_48_CHECK_BUSY); always_comb begin : cmd_inhibit cmd_inhibit_cmd_o = 1'b1; @@ -195,6 +195,7 @@ module cmd_logic ( cmd_write i_cmd_write ( .clk_i (clk_i), .rst_ni (rst_ni), + .clear_i (clear_i), .clk_en_p_i (clk_en_p_i), .clk_en_n_i (clk_en_n_i), @@ -203,8 +204,8 @@ module cmd_logic ( .cmd_o (sd_bus_cmd_o), .cmd_en_o (sd_bus_cmd_en_o), .start_tx_i (cmd_state_q == START), - .cmd_argument_i (cmd_arg_q), - .cmd_nr_i (cmd_q), + .cmd_argument_i (cmd_arg_i), + .cmd_nr_i (cmd_i), .tx_done_o (tx_done) ); @@ -213,15 +214,23 @@ module cmd_logic ( .clk_i (clk_i), .clk_en_i (clk_en_p_i), .rst_ni (rst_ni), + .clear_i (clear_i), .cmd_i (sd_bus_cmd_i), - .long_rsp_i (response_type_q == sdhci_pkg::RESPONSE_LENGTH_136), + .long_rsp_i (response_type_i == sdhci_pkg::RESPONSE_LENGTH_136), .start_listening_i (cmd_state_q == WAIT_RSP && (cycles_waiting == N_CR_MIN - 1)), .timeout_i (cmd_state_q == RSP_TIMEOUT), .receiving_o (rsp_receiving), .rsp_valid_o (rsp_received), - // TODO: do we buffer them? .end_bit_err_o (end_bit_error_o), - .rsp_o (rsp_o), + .response0_d_o (response0_d_o), + .response1_d_o (response1_d_o), + .response2_d_o (response2_d_o), + .response3_d_o (response3_d_o), + .response0_de_o (response0_de_o), + .response1_de_o (response1_de_o), + .response2_de_o (response2_de_o), + .response3_de_o (response3_de_o), + .response_index_o (response_index), .crc_corr_o (crc_correct) ); @@ -231,11 +240,11 @@ module cmd_logic ( ) i_counter ( .clk_i (clk_i), .rst_ni (rst_ni), - .clear_i (1'b0), + .clear_i (clear_i), .en_i (clk_en_p_i), .load_i (clear_cycle_counter), .down_i (1'b0), - .d_i ({'0, div_1_i}), + .d_i ({6'b0, div_1_i}), .q_o (cycles_waiting), .overflow_o () ); diff --git a/hw/cmd_write/cmd_write.sv b/hw/cmd_write/cmd_write.sv index e847668..44e7cdd 100644 --- a/hw/cmd_write/cmd_write.sv +++ b/hw/cmd_write/cmd_write.sv @@ -12,6 +12,7 @@ module cmd_write ( input logic clk_i, input logic rst_ni, + input logic clear_i, input logic clk_en_p_i, input logic clk_en_n_i, @@ -79,7 +80,7 @@ module cmd_write ( endcase end : cmd_write_state_transition - `FFL(tx_state_q, tx_state_d, clk_en_p_i, READY, clk_i, rst_ni); + `FFLARNC(tx_state_q, tx_state_d, clk_en_p_i, clear_i, READY, clk_i, rst_ni); /////////////// // Data Path // @@ -139,17 +140,18 @@ module cmd_write ( endcase end : cmd_tx_datapath - `FFL(tx_ongoing_q, tx_ongoing_d, clk_en_p_i, '0, clk_i, rst_ni); + `FFLARNC(tx_ongoing_q, tx_ongoing_d, clk_en_p_i, clear_i, '0, clk_i, rst_ni); // delay to negative edge of clk always_ff @( negedge clk_i or negedge rst_ni) begin if(!rst_ni) sd_cmd_div1 <= 1'b1; + else if(clear_i) sd_cmd_div1 <= 1'b1; else sd_cmd_div1 <= sd_cmd; end // delay to negative edge of sd_clk - `FFL(sd_cmd_divn, sd_cmd, clk_en_n_i, '1, clk_i, rst_ni); + `FFLARNC(sd_cmd_divn, sd_cmd, clk_en_n_i, clear_i, '1, clk_i, rst_ni); // if freq of sd_clk and clk is same, delay to negative edge of clk // otherwise delay to negative edge of sd_clk @@ -166,6 +168,7 @@ module cmd_write ( .clk_i (clk_i), .clk_en_i (clk_en_p_i), .rst_ni (rst_ni), + .clear_i (clear_i), .par_write_en_i (par_write_en), .shift_en_i (shift_en), .dat_par_i (cmd_bits_47_to_8), @@ -177,6 +180,7 @@ module cmd_write ( .clk_i (clk_i), .clk_en_i (clk_en_p_i), .rst_ni (rst_ni), + .clear_i (clear_i), .shift_out_crc7_i (crc7_shift_en), .input_en_i (shift_en), // only listen to input when shift reg outputs .dat_ser_i (shift_reg_out), @@ -189,7 +193,7 @@ module cmd_write ( ) i_tx_bits_counter ( .clk_i (clk_i), .rst_ni (rst_ni), - .clear_i (tx_done_o), // clears to 0 + .clear_i (tx_done_o || clear_i), // clears to 0 .en_i (tx_ongoing_q && clk_en_p_i), .load_i (1'b0), // always start at 0, no loading needed .down_i (1'b0), // count up diff --git a/hw/cmd_write/crc7_write.sv b/hw/cmd_write/crc7_write.sv index 0f716e3..d9bac94 100644 --- a/hw/cmd_write/crc7_write.sv +++ b/hw/cmd_write/crc7_write.sv @@ -15,6 +15,7 @@ module crc7_write ( input logic clk_i, input logic clk_en_i, input logic rst_ni, + input logic clear_i, input logic shift_out_crc7_i, input logic input_en_i, //enable for data_ser_i @@ -46,8 +47,8 @@ module crc7_write ( end end - `FFL (lower_3_q, lower_3_d, clk_en_i, 0, clk_i, rst_ni); - `FFL (upper_4_q, upper_4_d, clk_en_i, 0, clk_i, rst_ni); + `FFLARNC (lower_3_q, lower_3_d, clk_en_i, clear_i, 0, clk_i, rst_ni); + `FFLARNC (upper_4_q, upper_4_d, clk_en_i, clear_i, 0, clk_i, rst_ni); //Output assignment assign crc_ser_o = upper_4_q[3]; diff --git a/hw/dat_buffer.sv b/hw/dat_buffer.sv index 4fc3bed..f1aafec 100644 --- a/hw/dat_buffer.sv +++ b/hw/dat_buffer.sv @@ -12,10 +12,12 @@ module dat_buffer #( parameter int unsigned NumWords = 256, - parameter int unsigned MaxBlockBitSize = 10 + parameter int unsigned MaxBlockBitSize = 10, + parameter bit AllowNoncompliantBufferSizes = 1'b0 ) ( input logic clk_i, input logic rst_ni, + input logic clear_i, input logic read_operation_i, input logic write_operation_i, @@ -29,8 +31,16 @@ module dat_buffer #( output logic write_ready_o, output logic empty_o, + output logic buffer_data_port_read_ready_o, + output logic buffer_data_port_write_ready_o, - input sdhci_reg_pkg::sdhci_reg2hw_t reg2hw_i, + input logic [MaxBlockBitSize-1:0] block_size_i, + input logic [15:0] block_count_i, + input logic multi_block_i, + input logic block_count_enable_i, + input logic buffer_data_port_re_i, + input logic buffer_data_port_qe_i, + input logic [31:0] buffer_data_port_q_i, output logic [31:0] buffer_data_port_d_o, output `writable_reg_t() buffer_read_enable_o, @@ -40,11 +50,24 @@ module dat_buffer #( ); localparam int NumBytes = NumWords * 4; - logic [MaxBlockBitSize-1:0] block_size; - assign block_size = MaxBlockBitSize'(reg2hw_i.block_size.transfer_block_size.q); + `ASSERT_INIT(BufferSizeAtLeast32B, NumBytes >= 32, "data buffer must be at least 32 bytes") + `ASSERT_INIT(BufferSizeStandardBlock, + AllowNoncompliantBufferSizes || NumBytes >= 512, + "set AllowNoncompliantBufferSizes to use a non-SDHCI-compliant buffer below 512 bytes") + `ASSERT_INIT(BufferSizeAtMost1KiB, NumBytes <= 1024, "data buffer must be at most 1024 bytes") + `ASSERT_INIT(BufferSizePowerOfTwo, (NumWords & (NumWords - 1)) == 0, "data buffer word count must be a power of two") + + logic [MaxBlockBitSize-1:0] effective_block_size; + assign effective_block_size = (block_size_i == '0) ? MaxBlockBitSize'(1) : block_size_i; + + logic [MaxBlockBitSize-1:0] words_per_block; + assign words_per_block = (effective_block_size + MaxBlockBitSize'(3)) >> 2; logic [MaxBlockBitSize-1:0] current_word_counter_q, current_word_counter_d; - `FF (current_word_counter_q, current_word_counter_d, '0); + `FFARNC (current_word_counter_q, current_word_counter_d, clear_i, '0, clk_i, rst_ni); + + logic single_block_done_q, single_block_done_d; + `FFARNC(single_block_done_q, single_block_done_d, clear_i, 1'b0, clk_i, rst_ni); logic reg_empty; assign empty_o = reg_empty; @@ -53,9 +76,14 @@ module dat_buffer #( logic [cf_math_pkg::idx_width(NumBytes + 1)-1:0] reg_remaining_bytes; assign reg_remaining_bytes = (cf_math_pkg::idx_width(NumBytes + 1))'(NumBytes - reg_length * 4); - logic has_block, has_space; - assign has_space = reg_remaining_bytes >= block_size; - assign has_block = reg_length * 4 >= block_size; + logic has_block, has_block_space; + assign has_block = reg_length * 4 >= effective_block_size; + assign has_block_space = reg_remaining_bytes >= effective_block_size; + + logic accepts_data_port_chunk; + assign accepts_data_port_chunk = + (!multi_block_i && !single_block_done_q) || + (multi_block_i && (!block_count_enable_i || block_count_i != '0)); logic enable_reg; assign enable_reg = read_operation_i || write_operation_i; @@ -71,6 +99,8 @@ module dat_buffer #( buffer_read_enable_o = '{ de: '1, d: '0 }; buffer_write_enable_o = '{ de: '1, d: '0 }; buffer_data_port_d_o = '0; + buffer_data_port_read_ready_o = '0; + buffer_data_port_write_ready_o = '0; block_count_o = '{ de: '0, d: 'X }; @@ -79,35 +109,47 @@ module dat_buffer #( read_data_o = 'X; if (read_operation_i) begin - reg_push = write_valid_i; + reg_push = write_valid_i && !reg_full; reg_push_data = write_data_i; - write_ready_o = has_space; + write_ready_o = !reg_full; - buffer_read_enable_o.d = has_block; + buffer_data_port_read_ready_o = accepts_data_port_chunk && !reg_empty && !write_valid_i; + buffer_read_enable_o.d = accepts_data_port_chunk && + (AllowNoncompliantBufferSizes ? !reg_empty : has_block) && !write_valid_i; buffer_data_port_d_o = reg_pop_data; - reg_pop = reg2hw_i.buffer_data_port.re; + reg_pop = buffer_data_port_re_i && buffer_data_port_read_ready_o; end else if (write_operation_i) begin - reg_pop = read_ready_i; + reg_pop = read_ready_i && !reg_empty; read_data_o = reg_pop_data; - read_valid_o = has_block; + read_valid_o = !reg_empty; - buffer_write_enable_o.d = has_space; - reg_push_data = reg2hw_i.buffer_data_port.q; - reg_push = reg2hw_i.buffer_data_port.qe; + buffer_data_port_write_ready_o = accepts_data_port_chunk && !reg_full; + buffer_write_enable_o.d = accepts_data_port_chunk && + (AllowNoncompliantBufferSizes ? !reg_full : has_block_space); + reg_push_data = buffer_data_port_q_i; + reg_push = buffer_data_port_qe_i && buffer_data_port_write_ready_o; end current_word_counter_d = current_word_counter_q; + single_block_done_d = single_block_done_q; + + if (!read_operation_i && !write_operation_i) begin + single_block_done_d = 1'b0; + end - if ((read_operation_i && reg2hw_i.buffer_data_port.re) || (write_operation_i && reg2hw_i.buffer_data_port.qe)) begin - if (current_word_counter_q == (block_size + 3) / 4 - 1) begin + if ((read_operation_i && reg_pop) || (write_operation_i && reg_push)) begin + if (current_word_counter_q == words_per_block - 1) begin current_word_counter_d = '0; - // TODO block count enable / infity block transfer - if (reg2hw_i.transfer_mode.multi_single_block_select.q) begin + if (!multi_block_i) begin + single_block_done_d = 1'b1; + end + + if (multi_block_i && block_count_enable_i) begin // TODO this will have to be changed when adding support for suspend / resume - block_count_o = '{ de: '1, d: reg2hw_i.block_count.q - 1 }; - if (reg2hw_i.block_count.q != 'b1) begin + block_count_o = '{ de: '1, d: block_count_i - 1 }; + if (block_count_i != 'b1) begin // To trigger an interrupt buffer_write_enable_o.d = '0; buffer_read_enable_o.d = '0; @@ -119,12 +161,24 @@ module dat_buffer #( end end +`ifndef SYNTHESIS + always_ff @(posedge clk_i or negedge rst_ni) begin + if (rst_ni && !clear_i && enable_reg) begin + assert (block_size_i != '0) + else $error("DAT block size must be non-zero during data transfers"); + assert (AllowNoncompliantBufferSizes || effective_block_size <= NumBytes) + else $error("set AllowNoncompliantBufferSizes to use a DAT buffer smaller than the transfer block"); + end + end +`endif + sram_shift_reg #( .NumWords (NumWords) ) i_sram_shift_reg ( .clk_i, .rst_ni, + .clear_i, .en_i (enable_reg), diff --git a/hw/dat_read/crc16_read.sv b/hw/dat_read/crc16_read.sv index 6e74c6b..6e6994c 100644 --- a/hw/dat_read/crc16_read.sv +++ b/hw/dat_read/crc16_read.sv @@ -12,6 +12,7 @@ module crc16_read ( input logic clk_i, input logic sd_clk_en_i, input logic rst_ni, + input logic clear_i, input logic shift_in_i, @@ -41,7 +42,7 @@ module crc16_read ( end end - `FFL ( lower_5_q, lower_5_d, sd_clk_en_i, '0); - `FFL (middle_7_q, middle_7_d, sd_clk_en_i, '0); - `FFL ( upper_4_q, upper_4_d, sd_clk_en_i, '0); + `FFLARNC ( lower_5_q, lower_5_d, sd_clk_en_i, clear_i, '0, clk_i, rst_ni); + `FFLARNC (middle_7_q, middle_7_d, sd_clk_en_i, clear_i, '0, clk_i, rst_ni); + `FFLARNC ( upper_4_q, upper_4_d, sd_clk_en_i, clear_i, '0, clk_i, rst_ni); endmodule diff --git a/hw/dat_read/dat_read.sv b/hw/dat_read/dat_read.sv index a965103..b229e13 100644 --- a/hw/dat_read/dat_read.sv +++ b/hw/dat_read/dat_read.sv @@ -16,6 +16,7 @@ module dat_read #( input logic clk_i, input logic sd_clk_en_i, input logic rst_ni, + input logic clear_i, input logic [3:0] dat_i, input logic start_i, @@ -43,10 +44,10 @@ module dat_read #( } dat_rx_state_e; dat_rx_state_e state_q, state_d; - `FF (state_q, state_d, IDLE); + `FFARNC (state_q, state_d, clear_i, IDLE, clk_i, rst_ni); logic [CounterWidth-1:0] counter_q, counter_d; - `FFL (counter_q, counter_d, sd_clk_en_i, 0); + `FFLARNC (counter_q, counter_d, sd_clk_en_i, clear_i, 0, clk_i, rst_ni); logic [CounterWidth-1:0] required_clock_count; assign required_clock_count = bus_width_is_4_i ? 2*block_size_i : 8*block_size_i; @@ -92,7 +93,7 @@ module dat_read #( logic calculate_crc; logic [3:0] crc_errors; logic [31:0] data_buildup_q, data_buildup_d; - `FFL (data_buildup_q, data_buildup_d, sd_clk_en_i, 0); + `FFLARNC (data_buildup_q, data_buildup_d, sd_clk_en_i, clear_i, 0, clk_i, rst_ni); always_comb begin counter_d = '0; @@ -188,6 +189,7 @@ module dat_read #( .clk_i, .sd_clk_en_i, .rst_ni, + .clear_i, .shift_in_i (calculate_crc), diff --git a/hw/dat_wrap.sv b/hw/dat_wrap.sv index abe4c78..853ccba 100644 --- a/hw/dat_wrap.sv +++ b/hw/dat_wrap.sv @@ -11,6 +11,8 @@ module dat_wrap #( parameter int MaxBlockBitSize = 10, // max_block_length = 512 in caps + parameter int unsigned BufferNumWords = 256, + parameter bit AllowNoncompliantBufferSizes = 1'b0, parameter int unsigned TimeoutDivider = 1 // by how much to divide clk_i to get the timeout count frequency, // see dat_timeout for details ) ( @@ -19,6 +21,7 @@ module dat_wrap #( input logic sd_clk_en_n_i, input logic div_1_i, input logic rst_ni, + input logic clear_i, input logic [3:0] dat_i, output logic dat_en_o, @@ -45,6 +48,8 @@ module dat_wrap #( output logic [31:0] buffer_data_port_d_o, output `writable_reg_t() buffer_read_enable_o, output `writable_reg_t() buffer_write_enable_o, + output logic buffer_data_port_read_ready_o, + output logic buffer_data_port_write_ready_o, output `writable_reg_t() read_transfer_active_o, output `writable_reg_t() write_transfer_active_o, @@ -58,8 +63,12 @@ module dat_wrap #( logic write_done, write_crc_timeout; logic timeout_elapsed; + logic block_count_limited; + assign block_count_limited = !reg2hw_i.transfer_mode.multi_single_block_select.q || + reg2hw_i.transfer_mode.block_count_enable.q; + logic [15:0] transmitted_block_counter_q, transmitted_block_counter_d; - `FF (transmitted_block_counter_q, transmitted_block_counter_d, '0); + `FFARNC (transmitted_block_counter_q, transmitted_block_counter_d, clear_i, '0, clk_i, rst_ni); typedef enum logic [1:0] { READY, @@ -98,16 +107,16 @@ module dat_wrap #( } write_state_e; dat_state_e dat_state_q, dat_state_d; - `FF (dat_state_q, dat_state_d, READY, clk_i, rst_ni); + `FFARNC (dat_state_q, dat_state_d, clear_i, READY, clk_i, rst_ni); busy_state_e busy_state_q, busy_state_d; - `FF (busy_state_q, busy_state_d, BUSY_WAIT_FOR_CMD, clk_i, rst_ni); + `FFARNC (busy_state_q, busy_state_d, clear_i, BUSY_WAIT_FOR_CMD, clk_i, rst_ni); read_state_e read_state_q, read_state_d; - `FF (read_state_q, read_state_d, WAIT_FOR_CMD, clk_i, rst_ni); + `FFARNC (read_state_q, read_state_d, clear_i, WAIT_FOR_CMD, clk_i, rst_ni); write_state_e write_state_q, write_state_d; - `FF (write_state_q, write_state_d, WAIT_FOR_RSP, clk_i, rst_ni); + `FFARNC (write_state_q, write_state_d, clear_i, WAIT_FOR_RSP, clk_i, rst_ni); always_comb begin : main_fsm dat_state_d = dat_state_q; @@ -154,10 +163,10 @@ module dat_wrap #( assign sd_busy_o = dat_state_q == BUSY; logic [1:0] busy_counter_q, busy_counter_d; - `FF(busy_counter_q, busy_counter_d, 2'b0, clk_i, rst_ni); + `FFARNC(busy_counter_q, busy_counter_d, clear_i, 2'b0, clk_i, rst_ni); logic busy_saw_response_q, busy_saw_response_d; - `FF(busy_saw_response_q, busy_saw_response_d, 1'b0, clk_i, rst_ni); + `FFARNC(busy_saw_response_q, busy_saw_response_d, clear_i, 1'b0, clk_i, rst_ni); always_comb begin : busy_fsm busy_state_d = busy_state_q; @@ -245,7 +254,7 @@ module dat_wrap #( end end DONE_READING_BLOCK: begin - if (transmitted_block_counter_q == 'b1) begin + if (block_count_limited && transmitted_block_counter_q == 'b1) begin read_state_d = READING_BUSY; end else if (buffer_write_ready) begin read_state_d = START_READING; @@ -302,7 +311,7 @@ module dat_wrap #( end end DONE_WRITING_BLOCK: begin - if (transmitted_block_counter_q == 'b1) begin + if (block_count_limited && transmitted_block_counter_q == 'b1) begin write_state_d = DONE_WRITING; end else begin write_state_d = WAIT_FOR_WRITE_BUFFER; @@ -325,6 +334,12 @@ module dat_wrap #( logic [MaxBlockBitSize-1:0] block_size; assign block_size = MaxBlockBitSize'(reg2hw_i.block_size.transfer_block_size.q); + logic [MaxBlockBitSize-1:0] effective_block_size; + assign effective_block_size = (block_size == '0) ? MaxBlockBitSize'(1) : block_size; + + logic [MaxBlockBitSize-1:0] words_per_block; + assign words_per_block = (effective_block_size + MaxBlockBitSize'(3)) >> 2; + logic busy_waiting; logic read_waiting; @@ -335,6 +350,23 @@ module dat_wrap #( logic start_write, write_requests_next_word, write_crc_err, write_end_bit_err; logic [31:0] write_data, read_data; + logic pause_sd_clk_read, pause_sd_clk_write; + + assign pause_sd_clk_o = pause_sd_clk_read || pause_sd_clk_write; + + logic [MaxBlockBitSize-1:0] write_word_counter_q, write_word_counter_d; + `FFARNC(write_word_counter_q, write_word_counter_d, clear_i, '0, clk_i, rst_ni); + + always_comb begin + write_word_counter_d = write_word_counter_q; + if (dat_state_q != WRITE || write_state_q == WAIT_FOR_WRITE_BUFFER || + write_state_q == START_WRITING || write_state_q == DONE_WRITING_BLOCK) begin + write_word_counter_d = '0; + end else if (write_state_q == WRITING && buffer_read_ready && + write_word_counter_q < words_per_block) begin + write_word_counter_d = write_word_counter_q + 1'b1; + end + end always_comb begin : autocmd12 request_cmd12_o = '0; @@ -389,6 +421,8 @@ module dat_wrap #( always_comb begin if (reg2hw_i.transfer_mode.multi_single_block_select.q == 1'b0) begin new_block_count = 1'b1; + end else if (!reg2hw_i.transfer_mode.block_count_enable.q) begin + new_block_count = '0; end else begin new_block_count = reg2hw_i.block_count.q; end @@ -399,13 +433,13 @@ module dat_wrap #( if (dat_state_q == READ) begin if (read_state_q == WAIT_FOR_CMD) begin transmitted_block_counter_d = new_block_count; - end else if (read_state_q == DONE_READING_BLOCK) begin + end else if (block_count_limited && read_state_q == DONE_READING_BLOCK) begin transmitted_block_counter_d = transmitted_block_counter_q - 1; end end else if (dat_state_q == WRITE) begin if (write_state_q == WAIT_FOR_RSP) begin transmitted_block_counter_d = new_block_count; - end else if (write_state_q == DONE_WRITING_BLOCK) begin + end else if (block_count_limited && write_state_q == DONE_WRITING_BLOCK) begin transmitted_block_counter_d = transmitted_block_counter_q - 1; end end @@ -428,7 +462,7 @@ module dat_wrap #( end always_comb begin : read_control - pause_sd_clk_o = '0; + pause_sd_clk_read = '0; start_read = '0; buffer_write_valid = '0; @@ -437,13 +471,15 @@ module dat_wrap #( unique case (read_state_q) WAIT_FOR_CMD: ; WAIT_FOR_READ_BUFFER: begin - pause_sd_clk_o = '1; + pause_sd_clk_read = '1; end START_READING: begin start_read = '1; end READING: begin - if (read_valid) begin + if (!buffer_write_ready) begin + pause_sd_clk_read = '1; + end else if (read_valid) begin buffer_write_valid = '1; buffer_write_data = read_data; end @@ -460,6 +496,7 @@ module dat_wrap #( start_write = '0; write_data = 'X; buffer_read_ready = '0; + pause_sd_clk_write = '0; unique case (write_state_q) WAIT_FOR_RSP: ; @@ -468,7 +505,9 @@ module dat_wrap #( start_write = '1; end WRITING: begin - if (write_requests_next_word) begin + if (!buffer_read_valid && write_word_counter_q < words_per_block) begin + pause_sd_clk_write = '1; + end else if (write_requests_next_word && write_word_counter_q < words_per_block) begin buffer_read_ready = '1; end @@ -495,11 +534,13 @@ module dat_wrap #( dat_buffer #( - .NumWords (256), // = 1024, Just enough to double buffer 512 byte blocks - .MaxBlockBitSize (MaxBlockBitSize) + .NumWords (BufferNumWords), + .MaxBlockBitSize (MaxBlockBitSize), + .AllowNoncompliantBufferSizes (AllowNoncompliantBufferSizes) ) i_dat_buffer ( .clk_i, .rst_ni, + .clear_i, .read_operation_i (reg2hw_i.present_state.read_transfer_active.q), .write_operation_i (reg2hw_i.present_state.write_transfer_active.q), @@ -513,8 +554,16 @@ module dat_wrap #( .write_ready_o (buffer_write_ready), .empty_o (buffer_empty), - - .reg2hw_i, + .buffer_data_port_read_ready_o, + .buffer_data_port_write_ready_o, + + .block_size_i (block_size), + .block_count_i (reg2hw_i.block_count.q), + .multi_block_i (reg2hw_i.transfer_mode.multi_single_block_select.q), + .block_count_enable_i (reg2hw_i.transfer_mode.block_count_enable.q), + .buffer_data_port_re_i (reg2hw_i.buffer_data_port.re), + .buffer_data_port_qe_i (reg2hw_i.buffer_data_port.qe), + .buffer_data_port_q_i (reg2hw_i.buffer_data_port.q), .buffer_data_port_d_o, .buffer_read_enable_o, .buffer_write_enable_o, @@ -527,11 +576,12 @@ module dat_wrap #( .clk_i, .sd_clk_en_i (sd_clk_en_p_i), .rst_ni, + .clear_i, .dat_i, .start_i (start_read), .timeout_i (timeout_elapsed), - .block_size_i (block_size), + .block_size_i (effective_block_size), .bus_width_is_4_i (reg2hw_i.host_control.data_transfer_width.q), .data_valid_o (read_valid), @@ -551,12 +601,13 @@ module dat_wrap #( .sd_clk_en_n_i (sd_clk_en_n_i), .div_1_i (div_1_i), .rst_ni, + .clear_i, .dat0_i (dat_i[0]), .dat_o, .dat_en_o, .start_i (start_write), - .block_size_i (block_size), + .block_size_i (effective_block_size), .bus_width_is_4_i (reg2hw_i.host_control.data_transfer_width.q), .data_i (write_data), @@ -568,4 +619,13 @@ module dat_wrap #( .crc_err_o (write_crc_err), .end_bit_err_o (write_end_bit_err) ); + +`ifndef SYNTHESIS + always_ff @(posedge clk_i or negedge rst_ni) begin + if (rst_ni && !clear_i && cmd_started_i && cmd_data_present_i) begin + assert (block_size != '0) + else $error("DAT block size must be non-zero for data commands"); + end + end +`endif endmodule diff --git a/hw/dat_write/crc16_write.sv b/hw/dat_write/crc16_write.sv index 6a18c44..26d6dcc 100644 --- a/hw/dat_write/crc16_write.sv +++ b/hw/dat_write/crc16_write.sv @@ -12,6 +12,7 @@ module crc16_write ( input logic clk_i, input logic sd_clk_en_i, input logic rst_ni, + input logic clear_i, input logic shift_out_crc16_i, input logic dat_ser_i, @@ -48,9 +49,9 @@ module crc16_write ( end end - `FFL ( upper_4_q, upper_4_d, sd_clk_en_i, 0); - `FFL (middle_7_q, middle_7_d, sd_clk_en_i, 0); - `FFL ( lower_5_q, lower_5_d, sd_clk_en_i, 0); + `FFLARNC ( upper_4_q, upper_4_d, sd_clk_en_i, clear_i, 0, clk_i, rst_ni); + `FFLARNC (middle_7_q, middle_7_d, sd_clk_en_i, clear_i, 0, clk_i, rst_ni); + `FFLARNC ( lower_5_q, lower_5_d, sd_clk_en_i, clear_i, 0, clk_i, rst_ni); `ifdef VERILATOR logic [15:0] crc; diff --git a/hw/dat_write/dat_write.sv b/hw/dat_write/dat_write.sv index b9dbbbe..76f201a 100644 --- a/hw/dat_write/dat_write.sv +++ b/hw/dat_write/dat_write.sv @@ -18,6 +18,7 @@ module dat_write #( input logic sd_clk_en_n_i, input logic div_1_i, input logic rst_ni, + input logic clear_i, input logic dat0_i, output logic [3:0] dat_o, output logic dat_en_o, @@ -56,10 +57,10 @@ module dat_write #( } dat_tx_state_e; dat_tx_state_e dat_tx_state_d, dat_tx_state_q; - `FFL (dat_tx_state_q, dat_tx_state_d, sd_clk_en_p_i, READY); + `FFLARNC (dat_tx_state_q, dat_tx_state_d, sd_clk_en_p_i, clear_i, READY, clk_i, rst_ni); logic [CounterWidth-1:0] counter_q, counter_d; - `FFL (counter_q, counter_d, sd_clk_en_p_i, 0); + `FFLARNC (counter_q, counter_d, sd_clk_en_p_i, clear_i, 0, clk_i, rst_ni); logic [CounterWidth-1:0] required_clock_count; assign required_clock_count = bus_width_is_4_i ? 2*block_size_i : 8*block_size_i; @@ -87,26 +88,27 @@ module dat_write #( end logic [31:0] buffered_data_d, buffered_data_q; - `FFL (buffered_data_q, buffered_data_d, sd_clk_en_p_i, '0); + `FFLARNC (buffered_data_q, buffered_data_d, sd_clk_en_p_i, clear_i, '0, clk_i, rst_ni); logic end_bit_err_q, end_bit_err_d; - `FFL (end_bit_err_q, end_bit_err_d, sd_clk_en_p_i, '0); + `FFLARNC (end_bit_err_q, end_bit_err_d, sd_clk_en_p_i, clear_i, '0, clk_i, rst_ni); logic data_timeout_q, data_timeout_d; - `FFL (data_timeout_q, data_timeout_d, sd_clk_en_p_i, '0); + `FFLARNC (data_timeout_q, data_timeout_d, sd_clk_en_p_i, clear_i, '0, clk_i, rst_ni); logic [2:0] status_q, status_d; - `FFL (status_q, status_d, sd_clk_en_p_i, '0); + `FFLARNC (status_q, status_d, sd_clk_en_p_i, clear_i, '0, clk_i, rst_ni); logic [3:0] dat, dat_div1, dat_divn; //delay by half a clock cycle always_ff @( negedge clk_i or negedge rst_ni) begin if(!rst_ni) dat_div1 <= 4'b1; + else if(clear_i) dat_div1 <= 4'b1; else dat_div1 <= dat; end - `FFL(dat_divn, dat, sd_clk_en_n_i, 4'b1, clk_i, rst_ni); + `FFLARNC(dat_divn, dat, sd_clk_en_n_i, clear_i, 4'b1, clk_i, rst_ni); assign dat_o = (div_1_i) ? dat_div1 : dat_divn; @@ -232,6 +234,7 @@ module dat_write #( .clk_i, .sd_clk_en_i (sd_clk_en_p_i), .rst_ni, + .clear_i, .shift_out_crc16_i (shift_out_crc), .dat_ser_i (dat[i]), .crc_ser_o (crc[i]) diff --git a/hw/hw.mk b/hw/hw.mk index 51b2bc3..a0c7e30 100644 --- a/hw/hw.mk +++ b/hw/hw.mk @@ -6,16 +6,5 @@ # - Micha Wehrli # - Axel Vanoni -REGGEN ?= python $(shell $(BENDER) path register_interface)/vendor/lowrisc_opentitan/util/regtool.py - -$(SDHCI_ROOT)/hw/reg/%_reg_pkg.sv: $(SDHCI_ROOT)/hw/reg/%_regs.hjson - $(REGGEN) $< -r -t $(shell dirname $@) - -$(SDHCI_ROOT)/hw/reg/%_reg_top.sv: $(SDHCI_ROOT)/hw/reg/%_regs.hjson - $(REGGEN) $< -r -t $(shell dirname $@) - -sdhci-reggen: $(SDHCI_ROOT)/hw/reg/sdhci_reg_pkg.sv $(SDHCI_ROOT)/hw/reg/sdhci_reg_top.sv -.PHONY: sdhci-reggen - -sdhci-hw-all: sdhci-reggen +sdhci-hw-all: .PHONY: sdhci-hw-all diff --git a/hw/par_ser_shift_reg.sv b/hw/par_ser_shift_reg.sv index 1fc5f70..f30b45f 100644 --- a/hw/par_ser_shift_reg.sv +++ b/hw/par_ser_shift_reg.sv @@ -17,6 +17,7 @@ module par_ser_shift_reg #( input logic clk_i, input logic clk_en_i, input logic rst_ni, + input logic clear_i, input logic par_write_en_i, //write data in parallel to shift register input logic shift_en_i, //enable shifting, non-latching! @@ -38,8 +39,8 @@ module par_ser_shift_reg #( end end - `FFL(dat_q, dat_d, clk_en_i, 0, clk_i, rst_ni); + `FFLARNC(dat_q, dat_d, clk_en_i, clear_i, 0, clk_i, rst_ni); //output assignment assign dat_ser_o = dat_q[NumBits-1]; -endmodule \ No newline at end of file +endmodule diff --git a/hw/reg/sdhci_reg_logic.sv b/hw/reg/sdhci_reg_logic.sv index 4305bf9..29e6a6b 100644 --- a/hw/reg/sdhci_reg_logic.sv +++ b/hw/reg/sdhci_reg_logic.sv @@ -11,8 +11,9 @@ module sdhci_reg_logic ( input logic clk_i, input logic rst_ni, - input logic rst_cmd_ni, - input logic rst_dat_ni, + input logic clear_i, + input logic clear_cmd_i, + input logic clear_dat_i, input sdhci_reg_pkg::sdhci_reg2hw_t reg2hw_i, input sdhci_reg_pkg::sdhci_hw2reg_t hw2reg_i, @@ -45,100 +46,143 @@ module sdhci_reg_logic ( output logic [7:0] interrupt_signal_for_each_slot_o, output logic interrupt_o ); - `define did_get_set(register, field) ( \ - hw2reg_i.register.field.de & // Was written \ - (|(~reg2hw_i.register.field.q & // Was 0 \ - hw2reg_i.register.field.d))) // Is 1 - - `define did_get_unset(register, field) ( \ - hw2reg_i.register.field.de & // Was written \ - (|(reg2hw_i.register.field.q & // Was 1 \ - ~hw2reg_i.register.field.d))) // Is 0 - - `define instant_reg_value(register, field) \ - (hw2reg_i.register.field.de ? hw2reg_i.register.field.d : reg2hw_i.register.field.q) - - `define should_interrupt(register, field) ( \ - |( reg2hw_i.register``_status.field.q & // Is 1 \ - reg2hw_i.register``_signal_enable.field``_signal_enable.q)) // Should interrupt \ + logic [5:0] normal_interrupt_sources; + logic [7:0] error_interrupt_sources; + logic [7:0] visible_error_status; + logic [5:0] auto_cmd12_error_events; + + assign normal_interrupt_sources = { + reg2hw_i.normal_interrupt_status.card_removal.q & + reg2hw_i.normal_interrupt_signal_enable.card_removal_signal_enable.q, + reg2hw_i.normal_interrupt_status.card_insertion.q & + reg2hw_i.normal_interrupt_signal_enable.card_insertion_signal_enable.q, + reg2hw_i.normal_interrupt_status.buffer_read_ready.q & + reg2hw_i.normal_interrupt_signal_enable.buffer_read_ready_signal_enable.q, + reg2hw_i.normal_interrupt_status.buffer_write_ready.q & + reg2hw_i.normal_interrupt_signal_enable.buffer_write_ready_signal_enable.q, + reg2hw_i.normal_interrupt_status.transfer_complete.q & + reg2hw_i.normal_interrupt_signal_enable.transfer_complete_signal_enable.q, + reg2hw_i.normal_interrupt_status.command_complete.q & + reg2hw_i.normal_interrupt_signal_enable.command_complete_signal_enable.q + }; + + assign error_interrupt_sources = { + reg2hw_i.error_interrupt_status.auto_cmd12_error.q & + reg2hw_i.error_interrupt_signal_enable.auto_cmd12_error_signal_enable.q, + reg2hw_i.error_interrupt_status.data_end_bit_error.q & + reg2hw_i.error_interrupt_signal_enable.data_end_bit_error_signal_enable.q, + reg2hw_i.error_interrupt_status.data_crc_error.q & + reg2hw_i.error_interrupt_signal_enable.data_crc_error_signal_enable.q, + reg2hw_i.error_interrupt_status.data_timeout_error.q & + reg2hw_i.error_interrupt_signal_enable.data_timeout_error_signal_enable.q, + reg2hw_i.error_interrupt_status.command_index_error.q & + reg2hw_i.error_interrupt_signal_enable.command_index_error_signal_enable.q, + reg2hw_i.error_interrupt_status.command_end_bit_error.q & + reg2hw_i.error_interrupt_signal_enable.command_end_bit_error_signal_enable.q, + reg2hw_i.error_interrupt_status.command_crc_error.q & + reg2hw_i.error_interrupt_signal_enable.command_crc_error_signal_enable.q, + reg2hw_i.error_interrupt_status.command_timeout_error.q & + reg2hw_i.error_interrupt_signal_enable.command_timeout_error_signal_enable.q + }; + + assign visible_error_status = { + hw2reg_i.error_interrupt_status.auto_cmd12_error.de ? + hw2reg_i.error_interrupt_status.auto_cmd12_error.d : + reg2hw_i.error_interrupt_status.auto_cmd12_error.q, + hw2reg_i.error_interrupt_status.data_end_bit_error.de ? + hw2reg_i.error_interrupt_status.data_end_bit_error.d : + reg2hw_i.error_interrupt_status.data_end_bit_error.q, + hw2reg_i.error_interrupt_status.data_crc_error.de ? + hw2reg_i.error_interrupt_status.data_crc_error.d : + reg2hw_i.error_interrupt_status.data_crc_error.q, + hw2reg_i.error_interrupt_status.data_timeout_error.de ? + hw2reg_i.error_interrupt_status.data_timeout_error.d : + reg2hw_i.error_interrupt_status.data_timeout_error.q, + hw2reg_i.error_interrupt_status.command_index_error.de ? + hw2reg_i.error_interrupt_status.command_index_error.d : + reg2hw_i.error_interrupt_status.command_index_error.q, + hw2reg_i.error_interrupt_status.command_end_bit_error.de ? + hw2reg_i.error_interrupt_status.command_end_bit_error.d : + reg2hw_i.error_interrupt_status.command_end_bit_error.q, + hw2reg_i.error_interrupt_status.command_crc_error.de ? + hw2reg_i.error_interrupt_status.command_crc_error.d : + reg2hw_i.error_interrupt_status.command_crc_error.q, + hw2reg_i.error_interrupt_status.command_timeout_error.de ? + hw2reg_i.error_interrupt_status.command_timeout_error.d : + reg2hw_i.error_interrupt_status.command_timeout_error.q + }; + + assign auto_cmd12_error_events = { + hw2reg_i.auto_cmd12_error_status.command_not_issued_by_auto_cmd12_error.de & + ~reg2hw_i.auto_cmd12_error_status.command_not_issued_by_auto_cmd12_error.q & + hw2reg_i.auto_cmd12_error_status.command_not_issued_by_auto_cmd12_error.d, + hw2reg_i.auto_cmd12_error_status.auto_cmd12_index_error.de & + ~reg2hw_i.auto_cmd12_error_status.auto_cmd12_index_error.q & + hw2reg_i.auto_cmd12_error_status.auto_cmd12_index_error.d, + hw2reg_i.auto_cmd12_error_status.auto_cmd12_end_bit_error.de & + ~reg2hw_i.auto_cmd12_error_status.auto_cmd12_end_bit_error.q & + hw2reg_i.auto_cmd12_error_status.auto_cmd12_end_bit_error.d, + hw2reg_i.auto_cmd12_error_status.auto_cmd12_crc_error.de & + ~reg2hw_i.auto_cmd12_error_status.auto_cmd12_crc_error.q & + hw2reg_i.auto_cmd12_error_status.auto_cmd12_crc_error.d, + hw2reg_i.auto_cmd12_error_status.auto_cmd12_timeout_error.de & + ~reg2hw_i.auto_cmd12_error_status.auto_cmd12_timeout_error.q & + hw2reg_i.auto_cmd12_error_status.auto_cmd12_timeout_error.d, + hw2reg_i.auto_cmd12_error_status.auto_cmd12_not_executed.de & + ~reg2hw_i.auto_cmd12_error_status.auto_cmd12_not_executed.q & + hw2reg_i.auto_cmd12_error_status.auto_cmd12_not_executed.d + }; assign interrupt_signal_for_each_slot_o[7:1] = '0; assign interrupt_signal_for_each_slot_o[0] = - // `should_interrupt(normal_interrupt, card_interrupt ) | - `should_interrupt(normal_interrupt, card_removal ) | - `should_interrupt(normal_interrupt, card_insertion ) | - `should_interrupt(normal_interrupt, buffer_read_ready ) | - `should_interrupt(normal_interrupt, buffer_write_ready) | - // `should_interrupt(normal_interrupt, dma_interrupt ) | - // `should_interrupt(normal_interrupt, block_gap_event ) | - `should_interrupt(normal_interrupt, transfer_complete ) | - `should_interrupt(normal_interrupt, command_complete ) | - - `should_interrupt(error_interrupt, auto_cmd12_error ) | - // `should_interrupt(error_interrupt, current_limit_error ) | - `should_interrupt(error_interrupt, data_end_bit_error ) | - `should_interrupt(error_interrupt, data_crc_error ) | - `should_interrupt(error_interrupt, data_timeout_error ) | - `should_interrupt(error_interrupt, command_index_error ) | - `should_interrupt(error_interrupt, command_end_bit_error) | - `should_interrupt(error_interrupt, command_crc_error ) | - `should_interrupt(error_interrupt, command_timeout_error) /*| - `should_interrupt(error_interrupt, vendor_specific_error)*/; - - - /* logic interrupt_status_q, interrupt_status_d; */ - /* `FF(interrupt_status_q, interrupt_status_d, '0); */ - /* assign interrupt_status_d = interrupt_signal_for_each_slot_o[0]; */ - - // Send interrupt if any interupt status went from 0 to 1 + (|normal_interrupt_sources) | (|error_interrupt_sources); + + // Send interrupt if any interrupt status went from 0 to 1 assign interrupt_o = interrupt_signal_for_each_slot_o[0]; // Automatically write to Error Interrupt Status - assign error_interrupt_o.d = rst_ni & - (//(|`instant_reg_value(error_interrupt_status, vendor_specific_error)) | - `instant_reg_value(error_interrupt_status, auto_cmd12_error ) | - // `instant_reg_value(error_interrupt_status, current_limit_error ) | - `instant_reg_value(error_interrupt_status, data_end_bit_error ) | - `instant_reg_value(error_interrupt_status, data_crc_error ) | - `instant_reg_value(error_interrupt_status, data_timeout_error ) | - `instant_reg_value(error_interrupt_status, command_index_error ) | - `instant_reg_value(error_interrupt_status, command_end_bit_error) | - `instant_reg_value(error_interrupt_status, command_crc_error ) | - `instant_reg_value(error_interrupt_status, command_timeout_error)); + assign error_interrupt_o.d = !clear_i & (|visible_error_status); assign error_interrupt_o.de = '1; // Automatically write to AutoCMD12 Error Interrupt Status assign auto_cmd12_error_o.d = '1; - assign auto_cmd12_error_o.de = rst_ni & + assign auto_cmd12_error_o.de = !clear_i & reg2hw_i.error_interrupt_status_enable.auto_cmd12_error_status_enable.q & - (`did_get_set(auto_cmd12_error_status, command_not_issued_by_auto_cmd12_error) | - `did_get_set(auto_cmd12_error_status, auto_cmd12_index_error ) | - `did_get_set(auto_cmd12_error_status, auto_cmd12_end_bit_error ) | - `did_get_set(auto_cmd12_error_status, auto_cmd12_crc_error ) | - `did_get_set(auto_cmd12_error_status, auto_cmd12_timeout_error ) | - `did_get_set(auto_cmd12_error_status, auto_cmd12_not_executed )); + (|auto_cmd12_error_events); assign buffer_read_ready_o.d = '1; - assign buffer_read_ready_o.de = rst_dat_ni & `did_get_set(present_state, buffer_read_enable); + assign buffer_read_ready_o.de = !clear_dat_i & + hw2reg_i.present_state.buffer_read_enable.de & + ~reg2hw_i.present_state.buffer_read_enable.q & + hw2reg_i.present_state.buffer_read_enable.d; assign buffer_write_ready_o.d = '1; - assign buffer_write_ready_o.de = rst_dat_ni & `did_get_set(present_state, buffer_write_enable); + assign buffer_write_ready_o.de = !clear_dat_i & + hw2reg_i.present_state.buffer_write_enable.de & + ~reg2hw_i.present_state.buffer_write_enable.q & + hw2reg_i.present_state.buffer_write_enable.d; // technically, dat_line_active should be 0 once the last block of a read // transfer has been transferred into the buffer, at which point // read_transfer_active is still 1 assign dat_line_active_o.de = '1; - assign dat_line_active_o.d = rst_dat_ni & (sd_cmd_dat_busy_i | - `instant_reg_value(present_state, write_transfer_active) | - `instant_reg_value(present_state, read_transfer_active)); + assign dat_line_active_o.d = !clear_dat_i & (sd_cmd_dat_busy_i | + (hw2reg_i.present_state.write_transfer_active.de ? + hw2reg_i.present_state.write_transfer_active.d : + reg2hw_i.present_state.write_transfer_active.q) | + (hw2reg_i.present_state.read_transfer_active.de ? + hw2reg_i.present_state.read_transfer_active.d : + reg2hw_i.present_state.read_transfer_active.q)); // technically, command_inhibit_dat should be // dat_line_active | read_transfer_active, but as we or read_transfer_active // already into dat_line_active, this should be fine assign command_inhibit_dat_o.de = '1; - assign command_inhibit_dat_o.d = rst_dat_ni & - `instant_reg_value(present_state, dat_line_active); + assign command_inhibit_dat_o.d = !clear_dat_i & + (hw2reg_i.present_state.dat_line_active.de ? + hw2reg_i.present_state.dat_line_active.d : + reg2hw_i.present_state.dat_line_active.q); // transfer complete fires on: // - read transfer active 1->0 @@ -149,35 +193,45 @@ module sdhci_reg_logic ( // write active implies dat line active, // so looking at command inhibit is enough assign transfer_complete_o.d = '1; - assign transfer_complete_o.de = rst_dat_ni & - (`did_get_unset(present_state, command_inhibit_dat)); + assign transfer_complete_o.de = !clear_dat_i & + hw2reg_i.present_state.command_inhibit_dat.de & + reg2hw_i.present_state.command_inhibit_dat.q & + ~hw2reg_i.present_state.command_inhibit_dat.d; assign command_complete_o.d = '1; - assign command_complete_o.de = rst_cmd_ni & `did_get_unset(present_state, command_inhibit_cmd); + assign command_complete_o.de = !clear_cmd_i & + hw2reg_i.present_state.command_inhibit_cmd.de & + reg2hw_i.present_state.command_inhibit_cmd.q & + ~hw2reg_i.present_state.command_inhibit_cmd.d; assign card_insertion_o.d = '1; - assign card_insertion_o.de = rst_dat_ni & `did_get_set(present_state, card_inserted); + assign card_insertion_o.de = !clear_dat_i & + hw2reg_i.present_state.card_inserted.de & + ~reg2hw_i.present_state.card_inserted.q & + hw2reg_i.present_state.card_inserted.d; assign card_removal_o.d = '1; - assign card_removal_o.de = rst_dat_ni & `did_get_unset(present_state, card_inserted); + assign card_removal_o.de = !clear_dat_i & + hw2reg_i.present_state.card_inserted.de & + reg2hw_i.present_state.card_inserted.q & + ~hw2reg_i.present_state.card_inserted.d; // Writes to the transfer_mode register should be ignored when command_inhibit_cmd is active - `FFL (transfer_mode_reg_o.multi_single_block_select .d, reg2hw_i.transfer_mode.multi_single_block_select .q, - !reg2hw_i.present_state.command_inhibit_cmd.q && reg2hw_i.transfer_mode.multi_single_block_select .qe, '0) - `FFL (transfer_mode_reg_o.data_transfer_direction_select.d, reg2hw_i.transfer_mode.data_transfer_direction_select.q, - !reg2hw_i.present_state.command_inhibit_cmd.q && reg2hw_i.transfer_mode.data_transfer_direction_select.qe, '0) - `FFL (transfer_mode_reg_o.auto_cmd12_enable .d, reg2hw_i.transfer_mode.auto_cmd12_enable .q, - !reg2hw_i.present_state.command_inhibit_cmd.q && reg2hw_i.transfer_mode.auto_cmd12_enable .qe, '0) - `FFL (transfer_mode_reg_o.block_count_enable .d, reg2hw_i.transfer_mode.block_count_enable .q, - !reg2hw_i.present_state.command_inhibit_cmd.q && reg2hw_i.transfer_mode.block_count_enable .qe, '0) - `FFL (transfer_mode_reg_o.dma_enable .d, reg2hw_i.transfer_mode.dma_enable .q, - !reg2hw_i.present_state.command_inhibit_cmd.q && reg2hw_i.transfer_mode.dma_enable .qe, '0) + `FFLARNC (transfer_mode_reg_o.multi_single_block_select .d, reg2hw_i.transfer_mode.multi_single_block_select .q, + !reg2hw_i.present_state.command_inhibit_cmd.q && reg2hw_i.transfer_mode.multi_single_block_select .qe, clear_i, '0, clk_i, rst_ni) + `FFLARNC (transfer_mode_reg_o.data_transfer_direction_select.d, reg2hw_i.transfer_mode.data_transfer_direction_select.q, + !reg2hw_i.present_state.command_inhibit_cmd.q && reg2hw_i.transfer_mode.data_transfer_direction_select.qe, clear_i, '0, clk_i, rst_ni) + `FFLARNC (transfer_mode_reg_o.auto_cmd12_enable .d, reg2hw_i.transfer_mode.auto_cmd12_enable .q, + !reg2hw_i.present_state.command_inhibit_cmd.q && reg2hw_i.transfer_mode.auto_cmd12_enable .qe, clear_i, '0, clk_i, rst_ni) + `FFLARNC (transfer_mode_reg_o.block_count_enable .d, reg2hw_i.transfer_mode.block_count_enable .q, + !reg2hw_i.present_state.command_inhibit_cmd.q && reg2hw_i.transfer_mode.block_count_enable .qe, clear_i, '0, clk_i, rst_ni) + // dma_enable is read-only zero in the register file (DMA not implemented), no shadow needed // Writes to the block_count and block_size register should be ignored when command_inhibit_dat is active logic [11:0] block_size; - `FFL (block_size, reg2hw_i.block_size.transfer_block_size.q, - !reg2hw_i.present_state.command_inhibit_dat.q && reg2hw_i.block_size.transfer_block_size.qe, '0); + `FFLARNC (block_size, reg2hw_i.block_size.transfer_block_size.q, + !reg2hw_i.present_state.command_inhibit_dat.q && reg2hw_i.block_size.transfer_block_size.qe, clear_i, '0, clk_i, rst_ni); assign block_size_reg_o.transfer_block_size.d = block_size; assign block_size_reg_o.host_dma_buffer_boundary.d = '0; @@ -186,7 +240,9 @@ module sdhci_reg_logic ( `FF (block_count_q, block_count_d, '0); always_comb begin block_count_d = block_count_q; - if (!reg2hw_i.present_state.command_inhibit_dat.q && reg2hw_i.block_count.qe) begin + if (clear_dat_i) begin + block_count_d = '0; + end else if (!reg2hw_i.present_state.command_inhibit_dat.q && reg2hw_i.block_count.qe) begin block_count_d = reg2hw_i.block_count.q; end else if (block_count_hw_i.de) begin block_count_d = block_count_hw_i.d; @@ -201,7 +257,7 @@ module sdhci_reg_logic ( reg2hw_modified_o.transfer_mode.data_transfer_direction_select.q = transfer_mode_reg_o.data_transfer_direction_select.d; reg2hw_modified_o.transfer_mode.auto_cmd12_enable .q = transfer_mode_reg_o.auto_cmd12_enable .d; reg2hw_modified_o.transfer_mode.block_count_enable .q = transfer_mode_reg_o.block_count_enable .d; - reg2hw_modified_o.transfer_mode.dma_enable .q = transfer_mode_reg_o.dma_enable .d; + // dma_enable removed from struct (read-only zero in register file) reg2hw_modified_o.block_size.transfer_block_size.q = block_size_reg_o.transfer_block_size.d; diff --git a/hw/reg/sdhci_reg_pkg.sv b/hw/reg/sdhci_reg_pkg.sv index daaab16..4eb119d 100644 --- a/hw/reg/sdhci_reg_pkg.sv +++ b/hw/reg/sdhci_reg_pkg.sv @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 // -// Register Package auto-generated by `reggen` containing data structure +// SDHCI register data structures. package sdhci_reg_pkg; @@ -34,10 +34,6 @@ package sdhci_reg_pkg; } sdhci_reg2hw_argument_reg_t; typedef struct packed { - struct packed { - logic q; - logic qe; - } dma_enable; struct packed { logic q; logic qe; @@ -148,53 +144,11 @@ package sdhci_reg_pkg; } sdhci_reg2hw_present_state_reg_t; typedef struct packed { - struct packed { - logic q; - } led_control; struct packed { logic q; } data_transfer_width; - struct packed { - logic q; - } high_speed_enable; } sdhci_reg2hw_host_control_reg_t; - typedef struct packed { - struct packed { - logic q; - } sd_bus_power; - struct packed { - logic [2:0] q; - } sd_bus_voltage_select; - } sdhci_reg2hw_power_control_reg_t; - - typedef struct packed { - struct packed { - logic q; - } stop_at_block_gap_request; - struct packed { - logic q; - } continue_request; - struct packed { - logic q; - } read_wait_control; - struct packed { - logic q; - } interrupt_at_block_gap; - } sdhci_reg2hw_block_gap_control_reg_t; - - typedef struct packed { - struct packed { - logic q; - } wakeup_event_enable_on_card_interrupt; - struct packed { - logic q; - } wakeup_event_enable_on_sd_card_insertion; - struct packed { - logic q; - } wakeup_event_enable_on_sd_card_removal; - } sdhci_reg2hw_wakeup_control_reg_t; - typedef struct packed { struct packed { logic q; @@ -290,12 +244,6 @@ package sdhci_reg_pkg; struct packed { logic q; } transfer_complete_status_enable; - struct packed { - logic q; - } block_gap_event_status_enable; - struct packed { - logic q; - } dma_interrupt_status_enable; struct packed { logic q; } buffer_write_ready_status_enable; @@ -338,15 +286,9 @@ package sdhci_reg_pkg; struct packed { logic q; } data_end_bit_error_status_enable; - struct packed { - logic q; - } current_limit_error_status_enable; struct packed { logic q; } auto_cmd12_error_status_enable; - struct packed { - logic [3:0] q; - } vendor_specific_error_status_enable; } sdhci_reg2hw_error_interrupt_status_enable_reg_t; typedef struct packed { @@ -356,12 +298,6 @@ package sdhci_reg_pkg; struct packed { logic q; } transfer_complete_signal_enable; - struct packed { - logic q; - } block_gap_event_signal_enable; - struct packed { - logic q; - } dma_interrupt_signal_enable; struct packed { logic q; } buffer_write_ready_signal_enable; @@ -401,15 +337,9 @@ package sdhci_reg_pkg; struct packed { logic q; } data_end_bit_error_signal_enable; - struct packed { - logic q; - } current_limit_error_signal_enable; struct packed { logic q; } auto_cmd12_error_signal_enable; - struct packed { - logic [3:0] q; - } vendor_specific_error_signal_enable; } sdhci_reg2hw_error_interrupt_signal_enable_reg_t; typedef struct packed { @@ -447,9 +377,6 @@ package sdhci_reg_pkg; } sdhci_hw2reg_block_count_reg_t; typedef struct packed { - struct packed { - logic d; - } dma_enable; struct packed { logic d; } block_count_enable; @@ -551,6 +478,10 @@ package sdhci_reg_pkg; } sdhci_hw2reg_clock_control_reg_t; typedef struct packed { + struct packed { + logic d; + logic de; + } software_reset_for_all; struct packed { logic d; logic de; @@ -662,46 +593,43 @@ package sdhci_reg_pkg; // Register -> HW type typedef struct packed { - sdhci_reg2hw_block_size_reg_t block_size; // [374:358] - sdhci_reg2hw_block_count_reg_t block_count; // [357:341] - sdhci_reg2hw_argument_reg_t argument; // [340:309] - sdhci_reg2hw_transfer_mode_reg_t transfer_mode; // [308:299] - sdhci_reg2hw_command_reg_t command; // [298:280] - sdhci_reg2hw_response0_reg_t response0; // [279:248] - sdhci_reg2hw_response1_reg_t response1; // [247:216] - sdhci_reg2hw_response2_reg_t response2; // [215:184] - sdhci_reg2hw_response3_reg_t response3; // [183:152] - sdhci_reg2hw_buffer_data_port_reg_t buffer_data_port; // [151:118] - sdhci_reg2hw_present_state_reg_t present_state; // [117:102] - sdhci_reg2hw_host_control_reg_t host_control; // [101:99] - sdhci_reg2hw_power_control_reg_t power_control; // [98:95] - sdhci_reg2hw_block_gap_control_reg_t block_gap_control; // [94:91] - sdhci_reg2hw_wakeup_control_reg_t wakeup_control; // [90:88] - sdhci_reg2hw_clock_control_reg_t clock_control; // [87:73] - sdhci_reg2hw_timeout_control_reg_t timeout_control; // [72:69] - sdhci_reg2hw_software_reset_reg_t software_reset; // [68:66] - sdhci_reg2hw_normal_interrupt_status_reg_t normal_interrupt_status; // [65:59] - sdhci_reg2hw_error_interrupt_status_reg_t error_interrupt_status; // [58:51] - sdhci_reg2hw_normal_interrupt_status_enable_reg_t normal_interrupt_status_enable; // [50:41] - sdhci_reg2hw_error_interrupt_status_enable_reg_t error_interrupt_status_enable; // [40:28] - sdhci_reg2hw_normal_interrupt_signal_enable_reg_t normal_interrupt_signal_enable; // [27:19] - sdhci_reg2hw_error_interrupt_signal_enable_reg_t error_interrupt_signal_enable; // [18:6] + sdhci_reg2hw_block_size_reg_t block_size; // [345:329] + sdhci_reg2hw_block_count_reg_t block_count; // [328:312] + sdhci_reg2hw_argument_reg_t argument; // [311:280] + sdhci_reg2hw_transfer_mode_reg_t transfer_mode; // [279:272] + sdhci_reg2hw_command_reg_t command; // [271:253] + sdhci_reg2hw_response0_reg_t response0; // [252:221] + sdhci_reg2hw_response1_reg_t response1; // [220:189] + sdhci_reg2hw_response2_reg_t response2; // [188:157] + sdhci_reg2hw_response3_reg_t response3; // [156:125] + sdhci_reg2hw_buffer_data_port_reg_t buffer_data_port; // [124:91] + sdhci_reg2hw_present_state_reg_t present_state; // [90:75] + sdhci_reg2hw_host_control_reg_t host_control; // [74:74] + sdhci_reg2hw_clock_control_reg_t clock_control; // [73:59] + sdhci_reg2hw_timeout_control_reg_t timeout_control; // [58:55] + sdhci_reg2hw_software_reset_reg_t software_reset; // [54:52] + sdhci_reg2hw_normal_interrupt_status_reg_t normal_interrupt_status; // [51:45] + sdhci_reg2hw_error_interrupt_status_reg_t error_interrupt_status; // [44:37] + sdhci_reg2hw_normal_interrupt_status_enable_reg_t normal_interrupt_status_enable; // [36:29] + sdhci_reg2hw_error_interrupt_status_enable_reg_t error_interrupt_status_enable; // [28:21] + sdhci_reg2hw_normal_interrupt_signal_enable_reg_t normal_interrupt_signal_enable; // [20:14] + sdhci_reg2hw_error_interrupt_signal_enable_reg_t error_interrupt_signal_enable; // [13:6] sdhci_reg2hw_auto_cmd12_error_status_reg_t auto_cmd12_error_status; // [5:0] } sdhci_reg2hw_t; // HW -> register type typedef struct packed { - sdhci_hw2reg_block_size_reg_t block_size; // [284:270] - sdhci_hw2reg_block_count_reg_t block_count; // [269:254] - sdhci_hw2reg_transfer_mode_reg_t transfer_mode; // [253:249] - sdhci_hw2reg_response0_reg_t response0; // [248:216] - sdhci_hw2reg_response1_reg_t response1; // [215:183] - sdhci_hw2reg_response2_reg_t response2; // [182:150] - sdhci_hw2reg_response3_reg_t response3; // [149:117] - sdhci_hw2reg_buffer_data_port_reg_t buffer_data_port; // [116:85] - sdhci_hw2reg_present_state_reg_t present_state; // [84:56] - sdhci_hw2reg_clock_control_reg_t clock_control; // [55:54] - sdhci_hw2reg_software_reset_reg_t software_reset; // [53:50] + sdhci_hw2reg_block_size_reg_t block_size; // [285:271] + sdhci_hw2reg_block_count_reg_t block_count; // [270:255] + sdhci_hw2reg_transfer_mode_reg_t transfer_mode; // [254:251] + sdhci_hw2reg_response0_reg_t response0; // [250:218] + sdhci_hw2reg_response1_reg_t response1; // [217:185] + sdhci_hw2reg_response2_reg_t response2; // [184:152] + sdhci_hw2reg_response3_reg_t response3; // [151:119] + sdhci_hw2reg_buffer_data_port_reg_t buffer_data_port; // [118:87] + sdhci_hw2reg_present_state_reg_t present_state; // [86:58] + sdhci_hw2reg_clock_control_reg_t clock_control; // [57:56] + sdhci_hw2reg_software_reset_reg_t software_reset; // [55:50] sdhci_hw2reg_normal_interrupt_status_reg_t normal_interrupt_status; // [49:36] sdhci_hw2reg_error_interrupt_status_reg_t error_interrupt_status; // [35:20] sdhci_hw2reg_auto_cmd12_error_status_reg_t auto_cmd12_error_status; // [19:8] @@ -747,6 +675,7 @@ package sdhci_reg_pkg; parameter logic [0:0] SDHCI_BLOCK_SIZE_RSVD_15_RESVAL = 1'h 0; parameter logic [31:0] SDHCI_BLOCK_COUNT_RESVAL = 32'h 0; parameter logic [15:0] SDHCI_TRANSFER_MODE_RESVAL = 16'h 0; + parameter logic [0:0] SDHCI_TRANSFER_MODE_DMA_ENABLE_RESVAL = 1'h 0; parameter logic [0:0] SDHCI_TRANSFER_MODE_RSVD_3_RESVAL = 1'h 0; parameter logic [1:0] SDHCI_TRANSFER_MODE_RSVD_6_RESVAL = 2'h 0; parameter logic [7:0] SDHCI_TRANSFER_MODE_RSVD_8_RESVAL = 8'h 0; @@ -864,4 +793,3 @@ package sdhci_reg_pkg; }; endpackage - diff --git a/hw/reg/sdhci_reg_top.sv b/hw/reg/sdhci_reg_top.sv index a1ae4dc..ef75b2f 100644 --- a/hw/reg/sdhci_reg_top.sv +++ b/hw/reg/sdhci_reg_top.sv @@ -1,4425 +1,758 @@ // Copyright lowRISC contributors. // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 -// -// Register Top module auto-generated by `reggen` +module sdhci_reg_top #( + parameter type reg_req_t = logic, + parameter type reg_rsp_t = logic, + parameter int AW = 8, + parameter int unsigned BufferNumWords = 256, + parameter bit AllowNoncompliantBufferSizes = 1'b0 +) ( + input logic clk_i, + input logic rst_ni, + input reg_req_t reg_req_i, + output reg_rsp_t reg_rsp_o, -`include "common_cells/assertions.svh" - -module sdhci_reg_top #( - parameter type reg_req_t = logic, - parameter type reg_rsp_t = logic, - parameter int AW = 8 -) ( - input logic clk_i, - input logic rst_ni, - input reg_req_t reg_req_i, - output reg_rsp_t reg_rsp_o, - // To HW - output sdhci_reg_pkg::sdhci_reg2hw_t reg2hw, // Write - input sdhci_reg_pkg::sdhci_hw2reg_t hw2reg, // Read - - - // Config - input devmode_i // If 1, explicit error return for unmapped register access -); - - import sdhci_reg_pkg::* ; - - localparam int DW = 32; - localparam int DBW = DW/8; // Byte Width - - // register signals - logic reg_we; - logic reg_re; - logic [BlockAw-1:0] reg_addr; - logic [DW-1:0] reg_wdata; - logic [DBW-1:0] reg_be; - logic [DW-1:0] reg_rdata; - logic reg_error; - - logic addrmiss, wr_err; - - logic [DW-1:0] reg_rdata_next; - - // Below register interface can be changed - reg_req_t reg_intf_req; - reg_rsp_t reg_intf_rsp; - - - assign reg_intf_req = reg_req_i; - assign reg_rsp_o = reg_intf_rsp; - - - assign reg_we = reg_intf_req.valid & reg_intf_req.write; - assign reg_re = reg_intf_req.valid & ~reg_intf_req.write; - assign reg_addr = reg_intf_req.addr[BlockAw-1:0]; - assign reg_wdata = reg_intf_req.wdata; - assign reg_be = reg_intf_req.wstrb; - assign reg_intf_rsp.rdata = reg_rdata; - assign reg_intf_rsp.error = reg_error; - assign reg_intf_rsp.ready = 1'b1; - - assign reg_rdata = reg_rdata_next ; - assign reg_error = (devmode_i & addrmiss) | wr_err; - - - // Define SW related signals - // Format: __{wd|we|qs} - // or _{wd|we|qs} if field == 1 or 0 - logic [31:0] system_address_qs; - logic [31:0] system_address_wd; - logic system_address_we; - logic [11:0] block_size_transfer_block_size_qs; - logic [11:0] block_size_transfer_block_size_wd; - logic block_size_transfer_block_size_we; - logic block_size_transfer_block_size_re; - logic [2:0] block_size_host_dma_buffer_boundary_qs; - logic [2:0] block_size_host_dma_buffer_boundary_wd; - logic block_size_host_dma_buffer_boundary_we; - logic block_size_host_dma_buffer_boundary_re; - logic block_size_rsvd_15_qs; - logic block_size_rsvd_15_re; - logic [15:0] block_count_qs; - logic [15:0] block_count_wd; - logic block_count_we; - logic block_count_re; - logic [31:0] argument_qs; - logic [31:0] argument_wd; - logic argument_we; - logic transfer_mode_dma_enable_qs; - logic transfer_mode_dma_enable_wd; - logic transfer_mode_dma_enable_we; - logic transfer_mode_dma_enable_re; - logic transfer_mode_block_count_enable_qs; - logic transfer_mode_block_count_enable_wd; - logic transfer_mode_block_count_enable_we; - logic transfer_mode_block_count_enable_re; - logic transfer_mode_auto_cmd12_enable_qs; - logic transfer_mode_auto_cmd12_enable_wd; - logic transfer_mode_auto_cmd12_enable_we; - logic transfer_mode_auto_cmd12_enable_re; - logic transfer_mode_rsvd_3_qs; - logic transfer_mode_rsvd_3_re; - logic transfer_mode_data_transfer_direction_select_qs; - logic transfer_mode_data_transfer_direction_select_wd; - logic transfer_mode_data_transfer_direction_select_we; - logic transfer_mode_data_transfer_direction_select_re; - logic transfer_mode_multi_single_block_select_qs; - logic transfer_mode_multi_single_block_select_wd; - logic transfer_mode_multi_single_block_select_we; - logic transfer_mode_multi_single_block_select_re; - logic [1:0] transfer_mode_rsvd_6_qs; - logic transfer_mode_rsvd_6_re; - logic [7:0] transfer_mode_rsvd_8_qs; - logic transfer_mode_rsvd_8_re; - logic [1:0] command_response_type_select_qs; - logic [1:0] command_response_type_select_wd; - logic command_response_type_select_we; - logic command_rsvd_2_qs; - logic command_command_crc_check_enable_qs; - logic command_command_crc_check_enable_wd; - logic command_command_crc_check_enable_we; - logic command_command_index_check_enable_qs; - logic command_command_index_check_enable_wd; - logic command_command_index_check_enable_we; - logic command_data_present_select_qs; - logic command_data_present_select_wd; - logic command_data_present_select_we; - logic [1:0] command_command_type_qs; - logic [1:0] command_command_type_wd; - logic command_command_type_we; - logic [5:0] command_command_index_qs; - logic [5:0] command_command_index_wd; - logic command_command_index_we; - logic [1:0] command_rsvd_14_qs; - logic [31:0] response0_qs; - logic [31:0] response1_qs; - logic [31:0] response2_qs; - logic [31:0] response3_qs; - logic [31:0] buffer_data_port_qs; - logic [31:0] buffer_data_port_wd; - logic buffer_data_port_we; - logic buffer_data_port_re; - logic present_state_command_inhibit_cmd_qs; - logic present_state_command_inhibit_dat_qs; - logic present_state_dat_line_active_qs; - logic [4:0] present_state_rsvd_3_qs; - logic present_state_write_transfer_active_qs; - logic present_state_read_transfer_active_qs; - logic present_state_buffer_write_enable_qs; - logic present_state_buffer_read_enable_qs; - logic [3:0] present_state_rsvd_12_qs; - logic present_state_card_inserted_qs; - logic present_state_card_state_stable_qs; - logic present_state_card_detect_pin_level_qs; - logic present_state_write_protect_switch_pin_level_qs; - logic [3:0] present_state_dat_line_signal_level_qs; - logic present_state_cmd_line_signal_level_qs; - logic [6:0] present_state_rsvd_25_qs; - logic host_control_led_control_qs; - logic host_control_led_control_wd; - logic host_control_led_control_we; - logic host_control_data_transfer_width_qs; - logic host_control_data_transfer_width_wd; - logic host_control_data_transfer_width_we; - logic host_control_high_speed_enable_qs; - logic host_control_high_speed_enable_wd; - logic host_control_high_speed_enable_we; - logic [4:0] host_control_rsvd_3_qs; - logic power_control_sd_bus_power_qs; - logic power_control_sd_bus_power_wd; - logic power_control_sd_bus_power_we; - logic [2:0] power_control_sd_bus_voltage_select_qs; - logic [2:0] power_control_sd_bus_voltage_select_wd; - logic power_control_sd_bus_voltage_select_we; - logic [3:0] power_control_rsvd_4_qs; - logic block_gap_control_stop_at_block_gap_request_qs; - logic block_gap_control_stop_at_block_gap_request_wd; - logic block_gap_control_stop_at_block_gap_request_we; - logic block_gap_control_continue_request_qs; - logic block_gap_control_continue_request_wd; - logic block_gap_control_continue_request_we; - logic block_gap_control_read_wait_control_qs; - logic block_gap_control_read_wait_control_wd; - logic block_gap_control_read_wait_control_we; - logic block_gap_control_interrupt_at_block_gap_qs; - logic block_gap_control_interrupt_at_block_gap_wd; - logic block_gap_control_interrupt_at_block_gap_we; - logic [3:0] block_gap_control_rsvd_4_qs; - logic wakeup_control_wakeup_event_enable_on_card_interrupt_qs; - logic wakeup_control_wakeup_event_enable_on_card_interrupt_wd; - logic wakeup_control_wakeup_event_enable_on_card_interrupt_we; - logic wakeup_control_wakeup_event_enable_on_sd_card_insertion_qs; - logic wakeup_control_wakeup_event_enable_on_sd_card_insertion_wd; - logic wakeup_control_wakeup_event_enable_on_sd_card_insertion_we; - logic wakeup_control_wakeup_event_enable_on_sd_card_removal_qs; - logic wakeup_control_wakeup_event_enable_on_sd_card_removal_wd; - logic wakeup_control_wakeup_event_enable_on_sd_card_removal_we; - logic [4:0] wakeup_control_rsvd_3_qs; - logic clock_control_internal_clock_enable_qs; - logic clock_control_internal_clock_enable_wd; - logic clock_control_internal_clock_enable_we; - logic clock_control_internal_clock_stable_qs; - logic clock_control_sd_clock_enable_qs; - logic clock_control_sd_clock_enable_wd; - logic clock_control_sd_clock_enable_we; - logic [4:0] clock_control_rsvd_3_qs; - logic [7:0] clock_control_sdclk_frequency_select_qs; - logic [7:0] clock_control_sdclk_frequency_select_wd; - logic clock_control_sdclk_frequency_select_we; - logic [3:0] timeout_control_data_timeout_counter_value_qs; - logic [3:0] timeout_control_data_timeout_counter_value_wd; - logic timeout_control_data_timeout_counter_value_we; - logic [3:0] timeout_control_rsvd_4_qs; - logic software_reset_software_reset_for_all_qs; - logic software_reset_software_reset_for_all_wd; - logic software_reset_software_reset_for_all_we; - logic software_reset_software_reset_for_cmd_line_qs; - logic software_reset_software_reset_for_cmd_line_wd; - logic software_reset_software_reset_for_cmd_line_we; - logic software_reset_software_reset_for_dat_line_qs; - logic software_reset_software_reset_for_dat_line_wd; - logic software_reset_software_reset_for_dat_line_we; - logic [3:0] software_reset_rsvd_4_qs; - logic normal_interrupt_status_command_complete_qs; - logic normal_interrupt_status_command_complete_wd; - logic normal_interrupt_status_command_complete_we; - logic normal_interrupt_status_transfer_complete_qs; - logic normal_interrupt_status_transfer_complete_wd; - logic normal_interrupt_status_transfer_complete_we; - logic normal_interrupt_status_block_gap_event_qs; - logic normal_interrupt_status_block_gap_event_wd; - logic normal_interrupt_status_block_gap_event_we; - logic normal_interrupt_status_dma_interrupt_qs; - logic normal_interrupt_status_dma_interrupt_wd; - logic normal_interrupt_status_dma_interrupt_we; - logic normal_interrupt_status_buffer_write_ready_qs; - logic normal_interrupt_status_buffer_write_ready_wd; - logic normal_interrupt_status_buffer_write_ready_we; - logic normal_interrupt_status_buffer_read_ready_qs; - logic normal_interrupt_status_buffer_read_ready_wd; - logic normal_interrupt_status_buffer_read_ready_we; - logic normal_interrupt_status_card_insertion_qs; - logic normal_interrupt_status_card_insertion_wd; - logic normal_interrupt_status_card_insertion_we; - logic normal_interrupt_status_card_removal_qs; - logic normal_interrupt_status_card_removal_wd; - logic normal_interrupt_status_card_removal_we; - logic normal_interrupt_status_card_interrupt_qs; - logic [5:0] normal_interrupt_status_rsvd_9_qs; - logic normal_interrupt_status_error_interrupt_qs; - logic error_interrupt_status_command_timeout_error_qs; - logic error_interrupt_status_command_timeout_error_wd; - logic error_interrupt_status_command_timeout_error_we; - logic error_interrupt_status_command_crc_error_qs; - logic error_interrupt_status_command_crc_error_wd; - logic error_interrupt_status_command_crc_error_we; - logic error_interrupt_status_command_end_bit_error_qs; - logic error_interrupt_status_command_end_bit_error_wd; - logic error_interrupt_status_command_end_bit_error_we; - logic error_interrupt_status_command_index_error_qs; - logic error_interrupt_status_command_index_error_wd; - logic error_interrupt_status_command_index_error_we; - logic error_interrupt_status_data_timeout_error_qs; - logic error_interrupt_status_data_timeout_error_wd; - logic error_interrupt_status_data_timeout_error_we; - logic error_interrupt_status_data_crc_error_qs; - logic error_interrupt_status_data_crc_error_wd; - logic error_interrupt_status_data_crc_error_we; - logic error_interrupt_status_data_end_bit_error_qs; - logic error_interrupt_status_data_end_bit_error_wd; - logic error_interrupt_status_data_end_bit_error_we; - logic error_interrupt_status_current_limit_error_qs; - logic error_interrupt_status_current_limit_error_wd; - logic error_interrupt_status_current_limit_error_we; - logic error_interrupt_status_auto_cmd12_error_qs; - logic error_interrupt_status_auto_cmd12_error_wd; - logic error_interrupt_status_auto_cmd12_error_we; - logic [2:0] error_interrupt_status_rsvd_9_qs; - logic [3:0] error_interrupt_status_vendor_specific_error_qs; - logic [3:0] error_interrupt_status_vendor_specific_error_wd; - logic error_interrupt_status_vendor_specific_error_we; - logic normal_interrupt_status_enable_command_complete_status_enable_qs; - logic normal_interrupt_status_enable_command_complete_status_enable_wd; - logic normal_interrupt_status_enable_command_complete_status_enable_we; - logic normal_interrupt_status_enable_transfer_complete_status_enable_qs; - logic normal_interrupt_status_enable_transfer_complete_status_enable_wd; - logic normal_interrupt_status_enable_transfer_complete_status_enable_we; - logic normal_interrupt_status_enable_block_gap_event_status_enable_qs; - logic normal_interrupt_status_enable_block_gap_event_status_enable_wd; - logic normal_interrupt_status_enable_block_gap_event_status_enable_we; - logic normal_interrupt_status_enable_dma_interrupt_status_enable_qs; - logic normal_interrupt_status_enable_dma_interrupt_status_enable_wd; - logic normal_interrupt_status_enable_dma_interrupt_status_enable_we; - logic normal_interrupt_status_enable_buffer_write_ready_status_enable_qs; - logic normal_interrupt_status_enable_buffer_write_ready_status_enable_wd; - logic normal_interrupt_status_enable_buffer_write_ready_status_enable_we; - logic normal_interrupt_status_enable_buffer_read_ready_status_enable_qs; - logic normal_interrupt_status_enable_buffer_read_ready_status_enable_wd; - logic normal_interrupt_status_enable_buffer_read_ready_status_enable_we; - logic normal_interrupt_status_enable_card_insertion_status_enable_qs; - logic normal_interrupt_status_enable_card_insertion_status_enable_wd; - logic normal_interrupt_status_enable_card_insertion_status_enable_we; - logic normal_interrupt_status_enable_card_removal_status_enable_qs; - logic normal_interrupt_status_enable_card_removal_status_enable_wd; - logic normal_interrupt_status_enable_card_removal_status_enable_we; - logic normal_interrupt_status_enable_card_interrupt_status_enable_qs; - logic normal_interrupt_status_enable_card_interrupt_status_enable_wd; - logic normal_interrupt_status_enable_card_interrupt_status_enable_we; - logic [5:0] normal_interrupt_status_enable_rsvd_9_qs; - logic normal_interrupt_status_enable_fixed_to_0_qs; - logic error_interrupt_status_enable_command_timeout_error_status_enable_qs; - logic error_interrupt_status_enable_command_timeout_error_status_enable_wd; - logic error_interrupt_status_enable_command_timeout_error_status_enable_we; - logic error_interrupt_status_enable_command_crc_error_status_enable_qs; - logic error_interrupt_status_enable_command_crc_error_status_enable_wd; - logic error_interrupt_status_enable_command_crc_error_status_enable_we; - logic error_interrupt_status_enable_command_end_bit_error_status_enable_qs; - logic error_interrupt_status_enable_command_end_bit_error_status_enable_wd; - logic error_interrupt_status_enable_command_end_bit_error_status_enable_we; - logic error_interrupt_status_enable_command_index_error_status_enable_qs; - logic error_interrupt_status_enable_command_index_error_status_enable_wd; - logic error_interrupt_status_enable_command_index_error_status_enable_we; - logic error_interrupt_status_enable_data_timeout_error_status_enable_qs; - logic error_interrupt_status_enable_data_timeout_error_status_enable_wd; - logic error_interrupt_status_enable_data_timeout_error_status_enable_we; - logic error_interrupt_status_enable_data_crc_error_status_enable_qs; - logic error_interrupt_status_enable_data_crc_error_status_enable_wd; - logic error_interrupt_status_enable_data_crc_error_status_enable_we; - logic error_interrupt_status_enable_data_end_bit_error_status_enable_qs; - logic error_interrupt_status_enable_data_end_bit_error_status_enable_wd; - logic error_interrupt_status_enable_data_end_bit_error_status_enable_we; - logic error_interrupt_status_enable_current_limit_error_status_enable_qs; - logic error_interrupt_status_enable_current_limit_error_status_enable_wd; - logic error_interrupt_status_enable_current_limit_error_status_enable_we; - logic error_interrupt_status_enable_auto_cmd12_error_status_enable_qs; - logic error_interrupt_status_enable_auto_cmd12_error_status_enable_wd; - logic error_interrupt_status_enable_auto_cmd12_error_status_enable_we; - logic [2:0] error_interrupt_status_enable_rsvd_9_qs; - logic [3:0] error_interrupt_status_enable_vendor_specific_error_status_enable_qs; - logic [3:0] error_interrupt_status_enable_vendor_specific_error_status_enable_wd; - logic error_interrupt_status_enable_vendor_specific_error_status_enable_we; - logic normal_interrupt_signal_enable_command_complete_signal_enable_qs; - logic normal_interrupt_signal_enable_command_complete_signal_enable_wd; - logic normal_interrupt_signal_enable_command_complete_signal_enable_we; - logic normal_interrupt_signal_enable_transfer_complete_signal_enable_qs; - logic normal_interrupt_signal_enable_transfer_complete_signal_enable_wd; - logic normal_interrupt_signal_enable_transfer_complete_signal_enable_we; - logic normal_interrupt_signal_enable_block_gap_event_signal_enable_qs; - logic normal_interrupt_signal_enable_block_gap_event_signal_enable_wd; - logic normal_interrupt_signal_enable_block_gap_event_signal_enable_we; - logic normal_interrupt_signal_enable_dma_interrupt_signal_enable_qs; - logic normal_interrupt_signal_enable_dma_interrupt_signal_enable_wd; - logic normal_interrupt_signal_enable_dma_interrupt_signal_enable_we; - logic normal_interrupt_signal_enable_buffer_write_ready_signal_enable_qs; - logic normal_interrupt_signal_enable_buffer_write_ready_signal_enable_wd; - logic normal_interrupt_signal_enable_buffer_write_ready_signal_enable_we; - logic normal_interrupt_signal_enable_buffer_read_ready_signal_enable_qs; - logic normal_interrupt_signal_enable_buffer_read_ready_signal_enable_wd; - logic normal_interrupt_signal_enable_buffer_read_ready_signal_enable_we; - logic normal_interrupt_signal_enable_card_insertion_signal_enable_qs; - logic normal_interrupt_signal_enable_card_insertion_signal_enable_wd; - logic normal_interrupt_signal_enable_card_insertion_signal_enable_we; - logic normal_interrupt_signal_enable_card_removal_signal_enable_qs; - logic normal_interrupt_signal_enable_card_removal_signal_enable_wd; - logic normal_interrupt_signal_enable_card_removal_signal_enable_we; - logic normal_interrupt_signal_enable_card_interrupt_signal_enable_qs; - logic normal_interrupt_signal_enable_card_interrupt_signal_enable_wd; - logic normal_interrupt_signal_enable_card_interrupt_signal_enable_we; - logic [5:0] normal_interrupt_signal_enable_rsvd_9_qs; - logic normal_interrupt_signal_enable_fixed_to_0_qs; - logic error_interrupt_signal_enable_command_timeout_error_signal_enable_qs; - logic error_interrupt_signal_enable_command_timeout_error_signal_enable_wd; - logic error_interrupt_signal_enable_command_timeout_error_signal_enable_we; - logic error_interrupt_signal_enable_command_crc_error_signal_enable_qs; - logic error_interrupt_signal_enable_command_crc_error_signal_enable_wd; - logic error_interrupt_signal_enable_command_crc_error_signal_enable_we; - logic error_interrupt_signal_enable_command_end_bit_error_signal_enable_qs; - logic error_interrupt_signal_enable_command_end_bit_error_signal_enable_wd; - logic error_interrupt_signal_enable_command_end_bit_error_signal_enable_we; - logic error_interrupt_signal_enable_command_index_error_signal_enable_qs; - logic error_interrupt_signal_enable_command_index_error_signal_enable_wd; - logic error_interrupt_signal_enable_command_index_error_signal_enable_we; - logic error_interrupt_signal_enable_data_timeout_error_signal_enable_qs; - logic error_interrupt_signal_enable_data_timeout_error_signal_enable_wd; - logic error_interrupt_signal_enable_data_timeout_error_signal_enable_we; - logic error_interrupt_signal_enable_data_crc_error_signal_enable_qs; - logic error_interrupt_signal_enable_data_crc_error_signal_enable_wd; - logic error_interrupt_signal_enable_data_crc_error_signal_enable_we; - logic error_interrupt_signal_enable_data_end_bit_error_signal_enable_qs; - logic error_interrupt_signal_enable_data_end_bit_error_signal_enable_wd; - logic error_interrupt_signal_enable_data_end_bit_error_signal_enable_we; - logic error_interrupt_signal_enable_current_limit_error_signal_enable_qs; - logic error_interrupt_signal_enable_current_limit_error_signal_enable_wd; - logic error_interrupt_signal_enable_current_limit_error_signal_enable_we; - logic error_interrupt_signal_enable_auto_cmd12_error_signal_enable_qs; - logic error_interrupt_signal_enable_auto_cmd12_error_signal_enable_wd; - logic error_interrupt_signal_enable_auto_cmd12_error_signal_enable_we; - logic [2:0] error_interrupt_signal_enable_rsvd_9_qs; - logic [3:0] error_interrupt_signal_enable_vendor_specific_error_signal_enable_qs; - logic [3:0] error_interrupt_signal_enable_vendor_specific_error_signal_enable_wd; - logic error_interrupt_signal_enable_vendor_specific_error_signal_enable_we; - logic auto_cmd12_error_status_auto_cmd12_not_executed_qs; - logic auto_cmd12_error_status_auto_cmd12_timeout_error_qs; - logic auto_cmd12_error_status_auto_cmd12_crc_error_qs; - logic auto_cmd12_error_status_auto_cmd12_end_bit_error_qs; - logic auto_cmd12_error_status_auto_cmd12_index_error_qs; - logic [1:0] auto_cmd12_error_status_rsvd_5_qs; - logic auto_cmd12_error_status_command_not_issued_by_auto_cmd12_error_qs; - logic [7:0] auto_cmd12_error_status_rsvd_8_qs; - logic [5:0] capabilities_timeout_clock_frequency_qs; - logic capabilities_rsvd_6_qs; - logic capabilities_timeout_clock_unit_qs; - logic [5:0] capabilities_base_clock_frequency_for_sd_clock_qs; - logic [1:0] capabilities_rsvd_14_qs; - logic [1:0] capabilities_max_block_length_qs; - logic [2:0] capabilities_rsvd_18_qs; - logic capabilities_high_speed_support_qs; - logic capabilities_dma_support_qs; - logic capabilities_suspend_resume_support_qs; - logic capabilities_voltage_support_3_3v_qs; - logic capabilities_voltage_support_3_0v_qs; - logic capabilities_voltage_support_1_8v_qs; - logic [4:0] capabilities_rsvd_27_qs; - logic [31:0] capabilities_reserved_qs; - logic [7:0] maximum_current_capabilities_maximum_current_for_3_3v_qs; - logic [7:0] maximum_current_capabilities_maximum_current_for_3_0v_qs; - logic [7:0] maximum_current_capabilities_maximum_current_for_1_8v_qs; - logic [7:0] maximum_current_capabilities_rsvd_24_qs; - logic [31:0] maximum_current_capabilities_reserved_qs; - logic [7:0] slot_interrupt_status_interrupt_signal_for_each_slot_qs; - logic slot_interrupt_status_interrupt_signal_for_each_slot_re; - logic [7:0] slot_interrupt_status_rsvd_8_qs; - logic slot_interrupt_status_rsvd_8_re; - logic [7:0] host_controller_version_specification_version_number_qs; - logic [7:0] host_controller_version_vendor_version_number_qs; - - // Register instances - // R[system_address]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'h0) - ) u_system_address ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (system_address_we), - .wd (system_address_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (), - - // to register interface (read) - .qs (system_address_qs) - ); - - - // R[block_size]: V(True) - - // F[transfer_block_size]: 11:0 - prim_subreg_ext #( - .DW (12) - ) u_block_size_transfer_block_size ( - .re (block_size_transfer_block_size_re), - .we (block_size_transfer_block_size_we), - .wd (block_size_transfer_block_size_wd), - .d (hw2reg.block_size.transfer_block_size.d), - .qre (), - .qe (reg2hw.block_size.transfer_block_size.qe), - .q (reg2hw.block_size.transfer_block_size.q ), - .qs (block_size_transfer_block_size_qs) - ); - - - // F[host_dma_buffer_boundary]: 14:12 - prim_subreg_ext #( - .DW (3) - ) u_block_size_host_dma_buffer_boundary ( - .re (block_size_host_dma_buffer_boundary_re), - .we (block_size_host_dma_buffer_boundary_we), - .wd (block_size_host_dma_buffer_boundary_wd), - .d (hw2reg.block_size.host_dma_buffer_boundary.d), - .qre (), - .qe (reg2hw.block_size.host_dma_buffer_boundary.qe), - .q (reg2hw.block_size.host_dma_buffer_boundary.q ), - .qs (block_size_host_dma_buffer_boundary_qs) - ); - - - // F[rsvd_15]: 15:15 - prim_subreg_ext #( - .DW (1) - ) u_block_size_rsvd_15 ( - .re (block_size_rsvd_15_re), - .we (1'b0), - .wd ('0), - .d ('0), - .qre (), - .qe (), - .q (), - .qs (block_size_rsvd_15_qs) - ); - - - // R[block_count]: V(True) - - prim_subreg_ext #( - .DW (16) - ) u_block_count ( - .re (block_count_re), - .we (block_count_we), - .wd (block_count_wd), - .d (hw2reg.block_count.d), - .qre (), - .qe (reg2hw.block_count.qe), - .q (reg2hw.block_count.q ), - .qs (block_count_qs) - ); - - - // R[argument]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'h0) - ) u_argument ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (argument_we), - .wd (argument_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.argument.q ), - - // to register interface (read) - .qs (argument_qs) - ); - - - // R[transfer_mode]: V(True) - - // F[dma_enable]: 0:0 - prim_subreg_ext #( - .DW (1) - ) u_transfer_mode_dma_enable ( - .re (transfer_mode_dma_enable_re), - .we (transfer_mode_dma_enable_we), - .wd (transfer_mode_dma_enable_wd), - .d (hw2reg.transfer_mode.dma_enable.d), - .qre (), - .qe (reg2hw.transfer_mode.dma_enable.qe), - .q (reg2hw.transfer_mode.dma_enable.q ), - .qs (transfer_mode_dma_enable_qs) - ); - - - // F[block_count_enable]: 1:1 - prim_subreg_ext #( - .DW (1) - ) u_transfer_mode_block_count_enable ( - .re (transfer_mode_block_count_enable_re), - .we (transfer_mode_block_count_enable_we), - .wd (transfer_mode_block_count_enable_wd), - .d (hw2reg.transfer_mode.block_count_enable.d), - .qre (), - .qe (reg2hw.transfer_mode.block_count_enable.qe), - .q (reg2hw.transfer_mode.block_count_enable.q ), - .qs (transfer_mode_block_count_enable_qs) - ); - - - // F[auto_cmd12_enable]: 2:2 - prim_subreg_ext #( - .DW (1) - ) u_transfer_mode_auto_cmd12_enable ( - .re (transfer_mode_auto_cmd12_enable_re), - .we (transfer_mode_auto_cmd12_enable_we), - .wd (transfer_mode_auto_cmd12_enable_wd), - .d (hw2reg.transfer_mode.auto_cmd12_enable.d), - .qre (), - .qe (reg2hw.transfer_mode.auto_cmd12_enable.qe), - .q (reg2hw.transfer_mode.auto_cmd12_enable.q ), - .qs (transfer_mode_auto_cmd12_enable_qs) - ); - - - // F[rsvd_3]: 3:3 - prim_subreg_ext #( - .DW (1) - ) u_transfer_mode_rsvd_3 ( - .re (transfer_mode_rsvd_3_re), - .we (1'b0), - .wd ('0), - .d ('0), - .qre (), - .qe (), - .q (), - .qs (transfer_mode_rsvd_3_qs) - ); - - - // F[data_transfer_direction_select]: 4:4 - prim_subreg_ext #( - .DW (1) - ) u_transfer_mode_data_transfer_direction_select ( - .re (transfer_mode_data_transfer_direction_select_re), - .we (transfer_mode_data_transfer_direction_select_we), - .wd (transfer_mode_data_transfer_direction_select_wd), - .d (hw2reg.transfer_mode.data_transfer_direction_select.d), - .qre (), - .qe (reg2hw.transfer_mode.data_transfer_direction_select.qe), - .q (reg2hw.transfer_mode.data_transfer_direction_select.q ), - .qs (transfer_mode_data_transfer_direction_select_qs) - ); - - - // F[multi_single_block_select]: 5:5 - prim_subreg_ext #( - .DW (1) - ) u_transfer_mode_multi_single_block_select ( - .re (transfer_mode_multi_single_block_select_re), - .we (transfer_mode_multi_single_block_select_we), - .wd (transfer_mode_multi_single_block_select_wd), - .d (hw2reg.transfer_mode.multi_single_block_select.d), - .qre (), - .qe (reg2hw.transfer_mode.multi_single_block_select.qe), - .q (reg2hw.transfer_mode.multi_single_block_select.q ), - .qs (transfer_mode_multi_single_block_select_qs) - ); - - - // F[rsvd_6]: 7:6 - prim_subreg_ext #( - .DW (2) - ) u_transfer_mode_rsvd_6 ( - .re (transfer_mode_rsvd_6_re), - .we (1'b0), - .wd ('0), - .d ('0), - .qre (), - .qe (), - .q (), - .qs (transfer_mode_rsvd_6_qs) - ); - - - // F[rsvd_8]: 15:8 - prim_subreg_ext #( - .DW (8) - ) u_transfer_mode_rsvd_8 ( - .re (transfer_mode_rsvd_8_re), - .we (1'b0), - .wd ('0), - .d ('0), - .qre (), - .qe (), - .q (), - .qs (transfer_mode_rsvd_8_qs) - ); - - - // R[command]: V(False) - - // F[response_type_select]: 17:16 - prim_subreg #( - .DW (2), - .SWACCESS("RW"), - .RESVAL (2'h0) - ) u_command_response_type_select ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (command_response_type_select_we), - .wd (command_response_type_select_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (reg2hw.command.response_type_select.qe), - .q (reg2hw.command.response_type_select.q ), - - // to register interface (read) - .qs (command_response_type_select_qs) - ); - - - // F[rsvd_2]: 18:18 - // constant-only read - assign command_rsvd_2_qs = 1'h0; - - - // F[command_crc_check_enable]: 19:19 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_command_command_crc_check_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (command_command_crc_check_enable_we), - .wd (command_command_crc_check_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (reg2hw.command.command_crc_check_enable.qe), - .q (reg2hw.command.command_crc_check_enable.q ), - - // to register interface (read) - .qs (command_command_crc_check_enable_qs) - ); - - - // F[command_index_check_enable]: 20:20 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_command_command_index_check_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (command_command_index_check_enable_we), - .wd (command_command_index_check_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (reg2hw.command.command_index_check_enable.qe), - .q (reg2hw.command.command_index_check_enable.q ), - - // to register interface (read) - .qs (command_command_index_check_enable_qs) - ); - - - // F[data_present_select]: 21:21 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_command_data_present_select ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (command_data_present_select_we), - .wd (command_data_present_select_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (reg2hw.command.data_present_select.qe), - .q (reg2hw.command.data_present_select.q ), - - // to register interface (read) - .qs (command_data_present_select_qs) - ); - - - // F[command_type]: 23:22 - prim_subreg #( - .DW (2), - .SWACCESS("RW"), - .RESVAL (2'h0) - ) u_command_command_type ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (command_command_type_we), - .wd (command_command_type_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (reg2hw.command.command_type.qe), - .q (reg2hw.command.command_type.q ), - - // to register interface (read) - .qs (command_command_type_qs) - ); - - - // F[command_index]: 29:24 - prim_subreg #( - .DW (6), - .SWACCESS("RW"), - .RESVAL (6'h0) - ) u_command_command_index ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (command_command_index_we), - .wd (command_command_index_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (reg2hw.command.command_index.qe), - .q (reg2hw.command.command_index.q ), - - // to register interface (read) - .qs (command_command_index_qs) - ); - - - // F[rsvd_14]: 31:30 - // constant-only read - assign command_rsvd_14_qs = 2'h0; - - - // R[response0]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RO"), - .RESVAL (32'h0) - ) u_response0 ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.response0.de), - .d (hw2reg.response0.d ), - - // to internal hardware - .qe (), - .q (reg2hw.response0.q ), - - // to register interface (read) - .qs (response0_qs) - ); - - - // R[response1]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RO"), - .RESVAL (32'h0) - ) u_response1 ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.response1.de), - .d (hw2reg.response1.d ), - - // to internal hardware - .qe (), - .q (reg2hw.response1.q ), - - // to register interface (read) - .qs (response1_qs) - ); - - - // R[response2]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RO"), - .RESVAL (32'h0) - ) u_response2 ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.response2.de), - .d (hw2reg.response2.d ), - - // to internal hardware - .qe (), - .q (reg2hw.response2.q ), - - // to register interface (read) - .qs (response2_qs) - ); - - - // R[response3]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RO"), - .RESVAL (32'h0) - ) u_response3 ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.response3.de), - .d (hw2reg.response3.d ), - - // to internal hardware - .qe (), - .q (reg2hw.response3.q ), - - // to register interface (read) - .qs (response3_qs) - ); - - - // R[buffer_data_port]: V(True) - - prim_subreg_ext #( - .DW (32) - ) u_buffer_data_port ( - .re (buffer_data_port_re), - .we (buffer_data_port_we), - .wd (buffer_data_port_wd), - .d (hw2reg.buffer_data_port.d), - .qre (reg2hw.buffer_data_port.re), - .qe (reg2hw.buffer_data_port.qe), - .q (reg2hw.buffer_data_port.q ), - .qs (buffer_data_port_qs) - ); - - - // R[present_state]: V(False) - - // F[command_inhibit_cmd]: 0:0 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h0) - ) u_present_state_command_inhibit_cmd ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.present_state.command_inhibit_cmd.de), - .d (hw2reg.present_state.command_inhibit_cmd.d ), - - // to internal hardware - .qe (), - .q (reg2hw.present_state.command_inhibit_cmd.q ), - - // to register interface (read) - .qs (present_state_command_inhibit_cmd_qs) - ); - - - // F[command_inhibit_dat]: 1:1 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h0) - ) u_present_state_command_inhibit_dat ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.present_state.command_inhibit_dat.de), - .d (hw2reg.present_state.command_inhibit_dat.d ), - - // to internal hardware - .qe (), - .q (reg2hw.present_state.command_inhibit_dat.q ), - - // to register interface (read) - .qs (present_state_command_inhibit_dat_qs) - ); - - - // F[dat_line_active]: 2:2 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h0) - ) u_present_state_dat_line_active ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.present_state.dat_line_active.de), - .d (hw2reg.present_state.dat_line_active.d ), - - // to internal hardware - .qe (), - .q (reg2hw.present_state.dat_line_active.q ), - - // to register interface (read) - .qs (present_state_dat_line_active_qs) - ); - - - // F[rsvd_3]: 7:3 - // constant-only read - assign present_state_rsvd_3_qs = 5'h0; - - - // F[write_transfer_active]: 8:8 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h0) - ) u_present_state_write_transfer_active ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.present_state.write_transfer_active.de), - .d (hw2reg.present_state.write_transfer_active.d ), - - // to internal hardware - .qe (), - .q (reg2hw.present_state.write_transfer_active.q ), - - // to register interface (read) - .qs (present_state_write_transfer_active_qs) - ); - - - // F[read_transfer_active]: 9:9 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h0) - ) u_present_state_read_transfer_active ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.present_state.read_transfer_active.de), - .d (hw2reg.present_state.read_transfer_active.d ), - - // to internal hardware - .qe (), - .q (reg2hw.present_state.read_transfer_active.q ), - - // to register interface (read) - .qs (present_state_read_transfer_active_qs) - ); - - - // F[buffer_write_enable]: 10:10 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h0) - ) u_present_state_buffer_write_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.present_state.buffer_write_enable.de), - .d (hw2reg.present_state.buffer_write_enable.d ), - - // to internal hardware - .qe (), - .q (reg2hw.present_state.buffer_write_enable.q ), - - // to register interface (read) - .qs (present_state_buffer_write_enable_qs) - ); - - - // F[buffer_read_enable]: 11:11 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h0) - ) u_present_state_buffer_read_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.present_state.buffer_read_enable.de), - .d (hw2reg.present_state.buffer_read_enable.d ), - - // to internal hardware - .qe (), - .q (reg2hw.present_state.buffer_read_enable.q ), - - // to register interface (read) - .qs (present_state_buffer_read_enable_qs) - ); - - - // F[rsvd_12]: 15:12 - // constant-only read - assign present_state_rsvd_12_qs = 4'h0; - - - // F[card_inserted]: 16:16 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h0) - ) u_present_state_card_inserted ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.present_state.card_inserted.de), - .d (hw2reg.present_state.card_inserted.d ), - - // to internal hardware - .qe (), - .q (reg2hw.present_state.card_inserted.q ), - - // to register interface (read) - .qs (present_state_card_inserted_qs) - ); - - - // F[card_state_stable]: 17:17 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h0) - ) u_present_state_card_state_stable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.present_state.card_state_stable.de), - .d (hw2reg.present_state.card_state_stable.d ), - - // to internal hardware - .qe (), - .q (reg2hw.present_state.card_state_stable.q ), - - // to register interface (read) - .qs (present_state_card_state_stable_qs) - ); - - - // F[card_detect_pin_level]: 18:18 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h0) - ) u_present_state_card_detect_pin_level ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.present_state.card_detect_pin_level.de), - .d (hw2reg.present_state.card_detect_pin_level.d ), - - // to internal hardware - .qe (), - .q (reg2hw.present_state.card_detect_pin_level.q ), - - // to register interface (read) - .qs (present_state_card_detect_pin_level_qs) - ); - - - // F[write_protect_switch_pin_level]: 19:19 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h0) - ) u_present_state_write_protect_switch_pin_level ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.present_state.write_protect_switch_pin_level.de), - .d (hw2reg.present_state.write_protect_switch_pin_level.d ), - - // to internal hardware - .qe (), - .q (reg2hw.present_state.write_protect_switch_pin_level.q ), - - // to register interface (read) - .qs (present_state_write_protect_switch_pin_level_qs) - ); - - - // F[dat_line_signal_level]: 23:20 - prim_subreg #( - .DW (4), - .SWACCESS("RO"), - .RESVAL (4'h0) - ) u_present_state_dat_line_signal_level ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.present_state.dat_line_signal_level.de), - .d (hw2reg.present_state.dat_line_signal_level.d ), - - // to internal hardware - .qe (), - .q (reg2hw.present_state.dat_line_signal_level.q ), - - // to register interface (read) - .qs (present_state_dat_line_signal_level_qs) - ); - - - // F[cmd_line_signal_level]: 24:24 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h0) - ) u_present_state_cmd_line_signal_level ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.present_state.cmd_line_signal_level.de), - .d (hw2reg.present_state.cmd_line_signal_level.d ), - - // to internal hardware - .qe (), - .q (reg2hw.present_state.cmd_line_signal_level.q ), - - // to register interface (read) - .qs (present_state_cmd_line_signal_level_qs) - ); - - - // F[rsvd_25]: 31:25 - // constant-only read - assign present_state_rsvd_25_qs = 7'h0; - - - // R[host_control]: V(False) - - // F[led_control]: 0:0 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_host_control_led_control ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (host_control_led_control_we), - .wd (host_control_led_control_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.host_control.led_control.q ), - - // to register interface (read) - .qs (host_control_led_control_qs) - ); - - - // F[data_transfer_width]: 1:1 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_host_control_data_transfer_width ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (host_control_data_transfer_width_we), - .wd (host_control_data_transfer_width_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.host_control.data_transfer_width.q ), - - // to register interface (read) - .qs (host_control_data_transfer_width_qs) - ); - - - // F[high_speed_enable]: 2:2 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_host_control_high_speed_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (host_control_high_speed_enable_we), - .wd (host_control_high_speed_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.host_control.high_speed_enable.q ), - - // to register interface (read) - .qs (host_control_high_speed_enable_qs) - ); - - - // F[rsvd_3]: 7:3 - // constant-only read - assign host_control_rsvd_3_qs = 5'h0; - - - // R[power_control]: V(False) - - // F[sd_bus_power]: 8:8 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_power_control_sd_bus_power ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (power_control_sd_bus_power_we), - .wd (power_control_sd_bus_power_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.power_control.sd_bus_power.q ), - - // to register interface (read) - .qs (power_control_sd_bus_power_qs) - ); - - - // F[sd_bus_voltage_select]: 11:9 - prim_subreg #( - .DW (3), - .SWACCESS("RW"), - .RESVAL (3'h0) - ) u_power_control_sd_bus_voltage_select ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (power_control_sd_bus_voltage_select_we), - .wd (power_control_sd_bus_voltage_select_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.power_control.sd_bus_voltage_select.q ), - - // to register interface (read) - .qs (power_control_sd_bus_voltage_select_qs) - ); - - - // F[rsvd_4]: 15:12 - // constant-only read - assign power_control_rsvd_4_qs = 4'h0; - - - // R[block_gap_control]: V(False) - - // F[stop_at_block_gap_request]: 16:16 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_block_gap_control_stop_at_block_gap_request ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (block_gap_control_stop_at_block_gap_request_we), - .wd (block_gap_control_stop_at_block_gap_request_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.block_gap_control.stop_at_block_gap_request.q ), - - // to register interface (read) - .qs (block_gap_control_stop_at_block_gap_request_qs) - ); - - - // F[continue_request]: 17:17 - prim_subreg #( - .DW (1), - .SWACCESS("W1S"), - .RESVAL (1'h0) - ) u_block_gap_control_continue_request ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (block_gap_control_continue_request_we), - .wd (block_gap_control_continue_request_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.block_gap_control.continue_request.q ), - - // to register interface (read) - .qs (block_gap_control_continue_request_qs) - ); - - - // F[read_wait_control]: 18:18 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_block_gap_control_read_wait_control ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (block_gap_control_read_wait_control_we), - .wd (block_gap_control_read_wait_control_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.block_gap_control.read_wait_control.q ), - - // to register interface (read) - .qs (block_gap_control_read_wait_control_qs) - ); - - - // F[interrupt_at_block_gap]: 19:19 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_block_gap_control_interrupt_at_block_gap ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (block_gap_control_interrupt_at_block_gap_we), - .wd (block_gap_control_interrupt_at_block_gap_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.block_gap_control.interrupt_at_block_gap.q ), - - // to register interface (read) - .qs (block_gap_control_interrupt_at_block_gap_qs) - ); - - - // F[rsvd_4]: 23:20 - // constant-only read - assign block_gap_control_rsvd_4_qs = 4'h0; - - - // R[wakeup_control]: V(False) - - // F[wakeup_event_enable_on_card_interrupt]: 24:24 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_wakeup_control_wakeup_event_enable_on_card_interrupt ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (wakeup_control_wakeup_event_enable_on_card_interrupt_we), - .wd (wakeup_control_wakeup_event_enable_on_card_interrupt_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.wakeup_control.wakeup_event_enable_on_card_interrupt.q ), - - // to register interface (read) - .qs (wakeup_control_wakeup_event_enable_on_card_interrupt_qs) - ); - - - // F[wakeup_event_enable_on_sd_card_insertion]: 25:25 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_wakeup_control_wakeup_event_enable_on_sd_card_insertion ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (wakeup_control_wakeup_event_enable_on_sd_card_insertion_we), - .wd (wakeup_control_wakeup_event_enable_on_sd_card_insertion_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.wakeup_control.wakeup_event_enable_on_sd_card_insertion.q ), - - // to register interface (read) - .qs (wakeup_control_wakeup_event_enable_on_sd_card_insertion_qs) - ); - - - // F[wakeup_event_enable_on_sd_card_removal]: 26:26 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_wakeup_control_wakeup_event_enable_on_sd_card_removal ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (wakeup_control_wakeup_event_enable_on_sd_card_removal_we), - .wd (wakeup_control_wakeup_event_enable_on_sd_card_removal_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.wakeup_control.wakeup_event_enable_on_sd_card_removal.q ), - - // to register interface (read) - .qs (wakeup_control_wakeup_event_enable_on_sd_card_removal_qs) - ); - - - // F[rsvd_3]: 31:27 - // constant-only read - assign wakeup_control_rsvd_3_qs = 5'h0; - - - // R[clock_control]: V(False) - - // F[internal_clock_enable]: 0:0 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_clock_control_internal_clock_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (clock_control_internal_clock_enable_we), - .wd (clock_control_internal_clock_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (reg2hw.clock_control.internal_clock_enable.qe), - .q (reg2hw.clock_control.internal_clock_enable.q ), - - // to register interface (read) - .qs (clock_control_internal_clock_enable_qs) - ); - - - // F[internal_clock_stable]: 1:1 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h1) - ) u_clock_control_internal_clock_stable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.clock_control.internal_clock_stable.de), - .d (hw2reg.clock_control.internal_clock_stable.d ), - - // to internal hardware - .qe (reg2hw.clock_control.internal_clock_stable.qe), - .q (reg2hw.clock_control.internal_clock_stable.q ), - - // to register interface (read) - .qs (clock_control_internal_clock_stable_qs) - ); - - - // F[sd_clock_enable]: 2:2 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_clock_control_sd_clock_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (clock_control_sd_clock_enable_we), - .wd (clock_control_sd_clock_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (reg2hw.clock_control.sd_clock_enable.qe), - .q (reg2hw.clock_control.sd_clock_enable.q ), - - // to register interface (read) - .qs (clock_control_sd_clock_enable_qs) - ); - - - // F[rsvd_3]: 7:3 - // constant-only read - assign clock_control_rsvd_3_qs = 5'h0; - - - // F[sdclk_frequency_select]: 15:8 - prim_subreg #( - .DW (8), - .SWACCESS("RW"), - .RESVAL (8'h0) - ) u_clock_control_sdclk_frequency_select ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (clock_control_sdclk_frequency_select_we), - .wd (clock_control_sdclk_frequency_select_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (reg2hw.clock_control.sdclk_frequency_select.qe), - .q (reg2hw.clock_control.sdclk_frequency_select.q ), - - // to register interface (read) - .qs (clock_control_sdclk_frequency_select_qs) - ); - - - // R[timeout_control]: V(False) - - // F[data_timeout_counter_value]: 19:16 - prim_subreg #( - .DW (4), - .SWACCESS("RW"), - .RESVAL (4'h0) - ) u_timeout_control_data_timeout_counter_value ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (timeout_control_data_timeout_counter_value_we), - .wd (timeout_control_data_timeout_counter_value_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.timeout_control.data_timeout_counter_value.q ), - - // to register interface (read) - .qs (timeout_control_data_timeout_counter_value_qs) - ); - - - // F[rsvd_4]: 23:20 - // constant-only read - assign timeout_control_rsvd_4_qs = 4'h0; - - - // R[software_reset]: V(False) - - // F[software_reset_for_all]: 24:24 - prim_subreg #( - .DW (1), - .SWACCESS("W1S"), - .RESVAL (1'h0) - ) u_software_reset_software_reset_for_all ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (software_reset_software_reset_for_all_we), - .wd (software_reset_software_reset_for_all_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.software_reset.software_reset_for_all.q ), - - // to register interface (read) - .qs (software_reset_software_reset_for_all_qs) - ); - - - // F[software_reset_for_cmd_line]: 25:25 - prim_subreg #( - .DW (1), - .SWACCESS("W1S"), - .RESVAL (1'h0) - ) u_software_reset_software_reset_for_cmd_line ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (software_reset_software_reset_for_cmd_line_we), - .wd (software_reset_software_reset_for_cmd_line_wd), - - // from internal hardware - .de (hw2reg.software_reset.software_reset_for_cmd_line.de), - .d (hw2reg.software_reset.software_reset_for_cmd_line.d ), - - // to internal hardware - .qe (), - .q (reg2hw.software_reset.software_reset_for_cmd_line.q ), - - // to register interface (read) - .qs (software_reset_software_reset_for_cmd_line_qs) - ); - - - // F[software_reset_for_dat_line]: 26:26 - prim_subreg #( - .DW (1), - .SWACCESS("W1S"), - .RESVAL (1'h0) - ) u_software_reset_software_reset_for_dat_line ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (software_reset_software_reset_for_dat_line_we), - .wd (software_reset_software_reset_for_dat_line_wd), - - // from internal hardware - .de (hw2reg.software_reset.software_reset_for_dat_line.de), - .d (hw2reg.software_reset.software_reset_for_dat_line.d ), - - // to internal hardware - .qe (), - .q (reg2hw.software_reset.software_reset_for_dat_line.q ), - - // to register interface (read) - .qs (software_reset_software_reset_for_dat_line_qs) - ); - - - // F[rsvd_4]: 31:28 - // constant-only read - assign software_reset_rsvd_4_qs = 4'h0; - - - // R[normal_interrupt_status]: V(False) - - // F[command_complete]: 0:0 - prim_subreg #( - .DW (1), - .SWACCESS("W1C"), - .RESVAL (1'h0) - ) u_normal_interrupt_status_command_complete ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_status_command_complete_we), - .wd (normal_interrupt_status_command_complete_wd), - - // from internal hardware - .de (hw2reg.normal_interrupt_status.command_complete.de), - .d (hw2reg.normal_interrupt_status.command_complete.d ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_status.command_complete.q ), - - // to register interface (read) - .qs (normal_interrupt_status_command_complete_qs) - ); - - - // F[transfer_complete]: 1:1 - prim_subreg #( - .DW (1), - .SWACCESS("W1C"), - .RESVAL (1'h0) - ) u_normal_interrupt_status_transfer_complete ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_status_transfer_complete_we), - .wd (normal_interrupt_status_transfer_complete_wd), - - // from internal hardware - .de (hw2reg.normal_interrupt_status.transfer_complete.de), - .d (hw2reg.normal_interrupt_status.transfer_complete.d ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_status.transfer_complete.q ), - - // to register interface (read) - .qs (normal_interrupt_status_transfer_complete_qs) - ); - - - // F[block_gap_event]: 2:2 - prim_subreg #( - .DW (1), - .SWACCESS("W1C"), - .RESVAL (1'h0) - ) u_normal_interrupt_status_block_gap_event ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_status_block_gap_event_we), - .wd (normal_interrupt_status_block_gap_event_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (), - - // to register interface (read) - .qs (normal_interrupt_status_block_gap_event_qs) - ); - - - // F[dma_interrupt]: 3:3 - prim_subreg #( - .DW (1), - .SWACCESS("W1C"), - .RESVAL (1'h0) - ) u_normal_interrupt_status_dma_interrupt ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_status_dma_interrupt_we), - .wd (normal_interrupt_status_dma_interrupt_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (), - - // to register interface (read) - .qs (normal_interrupt_status_dma_interrupt_qs) - ); - - - // F[buffer_write_ready]: 4:4 - prim_subreg #( - .DW (1), - .SWACCESS("W1C"), - .RESVAL (1'h0) - ) u_normal_interrupt_status_buffer_write_ready ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_status_buffer_write_ready_we), - .wd (normal_interrupt_status_buffer_write_ready_wd), - - // from internal hardware - .de (hw2reg.normal_interrupt_status.buffer_write_ready.de), - .d (hw2reg.normal_interrupt_status.buffer_write_ready.d ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_status.buffer_write_ready.q ), - - // to register interface (read) - .qs (normal_interrupt_status_buffer_write_ready_qs) - ); - - - // F[buffer_read_ready]: 5:5 - prim_subreg #( - .DW (1), - .SWACCESS("W1C"), - .RESVAL (1'h0) - ) u_normal_interrupt_status_buffer_read_ready ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_status_buffer_read_ready_we), - .wd (normal_interrupt_status_buffer_read_ready_wd), - - // from internal hardware - .de (hw2reg.normal_interrupt_status.buffer_read_ready.de), - .d (hw2reg.normal_interrupt_status.buffer_read_ready.d ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_status.buffer_read_ready.q ), - - // to register interface (read) - .qs (normal_interrupt_status_buffer_read_ready_qs) - ); - - - // F[card_insertion]: 6:6 - prim_subreg #( - .DW (1), - .SWACCESS("W1C"), - .RESVAL (1'h0) - ) u_normal_interrupt_status_card_insertion ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_status_card_insertion_we), - .wd (normal_interrupt_status_card_insertion_wd), - - // from internal hardware - .de (hw2reg.normal_interrupt_status.card_insertion.de), - .d (hw2reg.normal_interrupt_status.card_insertion.d ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_status.card_insertion.q ), - - // to register interface (read) - .qs (normal_interrupt_status_card_insertion_qs) - ); - - - // F[card_removal]: 7:7 - prim_subreg #( - .DW (1), - .SWACCESS("W1C"), - .RESVAL (1'h0) - ) u_normal_interrupt_status_card_removal ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_status_card_removal_we), - .wd (normal_interrupt_status_card_removal_wd), - - // from internal hardware - .de (hw2reg.normal_interrupt_status.card_removal.de), - .d (hw2reg.normal_interrupt_status.card_removal.d ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_status.card_removal.q ), - - // to register interface (read) - .qs (normal_interrupt_status_card_removal_qs) - ); - - - // F[card_interrupt]: 8:8 - // constant-only read - assign normal_interrupt_status_card_interrupt_qs = 1'h0; - - - // F[rsvd_9]: 14:9 - // constant-only read - assign normal_interrupt_status_rsvd_9_qs = 6'h0; - - - // F[error_interrupt]: 15:15 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h0) - ) u_normal_interrupt_status_error_interrupt ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.normal_interrupt_status.error_interrupt.de), - .d (hw2reg.normal_interrupt_status.error_interrupt.d ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_status.error_interrupt.q ), - - // to register interface (read) - .qs (normal_interrupt_status_error_interrupt_qs) - ); - - - // R[error_interrupt_status]: V(False) - - // F[command_timeout_error]: 16:16 - prim_subreg #( - .DW (1), - .SWACCESS("W1C"), - .RESVAL (1'h0) - ) u_error_interrupt_status_command_timeout_error ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_status_command_timeout_error_we), - .wd (error_interrupt_status_command_timeout_error_wd), - - // from internal hardware - .de (hw2reg.error_interrupt_status.command_timeout_error.de), - .d (hw2reg.error_interrupt_status.command_timeout_error.d ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_status.command_timeout_error.q ), - - // to register interface (read) - .qs (error_interrupt_status_command_timeout_error_qs) - ); - - - // F[command_crc_error]: 17:17 - prim_subreg #( - .DW (1), - .SWACCESS("W1C"), - .RESVAL (1'h0) - ) u_error_interrupt_status_command_crc_error ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_status_command_crc_error_we), - .wd (error_interrupt_status_command_crc_error_wd), - - // from internal hardware - .de (hw2reg.error_interrupt_status.command_crc_error.de), - .d (hw2reg.error_interrupt_status.command_crc_error.d ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_status.command_crc_error.q ), - - // to register interface (read) - .qs (error_interrupt_status_command_crc_error_qs) - ); - - - // F[command_end_bit_error]: 18:18 - prim_subreg #( - .DW (1), - .SWACCESS("W1C"), - .RESVAL (1'h0) - ) u_error_interrupt_status_command_end_bit_error ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_status_command_end_bit_error_we), - .wd (error_interrupt_status_command_end_bit_error_wd), - - // from internal hardware - .de (hw2reg.error_interrupt_status.command_end_bit_error.de), - .d (hw2reg.error_interrupt_status.command_end_bit_error.d ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_status.command_end_bit_error.q ), - - // to register interface (read) - .qs (error_interrupt_status_command_end_bit_error_qs) - ); - - - // F[command_index_error]: 19:19 - prim_subreg #( - .DW (1), - .SWACCESS("W1C"), - .RESVAL (1'h0) - ) u_error_interrupt_status_command_index_error ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_status_command_index_error_we), - .wd (error_interrupt_status_command_index_error_wd), - - // from internal hardware - .de (hw2reg.error_interrupt_status.command_index_error.de), - .d (hw2reg.error_interrupt_status.command_index_error.d ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_status.command_index_error.q ), - - // to register interface (read) - .qs (error_interrupt_status_command_index_error_qs) - ); - - - // F[data_timeout_error]: 20:20 - prim_subreg #( - .DW (1), - .SWACCESS("W1C"), - .RESVAL (1'h0) - ) u_error_interrupt_status_data_timeout_error ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_status_data_timeout_error_we), - .wd (error_interrupt_status_data_timeout_error_wd), - - // from internal hardware - .de (hw2reg.error_interrupt_status.data_timeout_error.de), - .d (hw2reg.error_interrupt_status.data_timeout_error.d ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_status.data_timeout_error.q ), - - // to register interface (read) - .qs (error_interrupt_status_data_timeout_error_qs) - ); - - - // F[data_crc_error]: 21:21 - prim_subreg #( - .DW (1), - .SWACCESS("W1C"), - .RESVAL (1'h0) - ) u_error_interrupt_status_data_crc_error ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_status_data_crc_error_we), - .wd (error_interrupt_status_data_crc_error_wd), - - // from internal hardware - .de (hw2reg.error_interrupt_status.data_crc_error.de), - .d (hw2reg.error_interrupt_status.data_crc_error.d ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_status.data_crc_error.q ), - - // to register interface (read) - .qs (error_interrupt_status_data_crc_error_qs) - ); - - - // F[data_end_bit_error]: 22:22 - prim_subreg #( - .DW (1), - .SWACCESS("W1C"), - .RESVAL (1'h0) - ) u_error_interrupt_status_data_end_bit_error ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_status_data_end_bit_error_we), - .wd (error_interrupt_status_data_end_bit_error_wd), - - // from internal hardware - .de (hw2reg.error_interrupt_status.data_end_bit_error.de), - .d (hw2reg.error_interrupt_status.data_end_bit_error.d ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_status.data_end_bit_error.q ), - - // to register interface (read) - .qs (error_interrupt_status_data_end_bit_error_qs) - ); - - - // F[current_limit_error]: 23:23 - prim_subreg #( - .DW (1), - .SWACCESS("W1C"), - .RESVAL (1'h0) - ) u_error_interrupt_status_current_limit_error ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_status_current_limit_error_we), - .wd (error_interrupt_status_current_limit_error_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (), - - // to register interface (read) - .qs (error_interrupt_status_current_limit_error_qs) - ); - - - // F[auto_cmd12_error]: 24:24 - prim_subreg #( - .DW (1), - .SWACCESS("W1C"), - .RESVAL (1'h0) - ) u_error_interrupt_status_auto_cmd12_error ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_status_auto_cmd12_error_we), - .wd (error_interrupt_status_auto_cmd12_error_wd), - - // from internal hardware - .de (hw2reg.error_interrupt_status.auto_cmd12_error.de), - .d (hw2reg.error_interrupt_status.auto_cmd12_error.d ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_status.auto_cmd12_error.q ), - - // to register interface (read) - .qs (error_interrupt_status_auto_cmd12_error_qs) - ); - - - // F[rsvd_9]: 27:25 - // constant-only read - assign error_interrupt_status_rsvd_9_qs = 3'h0; - - - // F[vendor_specific_error]: 31:28 - prim_subreg #( - .DW (4), - .SWACCESS("W1C"), - .RESVAL (4'h0) - ) u_error_interrupt_status_vendor_specific_error ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_status_vendor_specific_error_we), - .wd (error_interrupt_status_vendor_specific_error_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (), - - // to register interface (read) - .qs (error_interrupt_status_vendor_specific_error_qs) - ); - - - // R[normal_interrupt_status_enable]: V(False) - - // F[command_complete_status_enable]: 0:0 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_normal_interrupt_status_enable_command_complete_status_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_status_enable_command_complete_status_enable_we), - .wd (normal_interrupt_status_enable_command_complete_status_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_status_enable.command_complete_status_enable.q ), - - // to register interface (read) - .qs (normal_interrupt_status_enable_command_complete_status_enable_qs) - ); - - - // F[transfer_complete_status_enable]: 1:1 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_normal_interrupt_status_enable_transfer_complete_status_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_status_enable_transfer_complete_status_enable_we), - .wd (normal_interrupt_status_enable_transfer_complete_status_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_status_enable.transfer_complete_status_enable.q ), - - // to register interface (read) - .qs (normal_interrupt_status_enable_transfer_complete_status_enable_qs) - ); - - - // F[block_gap_event_status_enable]: 2:2 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_normal_interrupt_status_enable_block_gap_event_status_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_status_enable_block_gap_event_status_enable_we), - .wd (normal_interrupt_status_enable_block_gap_event_status_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_status_enable.block_gap_event_status_enable.q ), - - // to register interface (read) - .qs (normal_interrupt_status_enable_block_gap_event_status_enable_qs) - ); - - - // F[dma_interrupt_status_enable]: 3:3 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_normal_interrupt_status_enable_dma_interrupt_status_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_status_enable_dma_interrupt_status_enable_we), - .wd (normal_interrupt_status_enable_dma_interrupt_status_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_status_enable.dma_interrupt_status_enable.q ), - - // to register interface (read) - .qs (normal_interrupt_status_enable_dma_interrupt_status_enable_qs) - ); - - - // F[buffer_write_ready_status_enable]: 4:4 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_normal_interrupt_status_enable_buffer_write_ready_status_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_status_enable_buffer_write_ready_status_enable_we), - .wd (normal_interrupt_status_enable_buffer_write_ready_status_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_status_enable.buffer_write_ready_status_enable.q ), - - // to register interface (read) - .qs (normal_interrupt_status_enable_buffer_write_ready_status_enable_qs) - ); - - - // F[buffer_read_ready_status_enable]: 5:5 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_normal_interrupt_status_enable_buffer_read_ready_status_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_status_enable_buffer_read_ready_status_enable_we), - .wd (normal_interrupt_status_enable_buffer_read_ready_status_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_status_enable.buffer_read_ready_status_enable.q ), - - // to register interface (read) - .qs (normal_interrupt_status_enable_buffer_read_ready_status_enable_qs) - ); - - - // F[card_insertion_status_enable]: 6:6 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_normal_interrupt_status_enable_card_insertion_status_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_status_enable_card_insertion_status_enable_we), - .wd (normal_interrupt_status_enable_card_insertion_status_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_status_enable.card_insertion_status_enable.q ), - - // to register interface (read) - .qs (normal_interrupt_status_enable_card_insertion_status_enable_qs) - ); - - - // F[card_removal_status_enable]: 7:7 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_normal_interrupt_status_enable_card_removal_status_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_status_enable_card_removal_status_enable_we), - .wd (normal_interrupt_status_enable_card_removal_status_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_status_enable.card_removal_status_enable.q ), - - // to register interface (read) - .qs (normal_interrupt_status_enable_card_removal_status_enable_qs) - ); - - - // F[card_interrupt_status_enable]: 8:8 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_normal_interrupt_status_enable_card_interrupt_status_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_status_enable_card_interrupt_status_enable_we), - .wd (normal_interrupt_status_enable_card_interrupt_status_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_status_enable.card_interrupt_status_enable.q ), - - // to register interface (read) - .qs (normal_interrupt_status_enable_card_interrupt_status_enable_qs) - ); - - - // F[rsvd_9]: 14:9 - // constant-only read - assign normal_interrupt_status_enable_rsvd_9_qs = 6'h0; - - - // F[fixed_to_0]: 15:15 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h0) - ) u_normal_interrupt_status_enable_fixed_to_0 ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_status_enable.fixed_to_0.q ), - - // to register interface (read) - .qs (normal_interrupt_status_enable_fixed_to_0_qs) - ); - - - // R[error_interrupt_status_enable]: V(False) - - // F[command_timeout_error_status_enable]: 16:16 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_error_interrupt_status_enable_command_timeout_error_status_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_status_enable_command_timeout_error_status_enable_we), - .wd (error_interrupt_status_enable_command_timeout_error_status_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_status_enable.command_timeout_error_status_enable.q ), - - // to register interface (read) - .qs (error_interrupt_status_enable_command_timeout_error_status_enable_qs) - ); - - - // F[command_crc_error_status_enable]: 17:17 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_error_interrupt_status_enable_command_crc_error_status_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_status_enable_command_crc_error_status_enable_we), - .wd (error_interrupt_status_enable_command_crc_error_status_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_status_enable.command_crc_error_status_enable.q ), - - // to register interface (read) - .qs (error_interrupt_status_enable_command_crc_error_status_enable_qs) - ); - - - // F[command_end_bit_error_status_enable]: 18:18 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_error_interrupt_status_enable_command_end_bit_error_status_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_status_enable_command_end_bit_error_status_enable_we), - .wd (error_interrupt_status_enable_command_end_bit_error_status_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_status_enable.command_end_bit_error_status_enable.q ), - - // to register interface (read) - .qs (error_interrupt_status_enable_command_end_bit_error_status_enable_qs) - ); - - - // F[command_index_error_status_enable]: 19:19 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_error_interrupt_status_enable_command_index_error_status_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_status_enable_command_index_error_status_enable_we), - .wd (error_interrupt_status_enable_command_index_error_status_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_status_enable.command_index_error_status_enable.q ), - - // to register interface (read) - .qs (error_interrupt_status_enable_command_index_error_status_enable_qs) - ); - - - // F[data_timeout_error_status_enable]: 20:20 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_error_interrupt_status_enable_data_timeout_error_status_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_status_enable_data_timeout_error_status_enable_we), - .wd (error_interrupt_status_enable_data_timeout_error_status_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_status_enable.data_timeout_error_status_enable.q ), - - // to register interface (read) - .qs (error_interrupt_status_enable_data_timeout_error_status_enable_qs) - ); - - - // F[data_crc_error_status_enable]: 21:21 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_error_interrupt_status_enable_data_crc_error_status_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_status_enable_data_crc_error_status_enable_we), - .wd (error_interrupt_status_enable_data_crc_error_status_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_status_enable.data_crc_error_status_enable.q ), - - // to register interface (read) - .qs (error_interrupt_status_enable_data_crc_error_status_enable_qs) - ); - - - // F[data_end_bit_error_status_enable]: 22:22 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_error_interrupt_status_enable_data_end_bit_error_status_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_status_enable_data_end_bit_error_status_enable_we), - .wd (error_interrupt_status_enable_data_end_bit_error_status_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_status_enable.data_end_bit_error_status_enable.q ), - - // to register interface (read) - .qs (error_interrupt_status_enable_data_end_bit_error_status_enable_qs) - ); - - - // F[current_limit_error_status_enable]: 23:23 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_error_interrupt_status_enable_current_limit_error_status_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_status_enable_current_limit_error_status_enable_we), - .wd (error_interrupt_status_enable_current_limit_error_status_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_status_enable.current_limit_error_status_enable.q ), - - // to register interface (read) - .qs (error_interrupt_status_enable_current_limit_error_status_enable_qs) - ); - - - // F[auto_cmd12_error_status_enable]: 24:24 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_error_interrupt_status_enable_auto_cmd12_error_status_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_status_enable_auto_cmd12_error_status_enable_we), - .wd (error_interrupt_status_enable_auto_cmd12_error_status_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_status_enable.auto_cmd12_error_status_enable.q ), - - // to register interface (read) - .qs (error_interrupt_status_enable_auto_cmd12_error_status_enable_qs) - ); - - - // F[rsvd_9]: 27:25 - // constant-only read - assign error_interrupt_status_enable_rsvd_9_qs = 3'h0; - - - // F[vendor_specific_error_status_enable]: 31:28 - prim_subreg #( - .DW (4), - .SWACCESS("RW"), - .RESVAL (4'h0) - ) u_error_interrupt_status_enable_vendor_specific_error_status_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_status_enable_vendor_specific_error_status_enable_we), - .wd (error_interrupt_status_enable_vendor_specific_error_status_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_status_enable.vendor_specific_error_status_enable.q ), - - // to register interface (read) - .qs (error_interrupt_status_enable_vendor_specific_error_status_enable_qs) - ); - - - // R[normal_interrupt_signal_enable]: V(False) - - // F[command_complete_signal_enable]: 0:0 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_normal_interrupt_signal_enable_command_complete_signal_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_signal_enable_command_complete_signal_enable_we), - .wd (normal_interrupt_signal_enable_command_complete_signal_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_signal_enable.command_complete_signal_enable.q ), - - // to register interface (read) - .qs (normal_interrupt_signal_enable_command_complete_signal_enable_qs) - ); - - - // F[transfer_complete_signal_enable]: 1:1 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_normal_interrupt_signal_enable_transfer_complete_signal_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_signal_enable_transfer_complete_signal_enable_we), - .wd (normal_interrupt_signal_enable_transfer_complete_signal_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_signal_enable.transfer_complete_signal_enable.q ), - - // to register interface (read) - .qs (normal_interrupt_signal_enable_transfer_complete_signal_enable_qs) - ); - - - // F[block_gap_event_signal_enable]: 2:2 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_normal_interrupt_signal_enable_block_gap_event_signal_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_signal_enable_block_gap_event_signal_enable_we), - .wd (normal_interrupt_signal_enable_block_gap_event_signal_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_signal_enable.block_gap_event_signal_enable.q ), - - // to register interface (read) - .qs (normal_interrupt_signal_enable_block_gap_event_signal_enable_qs) - ); - - - // F[dma_interrupt_signal_enable]: 3:3 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_normal_interrupt_signal_enable_dma_interrupt_signal_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_signal_enable_dma_interrupt_signal_enable_we), - .wd (normal_interrupt_signal_enable_dma_interrupt_signal_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_signal_enable.dma_interrupt_signal_enable.q ), - - // to register interface (read) - .qs (normal_interrupt_signal_enable_dma_interrupt_signal_enable_qs) - ); - - - // F[buffer_write_ready_signal_enable]: 4:4 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_normal_interrupt_signal_enable_buffer_write_ready_signal_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_signal_enable_buffer_write_ready_signal_enable_we), - .wd (normal_interrupt_signal_enable_buffer_write_ready_signal_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_signal_enable.buffer_write_ready_signal_enable.q ), - - // to register interface (read) - .qs (normal_interrupt_signal_enable_buffer_write_ready_signal_enable_qs) - ); - - - // F[buffer_read_ready_signal_enable]: 5:5 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_normal_interrupt_signal_enable_buffer_read_ready_signal_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_signal_enable_buffer_read_ready_signal_enable_we), - .wd (normal_interrupt_signal_enable_buffer_read_ready_signal_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_signal_enable.buffer_read_ready_signal_enable.q ), - - // to register interface (read) - .qs (normal_interrupt_signal_enable_buffer_read_ready_signal_enable_qs) - ); - - - // F[card_insertion_signal_enable]: 6:6 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_normal_interrupt_signal_enable_card_insertion_signal_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_signal_enable_card_insertion_signal_enable_we), - .wd (normal_interrupt_signal_enable_card_insertion_signal_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_signal_enable.card_insertion_signal_enable.q ), - - // to register interface (read) - .qs (normal_interrupt_signal_enable_card_insertion_signal_enable_qs) - ); - - - // F[card_removal_signal_enable]: 7:7 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_normal_interrupt_signal_enable_card_removal_signal_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_signal_enable_card_removal_signal_enable_we), - .wd (normal_interrupt_signal_enable_card_removal_signal_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_signal_enable.card_removal_signal_enable.q ), - - // to register interface (read) - .qs (normal_interrupt_signal_enable_card_removal_signal_enable_qs) - ); - - - // F[card_interrupt_signal_enable]: 8:8 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_normal_interrupt_signal_enable_card_interrupt_signal_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (normal_interrupt_signal_enable_card_interrupt_signal_enable_we), - .wd (normal_interrupt_signal_enable_card_interrupt_signal_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.normal_interrupt_signal_enable.card_interrupt_signal_enable.q ), - - // to register interface (read) - .qs (normal_interrupt_signal_enable_card_interrupt_signal_enable_qs) - ); - - - // F[rsvd_9]: 14:9 - // constant-only read - assign normal_interrupt_signal_enable_rsvd_9_qs = 6'h0; - - - // F[fixed_to_0]: 15:15 - // constant-only read - assign normal_interrupt_signal_enable_fixed_to_0_qs = 1'h0; - - - // R[error_interrupt_signal_enable]: V(False) - - // F[command_timeout_error_signal_enable]: 16:16 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_error_interrupt_signal_enable_command_timeout_error_signal_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_signal_enable_command_timeout_error_signal_enable_we), - .wd (error_interrupt_signal_enable_command_timeout_error_signal_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_signal_enable.command_timeout_error_signal_enable.q ), - - // to register interface (read) - .qs (error_interrupt_signal_enable_command_timeout_error_signal_enable_qs) - ); - - - // F[command_crc_error_signal_enable]: 17:17 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_error_interrupt_signal_enable_command_crc_error_signal_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_signal_enable_command_crc_error_signal_enable_we), - .wd (error_interrupt_signal_enable_command_crc_error_signal_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_signal_enable.command_crc_error_signal_enable.q ), - - // to register interface (read) - .qs (error_interrupt_signal_enable_command_crc_error_signal_enable_qs) - ); - - - // F[command_end_bit_error_signal_enable]: 18:18 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_error_interrupt_signal_enable_command_end_bit_error_signal_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_signal_enable_command_end_bit_error_signal_enable_we), - .wd (error_interrupt_signal_enable_command_end_bit_error_signal_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_signal_enable.command_end_bit_error_signal_enable.q ), - - // to register interface (read) - .qs (error_interrupt_signal_enable_command_end_bit_error_signal_enable_qs) - ); - - - // F[command_index_error_signal_enable]: 19:19 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_error_interrupt_signal_enable_command_index_error_signal_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_signal_enable_command_index_error_signal_enable_we), - .wd (error_interrupt_signal_enable_command_index_error_signal_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_signal_enable.command_index_error_signal_enable.q ), - - // to register interface (read) - .qs (error_interrupt_signal_enable_command_index_error_signal_enable_qs) - ); - - - // F[data_timeout_error_signal_enable]: 20:20 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_error_interrupt_signal_enable_data_timeout_error_signal_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_signal_enable_data_timeout_error_signal_enable_we), - .wd (error_interrupt_signal_enable_data_timeout_error_signal_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_signal_enable.data_timeout_error_signal_enable.q ), - - // to register interface (read) - .qs (error_interrupt_signal_enable_data_timeout_error_signal_enable_qs) - ); - - - // F[data_crc_error_signal_enable]: 21:21 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_error_interrupt_signal_enable_data_crc_error_signal_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_signal_enable_data_crc_error_signal_enable_we), - .wd (error_interrupt_signal_enable_data_crc_error_signal_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_signal_enable.data_crc_error_signal_enable.q ), - - // to register interface (read) - .qs (error_interrupt_signal_enable_data_crc_error_signal_enable_qs) - ); - - - // F[data_end_bit_error_signal_enable]: 22:22 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_error_interrupt_signal_enable_data_end_bit_error_signal_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_signal_enable_data_end_bit_error_signal_enable_we), - .wd (error_interrupt_signal_enable_data_end_bit_error_signal_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_signal_enable.data_end_bit_error_signal_enable.q ), - - // to register interface (read) - .qs (error_interrupt_signal_enable_data_end_bit_error_signal_enable_qs) - ); - - - // F[current_limit_error_signal_enable]: 23:23 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_error_interrupt_signal_enable_current_limit_error_signal_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_signal_enable_current_limit_error_signal_enable_we), - .wd (error_interrupt_signal_enable_current_limit_error_signal_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_signal_enable.current_limit_error_signal_enable.q ), - - // to register interface (read) - .qs (error_interrupt_signal_enable_current_limit_error_signal_enable_qs) - ); - - - // F[auto_cmd12_error_signal_enable]: 24:24 - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_error_interrupt_signal_enable_auto_cmd12_error_signal_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_signal_enable_auto_cmd12_error_signal_enable_we), - .wd (error_interrupt_signal_enable_auto_cmd12_error_signal_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_signal_enable.auto_cmd12_error_signal_enable.q ), - - // to register interface (read) - .qs (error_interrupt_signal_enable_auto_cmd12_error_signal_enable_qs) - ); - - - // F[rsvd_9]: 27:25 - // constant-only read - assign error_interrupt_signal_enable_rsvd_9_qs = 3'h0; - - - // F[vendor_specific_error_signal_enable]: 31:28 - prim_subreg #( - .DW (4), - .SWACCESS("RW"), - .RESVAL (4'h0) - ) u_error_interrupt_signal_enable_vendor_specific_error_signal_enable ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - // from register interface - .we (error_interrupt_signal_enable_vendor_specific_error_signal_enable_we), - .wd (error_interrupt_signal_enable_vendor_specific_error_signal_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0 ), - - // to internal hardware - .qe (), - .q (reg2hw.error_interrupt_signal_enable.vendor_specific_error_signal_enable.q ), - - // to register interface (read) - .qs (error_interrupt_signal_enable_vendor_specific_error_signal_enable_qs) - ); - - - // R[auto_cmd12_error_status]: V(False) - - // F[auto_cmd12_not_executed]: 0:0 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h0) - ) u_auto_cmd12_error_status_auto_cmd12_not_executed ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.auto_cmd12_error_status.auto_cmd12_not_executed.de), - .d (hw2reg.auto_cmd12_error_status.auto_cmd12_not_executed.d ), - - // to internal hardware - .qe (), - .q (reg2hw.auto_cmd12_error_status.auto_cmd12_not_executed.q ), - - // to register interface (read) - .qs (auto_cmd12_error_status_auto_cmd12_not_executed_qs) - ); - - - // F[auto_cmd12_timeout_error]: 1:1 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h0) - ) u_auto_cmd12_error_status_auto_cmd12_timeout_error ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.auto_cmd12_error_status.auto_cmd12_timeout_error.de), - .d (hw2reg.auto_cmd12_error_status.auto_cmd12_timeout_error.d ), - - // to internal hardware - .qe (), - .q (reg2hw.auto_cmd12_error_status.auto_cmd12_timeout_error.q ), - - // to register interface (read) - .qs (auto_cmd12_error_status_auto_cmd12_timeout_error_qs) - ); - - - // F[auto_cmd12_crc_error]: 2:2 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h0) - ) u_auto_cmd12_error_status_auto_cmd12_crc_error ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.auto_cmd12_error_status.auto_cmd12_crc_error.de), - .d (hw2reg.auto_cmd12_error_status.auto_cmd12_crc_error.d ), - - // to internal hardware - .qe (), - .q (reg2hw.auto_cmd12_error_status.auto_cmd12_crc_error.q ), - - // to register interface (read) - .qs (auto_cmd12_error_status_auto_cmd12_crc_error_qs) - ); - - - // F[auto_cmd12_end_bit_error]: 3:3 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h0) - ) u_auto_cmd12_error_status_auto_cmd12_end_bit_error ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.auto_cmd12_error_status.auto_cmd12_end_bit_error.de), - .d (hw2reg.auto_cmd12_error_status.auto_cmd12_end_bit_error.d ), - - // to internal hardware - .qe (), - .q (reg2hw.auto_cmd12_error_status.auto_cmd12_end_bit_error.q ), - - // to register interface (read) - .qs (auto_cmd12_error_status_auto_cmd12_end_bit_error_qs) - ); - - - // F[auto_cmd12_index_error]: 4:4 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h0) - ) u_auto_cmd12_error_status_auto_cmd12_index_error ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.auto_cmd12_error_status.auto_cmd12_index_error.de), - .d (hw2reg.auto_cmd12_error_status.auto_cmd12_index_error.d ), - - // to internal hardware - .qe (), - .q (reg2hw.auto_cmd12_error_status.auto_cmd12_index_error.q ), - - // to register interface (read) - .qs (auto_cmd12_error_status_auto_cmd12_index_error_qs) - ); - - - // F[rsvd_5]: 6:5 - // constant-only read - assign auto_cmd12_error_status_rsvd_5_qs = 2'h0; - - - // F[command_not_issued_by_auto_cmd12_error]: 7:7 - prim_subreg #( - .DW (1), - .SWACCESS("RO"), - .RESVAL (1'h0) - ) u_auto_cmd12_error_status_command_not_issued_by_auto_cmd12_error ( - .clk_i (clk_i ), - .rst_ni (rst_ni ), - - .we (1'b0), - .wd ('0 ), - - // from internal hardware - .de (hw2reg.auto_cmd12_error_status.command_not_issued_by_auto_cmd12_error.de), - .d (hw2reg.auto_cmd12_error_status.command_not_issued_by_auto_cmd12_error.d ), - - // to internal hardware - .qe (), - .q (reg2hw.auto_cmd12_error_status.command_not_issued_by_auto_cmd12_error.q ), - - // to register interface (read) - .qs (auto_cmd12_error_status_command_not_issued_by_auto_cmd12_error_qs) - ); - - - // F[rsvd_8]: 15:8 - // constant-only read - assign auto_cmd12_error_status_rsvd_8_qs = 8'h0; - - - // R[capabilities]: V(False) - - // F[timeout_clock_frequency]: 5:0 - // constant-only read - assign capabilities_timeout_clock_frequency_qs = 6'h32; - - - // F[rsvd_6]: 6:6 - // constant-only read - assign capabilities_rsvd_6_qs = 1'h0; - - - // F[timeout_clock_unit]: 7:7 - // constant-only read - assign capabilities_timeout_clock_unit_qs = 1'h1; - - - // F[base_clock_frequency_for_sd_clock]: 13:8 - // constant-only read - assign capabilities_base_clock_frequency_for_sd_clock_qs = 6'h32; - - - // F[rsvd_14]: 15:14 - // constant-only read - assign capabilities_rsvd_14_qs = 2'h0; - - - // F[max_block_length]: 17:16 - // constant-only read - assign capabilities_max_block_length_qs = 2'h0; - - - // F[rsvd_18]: 20:18 - // constant-only read - assign capabilities_rsvd_18_qs = 3'h0; - - - // F[high_speed_support]: 21:21 - // constant-only read - assign capabilities_high_speed_support_qs = 1'h0; - - - // F[dma_support]: 22:22 - // constant-only read - assign capabilities_dma_support_qs = 1'h0; - - - // F[suspend_resume_support]: 23:23 - // constant-only read - assign capabilities_suspend_resume_support_qs = 1'h0; - - - // F[voltage_support_3_3v]: 24:24 - // constant-only read - assign capabilities_voltage_support_3_3v_qs = 1'h1; - - - // F[voltage_support_3_0v]: 25:25 - // constant-only read - assign capabilities_voltage_support_3_0v_qs = 1'h0; - - - // F[voltage_support_1_8v]: 26:26 - // constant-only read - assign capabilities_voltage_support_1_8v_qs = 1'h0; - - - // F[rsvd_27]: 31:27 - // constant-only read - assign capabilities_rsvd_27_qs = 5'h0; - - - // R[capabilities_reserved]: V(False) - - // constant-only read - assign capabilities_reserved_qs = 32'h0; - - - // R[maximum_current_capabilities]: V(False) - - // F[maximum_current_for_3_3v]: 7:0 - // constant-only read - assign maximum_current_capabilities_maximum_current_for_3_3v_qs = 8'h0; - - - // F[maximum_current_for_3_0v]: 15:8 - // constant-only read - assign maximum_current_capabilities_maximum_current_for_3_0v_qs = 8'h0; - - - // F[maximum_current_for_1_8v]: 23:16 - // constant-only read - assign maximum_current_capabilities_maximum_current_for_1_8v_qs = 8'h0; - - - // F[rsvd_24]: 31:24 - // constant-only read - assign maximum_current_capabilities_rsvd_24_qs = 8'h0; - - - // R[maximum_current_capabilities_reserved]: V(False) - - // constant-only read - assign maximum_current_capabilities_reserved_qs = 32'h0; - - - // R[slot_interrupt_status]: V(True) - - // F[interrupt_signal_for_each_slot]: 7:0 - prim_subreg_ext #( - .DW (8) - ) u_slot_interrupt_status_interrupt_signal_for_each_slot ( - .re (slot_interrupt_status_interrupt_signal_for_each_slot_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.slot_interrupt_status.interrupt_signal_for_each_slot.d), - .qre (), - .qe (), - .q (), - .qs (slot_interrupt_status_interrupt_signal_for_each_slot_qs) - ); - - - // F[rsvd_8]: 15:8 - prim_subreg_ext #( - .DW (8) - ) u_slot_interrupt_status_rsvd_8 ( - .re (slot_interrupt_status_rsvd_8_re), - .we (1'b0), - .wd ('0), - .d ('0), - .qre (), - .qe (), - .q (), - .qs (slot_interrupt_status_rsvd_8_qs) - ); - - - // R[host_controller_version]: V(False) - - // F[specification_version_number]: 23:16 - // constant-only read - assign host_controller_version_specification_version_number_qs = 8'h0; - - - // F[vendor_version_number]: 31:24 - // constant-only read - assign host_controller_version_vendor_version_number_qs = 8'h0; - + output sdhci_reg_pkg::sdhci_reg2hw_t reg2hw, + input sdhci_reg_pkg::sdhci_hw2reg_t hw2reg, + input logic clear_i, + input logic buffer_data_port_read_ready_i, + input logic buffer_data_port_write_ready_i, + input devmode_i +); + import sdhci_reg_pkg::*; + + localparam int DW = 32; + localparam int DBW = DW / 8; + + localparam logic [DW-1:0] Capabilities = 32'h0100_32b2; + localparam logic [15:0] BufferDataPortChunkBytes = + AllowNoncompliantBufferSizes ? 16'(BufferNumWords * 4) : 16'd512; + localparam logic [DW-1:0] VendorCapabilities = { + AllowNoncompliantBufferSizes, 15'h0, BufferDataPortChunkBytes}; + + sdhci_reg2hw_t reg2hw_q, reg2hw_d; + sdhci_reg2hw_t reg2hw_o; + + logic [BlockAw-1:0] reg_addr; + logic [DW-1:0] reg_wdata; + logic [DBW-1:0] reg_be; + logic reg_we; + logic reg_re; + logic reg_ready; + logic accepted; + logic addrmiss; + logic wr_err; + + function automatic logic boundary_err(logic [DBW-1:0] be, logic [2:0] disallowed); + boundary_err = |((be ^ (be >> 1)) & disallowed); + endfunction + + function automatic logic w1c_next( + logic q, + logic d, + logic de, + logic write_clear, + logic wd + ); + w1c_next = de ? d : q; + if (write_clear && wd) begin + w1c_next = 1'b0; + end + endfunction + + function automatic logic w1s_next( + logic q, + logic d, + logic de, + logic write_set, + logic wd + ); + w1s_next = de ? d : q; + if (write_set && wd) begin + w1s_next = 1'b1; + end + endfunction + + assign reg_addr = {reg_req_i.addr[BlockAw-1:2], 2'b00}; + assign reg_wdata = reg_req_i.wdata; + assign reg_be = reg_req_i.wstrb; + assign reg_we = reg_req_i.valid & reg_req_i.write; + assign reg_re = reg_req_i.valid & ~reg_req_i.write; - logic [31:0] addr_hit; always_comb begin - addr_hit = '0; - addr_hit[ 0] = reg_addr == SDHCI_SYSTEM_ADDRESS_OFFSET; - addr_hit[ 1] = reg_addr == SDHCI_BLOCK_SIZE_OFFSET; - addr_hit[ 2] = reg_addr == SDHCI_BLOCK_COUNT_OFFSET; - addr_hit[ 3] = reg_addr == SDHCI_ARGUMENT_OFFSET; - addr_hit[ 4] = reg_addr == SDHCI_TRANSFER_MODE_OFFSET; - addr_hit[ 5] = reg_addr == SDHCI_COMMAND_OFFSET; - addr_hit[ 6] = reg_addr == SDHCI_RESPONSE0_OFFSET; - addr_hit[ 7] = reg_addr == SDHCI_RESPONSE1_OFFSET; - addr_hit[ 8] = reg_addr == SDHCI_RESPONSE2_OFFSET; - addr_hit[ 9] = reg_addr == SDHCI_RESPONSE3_OFFSET; - addr_hit[10] = reg_addr == SDHCI_BUFFER_DATA_PORT_OFFSET; - addr_hit[11] = reg_addr == SDHCI_PRESENT_STATE_OFFSET; - addr_hit[12] = reg_addr == SDHCI_HOST_CONTROL_OFFSET; - addr_hit[13] = reg_addr == SDHCI_POWER_CONTROL_OFFSET; - addr_hit[14] = reg_addr == SDHCI_BLOCK_GAP_CONTROL_OFFSET; - addr_hit[15] = reg_addr == SDHCI_WAKEUP_CONTROL_OFFSET; - addr_hit[16] = reg_addr == SDHCI_CLOCK_CONTROL_OFFSET; - addr_hit[17] = reg_addr == SDHCI_TIMEOUT_CONTROL_OFFSET; - addr_hit[18] = reg_addr == SDHCI_SOFTWARE_RESET_OFFSET; - addr_hit[19] = reg_addr == SDHCI_NORMAL_INTERRUPT_STATUS_OFFSET; - addr_hit[20] = reg_addr == SDHCI_ERROR_INTERRUPT_STATUS_OFFSET; - addr_hit[21] = reg_addr == SDHCI_NORMAL_INTERRUPT_STATUS_ENABLE_OFFSET; - addr_hit[22] = reg_addr == SDHCI_ERROR_INTERRUPT_STATUS_ENABLE_OFFSET; - addr_hit[23] = reg_addr == SDHCI_NORMAL_INTERRUPT_SIGNAL_ENABLE_OFFSET; - addr_hit[24] = reg_addr == SDHCI_ERROR_INTERRUPT_SIGNAL_ENABLE_OFFSET; - addr_hit[25] = reg_addr == SDHCI_AUTO_CMD12_ERROR_STATUS_OFFSET; - addr_hit[26] = reg_addr == SDHCI_CAPABILITIES_OFFSET; - addr_hit[27] = reg_addr == SDHCI_CAPABILITIES_RESERVED_OFFSET; - addr_hit[28] = reg_addr == SDHCI_MAXIMUM_CURRENT_CAPABILITIES_OFFSET; - addr_hit[29] = reg_addr == SDHCI_MAXIMUM_CURRENT_CAPABILITIES_RESERVED_OFFSET; - addr_hit[30] = reg_addr == SDHCI_SLOT_INTERRUPT_STATUS_OFFSET; - addr_hit[31] = reg_addr == SDHCI_HOST_CONTROLLER_VERSION_OFFSET; + addrmiss = 1'b0; + + unique case (reg_addr) + SDHCI_SYSTEM_ADDRESS_OFFSET, + SDHCI_BLOCK_SIZE_OFFSET, + SDHCI_ARGUMENT_OFFSET, + SDHCI_TRANSFER_MODE_OFFSET, + SDHCI_RESPONSE0_OFFSET, + SDHCI_RESPONSE1_OFFSET, + SDHCI_RESPONSE2_OFFSET, + SDHCI_RESPONSE3_OFFSET, + SDHCI_BUFFER_DATA_PORT_OFFSET, + SDHCI_PRESENT_STATE_OFFSET, + SDHCI_HOST_CONTROL_OFFSET, + SDHCI_CLOCK_CONTROL_OFFSET, + SDHCI_NORMAL_INTERRUPT_STATUS_OFFSET, + SDHCI_NORMAL_INTERRUPT_STATUS_ENABLE_OFFSET, + SDHCI_NORMAL_INTERRUPT_SIGNAL_ENABLE_OFFSET, + SDHCI_AUTO_CMD12_ERROR_STATUS_OFFSET, + SDHCI_CAPABILITIES_OFFSET, + SDHCI_CAPABILITIES_RESERVED_OFFSET, + SDHCI_MAXIMUM_CURRENT_CAPABILITIES_OFFSET, + SDHCI_MAXIMUM_CURRENT_CAPABILITIES_RESERVED_OFFSET, + SDHCI_SLOT_INTERRUPT_STATUS_OFFSET: addrmiss = 1'b0; + default: addrmiss = reg_req_i.valid; + endcase end - assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; - - // Check sub-word write is permitted always_comb begin - wr_err = (reg_we & - ((addr_hit[ 0] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[ 0]))) | - (addr_hit[ 1] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[ 1]))) | - (addr_hit[ 2] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[ 2]))) | - (addr_hit[ 3] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[ 3]))) | - (addr_hit[ 4] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[ 4]))) | - (addr_hit[ 5] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[ 5]))) | - (addr_hit[ 6] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[ 6]))) | - (addr_hit[ 7] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[ 7]))) | - (addr_hit[ 8] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[ 8]))) | - (addr_hit[ 9] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[ 9]))) | - (addr_hit[10] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[10]))) | - (addr_hit[11] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[11]))) | - (addr_hit[12] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[12]))) | - (addr_hit[13] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[13]))) | - (addr_hit[14] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[14]))) | - (addr_hit[15] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[15]))) | - (addr_hit[16] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[16]))) | - (addr_hit[17] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[17]))) | - (addr_hit[18] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[18]))) | - (addr_hit[19] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[19]))) | - (addr_hit[20] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[20]))) | - (addr_hit[21] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[21]))) | - (addr_hit[22] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[22]))) | - (addr_hit[23] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[23]))) | - (addr_hit[24] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[24]))) | - (addr_hit[25] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[25]))) | - (addr_hit[26] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[26]))) | - (addr_hit[27] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[27]))) | - (addr_hit[28] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[28]))) | - (addr_hit[29] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[29]))) | - (addr_hit[30] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[30]))) | - (addr_hit[31] & (|((reg_be ^ (reg_be >> 1)) & SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[31]))))); + wr_err = 1'b0; + + if (reg_we) begin + unique case (reg_addr) + SDHCI_SYSTEM_ADDRESS_OFFSET: + wr_err = boundary_err(reg_be, SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[SDHCI_SYSTEM_ADDRESS]); + SDHCI_BLOCK_SIZE_OFFSET: + wr_err = boundary_err(reg_be, SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[SDHCI_BLOCK_SIZE]) | + boundary_err(reg_be, SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[SDHCI_BLOCK_COUNT]); + SDHCI_ARGUMENT_OFFSET: + wr_err = boundary_err(reg_be, SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[SDHCI_ARGUMENT]); + SDHCI_RESPONSE0_OFFSET: + wr_err = boundary_err(reg_be, SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[SDHCI_RESPONSE0]); + SDHCI_RESPONSE1_OFFSET: + wr_err = boundary_err(reg_be, SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[SDHCI_RESPONSE1]); + SDHCI_RESPONSE2_OFFSET: + wr_err = boundary_err(reg_be, SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[SDHCI_RESPONSE2]); + SDHCI_RESPONSE3_OFFSET: + wr_err = boundary_err(reg_be, SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[SDHCI_RESPONSE3]); + SDHCI_BUFFER_DATA_PORT_OFFSET: + wr_err = boundary_err(reg_be, SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[SDHCI_BUFFER_DATA_PORT]); + SDHCI_CAPABILITIES_RESERVED_OFFSET: + wr_err = boundary_err(reg_be, + SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[SDHCI_CAPABILITIES_RESERVED]); + SDHCI_MAXIMUM_CURRENT_CAPABILITIES_RESERVED_OFFSET: + wr_err = boundary_err(reg_be, + SDHCI_DISALLOWED_BOUNDARY_CROSSINGS[SDHCI_MAXIMUM_CURRENT_CAPABILITIES_RESERVED]); + default: wr_err = 1'b0; + endcase + end end - assign system_address_we = addr_hit[0] & reg_we & !reg_error & (|(4'b 1111 & reg_be)); - assign system_address_wd = reg_wdata[31:0]; - - assign block_size_transfer_block_size_we = addr_hit[1] & reg_we & !reg_error & (|(4'b 0011 & reg_be)); - assign block_size_transfer_block_size_wd = reg_wdata[11:0]; - assign block_size_transfer_block_size_re = addr_hit[1] & reg_re & !reg_error; - - assign block_size_host_dma_buffer_boundary_we = addr_hit[1] & reg_we & !reg_error & (|(4'b 0010 & reg_be)); - assign block_size_host_dma_buffer_boundary_wd = reg_wdata[14:12]; - assign block_size_host_dma_buffer_boundary_re = addr_hit[1] & reg_re & !reg_error; - - assign block_size_rsvd_15_re = addr_hit[1] & reg_re & !reg_error; - - assign block_count_we = addr_hit[2] & reg_we & !reg_error & (|(4'b 1100 & reg_be)); - assign block_count_wd = reg_wdata[31:16]; - assign block_count_re = addr_hit[2] & reg_re & !reg_error; - - assign argument_we = addr_hit[3] & reg_we & !reg_error & (|(4'b 1111 & reg_be)); - assign argument_wd = reg_wdata[31:0]; - - assign transfer_mode_dma_enable_we = addr_hit[4] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign transfer_mode_dma_enable_wd = reg_wdata[0]; - assign transfer_mode_dma_enable_re = addr_hit[4] & reg_re & !reg_error; - - assign transfer_mode_block_count_enable_we = addr_hit[4] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign transfer_mode_block_count_enable_wd = reg_wdata[1]; - assign transfer_mode_block_count_enable_re = addr_hit[4] & reg_re & !reg_error; - - assign transfer_mode_auto_cmd12_enable_we = addr_hit[4] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign transfer_mode_auto_cmd12_enable_wd = reg_wdata[2]; - assign transfer_mode_auto_cmd12_enable_re = addr_hit[4] & reg_re & !reg_error; - - assign transfer_mode_rsvd_3_re = addr_hit[4] & reg_re & !reg_error; - - assign transfer_mode_data_transfer_direction_select_we = addr_hit[4] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign transfer_mode_data_transfer_direction_select_wd = reg_wdata[4]; - assign transfer_mode_data_transfer_direction_select_re = addr_hit[4] & reg_re & !reg_error; - - assign transfer_mode_multi_single_block_select_we = addr_hit[4] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign transfer_mode_multi_single_block_select_wd = reg_wdata[5]; - assign transfer_mode_multi_single_block_select_re = addr_hit[4] & reg_re & !reg_error; - - assign transfer_mode_rsvd_6_re = addr_hit[4] & reg_re & !reg_error; - - assign transfer_mode_rsvd_8_re = addr_hit[4] & reg_re & !reg_error; - - assign command_response_type_select_we = addr_hit[5] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign command_response_type_select_wd = reg_wdata[17:16]; - - assign command_command_crc_check_enable_we = addr_hit[5] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign command_command_crc_check_enable_wd = reg_wdata[19]; - - assign command_command_index_check_enable_we = addr_hit[5] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign command_command_index_check_enable_wd = reg_wdata[20]; - - assign command_data_present_select_we = addr_hit[5] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign command_data_present_select_wd = reg_wdata[21]; - - assign command_command_type_we = addr_hit[5] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign command_command_type_wd = reg_wdata[23:22]; - - assign command_command_index_we = addr_hit[5] & reg_we & !reg_error & (|(4'b 1000 & reg_be)); - assign command_command_index_wd = reg_wdata[29:24]; - - assign buffer_data_port_we = addr_hit[10] & reg_we & !reg_error & (|(4'b 1111 & reg_be)); - assign buffer_data_port_wd = reg_wdata[31:0]; - assign buffer_data_port_re = addr_hit[10] & reg_re & !reg_error; - - assign host_control_led_control_we = addr_hit[12] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign host_control_led_control_wd = reg_wdata[0]; - - assign host_control_data_transfer_width_we = addr_hit[12] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign host_control_data_transfer_width_wd = reg_wdata[1]; - - assign host_control_high_speed_enable_we = addr_hit[12] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign host_control_high_speed_enable_wd = reg_wdata[2]; - - assign power_control_sd_bus_power_we = addr_hit[13] & reg_we & !reg_error & (|(4'b 0010 & reg_be)); - assign power_control_sd_bus_power_wd = reg_wdata[8]; - - assign power_control_sd_bus_voltage_select_we = addr_hit[13] & reg_we & !reg_error & (|(4'b 0010 & reg_be)); - assign power_control_sd_bus_voltage_select_wd = reg_wdata[11:9]; - - assign block_gap_control_stop_at_block_gap_request_we = addr_hit[14] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign block_gap_control_stop_at_block_gap_request_wd = reg_wdata[16]; - - assign block_gap_control_continue_request_we = addr_hit[14] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign block_gap_control_continue_request_wd = reg_wdata[17]; - - assign block_gap_control_read_wait_control_we = addr_hit[14] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign block_gap_control_read_wait_control_wd = reg_wdata[18]; - - assign block_gap_control_interrupt_at_block_gap_we = addr_hit[14] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign block_gap_control_interrupt_at_block_gap_wd = reg_wdata[19]; - - assign wakeup_control_wakeup_event_enable_on_card_interrupt_we = addr_hit[15] & reg_we & !reg_error & (|(4'b 1000 & reg_be)); - assign wakeup_control_wakeup_event_enable_on_card_interrupt_wd = reg_wdata[24]; - - assign wakeup_control_wakeup_event_enable_on_sd_card_insertion_we = addr_hit[15] & reg_we & !reg_error & (|(4'b 1000 & reg_be)); - assign wakeup_control_wakeup_event_enable_on_sd_card_insertion_wd = reg_wdata[25]; - - assign wakeup_control_wakeup_event_enable_on_sd_card_removal_we = addr_hit[15] & reg_we & !reg_error & (|(4'b 1000 & reg_be)); - assign wakeup_control_wakeup_event_enable_on_sd_card_removal_wd = reg_wdata[26]; - - assign clock_control_internal_clock_enable_we = addr_hit[16] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign clock_control_internal_clock_enable_wd = reg_wdata[0]; - - assign clock_control_sd_clock_enable_we = addr_hit[16] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign clock_control_sd_clock_enable_wd = reg_wdata[2]; - - assign clock_control_sdclk_frequency_select_we = addr_hit[16] & reg_we & !reg_error & (|(4'b 0010 & reg_be)); - assign clock_control_sdclk_frequency_select_wd = reg_wdata[15:8]; - - assign timeout_control_data_timeout_counter_value_we = addr_hit[17] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign timeout_control_data_timeout_counter_value_wd = reg_wdata[19:16]; - - assign software_reset_software_reset_for_all_we = addr_hit[18] & reg_we & !reg_error & (|(4'b 1000 & reg_be)); - assign software_reset_software_reset_for_all_wd = reg_wdata[24]; - - assign software_reset_software_reset_for_cmd_line_we = addr_hit[18] & reg_we & !reg_error & (|(4'b 1000 & reg_be)); - assign software_reset_software_reset_for_cmd_line_wd = reg_wdata[25]; - - assign software_reset_software_reset_for_dat_line_we = addr_hit[18] & reg_we & !reg_error & (|(4'b 1000 & reg_be)); - assign software_reset_software_reset_for_dat_line_wd = reg_wdata[26]; - - assign normal_interrupt_status_command_complete_we = addr_hit[19] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_status_command_complete_wd = reg_wdata[0]; - - assign normal_interrupt_status_transfer_complete_we = addr_hit[19] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_status_transfer_complete_wd = reg_wdata[1]; - - assign normal_interrupt_status_block_gap_event_we = addr_hit[19] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_status_block_gap_event_wd = reg_wdata[2]; - - assign normal_interrupt_status_dma_interrupt_we = addr_hit[19] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_status_dma_interrupt_wd = reg_wdata[3]; - - assign normal_interrupt_status_buffer_write_ready_we = addr_hit[19] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_status_buffer_write_ready_wd = reg_wdata[4]; - - assign normal_interrupt_status_buffer_read_ready_we = addr_hit[19] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_status_buffer_read_ready_wd = reg_wdata[5]; - - assign normal_interrupt_status_card_insertion_we = addr_hit[19] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_status_card_insertion_wd = reg_wdata[6]; - - assign normal_interrupt_status_card_removal_we = addr_hit[19] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_status_card_removal_wd = reg_wdata[7]; - - assign error_interrupt_status_command_timeout_error_we = addr_hit[20] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_status_command_timeout_error_wd = reg_wdata[16]; - - assign error_interrupt_status_command_crc_error_we = addr_hit[20] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_status_command_crc_error_wd = reg_wdata[17]; - - assign error_interrupt_status_command_end_bit_error_we = addr_hit[20] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_status_command_end_bit_error_wd = reg_wdata[18]; - - assign error_interrupt_status_command_index_error_we = addr_hit[20] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_status_command_index_error_wd = reg_wdata[19]; - - assign error_interrupt_status_data_timeout_error_we = addr_hit[20] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_status_data_timeout_error_wd = reg_wdata[20]; - - assign error_interrupt_status_data_crc_error_we = addr_hit[20] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_status_data_crc_error_wd = reg_wdata[21]; - - assign error_interrupt_status_data_end_bit_error_we = addr_hit[20] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_status_data_end_bit_error_wd = reg_wdata[22]; - - assign error_interrupt_status_current_limit_error_we = addr_hit[20] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_status_current_limit_error_wd = reg_wdata[23]; - - assign error_interrupt_status_auto_cmd12_error_we = addr_hit[20] & reg_we & !reg_error & (|(4'b 1000 & reg_be)); - assign error_interrupt_status_auto_cmd12_error_wd = reg_wdata[24]; - - assign error_interrupt_status_vendor_specific_error_we = addr_hit[20] & reg_we & !reg_error & (|(4'b 1000 & reg_be)); - assign error_interrupt_status_vendor_specific_error_wd = reg_wdata[31:28]; - - assign normal_interrupt_status_enable_command_complete_status_enable_we = addr_hit[21] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_status_enable_command_complete_status_enable_wd = reg_wdata[0]; - - assign normal_interrupt_status_enable_transfer_complete_status_enable_we = addr_hit[21] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_status_enable_transfer_complete_status_enable_wd = reg_wdata[1]; - - assign normal_interrupt_status_enable_block_gap_event_status_enable_we = addr_hit[21] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_status_enable_block_gap_event_status_enable_wd = reg_wdata[2]; - - assign normal_interrupt_status_enable_dma_interrupt_status_enable_we = addr_hit[21] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_status_enable_dma_interrupt_status_enable_wd = reg_wdata[3]; - - assign normal_interrupt_status_enable_buffer_write_ready_status_enable_we = addr_hit[21] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_status_enable_buffer_write_ready_status_enable_wd = reg_wdata[4]; - - assign normal_interrupt_status_enable_buffer_read_ready_status_enable_we = addr_hit[21] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_status_enable_buffer_read_ready_status_enable_wd = reg_wdata[5]; - - assign normal_interrupt_status_enable_card_insertion_status_enable_we = addr_hit[21] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_status_enable_card_insertion_status_enable_wd = reg_wdata[6]; - - assign normal_interrupt_status_enable_card_removal_status_enable_we = addr_hit[21] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_status_enable_card_removal_status_enable_wd = reg_wdata[7]; - - assign normal_interrupt_status_enable_card_interrupt_status_enable_we = addr_hit[21] & reg_we & !reg_error & (|(4'b 0010 & reg_be)); - assign normal_interrupt_status_enable_card_interrupt_status_enable_wd = reg_wdata[8]; - - assign error_interrupt_status_enable_command_timeout_error_status_enable_we = addr_hit[22] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_status_enable_command_timeout_error_status_enable_wd = reg_wdata[16]; - - assign error_interrupt_status_enable_command_crc_error_status_enable_we = addr_hit[22] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_status_enable_command_crc_error_status_enable_wd = reg_wdata[17]; - - assign error_interrupt_status_enable_command_end_bit_error_status_enable_we = addr_hit[22] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_status_enable_command_end_bit_error_status_enable_wd = reg_wdata[18]; - - assign error_interrupt_status_enable_command_index_error_status_enable_we = addr_hit[22] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_status_enable_command_index_error_status_enable_wd = reg_wdata[19]; - - assign error_interrupt_status_enable_data_timeout_error_status_enable_we = addr_hit[22] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_status_enable_data_timeout_error_status_enable_wd = reg_wdata[20]; - - assign error_interrupt_status_enable_data_crc_error_status_enable_we = addr_hit[22] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_status_enable_data_crc_error_status_enable_wd = reg_wdata[21]; - - assign error_interrupt_status_enable_data_end_bit_error_status_enable_we = addr_hit[22] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_status_enable_data_end_bit_error_status_enable_wd = reg_wdata[22]; - - assign error_interrupt_status_enable_current_limit_error_status_enable_we = addr_hit[22] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_status_enable_current_limit_error_status_enable_wd = reg_wdata[23]; - - assign error_interrupt_status_enable_auto_cmd12_error_status_enable_we = addr_hit[22] & reg_we & !reg_error & (|(4'b 1000 & reg_be)); - assign error_interrupt_status_enable_auto_cmd12_error_status_enable_wd = reg_wdata[24]; - - assign error_interrupt_status_enable_vendor_specific_error_status_enable_we = addr_hit[22] & reg_we & !reg_error & (|(4'b 1000 & reg_be)); - assign error_interrupt_status_enable_vendor_specific_error_status_enable_wd = reg_wdata[31:28]; - - assign normal_interrupt_signal_enable_command_complete_signal_enable_we = addr_hit[23] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_signal_enable_command_complete_signal_enable_wd = reg_wdata[0]; - - assign normal_interrupt_signal_enable_transfer_complete_signal_enable_we = addr_hit[23] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_signal_enable_transfer_complete_signal_enable_wd = reg_wdata[1]; - - assign normal_interrupt_signal_enable_block_gap_event_signal_enable_we = addr_hit[23] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_signal_enable_block_gap_event_signal_enable_wd = reg_wdata[2]; - - assign normal_interrupt_signal_enable_dma_interrupt_signal_enable_we = addr_hit[23] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_signal_enable_dma_interrupt_signal_enable_wd = reg_wdata[3]; - - assign normal_interrupt_signal_enable_buffer_write_ready_signal_enable_we = addr_hit[23] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_signal_enable_buffer_write_ready_signal_enable_wd = reg_wdata[4]; - - assign normal_interrupt_signal_enable_buffer_read_ready_signal_enable_we = addr_hit[23] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_signal_enable_buffer_read_ready_signal_enable_wd = reg_wdata[5]; - - assign normal_interrupt_signal_enable_card_insertion_signal_enable_we = addr_hit[23] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_signal_enable_card_insertion_signal_enable_wd = reg_wdata[6]; - - assign normal_interrupt_signal_enable_card_removal_signal_enable_we = addr_hit[23] & reg_we & !reg_error & (|(4'b 0001 & reg_be)); - assign normal_interrupt_signal_enable_card_removal_signal_enable_wd = reg_wdata[7]; - - assign normal_interrupt_signal_enable_card_interrupt_signal_enable_we = addr_hit[23] & reg_we & !reg_error & (|(4'b 0010 & reg_be)); - assign normal_interrupt_signal_enable_card_interrupt_signal_enable_wd = reg_wdata[8]; - - assign error_interrupt_signal_enable_command_timeout_error_signal_enable_we = addr_hit[24] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_signal_enable_command_timeout_error_signal_enable_wd = reg_wdata[16]; - - assign error_interrupt_signal_enable_command_crc_error_signal_enable_we = addr_hit[24] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_signal_enable_command_crc_error_signal_enable_wd = reg_wdata[17]; - - assign error_interrupt_signal_enable_command_end_bit_error_signal_enable_we = addr_hit[24] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_signal_enable_command_end_bit_error_signal_enable_wd = reg_wdata[18]; - - assign error_interrupt_signal_enable_command_index_error_signal_enable_we = addr_hit[24] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_signal_enable_command_index_error_signal_enable_wd = reg_wdata[19]; - - assign error_interrupt_signal_enable_data_timeout_error_signal_enable_we = addr_hit[24] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_signal_enable_data_timeout_error_signal_enable_wd = reg_wdata[20]; - - assign error_interrupt_signal_enable_data_crc_error_signal_enable_we = addr_hit[24] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_signal_enable_data_crc_error_signal_enable_wd = reg_wdata[21]; - - assign error_interrupt_signal_enable_data_end_bit_error_signal_enable_we = addr_hit[24] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_signal_enable_data_end_bit_error_signal_enable_wd = reg_wdata[22]; - - assign error_interrupt_signal_enable_current_limit_error_signal_enable_we = addr_hit[24] & reg_we & !reg_error & (|(4'b 0100 & reg_be)); - assign error_interrupt_signal_enable_current_limit_error_signal_enable_wd = reg_wdata[23]; - - assign error_interrupt_signal_enable_auto_cmd12_error_signal_enable_we = addr_hit[24] & reg_we & !reg_error & (|(4'b 1000 & reg_be)); - assign error_interrupt_signal_enable_auto_cmd12_error_signal_enable_wd = reg_wdata[24]; - - assign error_interrupt_signal_enable_vendor_specific_error_signal_enable_we = addr_hit[24] & reg_we & !reg_error & (|(4'b 1000 & reg_be)); - assign error_interrupt_signal_enable_vendor_specific_error_signal_enable_wd = reg_wdata[31:28]; - - assign slot_interrupt_status_interrupt_signal_for_each_slot_re = addr_hit[30] & reg_re & !reg_error; - - assign slot_interrupt_status_rsvd_8_re = addr_hit[30] & reg_re & !reg_error; - - // Read data return always_comb begin - reg_rdata_next = '0; - if (addr_hit[0]) begin - reg_rdata_next[31:0] = system_address_qs; - end - - if (addr_hit[1]) begin - reg_rdata_next[11:0] = block_size_transfer_block_size_qs; - reg_rdata_next[14:12] = block_size_host_dma_buffer_boundary_qs; - reg_rdata_next[15] = block_size_rsvd_15_qs; - end - - if (addr_hit[2]) begin - reg_rdata_next[31:16] = block_count_qs; - end - - if (addr_hit[3]) begin - reg_rdata_next[31:0] = argument_qs; - end - - if (addr_hit[4]) begin - reg_rdata_next[0] = transfer_mode_dma_enable_qs; - reg_rdata_next[1] = transfer_mode_block_count_enable_qs; - reg_rdata_next[2] = transfer_mode_auto_cmd12_enable_qs; - reg_rdata_next[3] = transfer_mode_rsvd_3_qs; - reg_rdata_next[4] = transfer_mode_data_transfer_direction_select_qs; - reg_rdata_next[5] = transfer_mode_multi_single_block_select_qs; - reg_rdata_next[7:6] = transfer_mode_rsvd_6_qs; - reg_rdata_next[15:8] = transfer_mode_rsvd_8_qs; - end - - if (addr_hit[5]) begin - reg_rdata_next[17:16] = command_response_type_select_qs; - reg_rdata_next[18] = command_rsvd_2_qs; - reg_rdata_next[19] = command_command_crc_check_enable_qs; - reg_rdata_next[20] = command_command_index_check_enable_qs; - reg_rdata_next[21] = command_data_present_select_qs; - reg_rdata_next[23:22] = command_command_type_qs; - reg_rdata_next[29:24] = command_command_index_qs; - reg_rdata_next[31:30] = command_rsvd_14_qs; - end - - if (addr_hit[6]) begin - reg_rdata_next[31:0] = response0_qs; - end - - if (addr_hit[7]) begin - reg_rdata_next[31:0] = response1_qs; - end - - if (addr_hit[8]) begin - reg_rdata_next[31:0] = response2_qs; - end - - if (addr_hit[9]) begin - reg_rdata_next[31:0] = response3_qs; - end - - if (addr_hit[10]) begin - reg_rdata_next[31:0] = buffer_data_port_qs; - end - - if (addr_hit[11]) begin - reg_rdata_next[0] = present_state_command_inhibit_cmd_qs; - reg_rdata_next[1] = present_state_command_inhibit_dat_qs; - reg_rdata_next[2] = present_state_dat_line_active_qs; - reg_rdata_next[7:3] = present_state_rsvd_3_qs; - reg_rdata_next[8] = present_state_write_transfer_active_qs; - reg_rdata_next[9] = present_state_read_transfer_active_qs; - reg_rdata_next[10] = present_state_buffer_write_enable_qs; - reg_rdata_next[11] = present_state_buffer_read_enable_qs; - reg_rdata_next[15:12] = present_state_rsvd_12_qs; - reg_rdata_next[16] = present_state_card_inserted_qs; - reg_rdata_next[17] = present_state_card_state_stable_qs; - reg_rdata_next[18] = present_state_card_detect_pin_level_qs; - reg_rdata_next[19] = present_state_write_protect_switch_pin_level_qs; - reg_rdata_next[23:20] = present_state_dat_line_signal_level_qs; - reg_rdata_next[24] = present_state_cmd_line_signal_level_qs; - reg_rdata_next[31:25] = present_state_rsvd_25_qs; - end - - if (addr_hit[12]) begin - reg_rdata_next[0] = host_control_led_control_qs; - reg_rdata_next[1] = host_control_data_transfer_width_qs; - reg_rdata_next[2] = host_control_high_speed_enable_qs; - reg_rdata_next[7:3] = host_control_rsvd_3_qs; - end - - if (addr_hit[13]) begin - reg_rdata_next[8] = power_control_sd_bus_power_qs; - reg_rdata_next[11:9] = power_control_sd_bus_voltage_select_qs; - reg_rdata_next[15:12] = power_control_rsvd_4_qs; - end - - if (addr_hit[14]) begin - reg_rdata_next[16] = block_gap_control_stop_at_block_gap_request_qs; - reg_rdata_next[17] = block_gap_control_continue_request_qs; - reg_rdata_next[18] = block_gap_control_read_wait_control_qs; - reg_rdata_next[19] = block_gap_control_interrupt_at_block_gap_qs; - reg_rdata_next[23:20] = block_gap_control_rsvd_4_qs; - end - - if (addr_hit[15]) begin - reg_rdata_next[24] = wakeup_control_wakeup_event_enable_on_card_interrupt_qs; - reg_rdata_next[25] = wakeup_control_wakeup_event_enable_on_sd_card_insertion_qs; - reg_rdata_next[26] = wakeup_control_wakeup_event_enable_on_sd_card_removal_qs; - reg_rdata_next[31:27] = wakeup_control_rsvd_3_qs; - end - - if (addr_hit[16]) begin - reg_rdata_next[0] = clock_control_internal_clock_enable_qs; - reg_rdata_next[1] = clock_control_internal_clock_stable_qs; - reg_rdata_next[2] = clock_control_sd_clock_enable_qs; - reg_rdata_next[7:3] = clock_control_rsvd_3_qs; - reg_rdata_next[15:8] = clock_control_sdclk_frequency_select_qs; - end - - if (addr_hit[17]) begin - reg_rdata_next[19:16] = timeout_control_data_timeout_counter_value_qs; - reg_rdata_next[23:20] = timeout_control_rsvd_4_qs; - end - - if (addr_hit[18]) begin - reg_rdata_next[24] = software_reset_software_reset_for_all_qs; - reg_rdata_next[25] = software_reset_software_reset_for_cmd_line_qs; - reg_rdata_next[26] = software_reset_software_reset_for_dat_line_qs; - reg_rdata_next[31:28] = software_reset_rsvd_4_qs; - end - - if (addr_hit[19]) begin - reg_rdata_next[0] = normal_interrupt_status_command_complete_qs; - reg_rdata_next[1] = normal_interrupt_status_transfer_complete_qs; - reg_rdata_next[2] = normal_interrupt_status_block_gap_event_qs; - reg_rdata_next[3] = normal_interrupt_status_dma_interrupt_qs; - reg_rdata_next[4] = normal_interrupt_status_buffer_write_ready_qs; - reg_rdata_next[5] = normal_interrupt_status_buffer_read_ready_qs; - reg_rdata_next[6] = normal_interrupt_status_card_insertion_qs; - reg_rdata_next[7] = normal_interrupt_status_card_removal_qs; - reg_rdata_next[8] = normal_interrupt_status_card_interrupt_qs; - reg_rdata_next[14:9] = normal_interrupt_status_rsvd_9_qs; - reg_rdata_next[15] = normal_interrupt_status_error_interrupt_qs; - end - - if (addr_hit[20]) begin - reg_rdata_next[16] = error_interrupt_status_command_timeout_error_qs; - reg_rdata_next[17] = error_interrupt_status_command_crc_error_qs; - reg_rdata_next[18] = error_interrupt_status_command_end_bit_error_qs; - reg_rdata_next[19] = error_interrupt_status_command_index_error_qs; - reg_rdata_next[20] = error_interrupt_status_data_timeout_error_qs; - reg_rdata_next[21] = error_interrupt_status_data_crc_error_qs; - reg_rdata_next[22] = error_interrupt_status_data_end_bit_error_qs; - reg_rdata_next[23] = error_interrupt_status_current_limit_error_qs; - reg_rdata_next[24] = error_interrupt_status_auto_cmd12_error_qs; - reg_rdata_next[27:25] = error_interrupt_status_rsvd_9_qs; - reg_rdata_next[31:28] = error_interrupt_status_vendor_specific_error_qs; - end - - if (addr_hit[21]) begin - reg_rdata_next[0] = normal_interrupt_status_enable_command_complete_status_enable_qs; - reg_rdata_next[1] = normal_interrupt_status_enable_transfer_complete_status_enable_qs; - reg_rdata_next[2] = normal_interrupt_status_enable_block_gap_event_status_enable_qs; - reg_rdata_next[3] = normal_interrupt_status_enable_dma_interrupt_status_enable_qs; - reg_rdata_next[4] = normal_interrupt_status_enable_buffer_write_ready_status_enable_qs; - reg_rdata_next[5] = normal_interrupt_status_enable_buffer_read_ready_status_enable_qs; - reg_rdata_next[6] = normal_interrupt_status_enable_card_insertion_status_enable_qs; - reg_rdata_next[7] = normal_interrupt_status_enable_card_removal_status_enable_qs; - reg_rdata_next[8] = normal_interrupt_status_enable_card_interrupt_status_enable_qs; - reg_rdata_next[14:9] = normal_interrupt_status_enable_rsvd_9_qs; - reg_rdata_next[15] = normal_interrupt_status_enable_fixed_to_0_qs; - end - - if (addr_hit[22]) begin - reg_rdata_next[16] = error_interrupt_status_enable_command_timeout_error_status_enable_qs; - reg_rdata_next[17] = error_interrupt_status_enable_command_crc_error_status_enable_qs; - reg_rdata_next[18] = error_interrupt_status_enable_command_end_bit_error_status_enable_qs; - reg_rdata_next[19] = error_interrupt_status_enable_command_index_error_status_enable_qs; - reg_rdata_next[20] = error_interrupt_status_enable_data_timeout_error_status_enable_qs; - reg_rdata_next[21] = error_interrupt_status_enable_data_crc_error_status_enable_qs; - reg_rdata_next[22] = error_interrupt_status_enable_data_end_bit_error_status_enable_qs; - reg_rdata_next[23] = error_interrupt_status_enable_current_limit_error_status_enable_qs; - reg_rdata_next[24] = error_interrupt_status_enable_auto_cmd12_error_status_enable_qs; - reg_rdata_next[27:25] = error_interrupt_status_enable_rsvd_9_qs; - reg_rdata_next[31:28] = error_interrupt_status_enable_vendor_specific_error_status_enable_qs; - end - - if (addr_hit[23]) begin - reg_rdata_next[0] = normal_interrupt_signal_enable_command_complete_signal_enable_qs; - reg_rdata_next[1] = normal_interrupt_signal_enable_transfer_complete_signal_enable_qs; - reg_rdata_next[2] = normal_interrupt_signal_enable_block_gap_event_signal_enable_qs; - reg_rdata_next[3] = normal_interrupt_signal_enable_dma_interrupt_signal_enable_qs; - reg_rdata_next[4] = normal_interrupt_signal_enable_buffer_write_ready_signal_enable_qs; - reg_rdata_next[5] = normal_interrupt_signal_enable_buffer_read_ready_signal_enable_qs; - reg_rdata_next[6] = normal_interrupt_signal_enable_card_insertion_signal_enable_qs; - reg_rdata_next[7] = normal_interrupt_signal_enable_card_removal_signal_enable_qs; - reg_rdata_next[8] = normal_interrupt_signal_enable_card_interrupt_signal_enable_qs; - reg_rdata_next[14:9] = normal_interrupt_signal_enable_rsvd_9_qs; - reg_rdata_next[15] = normal_interrupt_signal_enable_fixed_to_0_qs; - end - - if (addr_hit[24]) begin - reg_rdata_next[16] = error_interrupt_signal_enable_command_timeout_error_signal_enable_qs; - reg_rdata_next[17] = error_interrupt_signal_enable_command_crc_error_signal_enable_qs; - reg_rdata_next[18] = error_interrupt_signal_enable_command_end_bit_error_signal_enable_qs; - reg_rdata_next[19] = error_interrupt_signal_enable_command_index_error_signal_enable_qs; - reg_rdata_next[20] = error_interrupt_signal_enable_data_timeout_error_signal_enable_qs; - reg_rdata_next[21] = error_interrupt_signal_enable_data_crc_error_signal_enable_qs; - reg_rdata_next[22] = error_interrupt_signal_enable_data_end_bit_error_signal_enable_qs; - reg_rdata_next[23] = error_interrupt_signal_enable_current_limit_error_signal_enable_qs; - reg_rdata_next[24] = error_interrupt_signal_enable_auto_cmd12_error_signal_enable_qs; - reg_rdata_next[27:25] = error_interrupt_signal_enable_rsvd_9_qs; - reg_rdata_next[31:28] = error_interrupt_signal_enable_vendor_specific_error_signal_enable_qs; - end - - if (addr_hit[25]) begin - reg_rdata_next[0] = auto_cmd12_error_status_auto_cmd12_not_executed_qs; - reg_rdata_next[1] = auto_cmd12_error_status_auto_cmd12_timeout_error_qs; - reg_rdata_next[2] = auto_cmd12_error_status_auto_cmd12_crc_error_qs; - reg_rdata_next[3] = auto_cmd12_error_status_auto_cmd12_end_bit_error_qs; - reg_rdata_next[4] = auto_cmd12_error_status_auto_cmd12_index_error_qs; - reg_rdata_next[6:5] = auto_cmd12_error_status_rsvd_5_qs; - reg_rdata_next[7] = auto_cmd12_error_status_command_not_issued_by_auto_cmd12_error_qs; - reg_rdata_next[15:8] = auto_cmd12_error_status_rsvd_8_qs; + reg_ready = 1'b1; + if (!wr_err && !(devmode_i && addrmiss) && + reg_addr == SDHCI_BUFFER_DATA_PORT_OFFSET && reg_req_i.valid) begin + reg_ready = reg_we ? buffer_data_port_write_ready_i : buffer_data_port_read_ready_i; end + end - if (addr_hit[26]) begin - reg_rdata_next[5:0] = capabilities_timeout_clock_frequency_qs; - reg_rdata_next[6] = capabilities_rsvd_6_qs; - reg_rdata_next[7] = capabilities_timeout_clock_unit_qs; - reg_rdata_next[13:8] = capabilities_base_clock_frequency_for_sd_clock_qs; - reg_rdata_next[15:14] = capabilities_rsvd_14_qs; - reg_rdata_next[17:16] = capabilities_max_block_length_qs; - reg_rdata_next[20:18] = capabilities_rsvd_18_qs; - reg_rdata_next[21] = capabilities_high_speed_support_qs; - reg_rdata_next[22] = capabilities_dma_support_qs; - reg_rdata_next[23] = capabilities_suspend_resume_support_qs; - reg_rdata_next[24] = capabilities_voltage_support_3_3v_qs; - reg_rdata_next[25] = capabilities_voltage_support_3_0v_qs; - reg_rdata_next[26] = capabilities_voltage_support_1_8v_qs; - reg_rdata_next[31:27] = capabilities_rsvd_27_qs; - end + assign accepted = reg_req_i.valid & reg_ready & !((devmode_i & addrmiss) | wr_err); - if (addr_hit[27]) begin - reg_rdata_next[31:0] = capabilities_reserved_qs; - end + always_comb begin + reg_rsp_o.ready = reg_ready; + reg_rsp_o.error = (devmode_i & addrmiss) | wr_err; + reg_rsp_o.rdata = '0; + + unique case (reg_addr) + SDHCI_BLOCK_SIZE_OFFSET: begin + reg_rsp_o.rdata[11:0] = hw2reg.block_size.transfer_block_size.d; + reg_rsp_o.rdata[14:12] = hw2reg.block_size.host_dma_buffer_boundary.d; + reg_rsp_o.rdata[31:16] = hw2reg.block_count.d; + end + + SDHCI_ARGUMENT_OFFSET: begin + reg_rsp_o.rdata = reg2hw_q.argument.q; + end + + SDHCI_TRANSFER_MODE_OFFSET: begin + reg_rsp_o.rdata[1] = hw2reg.transfer_mode.block_count_enable.d; + reg_rsp_o.rdata[2] = hw2reg.transfer_mode.auto_cmd12_enable.d; + reg_rsp_o.rdata[4] = hw2reg.transfer_mode.data_transfer_direction_select.d; + reg_rsp_o.rdata[5] = hw2reg.transfer_mode.multi_single_block_select.d; + reg_rsp_o.rdata[17:16] = reg2hw_q.command.response_type_select.q; + reg_rsp_o.rdata[19] = reg2hw_q.command.command_crc_check_enable.q; + reg_rsp_o.rdata[20] = reg2hw_q.command.command_index_check_enable.q; + reg_rsp_o.rdata[21] = reg2hw_q.command.data_present_select.q; + reg_rsp_o.rdata[23:22] = reg2hw_q.command.command_type.q; + reg_rsp_o.rdata[29:24] = reg2hw_q.command.command_index.q; + end + + SDHCI_RESPONSE0_OFFSET: reg_rsp_o.rdata = reg2hw_q.response0.q; + SDHCI_RESPONSE1_OFFSET: reg_rsp_o.rdata = reg2hw_q.response1.q; + SDHCI_RESPONSE2_OFFSET: reg_rsp_o.rdata = reg2hw_q.response2.q; + SDHCI_RESPONSE3_OFFSET: reg_rsp_o.rdata = reg2hw_q.response3.q; + SDHCI_BUFFER_DATA_PORT_OFFSET: reg_rsp_o.rdata = hw2reg.buffer_data_port.d; + + SDHCI_PRESENT_STATE_OFFSET: begin + reg_rsp_o.rdata[0] = reg2hw_q.present_state.command_inhibit_cmd.q; + reg_rsp_o.rdata[1] = reg2hw_q.present_state.command_inhibit_dat.q; + reg_rsp_o.rdata[2] = reg2hw_q.present_state.dat_line_active.q; + reg_rsp_o.rdata[8] = reg2hw_q.present_state.write_transfer_active.q; + reg_rsp_o.rdata[9] = reg2hw_q.present_state.read_transfer_active.q; + reg_rsp_o.rdata[10] = reg2hw_q.present_state.buffer_write_enable.q; + reg_rsp_o.rdata[11] = reg2hw_q.present_state.buffer_read_enable.q; + reg_rsp_o.rdata[16] = reg2hw_q.present_state.card_inserted.q; + reg_rsp_o.rdata[17] = reg2hw_q.present_state.card_state_stable.q; + reg_rsp_o.rdata[18] = reg2hw_q.present_state.card_detect_pin_level.q; + reg_rsp_o.rdata[19] = reg2hw_q.present_state.write_protect_switch_pin_level.q; + reg_rsp_o.rdata[23:20] = reg2hw_q.present_state.dat_line_signal_level.q; + reg_rsp_o.rdata[24] = reg2hw_q.present_state.cmd_line_signal_level.q; + end + + SDHCI_HOST_CONTROL_OFFSET: begin + reg_rsp_o.rdata[1] = reg2hw_q.host_control.data_transfer_width.q; + end + + SDHCI_CLOCK_CONTROL_OFFSET: begin + reg_rsp_o.rdata[0] = reg2hw_q.clock_control.internal_clock_enable.q; + reg_rsp_o.rdata[1] = reg2hw_q.clock_control.internal_clock_stable.q; + reg_rsp_o.rdata[2] = reg2hw_q.clock_control.sd_clock_enable.q; + reg_rsp_o.rdata[15:8] = reg2hw_q.clock_control.sdclk_frequency_select.q; + reg_rsp_o.rdata[19:16] = reg2hw_q.timeout_control.data_timeout_counter_value.q; + reg_rsp_o.rdata[24] = reg2hw_q.software_reset.software_reset_for_all.q; + reg_rsp_o.rdata[25] = reg2hw_q.software_reset.software_reset_for_cmd_line.q; + reg_rsp_o.rdata[26] = reg2hw_q.software_reset.software_reset_for_dat_line.q; + end + + SDHCI_NORMAL_INTERRUPT_STATUS_OFFSET: begin + reg_rsp_o.rdata[0] = reg2hw_q.normal_interrupt_status.command_complete.q; + reg_rsp_o.rdata[1] = reg2hw_q.normal_interrupt_status.transfer_complete.q; + reg_rsp_o.rdata[4] = reg2hw_q.normal_interrupt_status.buffer_write_ready.q; + reg_rsp_o.rdata[5] = reg2hw_q.normal_interrupt_status.buffer_read_ready.q; + reg_rsp_o.rdata[6] = reg2hw_q.normal_interrupt_status.card_insertion.q; + reg_rsp_o.rdata[7] = reg2hw_q.normal_interrupt_status.card_removal.q; + reg_rsp_o.rdata[15] = reg2hw_q.normal_interrupt_status.error_interrupt.q; + reg_rsp_o.rdata[16] = reg2hw_q.error_interrupt_status.command_timeout_error.q; + reg_rsp_o.rdata[17] = reg2hw_q.error_interrupt_status.command_crc_error.q; + reg_rsp_o.rdata[18] = reg2hw_q.error_interrupt_status.command_end_bit_error.q; + reg_rsp_o.rdata[19] = reg2hw_q.error_interrupt_status.command_index_error.q; + reg_rsp_o.rdata[20] = reg2hw_q.error_interrupt_status.data_timeout_error.q; + reg_rsp_o.rdata[21] = reg2hw_q.error_interrupt_status.data_crc_error.q; + reg_rsp_o.rdata[22] = reg2hw_q.error_interrupt_status.data_end_bit_error.q; + reg_rsp_o.rdata[24] = reg2hw_q.error_interrupt_status.auto_cmd12_error.q; + end + + SDHCI_NORMAL_INTERRUPT_STATUS_ENABLE_OFFSET: begin + reg_rsp_o.rdata[0] = reg2hw_q.normal_interrupt_status_enable.command_complete_status_enable.q; + reg_rsp_o.rdata[1] = reg2hw_q.normal_interrupt_status_enable.transfer_complete_status_enable.q; + reg_rsp_o.rdata[4] = reg2hw_q.normal_interrupt_status_enable.buffer_write_ready_status_enable.q; + reg_rsp_o.rdata[5] = reg2hw_q.normal_interrupt_status_enable.buffer_read_ready_status_enable.q; + reg_rsp_o.rdata[6] = reg2hw_q.normal_interrupt_status_enable.card_insertion_status_enable.q; + reg_rsp_o.rdata[7] = reg2hw_q.normal_interrupt_status_enable.card_removal_status_enable.q; + reg_rsp_o.rdata[8] = reg2hw_q.normal_interrupt_status_enable.card_interrupt_status_enable.q; + reg_rsp_o.rdata[15] = reg2hw_q.normal_interrupt_status_enable.fixed_to_0.q; + reg_rsp_o.rdata[16] = + reg2hw_q.error_interrupt_status_enable.command_timeout_error_status_enable.q; + reg_rsp_o.rdata[17] = + reg2hw_q.error_interrupt_status_enable.command_crc_error_status_enable.q; + reg_rsp_o.rdata[18] = + reg2hw_q.error_interrupt_status_enable.command_end_bit_error_status_enable.q; + reg_rsp_o.rdata[19] = + reg2hw_q.error_interrupt_status_enable.command_index_error_status_enable.q; + reg_rsp_o.rdata[20] = + reg2hw_q.error_interrupt_status_enable.data_timeout_error_status_enable.q; + reg_rsp_o.rdata[21] = + reg2hw_q.error_interrupt_status_enable.data_crc_error_status_enable.q; + reg_rsp_o.rdata[22] = + reg2hw_q.error_interrupt_status_enable.data_end_bit_error_status_enable.q; + reg_rsp_o.rdata[24] = + reg2hw_q.error_interrupt_status_enable.auto_cmd12_error_status_enable.q; + end + + SDHCI_NORMAL_INTERRUPT_SIGNAL_ENABLE_OFFSET: begin + reg_rsp_o.rdata[0] = reg2hw_q.normal_interrupt_signal_enable.command_complete_signal_enable.q; + reg_rsp_o.rdata[1] = reg2hw_q.normal_interrupt_signal_enable.transfer_complete_signal_enable.q; + reg_rsp_o.rdata[4] = reg2hw_q.normal_interrupt_signal_enable.buffer_write_ready_signal_enable.q; + reg_rsp_o.rdata[5] = reg2hw_q.normal_interrupt_signal_enable.buffer_read_ready_signal_enable.q; + reg_rsp_o.rdata[6] = reg2hw_q.normal_interrupt_signal_enable.card_insertion_signal_enable.q; + reg_rsp_o.rdata[7] = reg2hw_q.normal_interrupt_signal_enable.card_removal_signal_enable.q; + reg_rsp_o.rdata[8] = reg2hw_q.normal_interrupt_signal_enable.card_interrupt_signal_enable.q; + reg_rsp_o.rdata[16] = + reg2hw_q.error_interrupt_signal_enable.command_timeout_error_signal_enable.q; + reg_rsp_o.rdata[17] = + reg2hw_q.error_interrupt_signal_enable.command_crc_error_signal_enable.q; + reg_rsp_o.rdata[18] = + reg2hw_q.error_interrupt_signal_enable.command_end_bit_error_signal_enable.q; + reg_rsp_o.rdata[19] = + reg2hw_q.error_interrupt_signal_enable.command_index_error_signal_enable.q; + reg_rsp_o.rdata[20] = + reg2hw_q.error_interrupt_signal_enable.data_timeout_error_signal_enable.q; + reg_rsp_o.rdata[21] = + reg2hw_q.error_interrupt_signal_enable.data_crc_error_signal_enable.q; + reg_rsp_o.rdata[22] = + reg2hw_q.error_interrupt_signal_enable.data_end_bit_error_signal_enable.q; + reg_rsp_o.rdata[24] = + reg2hw_q.error_interrupt_signal_enable.auto_cmd12_error_signal_enable.q; + end + + SDHCI_AUTO_CMD12_ERROR_STATUS_OFFSET: begin + reg_rsp_o.rdata[0] = reg2hw_q.auto_cmd12_error_status.auto_cmd12_not_executed.q; + reg_rsp_o.rdata[1] = reg2hw_q.auto_cmd12_error_status.auto_cmd12_timeout_error.q; + reg_rsp_o.rdata[2] = reg2hw_q.auto_cmd12_error_status.auto_cmd12_crc_error.q; + reg_rsp_o.rdata[3] = reg2hw_q.auto_cmd12_error_status.auto_cmd12_end_bit_error.q; + reg_rsp_o.rdata[4] = reg2hw_q.auto_cmd12_error_status.auto_cmd12_index_error.q; + reg_rsp_o.rdata[7] = + reg2hw_q.auto_cmd12_error_status.command_not_issued_by_auto_cmd12_error.q; + end + + SDHCI_CAPABILITIES_OFFSET: reg_rsp_o.rdata = Capabilities; + SDHCI_CAPABILITIES_RESERVED_OFFSET: reg_rsp_o.rdata = VendorCapabilities; + SDHCI_SLOT_INTERRUPT_STATUS_OFFSET: begin + reg_rsp_o.rdata[7:0] = hw2reg.slot_interrupt_status.interrupt_signal_for_each_slot.d; + end + + default: reg_rsp_o.rdata = '0; + endcase + end - if (addr_hit[28]) begin - reg_rdata_next[7:0] = maximum_current_capabilities_maximum_current_for_3_3v_qs; - reg_rdata_next[15:8] = maximum_current_capabilities_maximum_current_for_3_0v_qs; - reg_rdata_next[23:16] = maximum_current_capabilities_maximum_current_for_1_8v_qs; - reg_rdata_next[31:24] = maximum_current_capabilities_rsvd_24_qs; + always_comb begin + reg2hw_d = reg2hw_q; + + reg2hw_d.block_size.transfer_block_size.qe = 1'b0; + reg2hw_d.block_size.host_dma_buffer_boundary.qe = 1'b0; + reg2hw_d.block_count.qe = 1'b0; + reg2hw_d.transfer_mode.block_count_enable.qe = 1'b0; + reg2hw_d.transfer_mode.auto_cmd12_enable.qe = 1'b0; + reg2hw_d.transfer_mode.data_transfer_direction_select.qe = 1'b0; + reg2hw_d.transfer_mode.multi_single_block_select.qe = 1'b0; + reg2hw_d.command.response_type_select.qe = 1'b0; + reg2hw_d.command.command_crc_check_enable.qe = 1'b0; + reg2hw_d.command.command_index_check_enable.qe = 1'b0; + reg2hw_d.command.data_present_select.qe = 1'b0; + reg2hw_d.command.command_type.qe = 1'b0; + reg2hw_d.command.command_index.qe = 1'b0; + reg2hw_d.buffer_data_port.qe = 1'b0; + reg2hw_d.buffer_data_port.re = 1'b0; + reg2hw_d.clock_control.internal_clock_enable.qe = 1'b0; + reg2hw_d.clock_control.internal_clock_stable.qe = 1'b0; + reg2hw_d.clock_control.sd_clock_enable.qe = 1'b0; + reg2hw_d.clock_control.sdclk_frequency_select.qe = 1'b0; + + if (hw2reg.response0.de) begin + reg2hw_d.response0.q = hw2reg.response0.d; + end + if (hw2reg.response1.de) begin + reg2hw_d.response1.q = hw2reg.response1.d; + end + if (hw2reg.response2.de) begin + reg2hw_d.response2.q = hw2reg.response2.d; + end + if (hw2reg.response3.de) begin + reg2hw_d.response3.q = hw2reg.response3.d; + end + + if (hw2reg.present_state.command_inhibit_cmd.de) begin + reg2hw_d.present_state.command_inhibit_cmd.q = hw2reg.present_state.command_inhibit_cmd.d; + end + if (hw2reg.present_state.command_inhibit_dat.de) begin + reg2hw_d.present_state.command_inhibit_dat.q = hw2reg.present_state.command_inhibit_dat.d; + end + if (hw2reg.present_state.dat_line_active.de) begin + reg2hw_d.present_state.dat_line_active.q = hw2reg.present_state.dat_line_active.d; + end + if (hw2reg.present_state.write_transfer_active.de) begin + reg2hw_d.present_state.write_transfer_active.q = hw2reg.present_state.write_transfer_active.d; + end + if (hw2reg.present_state.read_transfer_active.de) begin + reg2hw_d.present_state.read_transfer_active.q = hw2reg.present_state.read_transfer_active.d; + end + if (hw2reg.present_state.buffer_write_enable.de) begin + reg2hw_d.present_state.buffer_write_enable.q = hw2reg.present_state.buffer_write_enable.d; + end + if (hw2reg.present_state.buffer_read_enable.de) begin + reg2hw_d.present_state.buffer_read_enable.q = hw2reg.present_state.buffer_read_enable.d; + end + if (hw2reg.present_state.card_inserted.de) begin + reg2hw_d.present_state.card_inserted.q = hw2reg.present_state.card_inserted.d; + end + if (hw2reg.present_state.card_state_stable.de) begin + reg2hw_d.present_state.card_state_stable.q = hw2reg.present_state.card_state_stable.d; + end + if (hw2reg.present_state.card_detect_pin_level.de) begin + reg2hw_d.present_state.card_detect_pin_level.q = hw2reg.present_state.card_detect_pin_level.d; + end + if (hw2reg.present_state.write_protect_switch_pin_level.de) begin + reg2hw_d.present_state.write_protect_switch_pin_level.q = + hw2reg.present_state.write_protect_switch_pin_level.d; + end + if (hw2reg.present_state.dat_line_signal_level.de) begin + reg2hw_d.present_state.dat_line_signal_level.q = hw2reg.present_state.dat_line_signal_level.d; + end + if (hw2reg.present_state.cmd_line_signal_level.de) begin + reg2hw_d.present_state.cmd_line_signal_level.q = hw2reg.present_state.cmd_line_signal_level.d; + end + + if (hw2reg.clock_control.internal_clock_stable.de) begin + reg2hw_d.clock_control.internal_clock_stable.q = hw2reg.clock_control.internal_clock_stable.d; + end + + reg2hw_d.software_reset.software_reset_for_all.q = w1s_next( + reg2hw_q.software_reset.software_reset_for_all.q, + hw2reg.software_reset.software_reset_for_all.d, + hw2reg.software_reset.software_reset_for_all.de, + accepted && reg_we && reg_addr == SDHCI_SOFTWARE_RESET_OFFSET && reg_be[3], + reg_wdata[24]); + reg2hw_d.software_reset.software_reset_for_cmd_line.q = w1s_next( + reg2hw_q.software_reset.software_reset_for_cmd_line.q, + hw2reg.software_reset.software_reset_for_cmd_line.d, + hw2reg.software_reset.software_reset_for_cmd_line.de, + accepted && reg_we && reg_addr == SDHCI_SOFTWARE_RESET_OFFSET && reg_be[3], + reg_wdata[25]); + reg2hw_d.software_reset.software_reset_for_dat_line.q = w1s_next( + reg2hw_q.software_reset.software_reset_for_dat_line.q, + hw2reg.software_reset.software_reset_for_dat_line.d, + hw2reg.software_reset.software_reset_for_dat_line.de, + accepted && reg_we && reg_addr == SDHCI_SOFTWARE_RESET_OFFSET && reg_be[3], + reg_wdata[26]); + + reg2hw_d.normal_interrupt_status.command_complete.q = w1c_next( + reg2hw_q.normal_interrupt_status.command_complete.q, + hw2reg.normal_interrupt_status.command_complete.d, + hw2reg.normal_interrupt_status.command_complete.de, + accepted && reg_we && reg_addr == SDHCI_NORMAL_INTERRUPT_STATUS_OFFSET && reg_be[0], + reg_wdata[0]); + reg2hw_d.normal_interrupt_status.transfer_complete.q = w1c_next( + reg2hw_q.normal_interrupt_status.transfer_complete.q, + hw2reg.normal_interrupt_status.transfer_complete.d, + hw2reg.normal_interrupt_status.transfer_complete.de, + accepted && reg_we && reg_addr == SDHCI_NORMAL_INTERRUPT_STATUS_OFFSET && reg_be[0], + reg_wdata[1]); + reg2hw_d.normal_interrupt_status.buffer_write_ready.q = w1c_next( + reg2hw_q.normal_interrupt_status.buffer_write_ready.q, + hw2reg.normal_interrupt_status.buffer_write_ready.d, + hw2reg.normal_interrupt_status.buffer_write_ready.de, + accepted && reg_we && reg_addr == SDHCI_NORMAL_INTERRUPT_STATUS_OFFSET && reg_be[0], + reg_wdata[4]); + reg2hw_d.normal_interrupt_status.buffer_read_ready.q = w1c_next( + reg2hw_q.normal_interrupt_status.buffer_read_ready.q, + hw2reg.normal_interrupt_status.buffer_read_ready.d, + hw2reg.normal_interrupt_status.buffer_read_ready.de, + accepted && reg_we && reg_addr == SDHCI_NORMAL_INTERRUPT_STATUS_OFFSET && reg_be[0], + reg_wdata[5]); + reg2hw_d.normal_interrupt_status.card_insertion.q = w1c_next( + reg2hw_q.normal_interrupt_status.card_insertion.q, + hw2reg.normal_interrupt_status.card_insertion.d, + hw2reg.normal_interrupt_status.card_insertion.de, + accepted && reg_we && reg_addr == SDHCI_NORMAL_INTERRUPT_STATUS_OFFSET && reg_be[0], + reg_wdata[6]); + reg2hw_d.normal_interrupt_status.card_removal.q = w1c_next( + reg2hw_q.normal_interrupt_status.card_removal.q, + hw2reg.normal_interrupt_status.card_removal.d, + hw2reg.normal_interrupt_status.card_removal.de, + accepted && reg_we && reg_addr == SDHCI_NORMAL_INTERRUPT_STATUS_OFFSET && reg_be[0], + reg_wdata[7]); + reg2hw_d.normal_interrupt_status.error_interrupt.q = w1c_next( + reg2hw_q.normal_interrupt_status.error_interrupt.q, + hw2reg.normal_interrupt_status.error_interrupt.d, + hw2reg.normal_interrupt_status.error_interrupt.de, + accepted && reg_we && reg_addr == SDHCI_NORMAL_INTERRUPT_STATUS_OFFSET && reg_be[1], + reg_wdata[15]); + + reg2hw_d.error_interrupt_status.command_timeout_error.q = w1c_next( + reg2hw_q.error_interrupt_status.command_timeout_error.q, + hw2reg.error_interrupt_status.command_timeout_error.d, + hw2reg.error_interrupt_status.command_timeout_error.de, + accepted && reg_we && reg_addr == SDHCI_NORMAL_INTERRUPT_STATUS_OFFSET && reg_be[2], + reg_wdata[16]); + reg2hw_d.error_interrupt_status.command_crc_error.q = w1c_next( + reg2hw_q.error_interrupt_status.command_crc_error.q, + hw2reg.error_interrupt_status.command_crc_error.d, + hw2reg.error_interrupt_status.command_crc_error.de, + accepted && reg_we && reg_addr == SDHCI_NORMAL_INTERRUPT_STATUS_OFFSET && reg_be[2], + reg_wdata[17]); + reg2hw_d.error_interrupt_status.command_end_bit_error.q = w1c_next( + reg2hw_q.error_interrupt_status.command_end_bit_error.q, + hw2reg.error_interrupt_status.command_end_bit_error.d, + hw2reg.error_interrupt_status.command_end_bit_error.de, + accepted && reg_we && reg_addr == SDHCI_NORMAL_INTERRUPT_STATUS_OFFSET && reg_be[2], + reg_wdata[18]); + reg2hw_d.error_interrupt_status.command_index_error.q = w1c_next( + reg2hw_q.error_interrupt_status.command_index_error.q, + hw2reg.error_interrupt_status.command_index_error.d, + hw2reg.error_interrupt_status.command_index_error.de, + accepted && reg_we && reg_addr == SDHCI_NORMAL_INTERRUPT_STATUS_OFFSET && reg_be[2], + reg_wdata[19]); + reg2hw_d.error_interrupt_status.data_timeout_error.q = w1c_next( + reg2hw_q.error_interrupt_status.data_timeout_error.q, + hw2reg.error_interrupt_status.data_timeout_error.d, + hw2reg.error_interrupt_status.data_timeout_error.de, + accepted && reg_we && reg_addr == SDHCI_NORMAL_INTERRUPT_STATUS_OFFSET && reg_be[2], + reg_wdata[20]); + reg2hw_d.error_interrupt_status.data_crc_error.q = w1c_next( + reg2hw_q.error_interrupt_status.data_crc_error.q, + hw2reg.error_interrupt_status.data_crc_error.d, + hw2reg.error_interrupt_status.data_crc_error.de, + accepted && reg_we && reg_addr == SDHCI_NORMAL_INTERRUPT_STATUS_OFFSET && reg_be[2], + reg_wdata[21]); + reg2hw_d.error_interrupt_status.data_end_bit_error.q = w1c_next( + reg2hw_q.error_interrupt_status.data_end_bit_error.q, + hw2reg.error_interrupt_status.data_end_bit_error.d, + hw2reg.error_interrupt_status.data_end_bit_error.de, + accepted && reg_we && reg_addr == SDHCI_NORMAL_INTERRUPT_STATUS_OFFSET && reg_be[2], + reg_wdata[22]); + reg2hw_d.error_interrupt_status.auto_cmd12_error.q = w1c_next( + reg2hw_q.error_interrupt_status.auto_cmd12_error.q, + hw2reg.error_interrupt_status.auto_cmd12_error.d, + hw2reg.error_interrupt_status.auto_cmd12_error.de, + accepted && reg_we && reg_addr == SDHCI_NORMAL_INTERRUPT_STATUS_OFFSET && reg_be[3], + reg_wdata[24]); + + if (hw2reg.auto_cmd12_error_status.auto_cmd12_not_executed.de) begin + reg2hw_d.auto_cmd12_error_status.auto_cmd12_not_executed.q = + hw2reg.auto_cmd12_error_status.auto_cmd12_not_executed.d; + end + if (hw2reg.auto_cmd12_error_status.auto_cmd12_timeout_error.de) begin + reg2hw_d.auto_cmd12_error_status.auto_cmd12_timeout_error.q = + hw2reg.auto_cmd12_error_status.auto_cmd12_timeout_error.d; + end + if (hw2reg.auto_cmd12_error_status.auto_cmd12_crc_error.de) begin + reg2hw_d.auto_cmd12_error_status.auto_cmd12_crc_error.q = + hw2reg.auto_cmd12_error_status.auto_cmd12_crc_error.d; + end + if (hw2reg.auto_cmd12_error_status.auto_cmd12_end_bit_error.de) begin + reg2hw_d.auto_cmd12_error_status.auto_cmd12_end_bit_error.q = + hw2reg.auto_cmd12_error_status.auto_cmd12_end_bit_error.d; + end + if (hw2reg.auto_cmd12_error_status.auto_cmd12_index_error.de) begin + reg2hw_d.auto_cmd12_error_status.auto_cmd12_index_error.q = + hw2reg.auto_cmd12_error_status.auto_cmd12_index_error.d; + end + if (hw2reg.auto_cmd12_error_status.command_not_issued_by_auto_cmd12_error.de) begin + reg2hw_d.auto_cmd12_error_status.command_not_issued_by_auto_cmd12_error.q = + hw2reg.auto_cmd12_error_status.command_not_issued_by_auto_cmd12_error.d; + end + + if (accepted && reg_we) begin + unique case (reg_addr) + SDHCI_BLOCK_SIZE_OFFSET: begin + reg2hw_d.block_size.transfer_block_size.q = reg_wdata[11:0]; + reg2hw_d.block_size.transfer_block_size.qe = |(reg_be & 4'b0011); + reg2hw_d.block_size.host_dma_buffer_boundary.q = reg_wdata[14:12]; + reg2hw_d.block_size.host_dma_buffer_boundary.qe = reg_be[1]; + reg2hw_d.block_count.q = reg_wdata[31:16]; + reg2hw_d.block_count.qe = |(reg_be & 4'b1100); + end + + SDHCI_ARGUMENT_OFFSET: begin + if (reg_be[0]) reg2hw_d.argument.q[7:0] = reg_wdata[7:0]; + if (reg_be[1]) reg2hw_d.argument.q[15:8] = reg_wdata[15:8]; + if (reg_be[2]) reg2hw_d.argument.q[23:16] = reg_wdata[23:16]; + if (reg_be[3]) reg2hw_d.argument.q[31:24] = reg_wdata[31:24]; + end + + SDHCI_TRANSFER_MODE_OFFSET: begin + if (reg_be[0]) begin + reg2hw_d.transfer_mode.block_count_enable.q = reg_wdata[1]; + reg2hw_d.transfer_mode.auto_cmd12_enable.q = reg_wdata[2]; + reg2hw_d.transfer_mode.data_transfer_direction_select.q = reg_wdata[4]; + reg2hw_d.transfer_mode.multi_single_block_select.q = reg_wdata[5]; + reg2hw_d.transfer_mode.block_count_enable.qe = 1'b1; + reg2hw_d.transfer_mode.auto_cmd12_enable.qe = 1'b1; + reg2hw_d.transfer_mode.data_transfer_direction_select.qe = 1'b1; + reg2hw_d.transfer_mode.multi_single_block_select.qe = 1'b1; + end + if (reg_be[2]) begin + reg2hw_d.command.response_type_select.q = reg_wdata[17:16]; + reg2hw_d.command.command_crc_check_enable.q = reg_wdata[19]; + reg2hw_d.command.command_index_check_enable.q = reg_wdata[20]; + reg2hw_d.command.data_present_select.q = reg_wdata[21]; + reg2hw_d.command.command_type.q = reg_wdata[23:22]; + reg2hw_d.command.response_type_select.qe = 1'b1; + reg2hw_d.command.command_crc_check_enable.qe = 1'b1; + reg2hw_d.command.command_index_check_enable.qe = 1'b1; + reg2hw_d.command.data_present_select.qe = 1'b1; + reg2hw_d.command.command_type.qe = 1'b1; + end + if (reg_be[3]) begin + reg2hw_d.command.command_index.q = reg_wdata[29:24]; + reg2hw_d.command.command_index.qe = 1'b1; + end + end + + SDHCI_BUFFER_DATA_PORT_OFFSET: begin + reg2hw_d.buffer_data_port.q = reg_wdata; + reg2hw_d.buffer_data_port.qe = 1'b1; + end + + SDHCI_HOST_CONTROL_OFFSET: begin + if (reg_be[0]) begin + reg2hw_d.host_control.data_transfer_width.q = reg_wdata[1]; + end + end + + SDHCI_CLOCK_CONTROL_OFFSET: begin + if (reg_be[0]) begin + reg2hw_d.clock_control.internal_clock_enable.q = reg_wdata[0]; + reg2hw_d.clock_control.sd_clock_enable.q = reg_wdata[2]; + reg2hw_d.clock_control.internal_clock_enable.qe = 1'b1; + reg2hw_d.clock_control.sd_clock_enable.qe = 1'b1; + end + if (reg_be[1]) begin + reg2hw_d.clock_control.sdclk_frequency_select.q = reg_wdata[15:8]; + reg2hw_d.clock_control.sdclk_frequency_select.qe = 1'b1; + end + if (reg_be[2]) begin + reg2hw_d.timeout_control.data_timeout_counter_value.q = reg_wdata[19:16]; + end + end + + SDHCI_NORMAL_INTERRUPT_STATUS_ENABLE_OFFSET: begin + if (reg_be[0]) begin + reg2hw_d.normal_interrupt_status_enable.command_complete_status_enable.q = reg_wdata[0]; + reg2hw_d.normal_interrupt_status_enable.transfer_complete_status_enable.q = reg_wdata[1]; + reg2hw_d.normal_interrupt_status_enable.buffer_write_ready_status_enable.q = reg_wdata[4]; + reg2hw_d.normal_interrupt_status_enable.buffer_read_ready_status_enable.q = reg_wdata[5]; + reg2hw_d.normal_interrupt_status_enable.card_insertion_status_enable.q = reg_wdata[6]; + reg2hw_d.normal_interrupt_status_enable.card_removal_status_enable.q = reg_wdata[7]; + end + if (reg_be[1]) begin + reg2hw_d.normal_interrupt_status_enable.card_interrupt_status_enable.q = reg_wdata[8]; + end + if (reg_be[2]) begin + reg2hw_d.error_interrupt_status_enable.command_timeout_error_status_enable.q = + reg_wdata[16]; + reg2hw_d.error_interrupt_status_enable.command_crc_error_status_enable.q = + reg_wdata[17]; + reg2hw_d.error_interrupt_status_enable.command_end_bit_error_status_enable.q = + reg_wdata[18]; + reg2hw_d.error_interrupt_status_enable.command_index_error_status_enable.q = + reg_wdata[19]; + reg2hw_d.error_interrupt_status_enable.data_timeout_error_status_enable.q = + reg_wdata[20]; + reg2hw_d.error_interrupt_status_enable.data_crc_error_status_enable.q = + reg_wdata[21]; + reg2hw_d.error_interrupt_status_enable.data_end_bit_error_status_enable.q = + reg_wdata[22]; + end + if (reg_be[3]) begin + reg2hw_d.error_interrupt_status_enable.auto_cmd12_error_status_enable.q = + reg_wdata[24]; + end + end + + SDHCI_NORMAL_INTERRUPT_SIGNAL_ENABLE_OFFSET: begin + if (reg_be[0]) begin + reg2hw_d.normal_interrupt_signal_enable.command_complete_signal_enable.q = reg_wdata[0]; + reg2hw_d.normal_interrupt_signal_enable.transfer_complete_signal_enable.q = reg_wdata[1]; + reg2hw_d.normal_interrupt_signal_enable.buffer_write_ready_signal_enable.q = reg_wdata[4]; + reg2hw_d.normal_interrupt_signal_enable.buffer_read_ready_signal_enable.q = reg_wdata[5]; + reg2hw_d.normal_interrupt_signal_enable.card_insertion_signal_enable.q = reg_wdata[6]; + reg2hw_d.normal_interrupt_signal_enable.card_removal_signal_enable.q = reg_wdata[7]; + end + if (reg_be[1]) begin + reg2hw_d.normal_interrupt_signal_enable.card_interrupt_signal_enable.q = reg_wdata[8]; + end + if (reg_be[2]) begin + reg2hw_d.error_interrupt_signal_enable.command_timeout_error_signal_enable.q = + reg_wdata[16]; + reg2hw_d.error_interrupt_signal_enable.command_crc_error_signal_enable.q = + reg_wdata[17]; + reg2hw_d.error_interrupt_signal_enable.command_end_bit_error_signal_enable.q = + reg_wdata[18]; + reg2hw_d.error_interrupt_signal_enable.command_index_error_signal_enable.q = + reg_wdata[19]; + reg2hw_d.error_interrupt_signal_enable.data_timeout_error_signal_enable.q = + reg_wdata[20]; + reg2hw_d.error_interrupt_signal_enable.data_crc_error_signal_enable.q = + reg_wdata[21]; + reg2hw_d.error_interrupt_signal_enable.data_end_bit_error_signal_enable.q = + reg_wdata[22]; + end + if (reg_be[3]) begin + reg2hw_d.error_interrupt_signal_enable.auto_cmd12_error_signal_enable.q = + reg_wdata[24]; + end + end + + default: ; + endcase + end + + if (accepted && reg_re && reg_addr == SDHCI_BUFFER_DATA_PORT_OFFSET) begin + reg2hw_d.buffer_data_port.re = 1'b1; end + end - if (addr_hit[29]) begin - reg_rdata_next[31:0] = maximum_current_capabilities_reserved_qs; - end + always_comb begin + reg2hw_o = reg2hw_q; + + reg2hw_o.block_size.transfer_block_size.q = reg2hw_d.block_size.transfer_block_size.q; + reg2hw_o.block_size.transfer_block_size.qe = reg2hw_d.block_size.transfer_block_size.qe; + reg2hw_o.block_size.host_dma_buffer_boundary.q = reg2hw_d.block_size.host_dma_buffer_boundary.q; + reg2hw_o.block_size.host_dma_buffer_boundary.qe = + reg2hw_d.block_size.host_dma_buffer_boundary.qe; + reg2hw_o.block_count.q = reg2hw_d.block_count.q; + reg2hw_o.block_count.qe = reg2hw_d.block_count.qe; + + reg2hw_o.transfer_mode.block_count_enable.q = + reg2hw_d.transfer_mode.block_count_enable.q; + reg2hw_o.transfer_mode.block_count_enable.qe = + reg2hw_d.transfer_mode.block_count_enable.qe; + reg2hw_o.transfer_mode.auto_cmd12_enable.q = + reg2hw_d.transfer_mode.auto_cmd12_enable.q; + reg2hw_o.transfer_mode.auto_cmd12_enable.qe = + reg2hw_d.transfer_mode.auto_cmd12_enable.qe; + reg2hw_o.transfer_mode.data_transfer_direction_select.q = + reg2hw_d.transfer_mode.data_transfer_direction_select.q; + reg2hw_o.transfer_mode.data_transfer_direction_select.qe = + reg2hw_d.transfer_mode.data_transfer_direction_select.qe; + reg2hw_o.transfer_mode.multi_single_block_select.q = + reg2hw_d.transfer_mode.multi_single_block_select.q; + reg2hw_o.transfer_mode.multi_single_block_select.qe = + reg2hw_d.transfer_mode.multi_single_block_select.qe; + + reg2hw_o.buffer_data_port.q = reg2hw_d.buffer_data_port.q; + reg2hw_o.buffer_data_port.qe = reg2hw_d.buffer_data_port.qe; + reg2hw_o.buffer_data_port.re = reg2hw_d.buffer_data_port.re; + end - if (addr_hit[30]) begin - reg_rdata_next[7:0] = slot_interrupt_status_interrupt_signal_for_each_slot_qs; - reg_rdata_next[15:8] = slot_interrupt_status_rsvd_8_qs; - end + assign reg2hw = reg2hw_o; - if (addr_hit[31]) begin - reg_rdata_next[23:16] = host_controller_version_specification_version_number_qs; - reg_rdata_next[31:24] = host_controller_version_vendor_version_number_qs; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + reg2hw_q <= '0; + reg2hw_q.clock_control.internal_clock_stable.q <= 1'b1; + end else if (clear_i) begin + reg2hw_q <= '0; + reg2hw_q.clock_control.internal_clock_stable.q <= 1'b1; + end else begin + reg2hw_q <= reg2hw_d; end - end - // Unused signal tieoff - - // wdata / byte enable are not always fully used - // add a blanket unused statement to handle lint waivers - logic unused_wdata; - logic unused_be; - assign unused_wdata = ^reg_wdata; - assign unused_be = ^reg_be; - - // Assertions for Register Interface endmodule -module sdhci_reg_top_intf -#( +module sdhci_reg_top_intf #( parameter int AW = 8, + parameter int unsigned BufferNumWords = 256, + parameter bit AllowNoncompliantBufferSizes = 1'b0, localparam int DW = 32 ) ( - input logic clk_i, - input logic rst_ni, - REG_BUS.in regbus_slave, - // To HW - output sdhci_reg_pkg::sdhci_reg2hw_t reg2hw, // Write - input sdhci_reg_pkg::sdhci_hw2reg_t hw2reg, // Read - // Config - input devmode_i // If 1, explicit error return for unmapped register access + input logic clk_i, + input logic rst_ni, + REG_BUS.in regbus_slave, + + output sdhci_reg_pkg::sdhci_reg2hw_t reg2hw, + input sdhci_reg_pkg::sdhci_hw2reg_t hw2reg, + input logic clear_i, + input logic buffer_data_port_read_ready_i, + input logic buffer_data_port_write_ready_i, + + input devmode_i ); - localparam int unsigned STRB_WIDTH = DW/8; + + localparam int unsigned STRB_WIDTH = DW / 8; `include "register_interface/typedef.svh" `include "register_interface/assign.svh" - // Define structs for reg_bus typedef logic [AW-1:0] addr_t; typedef logic [DW-1:0] data_t; typedef logic [STRB_WIDTH-1:0] strb_t; @@ -4427,27 +760,27 @@ module sdhci_reg_top_intf reg_bus_req_t s_reg_req; reg_bus_rsp_t s_reg_rsp; - - // Assign SV interface to structs + `REG_BUS_ASSIGN_TO_REQ(s_reg_req, regbus_slave) `REG_BUS_ASSIGN_FROM_RSP(regbus_slave, s_reg_rsp) - - sdhci_reg_top #( .reg_req_t(reg_bus_req_t), .reg_rsp_t(reg_bus_rsp_t), - .AW(AW) + .AW(AW), + .BufferNumWords(BufferNumWords), + .AllowNoncompliantBufferSizes(AllowNoncompliantBufferSizes) ) i_regs ( .clk_i, .rst_ni, .reg_req_i(s_reg_req), .reg_rsp_o(s_reg_rsp), - .reg2hw, // Write - .hw2reg, // Read + .reg2hw, + .hw2reg, + .clear_i, + .buffer_data_port_read_ready_i, + .buffer_data_port_write_ready_i, .devmode_i ); - -endmodule - +endmodule diff --git a/hw/reg/sdhci_regs.hjson b/hw/reg/sdhci_regs.hjson deleted file mode 100644 index 25c7795..0000000 --- a/hw/reg/sdhci_regs.hjson +++ /dev/null @@ -1,1371 +0,0 @@ -// Copyright 2025 ETH Zurich and University of Bologna. -// Solderpad Hardware License, Version 0.51, see LICENSE for details. -// SPDX-License-Identifier: SHL-0.51 - -// Authors: -// - Micha Wehrli -// - Anton Buchner - -{ - #"human_name": SD Host Controller ver1.00 Registers - name: "sdhci" - clock_primary: "clk_i" - reset_primary: "rst_ni" - bus_interfaces: [ - { - protocol: "reg_iface" - direction: "device" - } - ] - regwidth: 32 - interrupt_list: [] - registers: [ - { - name: "system_address" - desc: "" - hwaccess: "none" - fields: [ - { - bits: "31:0" - name: "dma_system_address" - desc: "" - swaccess: "rw" - } - ] - } - { - packed: [ - { - name: "block_size" - desc: "" - hwaccess: "hrw" - hwqe: true - hwext: true - fields: [ - { - bits: "15" - name: "rsvd_15" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "14:12" - name: "host_dma_buffer_boundary" - desc: "" - swaccess: "rw" - } - { - bits: "11:0" - name: "transfer_block_size" - desc: "" - swaccess: "rw" - } - ] - } - { - name: "block_count" - desc: "" - hwaccess: "hrw" - hwqe: true - hwext: true - fields: [ - { - bits: "15:0" - name: "blocks_count_for_current_transfer" - desc: "" - swaccess: "rw" - } - ] - } - ] - } - { - name: "argument" - desc: "" - hwaccess: "hro" - fields: [ - { - bits: "31:0" - name: "command_argument" - desc: "" - swaccess: "rw" - } - ] - } - { - packed: [ - { - name: "transfer_mode" - desc: "" - hwaccess: "hrw" - hwqe: true - hwext: true - fields: [ - { - bits: "15:8" - name: "rsvd_8" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "7:6" - name: "rsvd_6" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "5" - name: "multi_single_block_select" - desc: "" - swaccess: "rw" - } - { - bits: "4" - name: "data_transfer_direction_select" - desc: "" - swaccess: "rw" - } - { - bits: "3" - name: "rsvd_3" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "2" - name: "auto_cmd12_enable" - desc: "" - swaccess: "rw" - } - { - bits: "1" - name: "block_count_enable" - desc: "" - swaccess: "rw" - } - { - bits: "0" - name: "dma_enable" - desc: "" - swaccess: "rw" - } - ] - } - { - name: "command" - desc: "" - hwaccess: "hro" - hwqe: true - fields: [ - { - bits: "15:14" - name: "rsvd_14" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "13:8" - name: "command_index" - desc: "" - swaccess: "rw" - } - { - bits: "7:6" - name: "command_type" - desc: "" - swaccess: "rw" - } - { - bits: "5" - name: "data_present_select" - desc: "" - swaccess: "rw" - } - { - bits: "4" - name: "command_index_check_enable" - desc: "" - swaccess: "rw" - } - { - bits: "3" - name: "command_crc_check_enable" - desc: "" - swaccess: "rw" - } - { - bits: "2" - name: "rsvd_2" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "1:0" - name: "response_type_select" - desc: "" - swaccess: "rw" - } - ] - } - ] - } - { - name: "response0" - desc: "" - hwaccess: "hrw" - // "hwqe": true - fields: [ - { - bits: "31:0" - name: "response" - desc: "" - swaccess: "ro" - resval: "0" - } - ] - } - { - name: "response1" - desc: "" - hwaccess: "hrw" - fields: [ - { - bits: "31:0" - name: "response" - desc: "" - swaccess: "ro" - resval: "0" - } - ] - } - { - name: "response2" - desc: "" - hwaccess: "hrw" - fields: [ - { - bits: "31:0" - name: "response" - desc: "" - swaccess: "ro" - resval: "0" - } - ] - } - { - name: "response3" - desc: "" - hwaccess: "hrw" - fields: [ - { - bits: "31:0" - name: "response" - desc: "" - swaccess: "ro" - resval: "0" - } - ] - } - { - name: "buffer_data_port" - desc: "" - hwext: true - hwqe: true - hwre: true - swaccess: "rw" - hwaccess: "hrw" - fields: [ - { - bits: "31:0" - name: "buffer_data" - desc: "" - } - ] - } - { - name: "present_state" - desc: "" - swaccess: "ro" - hwaccess: "hrw" - fields: [ - { - bits: "15:12" - name: "rsvd_12" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "11" - name: "buffer_read_enable" - desc: "" - resval: "0" - } - { - bits: "10" - name: "buffer_write_enable" - desc: "" - resval: "0" - } - { - bits: "9" - name: "read_transfer_active" - desc: "" - resval: "0" - } - { - bits: "8" - name: "write_transfer_active" - desc: "" - resval: "0" - } - { - bits: "7:3" - name: "rsvd_3" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "2" - name: "dat_line_active" - desc: "" - resval: "0" - } - { - bits: "1" - name: "command_inhibit_dat" - desc: "" - resval: "0" - } - { - bits: "0" - name: "command_inhibit_cmd" - desc: "" - resval: "0" - } - { - bits: "31:25" - name: "rsvd_25" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "24" - name: "cmd_line_signal_level" - desc: "" - resval: "0" - } - { - bits: "23:20" - name: "dat_line_signal_level" - desc: "" - resval: "0" - } - { - bits: "19" - name: "write_protect_switch_pin_level" - desc: "" - resval: "0" - } - { - bits: "18" - name: "card_detect_pin_level" - desc: "" - resval: "0" - } - { - bits: "17" - name: "card_state_stable" - desc: "" - resval: "0" - } - { - bits: "16" - name: "card_inserted" - desc: "" - resval: "0" - } - ] - } - { - packed: [ - { - name: "host_control" - desc: "" - swaccess: "rw" - hwaccess: "hro" - fields: [ - { - bits: "7:3" - name: "rsvd_3" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "2" - name: "high_speed_enable" - desc: "" - } - { - bits: "1" - name: "data_transfer_width" - desc: "" - resval: "0" - } - { - bits: "0" - name: "led_control" - desc: "" - } - ] - } - { - name: "power_control" - desc: "" - swaccess: "rw" - hwaccess: "hro" - fields: [ - { - bits: "7:4" - name: "rsvd_4" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "3:1" - name: "sd_bus_voltage_select" - desc: "" - } - { - bits: "0" - name: "sd_bus_power" - desc: "" - } - ] - } - { - name: "block_gap_control" - desc: "" - hwaccess: "hro" - fields: [ - { - bits: "7:4" - name: "rsvd_4" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "3" - name: "interrupt_at_block_gap" - desc: "" - swaccess: "rw" - } - { - bits: "2" - name: "read_wait_control" - desc: "" - swaccess: "rw" - } - { - bits: "1" - name: "continue_request" - desc: "" - swaccess: "rw1s" - } - { - bits: "0" - name: "stop_at_block_gap_request" - desc: "" - swaccess: "rw" - } - ] - } - { - name: "wakeup_control" - desc: "" - swaccess: "rw" - hwaccess: "hro" - fields: [ - { - bits: "7:3" - name: "rsvd_3" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "2" - name: "wakeup_event_enable_on_sd_card_removal" - desc: "" - swaccess: "rw" - } - { - bits: "1" - name: "wakeup_event_enable_on_sd_card_insertion" - desc: "" - swaccess: "rw" - } - { - bits: "0" - name: "wakeup_event_enable_on_card_interrupt" - desc: "" - swaccess: "rw" - } - ] - } - ] - } - { - packed: [ - { - name: "clock_control" - desc: "" - hwaccess: "hro" - hwqe: true - fields: [ - { - bits: "15:8" - name: "sdclk_frequency_select" - desc: "" - swaccess: "rw" - } - { - bits: "7:3" - name: "rsvd_3" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "2" - name: "sd_clock_enable" - desc: "" - swaccess: "rw" - } - { - bits: "1" - name: "internal_clock_stable" - desc: "" - swaccess: "ro" - hwaccess: "hrw" - resval: "1" - } - { - bits: "0" - name: "internal_clock_enable" - desc: "" - swaccess: "rw" - } - ] - } - { - name: "timeout_control" - desc: "" - hwaccess: "hro" - fields: [ - { - bits: "7:4" - name: "rsvd_4" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "3:0" - name: "data_timeout_counter_value" - desc: "" - swaccess: "rw" - } - ] - } - { - name: "software_reset" - desc: "" - hwaccess: "hrw" - resval: "0" - fields: [ - { - bits: "7:4" - name: "rsvd_4" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "2" - name: "software_reset_for_dat_line" - desc: "" - swaccess: "rw1s" - } - { - bits: "1" - name: "software_reset_for_cmd_line" - desc: "" - swaccess: "rw1s" - } - { - bits: "0" - name: "software_reset_for_all" - desc: "" - swaccess: "rw1s" - hwaccess: "hro" - } - ] - } - ] - } - { - packed: [ - { - name: "normal_interrupt_status" - desc: "" - hwaccess: "hrw" - fields: [ - { - bits: "15" - name: "error_interrupt" - desc: "" - swaccess: "ro" - resval: "0" - } - { - bits: "14:9" - name: "rsvd_9" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "8" - name: "card_interrupt" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "7" - name: "card_removal" - desc: "" - swaccess: "rw1c" - } - { - bits: "6" - name: "card_insertion" - desc: "" - swaccess: "rw1c" - } - { - bits: "5" - name: "buffer_read_ready" - desc: "" - swaccess: "rw1c" - } - { - bits: "4" - name: "buffer_write_ready" - desc: "" - swaccess: "rw1c" - } - { - // DMA not currently supported - bits: "3" - name: "dma_interrupt" - desc: "" - swaccess: "rw1c" - hwaccess: "none" - resval: "0" - } - { - // DMA not currently supported - bits: "2" - name: "block_gap_event" - desc: "" - swaccess: "rw1c" - hwaccess: "none" - resval: "0" - } - { - bits: "1" - name: "transfer_complete" - desc: "" - swaccess: "rw1c" - } - { - bits: "0" - name: "command_complete" - desc: "" - swaccess: "rw1c" - } - ] - } - { - name: "error_interrupt_status" - desc: "" - swaccess: "rw1c" - hwaccess: "hrw" - fields: [ - { - bits: "15:12" - name: "vendor_specific_error" - hwaccess: "none" - resval: "0" - desc: "" - } - { - bits: "11:9" - name: "rsvd_9" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "8" - name: "auto_cmd12_error" - resval: "0" - desc: "" - } - { - bits: "7" - name: "current_limit_error" - hwaccess: "none" - resval: "0" - desc: "" - } - { - bits: "6" - name: "data_end_bit_error" - desc: "" - } - { - bits: "5" - name: "data_crc_error" - desc: "" - } - { - bits: "4" - name: "data_timeout_error" - desc: "" - } - { - bits: "3" - name: "command_index_error" - desc: "" - } - { - bits: "2" - name: "command_end_bit_error" - desc: "" - } - { - bits: "1" - name: "command_crc_error" - desc: "" - } - { - bits: "0" - name: "command_timeout_error" - desc: "" - } - ] - } - ] - } - { - packed: [ - { - name: "normal_interrupt_status_enable" - desc: "" - hwaccess: "hro" - fields: [ - { - bits: "15" - name: "fixed_to_0" - desc: "" - swaccess: "ro" - resval: "0" - } - { - bits: "14:9" - name: "rsvd_9" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "8" - name: "card_interrupt_status_enable" - desc: "" - swaccess: "rw" - } - { - bits: "7" - name: "card_removal_status_enable" - desc: "" - swaccess: "rw" - } - { - bits: "6" - name: "card_insertion_status_enable" - desc: "" - swaccess: "rw" - } - { - bits: "5" - name: "buffer_read_ready_status_enable" - desc: "" - swaccess: "rw" - } - { - bits: "4" - name: "buffer_write_ready_status_enable" - desc: "" - swaccess: "rw" - } - { - bits: "3" - name: "dma_interrupt_status_enable" - desc: "" - swaccess: "rw" - } - { - bits: "2" - name: "block_gap_event_status_enable" - desc: "" - swaccess: "rw" - } - { - bits: "1" - name: "transfer_complete_status_enable" - desc: "" - swaccess: "rw" - } - { - bits: "0" - name: "command_complete_status_enable" - desc: "" - swaccess: "rw" - } - ] - } - { - name: "error_interrupt_status_enable" - desc: "" - swaccess: "rw" - hwaccess: "hro" - fields: [ - { - bits: "15:12" - name: "vendor_specific_error_status_enable" - desc: "" - } - { - bits: "11:9" - name: "rsvd_9" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "8" - name: "auto_cmd12_error_status_enable" - desc: "" - } - { - bits: "7" - name: "current_limit_error_status_enable" - desc: "" - } - { - bits: "6" - name: "data_end_bit_error_status_enable" - desc: "" - } - { - bits: "5" - name: "data_crc_error_status_enable" - desc: "" - } - { - bits: "4" - name: "data_timeout_error_status_enable" - desc: "" - } - { - bits: "3" - name: "command_index_error_status_enable" - desc: "" - } - { - bits: "2" - name: "command_end_bit_error_status_enable" - desc: "" - } - { - bits: "1" - name: "command_crc_error_status_enable" - desc: "" - } - { - bits: "0" - name: "command_timeout_error_status_enable" - desc: "" - } - ] - } - ] - } - { - packed: [ - { - name: "normal_interrupt_signal_enable" - desc: "" - hwaccess: "hro" - fields: [ - { - bits: "15" - name: "fixed_to_0" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "14:9" - name: "rsvd_9" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "8" - name: "card_interrupt_signal_enable" - desc: "" - swaccess: "rw" - } - { - bits: "7" - name: "card_removal_signal_enable" - desc: "" - swaccess: "rw" - } - { - bits: "6" - name: "card_insertion_signal_enable" - desc: "" - swaccess: "rw" - } - { - bits: "5" - name: "buffer_read_ready_signal_enable" - desc: "" - swaccess: "rw" - } - { - bits: "4" - name: "buffer_write_ready_signal_enable" - desc: "" - swaccess: "rw" - } - { - bits: "3" - name: "dma_interrupt_signal_enable" - desc: "" - swaccess: "rw" - } - { - bits: "2" - name: "block_gap_event_signal_enable" - desc: "" - swaccess: "rw" - } - { - bits: "1" - name: "transfer_complete_signal_enable" - desc: "" - swaccess: "rw" - } - { - bits: "0" - name: "command_complete_signal_enable" - desc: "" - swaccess: "rw" - } - ] - } - { - name: "error_interrupt_signal_enable" - desc: "" - swaccess: "rw" - hwaccess: "hro" - fields: [ - { - bits: "15:12" - name: "vendor_specific_error_signal_enable" - desc: "" - } - { - bits: "11:9" - name: "rsvd_9" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "8" - name: "auto_cmd12_error_signal_enable" - desc: "" - } - { - bits: "7" - name: "current_limit_error_signal_enable" - desc: "" - } - { - bits: "6" - name: "data_end_bit_error_signal_enable" - desc: "" - } - { - bits: "5" - name: "data_crc_error_signal_enable" - desc: "" - } - { - bits: "4" - name: "data_timeout_error_signal_enable" - desc: "" - } - { - bits: "3" - name: "command_index_error_signal_enable" - desc: "" - } - { - bits: "2" - name: "command_end_bit_error_signal_enable" - desc: "" - } - { - bits: "1" - name: "command_crc_error_signal_enable" - desc: "" - } - { - bits: "0" - name: "command_timeout_error_signal_enable" - desc: "" - } - ] - } - ] - } - { - name: "auto_cmd12_error_status" - desc: "" - swaccess: "ro" - resval: "0" - hwaccess: "hrw" - fields: [ - { - bits: "15:8" - name: "rsvd_8" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "7" - name: "command_not_issued_by_auto_cmd12_error" - desc: "" - } - { - bits: "6:5" - name: "rsvd_5" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "4" - name: "auto_cmd12_index_error" - desc: "" - } - { - bits: "3" - name: "auto_cmd12_end_bit_error" - desc: "" - } - { - bits: "2" - name: "auto_cmd12_crc_error" - desc: "" - } - { - bits: "1" - name: "auto_cmd12_timeout_error" - desc: "" - } - { - bits: "0" - name: "auto_cmd12_not_executed" - desc: "" - } - ] - } - { - name: "capabilities" - desc: "" - swaccess: "ro" - hwaccess: "none" - fields: [ - { - bits: "31:27" - name: "rsvd_27" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "26" - name: "voltage_support_1_8v" - desc: "" - resval: "0" - } - { - bits: "25" - name: "voltage_support_3_0v" - desc: "" - resval: "0" - } - { - bits: "24" - name: "voltage_support_3_3v" - desc: "" - resval: "1" - } - { - bits: "23" - name: "suspend_resume_support" - desc: "" - resval: "0" - } - { - bits: "22" - name: "dma_support" - desc: "" - resval: "0" - } - { - bits: "21" - name: "high_speed_support" - desc: "" - resval: "0" - } - { - bits: "20:18" - name: "rsvd_18" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "17:16" - name: "max_block_length" - desc: "" - resval: "0b00" // 512 - } - { - bits: "15:14" - name: "rsvd_14" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "13:8" - name: "base_clock_frequency_for_sd_clock" - desc: "" - resval: "50" // TODO: Change to next highest full MHz, max 63. (timeout_clock_frequency too) - } - { - bits: "7" - name: "timeout_clock_unit" - desc: "" - resval: "1" // MHz - } - { - bits: "6" - name: "rsvd_6" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "5:0" - name: "timeout_clock_frequency" - desc: "" - resval: "50" // MHz - } - ] - } - // Capabilities (Reserved) - { - name: "capabilities_reserved" - desc: "" - fields: [ - { - bits: "31:0" - name: "rsvd" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - ] - } - { - name: "maximum_current_capabilities" - desc: "" - swaccess: "ro" - hwaccess: "none" - fields: [ - { - bits: "31:24" - name: "rsvd_24" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "23:16" - name: "maximum_current_for_1_8v" - desc: "" - } - { - bits: "15:8" - name: "maximum_current_for_3_0v" - desc: "" - } - { - bits: "7:0" - name: "maximum_current_for_3_3v" - desc: "" - } - ] - } - // Maximum Current Capabilities (Reserved) - { - name: "maximum_current_capabilities_reserved" - desc: "" - fields: [ - { - bits: "31:0" - name: "rsvd" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - ] - } - - - // Unused - { - reserved: 41 - } - - // Shared Registry Area - { - reserved: 2 - } - { - packed: [ - { - name: "slot_interrupt_status" - desc: "" - swaccess: "ro" - resval: "0" - hwaccess: "hwo" - hwext: true - fields: [ - { - bits: "15:8" - name: "rsvd_8" - desc: "" - swaccess: "ro" - hwaccess: "none" - resval: "0" - } - { - bits: "7:0" - name: "interrupt_signal_for_each_slot" - desc: "" - } - ] - } - { - name: "host_controller_version" - desc: "" - swaccess: "ro" - hwaccess: "none" - fields: [ - { - bits: "15:8" - name: "vendor_version_number" - desc: "" - resval: "0" - } - { - bits: "7:0" - name: "specification_version_number" - desc: "" - resval: "0" - } - ] - } - ] - } - ] -} diff --git a/hw/rsp_read/crc7_read.sv b/hw/rsp_read/crc7_read.sv index 9e4ca5c..349e020 100644 --- a/hw/rsp_read/crc7_read.sv +++ b/hw/rsp_read/crc7_read.sv @@ -15,6 +15,7 @@ module crc7_read ( input logic clk_i, input logic clk_en_i, input logic rst_ni, + input logic clear_i, input logic start_i, //start considering input next clock cycle input logic end_output_i, //stop consider input and output result next cycle @@ -48,7 +49,7 @@ module crc7_read ( endcase end : crc7_state_transition - `FFL(crc_state_q, crc_state_d, clk_en_i, OUTPUT, clk_i, rst_ni); + `FFLARNC(crc_state_q, crc_state_d, clk_en_i, clear_i, OUTPUT, clk_i, rst_ni); /////////////// // Data Path // @@ -56,7 +57,7 @@ module crc7_read ( logic [2:0] lower_3_d, lower_3_q; //lower 3 lsb of crc logic [3:0] upper_4_d, upper_4_q; //upper 4 msb of crc - logic int_rst_n, rst_n, dat_i_xor_out; + logic clear_crc, dat_i_xor_out; assign dat_i_xor_out = (rsp_ser_i ^ upper_4_q[3]); @@ -64,11 +65,11 @@ module crc7_read ( lower_3_d = lower_3_q; upper_4_d = upper_4_q; - int_rst_n = 1'b1; + clear_crc = clear_i; unique case (crc_state_q) - START: int_rst_n = 1'b0; //reset contents to zero + START: clear_crc = 1'b1; // reset contents to zero CALCULATE: begin lower_3_d [2:1] = lower_3_q [1:0]; @@ -81,10 +82,8 @@ module crc7_read ( endcase end : crc7_data_path - assign rst_n = (rst_ni & int_rst_n); //only for data, not for state - - `FFL(lower_3_q, lower_3_d, clk_en_i, 3'b0, clk_i, rst_n); - `FFL(upper_4_q, upper_4_d, clk_en_i, 4'b0, clk_i, rst_n); + `FFLARNC(lower_3_q, lower_3_d, clk_en_i, clear_crc, 3'b0, clk_i, rst_ni); + `FFLARNC(upper_4_q, upper_4_d, clk_en_i, clear_crc, 4'b0, clk_i, rst_ni); //output assignment assign crc7_o[6:3] = upper_4_q; diff --git a/hw/rsp_read/rsp_read.sv b/hw/rsp_read/rsp_read.sv index 7550ed6..86b9406 100644 --- a/hw/rsp_read/rsp_read.sv +++ b/hw/rsp_read/rsp_read.sv @@ -14,6 +14,7 @@ module rsp_read ( input logic clk_i, input logic clk_en_i, input logic rst_ni, + input logic clear_i, input logic cmd_i, input logic long_rsp_i, // high if response is of type R2 (136 bit) @@ -23,7 +24,15 @@ module rsp_read ( output logic receiving_o, // start bit was observed output logic rsp_valid_o, // write response, end_bit_err and crc_corr to register output logic end_bit_err_o, // valid at the same time as response - output logic [119:0] rsp_o, // without start, transmission, reserved, crc and end bits + output logic [31:0] response0_d_o, + output logic [31:0] response1_d_o, + output logic [31:0] response2_d_o, + output logic [31:0] response3_d_o, + output logic response0_de_o, + output logic response1_de_o, + output logic response2_de_o, + output logic response3_de_o, + output logic [5:0] response_index_o, output logic crc_corr_o // active if crc7 was correct, valid when rsp_valid_o is active ); @@ -81,7 +90,7 @@ module rsp_read ( endcase end : rsp_state_transition - `FF(rx_state_q, rx_state_d, INACTIVE, clk_i, rst_ni); + `FFARNC(rx_state_q, rx_state_d, clear_i, INACTIVE, clk_i, rst_ni); /////////////// // Data Path // @@ -94,7 +103,7 @@ module rsp_read ( logic rsp_ser; assign rsp_ser = cmd_i; - logic shift_reg_shift_in_en, shift_reg_par_output_en; + logic capture_response_bit; logic crc_start, crc_end_output; logic [6:0] crc7_calc; @@ -110,8 +119,7 @@ module rsp_read ( always_comb begin : rsp_data_path start_bit_observed = 1'b0; all_bits_received = 1'b0; - shift_reg_shift_in_en = 1'b0; - shift_reg_par_output_en = 1'b0; + capture_response_bit = 1'b0; crc_start = 1'b0; crc_end_output = 1'b0; crc_corr_o = 1'b0; @@ -141,13 +149,12 @@ module rsp_read ( // shift in response. Start and transmission bit are not needed. Index is not needed for long response if (bit_cnt >= shift_start_cnt) begin - shift_reg_shift_in_en = 1'b1; + capture_response_bit = 1'b1; end // all relevant data is in the shift register if (bit_cnt >= shift_done_cnt) begin - shift_reg_shift_in_en = 1'b0; - shift_reg_par_output_en = 1'b1; + capture_response_bit = 1'b0; end // crc calculation is finished. Output crc @@ -161,7 +168,6 @@ module rsp_read ( end FINISHED: begin - shift_reg_par_output_en = 1'b1; rsp_valid_o = 1'b1; receiving_o = 1'b1; @@ -177,23 +183,82 @@ module rsp_read ( // Module Instantiations // /////////////////////////// - ser_par_shift_reg #( - .NumBits (120), // r2 response, start, transmission, reserved, crc and end bits not needed - .MaskOutput (1) // to avoid large number of gates switching during shifting - ) i_rsp_shift_reg ( - .clk_i (clk_i), - .clk_en_i (clk_en_i), - .rst_ni (rst_ni), - .shift_in_en_i (shift_reg_shift_in_en), - .par_output_en_i (shift_reg_par_output_en), - .dat_ser_i (rsp_ser), - .dat_par_o (rsp_o) - ); + logic [31:0] response_word_q, response_word_d; + logic [5:0] response_index_q, response_index_d; + + logic [31:0] response_word_shifted; + logic [5:0] response_index_shifted; + logic capture_short_index; + logic capture_word_bit; + logic response3_complete; + logic response2_complete; + logic response1_complete; + logic response0_complete; + + assign response_word_shifted = {response_word_q[30:0], rsp_ser}; + assign response_index_shifted = {response_index_q[4:0], rsp_ser}; + + assign capture_short_index = !long_rsp_i && capture_response_bit && + bit_cnt >= 8'd1 && bit_cnt <= 8'd6; + assign capture_word_bit = capture_response_bit && !(capture_short_index); + + assign response3_complete = long_rsp_i && bit_cnt == 8'd30; + assign response2_complete = long_rsp_i && bit_cnt == 8'd62; + assign response1_complete = long_rsp_i && bit_cnt == 8'd94; + assign response0_complete = (long_rsp_i && bit_cnt == 8'd126) || + (!long_rsp_i && bit_cnt == 8'd38); + + always_comb begin + response_word_d = response_word_q; + response_index_d = response_index_q; + + response0_d_o = response_word_shifted; + response1_d_o = response_word_shifted; + response2_d_o = response_word_shifted; + response3_d_o = {8'h00, response_word_shifted[23:0]}; + response0_de_o = 1'b0; + response1_de_o = 1'b0; + response2_de_o = 1'b0; + response3_de_o = 1'b0; + + if (rx_state_q != SHIFT_IN) begin + response_word_d = '0; + response_index_d = '0; + end else if (clk_en_i) begin + if (capture_short_index) begin + response_index_d = response_index_shifted; + end + + if (capture_word_bit) begin + response_word_d = response_word_shifted; + + if (response3_complete) begin + response3_de_o = 1'b1; + response_word_d = '0; + end else if (response2_complete) begin + response2_de_o = 1'b1; + response_word_d = '0; + end else if (response1_complete) begin + response1_de_o = 1'b1; + response_word_d = '0; + end else if (response0_complete) begin + response0_de_o = 1'b1; + response_word_d = '0; + end + end + end + end + + assign response_index_o = response_index_q; + + `FFARNC(response_word_q, response_word_d, clear_i, '0, clk_i, rst_ni); + `FFARNC(response_index_q, response_index_d, clear_i, '0, clk_i, rst_ni); crc7_read i_crc7_read ( .clk_i (clk_i), .clk_en_i (clk_en_i), .rst_ni (rst_ni), + .clear_i (clear_i), .start_i (crc_start), .end_output_i (crc_end_output), .rsp_ser_i (rsp_ser), @@ -206,7 +271,7 @@ module rsp_read ( ) i_rsp_counter ( .clk_i (clk_i), .rst_ni (rst_ni), - .clear_i (cnt_clear), + .clear_i (cnt_clear || clear_i), .en_i (cnt_en && clk_en_i), .load_i (1'b0), .down_i (1'b0), diff --git a/hw/sd_clk_generator.sv b/hw/sd_clk_generator.sv index 67135b1..96308a0 100644 --- a/hw/sd_clk_generator.sv +++ b/hw/sd_clk_generator.sv @@ -10,117 +10,137 @@ `include "defines.svh" module sd_clk_generator #( - parameter int unsigned ClkPreDivLog = 0 + parameter int unsigned ClkPreDiv = 2 )( input logic clk_i, input logic rst_ni, + input logic clear_i, input sdhci_reg_pkg::sdhci_reg2hw_t reg2hw_i, input logic pause_sd_clk_i, output logic sd_clk_o, - output logic clk_en_p_o, //high when next rising clk edge coincides with rising sd_clk edge - output logic clk_en_n_o, //high when next rising clk edge coincides with falling sd_clk edge, always high for div by 1 + output logic clk_en_p_o, // high for one clk_i cycle when sd_clk_o rises + output logic clk_en_n_o, // high for one clk_i cycle when sd_clk_o falls - output logic div_1_o, //high if source clock isn't divided, needed for negative edge triggering + output logic div_1_o, // always low; hardware enforces a minimum divide-by-2 SD clock output `writable_reg_t() sd_clk_stable_o ); - localparam int unsigned MsbConsidered = (ClkPreDivLog != 0) ? (ClkPreDivLog - 1) : 0; - //check if all bits from [ClkPreDivLog-1:0] are one - function logic lsbones(input logic[ClkPreDivLog+7:0] div); - if(ClkPreDivLog == 0) return '1; - else return (div[MsbConsidered:0] == '1); - endfunction + localparam int unsigned DivWidth = 16; + localparam logic [DivWidth-1:0] MinDiv = {{(DivWidth-2){1'b0}}, 2'b10}; - logic[7:0] div_d, div_q; - assign div_d = (!reg2hw_i.clock_control.sd_clock_enable.q) ? reg2hw_i.clock_control.sdclk_frequency_select.q : div_q; - `FF(div_q, div_d, 8'b0, clk_i, rst_ni); - - //counter - logic[ClkPreDivLog+7 :0] cnt_d, cnt_q; - assign cnt_d = cnt_q + 1; - `FF(cnt_q, cnt_d, '0, clk_i, rst_ni); - - logic clk_en_p_d, clk_en_p_q; - `FF(clk_en_p_q, clk_en_p_d, '0, clk_i, rst_ni); - - logic clk_en_n_d, clk_en_n_q; - `FF(clk_en_n_q, clk_en_n_d, '0, clk_i, rst_ni); - - logic [ClkPreDivLog+7:0] bitmask; - assign bitmask = (1 << ClkPreDivLog) >> 1; - - //clk source multiplexer - logic clk_div_d, clk_div_q, clk_o_ungated; - always_comb begin : clk_div_mux - clk_div_d = 1'b1; - clk_en_p_d = clk_en_p_q; - clk_en_n_d = clk_en_n_q; - - unique case (div_q) - 8'h00: begin - if (ClkPreDivLog != 0) begin - clk_div_d = cnt_q[MsbConsidered]; - clk_en_p_d = lsbones(cnt_q ^ bitmask); - clk_en_n_d = lsbones(cnt_q); - end - end - 8'h01: begin - clk_div_d = cnt_q[ClkPreDivLog]; - clk_en_p_d = (!cnt_q[ClkPreDivLog]) && lsbones(cnt_q); - clk_en_n_d = cnt_q[ClkPreDivLog] && lsbones(cnt_q); - end - 8'h02: begin - clk_div_d = cnt_q[ClkPreDivLog+1]; - clk_en_p_d = (cnt_q[ClkPreDivLog+1:ClkPreDivLog] == 2'b01) && lsbones(cnt_q); - clk_en_n_d = (cnt_q[ClkPreDivLog+1:ClkPreDivLog] == 2'b11) && lsbones(cnt_q); - end - 8'h04: begin - clk_div_d = cnt_q[ClkPreDivLog+2]; - clk_en_p_d = (cnt_q[ClkPreDivLog+2:ClkPreDivLog] == 3'b011) && lsbones(cnt_q); - clk_en_n_d = (cnt_q[ClkPreDivLog+2:ClkPreDivLog] == 3'b111) && lsbones(cnt_q); - end - 8'h08: begin - clk_div_d = cnt_q[ClkPreDivLog+3]; - clk_en_p_d = (cnt_q[ClkPreDivLog+3:ClkPreDivLog] == 4'b0111) && lsbones(cnt_q); - clk_en_n_d = (cnt_q[ClkPreDivLog+3:ClkPreDivLog] == 4'b1111) && lsbones(cnt_q); - end - 8'h10: begin - clk_div_d = cnt_q[ClkPreDivLog+4]; - clk_en_p_d = (cnt_q[ClkPreDivLog+4:ClkPreDivLog] == 5'b01111) && lsbones(cnt_q); - clk_en_n_d = (cnt_q[ClkPreDivLog+4:ClkPreDivLog] == 5'b11111) && lsbones(cnt_q); - end - 8'h20: begin - clk_div_d = cnt_q[ClkPreDivLog+5]; - clk_en_p_d = (cnt_q[ClkPreDivLog+5:ClkPreDivLog] == 6'b011111) && lsbones(cnt_q); - clk_en_n_d = (cnt_q[ClkPreDivLog+5:ClkPreDivLog] == 6'b111111) && lsbones(cnt_q); - end - 8'h40: begin - clk_div_d = cnt_q[ClkPreDivLog+6]; - clk_en_p_d = (cnt_q[ClkPreDivLog+6:ClkPreDivLog] == 7'b0111111) && lsbones(cnt_q); - clk_en_n_d = (cnt_q[ClkPreDivLog+6:ClkPreDivLog] == 7'b1111111) && lsbones(cnt_q); + if (ClkPreDiv == 0) begin : gen_invalid_prediv + $error("ClkPreDiv must be at least 1"); + end + + function automatic logic freq_sel_valid(input logic [7:0] freq_sel); + unique case (freq_sel) + 8'h00, 8'h01, 8'h02, 8'h04, 8'h08, 8'h10, 8'h20, 8'h40, 8'h80: begin + freq_sel_valid = 1'b1; end - 8'h80: begin - clk_div_d = cnt_q[ClkPreDivLog+7]; - clk_en_p_d = (cnt_q[ClkPreDivLog+7:ClkPreDivLog] == 8'b01111111) && lsbones(cnt_q); - clk_en_n_d = (cnt_q[ClkPreDivLog+7:ClkPreDivLog] == 8'b11111111) && lsbones(cnt_q); + default: begin + freq_sel_valid = 1'b0; end - - default: ; endcase - end - `FF(clk_div_q, clk_div_d, 1'b1, clk_i, rst_ni); - - assign clk_o_ungated = ((div_q == 8'h00) && (ClkPreDivLog == 0)) ? clk_i : clk_div_q; - assign clk_en_p_o = ((div_q == 8'h00) && (ClkPreDivLog == 0)) ? '1 : clk_en_p_q; - assign clk_en_n_o = ((div_q == 8'h00) && (ClkPreDivLog == 0)) ? '1 : clk_en_n_q; - - assign sd_clk_o = (reg2hw_i.clock_control.sd_clock_enable.q && !pause_sd_clk_i) ? clk_o_ungated : 1'b1; + endfunction - assign div_1_o = ((div_q == 8'h00) && (ClkPreDivLog == 0)); - assign sd_clk_stable_o = '{ de: '1, d: reg2hw_i.clock_control.internal_clock_enable.q}; + function automatic logic [8:0] decode_sdhci_div(input logic [7:0] freq_sel); + unique case (freq_sel) + 8'h00: decode_sdhci_div = 9'd1; + 8'h01: decode_sdhci_div = 9'd2; + 8'h02: decode_sdhci_div = 9'd4; + 8'h04: decode_sdhci_div = 9'd8; + 8'h08: decode_sdhci_div = 9'd16; + 8'h10: decode_sdhci_div = 9'd32; + 8'h20: decode_sdhci_div = 9'd64; + 8'h40: decode_sdhci_div = 9'd128; + 8'h80: decode_sdhci_div = 9'd256; + default: decode_sdhci_div = 9'd1; + endcase + endfunction + logic [31:0] requested_div_full; + assign requested_div_full = ClkPreDiv * decode_sdhci_div( + reg2hw_i.clock_control.sdclk_frequency_select.q); + + logic [31:0] effective_div_full; + // ClkPreDiv is arbitrary, so folding it into the SDHCI divider can produce + // an odd effective divide. Round odd values up to keep sd_clk_o at 50% duty. + assign effective_div_full = (requested_div_full < 32'd2) ? 32'd2 : + (requested_div_full[0] ? requested_div_full + 32'd1 : + requested_div_full); + + logic [DivWidth-1:0] requested_div; + assign requested_div = effective_div_full[DivWidth-1:0]; + + logic [DivWidth-1:0] div_d, div_q; + always_comb begin + div_d = div_q; + if (!reg2hw_i.clock_control.sd_clock_enable.q && + freq_sel_valid(reg2hw_i.clock_control.sdclk_frequency_select.q) && + effective_div_full < (32'd1 << DivWidth)) begin + div_d = requested_div; + end + end + `FFARNC(div_q, div_d, clear_i, MinDiv, clk_i, rst_ni); + + logic [DivWidth-1:0] cycle_count; + logic div_ready, div_loaded_q, div_loaded_d; + always_comb begin + div_loaded_d = div_loaded_q; + if (div_d != div_q) begin + div_loaded_d = 1'b0; + end else if (div_ready) begin + div_loaded_d = 1'b1; + end + end + `FFARNC(div_loaded_q, div_loaded_d, clear_i, 1'b0, clk_i, rst_ni); + + logic sd_clk_running; + assign sd_clk_running = reg2hw_i.clock_control.sd_clock_enable.q && div_loaded_q && !pause_sd_clk_i; + + clk_int_div #( + .DIV_VALUE_WIDTH (DivWidth), + .DEFAULT_DIV_VALUE (2), + .ENABLE_CLOCK_IN_RESET (1'b0) + ) i_clk_int_div ( + .clk_i, + .rst_ni, + .en_i (sd_clk_running), + .test_mode_en_i(1'b0), + .div_i (div_q), + .div_valid_i (!div_loaded_q), + .div_ready_o (div_ready), + .clk_o (), + .cycl_count_o (cycle_count) + ); + + logic sd_clk_data_d, sd_clk_data_q, sd_clk_data_prev_q; + assign sd_clk_data_d = sd_clk_running ? (cycle_count < (div_q >> 1)) : 1'b1; + `FFARNC(sd_clk_data_q, sd_clk_data_d, clear_i, 1'b1, clk_i, rst_ni); + `FFARNC(sd_clk_data_prev_q, sd_clk_data_q, clear_i, 1'b1, clk_i, rst_ni); + + assign sd_clk_o = sd_clk_data_q; + assign clk_en_p_o = sd_clk_running && !sd_clk_data_prev_q && sd_clk_data_q; + assign clk_en_n_o = sd_clk_running && sd_clk_data_prev_q && !sd_clk_data_q; + assign div_1_o = 1'b0; + + assign sd_clk_stable_o = '{ de: '1, d: reg2hw_i.clock_control.internal_clock_enable.q && div_loaded_q}; + +`ifndef SYNTHESIS + always_ff @(posedge clk_i or negedge rst_ni) begin + if (rst_ni && !clear_i && !reg2hw_i.clock_control.sd_clock_enable.q) begin + assert (freq_sel_valid(reg2hw_i.clock_control.sdclk_frequency_select.q)) + else $error("Unsupported SDHCI SDCLK frequency select value %02h", + reg2hw_i.clock_control.sdclk_frequency_select.q); + assert (effective_div_full >= 32'd2 && !effective_div_full[0]) + else $error("SD clock effective divider must be even and at least 2"); + assert (effective_div_full < (32'd1 << DivWidth)) + else $error("SD clock effective divider %0d exceeds divider width", requested_div_full); + end + end +`endif endmodule diff --git a/hw/sdhci_obi_to_reg.sv b/hw/sdhci_obi_to_reg.sv new file mode 100644 index 0000000..473cdca --- /dev/null +++ b/hw/sdhci_obi_to_reg.sv @@ -0,0 +1,65 @@ +// Copyright 2026 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 + +// OBI to register-interface bridge for the SDHCI top. Unlike the generic +// adapter this only returns a response for requests accepted by the register +// side, so Buffer Data Port wait states do not create spurious rvalid pulses. +module sdhci_obi_to_reg #( + parameter int unsigned DATA_WIDTH = 32, + parameter int unsigned ID_WIDTH = 0, + + parameter type obi_req_t = logic, + parameter type obi_rsp_t = logic, + + parameter type reg_req_t = logic, + parameter type reg_rsp_t = logic +) ( + input logic clk_i, + input logic rst_ni, + + input obi_req_t obi_req_i, + output obi_rsp_t obi_rsp_o, + + output reg_req_t reg_req_o, + input reg_rsp_t reg_rsp_i +); + logic accepted; + logic rsp_valid_q; + logic [ID_WIDTH-1:0] aid_q; + logic [DATA_WIDTH-1:0] rdata_q; + logic error_q; + + assign accepted = obi_req_i.req & reg_rsp_i.ready; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + rsp_valid_q <= 1'b0; + aid_q <= '0; + rdata_q <= '0; + error_q <= 1'b0; + end else begin + rsp_valid_q <= accepted; + if (accepted) begin + aid_q <= obi_req_i.a.aid; + rdata_q <= reg_rsp_i.rdata; + error_q <= reg_rsp_i.error; + end + end + end + + assign reg_req_o.valid = obi_req_i.req; + assign reg_req_o.addr = obi_req_i.a.addr; + assign reg_req_o.write = obi_req_i.a.we; + assign reg_req_o.wdata = obi_req_i.a.wdata; + assign reg_req_o.wstrb = obi_req_i.a.be; + + always_comb begin + obi_rsp_o = '0; + obi_rsp_o.gnt = accepted; + obi_rsp_o.rvalid = rsp_valid_q; + obi_rsp_o.r.rdata = rdata_q; + obi_rsp_o.r.rid = aid_q; + obi_rsp_o.r.err = error_q; + end +endmodule diff --git a/hw/sdhci_top.sv b/hw/sdhci_top.sv index 2a3dc88..3e8286c 100644 --- a/hw/sdhci_top.sv +++ b/hw/sdhci_top.sv @@ -10,21 +10,32 @@ `include "common_cells/registers.svh" `include "defines.svh" +// SDC note: sd_clk_o is a clk_i-registered clock-as-data pad output. The +// controller internals remain in the clk_i domain and use sd_clk_en_p/n strobes +// derived from the same divider. Do not propagate CTS through sd_clk_o; constrain +// SD CMD/DAT pad delays against clk_i, and document the board/protocol SDCLK +// period as ClkPreDiv times the SDHCI frequency-select divider. Hardware +// enforces a minimum effective divide by 2 for sdclk_frequency_select=0. module sdhci_top #( parameter int unsigned AddrWidth = 32'd32, parameter type reg_req_t = logic, parameter type reg_rsp_t = logic, - //sw handles clock division. However, largest base freq. accepted is 63MHz! - //-> internal clock predivider to get below 63MHz - //only power of 2 dividers allowed :( - //input log2 of divider i.e div by 4 -> ClkPreDivLog = 2 - parameter int unsigned ClkPreDivLog = 1, - //also change base_clock_frequency_for_sd_clock resval in reg/sdhci_regs.hjson and regenerate registers + // Software handles SDHCI clock division. ClkPreDiv is a hidden integration + // predivider folded into the same physical divider as sdclk_frequency_select; + // advertise clk_i/ClkPreDiv as base_clock_frequency_for_sd_clock. + parameter int unsigned ClkPreDiv = 2, parameter int unsigned TimeoutDivider = 1, // by how much to divide clk_i to get the timeout count frequency, // see dat_timeout for details + // Warranty-void integration escape hatch: default mode is SDHCI-compliant + // and requires enough FIFO space for a full 512-byte block. Setting + // AllowNoncompliantBufferSizes permits smaller FIFOs and reports the usable + // Buffer Data Port chunk size in the vendor extension at offset 0x44. + parameter int unsigned BufferNumWords = 256, + parameter bit AllowNoncompliantBufferSizes = 1'b0, + // clock runs at 50MHz, so 1ms is 50_000 cycles parameter int unsigned NumDebounceCycles = 500_000 // 10ms ) ( @@ -47,9 +58,11 @@ module sdhci_top #( output logic interrupt_o ); - logic sd_rst_n, sd_rst_cmd_n, sd_rst_dat_n; + logic sd_clear, sd_clear_cmd, sd_clear_dat; sdhci_reg_pkg::sdhci_reg2hw_t reg2hw, reg2hw_orig; sdhci_reg_pkg::sdhci_hw2reg_t hw2reg; + logic buffer_data_port_read_ready; + logic buffer_data_port_write_ready; // Soft Reset Logic ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// logic software_reset_all_q, software_reset_all_d, software_reset_cmd_q, software_reset_cmd_d, software_reset_dat_q, software_reset_dat_d; @@ -58,18 +71,20 @@ module sdhci_top #( `FF(software_reset_all_q, software_reset_all_d, '0, clk_i, rst_ni); assign software_reset_cmd_d = reg2hw.software_reset.software_reset_for_cmd_line.q; // command circuit soft reset - `FF(software_reset_cmd_q, software_reset_cmd_d, '1, clk_i, rst_ni); + `FF(software_reset_cmd_q, software_reset_cmd_d, '0, clk_i, rst_ni); assign software_reset_dat_d = reg2hw.software_reset.software_reset_for_dat_line.q; // dat circuit soft reset - `FF(software_reset_dat_q, software_reset_dat_d, '1, clk_i, rst_ni); + `FF(software_reset_dat_q, software_reset_dat_d, '0, clk_i, rst_ni); - assign sd_rst_n = rst_ni && !software_reset_all_q; - assign sd_rst_cmd_n = sd_rst_n && !software_reset_cmd_q; - assign sd_rst_dat_n = sd_rst_n && !software_reset_dat_q; + assign sd_clear = software_reset_all_q; + assign sd_clear_cmd = sd_clear || software_reset_cmd_q; + assign sd_clear_dat = sd_clear || software_reset_dat_q; + assign hw2reg.software_reset.software_reset_for_all.d = 1'b0; assign hw2reg.software_reset.software_reset_for_dat_line.d = 1'b0; assign hw2reg.software_reset.software_reset_for_cmd_line.d = 1'b0; + assign hw2reg.software_reset.software_reset_for_all.de = software_reset_all_q; assign hw2reg.software_reset.software_reset_for_dat_line.de = software_reset_dat_q; assign hw2reg.software_reset.software_reset_for_cmd_line.de = software_reset_cmd_q; @@ -77,14 +92,19 @@ module sdhci_top #( sdhci_reg_top #( .AW (AddrWidth), .reg_req_t (reg_req_t), - .reg_rsp_t (reg_rsp_t) + .reg_rsp_t (reg_rsp_t), + .BufferNumWords(BufferNumWords), + .AllowNoncompliantBufferSizes(AllowNoncompliantBufferSizes) ) i_regs ( .clk_i, - .rst_ni (sd_rst_n), + .rst_ni, .reg_req_i, .reg_rsp_o, .reg2hw (reg2hw_orig), .hw2reg, + .clear_i (sd_clear), + .buffer_data_port_read_ready_i (AllowNoncompliantBufferSizes ? buffer_data_port_read_ready : 1'b1), + .buffer_data_port_write_ready_i (AllowNoncompliantBufferSizes ? buffer_data_port_write_ready : 1'b1), .devmode_i (1'b1) ); @@ -95,9 +115,10 @@ module sdhci_top #( sdhci_reg_logic i_sdhci_reg_logic ( .clk_i, - .rst_ni (sd_rst_n), - .rst_cmd_ni (sd_rst_cmd_n), - .rst_dat_ni (sd_rst_dat_n), + .rst_ni, + .clear_i (sd_clear), + .clear_cmd_i (sd_clear_cmd), + .clear_dat_i (sd_clear_dat), .reg2hw_i (reg2hw_orig), .hw2reg_i (hw2reg), @@ -132,10 +153,11 @@ module sdhci_top #( logic pause_sd_clk, sd_clk_en_p, sd_clk_en_n, div_1; sd_clk_generator #( - .ClkPreDivLog (ClkPreDivLog) + .ClkPreDiv (ClkPreDiv) ) i_sd_clk_generator ( .clk_i, - .rst_ni (sd_rst_n), + .rst_ni, + .clear_i (sd_clear), .reg2hw_i (reg2hw), .pause_sd_clk_i (pause_sd_clk), @@ -176,7 +198,8 @@ module sdhci_top #( autocmd_wrap i_autocmd_wrap ( .clk_i (clk_i), - .rst_ni (sd_rst_cmd_n), + .rst_ni, + .clear_i (sd_clear_cmd), .clk_en_p_i (sd_clk_en_p), .clk_en_n_i (sd_clk_en_n), .div_1_i (div_1), @@ -213,13 +236,16 @@ module sdhci_top #( dat_wrap #( - .TimeoutDivider(TimeoutDivider) + .TimeoutDivider (TimeoutDivider), + .BufferNumWords (BufferNumWords), + .AllowNoncompliantBufferSizes (AllowNoncompliantBufferSizes) ) i_dat_wrap ( .clk_i, .sd_clk_en_p_i (sd_clk_en_p), .sd_clk_en_n_i (sd_clk_en_n), .div_1_i (div_1), - .rst_ni (sd_rst_dat_n), + .rst_ni, + .clear_i (sd_clear_dat), .dat_i (sd_dat_i), .dat_en_o (sd_dat_en_o), @@ -246,6 +272,8 @@ module sdhci_top #( .buffer_data_port_d_o (hw2reg.buffer_data_port.d), .buffer_read_enable_o (hw2reg.present_state.buffer_read_enable), .buffer_write_enable_o (hw2reg.present_state.buffer_write_enable), + .buffer_data_port_read_ready_o (buffer_data_port_read_ready), + .buffer_data_port_write_ready_o (buffer_data_port_write_ready), .read_transfer_active_o (hw2reg.present_state.read_transfer_active), .write_transfer_active_o (hw2reg.present_state.write_transfer_active), diff --git a/hw/sdhci_top_obi.sv b/hw/sdhci_top_obi.sv index ab78b19..fdc9764 100644 --- a/hw/sdhci_top_obi.sv +++ b/hw/sdhci_top_obi.sv @@ -12,8 +12,10 @@ module sdhci_top_obi #( parameter obi_pkg::obi_cfg_t ObiCfg = obi_pkg::ObiDefaultConfig, parameter type obi_req_t = logic, parameter type obi_rsp_t = logic, - parameter int unsigned ClkPreDivLog = 1, + parameter int unsigned ClkPreDiv = 2, parameter int unsigned NumDebounceCycles = 500_000, + parameter int unsigned BufferNumWords = 256, + parameter bit AllowNoncompliantBufferSizes = 1'b0, parameter int TimeoutDivider = 1 ) ( input logic clk_i, @@ -43,7 +45,7 @@ module sdhci_top_obi #( reg_req_t reg_req; reg_rsp_t reg_rsp; - obi_to_reg #( + sdhci_obi_to_reg #( .DATA_WIDTH (ObiCfg.DataWidth), .ID_WIDTH (ObiCfg.IdWidth), @@ -65,8 +67,10 @@ module sdhci_top_obi #( .AddrWidth (ObiCfg.AddrWidth), .reg_req_t (reg_req_t), .reg_rsp_t (reg_rsp_t), - .ClkPreDivLog (ClkPreDivLog), + .ClkPreDiv (ClkPreDiv), .NumDebounceCycles(NumDebounceCycles), + .BufferNumWords (BufferNumWords), + .AllowNoncompliantBufferSizes(AllowNoncompliantBufferSizes), .TimeoutDivider (TimeoutDivider) ) i_sdhci_impl ( .clk_i, diff --git a/hw/sdhci_top_synth.sv b/hw/sdhci_top_synth.sv new file mode 100644 index 0000000..10e04f7 --- /dev/null +++ b/hw/sdhci_top_synth.sv @@ -0,0 +1,45 @@ +// Copyright 2026 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 + +// Authors: +// - Philippe Sauter + +module sdhci_top_synth #( + parameter int unsigned AddrWidth = 32'd32, + parameter type reg_req_t = struct packed { logic [31:0] addr; logic write; logic [31:0] wdata; logic [3:0] wstrb; logic valid; }, + parameter type reg_rsp_t = struct packed { logic [31:0] rdata; logic error; logic ready; } +) ( + input logic clk_i, + input logic rst_ni, + + input reg_req_t reg_req_i, + output reg_rsp_t reg_rsp_o, + + output logic sd_clk_o, + input logic sd_cd_ni, + output logic sd_cmd_en_o, + output logic sd_cmd_o, + input logic sd_cmd_i, + + input logic [3:0] sd_dat_i, + output logic [3:0] sd_dat_o, + output logic sd_dat_en_o, + + output logic interrupt_o + +); + +sdhci_top #( + .AddrWidth ( 32'd32 ), + .reg_req_t ( reg_req_t ), + .reg_rsp_t ( reg_rsp_t ), + .ClkPreDiv ( 2 ), + .TimeoutDivider ( 1 ), + .NumDebounceCycles ( 500_000 ) +) i_top ( + .* +); + + +endmodule diff --git a/hw/ser_par_shift_reg.sv b/hw/ser_par_shift_reg.sv deleted file mode 100644 index ff42a2a..0000000 --- a/hw/ser_par_shift_reg.sv +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2025 ETH Zurich and University of Bologna. -// Solderpad Hardware License, Version 0.51, see LICENSE for details. -// SPDX-License-Identifier: SHL-0.51 - -// Authors: -// - Anton Buchner - -//serial to parallel converter with active low asynchronous reset -//shifts in MSb first! - -`include "common_cells/registers.svh" - -module ser_par_shift_reg #( - parameter int unsigned NumBits = 48, - parameter bit MaskOutput = 0 //if output is masked with zeros during shifting, if 1, par_output_en_i is needed. -) ( - input logic clk_i, - input logic clk_en_i, - input logic rst_ni, - - input logic shift_in_en_i, - input logic par_output_en_i, - - input logic dat_ser_i, - output logic [NumBits-1:0] dat_par_o -); - logic [NumBits-1:0] dat_d, dat_q; - - always_comb begin - dat_d = dat_q; //default assignment - - if (shift_in_en_i) begin : shift_in - dat_d[NumBits-1:1] = dat_q[NumBits-2:0]; - dat_d[0] = dat_ser_i; - end - end - - `FFL(dat_q, dat_d, clk_en_i, 0, clk_i, rst_ni); - - generate - if (MaskOutput) begin - assign dat_par_o = (par_output_en_i) ? dat_q : '0; - end else begin - assign dat_par_o = dat_q; - end - endgenerate - -endmodule \ No newline at end of file diff --git a/hw/sram_shift_reg.sv b/hw/sram_shift_reg.sv index dc7d01b..00ca43b 100644 --- a/hw/sram_shift_reg.sv +++ b/hw/sram_shift_reg.sv @@ -28,6 +28,7 @@ module sram_shift_reg #( ) ( input logic clk_i, input logic rst_ni, + input logic clear_i, input logic en_i, @@ -42,22 +43,22 @@ module sram_shift_reg #( ); // Push a pop operation to the next clock cycle if the sram is busy logic pop_front_q, pop_front_d; - `FF(pop_front_q, pop_front_d, '0, clk_i, rst_ni); + `FFARNC(pop_front_q, pop_front_d, clear_i, '0, clk_i, rst_ni); assign pop_front_d = pop_front_i & (push_back_i | pop_front_q); `ASSERT_NEVER(Overload, pop_front_i & push_back_i & pop_front_q); logic [AddrWidth-1:0] back_addr_q, back_addr_d; - `FF(back_addr_q, back_addr_d, '0, clk_i, rst_ni); + `FFARNC(back_addr_q, back_addr_d, clear_i, '0, clk_i, rst_ni); logic [LengthWidth-1:0] length_q, length_d; - `FF(length_q, length_d, '0, clk_i, rst_ni); + `FFARNC(length_q, length_d, clear_i, '0, clk_i, rst_ni); always_comb begin length_d = length_q; back_addr_d = back_addr_q; - if (!en_i) begin + if (clear_i || !en_i) begin length_d = '0; end else if (push_back_i) begin length_d = length_q + 1; diff --git a/target/sim/src/sdhci_fixture.sv b/target/sim/src/sdhci_fixture.sv index 6459f7c..bd5e845 100644 --- a/target/sim/src/sdhci_fixture.sv +++ b/target/sim/src/sdhci_fixture.sv @@ -9,7 +9,9 @@ module sdhci_fixture #( parameter time ClkPeriod = 50ns, parameter int unsigned RstCycles = 1, - parameter int unsigned TimeoutDivider = 1 + parameter int unsigned TimeoutDivider = 1, + parameter int unsigned BufferNumWords = 256, + parameter bit AllowNoncompliantBufferSizes = 1'b0 )(); `include "obi/typedef.svh" @@ -30,8 +32,10 @@ module sdhci_fixture #( .ObiCfg (sdhci_obi_cfg), .obi_req_t (sdhci_obi_req_t), .obi_rsp_t (sdhci_obi_rsp_t), - .ClkPreDivLog (0), + .ClkPreDiv (2), .NumDebounceCycles(2), + .BufferNumWords (BufferNumWords), + .AllowNoncompliantBufferSizes(AllowNoncompliantBufferSizes), .TimeoutDivider (TimeoutDivider) ) i_sdhci_top ( .clk_i (clk), diff --git a/target/sim/src/sdhci_obi_driver.sv b/target/sim/src/sdhci_obi_driver.sv index 1e6bd36..4e05b9f 100644 --- a/target/sim/src/sdhci_obi_driver.sv +++ b/target/sim/src/sdhci_obi_driver.sv @@ -262,6 +262,6 @@ module sdhci_obi_driver #( be = 4'b0011; obi_read('h024, be, response); buffer_read_enable = response[11]; - buffer_read_enable = response[10]; + buffer_write_enable = response[10]; endtask endmodule diff --git a/target/sim/src/tb_acmd12_errorhandling.sv b/target/sim/src/tb_acmd12_errorhandling.sv index 1f046a6..b655129 100644 --- a/target/sim/src/tb_acmd12_errorhandling.sv +++ b/target/sim/src/tb_acmd12_errorhandling.sv @@ -91,7 +91,9 @@ module tb_acmd12_errorhandling #( $dumpvars(0); if (!$value$plusargs("CyclesThatDriverCommandArrivesBeforeCMD12=%d", CyclesThatDriverCommandArrivesBeforeCMD12)) begin - CyclesThatDriverCommandArrivesBeforeCMD12 = 0; + // Keep the default regression point away from the timing boundary; directed + // sweeps can still override this plusarg to exercise the collision window. + CyclesThatDriverCommandArrivesBeforeCMD12 = 10; end if (!$value$plusargs("IsFirstResponseValid=%d", IsFirstResponseValid)) begin IsFirstResponseValid = 0; @@ -168,7 +170,7 @@ module tb_acmd12_errorhandling #( if (buf_write_en) begin // we submitted all the data for the block - $fatal("Buffer write enable should be off"); + $fatal(1, "Buffer write enable should be off"); end fixture.vip.sd.wait_for_dat_held(); @@ -179,7 +181,7 @@ module tb_acmd12_errorhandling #( 1: repeat(8 - CyclesThatDriverCommandArrivesBeforeCMD12) fixture.vip.wait_for_clk(); 2: repeat(17 - CyclesThatDriverCommandArrivesBeforeCMD12) fixture.vip.wait_for_clk(); 4: repeat(35 - CyclesThatDriverCommandArrivesBeforeCMD12) fixture.vip.wait_for_clk(); - default: $fatal("ClkEnPeriod not supported"); + default: $fatal(1, "ClkEnPeriod not supported"); endcase fixture.vip.obi.launch_command( diff --git a/target/sim/src/tb_block_read.sv b/target/sim/src/tb_block_read.sv index 05fb766..7c81e30 100644 --- a/target/sim/src/tb_block_read.sv +++ b/target/sim/src/tb_block_read.sv @@ -11,12 +11,20 @@ module tb_block_read #( parameter int unsigned ClkEnPeriod = 1, parameter int unsigned BlockSize = 512, parameter int unsigned BlockCount = 2, - parameter logic Do4Bit = 1'b1 + parameter logic Do4Bit = 1'b1, + parameter int unsigned BufferNumWords = 256, + parameter bit AllowNoncompliantBufferSizes = 1'b0 )(); + localparam int unsigned ExpectedChunkBytes = + AllowNoncompliantBufferSizes ? BufferNumWords * 4 : 512; + localparam logic [31:0] ExpectedVendorCapabilities = { + AllowNoncompliantBufferSizes, 15'h0, 16'(ExpectedChunkBytes)}; sdhci_fixture #( .ClkPeriod(ClkPeriod), - .RstCycles(RstCycles) + .RstCycles(RstCycles), + .BufferNumWords(BufferNumWords), + .AllowNoncompliantBufferSizes(AllowNoncompliantBufferSizes) ) fixture (); task automatic wfi(input int unsigned timeout_cycles, string error_context); @@ -84,6 +92,62 @@ module tb_block_read #( end endtask + task automatic wait_irq_bits(logic [15:0] required_normal, logic [15:0] allowed_normal, + logic [15:0] expected_error, int unsigned timeout_cycles, + string error_context); + logic [15:0] error_interrupt_status; + logic [15:0] normal_interrupt_status; + logic [15:0] normal_interrupt_status_seen; + + normal_interrupt_status_seen = '0; + while ((normal_interrupt_status_seen & required_normal) != required_normal) begin + wfi(timeout_cycles, error_context); + fixture.vip.obi.get_interrupt_status( + .normal_interrupt_status(normal_interrupt_status), + .error_interrupt_status(error_interrupt_status) + ); + fixture.vip.obi.clear_interrupt_status( + .normal_interrupt_status(normal_interrupt_status), + .error_interrupt_status(error_interrupt_status) + ); + + if (error_interrupt_status != expected_error) begin + $fatal(1, "Unexpected error interrupt status, got %x, expected %x (%s)", + error_interrupt_status, expected_error, error_context); + end + if (normal_interrupt_status & ~allowed_normal) begin + $fatal(1, "Unexpected normal interrupt status, got %x, allowed %x (%s)", + normal_interrupt_status, allowed_normal, error_context); + end + + normal_interrupt_status_seen |= normal_interrupt_status; + end + endtask + + task automatic read_noncompliant_block(output logic [31:0] read_data); + int unsigned words_read; + int unsigned words_left; + int unsigned words_this_chunk; + + words_read = 0; + while (words_read < BlockSize / 4) begin + wait_irq_bits( + .required_normal('h20), // noncompliant data ready + .allowed_normal ('h20), + .expected_error ('h0), + .timeout_cycles (BlockSize * 8 + 500), + .error_context ("noncompliant cmd18 data ready") + ); + + words_left = (BlockSize / 4) - words_read; + words_this_chunk = (words_left < BufferNumWords) ? words_left : BufferNumWords; + repeat (words_this_chunk) begin + fixture.vip.obi.read_buffer_data(.data(read_data)); + end + words_read += words_this_chunk; + end + endtask + initial begin : cmd_response fixture.vip.wait_for_reset(); @@ -144,9 +208,16 @@ module tb_block_read #( initial begin : obi_driver logic [31:0] read_data; + logic [31:0] vendor_capabilities; logic buffer_read_enable, buffer_write_enable; fixture.vip.wait_for_reset(); + fixture.vip.obi.obi_read('h044, 4'b1111, vendor_capabilities); + if (vendor_capabilities != ExpectedVendorCapabilities) begin + $fatal(1, "Unexpected vendor capabilities: got 0x%08x expected 0x%08x", + vendor_capabilities, ExpectedVendorCapabilities); + end + fixture.vip.obi.set_interrupt_status_enable( .normal_interrupt_status_enable('hFFFF), .error_interrupt_status_enable('hFFFF), @@ -196,46 +267,69 @@ module tb_block_read #( .finish_transaction(1'b1) ); - wfi(200, "cmd18 complete"); - check_irq( - .expected_normal('h01), // cmd complete - .expected_error ('h0), // no error - .error_context("cmd18 complete") - ); + if (AllowNoncompliantBufferSizes) begin + wait_irq_bits( + .required_normal('h01), // cmd complete + .allowed_normal ('h21), // cmd complete and noncompliant per-word data ready + .expected_error ('h0), // no error + .timeout_cycles (BlockSize * 8 + 500), + .error_context ("noncompliant cmd18 complete") + ); - wfi(BlockSize * 8 + 500, "first data present"); - check_irq( - .expected_normal('h20), // data present - .expected_error ('h0), // no error - .error_context("first data present") - ); + repeat (BlockCount) begin + read_noncompliant_block(read_data); + end + + wait_irq_bits( + .required_normal('h02), // transfer complete + .allowed_normal ('h22), // transfer complete and noncompliant data ready + .expected_error ('h0), // no error + .timeout_cycles (BlockSize * 8 + 500), + .error_context ("noncompliant cmd18 transfer complete") + ); + end else begin + wfi(200, "cmd18 complete"); + check_irq( + .expected_normal('h01), // cmd complete + .expected_error ('h0), // no error + .error_context("cmd18 complete") + ); - repeat (BlockCount - 1) begin + wfi(BlockSize * 8 + 500, "first data present"); + check_irq( + .expected_normal('h20), // data present + .expected_error ('h0), // no error + .error_context("first data present") + ); + + repeat (BlockCount - 1) begin + repeat (BlockSize / 4) begin + fixture.vip.obi.read_buffer_data(.data(read_data)); + end + fixture.vip.obi.get_present_status_buffer_enable( + .buffer_read_enable(buffer_read_enable), + .buffer_write_enable(buffer_write_enable) + ); + if (!buffer_read_enable) begin + wfi(BlockSize * 8 + 500, "data present during loop"); + end + check_irq( + .expected_normal('h20), // data present + .expected_error ('h0), // no error + .error_context("data present during loop") + ); + end repeat (BlockSize / 4) begin fixture.vip.obi.read_buffer_data(.data(read_data)); end - fixture.vip.obi.get_present_status_buffer_enable( - .buffer_read_enable(buffer_read_enable), - .buffer_write_enable(buffer_write_enable) - ); - if (!buffer_read_enable) begin - wfi(BlockSize * 8 + 500, "data present during loop"); - end + wfi(200, "cmd18 transfer complete"); check_irq( - .expected_normal('h20), // data present + .expected_normal('h02), // transfer complete .expected_error ('h0), // no error - .error_context("data present during loop") + .error_context("cmd18 transfer complete") ); end - repeat (BlockSize / 4) begin - fixture.vip.obi.read_buffer_data(.data(read_data)); - end - wfi(200, "cmd18 transfer complete"); - check_irq( - .expected_normal('h02), // transfer complete - .expected_error ('h0), // no error - .error_context("cmd18 transfer complete") - ); + fixture.vip.obi.get_present_status_buffer_enable( .buffer_read_enable(buffer_read_enable), .buffer_write_enable(buffer_write_enable) @@ -245,8 +339,6 @@ module tb_block_read #( $fatal(1, "We should no longer have data!"); end - // TODO: read interrupt registers + check transfer complete - fixture.vip.obi.launch_command( .command_index(6'd12), .command_type (2'b00), // normal command @@ -257,12 +349,22 @@ module tb_block_read #( .finish_transaction(1'b1) ); - wfi(200, "cmd12 complete and transfer complete"); - check_irq( - .expected_normal('h03), // cmd complete - .expected_error ('h0), // no error - .error_context("cmd12 complete and transfer complete") - ); + if (AllowNoncompliantBufferSizes) begin + wait_irq_bits( + .required_normal('h03), // cmd complete and transfer complete + .allowed_normal ('h03), + .expected_error ('h0), // no error + .timeout_cycles (200), + .error_context ("cmd12 complete and transfer complete") + ); + end else begin + wfi(200, "cmd12 complete and transfer complete"); + check_irq( + .expected_normal('h03), // cmd complete + .expected_error ('h0), // no error + .error_context("cmd12 complete and transfer complete") + ); + end $display("All good"); @@ -270,3 +372,11 @@ module tb_block_read #( end endmodule + +module tb_noncompliant_block_read(); + tb_block_read #( + .BlockCount(2), + .BufferNumWords(8), + .AllowNoncompliantBufferSizes(1'b1) + ) i_noncompliant_block_read (); +endmodule diff --git a/target/sim/src/tb_dat.sv b/target/sim/src/tb_dat.sv index 4b1af9b..d26408d 100644 --- a/target/sim/src/tb_dat.sv +++ b/target/sim/src/tb_dat.sv @@ -9,6 +9,26 @@ module tb_dat #( parameter time ClkPeriod = 50ns, parameter int unsigned RstCycles = 1 )(); + localparam int unsigned TestClkPreDiv = 2; + + function automatic logic [7:0] encode_frequency_select(input int unsigned min_effective_div); + int unsigned sdhci_div; + int unsigned effective_div; + sdhci_div = 1; + effective_div = TestClkPreDiv; + if (effective_div < 2) begin + effective_div = 2; + end + while (effective_div < min_effective_div && sdhci_div < 256) begin + sdhci_div <<= 1; + effective_div = TestClkPreDiv * sdhci_div; + if (effective_div[0]) begin + effective_div++; + end + end + return (sdhci_div == 1) ? 8'h00 : 8'(sdhci_div >> 1); + endfunction + logic clk; logic rst_n; @@ -30,6 +50,7 @@ module tb_dat #( sd_clk_generator sd_clk_div ( .clk_i (clk), .rst_ni (rst_n), + .clear_i(1'b0), .reg2hw_i, @@ -64,6 +85,7 @@ module tb_dat #( .sd_clk_en_n_i (sd_clk_en_n), .div_1_i (div_1), .rst_ni (rst_n), + .clear_i(1'b0), .start_i (start_write), .block_size_i (MaxBlockBitSize'(BlockSize)), @@ -75,6 +97,8 @@ module tb_dat #( .done_o (done_write), .crc_err_o (), .end_bit_err_o (), + .data_timeout_o(), + .waiting_o (), .dat0_i (dat[0]), .dat_o, @@ -89,9 +113,11 @@ module tb_dat #( .clk_i (clk), .sd_clk_en_i (sd_clk_en_p), .rst_ni (rst_n), + .clear_i(1'b0), .dat_i (dat), .start_i (start_read), + .timeout_i (1'b0), .block_size_i (MaxBlockBitSize'(BlockSize)), .bus_width_is_4_i (UseWideBus), @@ -100,7 +126,8 @@ module tb_dat #( .done_o (done_read), .crc_err_o, - .end_bit_err_o + .end_bit_err_o, + .waiting_o () ); ///////////////// @@ -108,12 +135,12 @@ module tb_dat #( ///////////////// always begin - if (done_o && crc_err_o) begin + if (done_read && crc_err_o) begin $error("CRC Error"); @(negedge clk) $fatal(); end - if (done_o && end_bit_err_o) begin + if (done_read && end_bit_err_o) begin $error("End Bit Error"); @(negedge clk) $fatal(); @@ -124,11 +151,14 @@ module tb_dat #( logic [31:0] entries [$]; int ClkEnPeriod, remainingBlocks; + int watchdog_cycles; logic [31:0] got, want; initial begin $timeformat(-9, 0, "ns", 12); - $dumpfile("tb_dat.vcd"); - $dumpvars(0); + if ($test$plusargs("vcd")) begin + $dumpfile("tb_dat.vcd"); + $dumpvars(0); + end if (!$value$plusargs("UseWideBus=%d", UseWideBus)) begin UseWideBus = 1; @@ -142,7 +172,7 @@ module tb_dat #( reg2hw_i = '0; reg2hw_i.clock_control.sd_clock_enable.q = 1; - reg2hw_i.clock_control.sdclk_frequency_select.q = 8'(ClkEnPeriod); + reg2hw_i.clock_control.sdclk_frequency_select.q = encode_frequency_select(ClkEnPeriod); $display("Testing dat line with UseWideBus=%d, BlockSize=%d, ClkEnPeriod=%d", UseWideBus, BlockSize, ClkEnPeriod); @@ -163,6 +193,7 @@ module tb_dat #( start_read = '0; remainingBlocks = BlockSize; + watchdog_cycles = 0; while (!done_read) begin @@ -205,11 +236,18 @@ module tb_dat #( @(negedge sd_clk); @(posedge clk); + #1ns; + watchdog_cycles++; + if (watchdog_cycles > (BlockSize * (UseWideBus ? 16 : 64) + 1000)) begin + $fatal(1, "DAT transfer timed out"); + end end repeat(50) @(posedge clk); - $dumpflush; + if ($test$plusargs("vcd")) begin + $dumpflush; + end $finish(); end diff --git a/target/sim/src/tb_dat_buffer_sizes.sv b/target/sim/src/tb_dat_buffer_sizes.sv new file mode 100644 index 0000000..11a66b3 --- /dev/null +++ b/target/sim/src/tb_dat_buffer_sizes.sv @@ -0,0 +1,388 @@ +// Copyright 2025 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 + +`include "defines.svh" + +module tb_dat_buffer_sizes #( + parameter time ClkPeriod = 50ns +)(); + logic clk; + logic rst_n; + logic [2:0] done; + + clk_rst_gen #( + .ClkPeriod ( ClkPeriod ), + .RstClkCycles ( 1 ) + ) i_clk_rst_sys ( + .clk_o ( clk ), + .rst_no ( rst_n ) + ); + + tb_dat_buffer_size_case #( + .NumWords(8), + .AllowNoncompliantBufferSizes(1'b1) + ) i_32b_noncompliant ( + .clk_i (clk), + .rst_ni (rst_n), + .done_o (done[0]) + ); + + tb_dat_buffer_size_case #(.NumWords(128)) i_512b ( + .clk_i (clk), + .rst_ni (rst_n), + .done_o (done[1]) + ); + + tb_dat_buffer_size_case #(.NumWords(256)) i_1024b ( + .clk_i (clk), + .rst_ni (rst_n), + .done_o (done[2]) + ); + + initial begin + wait(&done); + repeat (10) @(posedge clk); + $finish(); + end +endmodule + +module tb_dat_buffer_size_case #( + parameter int unsigned NumWords = 8, + parameter int unsigned BlockSize = 512, + parameter bit AllowNoncompliantBufferSizes = 1'b0 +) ( + input logic clk_i, + input logic rst_ni, + output logic done_o +); + localparam int unsigned BlockWords = BlockSize / 4; + + logic clear; + logic read_operation; + logic write_operation; + logic read_ready; + logic read_valid; + logic [31:0] read_data; + logic write_valid; + logic [31:0] write_data; + logic write_ready; + logic empty; + logic [31:0] buffer_data_port_d; + logic buffer_data_port_read_ready; + logic buffer_data_port_write_ready; + logic buffer_read_enable; + logic buffer_write_enable; + logic [15:0] block_count; + + logic [9:0] block_size; + logic [15:0] programmed_block_count; + logic multi_block; + logic block_count_enable; + logic buffer_data_port_re; + logic buffer_data_port_qe; + logic [31:0] buffer_data_port_q; + `writable_reg_t() buffer_read_enable_hw; + `writable_reg_t() buffer_write_enable_hw; + `writable_reg_t([15:0]) block_count_hw; + + assign buffer_read_enable = buffer_read_enable_hw.d; + assign buffer_write_enable = buffer_write_enable_hw.d; + assign block_count = block_count_hw.d; + + dat_buffer #( + .NumWords (NumWords), + .MaxBlockBitSize (10), + .AllowNoncompliantBufferSizes(AllowNoncompliantBufferSizes) + ) i_dat_buffer ( + .clk_i, + .rst_ni, + .clear_i (clear), + .read_operation_i (read_operation), + .write_operation_i (write_operation), + .read_ready_i (read_ready), + .read_valid_o (read_valid), + .read_data_o (read_data), + .write_valid_i (write_valid), + .write_data_i (write_data), + .write_ready_o (write_ready), + .empty_o (empty), + .buffer_data_port_read_ready_o(buffer_data_port_read_ready), + .buffer_data_port_write_ready_o(buffer_data_port_write_ready), + .block_size_i (block_size), + .block_count_i (programmed_block_count), + .multi_block_i (multi_block), + .block_count_enable_i(block_count_enable), + .buffer_data_port_re_i(buffer_data_port_re), + .buffer_data_port_qe_i(buffer_data_port_qe), + .buffer_data_port_q_i(buffer_data_port_q), + .buffer_data_port_d_o(buffer_data_port_d), + .buffer_read_enable_o(buffer_read_enable_hw), + .buffer_write_enable_o(buffer_write_enable_hw), + .block_count_o (block_count_hw) + ); + + task automatic init_inputs(); + clear = 1'b0; + read_operation = 1'b0; + write_operation = 1'b0; + read_ready = 1'b0; + write_valid = 1'b0; + write_data = '0; + block_size = BlockSize; + programmed_block_count = 16'd2; + multi_block = 1'b1; + block_count_enable = 1'b0; + buffer_data_port_re = 1'b0; + buffer_data_port_qe = 1'b0; + buffer_data_port_q = '0; + endtask + + task automatic tick(); + @(posedge clk_i); + #1ns; + endtask + + task automatic pulse_clear(); + clear = 1'b1; + tick(); + clear = 1'b0; + tick(); + endtask + + task automatic test_default_read_side(); + read_operation = 1'b1; + tick(); + + for (int unsigned i = 0; i < BlockWords - 1; i++) begin + repeat (10) begin + if (write_ready) begin + break; + end + tick(); + end + if (!write_ready) begin + $fatal(1, "read-side buffer did not become writable for NumWords=%0d", NumWords); + end + write_data = 32'h1000_0000 + i; + write_valid = 1'b1; + tick(); + end + + write_valid = 1'b0; + tick(); + if (buffer_read_enable) begin + $fatal(1, "buffer_read_enable asserted before one chunk for NumWords=%0d", NumWords); + end + + write_data = 32'h1000_0000 + BlockWords - 1; + write_valid = 1'b1; + tick(); + write_valid = 1'b0; + tick(); + + if (!buffer_read_enable) begin + $fatal(1, "buffer_read_enable did not assert after one block for NumWords=%0d", NumWords); + end + + for (int unsigned i = 0; i < BlockWords; i++) begin + buffer_data_port_re = 1'b1; + tick(); + buffer_data_port_re = 1'b0; + write_valid = 1'b0; + tick(); + end + + read_operation = 1'b0; + endtask + + task automatic test_default_write_side(); + write_operation = 1'b1; + tick(); + if (!buffer_write_enable) begin + $fatal(1, "buffer_write_enable not asserted on empty buffer for NumWords=%0d", NumWords); + end + + for (int unsigned i = 0; i < BlockWords; i++) begin + buffer_data_port_q = 32'h2000_0000 + i; + buffer_data_port_qe = 1'b1; + tick(); + buffer_data_port_qe = 1'b0; + tick(); + end + + if (BlockWords == NumWords && buffer_write_enable) begin + $fatal(1, "buffer_write_enable remained asserted on full buffer for NumWords=%0d", NumWords); + end + + for (int unsigned i = 0; i < BlockWords; i++) begin + if (!read_valid) begin + $fatal(1, "read_valid deasserted before buffered chunk drained for NumWords=%0d", NumWords); + end + read_ready = 1'b1; + tick(); + read_ready = 1'b0; + tick(); + end + + write_operation = 1'b0; + endtask + + task automatic test_noncompliant_read_side(); + int unsigned produced; + int unsigned consumed; + int unsigned cycles; + + read_operation = 1'b1; + produced = 0; + consumed = 0; + cycles = 0; + tick(); + + while (consumed < BlockWords) begin + logic accepted_write; + logic accepted_read; + + write_valid = 1'b0; + buffer_data_port_re = 1'b0; + + if (produced < BlockWords && write_ready) begin + write_data = 32'h3000_0000 + produced; + write_valid = 1'b1; + end else if (buffer_data_port_read_ready) begin + buffer_data_port_re = 1'b1; + end + + accepted_write = write_valid && write_ready; + accepted_read = buffer_data_port_re && buffer_data_port_read_ready; + tick(); + if (accepted_write) begin + produced++; + end + if (accepted_read) begin + consumed++; + end + + cycles++; + if (cycles > BlockWords * 16) begin + $fatal(1, "noncompliant read-side buffer stalled for NumWords=%0d produced=%0d consumed=%0d", + NumWords, produced, consumed); + end + end + + write_valid = 1'b0; + buffer_data_port_re = 1'b0; + read_operation = 1'b0; + endtask + + task automatic test_noncompliant_write_stall_resume(); + write_operation = 1'b1; + tick(); + + for (int unsigned i = 0; i < NumWords; i++) begin + if (!buffer_data_port_write_ready) begin + $fatal(1, "noncompliant write-side buffer became full too early for NumWords=%0d", NumWords); + end + buffer_data_port_q = 32'h4000_0000 + i; + buffer_data_port_qe = 1'b1; + tick(); + end + buffer_data_port_qe = 1'b0; + tick(); + + if (buffer_data_port_write_ready) begin + $fatal(1, "noncompliant write-side Buffer Data Port did not stall when full for NumWords=%0d", NumWords); + end + + buffer_data_port_q = 32'h4BAD_F00D; + buffer_data_port_qe = 1'b1; + tick(); + buffer_data_port_qe = 1'b0; + + read_ready = 1'b1; + tick(); + read_ready = 1'b0; + + repeat (4) begin + if (buffer_data_port_write_ready) begin + break; + end + tick(); + end + if (!buffer_data_port_write_ready) begin + $fatal(1, "noncompliant write-side Buffer Data Port did not resume for NumWords=%0d", NumWords); + end + + write_operation = 1'b0; + endtask + + task automatic test_noncompliant_write_side(); + int unsigned produced; + int unsigned consumed; + int unsigned cycles; + + write_operation = 1'b1; + produced = 0; + consumed = 0; + cycles = 0; + tick(); + + while (consumed < BlockWords) begin + logic accepted_write; + logic accepted_read; + + buffer_data_port_qe = 1'b0; + read_ready = 1'b0; + + if (produced < BlockWords && buffer_data_port_write_ready) begin + buffer_data_port_q = 32'h5000_0000 + produced; + buffer_data_port_qe = 1'b1; + end else if (read_valid) begin + read_ready = 1'b1; + end + + accepted_write = buffer_data_port_qe && buffer_data_port_write_ready; + accepted_read = read_ready && read_valid; + tick(); + if (accepted_write) begin + produced++; + end + if (accepted_read) begin + consumed++; + end + + cycles++; + if (cycles > BlockWords * 16) begin + $fatal(1, "noncompliant write-side buffer stalled for NumWords=%0d produced=%0d consumed=%0d", + NumWords, produced, consumed); + end + end + + buffer_data_port_qe = 1'b0; + read_ready = 1'b0; + write_operation = 1'b0; + endtask + + initial begin + done_o = 1'b0; + init_inputs(); + wait(rst_ni); + tick(); + + if (AllowNoncompliantBufferSizes) begin + pulse_clear(); + test_noncompliant_read_side(); + pulse_clear(); + test_noncompliant_write_stall_resume(); + pulse_clear(); + test_noncompliant_write_side(); + end else begin + pulse_clear(); + test_default_read_side(); + pulse_clear(); + test_default_write_side(); + end + + done_o = 1'b1; + end +endmodule diff --git a/target/sim/src/tb_reg_reset.sv b/target/sim/src/tb_reg_reset.sv new file mode 100644 index 0000000..f4aba2e --- /dev/null +++ b/target/sim/src/tb_reg_reset.sv @@ -0,0 +1,189 @@ +// Copyright 2026 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 + +module tb_reg_reset #( + parameter time ClkPeriod = 20ns +)(); + typedef struct packed { + logic [31:0] addr; + logic write; + logic [31:0] wdata; + logic [3:0] wstrb; + logic valid; + } reg_req_t; + + typedef struct packed { + logic [31:0] rdata; + logic error; + logic ready; + } reg_rsp_t; + + localparam logic [31:0] BlockSizeCountOffset = 32'h004; + localparam logic [31:0] ArgumentOffset = 32'h008; + localparam logic [31:0] TransferModeOffset = 32'h00c; + localparam logic [31:0] HostControlOffset = 32'h028; + localparam logic [31:0] ClockResetOffset = 32'h02c; + localparam logic [31:0] IntStatusEnOffset = 32'h034; + localparam logic [31:0] IntSignalEnOffset = 32'h038; + + logic clk; + logic rst_n; + reg_req_t reg_req; + reg_rsp_t reg_rsp; + logic sd_clk; + logic sd_cmd_en; + logic sd_cmd; + logic [3:0] sd_dat; + logic sd_dat_en; + logic interrupt; + + clk_rst_gen #( + .ClkPeriod (ClkPeriod), + .RstClkCycles (2) + ) i_clk_rst_sys ( + .clk_o (clk), + .rst_no (rst_n) + ); + + sdhci_top #( + .AddrWidth (32), + .reg_req_t (reg_req_t), + .reg_rsp_t (reg_rsp_t) + ) i_dut ( + .clk_i (clk), + .rst_ni (rst_n), + .reg_req_i (reg_req), + .reg_rsp_o (reg_rsp), + .sd_clk_o (sd_clk), + .sd_cd_ni (1'b0), + .sd_cmd_en_o(sd_cmd_en), + .sd_cmd_o (sd_cmd), + .sd_cmd_i (1'b1), + .sd_dat_i (4'hf), + .sd_dat_o (sd_dat), + .sd_dat_en_o(sd_dat_en), + .interrupt_o(interrupt) + ); + + task automatic reg_write(input logic [31:0] addr, input logic [3:0] be, + input logic [31:0] data); + @(posedge clk); + #1ns; + reg_req.addr = addr; + reg_req.write = 1'b1; + reg_req.wdata = data; + reg_req.wstrb = be; + reg_req.valid = 1'b1; + #1ns; + while (!reg_rsp.ready) begin + @(posedge clk); + #1ns; + end + @(posedge clk); + #1ns; + reg_req = '0; + endtask + + task automatic reg_read(input logic [31:0] addr, input logic [3:0] be, + output logic [31:0] data); + @(posedge clk); + #1ns; + reg_req.addr = addr; + reg_req.write = 1'b0; + reg_req.wdata = '0; + reg_req.wstrb = be; + reg_req.valid = 1'b1; + #1ns; + while (!reg_rsp.ready) begin + @(posedge clk); + #1ns; + end + data = reg_rsp.rdata; + @(posedge clk); + #1ns; + reg_req = '0; + endtask + + task automatic expect_masked(input string name, input logic [31:0] actual, + input logic [31:0] expected, input logic [31:0] mask); + if ((actual & mask) !== (expected & mask)) begin + $fatal(1, "%s mismatch: got 0x%08x expected 0x%08x mask 0x%08x", + name, actual, expected, mask); + end + endtask + + task automatic write_nonzero_register_state(); + reg_write(BlockSizeCountOffset, 4'b1111, 32'h0003_0200); + reg_write(ArgumentOffset, 4'b1111, 32'h89ab_cdef); + reg_write(TransferModeOffset, 4'b0001, 32'h0000_0032); + reg_write(HostControlOffset, 4'b0001, 32'h0000_0002); + reg_write(ClockResetOffset, 4'b0011, 32'h0000_0105); + reg_write(ClockResetOffset, 4'b0100, 32'h000a_0000); + reg_write(IntStatusEnOffset, 4'b1111, 32'h001f_00f3); + reg_write(IntSignalEnOffset, 4'b1111, 32'h001f_00f3); + repeat (2) @(posedge clk); + endtask + + task automatic expect_nonzero_register_state(input string reset_context, + input logic dat_counter_cleared = 1'b0); + logic [31:0] data; + reg_read(BlockSizeCountOffset, 4'b1111, data); + expect_masked({reset_context, " block_size/count"}, data, + dat_counter_cleared ? 32'h0000_0200 : 32'h0003_0200, 32'hffff_0fff); + reg_read(ArgumentOffset, 4'b1111, data); + expect_masked({reset_context, " argument"}, data, 32'h89ab_cdef, 32'hffff_ffff); + reg_read(TransferModeOffset, 4'b0001, data); + expect_masked({reset_context, " transfer_mode"}, data, 32'h0000_0032, 32'h0000_003f); + reg_read(HostControlOffset, 4'b0001, data); + expect_masked({reset_context, " host_control"}, data, 32'h0000_0002, 32'h0000_0002); + reg_read(ClockResetOffset, 4'b0111, data); + expect_masked({reset_context, " clock/timeout"}, data, 32'h000a_0105, 32'h000f_ff05); + reg_read(IntStatusEnOffset, 4'b1111, data); + expect_masked({reset_context, " status_enable"}, data, 32'h001f_00f3, 32'hffff_ffff); + reg_read(IntSignalEnOffset, 4'b1111, data); + expect_masked({reset_context, " signal_enable"}, data, 32'h001f_00f3, 32'hffff_ffff); + endtask + + task automatic expect_cleared_register_state(); + logic [31:0] data; + reg_read(BlockSizeCountOffset, 4'b1111, data); + expect_masked("all reset block_size/count", data, 32'h0, 32'hffff_0fff); + reg_read(ArgumentOffset, 4'b1111, data); + expect_masked("all reset argument", data, 32'h0, 32'hffff_ffff); + reg_read(TransferModeOffset, 4'b0001, data); + expect_masked("all reset transfer_mode", data, 32'h0, 32'h0000_003f); + reg_read(HostControlOffset, 4'b0001, data); + expect_masked("all reset host_control", data, 32'h0, 32'h0000_0002); + reg_read(ClockResetOffset, 4'b0111, data); + expect_masked("all reset clock/timeout", data, 32'h0, 32'h000f_ff05); + reg_read(IntStatusEnOffset, 4'b1111, data); + expect_masked("all reset status_enable", data, 32'h0, 32'hffff_ffff); + reg_read(IntSignalEnOffset, 4'b1111, data); + expect_masked("all reset signal_enable", data, 32'h0, 32'hffff_ffff); + endtask + + task automatic software_reset(input logic [2:0] reset_bits); + reg_write(ClockResetOffset, 4'b1000, {5'b0, reset_bits, 24'b0}); + repeat (6) @(posedge clk); + endtask + + initial begin + reg_req = '0; + wait(rst_n); + repeat (4) @(posedge clk); + + write_nonzero_register_state(); + software_reset(3'b010); + expect_nonzero_register_state("cmd reset"); + + software_reset(3'b100); + expect_nonzero_register_state("dat reset", 1'b1); + + software_reset(3'b001); + expect_cleared_register_state(); + + repeat (10) @(posedge clk); + $finish(); + end +endmodule