mirror of
https://github.com/retroSoC/common.git
synced 2026-11-04 22:32:37 +00:00
feat: enhance validation and error handling in RTL modules
- Added geometry validation for BIT_WIDTH, WORD_DEPTH, and ADDR_WIDTH in tech_ram, tech_ram_bm, tech_regfile, and tech_regfile_bm modules to ensure proper configurations. - Implemented address range checks in tech_ram, tech_ram_bm, tech_regfile, and tech_regfile_bm modules to prevent out-of-bounds access. - Improved error messages for unsupported access types in regfield module, including validation for DATA_WIDTH. - Added DATA_WIDTH validation in spill_register module to ensure positive values. - Refactored APB4AXI4Master and APB4Master classes to streamline constructor definitions and improve readability. - Enhanced AXI4Master class with additional burst address calculations and legality checks for read/write operations. - Updated read/write tasks in AXI4Master to include error handling for response mismatches and illegal burst conditions. - Simplified the filtering of reference data in rd_check task of AXI4Master to improve clarity and maintainability. - Cleaned up the TestBase class constructor for consistency and clarity.
This commit is contained in:
36 files changed
+1278
-349
No files matched your search
+81
-31
@@ -27,7 +27,8 @@
|
||||
`include "config.svh"
|
||||
|
||||
module cdc_2phase #(
|
||||
parameter int DATA_WIDTH = 32
|
||||
parameter int DATA_WIDTH = 32,
|
||||
parameter int SYNC_STAGES = 2
|
||||
) (
|
||||
input logic src_clk_i,
|
||||
input logic src_rst_n_i,
|
||||
@@ -45,23 +46,58 @@ module cdc_2phase #(
|
||||
logic s_async_req;
|
||||
logic s_async_ack;
|
||||
logic [DATA_WIDTH-1:0] s_async_data;
|
||||
logic s_link_rst_n;
|
||||
logic s_src_rst_n;
|
||||
logic s_dst_rst_n;
|
||||
logic s_src_ready;
|
||||
logic s_dst_valid;
|
||||
|
||||
cdc_2phase_src #(DATA_WIDTH) u_cdc_2phase_src (
|
||||
initial begin
|
||||
if (DATA_WIDTH < 1 || SYNC_STAGES < 2) begin
|
||||
$fatal(1, "cdc_2phase: DATA_WIDTH must be positive and SYNC_STAGES at least two");
|
||||
end
|
||||
end
|
||||
|
||||
// A toggle handshake has no unambiguous unilateral-reset recovery state.
|
||||
// Either endpoint reset therefore aborts the in-flight item and flushes both
|
||||
// local protocol states before synchronized release.
|
||||
assign s_link_rst_n = src_rst_n_i && dst_rst_n_i;
|
||||
cdc_reset_barrier #(
|
||||
.STAGES(SYNC_STAGES)
|
||||
) u_reset_barrier (
|
||||
.clk_a_i (src_clk_i),
|
||||
.clk_b_i (dst_clk_i),
|
||||
.rst_n_i (s_link_rst_n),
|
||||
.release_i(1'b1),
|
||||
.rst_a_n_o(s_src_rst_n),
|
||||
.rst_b_n_o(s_dst_rst_n)
|
||||
);
|
||||
|
||||
assign src_ready_o = s_src_rst_n && s_src_ready;
|
||||
assign dst_valid_o = s_dst_rst_n && s_dst_valid;
|
||||
|
||||
cdc_2phase_src #(
|
||||
.DATA_WIDTH (DATA_WIDTH),
|
||||
.SYNC_STAGES(SYNC_STAGES)
|
||||
) u_cdc_2phase_src (
|
||||
.clk_i (src_clk_i),
|
||||
.rst_n_i (src_rst_n_i),
|
||||
.rst_n_i (s_src_rst_n),
|
||||
.data_i (src_data_i),
|
||||
.valid_i (src_valid_i),
|
||||
.ready_o (src_ready_o),
|
||||
.ready_o (s_src_ready),
|
||||
.async_req_o (s_async_req),
|
||||
.async_ack_i (s_async_ack),
|
||||
.async_data_o(s_async_data)
|
||||
);
|
||||
|
||||
cdc_2phase_dst #(DATA_WIDTH) u_cdc_2phase_dst (
|
||||
cdc_2phase_dst #(
|
||||
.DATA_WIDTH (DATA_WIDTH),
|
||||
.SYNC_STAGES(SYNC_STAGES)
|
||||
) u_cdc_2phase_dst (
|
||||
.clk_i (dst_clk_i),
|
||||
.rst_n_i (dst_rst_n_i),
|
||||
.rst_n_i (s_dst_rst_n),
|
||||
.data_o (dst_data_o),
|
||||
.valid_o (dst_valid_o),
|
||||
.valid_o (s_dst_valid),
|
||||
.ready_i (dst_ready_i),
|
||||
.async_req_i (s_async_req),
|
||||
.async_ack_o (s_async_ack),
|
||||
@@ -71,7 +107,8 @@ module cdc_2phase #(
|
||||
endmodule
|
||||
|
||||
module cdc_2phase_src #(
|
||||
parameter int DATA_WIDTH = 32
|
||||
parameter int DATA_WIDTH = 32,
|
||||
parameter int SYNC_STAGES = 2
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_n_i,
|
||||
@@ -88,6 +125,12 @@ module cdc_2phase_src #(
|
||||
logic s_ack_q;
|
||||
logic [DATA_WIDTH-1:0] s_data_src_d, s_data_src_q;
|
||||
|
||||
initial begin
|
||||
if (DATA_WIDTH < 1 || SYNC_STAGES < 2) begin
|
||||
$fatal(1, "cdc_2phase_src: DATA_WIDTH must be positive and SYNC_STAGES at least two");
|
||||
end
|
||||
end
|
||||
|
||||
// The req_src and data_src registers change when a new data item is accepted.
|
||||
assign s_req_src_d = (valid_i && ready_o) ? ~s_req_src_q : s_req_src_q;
|
||||
dffr #(1) u_req_src_dffr (
|
||||
@@ -105,11 +148,13 @@ module cdc_2phase_src #(
|
||||
s_data_src_q
|
||||
);
|
||||
|
||||
cdc_sync #(2, 1) u_ack_sync (
|
||||
clk_i,
|
||||
rst_n_i,
|
||||
async_ack_i,
|
||||
s_ack_q
|
||||
cdc_sync #(
|
||||
.STAGE(SYNC_STAGES)
|
||||
) u_ack_sync (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i(rst_n_i),
|
||||
.dat_i (async_ack_i),
|
||||
.dat_o (s_ack_q)
|
||||
);
|
||||
|
||||
assign ready_o = (s_req_src_q == s_ack_q);
|
||||
@@ -119,7 +164,8 @@ module cdc_2phase_src #(
|
||||
endmodule
|
||||
|
||||
module cdc_2phase_dst #(
|
||||
parameter int DATA_WIDTH = 32
|
||||
parameter int DATA_WIDTH = 32,
|
||||
parameter int SYNC_STAGES = 2
|
||||
) (
|
||||
input logic rst_n_i,
|
||||
input logic clk_i,
|
||||
@@ -132,10 +178,17 @@ module cdc_2phase_dst #(
|
||||
);
|
||||
|
||||
|
||||
logic r_req_dst_q, r_req_q0, r_req_q1;
|
||||
logic s_req_pre;
|
||||
logic s_req_sync;
|
||||
logic s_ack_dst_d, s_ack_dst_q;
|
||||
logic [DATA_WIDTH-1:0] s_data_dst_d, s_data_dst_q;
|
||||
|
||||
initial begin
|
||||
if (DATA_WIDTH < 1 || SYNC_STAGES < 2) begin
|
||||
$fatal(1, "cdc_2phase_dst: DATA_WIDTH must be positive and SYNC_STAGES at least two");
|
||||
end
|
||||
end
|
||||
|
||||
// The ack_dst register changes when a new data item is accepted.
|
||||
assign s_ack_dst_d = (valid_o && ready_i) ? ~s_ack_dst_q : s_ack_dst_q;
|
||||
dffr #(1) u_ack_dst_dffr (
|
||||
@@ -145,9 +198,9 @@ module cdc_2phase_dst #(
|
||||
s_ack_dst_q
|
||||
);
|
||||
|
||||
// The data_dst register changes when a new data item is presented. This is
|
||||
// indicated by the async_req line changing levels.
|
||||
assign s_data_dst_d = (r_req_q0 != r_req_q1 && !valid_o) ? async_data_i : s_data_dst_q;
|
||||
// Capture bundled data one cycle before the synchronized toggle becomes
|
||||
// visible as valid. The source holds it stable until acknowledgement.
|
||||
assign s_data_dst_d = (s_req_pre != s_req_sync && !valid_o) ? async_data_i : s_data_dst_q;
|
||||
dffr #(DATA_WIDTH) u_data_dst_dffr (
|
||||
clk_i,
|
||||
rst_n_i,
|
||||
@@ -155,20 +208,17 @@ module cdc_2phase_dst #(
|
||||
s_data_dst_q
|
||||
);
|
||||
|
||||
// The req_dst and req registers act as synchronization stages.
|
||||
always_ff @(posedge clk_i or negedge rst_n_i) begin
|
||||
if (!rst_n_i) begin
|
||||
r_req_dst_q <= '0;
|
||||
r_req_q0 <= '0;
|
||||
r_req_q1 <= '0;
|
||||
end else begin
|
||||
r_req_dst_q <= async_req_i;
|
||||
r_req_q0 <= r_req_dst_q;
|
||||
r_req_q1 <= r_req_q0;
|
||||
end
|
||||
end
|
||||
cdc_sync_det #(
|
||||
.STAGE(SYNC_STAGES)
|
||||
) u_req_sync (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.dat_i (async_req_i),
|
||||
.dat_pre_o(s_req_pre),
|
||||
.dat_o (s_req_sync)
|
||||
);
|
||||
|
||||
assign valid_o = (s_ack_dst_q != r_req_q1);
|
||||
assign valid_o = (s_ack_dst_q != s_req_sync);
|
||||
assign data_o = s_data_dst_q;
|
||||
assign async_ack_o = s_ack_dst_q;
|
||||
|
||||
|
||||
Reference in new issue
Block a user