diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index d918720c..ccfb431f 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -73,6 +73,14 @@ jobs: - name: Test scripts run: python3 -m pytest -q + - name: Set up locked APU simulation tools + uses: ./.github/actions/locked-tools + with: + tools: verilator sv2v iverilog + + - name: Run APU P5 simulator acceptance + run: python3 -m pytest -q tests/test_apu_codec_transport.py + - name: Lint YAML run: yamllint .github .yamllint.yml diff --git a/Makefile b/Makefile index 37de1123..c23316d7 100644 --- a/Makefile +++ b/Makefile @@ -707,4 +707,4 @@ regress-nightly: python3 $(ROOT_PATH)/scripts/regress.py --root $(ROOT_PATH) --suite nightly sim-asm: asm - $(MAKE) SIM_FIRMWARE_NAME=$(ASM_FIRMWARE_NAME) sim + $(MAKE) SIM_FIRMWARE_NAME=$(ASM_FIRMWARE_NAME) sim \ No newline at end of file diff --git a/rtl/ip/multimedia/apb4_apu.sv b/rtl/ip/multimedia/apb4_apu.sv index 72b5c8a6..c32fa48f 100644 --- a/rtl/ip/multimedia/apb4_apu.sv +++ b/rtl/ip/multimedia/apb4_apu.sv @@ -140,7 +140,7 @@ module apb4_apu ( logic [31:0] s_dma_err_addr; logic s_dma_input_pending, s_dma_output_pending; logic [63:0] s_dma_read_bytes, s_dma_write_bytes; - logic s_dma_write_burst_done; + logic s_dma_write_burst_done; logic [31:0] s_dma_write_burst_bytes; logic [63:0] s_dma_read_stalls, s_dma_write_stalls; logic s_scheduler_idle, s_scheduler_aborting, s_stream_idle; diff --git a/rtl/ip/multimedia/apu_codec_controller.sv b/rtl/ip/multimedia/apu_codec_controller.sv index 028ba108..dabe6ca2 100644 --- a/rtl/ip/multimedia/apu_codec_controller.sv +++ b/rtl/ip/multimedia/apu_codec_controller.sv @@ -329,8 +329,8 @@ module apu_codec_controller ( fault_valid_o <= 1'b0; if (transport_job_done_i) s_transport_done_q <= 1'b1; if (soft_reset_i || resource_reset_apply_i) begin - s_state_q <= Idle; - s_job_stat_q <= 32'd0; + s_state_q <= Idle; + s_job_stat_q <= 32'd0; s_transport_done_q <= 1'b0; end else begin unique case (s_state_q) diff --git a/rtl/ip/multimedia/apu_codec_transport.sv b/rtl/ip/multimedia/apu_codec_transport.sv index f9cae742..da769fa9 100644 --- a/rtl/ip/multimedia/apu_codec_transport.sv +++ b/rtl/ip/multimedia/apu_codec_transport.sv @@ -168,7 +168,7 @@ module apu_codec_transport ( logic s_input_contract_ok, s_input_reservation_ok; logic s_output_contract_ok, s_output_capacity_error, s_output_cursor_overflow; logic s_job_result_contract_ok, s_frame_commit_contract_ok; - logic s_source_info_valid; + logic s_source_info_valid; logic [1:0] s_output_channels; logic [3:0] s_output_frame_bytes; logic s_active_input, s_active_output, s_opposite_async_request; @@ -180,9 +180,9 @@ module apu_codec_transport ( logic [ 1:0] s_channels; logic [ 5:0] s_bits; begin - s_rate = source_info_i[16:0]; + s_rate = source_info_i[16:0]; s_channels = source_info_i[18:17]; - s_bits = source_info_i[24:19]; + s_bits = source_info_i[24:19]; return (source_info_i[31:25] == 7'd0) && (s_rate >= 17'd8000) && (s_rate <= 17'd96000) && (s_channels inside {2'd1, 2'd2}) && @@ -258,27 +258,9 @@ module apu_codec_transport ( ({1'b0, s_logical_output_q} + {1'b0, request_source1_i} <= {1'b0, s_output_cursor_q}); assign s_source_info_valid = source_info_valid(memory_data_i); - assign s_req_trap_detail1 = { - request_detail_aux_i, - request_opcode_i, - 4'd6, - request_pc_i, - 8'd1 - }; - assign s_req_trap_detail5 = { - request_detail_aux_i, - request_opcode_i, - 4'd6, - request_pc_i, - 8'd5 - }; - assign s_req_trap_detail9 = { - request_detail_aux_i, - request_opcode_i, - 4'd6, - request_pc_i, - 8'd9 - }; + assign s_req_trap_detail1 = {request_detail_aux_i, request_opcode_i, 4'd6, request_pc_i, 8'd1}; + assign s_req_trap_detail5 = {request_detail_aux_i, request_opcode_i, 4'd6, request_pc_i, 8'd5}; + assign s_req_trap_detail9 = {request_detail_aux_i, request_opcode_i, 4'd6, request_pc_i, 8'd9}; assign s_active_trap_detail5 = {1'b0, s_req_aux_q, s_opcode_q, 4'd6, s_pc_q, 8'd5}; assign s_active_trap_detail9 = {1'b0, s_req_aux_q, s_opcode_q, 4'd6, s_pc_q, 8'd9}; assign s_output_channels = (s_descriptor_q[0][9:8] == 2'd1) ? 2'd2 : diff --git a/rtl/mini/formal/apu_codec_formal.sv b/rtl/mini/formal/apu_codec_formal.sv index e444a4b1..4563390a 100644 --- a/rtl/mini/formal/apu_codec_formal.sv +++ b/rtl/mini/formal/apu_codec_formal.sv @@ -5,7 +5,7 @@ module apu_codec_formal_design ( input logic clk_i, output logic rst_n_i, output logic f_past_valid, - output logic [2:0] scenario, + output logic [ 2:0] scenario, output logic [ 5:0] cycle, output logic block_new, output logic context_ready, @@ -18,11 +18,11 @@ module apu_codec_formal_design ( output logic memory_claim, output logic memory_request, output logic fault_valid, - output logic [5:0] fault_code, - output logic [3:0] fault_stage, + output logic [ 5:0] fault_code, + output logic [ 3:0] fault_stage, output logic [31:0] fault_detail ); - (* anyconst *)logic [2:0] f_scenario; + (* anyconst *)logic [ 2:0] f_scenario; logic [ 5:0] s_cycle_q; logic [1023:0] s_descriptor; @@ -46,7 +46,7 @@ module apu_codec_formal_design ( ); always_comb begin - s_descriptor = '0; + s_descriptor = '0; s_descriptor[(2*32)+:32] = 32'h1000_0000; s_descriptor[(3*32)+:32] = 32'd64; s_descriptor[(4*32)+:32] = 32'h2000_0000; diff --git a/rtl/mini/formal/apu_codec_formal_props.sv b/rtl/mini/formal/apu_codec_formal_props.sv index ec42cacc..2dfcc6e5 100644 --- a/rtl/mini/formal/apu_codec_formal_props.sv +++ b/rtl/mini/formal/apu_codec_formal_props.sv @@ -9,9 +9,9 @@ module apu_codec_formal; wire block_new, context_ready, request_valid, request_ready; wire dma_request_valid, dma_request_ready, memory_claim, memory_request; wire [31:0] dma_request_addr, dma_request_bytes; - wire fault_valid; - wire [5:0] fault_code; - wire [3:0] fault_stage; + wire fault_valid; + wire [ 5:0] fault_code; + wire [ 3:0] fault_stage; wire [31:0] fault_detail; apu_codec_formal_design u_design (.*); @@ -49,7 +49,6 @@ module apu_codec_formal; cover (rst_n_i && dma_request_valid && !block_new && (cycle >= 6'd22)); cover (rst_n_i && block_new && request_valid && !request_ready); cover (rst_n_i && (scenario == 3'd1) && fault_valid && (fault_detail[7:0] == 8'd5)); - cover (rst_n_i && (scenario == 3'd2) && fault_valid && - (fault_detail[15:0] == 16'h0051)); + cover (rst_n_i && (scenario == 3'd2) && fault_valid && (fault_detail[15:0] == 16'h0051)); end endmodule diff --git a/rtl/mini/mk/formal.mk b/rtl/mini/mk/formal.mk index 58ac84af..b9ef51d6 100644 --- a/rtl/mini/mk/formal.mk +++ b/rtl/mini/mk/formal.mk @@ -220,14 +220,14 @@ $(FORMAL_DIR)/%/prove.sby: $(FORMAL_DIR)/%/design.v \ $(FORMAL_SBY_GENERATOR) python3 $(FORMAL_SBY_GENERATOR) --top $(FORMAL_TARGET_TOP)_formal --input $< \ --properties $(RTL_PATH)/formal/$(FORMAL_TARGET_TOP)_formal_props.sv --solver $(FORMAL_SOLVER) \ - --mode $(if $(filter dma apu apu_codec apu_primitives apu_sequencer $(FORMAL_APU_LOADER_TARGETS) $(FORMAL_APU_PRIMITIVE_TARGETS) gateway_a sdio onchip_ram,$*),bmc,prove) --depth $(if $(filter pll_rcu,$*),$(FORMAL_PLL_RCU_DEPTH),$(if $(filter dma,$*),$(FORMAL_DMA_DEPTH),$(if $(filter apu apu_codec apu_primitives apu_sequencer $(FORMAL_APU_LOADER_TARGETS) $(FORMAL_APU_PRIMITIVE_TARGETS),$*),$(FORMAL_APU_TARGET_DEPTH),$(if $(filter gateway_a,$*),$(FORMAL_GATEWAY_A_DEPTH),$(if $(filter sdio,$*),$(FORMAL_SDIO_DEPTH),$(if $(filter opipsram,$*),$(FORMAL_OPIPSRAM_DEPTH),$(if $(filter ws2812,$*),$(FORMAL_WS2812_DEPTH),$(if $(filter i2c,$*),$(FORMAL_I2C_DEPTH),$(if $(filter clint,$*),$(FORMAL_CLINT_DEPTH),$(if $(filter psram,$*),$(FORMAL_PSRAM_DEPTH),$(FORMAL_DEPTH))))))))))) --output $@ + --mode $(if $(filter dma apu apu_codec apu_primitives apu_sequencer $(FORMAL_APU_LOADER_TARGETS) $(FORMAL_APU_PRIMITIVE_TARGETS) gateway_a sdio onchip_ram,$*),bmc,prove) --depth $(if $(filter pll_rcu,$*),$(FORMAL_PLL_RCU_DEPTH),$(if $(filter dma,$*),$(FORMAL_DMA_DEPTH),$(if $(filter apu apu_codec apu_primitives apu_sequencer $(FORMAL_APU_LOADER_TARGETS) $(FORMAL_APU_PRIMITIVE_TARGETS),$*),$(FORMAL_APU_TARGET_DEPTH),$(if $(filter gateway_a,$*),$(FORMAL_GATEWAY_A_DEPTH),$(if $(filter sdio,$*),$(FORMAL_SDIO_DEPTH),$(if $(filter opipsram,$*),$(FORMAL_OPIPSRAM_DEPTH),$(if $(filter ws2812,$*),$(FORMAL_WS2812_DEPTH),$(if $(filter i2c,$*),$(FORMAL_I2C_DEPTH),$(if $(filter clint,$*),$(FORMAL_CLINT_DEPTH),$(if $(filter psram,$*),$(FORMAL_PSRAM_DEPTH),$(FORMAL_DEPTH))))))))))) --output $@ @if [ "$*" = opipsram ]; then sed -i '/^async2sync/i clk2fflogic' $@; fi $(FORMAL_DIR)/%/cover.sby: $(FORMAL_DIR)/%/design.v \ $(FORMAL_SBY_GENERATOR) python3 $(FORMAL_SBY_GENERATOR) --top $(FORMAL_TARGET_TOP)_formal --input $< \ --properties $(RTL_PATH)/formal/$(FORMAL_TARGET_TOP)_formal_props.sv --solver $(FORMAL_SOLVER) \ - --mode cover --depth $(if $(filter pll_rcu,$*),$(FORMAL_PLL_RCU_DEPTH),$(if $(filter dma,$*),$(FORMAL_DMA_COVER_DEPTH),$(if $(filter apu apu_codec apu_primitives apu_sequencer $(FORMAL_APU_LOADER_TARGETS) $(FORMAL_APU_PRIMITIVE_TARGETS),$*),$(FORMAL_APU_TARGET_COVER_DEPTH),$(if $(filter gateway_a,$*),$(FORMAL_GATEWAY_A_DEPTH),$(if $(filter sdio,$*),$(FORMAL_SDIO_COVER_DEPTH),$(if $(filter opipsram,$*),$(FORMAL_OPIPSRAM_DEPTH),$(if $(filter ws2812,$*),$(FORMAL_WS2812_DEPTH),$(if $(filter i2c,$*),$(FORMAL_I2C_DEPTH),$(if $(filter clint,$*),$(FORMAL_CLINT_DEPTH),$(if $(filter psram,$*),$(FORMAL_PSRAM_DEPTH),$(FORMAL_DEPTH))))))))))) \ + --mode cover --depth $(if $(filter pll_rcu,$*),$(FORMAL_PLL_RCU_DEPTH),$(if $(filter dma,$*),$(FORMAL_DMA_COVER_DEPTH),$(if $(filter apu apu_codec apu_primitives apu_sequencer $(FORMAL_APU_LOADER_TARGETS) $(FORMAL_APU_PRIMITIVE_TARGETS),$*),$(FORMAL_APU_TARGET_COVER_DEPTH),$(if $(filter gateway_a,$*),$(FORMAL_GATEWAY_A_DEPTH),$(if $(filter sdio,$*),$(FORMAL_SDIO_COVER_DEPTH),$(if $(filter opipsram,$*),$(FORMAL_OPIPSRAM_DEPTH),$(if $(filter ws2812,$*),$(FORMAL_WS2812_DEPTH),$(if $(filter i2c,$*),$(FORMAL_I2C_DEPTH),$(if $(filter clint,$*),$(FORMAL_CLINT_DEPTH),$(if $(filter psram,$*),$(FORMAL_PSRAM_DEPTH),$(FORMAL_DEPTH))))))))))) \ $(if $(filter $(FORMAL_COMPACT_COVER_TARGETS),$*),--no-vcd) --output $@ @if [ "$*" = opipsram ]; then sed -i '/^async2sync/i clk2fflogic' $@; fi @@ -340,4 +340,4 @@ formal-doctor: formal-clean: python3 $(ROOT_PATH)/scripts/clean.py --root $(ROOT_PATH) --path $(FORMAL_DIR) -.PHONY: formal formal-bus formal-rib-adapter formal-rib2apb formal-sysctrl formal-pll-rcu formal-gpio formal-ws2812 formal-uart formal-i2c formal-timer formal-clint formal-dvp formal-i2s formal-psram formal-onchip-ram formal-opipsram formal-dma formal-apu formal-apu-loader formal-apu-sequencer formal-gateway-a formal-sdio formal-doctor formal-clean +.PHONY: formal formal-bus formal-rib-adapter formal-rib2apb formal-sysctrl formal-pll-rcu formal-gpio formal-ws2812 formal-uart formal-i2c formal-timer formal-clint formal-dvp formal-i2s formal-psram formal-onchip-ram formal-opipsram formal-dma formal-apu formal-apu-loader formal-apu-sequencer formal-gateway-a formal-sdio formal-doctor formal-clean \ No newline at end of file diff --git a/tests/rtl/apu_dma_tb.sv b/tests/rtl/apu_dma_tb.sv index 37d333a4..ddf9d060 100644 --- a/tests/rtl/apu_dma_tb.sv +++ b/tests/rtl/apu_dma_tb.sv @@ -45,9 +45,9 @@ module apu_dma_tb; logic allow_write_response = 1'b1; logic [7:0] source_last_index = 8'd0; int unsigned read_bursts, write_bursts; - int unsigned write_burst_completions; - logic [63:0] successful_write_burst_bytes; - string s_phase; + int unsigned write_burst_completions; + logic [63:0] successful_write_burst_bytes; + string s_phase; axi4_if #( .ADDR_WIDTH(32), @@ -190,7 +190,7 @@ module apu_dma_tb; write_bursts <= write_bursts + 1; end if (write_burst_done_o) begin - write_burst_completions <= write_burst_completions + 1; + write_burst_completions <= write_burst_completions + 1; successful_write_burst_bytes <= successful_write_burst_bytes + write_burst_bytes_o; end if (axi4.wvalid && axi4.wready) begin diff --git a/tests/rtl/apu_p5_integration_tb.sv b/tests/rtl/apu_p5_integration_tb.sv index 6457875e..909864a3 100644 --- a/tests/rtl/apu_p5_integration_tb.sv +++ b/tests/rtl/apu_p5_integration_tb.sv @@ -138,7 +138,7 @@ module apu_p5_integration_tb; end if (i2s_tx_axis.tvalid && i2s_tx_axis.tready) begin tx_data_q[tx_count_q] <= i2s_tx_axis.tdata; - tx_count_q <= tx_count_q + 1'b1; + tx_count_q <= tx_count_q + 1'b1; if (i2s_tx_axis.tlast) begin tx_last_q <= 1'b1; tx_last_count_q <= tx_last_count_q + 1'b1; diff --git a/tests/rtl/apu_p5_transport_tb.sv b/tests/rtl/apu_p5_transport_tb.sv index 5edb936f..2654fa3f 100644 --- a/tests/rtl/apu_p5_transport_tb.sv +++ b/tests/rtl/apu_p5_transport_tb.sv @@ -26,8 +26,8 @@ module apu_p5_transport_tb; logic dma_done, dma_error; logic dma_error_q, dma_write_burst_done_q, dma_write_active_q, dma_fault_after_prefix_q; logic [31:0] dma_write_burst_bytes_q; - logic [6:0] dma_write_beat_q; - logic tx_ready_q; + logic [ 6:0] dma_write_beat_q; + logic tx_ready_q; logic fault_valid, event_input, event_output, tx_active, input_pending, output_pending; logic [5:0] fault_code; logic [3:0] fault_stage; diff --git a/tests/rtl/axi4_target_guard_tb.sv b/tests/rtl/axi4_target_guard_tb.sv index f1b027a9..32d95cfb 100644 --- a/tests/rtl/axi4_target_guard_tb.sv +++ b/tests/rtl/axi4_target_guard_tb.sv @@ -74,8 +74,8 @@ module axi4_target_guard_tb; end endtask - task automatic return_read_beat(input logic [5:0] id, input logic last, - input logic expected_last, input logic [1:0] expected_resp); + task automatic return_read_beat(input logic [5:0] id, input logic last, input logic expected_last, + input logic [1:0] expected_resp); begin @(negedge clk_i); sink.rid = id; diff --git a/tests/test_apu_codec_transport.py b/tests/test_apu_codec_transport.py index a9772480..a71771a9 100644 --- a/tests/test_apu_codec_transport.py +++ b/tests/test_apu_codec_transport.py @@ -9,6 +9,8 @@ from pathlib import Path import shutil import subprocess +import pytest + ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT / "scripts")) @@ -88,7 +90,7 @@ def test_p5_production_transport_matches_icarus_and_verilator(tmp_path: Path) -> sv2v = shutil.which("sv2v") verilator = shutil.which("verilator") if None in (iverilog, vvp, sv2v, verilator): - raise RuntimeError("P5 requires Icarus, vvp, sv2v, and Verilator") + pytest.skip("P5 requires Icarus, vvp, sv2v, and Verilator") common = ROOT / "rtl/managed/clusterip/common/rtl" multimedia = ROOT / "rtl/ip/multimedia" filelist = tmp_path / "apu_p5_transport.fl" @@ -161,7 +163,7 @@ def test_p5_direct_wav_uses_product_loader_dma_sequencer_and_tx(tmp_path: Path) sv2v = shutil.which("sv2v") verilator = shutil.which("verilator") if None in (iverilog, vvp, sv2v, verilator): - raise RuntimeError("P5 integration requires Icarus, vvp, sv2v, and Verilator") + pytest.skip("P5 integration requires Icarus, vvp, sv2v, and Verilator") multimedia = ROOT / "rtl/ip/multimedia" common = ROOT / "rtl/managed/clusterip/common/rtl" assembly = assemble( diff --git a/tests/test_script_tools.py b/tests/test_script_tools.py index c227fd63..6621c6ee 100644 --- a/tests/test_script_tools.py +++ b/tests/test_script_tools.py @@ -1434,6 +1434,13 @@ def test_nightly_workflow_splits_netsim_from_extended_recipes() -> None: assert "--suite nightly-extra --pdk IHP130 --behavioral-only --dry-run" in quality +def test_quality_runs_p5_with_locked_open_source_simulators() -> None: + quality = (ROOT / ".github/workflows/quality.yml").read_text() + + assert "tools: verilator sv2v iverilog" in quality + assert "python3 -m pytest -q tests/test_apu_codec_transport.py" in quality + + def test_regression_observations_do_not_block_or_skip_metrics( monkeypatch, tmp_path: Path, capsys ) -> None: