mirror of
https://github.com/retroSoC/common.git
synced 2026-11-04 22:32:37 +00:00
- 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.
108 lines
2.8 KiB
Systemverilog
108 lines
2.8 KiB
Systemverilog
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
|
// SPDX-License-Identifier: MulanPSL-2.0
|
|
// Small combinational primitives intentionally have no external dependency.
|
|
|
|
module bit_count #(
|
|
parameter int WIDTH = 32,
|
|
parameter int COUNT_WIDTH = $clog2(WIDTH + 1)
|
|
) (
|
|
input logic [ WIDTH-1:0] value_i,
|
|
output logic [COUNT_WIDTH-1:0] count_o
|
|
);
|
|
initial begin
|
|
if (WIDTH < 1 || COUNT_WIDTH < $clog2(WIDTH + 1)) begin
|
|
$fatal(1, "bit_count: WIDTH must be positive and COUNT_WIDTH sufficient");
|
|
end
|
|
end
|
|
|
|
always_comb begin
|
|
count_o = '0;
|
|
for (int unsigned bit_idx = 0; bit_idx < WIDTH; bit_idx++) begin
|
|
count_o = count_o + value_i[bit_idx];
|
|
end
|
|
end
|
|
endmodule
|
|
|
|
module leading_zero_count #(
|
|
parameter int WIDTH = 32,
|
|
parameter int COUNT_WIDTH = $clog2(WIDTH + 1)
|
|
) (
|
|
input logic [ WIDTH-1:0] value_i,
|
|
output logic [COUNT_WIDTH-1:0] count_o,
|
|
output logic all_zero_o
|
|
);
|
|
logic s_seen_one;
|
|
initial begin
|
|
if (WIDTH < 1 || COUNT_WIDTH < $clog2(WIDTH + 1)) begin
|
|
$fatal(1, "leading_zero_count: WIDTH must be positive and COUNT_WIDTH sufficient");
|
|
end
|
|
end
|
|
|
|
always_comb begin
|
|
count_o = '0;
|
|
s_seen_one = 1'b0;
|
|
for (int bit_idx = WIDTH - 1; bit_idx >= 0; bit_idx--) begin
|
|
if (!s_seen_one && value_i[bit_idx]) begin
|
|
s_seen_one = 1'b1;
|
|
end else if (!s_seen_one) begin
|
|
count_o = count_o + 1'b1;
|
|
end
|
|
end
|
|
all_zero_o = !s_seen_one;
|
|
end
|
|
endmodule
|
|
|
|
module onehot_check #(
|
|
parameter int WIDTH = 32,
|
|
parameter bit ALLOW_ZERO = 1'b0
|
|
) (
|
|
input logic [WIDTH-1:0] value_i,
|
|
output logic valid_o
|
|
);
|
|
initial begin
|
|
if (WIDTH < 1) $fatal(1, "onehot_check: WIDTH must be positive");
|
|
end
|
|
|
|
always_comb begin
|
|
valid_o = (value_i != '0) && ((value_i & (value_i - 1'b1)) == '0);
|
|
if (ALLOW_ZERO && value_i == '0) begin
|
|
valid_o = 1'b1;
|
|
end
|
|
end
|
|
endmodule
|
|
|
|
module onehot_to_index #(
|
|
parameter int WIDTH = 32,
|
|
parameter int INDEX_WIDTH = (WIDTH > 1) ? $clog2(WIDTH) : 1
|
|
) (
|
|
input logic [ WIDTH-1:0] value_i,
|
|
output logic [INDEX_WIDTH-1:0] index_o,
|
|
output logic valid_o
|
|
);
|
|
logic [WIDTH-1:0] s_onehot;
|
|
|
|
initial begin
|
|
if (WIDTH < 1 || INDEX_WIDTH < ((WIDTH > 1) ? $clog2(WIDTH) : 1)) begin
|
|
$fatal(1, "onehot_to_index: WIDTH must be positive and INDEX_WIDTH sufficient");
|
|
end
|
|
end
|
|
|
|
onehot_check #(
|
|
.WIDTH (WIDTH),
|
|
.ALLOW_ZERO(1'b0)
|
|
) u_onehot_check (
|
|
.value_i(value_i),
|
|
.valid_o(valid_o)
|
|
);
|
|
|
|
assign s_onehot = value_i;
|
|
always_comb begin
|
|
index_o = '0;
|
|
for (int unsigned bit_idx = 0; bit_idx < WIDTH; bit_idx++) begin
|
|
if (s_onehot[bit_idx]) begin
|
|
index_o = INDEX_WIDTH'(bit_idx);
|
|
end
|
|
end
|
|
end
|
|
endmodule
|