* Initial plan * Fix nonconstant index error by using unpacked structs and arrays Co-authored-by: arnavsacheti <36746504+arnavsacheti@users.noreply.github.com> * Add comprehensive tests for Questa compatibility with instance arrays Co-authored-by: arnavsacheti <36746504+arnavsacheti@users.noreply.github.com> * Add intermediate signals for interface array fanin to fix Questa compatibility Questa simulator rejects indexing interface arrays with non-constant variables in procedural blocks (always_comb). This fix creates intermediate unpacked array signals that are assigned from interface arrays using generate loops (with genvar), then references those intermediates in the fanin logic. Changes: - Added fanin_intermediate_gen.py to generate intermediate signals - Modified APB3/APB4/AXI4-Lite cpuif classes to use intermediates for interface arrays - Updated templates to include intermediate signal section - Intermediate signals use genvar indexing (legal) instead of variable indexing (illegal in Questa) Co-authored-by: arnavsacheti <36746504+arnavsacheti@users.noreply.github.com> * Fix type checking and formatting issues in fanin intermediate generator - Added proper null checks for node.array_dimensions to avoid type errors - Used getattr() to safely access is_interface and _interface attributes - Added early returns when interface is None to prevent errors - Fixed formatting issues in fanin_intermediate_gen.py - All type checks now pass (only pre-existing errors remain in other files) - All 67 tests still pass Co-authored-by: arnavsacheti <36746504+arnavsacheti@users.noreply.github.com> * Fix test collection when cocotb is not installed The cocotb test files (test_runner.py) have imports that fail at module level when cocotb is not installed, causing pytest collection to fail. This prevents running tests in environments without cocotb dependencies. Solution: Updated conftest.py to conditionally ignore cocotb tests when cocotb is not available, allowing tests to pass in both environments (with and without cocotb). - When cocotb is available: only ignore test_register_access.py files (existing behavior) - When cocotb is not available: ignore all files under cocotb/** directories This allows CI to run all 67 non-simulation tests successfully without requiring cocotb/verilator dependencies for basic testing. Co-authored-by: arnavsacheti <36746504+arnavsacheti@users.noreply.github.com> * add default for unpacked struct * cocotb is test dependancy * Refactor fanin intermediate signal logic to cpuif level Moved the interface-specific signal assignment logic from fanin_intermediate_gen.py to individual cpuif classes (APB3Cpuif, APB4Cpuif, AXI4LiteCpuif). This follows better architecture principles where each cpuif knows which signals it needs. Changes: - Added fanin_intermediate_assignments() method to BaseCpuif - Implemented fanin_intermediate_assignments() in APB3Cpuif, APB4Cpuif, and AXI4LiteCpuif - Updated FaninIntermediateGenerator to call the cpuif method instead of checking interface type - Removed interface type checking logic from fanin_intermediate_gen.py This makes the code more maintainable and follows the single responsibility principle - each cpuif class knows its own signal requirements. Co-authored-by: arnavsacheti <36746504+arnavsacheti@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: arnavsacheti <36746504+arnavsacheti@users.noreply.github.com>
67 lines
3.3 KiB
Systemverilog
67 lines
3.3 KiB
Systemverilog
{%- if cpuif.is_interface -%}
|
|
`ifndef SYNTHESIS
|
|
initial begin
|
|
// Width checks (AXI4-Lite)
|
|
assert_bad_awaddr_width: assert($bits({{cpuif.signal("AWADDR")}}) >= {{ds.package_name}}::{{ds.module_name|upper}}_MIN_ADDR_WIDTH)
|
|
else $error("AWADDR width %0d < MIN_ADDR_WIDTH %0d",
|
|
$bits({{cpuif.signal("AWADDR")}}), {{ds.package_name}}::{{ds.module_name|upper}}_MIN_ADDR_WIDTH);
|
|
|
|
assert_bad_araddr_width: assert($bits({{cpuif.signal("ARADDR")}}) >= {{ds.package_name}}::{{ds.module_name|upper}}_MIN_ADDR_WIDTH)
|
|
else $error("ARADDR width %0d < MIN_ADDR_WIDTH %0d",
|
|
$bits({{cpuif.signal("ARADDR")}}), {{ds.package_name}}::{{ds.module_name|upper}}_MIN_ADDR_WIDTH);
|
|
|
|
assert_bad_data_width: assert($bits({{cpuif.signal("WDATA")}}) == {{ds.package_name}}::{{ds.module_name|upper}}_DATA_WIDTH)
|
|
else $error("WDATA width %0d != DATA_WIDTH %0d",
|
|
$bits({{cpuif.signal("WDATA")}}), {{ds.package_name}}::{{ds.module_name|upper}}_DATA_WIDTH);
|
|
end
|
|
|
|
// Simple handshake sanity (one-cycle implication; relax/adjust as needed)
|
|
assert_rd_resp_enc: assert property (@(posedge {{cpuif.signal("ACLK")}})
|
|
{{cpuif.signal("RVALID")}} |-> (^{{cpuif.signal("RRESP")}} !== 1'bx))
|
|
else $error("RRESP must be a legal AXI response when RVALID is high");
|
|
|
|
assert_wr_resp_enc: assert property (@(posedge {{cpuif.signal("ACLK")}})
|
|
{{cpuif.signal("BVALID")}} |-> (^{{cpuif.signal("BRESP")}} !== 1'bx))
|
|
else $error("BRESP must be a legal AXI response when BVALID is high");
|
|
`endif
|
|
{% endif -%}
|
|
|
|
|
|
assign cpuif_req = {{cpuif.signal("AWVALID")}} | {{cpuif.signal("ARVALID")}};
|
|
assign cpuif_wr_en = {{cpuif.signal("AWVALID")}} & {{cpuif.signal("WVALID")}};
|
|
assign cpuif_rd_en = {{cpuif.signal("ARVALID")}};
|
|
|
|
assign cpuif_wr_addr = {{cpuif.signal("AWADDR")}};
|
|
assign cpuif_rd_addr = {{cpuif.signal("ARADDR")}};
|
|
|
|
assign cpuif_wr_data = {{cpuif.signal("WDATA")}};
|
|
assign cpuif_wr_byte_en = {{cpuif.signal("WSTRB")}};
|
|
|
|
//
|
|
// Return paths back to AXI master from generic cpuif_*
|
|
// Read: ack=RVALID, err=RRESP[1] (SLVERR/DECERR), data=RDATA
|
|
//
|
|
assign {{cpuif.signal("RDATA")}} = cpuif_rd_data;
|
|
assign {{cpuif.signal("RVALID")}} = cpuif_rd_ack;
|
|
assign {{cpuif.signal("RRESP")}} = (cpuif_rd_err | cpuif_rd_sel.cpuif_err | cpuif_wr_sel.cpuif_err) ? 2'b10 : 2'b00;
|
|
|
|
// Write: ack=BVALID, err=BRESP[1]
|
|
assign {{cpuif.signal("BVALID")}} = cpuif_wr_ack;
|
|
assign {{cpuif.signal("BRESP")}} = (cpuif_wr_err | cpuif_wr_sel.cpuif_err | cpuif_rd_sel.cpuif_err) ? 2'b10 : 2'b00;
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Fanout CPU Bus interface signals
|
|
//--------------------------------------------------------------------------
|
|
{{fanout|walk(cpuif=cpuif)}}
|
|
{%- if cpuif.is_interface %}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Intermediate signals for interface array fanin
|
|
//--------------------------------------------------------------------------
|
|
{{fanin_intermediate|walk(cpuif=cpuif)}}
|
|
{%- endif %}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Fanin CPU Bus interface signals
|
|
//--------------------------------------------------------------------------
|
|
{{fanin|walk(cpuif=cpuif)}} |