mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-04 22:32:36 +00:00
- Implemented tests for AXI4 async bridge functionality, including transfer and warm flush scenarios. - Added tests for AXI4 data crossbar to validate concurrent outstanding requests and ACL handling. - Introduced clock frequency monitor tests to ensure detection of clock stop and restart events. - Developed tests for extension DMA master to verify copy operations, tail strobe behavior, and timeout handling. - Created tests for HP lifecycle controller to validate drain, flush, and forced reset functionalities. - Updated existing test scripts to include new RTL components and ensure proper simulation configurations.
410 lines
11 KiB
Systemverilog
410 lines
11 KiB
Systemverilog
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
|
// SPDX-License-Identifier: MulanPSL-2.0
|
|
|
|
module soc_data_plane (
|
|
// verilog_format: off -- preserve the LP/HP and memory-target boundary columns
|
|
input logic clk_lp_i,
|
|
input logic rst_lp_n_i,
|
|
input logic clk_io_i,
|
|
input logic rst_io_n_i,
|
|
input logic clk_hp_i,
|
|
input logic rst_hp_n_i,
|
|
input logic block_new_i,
|
|
input logic recovery_i,
|
|
input logic flush_i,
|
|
input logic [1:0] mem_pad_mode_i,
|
|
input logic ext_h_block_i,
|
|
input logic [31:0] ext_h_read_base_i,
|
|
input logic [31:0] ext_h_read_limit_i,
|
|
input logic [31:0] ext_h_write_base_i,
|
|
input logic [31:0] ext_h_write_limit_i,
|
|
axi4_if.slave hp_icache_axi4,
|
|
axi4_if.slave hp_dcache_axi4,
|
|
axi4_if.slave dma_axi4,
|
|
axi4_if.slave sdio0_axi4,
|
|
axi4_if.slave sdio1_axi4,
|
|
axi4_if.slave spisd_axi4,
|
|
axi4_if.slave usb2_axi4,
|
|
axi4_if.slave lp_data_axi4,
|
|
axi4_if.slave ext_h_axi4,
|
|
axi4_if.master sram_gateway_axi4,
|
|
axi4_if.master sdram_gateway_axi4,
|
|
axi4_if.master qpi_gateway_axi4,
|
|
axi4_if.master opi_gateway_axi4,
|
|
axi4_if.master xpi_gateway_axi4,
|
|
output logic idle_o,
|
|
output logic flush_busy_o,
|
|
output logic ext_h_idle_o,
|
|
output logic [7:0] outstanding_read_o,
|
|
output logic [7:0] outstanding_write_o,
|
|
output logic fault_valid_o,
|
|
output logic [2:0] fault_master_o,
|
|
output logic [2:0] fault_target_o,
|
|
output logic [31:0] fault_addr_o,
|
|
output logic fault_write_o,
|
|
output logic [3:0] fault_reason_o
|
|
// verilog_format: on
|
|
);
|
|
localparam int unsigned NumIoMasters = 3;
|
|
localparam int unsigned NumMemoryTargets = 5;
|
|
|
|
logic s_block_new_hp;
|
|
logic [ 1:0] s_mem_pad_mode_hp;
|
|
logic [ NumIoMasters-1:0] s_io_clear_busy;
|
|
logic [NumMemoryTargets-1:0] s_target_clear_busy;
|
|
logic s_lp_clear_busy;
|
|
logic s_ext_clear_busy;
|
|
logic [ NumIoMasters-1:0][7:0] unused_io_epoch;
|
|
logic [NumMemoryTargets-1:0][7:0] unused_target_epoch;
|
|
logic [ 7:0] unused_lp_epoch;
|
|
logic [ 7:0] unused_ext_epoch;
|
|
logic [ 2:0] s_unused_epoch;
|
|
|
|
axi4_if #(
|
|
.ADDR_WIDTH(32),
|
|
.DATA_WIDTH(64),
|
|
.ID_WIDTH (6),
|
|
.USER_WIDTH(1)
|
|
) u_master_axi4[8] (
|
|
.aclk (clk_hp_i),
|
|
.aresetn(rst_hp_n_i)
|
|
);
|
|
axi4_if #(
|
|
.ADDR_WIDTH(32),
|
|
.DATA_WIDTH(64),
|
|
.ID_WIDTH (6),
|
|
.USER_WIDTH(1)
|
|
) u_target_axi4[6] (
|
|
.aclk (clk_hp_i),
|
|
.aresetn(rst_hp_n_i)
|
|
);
|
|
axi4_if #(
|
|
.ADDR_WIDTH(32),
|
|
.DATA_WIDTH(64),
|
|
.ID_WIDTH (6),
|
|
.USER_WIDTH(1)
|
|
) u_hp_icache_prefixed_axi4 (
|
|
.aclk (clk_hp_i),
|
|
.aresetn(rst_hp_n_i)
|
|
);
|
|
axi4_if #(
|
|
.ADDR_WIDTH(32),
|
|
.DATA_WIDTH(64),
|
|
.ID_WIDTH (6),
|
|
.USER_WIDTH(1)
|
|
) u_hp_dcache_prefixed_axi4 (
|
|
.aclk (clk_hp_i),
|
|
.aresetn(rst_hp_n_i)
|
|
);
|
|
axi4_if #(
|
|
.ADDR_WIDTH(32),
|
|
.DATA_WIDTH(32),
|
|
.ID_WIDTH (1),
|
|
.USER_WIDTH(1)
|
|
) u_io_lp_axi4[NumIoMasters] (
|
|
.aclk (clk_io_i),
|
|
.aresetn(rst_io_n_i)
|
|
);
|
|
axi4_if #(
|
|
.ADDR_WIDTH(32),
|
|
.DATA_WIDTH(32),
|
|
.ID_WIDTH (1),
|
|
.USER_WIDTH(1)
|
|
) u_io_hp_axi4[NumIoMasters] (
|
|
.aclk (clk_hp_i),
|
|
.aresetn(rst_hp_n_i)
|
|
);
|
|
axi4_if #(
|
|
.ADDR_WIDTH(32),
|
|
.DATA_WIDTH(32),
|
|
.ID_WIDTH (1),
|
|
.USER_WIDTH(1)
|
|
) u_io_idle_axi4[2] (
|
|
.aclk (clk_io_i),
|
|
.aresetn(rst_io_n_i)
|
|
);
|
|
axi4_if #(
|
|
.ADDR_WIDTH(32),
|
|
.DATA_WIDTH(32),
|
|
.ID_WIDTH (1),
|
|
.USER_WIDTH(1)
|
|
) u_lp_data_hp_axi4 (
|
|
.aclk (clk_hp_i),
|
|
.aresetn(rst_hp_n_i)
|
|
);
|
|
axi4_if #(
|
|
.ADDR_WIDTH(32),
|
|
.DATA_WIDTH(64),
|
|
.ID_WIDTH (3),
|
|
.USER_WIDTH(1)
|
|
) u_ext_h_hp_axi4 (
|
|
.aclk (clk_hp_i),
|
|
.aresetn(rst_hp_n_i)
|
|
);
|
|
axi4_if #(
|
|
.ADDR_WIDTH(32),
|
|
.DATA_WIDTH(64),
|
|
.ID_WIDTH (3),
|
|
.USER_WIDTH(1)
|
|
) u_ext_h_gated_axi4 (
|
|
.aclk (clk_io_i),
|
|
.aresetn(rst_io_n_i)
|
|
);
|
|
axi4_if #(
|
|
.ADDR_WIDTH(32),
|
|
.DATA_WIDTH(64),
|
|
.ID_WIDTH (6),
|
|
.USER_WIDTH(1)
|
|
) u_ext_h_prefixed_axi4 (
|
|
.aclk (clk_hp_i),
|
|
.aresetn(rst_hp_n_i)
|
|
);
|
|
axi4_if #(
|
|
.ADDR_WIDTH(32),
|
|
.DATA_WIDTH(32),
|
|
.ID_WIDTH (1),
|
|
.USER_WIDTH(1)
|
|
) u_target_hp_axi4[NumMemoryTargets] (
|
|
.aclk (clk_hp_i),
|
|
.aresetn(rst_hp_n_i)
|
|
);
|
|
axi4_if #(
|
|
.ADDR_WIDTH(32),
|
|
.DATA_WIDTH(32),
|
|
.ID_WIDTH (1),
|
|
.USER_WIDTH(1)
|
|
) u_gateway_lp_axi4[NumMemoryTargets] (
|
|
.aclk (clk_lp_i),
|
|
.aresetn(rst_lp_n_i)
|
|
);
|
|
|
|
cdc_sync #(
|
|
.STAGE (2),
|
|
.DATA_WIDTH(1)
|
|
) u_block_new_sync (
|
|
.clk_i (clk_hp_i),
|
|
.rst_n_i(rst_hp_n_i),
|
|
.dat_i (block_new_i),
|
|
.dat_o (s_block_new_hp)
|
|
);
|
|
cdc_sync #(
|
|
.STAGE (2),
|
|
.DATA_WIDTH(2)
|
|
) u_mem_pad_mode_sync (
|
|
.clk_i (clk_hp_i),
|
|
.rst_n_i(rst_hp_n_i),
|
|
.dat_i (mem_pad_mode_i),
|
|
.dat_o (s_mem_pad_mode_hp)
|
|
);
|
|
|
|
axi4_id_prefix #(
|
|
.MasterIndex(3'd0)
|
|
) u_hp_icache_prefix (
|
|
.source(hp_icache_axi4),
|
|
.sink (u_hp_icache_prefixed_axi4)
|
|
);
|
|
axi4_connector u_hp_icache_connector (
|
|
.source(u_hp_icache_prefixed_axi4),
|
|
.sink (u_master_axi4[0])
|
|
);
|
|
axi4_id_prefix #(
|
|
.MasterIndex(3'd1)
|
|
) u_hp_dcache_prefix (
|
|
.source(hp_dcache_axi4),
|
|
.sink (u_hp_dcache_prefixed_axi4)
|
|
);
|
|
axi4_connector u_hp_dcache_connector (
|
|
.source(u_hp_dcache_prefixed_axi4),
|
|
.sink (u_master_axi4[1])
|
|
);
|
|
|
|
axi4_connector u_dma_source_connector (
|
|
.source(dma_axi4),
|
|
.sink (u_io_lp_axi4[0])
|
|
);
|
|
hp_axi4_mux3 u_io_gateway_a (
|
|
.clk_i (clk_io_i),
|
|
.rst_n_i(rst_io_n_i),
|
|
.icache (u_io_idle_axi4[0]),
|
|
.dcache (sdio0_axi4),
|
|
.mmio (usb2_axi4),
|
|
.axi4 (u_io_lp_axi4[1])
|
|
);
|
|
hp_axi4_mux3 u_io_gateway_b (
|
|
.clk_i (clk_io_i),
|
|
.rst_n_i(rst_io_n_i),
|
|
.icache (u_io_idle_axi4[1]),
|
|
.dcache (spisd_axi4),
|
|
.mmio (sdio1_axi4),
|
|
.axi4 (u_io_lp_axi4[2])
|
|
);
|
|
axi4_master_idle u_io_gateway_a_idle (.axi4(u_io_idle_axi4[0]));
|
|
axi4_master_idle u_io_gateway_b_idle (.axi4(u_io_idle_axi4[1]));
|
|
|
|
for (genvar master = 0; master < NumIoMasters; master++) begin : gen_io_master
|
|
axi4_async_bridge #(
|
|
.DataWidth(32),
|
|
.IdWidth (1)
|
|
) u_io_cdc (
|
|
.src_clk_i (clk_io_i),
|
|
.src_rst_n_i (rst_io_n_i),
|
|
.dst_clk_i (clk_hp_i),
|
|
.dst_rst_n_i (rst_hp_n_i),
|
|
.clear_i (flush_i),
|
|
.clear_busy_o(s_io_clear_busy[master]),
|
|
.epoch_o (unused_io_epoch[master]),
|
|
.src_axi4 (u_io_lp_axi4[master]),
|
|
.dst_axi4 (u_io_hp_axi4[master])
|
|
);
|
|
axi4_upsizer_32to64 #(
|
|
.MasterIndex(3'(master + 2))
|
|
) u_io_upsizer (
|
|
.clk_i (clk_hp_i),
|
|
.rst_n_i(rst_hp_n_i),
|
|
.narrow (u_io_hp_axi4[master]),
|
|
.wide (u_master_axi4[master+2])
|
|
);
|
|
end
|
|
|
|
axi4_async_bridge #(
|
|
.DataWidth(32),
|
|
.IdWidth (1)
|
|
) u_lp_data_cdc (
|
|
.src_clk_i (clk_lp_i),
|
|
.src_rst_n_i (rst_lp_n_i),
|
|
.dst_clk_i (clk_hp_i),
|
|
.dst_rst_n_i (rst_hp_n_i),
|
|
.clear_i (flush_i),
|
|
.clear_busy_o(s_lp_clear_busy),
|
|
.epoch_o (unused_lp_epoch),
|
|
.src_axi4 (lp_data_axi4),
|
|
.dst_axi4 (u_lp_data_hp_axi4)
|
|
);
|
|
axi4_upsizer_32to64 #(
|
|
.MasterIndex(3'd5)
|
|
) u_lp_data_upsizer (
|
|
.clk_i (clk_hp_i),
|
|
.rst_n_i(rst_hp_n_i),
|
|
.narrow (u_lp_data_hp_axi4),
|
|
.wide (u_master_axi4[5])
|
|
);
|
|
axi4_master_idle u_reserved_master_idle (.axi4(u_master_axi4[6]));
|
|
|
|
axi4_async_bridge #(
|
|
.DataWidth(64),
|
|
.IdWidth (3)
|
|
) u_ext_h_cdc (
|
|
.src_clk_i (clk_io_i),
|
|
.src_rst_n_i (rst_io_n_i),
|
|
.dst_clk_i (clk_hp_i),
|
|
.dst_rst_n_i (rst_hp_n_i),
|
|
.clear_i (flush_i),
|
|
.clear_busy_o(s_ext_clear_busy),
|
|
.epoch_o (unused_ext_epoch),
|
|
.src_axi4 (u_ext_h_gated_axi4),
|
|
.dst_axi4 (u_ext_h_hp_axi4)
|
|
);
|
|
axi4_address_gate u_ext_h_address_gate (
|
|
.clk_i (clk_io_i),
|
|
.rst_n_i (rst_io_n_i),
|
|
.block_new_i(ext_h_block_i),
|
|
.source (ext_h_axi4),
|
|
.sink (u_ext_h_gated_axi4),
|
|
.idle_o (ext_h_idle_o)
|
|
);
|
|
axi4_id_prefix #(
|
|
.MasterIndex(3'd7)
|
|
) u_ext_h_prefix (
|
|
.source(u_ext_h_hp_axi4),
|
|
.sink (u_ext_h_prefixed_axi4)
|
|
);
|
|
axi4_connector u_ext_h_connector (
|
|
.source(u_ext_h_prefixed_axi4),
|
|
.sink (u_master_axi4[7])
|
|
);
|
|
|
|
axi4_data_crossbar u_data_crossbar (
|
|
.clk_i (clk_hp_i),
|
|
.rst_n_i (rst_hp_n_i),
|
|
.block_new_i (s_block_new_hp),
|
|
.recovery_i (recovery_i),
|
|
.mem_pad_mode_i (s_mem_pad_mode_hp),
|
|
.ext_h_read_base_i (ext_h_read_base_i),
|
|
.ext_h_read_limit_i (ext_h_read_limit_i),
|
|
.ext_h_write_base_i (ext_h_write_base_i),
|
|
.ext_h_write_limit_i(ext_h_write_limit_i),
|
|
.masters (u_master_axi4),
|
|
.targets (u_target_axi4),
|
|
.idle_o (idle_o),
|
|
.outstanding_read_o (outstanding_read_o),
|
|
.outstanding_write_o(outstanding_write_o),
|
|
.fault_valid_o (fault_valid_o),
|
|
.fault_master_o (fault_master_o),
|
|
.fault_target_o (fault_target_o),
|
|
.fault_addr_o (fault_addr_o),
|
|
.fault_write_o (fault_write_o),
|
|
.fault_reason_o (fault_reason_o)
|
|
);
|
|
|
|
for (genvar target = 0; target < NumMemoryTargets; target++) begin : gen_memory_target
|
|
axi4_downsizer_64to32 #(
|
|
.WideIdWidth(6)
|
|
) u_target_downsizer (
|
|
.clk_i (clk_hp_i),
|
|
.rst_n_i(rst_hp_n_i),
|
|
.wide (u_target_axi4[target]),
|
|
.narrow (u_target_hp_axi4[target])
|
|
);
|
|
axi4_async_bridge #(
|
|
.DataWidth(32),
|
|
.IdWidth (1)
|
|
) u_target_cdc (
|
|
.src_clk_i (clk_hp_i),
|
|
.src_rst_n_i (rst_hp_n_i),
|
|
.dst_clk_i (clk_lp_i),
|
|
.dst_rst_n_i (rst_lp_n_i),
|
|
.clear_i (flush_i),
|
|
.clear_busy_o(s_target_clear_busy[target]),
|
|
.epoch_o (unused_target_epoch[target]),
|
|
.src_axi4 (u_target_hp_axi4[target]),
|
|
.dst_axi4 (u_gateway_lp_axi4[target])
|
|
);
|
|
end
|
|
|
|
axi4_error_slave #(
|
|
.Response(2'b11),
|
|
.IdWidth (6)
|
|
) u_data_error_slave (
|
|
.clk_i (clk_hp_i),
|
|
.rst_n_i(rst_hp_n_i),
|
|
.axi4 (u_target_axi4[5])
|
|
);
|
|
|
|
assign flush_busy_o = (|s_io_clear_busy) || (|s_target_clear_busy) ||
|
|
s_lp_clear_busy || s_ext_clear_busy;
|
|
assign s_unused_epoch = {
|
|
^unused_io_epoch, ^unused_target_epoch, ^{unused_lp_epoch, unused_ext_epoch}
|
|
};
|
|
|
|
axi4_connector u_sram_gateway_connector (
|
|
.source(u_gateway_lp_axi4[0]),
|
|
.sink (sram_gateway_axi4)
|
|
);
|
|
axi4_connector u_sdram_gateway_connector (
|
|
.source(u_gateway_lp_axi4[1]),
|
|
.sink (sdram_gateway_axi4)
|
|
);
|
|
axi4_connector u_qpi_gateway_connector (
|
|
.source(u_gateway_lp_axi4[2]),
|
|
.sink (qpi_gateway_axi4)
|
|
);
|
|
axi4_connector u_opi_gateway_connector (
|
|
.source(u_gateway_lp_axi4[3]),
|
|
.sink (opi_gateway_axi4)
|
|
);
|
|
axi4_connector u_xpi_gateway_connector (
|
|
.source(u_gateway_lp_axi4[4]),
|
|
.sink (xpi_gateway_axi4)
|
|
);
|
|
endmodule
|