mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-04 22:32:36 +00:00
Integrate the SPI-P2 shared-DMA ABI into the Tiny product: SPI0 at 0x1001D000 with IRQ25 and RCU target16, the four frozen Gen1 ALT routes, latched four-bit source qualification through the fabric and APB CDC, GPIO readiness/ownership guard, and the bounded rs_spi_* HAL with the TINY_SPI_P3_ACCEPTANCE ci_smoke image. Tiny DMA enables V2.2 requests 16/17 with exact fixed FIFO MMIO checks; Mini remains default-disabled and unchanged. Review closure: the DMA AXI4 master stages the origin channel with each burst so final and contended SPI alias bursts stay qualified, the RCU spare feedback bit is tied off for four-state simulators, and the clock-switch quiescence now includes the SPI session. Validation: full Pytest 2097 passed, 0 failed, 1 skipped (optional pypdf); both Tiny profiles pass the SPI-P3 Verilator acceptance (SIM_TEST_PASS cycles=1030088); R2-P7 Verilator acceptance, Mini DMA formal prove and cover, Mini/Tiny lint, Tiny Yosys synthesis, netsim-boot and OpenSTA pass; C format/policy/host tests and RTL format/style checks clean. Evidence and remaining obligations are recorded in docs/ip/spi-verification.md. Tiny Icarus behavioral remains blocked by the pre-existing observer/sv2v defect (routed to the R2 DV owners); Mini smoke synthesis host timeout is skipped per maintainer decision. Human phase acceptance and SPI-P4/P5 remain outstanding; phase_accepted stays false.
124 lines
4.5 KiB
Systemverilog
124 lines
4.5 KiB
Systemverilog
// Standalone SPI shell. DMA pacing is local; product route and fabric origin remain external.
|
|
module apb4_spi #(
|
|
parameter bit EnableDma = 1'b1
|
|
) (
|
|
input logic clk_i,
|
|
rst_n_i,
|
|
input logic [31:0] clock_hz_i,
|
|
input logic [ 1:0] origin_i,
|
|
input logic [ 4:0] request_i,
|
|
input logic [ 2:0] channel_i,
|
|
input logic [ 1:0] credit_valid_i,
|
|
credit_retire_i,
|
|
input logic [ 3:0] dma_status_i,
|
|
input logic [ 1:0] dma_start_pending_i,
|
|
input logic dma_error_i,
|
|
input logic [31:0] user_select_i,
|
|
handoff_i,
|
|
alt_enable_i,
|
|
alt_select_i,
|
|
input logic [31:0] output_enable_i,
|
|
open_drain_i,
|
|
input logic gpio_ready_i,
|
|
miso_i,
|
|
output logic sck_o,
|
|
mosi_o,
|
|
cs_n_o,
|
|
output_enable_o,
|
|
irq_o,
|
|
session_owned_o,
|
|
lifecycle_idle_o,
|
|
output logic [ 1:0] credit_commit_o,
|
|
apb4_if.slave apb4
|
|
);
|
|
spi_ctrl_if u_ctrl ();
|
|
spi_pkg::configuration_t s_cfg;
|
|
spi_pkg::status_t s_stat;
|
|
logic [31:0] s_claim, s_ready;
|
|
logic s_handback, s_credit_fault, s_reg_credit_fault, s_pacing_fault;
|
|
logic s_fifo_pending;
|
|
logic [1:0] s_credit_pending, s_pacing_pending, s_reg_credit_pending;
|
|
logic [1:0] s_credit_valid, s_credit_retire, s_credit_commit;
|
|
logic [3:0] s_dma_stat;
|
|
logic s_unused;
|
|
assign s_cfg = u_ctrl.cfg;
|
|
assign s_stat = u_ctrl.stat;
|
|
// Only personality bits feed the GPIO guard; other fields feed the core/reg blocks.
|
|
assign s_unused = ^s_cfg;
|
|
assign s_credit_fault = s_reg_credit_fault | s_pacing_fault;
|
|
assign s_credit_pending = s_pacing_pending | s_reg_credit_pending;
|
|
spi_dma_pacing u_dma_pacing (
|
|
.clk_i (clk_i),
|
|
.rst_n_i (rst_n_i),
|
|
.enable_i (EnableDma),
|
|
.tx_binding_i (s_cfg.tx_binding),
|
|
.rx_binding_i (s_cfg.rx_binding),
|
|
.dma_start_pending_i(dma_start_pending_i),
|
|
.dma_status_i (dma_status_i),
|
|
.dma_error_i (dma_error_i),
|
|
.credit_valid_i (credit_valid_i),
|
|
.credit_retire_i (credit_retire_i),
|
|
.credit_commit_i (s_credit_commit),
|
|
.credit_valid_o (s_credit_valid),
|
|
.credit_retire_o (s_credit_retire),
|
|
.credit_pending_o (s_pacing_pending),
|
|
.dma_status_o (s_dma_stat),
|
|
.credit_fault_o (s_pacing_fault),
|
|
.busy_o ()
|
|
);
|
|
spi_gpio_guard u_gpio_guard (
|
|
.session_i (s_cfg.session),
|
|
.user_select_i (user_select_i),
|
|
.handoff_i (handoff_i),
|
|
.alt_enable_i (alt_enable_i),
|
|
.alt_select_i (alt_select_i),
|
|
.output_enable_i(output_enable_i),
|
|
.open_drain_i (open_drain_i),
|
|
.gpio_ready_i (gpio_ready_i),
|
|
.claim_o (s_claim),
|
|
.ready_o (s_ready),
|
|
.handback_o (s_handback)
|
|
);
|
|
spi_reg u_reg (
|
|
.clk_i (clk_i),
|
|
.rst_n_i (rst_n_i),
|
|
.clock_hz_i (clock_hz_i),
|
|
.origin_i (origin_i),
|
|
.request_i (request_i),
|
|
.channel_i (channel_i),
|
|
.credit_valid_i (s_credit_valid),
|
|
.credit_retire_i (s_credit_retire),
|
|
.dma_status_i (s_dma_stat),
|
|
.dma_start_pending_i(dma_start_pending_i),
|
|
.credit_commit_o (s_credit_commit),
|
|
.credit_pending_o (s_reg_credit_pending),
|
|
.fifo_pending_o (s_fifo_pending),
|
|
.credit_fault_o (s_reg_credit_fault),
|
|
.irq_o (irq_o),
|
|
.apb4 (apb4),
|
|
.ctrl (u_ctrl)
|
|
);
|
|
assign credit_commit_o = s_credit_commit;
|
|
assign session_owned_o = s_stat.status[5];
|
|
assign lifecycle_idle_o = s_stat.status[10] && s_stat.status[11] && !s_stat.status[5];
|
|
spi_master_core u_master_core (
|
|
.apb_pending_i (s_fifo_pending),
|
|
.clk_i (clk_i),
|
|
.rst_n_i (rst_n_i),
|
|
.claim_i (s_claim),
|
|
.ready_pins_i (s_ready),
|
|
.gpio_ready_i (gpio_ready_i),
|
|
.handback_i (s_handback),
|
|
.dma_status_i (s_dma_stat),
|
|
.dma_start_pending_i(dma_start_pending_i),
|
|
.dma_error_i (dma_error_i),
|
|
.credit_fault_i (s_credit_fault),
|
|
.miso_i (miso_i),
|
|
.sck_o (sck_o),
|
|
.mosi_o (mosi_o),
|
|
.cs_n_o (cs_n_o),
|
|
.output_enable_o (output_enable_o),
|
|
.ctrl (u_ctrl)
|
|
);
|
|
endmodule
|