diff --git a/.github/workflows/_regression.yml b/.github/workflows/_regression.yml index 98218c41..2c2a24d9 100644 --- a/.github/workflows/_regression.yml +++ b/.github/workflows/_regression.yml @@ -28,7 +28,7 @@ on: toolset: description: Space-separated locked tools required by this suite required: false - default: verilator sv2v iverilog yosys opensta openocd riscv_gnu + default: verilator sv2v iverilog yosys opensta openocd sbt riscv_gnu type: string full_flow_checks: description: Check Yosys and OpenSTA environments before running the suite diff --git a/.github/workflows/regression-smoke.yml b/.github/workflows/regression-smoke.yml index f1e56c8c..fc5daedd 100644 --- a/.github/workflows/regression-smoke.yml +++ b/.github/workflows/regression-smoke.yml @@ -23,6 +23,6 @@ jobs: profile: configs/ci/ihp130.mk retention_days: 14 timeout_minutes: 60 - toolset: verilator sv2v iverilog yosys sby bitwuzla riscv_gnu + toolset: verilator sv2v iverilog yosys sby bitwuzla sbt riscv_gnu full_flow_checks: false formal_checks: true diff --git a/Makefile b/Makefile index 38eb7c69..0847cdbe 100644 --- a/Makefile +++ b/Makefile @@ -474,9 +474,9 @@ crypto-p1-report: manifest $(PYTHON) $(ROOT_PATH)/scripts/crypto_p1.py report --variant-root $(VARIANT_ROOT) \ --baseline-root $(CRYPTO_P0_BASELINE_ROOT) --lp-variant-root $(CRYPTO_P1_LP_ROOT) \ $(if $(CRYPTO_P1_CI_ROOT),--ci-variant-root $(CRYPTO_P1_CI_ROOT),) -CRYPTO_P1_ROOT ?= $(VARIANT_ROOT) -CRYPTO_P2_NETLIST_ROOT ?= $(VARIANT_ROOT) -CRYPTO_P2_STA_ROOT ?= $(VARIANT_ROOT) +CRYPTO_P1_ROOT ?= $(VARIANT_ROOT) +CRYPTO_P2_NETLIST_ROOT ?= $(VARIANT_ROOT) +CRYPTO_P2_STA_ROOT ?= $(VARIANT_ROOT) CRYPTO_P2_PHYSICAL_ROOT ?= $(VARIANT_ROOT) crypto-p2-synth: manifest $(MAKE) CONFIG=$(ROOT_PATH)/configs/ci/ihp130.mk BUILD_TIMESTAMP=$(BUILD_TIMESTAMP) \ @@ -1199,4 +1199,4 @@ regress-nightly: python3 $(ROOT_PATH)/scripts/regress.py --root $(ROOT_PATH) --suite nightly $(if $(filter TINY,$(SOC)),--soc TINY) 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/app/apps/apu_release/app.mk b/app/apps/apu_release/app.mk index 0b4ee5e4..f6bfa883 100644 --- a/app/apps/apu_release/app.mk +++ b/app/apps/apu_release/app.mk @@ -14,4 +14,4 @@ $(APU_RELEASE_ASSETS_H): $(APU_P5_BUNDLE) $(APU_P7_MODEL) $(APU_P9_APUC) \ --kws-corpus $(CACHE_ROOT)/sources/apu-kws-pcm \ --output $@ -$(SW_BUILD_DIR)/firmware: $(APU_RELEASE_ASSETS_H) +$(SW_BUILD_DIR)/firmware: $(APU_RELEASE_ASSETS_H) \ No newline at end of file diff --git a/app/apps/hp_boot/app.mk b/app/apps/hp_boot/app.mk index fee763c8..36b4b62d 100644 --- a/app/apps/hp_boot/app.mk +++ b/app/apps/hp_boot/app.mk @@ -1,3 +1,3 @@ APP_SRCS += $(ROOT_PATH)/app/apps/hp_boot/main.c APP_SRCS += $(ROOT_PATH)/app/apps/hp_boot/hp_boot_bundle.c -APP_INC_DIRS += $(ROOT_PATH)/app/apps/hp_boot +APP_INC_DIRS += $(ROOT_PATH)/app/apps/hp_boot \ No newline at end of file diff --git a/configs/ci/ihp130-rtthread.mk b/configs/ci/ihp130-rtthread.mk index 6f57a63b..dbb2719a 100644 --- a/configs/ci/ihp130-rtthread.mk +++ b/configs/ci/ihp130-rtthread.mk @@ -19,4 +19,4 @@ LINK_TYPE := ld2_all_sram SIM_SUCCESS_MARKER := SIM_TEST_PASS RTL_SIM_TIMEOUT := 20000000 FIRMWARE_NAME := retrosoc_hp_boot -SIM_FIRMWARE_NAME := retrosoc_hp_boot +SIM_FIRMWARE_NAME := retrosoc_hp_boot \ No newline at end of file diff --git a/dependencies/dependencies.lock.json b/dependencies/dependencies.lock.json index 2ad99b8b..12fa8b02 100644 --- a/dependencies/dependencies.lock.json +++ b/dependencies/dependencies.lock.json @@ -384,10 +384,10 @@ "path": "xpack-openocd-0.12.0-1/bin" }, "sbt": { - "version": "1.10.0", - "url": "https://github.com/sbt/sbt/releases/download/v1.10.0/sbt-1.10.0.tgz", - "sha256": "154b7de6c19207c73d0a304f901c8c4b6ead9a9c3a99a98a9d72ac19419d2640", - "archive": "sbt-1.10.0.tgz", + "version": "2.0.5", + "url": "https://github.com/sbt/sbt/releases/download/v2.0.5/sbt-2.0.5.tgz", + "sha256": "2a53c95403cb7fccd5da05d48cfe03ff4be573a3f3d0295a41963b109e756a18", + "archive": "sbt-2.0.5.tgz", "path": "sbt/bin", "download_timeout_seconds": 600, "resume": true diff --git a/docs/engineering.md b/docs/engineering.md index d0db8885..54b55c59 100644 --- a/docs/engineering.md +++ b/docs/engineering.md @@ -18,12 +18,12 @@ Regression Verilator firmware simulations override the profiles' manual `bringup` default with `APP=ci_smoke`. The IHP130 PR simulation also uses the 32 KiB `ld2_all_sram` layout, the explicit Verilator `--fast-flash` backend, and an 1800-second wall-clock budget. GF180, ICS55, and SKY130 use the common -`ld2_sdram` execution layout, the same fast-flash backend, and an 1800-second -budget for the GA2D acceptance workload while LP instruction traffic shares -the SDRAM target. The broad smoke therefore does not execute from the serial -PSRAM model. The full serial XPI and PSRAM path remains covered by the Icarus -assembly self-test and directed memory-model tests. This application verifies -UART output, +`ld2_sdram` execution layout, the same fast-flash backend, and a 3600-second +budget for the peripheral acceptance workload while LP instruction traffic +shares the SDRAM target. The broad smoke therefore does not execute from the +serial PSRAM model. The full serial XPI and PSRAM path remains covered by the +Icarus assembly self-test and directed memory-model tests. This application +verifies UART output, archinfo APB readback, on-chip SRAM first/last-word and 8/16/32-bit access, Fabric Monitor collection through the PCLK-to-HP APB path, truthful extension capabilities, RNG integration, SDRAM 8/16/32-bit access in a reserved tail diff --git a/physical/librelane/tiny/Makefile b/physical/librelane/tiny/Makefile index 63fa0ebd..e67e6f21 100644 --- a/physical/librelane/tiny/Makefile +++ b/physical/librelane/tiny/Makefile @@ -130,4 +130,4 @@ librelane-klayout: librelane-doctor librelane-package: librelane-chip $(FLOW_PYTHON) $(LIBRELANE_FLOW_ROOT)/scripts/package.py \ --root $(ROOT_PATH) --variant-root $(VARIANT_ROOT) \ - --run-root $(LIBRELANE_RUN_ROOT) --output $(LIBRELANE_ARCHIVE) + --run-root $(LIBRELANE_RUN_ROOT) --output $(LIBRELANE_ARCHIVE) \ No newline at end of file diff --git a/physical/smoke/syn/yosys/apu_block.mk b/physical/smoke/syn/yosys/apu_block.mk index 41480be2..94c9edc5 100644 --- a/physical/smoke/syn/yosys/apu_block.mk +++ b/physical/smoke/syn/yosys/apu_block.mk @@ -171,4 +171,4 @@ apu-block-clean: python3 $(ROOT_PATH)/scripts/clean.py --root $(ROOT_PATH) --path $(APU_BLOCK_REPORT_DIR) .PHONY: apu-block-filelist apu-block-synth apu-block-sta apu-block-report \ - apu-block-evidence apu-block-clean + apu-block-evidence apu-block-clean \ No newline at end of file diff --git a/physical/smoke/syn/yosys/ga2d_block.mk b/physical/smoke/syn/yosys/ga2d_block.mk index 507f92b7..b6022edb 100644 --- a/physical/smoke/syn/yosys/ga2d_block.mk +++ b/physical/smoke/syn/yosys/ga2d_block.mk @@ -176,4 +176,4 @@ sta-ga2d-block-clean: python3 $(ROOT_PATH)/scripts/clean.py --root $(ROOT_PATH) --path $(GA2D_BLOCK_STA_DIR) .PHONY: synth-ga2d-block synth-ga2d-block-clean netsim-ga2d-block netsim-ga2d-block-clean \ - sta-ga2d-block sta-ga2d-block-clean + sta-ga2d-block sta-ga2d-block-clean \ No newline at end of file diff --git a/publications/boot_acceptance_reference.py b/publications/boot_acceptance_reference.py index 948d734c..de42d8ec 100644 --- a/publications/boot_acceptance_reference.py +++ b/publications/boot_acceptance_reference.py @@ -10,13 +10,25 @@ from publications.implementation_reference import without_comments BOOT_SOURCE = "app/apps/hp_boot/main.c" -READY_SOURCE = "app/ports/linux/rootfs-overlay/etc/init.d/S99retrosoc-hp" +BUNDLE_SOURCE = "app/apps/hp_boot/hp_boot_bundle.c" +INIT_SOURCE = "app/ports/linux/init" +READY_SOURCE = "app/ports/linux/hp_ready.c" HAL_SOURCE = "crt/src/hal/hp_mailbox.c" STATUS_SOURCE = "crt/include/retrosoc/core/status.h" REGISTER_SOURCE = "rtl/ip/peripheral/hp_mailbox_define.svh" MAILBOX_SOURCE = "rtl/ip/peripheral/apb4_hp_mailbox.sv" MAP_SOURCE = "rtl/mini/address_map/memory_map.json" -SOURCES = {BOOT_SOURCE, READY_SOURCE, HAL_SOURCE, STATUS_SOURCE, REGISTER_SOURCE, MAILBOX_SOURCE, MAP_SOURCE} +SOURCES = { + BOOT_SOURCE, + BUNDLE_SOURCE, + INIT_SOURCE, + READY_SOURCE, + HAL_SOURCE, + STATUS_SOURCE, + REGISTER_SOURCE, + MAILBOX_SOURCE, + MAP_SOURCE, +} NPU_DEFINES = ("RS_NPU_P5_ACCEPTANCE", "RS_NPU_P6_ACCEPTANCE") @@ -29,8 +41,18 @@ def uint_constants(source: str) -> dict[str, int]: r"^#define\s+(\w+)\s+UINT32_C\((0x[\da-fA-F]+|\d+)\)\s*$", source, re.M)} +def c_uint_literal(expression: str) -> int: + wrapper = re.fullmatch(r"UINT32_C\((0x[\da-fA-F]+|\d+)\)", expression.strip()) + if wrapper: + return int(wrapper[1], 0) + literal = re.fullmatch(r"(0x[\da-fA-F]+|\d+)[uUlL]*", expression.strip()) + if literal: + return int(literal[1], 0) + raise ValueError("Linux ready mailbox value expression changed") + + def ready_mailbox(root: Path) -> list[dict]: - """Resolve rootfs writes to register purposes, rather than positional labels.""" + """Resolve the Linux helper writes to register purposes and source order.""" hal = (root / HAL_SOURCE).read_text(encoding="utf-8") rtl = (root / REGISTER_SOURCE).read_text(encoding="utf-8") offsets = {name: int(value, 16) for name, value in re.findall( @@ -63,27 +85,59 @@ def ready_mailbox(root: Path) -> list[dict]: expected_values = [boot_constants[key] for key in ( "RS_HP_BOOT_READY_EVENT", "RS_HP_BOOT_READY_ARG", "RS_HP_BOOT_MAILBOX_READY_SEQUENCE")] + [1] ready = (root / READY_SOURCE).read_text(encoding="utf-8") - writes = [(int(address, 0), int(value, 0)) for address, value in re.findall( - r"^\s*devmem\s+(0x[\da-fA-F]+)\s+32\s+(0x[\da-fA-F]+)\s*$", ready, re.M)] - expected = [(base + offsets[register], value) - for register, value in zip(registers, expected_values, strict=True)] - if writes != expected or sum(line.lstrip().startswith("devmem ") for line in ready.splitlines()) != len(writes): + mappings = re.findall(r"\bmmap\([^;]*,\s*(0x[\da-fA-F]+)\s*\);", ready) + if len(mappings) != 1 or int(mappings[0], 0) != base: + raise ValueError("Linux ready mailbox mapping changed") + writes = list(re.finditer(r"mailbox\[(\d+)\]\s*=\s*([^;]+);", ready)) + if [match[1] for match in writes] != ["8", "9", "10", "11"]: raise ValueError("Linux ready mailbox sequence changed") - message = 'echo "retroSoC HP Linux ready"' - if message not in ready or ready.index(message) > ready.index("devmem"): - raise ValueError("Linux ready message/publication order changed") - # A newly added responder invalidates the documented ready-only service gap. - shell_lines = [line.strip() for line in ready.splitlines() - if line.strip() and not line.lstrip().startswith("#")] - scaffold = ['case "$1" in', "start)", message, ";;", "esac"] - if [line for line in shell_lines if not line.startswith("devmem ")] != scaffold: + literal = r"(?:UINT32_C\((?:0x[\da-fA-F]+|\d+)\)|(?:0x[\da-fA-F]+|\d+)[uUlL]*)" + expressions = [match[2].strip() for match in writes] + event = re.fullmatch( + rf"\(\s*error\s*==\s*0U\s*\)\s*\?\s*({literal})\s*:\s*3U", expressions[0] + ) + argument = re.fullmatch( + rf"\(\s*error\s*==\s*0U\s*\)\s*\?\s*({literal})\s*:\s*error", expressions[1] + ) + direct = [re.fullmatch(literal, expression) for expression in expressions[2:]] + if event is None or argument is None or any(match is None for match in direct): + raise ValueError("Linux ready mailbox value expression changed") + actual_values = [ + c_uint_literal(event[1]), + c_uint_literal(argument[1]), + *(c_uint_literal(match[0]) for match in direct if match is not None), + ] + if actual_values != expected_values: + raise ValueError("Linux ready mailbox values differ from LP acceptance contract") + expected_addresses = [base + offsets[register] for register in registers] + actual_addresses = [base + (int(match[1]) * 4) for match in writes] + if actual_addresses != expected_addresses: + raise ValueError("Linux ready mailbox addresses differ from RTL register offsets") + message = '(void)puts("retroSoC HP Linux ready");' + fence = '__asm__ volatile("fence iorw, iorw" ::: "memory");' + if message not in ready or fence not in ready: + raise ValueError("Linux ready message/publication sequence changed") + ordered_positions = [ + ready.index(message), + *(match.start() for match in writes[:3]), + ready.index(fence), + writes[3].start(), + ] + if ordered_positions != sorted(ordered_positions): + raise ValueError("Linux ready message/publication sequence changed") + init = (root / INIT_SOURCE).read_text(encoding="utf-8") + init_lines = [line.strip() for line in init.splitlines() if line.strip()] + if not init_lines or init_lines[-1] != "exec /bin/hp-ready": + raise ValueError("Linux minimal init no longer terminates in the ready helper") + if not compact(ready).endswith("mailbox[11]=1U;for(;;){(void)pause();}}"): raise ValueError("Linux ready-only service changed; review its acceptance coverage") + actual = list(zip(actual_addresses, actual_values, strict=True)) purposes = {"HP_EVENT": "Linux-ready event", "HP_ARG0": "Ready-state argument", "HP_SEQUENCE": "Publication sequence", "HP_DOORBELL": "LP interrupt request"} - register_by_address = {base + offsets[register]: register for register in registers} + register_by_address = dict(zip(actual_addresses, registers, strict=True)) return [{"address": f"0x{address:08X}", "value": f"0x{value:08X}", "register": register_by_address[address], "purpose": purposes[register_by_address[address]]} - for address, value in writes] + for address, value in actual] def split_npu_conditions(body: str) -> tuple[str, list[tuple[str, str]]]: @@ -222,10 +276,27 @@ def collect_boot_acceptance(root: Path, function_body: Callable[[str, str], str] raise ValueError(f"HP boot {name} wait is no longer the reviewed bounded poll") if not body.endswith("returnfalse;") or "while(" in body or "do{" in body: raise ValueError(f"HP boot {name} wait termination changed") - wait_body = compact(function_body(source, "rs_hp_boot_wait_message")) - if ("if(message.sequence==sequence){return(message.code==code)&&(message.argument==argument);}" not in wait_body - or "if(rs_hp_mailbox_receive_from_hp(&message)!=RS_OK){returnfalse;}" not in wait_body): + bundle = (root / BUNDLE_SOURCE).read_text(encoding="utf-8") + expected_status = compact(""" + if ((sequence > expected_sequence) || ((sequence != 0U) && (code == 3U))) { + return 2U; + } + if (sequence == expected_sequence) { + return ((code == expected_code) && (argument == expected_argument)) ? 1U : 2U; + } + return 0U; + """) + if compact(function_body(bundle, "rs_hp_boot_message_status")) != expected_status: raise ValueError("HP boot mailbox token/error matching changed") + wait_body = compact(function_body(source, "rs_hp_boot_wait_message")) + for binding in ( + "if(rs_hp_mailbox_receive_from_hp(&message)!=RS_OK){returnfalse;}", + "status=rs_hp_boot_message_status(message.code,message.argument,message.sequence,code,argument,sequence);", + "if(status==2U){printf(\"HP_PAYLOAD_FAILED:%u\\n\",(unsignedint)message.argument);returnfalse;}", + "if(status==1U){returntrue;}", + ): + if binding not in wait_body: + raise ValueError("HP boot mailbox token/error matching changed") main, gated = split_npu_conditions(function_body(source, "main")) main = compact(main) phases = ( @@ -257,7 +328,14 @@ def collect_boot_acceptance(root: Path, function_body: Callable[[str, str], str] if position < 0: raise ValueError(f"HP boot required phase or ordering changed: {phase}") cursor = position + len(phase) - if (main.count("rs_test_finish(RS_TEST_PASSED,") != 1 or not main.endswith(phases[-1]) + workload_branches = ( + "if(header.workload==RS_HP_BOOT_WORKLOAD_SMOKE){", + "if(header.workload==RS_HP_BOOT_WORKLOAD_RTTHREAD){", + "if(header.workload==RS_HP_BOOT_WORKLOAD_LINUX){", + ) + if any(main.count(branch) != 1 for branch in workload_branches): + raise ValueError("HP boot workload selection changed") + if (main.count("rs_test_finish(RS_TEST_PASSED,") != 3 or not main.endswith(phases[-1]) or re.findall(r"cache_clean_completed=(true|false);", main) != ["false", "true"] or re.findall(r"s_hp_boot_ga2d_owned_by_hp=(true|false);", main) != ["true", "false"]): raise ValueError("HP boot terminal pass or cache completion changed") diff --git a/publications/datasheets/diagram-circuits.json b/publications/datasheets/diagram-circuits.json index 34c4b78b..8cc2c037 100644 --- a/publications/datasheets/diagram-circuits.json +++ b/publications/datasheets/diagram-circuits.json @@ -5342,7 +5342,7 @@ }, { "id": "aes", - "title": "AES engine\nkey schedule / modes", + "title": "AES SRAM engine\nkey schedule / modes", "x": 0.0, "y": 3.5, "w": 4.0, @@ -5369,18 +5369,18 @@ ], "sources": [ "rtl/ip/security/apb4_crypto.sv", - "rtl/ip/security/crypto_aes_engine.sv" + "rtl/ip/security/crypto_aes_sram_engine.sv" ], - "instance_source": { - "file": "rtl/ip/security/apb4_crypto.sv", - "name": "u_crypto_aes_engine", - "module": "crypto_aes_engine", - "declaration_file": "rtl/ip/security/crypto_aes_engine.sv" - } + "instance_source": { + "file": "rtl/ip/security/apb4_crypto.sv", + "name": "u_aes", + "module": "crypto_aes_sram_engine", + "declaration_file": "rtl/ip/security/crypto_aes_sram_engine.sv" + } }, { "id": "sha", - "title": "SHA-224 / SHA-256\nschedule / compression", + "title": "SHA SRAM engine\nschedule / compression", "x": 6.3, "y": 3.5, "w": 4.0, @@ -5401,18 +5401,18 @@ ], "sources": [ "rtl/ip/security/apb4_crypto.sv", - "rtl/ip/security/crypto_sha2_engine.sv" + "rtl/ip/security/crypto_sha2_sram_engine.sv" ], - "instance_source": { - "file": "rtl/ip/security/apb4_crypto.sv", - "name": "u_crypto_sha2_engine", - "module": "crypto_sha2_engine", - "declaration_file": "rtl/ip/security/crypto_sha2_engine.sv" - } + "instance_source": { + "file": "rtl/ip/security/apb4_crypto.sv", + "name": "u_sha", + "module": "crypto_sha2_sram_engine", + "declaration_file": "rtl/ip/security/crypto_sha2_sram_engine.sv" + } }, { "id": "rsa", - "title": "RSA Montgomery core\nprepare / exponentiation", + "title": "RSA SRAM core\nprepare / exponentiation", "x": 12.6, "y": 3.5, "w": 4.0, @@ -5425,22 +5425,22 @@ "side": "north" }, { - "id": "p6", - "direction": "out", - "width": 2048, + "id": "p6", + "direction": "out", + "width": 32, "side": "south" } ], "sources": [ "rtl/ip/security/apb4_crypto.sv", - "rtl/ip/security/crypto_rsa_core.sv" + "rtl/ip/security/crypto_rsa_sram_core.sv" ], - "instance_source": { - "file": "rtl/ip/security/apb4_crypto.sv", - "name": "u_crypto_rsa_core", - "module": "crypto_rsa_core", - "declaration_file": "rtl/ip/security/crypto_rsa_core.sv" - } + "instance_source": { + "file": "rtl/ip/security/apb4_crypto.sv", + "name": "u_rsa", + "module": "crypto_rsa_sram_core", + "declaration_file": "rtl/ip/security/crypto_rsa_sram_core.sv" + } }, { "id": "stream", @@ -5488,16 +5488,16 @@ }, { "id": "rsa_words", - "title": "APB operand / result\n2048-bit vectors", + "title": "APB storage portals\nresult / progress status", "x": 12.6, "y": 0.0, "w": 4.0, "h": 1.8, "ports": [ { - "id": "p6", - "direction": "in", - "width": 2048, + "id": "p6", + "direction": "in", + "width": 32, "side": "north" } ], @@ -5513,27 +5513,19 @@ "kind": "control", "label": "START", "style": "zigzag", - "bindings": [ - { - "file": "rtl/ip/security/apb4_crypto.sv", - "text": ".start_i(s_aes_start)" - } - ], - "signals": [ - { - "file": "rtl/ip/security/apb4_crypto.sv", - "scope": "apb4_crypto", - "symbol": "s_aes_start", - "bits": 1 - } - ], - "instance_ports": [ - { - "node": "aes", - "port": "start_i", - "expression": "s_aes_start" - } - ], + "bindings": [ + { + "file": "rtl/ip/security/apb4_crypto.sv", + "text": ".start_i(s_start[0])" + } + ], + "instance_ports": [ + { + "node": "aes", + "port": "start_i", + "expression": "s_start[0]" + } + ], "zigzag-dir": "horizontal" }, { @@ -5542,27 +5534,19 @@ "kind": "control", "label": "START", "style": "direct", - "bindings": [ - { - "file": "rtl/ip/security/apb4_crypto.sv", - "text": ".start_i(s_sha_start)" - } - ], - "signals": [ - { - "file": "rtl/ip/security/apb4_crypto.sv", - "scope": "apb4_crypto", - "symbol": "s_sha_start", - "bits": 1 - } - ], - "instance_ports": [ - { - "node": "sha", - "port": "start_i", - "expression": "s_sha_start" - } - ], + "bindings": [ + { + "file": "rtl/ip/security/apb4_crypto.sv", + "text": ".start_i(s_start[1])" + } + ], + "instance_ports": [ + { + "node": "sha", + "port": "start_i", + "expression": "s_start[1]" + } + ], "zigzag-dir": "horizontal" }, { @@ -5571,27 +5555,19 @@ "kind": "control", "label": "START", "style": "zigzag", - "bindings": [ - { - "file": "rtl/ip/security/apb4_crypto.sv", - "text": ".start_i(s_rsa_start)" - } - ], - "signals": [ - { - "file": "rtl/ip/security/apb4_crypto.sv", - "scope": "apb4_crypto", - "symbol": "s_rsa_start", - "bits": 1 - } - ], - "instance_ports": [ - { - "node": "rsa", - "port": "start_i", - "expression": "s_rsa_start" - } - ], + "bindings": [ + { + "file": "rtl/ip/security/apb4_crypto.sv", + "text": ".start_i(s_start[2])" + } + ], + "instance_ports": [ + { + "node": "rsa", + "port": "start_i", + "expression": "s_start[2]" + } + ], "zigzag-dir": "horizontal" }, { @@ -5600,27 +5576,19 @@ "kind": "data", "label": "INPUT / 32", "style": "direct", - "bindings": [ - { - "file": "rtl/ip/security/apb4_crypto.sv", - "text": ".input_data_i(s_aes_input_data)" - } - ], - "signals": [ - { - "file": "rtl/ip/security/apb4_crypto.sv", - "scope": "apb4_crypto", - "symbol": "s_aes_input_data", - "bits": 32 - } - ], - "instance_ports": [ - { - "node": "aes", - "port": "input_data_i", - "expression": "s_aes_input_data" - } - ], + "bindings": [ + { + "file": "rtl/ip/security/apb4_crypto.sv", + "text": ".input_data_i(s_aes_dma_active ? crypto_in_axis.tdata : s_wdata)" + } + ], + "instance_ports": [ + { + "node": "aes", + "port": "input_data_i", + "expression": "s_aes_dma_active ? crypto_in_axis.tdata : s_wdata" + } + ], "zigzag-dir": "horizontal" }, { @@ -5658,60 +5626,44 @@ "kind": "data", "label": "INPUT / 32", "style": "direct", - "bindings": [ - { - "file": "rtl/ip/security/apb4_crypto.sv", - "text": ".input_data_i(s_sha_input_data)" - } - ], - "signals": [ - { - "file": "rtl/ip/security/apb4_crypto.sv", - "scope": "apb4_crypto", - "symbol": "s_sha_input_data", - "bits": 32 - } - ], - "instance_ports": [ - { - "node": "sha", - "port": "input_data_i", - "expression": "s_sha_input_data" - } - ], - "zigzag-dir": "horizontal" + "bindings": [ + { + "file": "rtl/ip/security/apb4_crypto.sv", + "text": ".input_data_i(s_sha_dma_active ? crypto_in_axis.tdata : s_wdata)" + } + ], + "instance_ports": [ + { + "node": "sha", + "port": "input_data_i", + "expression": "s_sha_dma_active ? crypto_in_axis.tdata : s_wdata" + } + ], + "zigzag-dir": "horizontal" }, { "from": "rsa.p6", "to": "rsa_words.p6", "kind": "data", - "label": "RESULT / 2048", + "label": "PROGRESS / 32", "style": "direct", "bindings": [ { "file": "rtl/ip/security/apb4_crypto.sv", - "text": ".result_o(s_rsa_result)" - } - ], - "signals": [ - { - "file": "rtl/ip/security/apb4_crypto.sv", - "scope": "apb4_crypto", - "symbol": "s_rsa_result", - "bits": 2048 + "text": ".progress_o(s_rsa_progress)" } ], "instance_ports": [ { "node": "rsa", - "port": "result_o", - "expression": "s_rsa_result" + "port": "progress_o", + "expression": "s_rsa_progress" } ], "zigzag-dir": "horizontal" } ], - "note": "AES and SHA consume PIO or selected stream words; RSA uses operand windows. Keys and operands reside in ordinary state and follow zeroize/abort rules. These are independent engines, not an invented descriptor queue or secure key store." + "note": "AES and SHA consume PIO or selected stream words. AES/SHA constants and work state plus RSA operands/results reside in the six private SRAM banks behind the wrapper's storage controller. The engines remain independently sequenced; no descriptor queue or readable secret-key aperture is implied." }, "i2s": { "nodes": [ diff --git a/publications/datasheets/diagram-layouts.json b/publications/datasheets/diagram-layouts.json index b693f129..e04628a7 100644 --- a/publications/datasheets/diagram-layouts.json +++ b/publications/datasheets/diagram-layouts.json @@ -1969,7 +1969,7 @@ "section": "protocol", "sources": [ "docs/ip/crypto.md", - "rtl/ip/security/crypto_sha2_engine.sv" + "rtl/ip/security/crypto_sha2_sram_engine.sv" ], "note": "Digest word 0 is the most significant digest word. SHA-256 uses eight words; SHA-224 uses seven meaningful words and returns zero in word 7. This word significance differs from RSA limb significance.", "bindings": [ @@ -2049,7 +2049,7 @@ "section": "protocol", "sources": [ "docs/ip/crypto.md", - "rtl/ip/security/crypto_rsa_core.sv" + "rtl/ip/security/crypto_rsa_sram_core.sv" ], "note": "64 little-endian 32-bit limbs; word 0 is least significant and word 63 is most significant. The middle 60 words are collapsed in this schematic. Public/private exponent rules and operand validity remain those of the RSA contract.", "bindings": [ diff --git a/publications/datasheets/diagram-storage.json b/publications/datasheets/diagram-storage.json index 7c8a6dd1..d60fb355 100644 --- a/publications/datasheets/diagram-storage.json +++ b/publications/datasheets/diagram-storage.json @@ -421,30 +421,34 @@ "section": "functional", "stores": [ { - "file": "rtl/ip/security/crypto_aes_engine.sv", - "instance": "u_input_fifo", + "file": "rtl/ip/security/crypto_clearable_fifo.sv", + "instance": "u_payload", + "parameters": {"Depth": 8}, "title": "AES input FIFO", "depth": 8, "bits": 37 }, { - "file": "rtl/ip/security/crypto_aes_engine.sv", - "instance": "u_output_fifo", + "file": "rtl/ip/security/crypto_clearable_fifo.sv", + "instance": "u_payload", + "parameters": {"Depth": 8}, "title": "AES output FIFO", "depth": 8, "bits": 37 }, { - "file": "rtl/ip/security/crypto_sha2_engine.sv", - "instance": "u_input_fifo", + "file": "rtl/ip/security/crypto_clearable_fifo.sv", + "instance": "u_payload", + "parameters": {"Depth": 16}, "title": "SHA input FIFO", "depth": 16, "bits": 37 } ], "sources": [ - "rtl/ip/security/crypto_aes_engine.sv", - "rtl/ip/security/crypto_sha2_engine.sv" + "rtl/ip/security/crypto_aes_sram_engine.sv", + "rtl/ip/security/crypto_clearable_fifo.sv", + "rtl/ip/security/crypto_sha2_sram_engine.sv" ], "bindings": [], "note": "Entries carry data and valid-byte/LAST metadata. AES has independent input/output FIFOs; SHA has an input FIFO and separate digest state. Zeroize/abort and ownership rules remain mandatory." @@ -645,51 +649,42 @@ "section": "functional", "stores": [ { - "file": "rtl/ip/security/crypto_rsa_core.sv", - "symbols": [ - "modulus_i" - ], - "word_view": 32, + "depth_ref": {"file": "crt/include/retrosoc/hal/crypto_regs.h", "constant": "RS_CRYPTO_RSA_WORDS"}, + "bits_ref": {"file": "rtl/ip/security/apb4_crypto.sv", "symbol": "s_wdata"}, "title": "Modulus", "depth": 64, "bits": 32 }, { - "file": "rtl/ip/security/crypto_rsa_core.sv", - "symbols": [ - "exponent_i" - ], - "word_view": 32, + "depth_ref": {"file": "crt/include/retrosoc/hal/crypto_regs.h", "constant": "RS_CRYPTO_RSA_WORDS"}, + "bits_ref": {"file": "rtl/ip/security/apb4_crypto.sv", "symbol": "s_wdata"}, "title": "Exponent", "depth": 64, "bits": 32 }, { - "file": "rtl/ip/security/crypto_rsa_core.sv", - "symbols": [ - "base_i" - ], - "word_view": 32, + "depth_ref": {"file": "crt/include/retrosoc/hal/crypto_regs.h", "constant": "RS_CRYPTO_RSA_WORDS"}, + "bits_ref": {"file": "rtl/ip/security/apb4_crypto.sv", "symbol": "s_wdata"}, "title": "Base", "depth": 64, "bits": 32 }, { - "file": "rtl/ip/security/crypto_rsa_core.sv", - "symbols": [ - "result_o" - ], - "word_view": 32, + "depth_ref": {"file": "crt/include/retrosoc/hal/crypto_regs.h", "constant": "RS_CRYPTO_RSA_WORDS"}, + "bits_ref": {"file": "rtl/ip/security/apb4_crypto.sv", "symbol": "s_wdata"}, "title": "Result", "depth": 64, "bits": 32 } ], "sources": [ - "rtl/ip/security/crypto_rsa_core.sv" + "crt/include/retrosoc/hal/crypto_regs.h", + "rtl/ip/security/apb4_crypto.sv", + "rtl/ip/security/crypto_rsa_sram_core.sv", + "rtl/ip/security/crypto_sram_store.sv" ], "bindings": [], - "note": "Each 2,048-bit vector is shown as 64 little-endian 32-bit limb positions. These interfaces represent logical operand state, not secure SRAM, persistent keys or a key-slot service." + "note": "Each logical 2,048-bit APB aperture is shown as 64 little-endian 32-bit limb positions. P1 stores the live values in the shared private SRAM banks; the diagram does not imply separate arrays, persistent keys or a key-slot service." }, { "id": "xpi-windows", diff --git a/publications/datasheets/register-annotations.json b/publications/datasheets/register-annotations.json index 2a594168..1c093925 100644 --- a/publications/datasheets/register-annotations.json +++ b/publications/datasheets/register-annotations.json @@ -4198,6 +4198,135 @@ } }, "crypto": { + "main.MEM_STATUS": { + "access": "RO", + "description": "Storage initialization, verification, scrub, lock and fault state.", + "reset": "0x00000004", + "fields": [ + {"lsb": 0, "msb": 0, "name": "READY", "description": "Constants are valid and locked, erasure is complete, and no memory fault is active.", "reset": "0", "expression": "`APB4_CRYPTO__MEM_STATUS_READY"}, + {"lsb": 1, "msb": 1, "name": "TABLE_VALID", "description": "The committed constants image passed validation.", "reset": "0", "expression": "`APB4_CRYPTO__MEM_STATUS_TABLE_VALID"}, + {"lsb": 2, "msb": 2, "name": "SCRUB_BUSY", "description": "Reset or zeroize scrubbing is active.", "reset": "1", "expression": "`APB4_CRYPTO__MEM_STATUS_SCRUB_BUSY"}, + {"lsb": 3, "msb": 3, "name": "LOAD_ACTIVE", "description": "A TABLE_DATA loading transaction is active.", "reset": "0", "expression": "`APB4_CRYPTO__MEM_STATUS_LOAD_ACTIVE"}, + {"lsb": 4, "msb": 4, "name": "VERIFY_BUSY", "description": "Full storage readback and CRC verification is active.", "reset": "0", "expression": "`APB4_CRYPTO__MEM_STATUS_VERIFY_BUSY"}, + {"lsb": 5, "msb": 5, "name": "TABLE_LOCKED", "description": "The verified constants banks remain locked until hard/PCLK reset; zeroize does not unlock them.", "reset": "0", "expression": "`APB4_CRYPTO__MEM_STATUS_TABLE_LOCKED"}, + {"lsb": 6, "msb": 6, "name": "FAULT", "description": "A sticky storage lifecycle fault is active.", "reset": "0", "expression": "`APB4_CRYPTO__MEM_STATUS_FAULT"}, + {"lsb": 7, "msb": 31, "name": "Reserved", "description": "Reserved; reads zero.", "reset": "0", "expression": "25'd0"} + ] + }, + "main.MEM_CONTROL": { + "access": "WO", + "description": "One-hot storage lifecycle command; zero is a no-op.", + "reset": "Not retained (command/data port)", + "fields": [ + {"lsb": 0, "msb": 0, "name": "BEGIN", "description": "Begin a new ordered constants load.", "reset": "Not retained", "expression": "`APB4_CRYPTO__MEM_CONTROL_BEGIN"}, + {"lsb": 1, "msb": 1, "name": "COMMIT", "description": "Commit the complete image and start readback verification.", "reset": "Not retained", "expression": "`APB4_CRYPTO__MEM_CONTROL_COMMIT"}, + {"lsb": 2, "msb": 2, "name": "CANCEL", "description": "Cancel an unlocked load attempt and start cleanup.", "reset": "Not retained", "expression": "`APB4_CRYPTO__MEM_CONTROL_CANCEL"}, + {"lsb": 3, "msb": 31, "name": "Reserved", "description": "Reserved; write zero.", "reset": "Not retained", "expression": "29'd0"} + ] + }, + "main.TABLE_ID": { + "access": "RO", + "description": "Frozen CRYC1 constants-image identity.", + "reset": "0x43525901", + "fields": [ + {"lsb": 0, "msb": 31, "name": "ID", "description": "CRYC1 image identifier.", "reset": "0x43525901", "expression": "`APB4_CRYPTO__TABLE_ID_VALUE"} + ] + }, + "main.TABLE_WORDS": { + "access": "RO", + "description": "Accepted ordered payload word count; BEGIN, CANCEL and reset clear it.", + "reset": "0", + "fields": [ + {"lsb": 0, "msb": 11, "name": "WORDS", "description": "Accepted word count from 0 through 2048.", "reset": "0", "expression": "s_table_words"}, + {"lsb": 12, "msb": 31, "name": "Reserved", "description": "Reserved; reads zero.", "reset": "0", "expression": "20'd0"} + ] + }, + "main.TABLE_DATA": { + "access": "WO", + "description": "Auto-incrementing full-word constants loader input.", + "reset": "Not retained (command/data port)", + "fields": [ + {"lsb": 0, "msb": 31, "name": "DATA", "description": "Next constants-image word; full PSTRB is required.", "reset": "Not retained", "expression": "write data"} + ] + }, + "main.TABLE_CRC": { + "access": "RO", + "description": "CRC from the last complete full-storage readback.", + "reset": "0", + "fields": [ + {"lsb": 0, "msb": 31, "name": "CRC", "description": "Readback CRC; zero until verification completes.", "reset": "0", "expression": "s_table_crc"} + ] + }, + "main.MEM_ERROR": { + "access": "RO", + "description": "First storage lifecycle error with physical bank and row context.", + "reset": "0", + "fields": [ + {"lsb": 0, "msb": 7, "name": "CODE", "description": "First lifecycle error code; values 1 through 6 are defined.", "reset": "0", "expression": "`APB4_CRYPTO__MEM_ERROR_CODE_MASK"}, + {"lsb": 8, "msb": 10, "name": "BANK", "description": "Physical bank index; non-addressed errors report zero.", "reset": "0", "expression": "`APB4_CRYPTO__MEM_ERROR_BANK_MASK"}, + {"lsb": 11, "msb": 20, "name": "ROW", "description": "Physical row index; non-addressed errors report zero.", "reset": "0", "expression": "`APB4_CRYPTO__MEM_ERROR_ROW_MASK"}, + {"lsb": 21, "msb": 30, "name": "Reserved", "description": "Reserved; reads zero.", "reset": "0", "expression": "10'd0"}, + {"lsb": 31, "msb": 31, "name": "VALID", "description": "The first-error record is valid.", "reset": "0", "expression": "`APB4_CRYPTO__MEM_ERROR_VALID"} + ] + }, + "main.MEM_CYCLES": { + "access": "RO", + "description": "Active PCLK cycles in the current or last verify/scrub operation.", + "reset": "0", + "fields": [ + {"lsb": 0, "msb": 31, "name": "CYCLES", "description": "Maintenance cycle count, excluding loader inter-write gaps.", "reset": "0", "expression": "s_mem_cycles"} + ] + }, + "main.AES_BYTES_IN": { + "access": "RO", + "description": "Accepted AES input byte count.", + "reset": "0", + "fields": [ + {"lsb": 0, "msb": 31, "name": "COUNT", "description": "Bytes accepted for the current or last AES operation.", "reset": "0", "expression": "s_aes_bytes_in"} + ] + }, + "main.AES_BYTES_OUT": { + "access": "RO", + "description": "Consumed AES output byte count.", + "reset": "0", + "fields": [ + {"lsb": 0, "msb": 31, "name": "COUNT", "description": "Bytes consumed from the current or last AES operation.", "reset": "0", "expression": "s_aes_bytes_out"} + ] + }, + "main.AES_CYCLES": { + "access": "RO", + "description": "AES operation cycle count.", + "reset": "0", + "fields": [ + {"lsb": 0, "msb": 31, "name": "CYCLES", "description": "Cycles in the current or last AES operation.", "reset": "0", "expression": "s_aes_cycles"} + ] + }, + "main.SHA_CYCLES": { + "access": "RO", + "description": "SHA operation cycle count.", + "reset": "0", + "fields": [ + {"lsb": 0, "msb": 31, "name": "CYCLES", "description": "Cycles in the current or last SHA operation.", "reset": "0", "expression": "s_sha_cycles"} + ] + }, + "main.RSA_CYCLES": { + "access": "RO", + "description": "RSA operation cycle count.", + "reset": "0", + "fields": [ + {"lsb": 0, "msb": 31, "name": "CYCLES", "description": "Cycles in the current or last RSA operation.", "reset": "0", "expression": "s_rsa_cycles"} + ] + }, + "main.RSA_PROGRESS": { + "access": "RO", + "description": "RSA private-operation flag and exponent position.", + "reset": "0", + "fields": [ + {"lsb": 0, "msb": 0, "name": "PRIVATE", "description": "The active operation uses the private exponent path.", "reset": "0", "expression": "s_regs_q.private_operation"}, + {"lsb": 1, "msb": 11, "name": "EXPONENT_INDEX", "description": "Current exponent bit position.", "reset": "0", "expression": "s_regs_q.exponent_index"}, + {"lsb": 12, "msb": 31, "name": "Reserved", "description": "Reserved; reads zero.", "reset": "0", "expression": "20'd0"} + ] + }, "main.COMMAND": { "fields": [ { @@ -4287,11 +4416,19 @@ }, { "lsb": 5, + "msb": 5, + "name": "MEMORY_READY", + "description": "Writing one injects MEMORY_READY into sticky IRQ state for interrupt-path testing; it is not initialization or physical-erasure completion evidence.", + "reset": "Register reset applies", + "expression": "`APB4_CRYPTO__IRQ_MEMORY_READY" + }, + { + "lsb": 6, "msb": 31, "name": "Reserved", "description": "Reserved; write zero.", "reset": "Not retained", - "expression": "32'd0" + "expression": "26'd0" } ], "reset": "Not retained (command/data port)" diff --git a/publications/datasheets/register-profiles.json b/publications/datasheets/register-profiles.json index b0519628..3d838724 100644 --- a/publications/datasheets/register-profiles.json +++ b/publications/datasheets/register-profiles.json @@ -1397,12 +1397,13 @@ } ], "support": [ - "rtl/ip/security/crypto_aes_core.sv", - "rtl/ip/security/crypto_aes_engine.sv", - "rtl/ip/security/crypto_montgomery.sv", - "rtl/ip/security/crypto_rsa_core.sv", - "rtl/ip/security/crypto_sha2_core.sv", - "rtl/ip/security/crypto_sha2_engine.sv" + "rtl/ip/security/crypto_aes_sram_core.sv", + "rtl/ip/security/crypto_aes_sram_engine.sv", + "rtl/ip/security/crypto_mem_ctrl.sv", + "rtl/ip/security/crypto_montgomery_sram.sv", + "rtl/ip/security/crypto_rsa_sram_core.sv", + "rtl/ip/security/crypto_sha2_sram_engine.sv", + "rtl/ip/security/crypto_sram_store.sv" ] }, "mailbox": { diff --git a/publications/datasheets/sections/development-environment.typ b/publications/datasheets/sections/development-environment.typ index 374c89e9..6d5aa0a8 100644 --- a/publications/datasheets/sections/development-environment.typ +++ b/publications/datasheets/sections/development-environment.typ @@ -7,8 +7,10 @@ The supported open-source tool environment targets #environment.platform. The Docker image, Nix application and manual Ubuntu #environment.ubuntu bootstrap share the repository's locked installer. Docker and Nix use Python #environment.python to match the pinned requirement sets; -both provide Java #environment.java for the locked SBT #environment.sbt toolchain. These are -development prerequisites, *not additional SoC functions* or a statement of target performance. +both provide Java #environment.java for the locked SBT launcher #environment.sbt_launcher. +Each project selects its SBT engine through its own pinned build properties; the launcher +version is not an engine-version claim. These are development prerequisites, +*not additional SoC functions* or a statement of target performance. #ds-table("development-entrypoints",[Development entrypoints and their boundaries], ([Entrypoint],[Reproducible input],[Use and evidence boundary]), diff --git a/publications/datasheets/system-reference.json b/publications/datasheets/system-reference.json index 8a5cc233..55a67220 100644 --- a/publications/datasheets/system-reference.json +++ b/publications/datasheets/system-reference.json @@ -1,22 +1,30 @@ { "schema_version": 1, - "source_revision": "2a497ecef0b084c02f77ddfb1e94fb0197e14b02", + "source_revision": "c3de7c602a7ca0f0f9ade9d3ffb59339bc34fb8b", "sources": [ + "Makefile", "app/README.md", + "app/apps/apu_release/main.c", "app/apps/hp_boot/hp_boot_bundle.h", "app/apps/hp_boot/main.c", + "app/ports/hp-apu/main.c", "app/ports/linux/README.md", "app/ports/linux/linux/retrosoc_hp.dts", "app/ports/linux/opensbi/retrosoc_hp/platform.c", "configs/benchmark/ihp130-hazard3-coremark.mk", + "configs/ci/ihp130-apu.mk", "configs/ci/ihp130-hp.mk", "configs/ci/ihp130.mk", "configs/cluster/mini-mpw.mk", "crt/README.md", + "crt/include/retrosoc/hal/apu_regs.h", "crt/include/retrosoc/hal/ga2d.h", + "crt/include/retrosoc/hal/npu.h", + "crt/include/retrosoc/hal/npu_regs.h", "crt/include/retrosoc/hal/resource.h", "crt/include/retrosoc/hal/sysctrl.h", "crt/src/hal/ga2d.c", + "crt/src/hal/npu.c", "crt/src/hal/resource.c", "crt/src/hal/sysctrl.c", "docs/axi4-interconnect.md", @@ -26,6 +34,7 @@ "docs/hazard3-debug.md", "docs/ip/fabric-monitor.md", "docs/ip/ga2d.md", + "docs/ip/npu-verification.md", "docs/ip/resource-controller.md", "docs/lp-hp-architecture.md", "docs/mini-high-performance-traceability.md", @@ -34,17 +43,28 @@ "physical/README.md", "publications/datasheets/mini.json", "publications/datasheets/register-profiles.json", + "publications/examples/npu.c", "rtl/ip/multimedia/apb4_apu.sv", "rtl/ip/multimedia/apb4_ga2d.sv", + "rtl/ip/multimedia/apb4_npu.sv", "rtl/ip/multimedia/apu_define.svh", "rtl/ip/multimedia/apu_kws_engine.sv", "rtl/ip/multimedia/apu_kws_model_loader.sv", "rtl/ip/multimedia/apu_kws_sram_client.sv", "rtl/ip/multimedia/apu_local_sram.sv", "rtl/ip/multimedia/apu_p5_codecs.apus", + "rtl/ip/multimedia/apu_reg.sv", "rtl/ip/multimedia/ga2d_core.sv", "rtl/ip/multimedia/ga2d_dma.sv", + "rtl/ip/multimedia/npu_accumulator.sv", + "rtl/ip/multimedia/npu_define.svh", + "rtl/ip/multimedia/npu_job_decoder.sv", + "rtl/ip/multimedia/npu_local_sram.sv", + "rtl/ip/multimedia/npu_pkg.sv", + "rtl/ip/multimedia/npu_reg.sv", + "rtl/ip/multimedia/npu_scheduler.sv", "rtl/mini/integration/soc_topology.json", + "scripts/apu_abi_digest.py", "scripts/apu_isa.py", "scripts/apu_kws.py", "scripts/apu_mcasm.py", @@ -52,8 +72,23 @@ "scripts/build_apu_p5_bundle.py", "scripts/build_hp_linux.py", "scripts/check_lp_hp_performance.py", + "scripts/npu_compiler.py", + "scripts/npu_compiler_p0.py", + "scripts/npu_descriptors.py", "scripts/package_hp_boot.py", - "tests/test_lp_irq.py" + "scripts/parse_performance_log.py", + "tests/test_lp_irq.py", + "rtl/mini/top/retrosoc.sv", + "rtl/mini/top/apb4_periph.sv", + "docs/development-environment.md", + "scripts/development_environment.py", + "dependencies/dependencies.lock.json", + "docker/Dockerfile", + "flake.nix", + ".github/workflows/development-environment.yml", + ".github/workflows/quality.yml", + "CONTRIBUTING.md", + "docs/git-workflow.md" ], "support": [ { @@ -609,7 +644,7 @@ "id": "resource", "title": "Resource Controller", "implementation": "Partial", - "scope": "Nine independently managed shared resources; resource 8 owns the active P5 GA2D direct 2D engine and IRQ route.", + "scope": "Ten independently managed shared resources; resource 8 owns GA2D and resource 9 owns NPU execution, including lifecycle and LP/HP IRQ routing.", "dependencies": "No additional off-chip component implied; use the selected clock/reset and access policy.", "hal": "Published API and syntax example; see the IP chapter.", "linux": "Native driver support not established in this publication.", @@ -629,7 +664,7 @@ "id": "monitor", "title": "Fabric Monitor", "implementation": "Integrated", - "scope": "Nine master and six target observation banks; bank 8 observes active P5 GA2D direct 2D traffic.", + "scope": "Ten master and six target observation banks; master bank 8 observes GA2D traffic and master bank 9 observes NPU descriptor and data DMA traffic.", "dependencies": "No additional off-chip component implied; use the selected clock/reset and access policy.", "hal": "Published API and syntax example; see the IP chapter.", "linux": "Native driver support not established in this publication.", @@ -739,23 +774,80 @@ "id": "apu", "title": "Audio Processing Unit", "implementation": "Partial", - "scope": "Microcode-controlled WAV/FLAC decoding with private DMA, direct/ring submission, I2S TX and local storage.", - "dependencies": "Load the compatible checked-in P5 APUMC V2 image. MP3 is unsupported and KWS is gated off by default; corpus, real-time and physical qualification remain separate.", + "scope": "WAV/FLAC image and job/stream execution; APUC-backed KWS is enabled only in the P9 acceptance configuration. MP3 remains unsupported.", + "dependencies": "Load compatible APUMC V2, APUC and APUM images in order. MP3 is unsupported and KWS is gated off by default; corpus, real-time and physical qualification remain separate.", "hal": "Published API and syntax example; see the IP chapter.", - "linux": "Native driver support not established in this publication.", + "linux": "No delivered Linux ASoC integration. The LP/HP APU release image is bare-metal acceptance firmware, not a kernel driver.", "verification": "Tests available", "sources": [ + "Makefile", + "app/apps/apu_release/main.c", + "app/ports/hp-apu/main.c", + "configs/ci/ihp130-apu.mk", "crt/include/retrosoc/hal/apu.h", + "crt/include/retrosoc/hal/apu_regs.h", "crt/src/hal/apu.c", "docs/ip/apu.md", "publications/examples/apu.c", "rtl/ip/multimedia/apb4_apu.sv", + "rtl/ip/multimedia/apu_define.svh", + "rtl/ip/multimedia/apu_kws_coeff_loader.sv", + "rtl/ip/multimedia/apu_kws_coeff_store.sv", + "rtl/ip/multimedia/apu_kws_sram_client.sv", + "rtl/ip/multimedia/apu_local_sram.sv", "rtl/ip/multimedia/apu_p5_codecs.apus", "rtl/ip/multimedia/apu_reg.sv", + "rtl/ip/multimedia/apu_proof_memo.sv", + "scripts/apu_abi_digest.py", + "scripts/apu_isa.py", + "scripts/apu_kws.py", + "scripts/apu_kws_coeff.py", + "scripts/apu_mcasm.py", + "scripts/apu_p5_coefficients.py", "scripts/build_apu_p5_bundle.py" ], "tests": [ - "tests/test_apu.py" + "tests/test_apu.py", + "tests/test_apu_p7_concurrent.py", + "tests/test_apu_p7_qualification.py", + "tests/test_apu_p8_contention.py", + "tests/test_apu_p8_quiesce_load.py" + ], + "reports": [] + }, + { + "id": "npu", + "title": "Neural Processing Unit", + "implementation": "Integrated", + "scope": "Eight INT8 operators with native HP descriptor/DMA execution and private local SRAM.", + "dependencies": "Static compiler-supported graphs, exclusive resource/buffer ownership and explicit cache maintenance; locked KWS/VWW references for qualification.", + "hal": "Eleven public NPU HAL operations and a bounded submission example.", + "linux": "No native Linux NPU driver ABI is established. The HP smoke payload is freestanding acceptance firmware.", + "verification": "Tests available", + "sources": [ + "crt/include/retrosoc/hal/npu.h", + "crt/include/retrosoc/hal/npu_regs.h", + "crt/src/hal/npu.c", + "docs/ip/npu-verification.md", + "docs/ip/npu.md", + "publications/examples/npu.c", + "rtl/ip/multimedia/apb4_npu.sv", + "rtl/ip/multimedia/npu_accumulator.sv", + "rtl/ip/multimedia/npu_define.svh", + "rtl/ip/multimedia/npu_job_decoder.sv", + "rtl/ip/multimedia/npu_local_sram.sv", + "rtl/ip/multimedia/npu_pkg.sv", + "rtl/ip/multimedia/npu_reg.sv", + "rtl/ip/multimedia/npu_scheduler.sv", + "scripts/npu_compiler.py", + "scripts/npu_compiler_p0.py", + "scripts/npu_descriptors.py" + ], + "tests": [ + "tests/test_npu_register_parity.py", + "tests/test_npu_rtl_p4.py", + "tests/test_npu_compiler.py", + "tests/test_npu_p6.py" ], "reports": [] }, @@ -896,7 +988,7 @@ "impact": "Stale reads or loss of dirty data across CPU/DMA ownership changes.", "trigger": "Concurrent cached CPU access and non-snooping DMA/LP access.", "workaround": "Use exclusive ownership, whole cache-block ranges, directional cache maintenance and fences.", - "applies_to": "Reviewed v0.4 PRODUCT snapshot; MPW differences are stated separately.", + "applies_to": "Reviewed v0.5 PRODUCT snapshot; MPW differences are stated separately.", "sources": [ "docs/lp-hp-architecture.md", "docs/ip/resource-controller.md" @@ -904,14 +996,16 @@ }, { "id": "hp-ready-wait", - "title": "HP loader has no firmware-local ready timeout", - "impact": "LP can wait indefinitely for the expected Linux mailbox event.", - "trigger": "No mailbox message after HP release.", - "workaround": "Use the simulator deadline during acceptance. A board supervisor/watchdog policy is integration work; no automatic retry is implemented here.", - "applies_to": "Reviewed v0.4 PRODUCT snapshot; MPW differences are stated separately.", + "title": "Linux ready service does not complete loader acceptance", + "impact": "The supplied rootfs publishes the initial ready checkpoint but does not provide the later GA2D result and cache-clean service required by the current hp_boot acceptance sequence.", + "trigger": "Using the ready-only Linux service where the loader expects the full acceptance mailbox protocol.", + "workaround": "Pair the loader with a matching acceptance payload or service. Current polling is bounded by iteration budgets and missing handshakes fail their stage; an initial ready message is not a terminal pass.", + "applies_to": "Reviewed v0.5 PRODUCT snapshot; MPW differences are stated separately.", "sources": [ "app/apps/hp_boot/main.c", - "configs/ci/ihp130-hp.mk" + "configs/ci/ihp130-hp.mk", + "app/ports/linux/hp_ready.c", + "crt/src/hal/hp_mailbox.c" ] }, { @@ -920,7 +1014,7 @@ "impact": "A CRC-valid image is not proven to come from a trusted signer.", "trigger": "Untrusted image or writable external boot storage.", "workaround": "Treat signing, key storage, rollback prevention and secure recovery as separate unimplemented system requirements.", - "applies_to": "Reviewed v0.4 PRODUCT snapshot; MPW differences are stated separately.", + "applies_to": "Reviewed v0.5 PRODUCT snapshot; MPW differences are stated separately.", "sources": [ "app/apps/hp_boot/main.c", "app/apps/hp_boot/hp_boot_bundle.h" @@ -932,7 +1026,7 @@ "impact": "A HAL or DT node does not provide a native Linux driver.", "trigger": "Applications attempt direct Linux use of a custom peripheral.", "workaround": "Use the published support matrix, retain LP ownership where needed, and validate a platform driver before handoff.", - "applies_to": "Reviewed v0.4 PRODUCT snapshot; MPW differences are stated separately.", + "applies_to": "Reviewed v0.5 PRODUCT snapshot; MPW differences are stated separately.", "sources": [ "app/ports/linux/README.md", "app/ports/linux/linux/retrosoc_hp.dts" @@ -944,7 +1038,7 @@ "impact": "Some downstream peripheral engines are not reset by the central lifecycle request.", "trigger": "Using Resource CONTROL.RESET as independent engine reset containment.", "workaround": "Drain and use each IP reset/recovery contract. APU P1 has a local reset connection; do not generalize it to all engines.", - "applies_to": "Reviewed v0.4 PRODUCT snapshot; MPW differences are stated separately.", + "applies_to": "Reviewed v0.5 PRODUCT snapshot; MPW differences are stated separately.", "sources": [ "docs/ip/resource-controller.md" ] @@ -955,7 +1049,7 @@ "impact": "Missing cache-clean acknowledgement prevents preservation of modified shared data.", "trigger": "HP shutdown times out before acknowledgement.", "workaround": "Keep a recoverable authoritative copy outside dirty HP cache; treat timed-out work as failed and reinitialize dependent queues.", - "applies_to": "Reviewed v0.4 PRODUCT snapshot; MPW differences are stated separately.", + "applies_to": "Reviewed v0.5 PRODUCT snapshot; MPW differences are stated separately.", "sources": [ "docs/lp-hp-architecture.md", "docs/ip/resource-controller.md" @@ -967,7 +1061,7 @@ "impact": "The inactive memory window returns an error and its pads are disconnected.", "trigger": "Accessing the inactive memory mode or attempting a live protocol change.", "workaround": "Select the mode at boot before use; respect the sticky lock. A live handover is not supported.", - "applies_to": "Reviewed v0.4 PRODUCT snapshot; MPW differences are stated separately.", + "applies_to": "Reviewed v0.5 PRODUCT snapshot; MPW differences are stated separately.", "sources": [ "docs/lp-hp-architecture.md" ] @@ -978,7 +1072,7 @@ "impact": "Dedicated USB2 ULPI and SDIO1 pads need board assignment and electrical/timing review.", "trigger": "Assuming logical pads are FPGA ball or package-pin assignments.", "workaround": "Supply board constraints, bank voltages, external devices and validated timing before enabling a physical route.", - "applies_to": "Reviewed v0.4 PRODUCT snapshot; MPW differences are stated separately.", + "applies_to": "Reviewed v0.5 PRODUCT snapshot; MPW differences are stated separately.", "sources": [ "fpga/README.md", "publications/datasheets/sections/pins.typ" @@ -987,10 +1081,10 @@ { "id": "apu-production", "title": "APU MP3/KWS availability and qualification limits", - "impact": "WAV/FLAC code and image are implemented; this does not establish complete corpus, sustained real-time or physical qualification. MP3 remains a reserved trap entry; KWS RTL exists but PRODUCT defaults to EnableP7=0 and does not advertise KWS.", + "impact": "WAV/FLAC code and image are implemented. MP3 remains a reserved trap; default PRODUCT disables KWS, while the dedicated P7 configuration enables its fixed APUM model. These facts do not establish full-corpus, sustained real-time or physical qualification.", "trigger": "Submitting MP3, assuming default KWS availability, or inferring full qualification from capability bits.", - "workaround": "Use advertised WAV/FLAC paths with a validated APUMC image and supported formats/rates. Treat KWS as gated development functionality until its complete qualification evidence is supplied.", - "applies_to": "Reviewed v0.4 PRODUCT snapshot; MPW differences are stated separately.", + "workaround": "Read the configuration-specific capability/digest. Use the supported image/model and explicit loader, cache and ownership protocol. Obtain complete revision-matched accuracy/concurrency/physical reports before wider qualification.", + "applies_to": "Reviewed v0.5 PRODUCT snapshot; MPW differences are stated separately.", "sources": [ "publications/datasheets/ips/apu.typ", "rtl/ip/multimedia/apu_reg.sv" @@ -1002,7 +1096,7 @@ "impact": "Deterministic test data cannot supply production cryptographic entropy.", "trigger": "Using the current entropy stream to generate secret keys or nonces.", "workaround": "Keep diagnostic use separate; production entropy requires a reviewed physical source and qualification.", - "applies_to": "Reviewed v0.4 PRODUCT snapshot; MPW differences are stated separately.", + "applies_to": "Reviewed v0.5 PRODUCT snapshot; MPW differences are stated separately.", "sources": [ "publications/datasheets/ips/rng.typ", "rtl/mini/top/apb4_system.sv" @@ -1014,7 +1108,7 @@ "impact": "Configuration clocks and behavioral models are not electrical or silicon ratings.", "trigger": "Selecting board voltage, frequency, thermal or timing limits from RTL defaults.", "workaround": "Use approved technology, macro, package and board reports; leave absent specifications TBD.", - "applies_to": "Reviewed v0.4 PRODUCT snapshot; MPW differences are stated separately.", + "applies_to": "Reviewed v0.5 PRODUCT snapshot; MPW differences are stated separately.", "sources": [ "physical/README.md", "docs/pll-clock-control.md" @@ -1026,7 +1120,7 @@ "impact": "Legacy selection writes are rejected in PRODUCT.", "trigger": "Calling selectable user-core/IP mutators on a fixed PRODUCT configuration.", "workaround": "Detect mode/capabilities first and use fixed EXT-L/EXT-H APIs in PRODUCT.", - "applies_to": "Reviewed v0.4 PRODUCT snapshot; MPW differences are stated separately.", + "applies_to": "Reviewed v0.5 PRODUCT snapshot; MPW differences are stated separately.", "sources": [ "docs/lp-hp-architecture.md", "docs/ip/user-ip.md" @@ -1050,7 +1144,7 @@ "impact": "READ_BASE and WRITE_BASE next-state assignments are not gated by the KindExtH write-legal result; an EXT-L write can change those readbacks while returning PSLVERR.", "trigger": "Writing READ_BASE or WRITE_BASE through the EXT-L register window.", "workaround": "Treat these writes as invalid and avoid them. Preserve the slot fault/address when diagnosing an error; do not assume a rejected write rolls back state. EXT-L has no connected data master, so these local outputs do not grant an EXT-L DMA path.", - "applies_to": "Reviewed v0.4 PRODUCT source snapshot; static RTL observation, no new simulation or hardware test.", + "applies_to": "Reviewed v0.5 PRODUCT source snapshot; static RTL observation, no new simulation or hardware test.", "sources": [ "rtl/mini/top/extension_slot.sv", "rtl/mini/top/extension_subsystem.sv" @@ -1067,6 +1161,20 @@ "crt/arch/riscv/startup.S", "rtl/mk/software.mk" ] + }, + { + "id": "npu-deployment-scope", + "title": "NPU execution does not imply arbitrary model or qualified performance support", + "impact": "Unsupported graphs, unsafe buffer reuse or an assumed Linux driver can prevent correct deployment.", + "trigger": "Dynamic/arbitrary TFLite graphs, unadvertised operators, timeout without drain, or missing cache/ownership handoff.", + "workaround": "Use the static compiler subset and explicit CPU preprocessing/Softmax. Check capability and numeric profile, retain buffers until terminal/drained state, and require exact-revision reports for accuracy/performance claims.", + "applies_to": "Reviewed v0.5 PRODUCT snapshot; no MLPerf, timing-closure or silicon qualification claim.", + "sources": [ + "rtl/ip/multimedia/npu_reg.sv", + "rtl/ip/multimedia/apb4_npu.sv", + "scripts/npu_compiler.py", + "crt/src/hal/npu.c" + ] } ], "programming": { @@ -2548,7 +2656,7 @@ { "file": "publications/datasheets/features.json", "kind": "snippet", - "text": "\"64-byte TX and RX FIFOs; fractional baud-rate generator.\"" + "text": "\"**64-byte TX and RX FIFOs**; fractional baud-rate generator.\"" } ] }, @@ -2572,7 +2680,7 @@ { "file": "publications/datasheets/features.json", "kind": "snippet", - "text": "\"Two controller instances with 7-bit and 10-bit addressing.\"" + "text": "\"Two controller instances with **7-bit and 10-bit addressing**.\"" } ] }, @@ -2597,7 +2705,7 @@ { "file": "publications/datasheets/features.json", "kind": "snippet", - "text": "\"Stereo master TX/RX with independent audio clock.\"" + "text": "\"**Stereo master TX/RX** with independent audio clock.\"" } ] }, @@ -2621,7 +2729,7 @@ { "file": "publications/datasheets/features.json", "kind": "snippet", - "text": "\"Bidirectional open-drain host interface.\"" + "text": "\"Bidirectional **open-drain** host interface.\"" } ] }, @@ -2645,7 +2753,7 @@ { "file": "publications/datasheets/features.json", "kind": "snippet", - "text": "\"24-bit GRB transmission on one GPIO alternate function.\"" + "text": "\"**24-bit GRB** transmission on one GPIO alternate function.\"" } ] }, @@ -2670,7 +2778,7 @@ { "file": "publications/datasheets/features.json", "kind": "snippet", - "text": "\"SD card SPI-mode command/data host.\"" + "text": "\"SD card **SPI-mode** command/data host.\"" } ] }, @@ -2696,7 +2804,7 @@ { "file": "publications/datasheets/features.json", "kind": "snippet", - "text": "\"Native one-bit/four-bit SDR operation.\"" + "text": "\"Native **one-bit/four-bit SDR** operation.\"" } ] }, @@ -2721,7 +2829,7 @@ { "file": "publications/datasheets/features.json", "kind": "snippet", - "text": "\"Dual-role digital controller with external 8-bit ULPI PHY.\"" + "text": "\"Dual-role digital controller with **external 8-bit ULPI PHY**.\"" } ] }, @@ -2746,7 +2854,7 @@ { "file": "publications/datasheets/features.json", "kind": "snippet", - "text": "\"Four chip-select slots and 16 programmable LUT sequences.\"" + "text": "\"Four chip-select slots and **16 programmable LUT sequences**.\"" } ] }, @@ -2771,7 +2879,7 @@ { "file": "publications/datasheets/features.json", "kind": "snippet", - "text": "\"Four ESP-PSRAM64H devices addressable through a 32 MiB window.\"" + "text": "\"Four ESP-PSRAM64H devices addressable through a **32 MiB window**.\"" } ] }, @@ -2796,7 +2904,7 @@ { "file": "publications/datasheets/features.json", "kind": "snippet", - "text": "\"One octal DDR memory interface and one selected protocol profile.\"" + "text": "\"One octal DDR memory interface and **one selected protocol profile**.\"" } ] }, @@ -2821,7 +2929,7 @@ { "file": "publications/datasheets/features.json", "kind": "snippet", - "text": "\"Fixed 64 MiB, x16 SDR geometry with bank/row tracking.\"" + "text": "\"Fixed **64 MiB, x16 SDR** geometry with bank/row tracking.\"" } ] }, @@ -2845,7 +2953,7 @@ { "file": "publications/datasheets/features.json", "kind": "snippet", - "text": "\"8-bit parallel RGB565/YUV422 capture.\"" + "text": "\"**8-bit parallel RGB565/YUV422** capture.\"" } ] }, @@ -2857,7 +2965,7 @@ "title": "JPEG", "role": "Baseline sequential codec", "modes": "8-bit SOF0 encode/decode and the indexed raster formats; modes are mutually exclusive.", - "excluded": "No progressive/lossless/arithmetic/10-12-bit modes. Native SoC DMA admission is currently blocked at slot 6.", + "excluded": "No progressive/lossless/arithmetic/10-12-bit modes. DMA permits one normal read and one normal write at a time.", "software": "Standalone codec/register behavior is distinct from end-to-end SoC payload availability.", "evidence": "Source-level subset; no compliance report attached", "sources": [ @@ -2870,7 +2978,7 @@ { "file": "publications/datasheets/features.json", "kind": "snippet", - "text": "\"8-bit Baseline Sequential JPEG encode or decode.\"" + "text": "\"8-bit **Baseline Sequential JPEG** encode or decode.\"" } ] }, @@ -2882,7 +2990,7 @@ "title": "APU", "role": "Coreless control/transport subsystem", "modes": "Register/transport and bounded development codec paths described in the IP chapter.", - "excluded": "MP3 is not supported. KWS is implemented as a gated development path and remains disabled/unadvertised by default. No generic codec or full corpus qualification is implied.", + "excluded": "MP3 unsupported; KWS requires the P7-enabled configuration. No generic codec, arbitrary TFLite, Linux ASoC or complete corpus qualification is implied.", "software": "A HAL, microcode format or test source does not establish an enabled production audio service.", "evidence": "Source-level subset; no compliance report attached", "sources": [ @@ -2894,7 +3002,7 @@ { "file": "publications/datasheets/features.json", "kind": "snippet", - "text": "\"Coreless microcode sequencer with private DMA and local storage.\"" + "text": "\"**Coreless microcode sequencer** with private DMA and local storage.\"" } ] }, @@ -2921,6 +3029,30 @@ "text": "`define APB4_GA2D__CAPABILITY_P5 32'h0000_07ff" } ] + }, + { + "id": "npu", + "ips": [ + "npu" + ], + "title": "NPU", + "role": "Static INT8 tensor processing", + "modes": "Eight operator classes, checked INT32 accumulation, double-rounding requantization and native HP descriptor DMA.", + "software": "Static compiler-generated C, NPU HAL and freestanding LP/HP acceptance; preprocessing and terminal Softmax run on CPU.", + "excluded": "No arbitrary/dynamic TFLite graphs, implicit fallback, APUM binary compatibility, dedicated camera/audio stream or native Linux driver ABI.", + "evidence": "Source-level subset; no compliance report attached", + "sources": [ + "rtl/ip/multimedia/npu_define.svh", + "rtl/ip/multimedia/apb4_npu.sv", + "scripts/npu_compiler.py" + ], + "bindings": [ + { + "file": "rtl/ip/multimedia/npu_define.svh", + "kind": "snippet", + "text": "`define APB4_NPU__CAPABILITY_P4 32'h0000_007f" + } + ] } ], "formats": [ @@ -3194,7 +3326,7 @@ { "file": "publications/datasheets/features.json", "kind": "snippet", - "text": "\"Coreless microcode sequencer with private DMA and local storage.\"" + "text": "\"**Coreless microcode sequencer** with private DMA and local storage.\"" } ] } @@ -3728,6 +3860,22 @@ "rtl/ip/multimedia/ga2d_core.sv" ] }, + { + "id": "apb4_npu", + "chapter": "npu", + "family": "npu", + "mode": "PRODUCT", + "region": "APB4_NPU", + "catalog": "npu", + "qualification": "Integrated native-HP NPU execution with eight operator classes, descriptor DMA and private SRAM; CAPABILITY=0x7F and OP_CAPABILITY=0x1FE. Resource 9 routes LP vector 33 / HP PLIC source 12. Use configured lifecycle, cache and descriptor admission rules; no native Linux driver, arbitrary model or current corpus/physical qualification is implied.", + "sources": [ + "docs/ip/npu.md", + "rtl/ip/multimedia/npu_reg.sv", + "rtl/ip/multimedia/apb4_npu.sv", + "rtl/ip/multimedia/npu_control_cdc.sv", + "rtl/ip/multimedia/npu_core.sv" + ] + }, { "id": "apb4_crypto", "chapter": "crypto", @@ -4993,6 +5141,8 @@ 9, 9, 9, + 18, + 18, 10, 18, 19, @@ -5003,7 +5153,8 @@ 15, 16, 17, - 17 + 17, + 19 ], "expected_entries": 4, "meanings": { @@ -5025,8 +5176,8 @@ "15": "The request to hold HP after P5 GA2D completion returned an unexpected error.", "16": "Cache-clean request, P5 GA2D cache mailbox event, clean acknowledgement, or HP-held confirmation failed.", "17": "GA2D handoff back to LP or LP-owned safe-idle confirmation failed.", - "18": "RT-Thread ready message failed validation or HP reported a test failure.", - "19": "LP-to-HP IRQ command failed or RT-Thread final verdict failed validation." + "18": "NPU handoff to HP failed, or the RT-Thread ready message reported failure or mismatched identity.", + "19": "NPU handoff back to LP failed, or the RT-Thread IRQ command/final verdict failed." } } }, @@ -5068,6 +5219,11 @@ "rtl/mk/software.mk", "scripts/build_hp_linux.py", "scripts/regress.py", + "crt/src/hal/hp_mailbox.c", + "crt/include/retrosoc/core/status.h", + "rtl/ip/peripheral/hp_mailbox_define.svh", + "rtl/mini/address_map/memory_map.json", + "rtl/ip/peripheral/apb4_hp_mailbox.sv", "app/ports/linux/init" ], "bindings": [ @@ -5455,6 +5611,33 @@ "coverage": "Discover P5 capability, submit direct single-job FILL/COPY/CONVERT/BLEND work through master 8, including A8 fixed-color foreground masks and exact equal background/destination in-place composition, verify the resource-owned LP external completion route, and inspect destinations.", "boundary": "Exercises the direct private-AXI64 P5 functional subset only; it does not cover transparent-background/premultiplied-alpha modes, scaling, rendering, descriptor/ring/queue submission, cache coherency, a Linux graphics driver, HP P5 composition acceptance, or physical performance." }, + { + "id": "ga2d-bounded-wait", + "title": "GA2D bounded wait and timeout ownership", + "kind": "test-fail", + "code": 15, + "trigger": "rs_ci_smoke_ga2d_bounded_wait(", + "coverage": "Force a deliberately small rs_ga2d_wait budget to expire with RS_ETIMEOUT while a real SDRAM job keeps running, prove timeout expiry does not imply safe idle or buffer reclaim, then complete the job under a normal bounded wait with exact destination and counter checks, and confirm rs_ga2d_abort_wait on the idle engine.", + "boundary": "Covers LP polling-budget semantics only; it does not exercise HP-side timeout handling, watchdog TIMEOUT error recovery, or abort of an in-flight job." + }, + { + "id": "ga2d-dma-contention", + "title": "GA2D and central DMA concurrent progress", + "kind": "test-fail", + "code": 16, + "trigger": "rs_ci_smoke_ga2d_dma_contention(", + "coverage": "Run a central-DMA memory-to-memory transfer and a GA2D copy concurrently in disjoint SDRAM regions, verify both payloads byte-exactly, and confirm fabric-monitor request counters advance for both master 2 and master 8 during the shared window.", + "boundary": "Covers LP CPU, central DMA, and GA2D competition with SDRAM refresh in the behavioral product; wider peripheral-master contention is evidenced in the GA2D platform testbench, and no starvation bound is proven here." + }, + { + "id": "npu-p2-shell-irq", + "title": "NPU P2 shell ownership and IRQ route", + "kind": "test-fail", + "code": 17, + "trigger": "rs_ci_smoke_npu_irq(", + "coverage": "Hand resource 9 to LP through the Resource Controller quiesce/acknowledge round trip, read back the shell identity/capability, and verify the IRQ_TEST-injected event reaches external ordinal 31 and clears by W1C.", + "boundary": "Covers the P2 register shell and interrupt route only; EXECUTION_READY stays clear, the private master is tied idle, and no job, DMA, or operator behavior is exercised." + }, { "id": "apu", "title": "APU discovery", @@ -5830,6 +6013,7 @@ "rtl/ip/multimedia/apb4_apu.sv", "rtl/ip/multimedia/apb4_ga2d.sv", "rtl/ip/multimedia/apb4_jpeg.sv", + "rtl/ip/multimedia/apb4_npu.sv", "rtl/ip/multimedia/apu_control_store.sv", "rtl/ip/multimedia/apu_define.svh", "rtl/ip/multimedia/apu_local_sram.sv", @@ -5850,6 +6034,15 @@ "rtl/ip/multimedia/jpeg_encode_core.sv", "rtl/ip/multimedia/jpeg_reg.sv", "rtl/ip/multimedia/jpeg_table_store.sv", + "rtl/ip/multimedia/npu_accumulator.sv", + "rtl/ip/multimedia/npu_control_cdc.sv", + "rtl/ip/multimedia/npu_core.sv", + "rtl/ip/multimedia/npu_define.svh", + "rtl/ip/multimedia/npu_dma.sv", + "rtl/ip/multimedia/npu_local_sram.sv", + "rtl/ip/multimedia/npu_pkg.sv", + "rtl/ip/multimedia/npu_reg.sv", + "rtl/ip/multimedia/npu_scheduler.sv", "rtl/ip/peripheral/apb4_clint.sv", "rtl/ip/peripheral/apb4_dma.sv", "rtl/ip/peripheral/apb4_gpio.sv", @@ -5866,10 +6059,12 @@ "rtl/ip/peripheral/sysctrl_reg.sv", "rtl/ip/peripheral/timer_core.sv", "rtl/ip/peripheral/timer_reg.sv", + "crt/include/retrosoc/hal/crypto_regs.h", "rtl/ip/security/apb4_crypto.sv", - "rtl/ip/security/crypto_aes_engine.sv", - "rtl/ip/security/crypto_rsa_core.sv", - "rtl/ip/security/crypto_sha2_engine.sv", + "rtl/ip/security/crypto_aes_sram_engine.sv", + "rtl/ip/security/crypto_clearable_fifo.sv", + "rtl/ip/security/crypto_rsa_sram_core.sv", + "rtl/ip/security/crypto_sha2_sram_engine.sv", "rtl/ip/serial/apb4_i2c.sv", "rtl/ip/serial/apb4_i2c_define.svh", "rtl/ip/serial/apb4_i2s.sv", @@ -5965,6 +6160,9 @@ "rtl/mini/top/user_ip_top.sv", "rtl/mini/top/user_ip_wrapper.sv", "scripts/apu_isa.py", + "scripts/npu_compiler_p0.py", + "scripts/npu_descriptors.py", + "scripts/npu_executor.py", "scripts/package_hp_boot.py" ], "bindings": [ @@ -7151,57 +7349,110 @@ "soc_architecture_catalog": "publications/datasheets/soc-architecture.json" }, "ci_snapshot": { - "revision": "2a497ecef0b084c02f77ddfb1e94fb0197e14b02", - "checked_date": "2026-09-17", - "boundary": "Public GitHub workflow/job outcomes for this exact commit. Behavioral regression success is not synthesis, netlist, STA, formal, FPGA or silicon qualification. A failed prerequisite can leave later tests unexecuted.", + "revision": "c3de7c602a7ca0f0f9ade9d3ffb59339bc34fb8b", + "checked_date": "2026-09-23", + "checked_at": "2026-09-23T08:26:42Z", + "boundary": "Observed public GitHub workflow status for this exact commit. Unfinished runs have no conclusion. Installation, environment checking and runtime regression are separate evidence; workflow outcomes do not qualify unexecuted physical or silicon stages.", "runs": [ { - "name": "regression-ihp130", - "run_id": 35035899124, - "result": "success", - "scope": "IHP130 PR behavioral-only regression", - "note": "Run pr regression passed; formal environment step skipped. Synthesis/timing environment checks are setup checks, not physical results.", - "url": "https://github.com/retroSoC/retroSoC/actions/runs/35035899124" - }, - { - "name": "regression-gf180", - "run_id": 35035899130, - "result": "success", - "scope": "GF180 workflow", - "note": "Workflow outcome only; detailed stages require their own artifacts.", - "url": "https://github.com/retroSoC/retroSoC/actions/runs/35035899130" - }, - { - "name": "regression-ics55", - "run_id": 35035899146, - "result": "success", - "scope": "ICS55 workflow", - "note": "Workflow outcome only; detailed stages require their own artifacts.", - "url": "https://github.com/retroSoC/retroSoC/actions/runs/35035899146" + "name": "quality", + "run_id": 35833990836, + "status": "in_progress", + "conclusion": null, + "url": "https://github.com/retroSoC/retroSoC/actions/runs/35833990836", + "scope": "Repository quality checks and script/RTL fixture tests", + "note": "No terminal conclusion has been observed. No per-IP corpus or physical qualification is inferred." }, { "name": "regression-smoke", - "run_id": 35035899140, - "result": "success", - "scope": "Smoke workflow", - "note": "Does not qualify all peripheral use cases.", - "url": "https://github.com/retroSoC/retroSoC/actions/runs/35035899140" + "run_id": 35833991124, + "status": "completed", + "conclusion": "success", + "url": "https://github.com/retroSoC/retroSoC/actions/runs/35833991124", + "scope": "Bounded IHP130 smoke regression", + "note": "Selected workflow stages completed successfully. No per-IP corpus or physical qualification is inferred." }, { - "name": "quality", - "run_id": 35035898949, - "result": "failure", - "scope": "Quality workflow", - "note": "Check source formatting failed. Later host tests, script tests and APU P5 acceptance were skipped.", - "url": "https://github.com/retroSoC/retroSoC/actions/runs/35035898949" + "name": "regression-ihp130", + "run_id": 35833991071, + "status": "in_progress", + "conclusion": null, + "url": "https://github.com/retroSoC/retroSoC/actions/runs/35833991071", + "scope": "IHP130 hosted behavioral regression", + "note": "No terminal conclusion has been observed. No per-IP corpus or physical qualification is inferred." }, { "name": "regression-sky130", - "run_id": 35035899137, - "result": "failure", - "scope": "SKY130 PR workflow", - "note": "Run pr regression failed. Do not present this platform as passing.", - "url": "https://github.com/retroSoC/retroSoC/actions/runs/35035899137" + "run_id": 35833991199, + "status": "in_progress", + "conclusion": null, + "url": "https://github.com/retroSoC/retroSoC/actions/runs/35833991199", + "scope": "SKY130 hosted behavioral regression", + "note": "No terminal conclusion has been observed. No per-IP corpus or physical qualification is inferred." + }, + { + "name": "regression-gf180", + "run_id": 35833991194, + "status": "in_progress", + "conclusion": null, + "url": "https://github.com/retroSoC/retroSoC/actions/runs/35833991194", + "scope": "GF180 hosted behavioral regression", + "note": "No terminal conclusion has been observed. No per-IP corpus or physical qualification is inferred." + }, + { + "name": "regression-ics55", + "run_id": 35833991306, + "status": "in_progress", + "conclusion": null, + "url": "https://github.com/retroSoC/retroSoC/actions/runs/35833991306", + "scope": "ICS55 hosted behavioral regression", + "note": "No terminal conclusion has been observed. No per-IP corpus or physical qualification is inferred." + }, + { + "name": "development-environment", + "run_id": 35833990893, + "status": "in_progress", + "conclusion": null, + "url": "https://github.com/retroSoC/retroSoC/actions/runs/35833990893", + "scope": "Docker/Nix installation, environment checks and hosted IHP130 behavioral regression", + "note": "No terminal conclusion has been observed. No per-IP corpus or physical qualification is inferred.", + "observations": [ + { + "name": "docker: Build Docker development environment", + "scope": "installation", + "status": "completed", + "conclusion": "success", + "url": "https://github.com/retroSoC/retroSoC/actions/runs/35833990893/job/107092965761" + }, + { + "name": "docker: Run IHP130 regression in development environment", + "scope": "runtime-regression", + "status": "in_progress", + "conclusion": null, + "url": "https://github.com/retroSoC/retroSoC/actions/runs/35833990893/job/107092965761" + }, + { + "name": "nix: Install Nix", + "scope": "installation", + "status": "completed", + "conclusion": "success", + "url": "https://github.com/retroSoC/retroSoC/actions/runs/35833990893/job/107092965933" + }, + { + "name": "nix: Check Nix flake", + "scope": "environment-check", + "status": "completed", + "conclusion": "success", + "url": "https://github.com/retroSoC/retroSoC/actions/runs/35833990893/job/107092965933" + }, + { + "name": "nix: Run IHP130 regression in development environment", + "scope": "runtime-regression", + "status": "completed", + "conclusion": "success", + "url": "https://github.com/retroSoC/retroSoC/actions/runs/35833990893/job/107092965933" + } + ] } ] } diff --git a/publications/datasheets/waveforms.json b/publications/datasheets/waveforms.json index 369da095..781ca2fb 100644 --- a/publications/datasheets/waveforms.json +++ b/publications/datasheets/waveforms.json @@ -2505,54 +2505,54 @@ "skin": "lowkey" } }, - "note": "Scope: crypto_aes_engine. Clock: clk_i; AES processing intervals omitted. AES engine example with key expansion complete and valid parameters. The final output waits for output_ready_i; internal block processing and earlier words are omitted. SHA/RSA have separate engine sequencing.", + "note": "Scope: crypto_aes_sram_engine. Clock: clk_i; AES processing intervals omitted. AES engine example with key expansion complete and valid parameters. The final output waits for output_ready_i; internal block processing and earlier words are omitted. SHA/RSA have separate engine sequencing.", "clock_domain": "clk_i; AES processing intervals omitted", "signals": { "key_valid_o": { - "file": "rtl/ip/security/crypto_aes_engine.sv", - "scope": "crypto_aes_engine", + "file": "rtl/ip/security/crypto_aes_sram_engine.sv", + "scope": "crypto_aes_sram_engine", "symbol": "key_valid_o", "meaning": "A committed expanded key is valid before start.", "polarity": "active-high" }, "start_i": { - "file": "rtl/ip/security/crypto_aes_engine.sv", - "scope": "crypto_aes_engine", + "file": "rtl/ip/security/crypto_aes_sram_engine.sv", + "scope": "crypto_aes_sram_engine", "symbol": "start_i", "meaning": "Start a configured AES job.", "polarity": "active-high" }, "busy_o": { - "file": "rtl/ip/security/crypto_aes_engine.sv", - "scope": "crypto_aes_engine", + "file": "rtl/ip/security/crypto_aes_sram_engine.sv", + "scope": "crypto_aes_sram_engine", "symbol": "busy_o", "meaning": "AES engine active.", "polarity": "active-high" }, "output_valid_o": { - "file": "rtl/ip/security/crypto_aes_engine.sv", - "scope": "crypto_aes_engine", + "file": "rtl/ip/security/crypto_aes_sram_engine.sv", + "scope": "crypto_aes_sram_engine", "symbol": "output_valid_o", "meaning": "Final output word offered and retained until accepted.", "polarity": "active-high" }, "output_ready_i": { - "file": "rtl/ip/security/crypto_aes_engine.sv", - "scope": "crypto_aes_engine", + "file": "rtl/ip/security/crypto_aes_sram_engine.sv", + "scope": "crypto_aes_sram_engine", "symbol": "output_ready_i", "meaning": "Output consumer readiness.", "polarity": "active-high" }, "done_o": { - "file": "rtl/ip/security/crypto_aes_engine.sv", - "scope": "crypto_aes_engine", + "file": "rtl/ip/security/crypto_aes_sram_engine.sv", + "scope": "crypto_aes_sram_engine", "symbol": "done_o", "meaning": "Job completion after the final accepted output.", "polarity": "active-high" } }, "review_sources": [ - "rtl/ip/security/crypto_aes_engine.sv" + "rtl/ip/security/crypto_aes_sram_engine.sv" ], "review_note": "Replaced generic accelerator lanes with the AES engine ready/valid and completion contract; no cipher throughput claim." }, diff --git a/publications/environment_reference.py b/publications/environment_reference.py index 52cb62fb..834ead06 100644 --- a/publications/environment_reference.py +++ b/publications/environment_reference.py @@ -32,6 +32,6 @@ def development_environment(root: Path) -> dict: return { "platform": "Linux x86_64", "ubuntu": ubuntu[0], "python": ".".join(python[0]), "java": java_nix[0], - "sbt": lock["toolchains"]["ubuntu-22.04"]["sbt"]["version"], + "sbt_launcher": lock["toolchains"]["ubuntu-22.04"]["sbt"]["version"], "sources": list(ENVIRONMENT_SOURCES), } diff --git a/publications/software_reference.py b/publications/software_reference.py index 3f0e870c..ab8f03be 100644 --- a/publications/software_reference.py +++ b/publications/software_reference.py @@ -183,11 +183,20 @@ def linux_platform(root: Path) -> dict: writes = [(0x10019020, 1), (0x10019024, 0x4C4E5801), (0x10019028, 1), (0x1001902C, 1)] if "descriptor, 0x10019000)" not in ready: raise ValueError("Linux mailbox mapping changed") + registers = ("HP_EVENT", "HP_ARG0", "HP_SEQUENCE", "HP_DOORBELL") + purposes = ("Linux-ready event", "Ready-state argument", "Publication sequence", + "LP interrupt request") return {"hart_id": 1, "timebase_hz": timebase, "clock_hz": int(clocks[0]), "cbom_bytes": dt_value("riscv,cbom-block-size"), "memory_base": memory[0][0], "memory_bytes": int(memory[0][1], 0), "initrd_start": dt_value("linux,initrd-start"), "initrd_template_end": dt_value("linux,initrd-end"), "bootargs": bootargs[0], - "ready_writes": [{"address": f"0x{a:08X}", "value": f"0x{v:08X}"} for a, v in writes]} + "ready_writes": [ + {"address": f"0x{address:08X}", "value": f"0x{value:08X}", + "register": register, "purpose": purpose} + for (address, value), register, purpose in zip( + writes, registers, purposes, strict=True + ) + ]} def collect_software(root: Path, spec: dict) -> dict: diff --git a/rtl/ip/multimedia/apb4_apu.sv b/rtl/ip/multimedia/apb4_apu.sv index c5d71d40..ebb76b57 100644 --- a/rtl/ip/multimedia/apb4_apu.sv +++ b/rtl/ip/multimedia/apb4_apu.sv @@ -100,17 +100,17 @@ module apb4_apu #( logic [13:0] s_kws_coeff_front_index; logic s_kws_coeff_front_resp_valid, s_kws_coeff_front_resp_ready; logic [63:0] s_kws_coeff_front_resp_data; - logic s_kws_coeff_front_resp_fault; + logic s_kws_coeff_front_resp_fault; logic s_kws_coeff_infer_req, s_kws_coeff_infer_ready; logic [6:0] s_kws_coeff_infer_index; logic s_kws_coeff_infer_resp_valid, s_kws_coeff_infer_resp_ready; logic [31:0] s_kws_coeff_infer_resp_data; - logic s_kws_coeff_infer_resp_fault; + logic s_kws_coeff_infer_resp_fault; logic s_kws_coeff_profile_req, s_kws_coeff_profile_ready; logic [10:0] s_kws_coeff_profile_index; logic s_kws_coeff_profile_resp_valid, s_kws_coeff_profile_resp_ready; logic [31:0] s_kws_coeff_profile_resp_data; - logic s_kws_coeff_profile_resp_fault; + logic s_kws_coeff_profile_resp_fault; logic s_kws_engine_model_v_unused, s_kws_engine_model_lock_unused; logic [31:0] s_kws_engine_model_stat_unused, s_kws_engine_model_crc_unused; logic s_direct_start_allowed; @@ -840,146 +840,146 @@ module apb4_apu #( ); apu_kws_engine u_kws_engine ( - .clk_i(clk_i), - .rst_n_i(rst_n_i), - .soft_reset_i(s_soft_reset), - .resource_reset_i(s_resource_reset_apply_q), - .counter_clear_i(s_cnt_clear), - .xrun_clear_i(s_xrun_clear), - .abort_i(s_abort), - .quiesce_i(quiesce_i), - .disable_i(s_kws_disable_request), - .flush_busy_i(i2s_rx_flush_busy_i), - .enable_i(s_kws_control[0]), - .memory_window_i(s_kws_control[1]), - .clear_history_i(s_kws_clear_history), - .model_valid_i(s_kws_model_valid), - .model_lock_i(s_kws_model_lock), - .sequencer_timeout_i(s_sequencer_timeout), - .memory_start_i(s_kws_memory_start), - .memory_start_ready_o(s_kws_mem_start_ready), - .memory_address_i(s_codec_descriptor[(2*32)+:32]), - .memory_dma_request_valid_o(s_kws_mem_dma_req), - .memory_dma_request_ready_i(s_kws_mem_dma_rdy), + .clk_i (clk_i), + .rst_n_i (rst_n_i), + .soft_reset_i (s_soft_reset), + .resource_reset_i (s_resource_reset_apply_q), + .counter_clear_i (s_cnt_clear), + .xrun_clear_i (s_xrun_clear), + .abort_i (s_abort), + .quiesce_i (quiesce_i), + .disable_i (s_kws_disable_request), + .flush_busy_i (i2s_rx_flush_busy_i), + .enable_i (s_kws_control[0]), + .memory_window_i (s_kws_control[1]), + .clear_history_i (s_kws_clear_history), + .model_valid_i (s_kws_model_valid), + .model_lock_i (s_kws_model_lock), + .sequencer_timeout_i (s_sequencer_timeout), + .memory_start_i (s_kws_memory_start), + .memory_start_ready_o (s_kws_mem_start_ready), + .memory_address_i (s_codec_descriptor[(2*32)+:32]), + .memory_dma_request_valid_o (s_kws_mem_dma_req), + .memory_dma_request_ready_i (s_kws_mem_dma_rdy), .memory_dma_request_address_o(s_kws_mem_dma_addr), - .memory_dma_request_bytes_o(s_kws_mem_dma_bytes), - .memory_dma_data_i(u_dma_read_axis.tdata), - .memory_dma_keep_i(u_dma_read_axis.tkeep), - .memory_dma_last_i(u_dma_read_axis.tlast), - .memory_dma_valid_i(s_kws_mem_data_v), - .memory_dma_ready_o(s_kws_mem_dma_data_rdy), - .memory_dma_done_i(s_kws_mem_dma_done), - .memory_dma_error_i(s_kws_mem_dma_error), - .memory_dma_error_code_i(s_dma_err_code), - .memory_dma_error_stage_i(s_dma_err_stage), - .memory_dma_error_resp_i(s_dma_err_resp), - .memory_dma_error_address_i(s_dma_err_addr), - .memory_done_o(s_kws_mem_done), - .memory_error_o(s_kws_mem_err), - .memory_error_code_o(s_kws_mem_err_code), - .memory_error_stage_o(s_kws_mem_err_stage), - .memory_error_resp_o(s_kws_mem_err_resp), - .memory_error_address_o(s_kws_mem_err_addr), - .memory_error_detail_o(s_kws_mem_err_detail), - .memory_input_used_o(s_kws_mem_input_used), - .kws_config_i(s_codec_kws_config_valid ? s_codec_kws_config : s_kws_config), - .input_config_i(s_kws_input_config), - .storage_req_o(s_kws_storage_req), - .storage_ready_i(s_kws_storage_ready), - .storage_done_i(s_kws_storage_done), - .storage_progress_i(s_kws_storage_progress), - .storage_write_o(s_kws_storage_write), - .model_read_valid_o(s_kws_model_read_valid), - .model_addr_o(s_kws_model_read_addr), - .model_data_i(s_kws_model_read_data), - .scratch_clear_o(s_kws_scratch_clear), - .scratch_read_valid_o(s_kws_scratch_read_valid), - .scratch_read_addr_o(s_kws_scratch_read_addr), - .scratch_read_data_i(s_kws_scratch_read_data), - .scratch_write_valid_o(s_kws_scratch_write_valid), - .scratch_write_addr_o(s_kws_scratch_write_addr), - .scratch_write_data_o(s_kws_scratch_write_data), - .scratch_write_strb_o(s_kws_scratch_write_strb), - .scratch_access_err_i(s_kws_scratch_err), - .coeff_frontend_req_valid_o(s_kws_coeff_front_req), - .coeff_frontend_req_ready_i(s_kws_coeff_front_ready), - .coeff_frontend_kind_o(s_kws_coeff_front_kind), - .coeff_frontend_index_o(s_kws_coeff_front_index), - .coeff_frontend_resp_valid_i(s_kws_coeff_front_resp_valid), - .coeff_frontend_resp_ready_o(s_kws_coeff_front_resp_ready), - .coeff_frontend_data_i(s_kws_coeff_front_resp_data), - .coeff_frontend_fault_i(s_kws_coeff_front_resp_fault), - .coeff_inference_req_valid_o(s_kws_coeff_infer_req), - .coeff_inference_req_ready_i(s_kws_coeff_infer_ready), - .coeff_inference_index_o(s_kws_coeff_infer_index), + .memory_dma_request_bytes_o (s_kws_mem_dma_bytes), + .memory_dma_data_i (u_dma_read_axis.tdata), + .memory_dma_keep_i (u_dma_read_axis.tkeep), + .memory_dma_last_i (u_dma_read_axis.tlast), + .memory_dma_valid_i (s_kws_mem_data_v), + .memory_dma_ready_o (s_kws_mem_dma_data_rdy), + .memory_dma_done_i (s_kws_mem_dma_done), + .memory_dma_error_i (s_kws_mem_dma_error), + .memory_dma_error_code_i (s_dma_err_code), + .memory_dma_error_stage_i (s_dma_err_stage), + .memory_dma_error_resp_i (s_dma_err_resp), + .memory_dma_error_address_i (s_dma_err_addr), + .memory_done_o (s_kws_mem_done), + .memory_error_o (s_kws_mem_err), + .memory_error_code_o (s_kws_mem_err_code), + .memory_error_stage_o (s_kws_mem_err_stage), + .memory_error_resp_o (s_kws_mem_err_resp), + .memory_error_address_o (s_kws_mem_err_addr), + .memory_error_detail_o (s_kws_mem_err_detail), + .memory_input_used_o (s_kws_mem_input_used), + .kws_config_i (s_codec_kws_config_valid ? s_codec_kws_config : s_kws_config), + .input_config_i (s_kws_input_config), + .storage_req_o (s_kws_storage_req), + .storage_ready_i (s_kws_storage_ready), + .storage_done_i (s_kws_storage_done), + .storage_progress_i (s_kws_storage_progress), + .storage_write_o (s_kws_storage_write), + .model_read_valid_o (s_kws_model_read_valid), + .model_addr_o (s_kws_model_read_addr), + .model_data_i (s_kws_model_read_data), + .scratch_clear_o (s_kws_scratch_clear), + .scratch_read_valid_o (s_kws_scratch_read_valid), + .scratch_read_addr_o (s_kws_scratch_read_addr), + .scratch_read_data_i (s_kws_scratch_read_data), + .scratch_write_valid_o (s_kws_scratch_write_valid), + .scratch_write_addr_o (s_kws_scratch_write_addr), + .scratch_write_data_o (s_kws_scratch_write_data), + .scratch_write_strb_o (s_kws_scratch_write_strb), + .scratch_access_err_i (s_kws_scratch_err), + .coeff_frontend_req_valid_o (s_kws_coeff_front_req), + .coeff_frontend_req_ready_i (s_kws_coeff_front_ready), + .coeff_frontend_kind_o (s_kws_coeff_front_kind), + .coeff_frontend_index_o (s_kws_coeff_front_index), + .coeff_frontend_resp_valid_i (s_kws_coeff_front_resp_valid), + .coeff_frontend_resp_ready_o (s_kws_coeff_front_resp_ready), + .coeff_frontend_data_i (s_kws_coeff_front_resp_data), + .coeff_frontend_fault_i (s_kws_coeff_front_resp_fault), + .coeff_inference_req_valid_o (s_kws_coeff_infer_req), + .coeff_inference_req_ready_i (s_kws_coeff_infer_ready), + .coeff_inference_index_o (s_kws_coeff_infer_index), .coeff_inference_resp_valid_i(s_kws_coeff_infer_resp_valid), .coeff_inference_resp_ready_o(s_kws_coeff_infer_resp_ready), - .coeff_inference_data_i(s_kws_coeff_infer_resp_data), - .coeff_inference_fault_i(s_kws_coeff_infer_resp_fault), - .stream_i(u_apu_rx_axis), - .rx_ready_o(s_kws_rx_ready), - .status_o(s_kws_status), - .result_o(s_kws_result), - .timestamp_lo_o(s_kws_timestamp_lo), - .timestamp_hi_o(s_kws_timestamp_hi), - .frame_count_o(s_kws_frame_count), - .inference_count_o(s_kws_inference_count), - .hit_count_o(s_kws_hit_count), - .overrun_count_o(s_kws_overrun_count), - .model_status_o(s_kws_engine_model_stat_unused), - .model_actual_crc_o(s_kws_engine_model_crc_unused), - .irq_set_o(s_kws_irq_set), - .fault_valid_o(s_kws_fault_valid), - .fault_code_o(s_kws_fault_code), - .fault_stage_o(s_kws_fault_stage), - .fault_resp_o(s_kws_fault_resp), - .fault_index_o(s_kws_fault_index), - .fault_addr_o(s_kws_fault_addr), - .fault_detail_o(s_kws_fault_detail), - .model_valid_o(s_kws_engine_model_v_unused), - .model_lock_o(s_kws_engine_model_lock_unused), - .busy_o(s_kws_busy), - .idle_o(s_kws_idle) + .coeff_inference_data_i (s_kws_coeff_infer_resp_data), + .coeff_inference_fault_i (s_kws_coeff_infer_resp_fault), + .stream_i (u_apu_rx_axis), + .rx_ready_o (s_kws_rx_ready), + .status_o (s_kws_status), + .result_o (s_kws_result), + .timestamp_lo_o (s_kws_timestamp_lo), + .timestamp_hi_o (s_kws_timestamp_hi), + .frame_count_o (s_kws_frame_count), + .inference_count_o (s_kws_inference_count), + .hit_count_o (s_kws_hit_count), + .overrun_count_o (s_kws_overrun_count), + .model_status_o (s_kws_engine_model_stat_unused), + .model_actual_crc_o (s_kws_engine_model_crc_unused), + .irq_set_o (s_kws_irq_set), + .fault_valid_o (s_kws_fault_valid), + .fault_code_o (s_kws_fault_code), + .fault_stage_o (s_kws_fault_stage), + .fault_resp_o (s_kws_fault_resp), + .fault_index_o (s_kws_fault_index), + .fault_addr_o (s_kws_fault_addr), + .fault_detail_o (s_kws_fault_detail), + .model_valid_o (s_kws_engine_model_v_unused), + .model_lock_o (s_kws_engine_model_lock_unused), + .busy_o (s_kws_busy), + .idle_o (s_kws_idle) ); apu_dma u_apu_dma ( - .clk_i(clk_i), - .rst_n_i(rst_n_i), - .abort_i(s_dma_abort), - .quiesce_i(s_dma_quiesce), - .bridge_epoch_i(bridge_epoch_i), - .perf_enable_i(s_perf_enable), - .counter_clear_i(s_cnt_clear), - .request_valid_i(s_dma_req_valid), - .request_ready_o(s_dma_req_ready), - .request_write_i(s_dma_req_write), - .request_addr_i(s_dma_req_addr), - .request_bytes_i(s_dma_req_bytes), - .read_base_i(s_read_base), - .read_limit_i(s_read_limit), - .write_base_i(s_write_base), - .write_limit_i(s_write_limit), - .timeout_i(s_dma_timeout), - .read_axis(u_dma_read_axis), - .write_axis(u_dma_write_axis), - .busy_o(s_dma_busy), - .done_o(s_dma_done), - .error_o(s_dma_err), - .aborted_o(s_dma_aborted), - .aborting_o(s_dma_aborting), - .error_code_o(s_dma_err_code), - .error_stage_o(s_dma_err_stage), - .error_resp_o(s_dma_err_resp), - .error_addr_o(s_dma_err_addr), - .input_pending_o(s_dma_input_pending), - .output_pending_o(s_dma_output_pending), - .read_bytes_o(s_dma_read_bytes), - .write_bytes_o(s_dma_write_bytes), - .write_burst_done_o(s_dma_write_burst_done), + .clk_i (clk_i), + .rst_n_i (rst_n_i), + .abort_i (s_dma_abort), + .quiesce_i (s_dma_quiesce), + .bridge_epoch_i (bridge_epoch_i), + .perf_enable_i (s_perf_enable), + .counter_clear_i (s_cnt_clear), + .request_valid_i (s_dma_req_valid), + .request_ready_o (s_dma_req_ready), + .request_write_i (s_dma_req_write), + .request_addr_i (s_dma_req_addr), + .request_bytes_i (s_dma_req_bytes), + .read_base_i (s_read_base), + .read_limit_i (s_read_limit), + .write_base_i (s_write_base), + .write_limit_i (s_write_limit), + .timeout_i (s_dma_timeout), + .read_axis (u_dma_read_axis), + .write_axis (u_dma_write_axis), + .busy_o (s_dma_busy), + .done_o (s_dma_done), + .error_o (s_dma_err), + .aborted_o (s_dma_aborted), + .aborting_o (s_dma_aborting), + .error_code_o (s_dma_err_code), + .error_stage_o (s_dma_err_stage), + .error_resp_o (s_dma_err_resp), + .error_addr_o (s_dma_err_addr), + .input_pending_o (s_dma_input_pending), + .output_pending_o (s_dma_output_pending), + .read_bytes_o (s_dma_read_bytes), + .write_bytes_o (s_dma_write_bytes), + .write_burst_done_o (s_dma_write_burst_done), .write_burst_bytes_o(s_dma_write_burst_bytes), - .read_stalls_o(s_dma_read_stalls), - .write_stalls_o(s_dma_write_stalls), - .axi4(axi4) + .read_stalls_o (s_dma_read_stalls), + .write_stalls_o (s_dma_write_stalls), + .axi4 (axi4) ); apu_microcode_loader #( diff --git a/rtl/ip/multimedia/apu_kws_coeff_loader.sv b/rtl/ip/multimedia/apu_kws_coeff_loader.sv index 9c801246..01915f21 100644 --- a/rtl/ip/multimedia/apu_kws_coeff_loader.sv +++ b/rtl/ip/multimedia/apu_kws_coeff_loader.sv @@ -78,8 +78,8 @@ module apu_kws_coeff_loader ( CancelWait } loader_state_e; - loader_state_e s_state_q; - logic [15:0][31:0] s_header_q; + loader_state_e s_state_q; + logic [15:0][31:0] s_header_q; logic [31:0] s_addr_q, s_size_q, s_expected_crc_q, s_acl_base_q, s_acl_limit_q; logic [31:0] s_received_q; logic [31:0] s_crc_q, s_readback_crc_q; @@ -129,10 +129,10 @@ module apu_kws_coeff_loader ( s_bank = word_i[13:10]; s_row = word_i[9:0]; unique case (s_bank) - 4'd0: payload_word_is_padding = s_row >= 10'd1006; - 4'd1: payload_word_is_padding = s_row >= 10'd769; - 4'd2: payload_word_is_padding = s_row >= 10'd768; - 4'd14: payload_word_is_padding = s_row >= 10'd637; + 4'd0: payload_word_is_padding = s_row >= 10'd1006; + 4'd1: payload_word_is_padding = s_row >= 10'd769; + 4'd2: payload_word_is_padding = s_row >= 10'd768; + 4'd14: payload_word_is_padding = s_row >= 10'd637; default: payload_word_is_padding = 1'b0; endcase end @@ -152,7 +152,7 @@ module apu_kws_coeff_loader ( always_comb begin s_header_size_err = 1'b0; - s_header_err = 1'b0; + s_header_err = 1'b0; s_header_err_addr = s_addr_q; if (s_header_q[2] != ImageBytes) begin s_header_size_err = 1'b1; diff --git a/rtl/ip/multimedia/apu_kws_coeff_store.sv b/rtl/ip/multimedia/apu_kws_coeff_store.sv index eed4c39d..ac29fe2f 100644 --- a/rtl/ip/multimedia/apu_kws_coeff_store.sv +++ b/rtl/ip/multimedia/apu_kws_coeff_store.sv @@ -303,8 +303,8 @@ module apu_kws_coeff_store ( end if (s_loader_accept) begin - s_loader_fault_q <= loader_addr_i >= 14'd15360; - s_loader_bank_q <= loader_addr_i[13:10]; + s_loader_fault_q <= loader_addr_i >= 14'd15360; + s_loader_bank_q <= loader_addr_i[13:10]; s_loader_pending_q <= !loader_write_i; end else begin s_loader_pending_q <= 1'b0; diff --git a/rtl/ip/multimedia/apu_kws_engine.sv b/rtl/ip/multimedia/apu_kws_engine.sv index 10b55715..20089ede 100644 --- a/rtl/ip/multimedia/apu_kws_engine.sv +++ b/rtl/ip/multimedia/apu_kws_engine.sv @@ -483,8 +483,8 @@ module apu_kws_engine ( log_lookup_t s_lookup; logic [95:0] fraction_scaled, fraction_quotient, fraction_remainder; begin - numerator = 96'd1000000 * mel_i + 96'd16 * peak_i; - denominator = 96'd16000000 * peak_i; + numerator = 96'd1000000 * mel_i + 96'd16 * peak_i; + denominator = 96'd16000000 * peak_i; s_lookup.exponent = 0; if (numerator >= denominator) begin normalized_denominator = denominator; @@ -498,7 +498,7 @@ module apu_kws_engine ( normalized_denominator = denominator; for (int iteration = 0; iteration < 95; iteration++) begin if (numerator < normalized_denominator) begin - numerator = numerator << 1; + numerator = numerator << 1; s_lookup.exponent = s_lookup.exponent - 1'b1; end end @@ -1049,13 +1049,13 @@ module apu_kws_engine ( end endcase - s_infer_coeff_needed = 1'b0; + s_infer_coeff_needed = 1'b0; coeff_inference_index_o = 7'd0; if (s_infer_state_q == InferSoftmaxSum) begin - s_infer_coeff_needed = !s_coeff_operand_ready || (s_softmax_sum_diff >= -9'sd124); + s_infer_coeff_needed = !s_coeff_operand_ready || (s_softmax_sum_diff >= -9'sd124); coeff_inference_index_o = 7'(-s_softmax_sum_diff); end else if ((s_infer_state_q == InferSoftmaxScale) && (s_softmax_index_q != 4'd0)) begin - s_infer_coeff_needed = !s_coeff_operand_ready || (s_softmax_scale_diff >= -9'sd124); + s_infer_coeff_needed = !s_coeff_operand_ready || (s_softmax_scale_diff >= -9'sd124); coeff_inference_index_o = 7'(-s_softmax_scale_diff); end end diff --git a/rtl/ip/multimedia/apu_proof_memo.sv b/rtl/ip/multimedia/apu_proof_memo.sv index 16bc35a1..db0221a6 100644 --- a/rtl/ip/multimedia/apu_proof_memo.sv +++ b/rtl/ip/multimedia/apu_proof_memo.sv @@ -71,10 +71,10 @@ module apu_proof_memo #( s_bitmap_cs = 1'b1; s_bitmap_addr = {2'd0, addr_i[12:5]}; end else if ((s_state_q == Idle) && insert_i) begin - s_key_cs[addr_i[12:10]] = 1'b1; + s_key_cs[addr_i[12:10]] = 1'b1; s_key_wren[addr_i[12:10]] = 1'b1; - s_bitmap_cs = 1'b1; - s_bitmap_addr = {2'd0, addr_i[12:5]}; + s_bitmap_cs = 1'b1; + s_bitmap_addr = {2'd0, addr_i[12:5]}; end else if (s_state_q == InsertBitmapWrite) begin s_bitmap_cs = 1'b1; s_bitmap_wren = 1'b1; @@ -119,8 +119,8 @@ module apu_proof_memo #( .data_o(s_bitmap_rdata) ); `else - logic [63:0] s_key_mem [0:Depth-1]; - logic [31:0] s_bitmap_mem[0:BitmapRows-1]; + logic [63:0] s_key_mem [ 0:Depth-1]; + logic [31:0] s_bitmap_mem [0:BitmapRows-1]; logic [12:0] s_key_access_addr; logic [63:0] s_key_access_data; diff --git a/rtl/ip/multimedia/npu_core.sv b/rtl/ip/multimedia/npu_core.sv index a0edcc71..4f68a5f8 100644 --- a/rtl/ip/multimedia/npu_core.sv +++ b/rtl/ip/multimedia/npu_core.sv @@ -131,26 +131,26 @@ module npu_core #( logic s_epoch_restart; logic s_unused; - assign launch_ready_o = 1'b1; - assign result_valid_o = 1'b0; - assign result_data_o = '0; - assign busy_o = 1'b0; - assign draining_o = 1'b0; - assign flush_busy_o = 1'b0; - assign snapshot_resp_data_o = '0; + assign launch_ready_o = 1'b1; + assign result_valid_o = 1'b0; + assign result_data_o = '0; + assign busy_o = 1'b0; + assign draining_o = 1'b0; + assign flush_busy_o = 1'b0; + assign snapshot_resp_data_o = '0; // With zero accepted AXI obligations and no internal work, the // clock-pause acknowledge is immediate and the HP idle contribution // follows the platform formula !block_new_i || clock_pause_ack_o. - assign clock_pause_ack_o = block_new_i; - assign pause_active_o = block_new_i && clock_pause_ack_o; - assign idle_o = !block_new_i || clock_pause_ack_o; + assign clock_pause_ack_o = block_new_i; + assign pause_active_o = block_new_i && clock_pause_ack_o; + assign idle_o = !block_new_i || clock_pause_ack_o; - assign epoch_ack_o = s_epoch_ack_q; - assign quiesce_ack_o = s_quiesce_ack_q; + assign epoch_ack_o = s_epoch_ack_q; + assign quiesce_ack_o = s_quiesce_ack_q; - assign s_epoch_restart = (epoch_req_i != s_epoch_ack_q); - assign s_unused = ^{launch_data_i, result_ready_i, flush_i, 1'b0}; + assign s_epoch_restart = (epoch_req_i != s_epoch_ack_q); + assign s_unused = ^{launch_data_i, result_ready_i, flush_i, 1'b0}; assign dma_clear_o = 1'b0; assign dma_read_req_valid_o = 1'b0; @@ -259,7 +259,7 @@ module npu_core #( snap_state_e s_snap_state_d, s_snap_state_q; logic [EpochWidth-1:0] s_epoch_ack_d, s_epoch_ack_q; logic s_quiesce_ack_d, s_quiesce_ack_q; - logic s_epoch_restart; + logic s_epoch_restart; // job context logic [31:0] s_job_base_q; logic [31:0] s_job_id_q; @@ -267,26 +267,26 @@ module npu_core #( logic [15:0] s_job_count_q; logic [31:0] s_term_job_id_q; // first-fault record - logic s_fault_seen_d, s_fault_seen_q; - logic [ 3:0] s_fault_code_d, s_fault_code_q; + logic s_fault_seen_d, s_fault_seen_q; + logic [3:0] s_fault_code_d, s_fault_code_q; logic [31:0] s_fault_addr_d, s_fault_addr_q; logic [31:0] s_fault_info_d, s_fault_info_q; logic [31:0] s_fault_desc_d, s_fault_desc_q; // terminal record - logic [ 2:0] s_res_code_d, s_res_code_q; - logic [ 2:0] s_res_irq_d, s_res_irq_q; + logic [2:0] s_res_code_d, s_res_code_q; + logic [2:0] s_res_irq_d, s_res_irq_q; logic [31:0] s_res_completed_d, s_res_completed_q; // snapshot capture logic [SnapshotPayloadWidth-1:0] s_snap_payload_d, s_snap_payload_q; - logic s_launch_accept; - logic s_job_busy; - logic s_dec_busy; - logic s_sch_busy; - logic s_sch_drained; - logic s_drained; - logic s_compose_terminal; - logic s_stop; - logic s_clear; + logic s_launch_accept; + logic s_job_busy; + logic s_dec_busy; + logic s_sch_busy; + logic s_sch_drained; + logic s_drained; + logic s_compose_terminal; + logic s_stop; + logic s_clear; // decoder wires logic s_dec_job_start; logic s_dec_read_req_valid; @@ -314,51 +314,52 @@ module npu_core #( logic [31:0] s_rec_input0_base, s_rec_output_base; logic [31:0] s_rec_weight_base, s_rec_param_base; logic [31:0] s_rec_irow, s_rec_orow; - logic [ 7:0] s_rec_kh, s_rec_kw, s_rec_sh, s_rec_sw; - logic [ 7:0] s_rec_pad_top, s_rec_pad_left, s_rec_in0_zero; - logic [ 7:0] s_rec_tile_h, s_rec_tile_w; + logic [7:0] s_rec_kh, s_rec_kw, s_rec_sh, s_rec_sw; + logic [7:0] s_rec_pad_top, s_rec_pad_left, s_rec_in0_zero; + logic [7:0] s_rec_tile_h, s_rec_tile_w; logic [15:0] s_rec_k_slice; logic [31:0] s_rec_input1_base, s_rec_input1_row_bytes; - logic [ 7:0] s_rec_in1_zero, s_rec_out_zero, s_rec_act_min, s_rec_act_max; + logic [7:0] s_rec_in1_zero, s_rec_out_zero, s_rec_act_min, s_rec_act_max; logic [31:0] s_rec_weight_bytes, s_rec_param_bytes; - logic [15:0] s_rec_desc_index; + logic [ 15:0] s_rec_desc_index; // scheduler wires - logic s_sch_launch; - logic s_sch_retired; - logic [31:0] s_sch_completed; - logic s_sch_read_req_valid; - logic s_sch_read_req_ready; - logic [31:0] s_sch_read_addr; - logic [31:0] s_sch_read_bytes; - logic s_sch_read_data_valid; - logic s_sch_read_data_ready; - logic s_sch_write_req_valid; - logic [31:0] s_sch_write_addr; - logic [31:0] s_sch_write_bytes; - logic s_sch_write_data_valid; - logic [63:0] s_sch_write_data; - logic [ 7:0] s_sch_write_keep; - logic s_sch_write_last; - logic s_sch_pause_ok; - logic s_sch_terminal; + logic s_sch_launch; + logic s_sch_retired; + logic [ 31:0] s_sch_completed; + logic s_sch_read_req_valid; + logic s_sch_read_req_ready; + logic [ 31:0] s_sch_read_addr; + logic [ 31:0] s_sch_read_bytes; + logic s_sch_read_data_valid; + logic s_sch_read_data_ready; + logic s_sch_write_req_valid; + logic [ 31:0] s_sch_write_addr; + logic [ 31:0] s_sch_write_bytes; + logic s_sch_write_data_valid; + logic [ 63:0] s_sch_write_data; + logic [ 7:0] s_sch_write_keep; + logic s_sch_write_last; + logic s_sch_pause_ok; + logic s_sch_terminal; logic [639:0] s_sch_counters; logic [639:0] s_sch_term_counters; - logic s_sch_fault_req; - logic [ 3:0] s_sch_fault_code; - logic [31:0] s_sch_fault_addr; - logic [31:0] s_sch_fault_info; - logic [31:0] s_sch_fault_desc; + logic s_sch_fault_req; + logic [ 3:0] s_sch_fault_code; + logic [ 31:0] s_sch_fault_addr; + logic [ 31:0] s_sch_fault_info; + logic [ 31:0] s_sch_fault_desc; // fault arbitration - logic s_evt_dec; - logic s_evt_sch; - logic s_evt_cmd_err; - logic [ 3:0] s_evt_code; - logic [31:0] s_evt_addr; - logic [31:0] s_evt_info; - logic [31:0] s_evt_desc; - logic s_evt_any; + logic s_evt_dec; + logic s_evt_sch; + logic s_evt_cmd_err; + logic [ 3:0] s_evt_code; + logic [ 31:0] s_evt_addr; + logic [ 31:0] s_evt_info; + logic [ 31:0] s_evt_desc; + logic s_evt_any; // Deterministic same-cycle first-fault priority: lower rank wins. + // verilog_format: off -- preserve macro case labels that Verible misclassifies as item tokens function automatic logic [3:0] fault_rank(input logic [3:0] code_i); logic [3:0] rank; begin @@ -377,6 +378,7 @@ module npu_core #( return rank; end endfunction + // verilog_format: on assign s_evt_dec = s_dec_fault_req; assign s_evt_sch = s_sch_fault_req; @@ -396,8 +398,11 @@ module npu_core #( s_evt_info = s_dec_fault_info; s_evt_desc = s_dec_fault_desc; end - if (s_evt_sch && (!s_evt_dec || - (fault_rank(s_sch_fault_code) <= fault_rank(s_dec_fault_code)))) begin + if (s_evt_sch && (!s_evt_dec || (fault_rank( + s_sch_fault_code + ) <= fault_rank( + s_dec_fault_code + )))) begin s_evt_code = s_sch_fault_code; s_evt_addr = s_sch_fault_addr; s_evt_info = s_sch_fault_info; @@ -405,6 +410,7 @@ module npu_core #( // phase) belongs to the descriptor the decoder holds. s_evt_desc = s_dec_busy ? {16'd0, s_dec_cur_index} : s_sch_fault_desc; end + // verilog_format: off -- preserve macro argument tokens that Verible misclassifies if (s_evt_cmd_err && (!s_evt_dec && !s_evt_sch || (fault_rank(`APB4_NPU__FAULT_CODE_LOCAL_STATE) <= fault_rank(s_evt_code)))) begin @@ -413,6 +419,7 @@ module npu_core #( s_evt_info = {16'd0, 8'd255, 4'd0, 2'd0, 2'd0}; s_evt_desc = s_dec_busy ? {16'd0, s_dec_cur_index} : s_sch_fault_desc; end + // verilog_format: on end assign s_job_busy = (s_state_q != CoreIdle); @@ -439,8 +446,7 @@ module npu_core #( (s_state_q == CoreDrainReset); assign flush_busy_o = 1'b0; assign idle_o = !block_new_i || clock_pause_ack_o; - assign clock_pause_ack_o = block_new_i && dma_pause_ack_i && s_dec_pause_ok && - s_sch_pause_ok; + assign clock_pause_ack_o = block_new_i && dma_pause_ack_i && s_dec_pause_ok && s_sch_pause_ok; assign pause_active_o = block_new_i && clock_pause_ack_o; assign epoch_ack_o = s_epoch_ack_q; assign quiesce_ack_o = s_quiesce_ack_q; @@ -475,20 +481,20 @@ module npu_core #( // Core FSM // ------------------------------------------------------------- always_comb begin - s_state_d = s_state_q; - s_epoch_ack_d = s_epoch_ack_q; - s_quiesce_ack_d = s_quiesce_ack_q; - s_snap_state_d = s_snap_state_q; - s_snap_payload_d = s_snap_payload_q; - s_fault_seen_d = s_fault_seen_q; - s_fault_code_d = s_fault_code_q; - s_fault_addr_d = s_fault_addr_q; - s_fault_info_d = s_fault_info_q; - s_fault_desc_d = s_fault_desc_q; - s_res_code_d = s_res_code_q; - s_res_irq_d = s_res_irq_q; - s_res_completed_d = s_res_completed_q; - snapshot_req_ready_o = 1'b0; + s_state_d = s_state_q; + s_epoch_ack_d = s_epoch_ack_q; + s_quiesce_ack_d = s_quiesce_ack_q; + s_snap_state_d = s_snap_state_q; + s_snap_payload_d = s_snap_payload_q; + s_fault_seen_d = s_fault_seen_q; + s_fault_code_d = s_fault_code_q; + s_fault_addr_d = s_fault_addr_q; + s_fault_info_d = s_fault_info_q; + s_fault_desc_d = s_fault_desc_q; + s_res_code_d = s_res_code_q; + s_res_irq_d = s_res_irq_q; + s_res_completed_d = s_res_completed_q; + snapshot_req_ready_o = 1'b0; snapshot_resp_valid_o = 1'b0; // snapshot endpoint: atomic capture of the live or retained bank @@ -532,14 +538,14 @@ module npu_core #( if (s_evt_any && !s_fault_seen_q) begin s_state_d = CoreDrainFault; end else if (s_all_done_q) begin - s_res_code_d = 3'(`APB4_NPU__RESULT_CODE_DONE); - s_res_irq_d = 3'b001; + s_res_code_d = 3'(`APB4_NPU__RESULT_CODE_DONE); + s_res_irq_d = 3'b001; s_res_completed_d = {16'd0, s_job_count_q}; - s_fault_code_d = 4'(`APB4_NPU__FAULT_CODE_NONE); - s_fault_desc_d = 32'hffff_ffff; - s_fault_addr_d = 32'd0; - s_fault_info_d = 32'd0; - s_state_d = CorePublish; + s_fault_code_d = 4'(`APB4_NPU__FAULT_CODE_NONE); + s_fault_desc_d = 32'hffff_ffff; + s_fault_addr_d = 32'd0; + s_fault_info_d = 32'd0; + s_state_d = CorePublish; end else if (abort_i) begin s_state_d = CoreDrainAbort; end else if (quiesce_req_i) begin @@ -550,17 +556,17 @@ module npu_core #( if (s_drained) begin if (s_fault_seen_q) begin s_res_code_d = 3'(`APB4_NPU__RESULT_CODE_ERROR); - s_res_irq_d = 3'b010; + s_res_irq_d = 3'b010; end else begin - s_res_code_d = 3'(`APB4_NPU__RESULT_CODE_ABORTED); - s_res_irq_d = 3'b100; + s_res_code_d = 3'(`APB4_NPU__RESULT_CODE_ABORTED); + s_res_irq_d = 3'b100; s_fault_code_d = 4'(`APB4_NPU__FAULT_CODE_NONE); s_fault_desc_d = 32'hffff_ffff; s_fault_addr_d = 32'd0; s_fault_info_d = 32'd0; end s_res_completed_d = s_sch_completed; - s_state_d = CorePublish; + s_state_d = CorePublish; end end CoreDrainReset: begin @@ -570,17 +576,17 @@ module npu_core #( s_epoch_ack_d = epoch_req_i; if (s_fault_seen_q) begin s_res_code_d = 3'(`APB4_NPU__RESULT_CODE_ERROR); - s_res_irq_d = 3'b010; + s_res_irq_d = 3'b010; end else begin - s_res_code_d = 3'(`APB4_NPU__RESULT_CODE_RESET_CANCELLED); - s_res_irq_d = 3'b010; + s_res_code_d = 3'(`APB4_NPU__RESULT_CODE_RESET_CANCELLED); + s_res_irq_d = 3'b010; s_fault_code_d = 4'(`APB4_NPU__FAULT_CODE_RESET_CANCELLED); s_fault_desc_d = 32'hffff_ffff; s_fault_addr_d = 32'd0; s_fault_info_d = 32'd0; end s_res_completed_d = s_sch_completed; - s_state_d = CorePublish; + s_state_d = CorePublish; end end CorePublish: begin @@ -618,46 +624,54 @@ module npu_core #( end assign result_valid_o = (s_state_q == CorePublish); - assign result_data_o = {s_res_irq_q, s_fault_code_q, s_res_code_q, s_fault_info_q, - s_fault_addr_q, s_fault_desc_q, s_res_completed_q, s_job_id_q}; + assign result_data_o = { + s_res_irq_q, + s_fault_code_q, + s_res_code_q, + s_fault_info_q, + s_fault_addr_q, + s_fault_desc_q, + s_res_completed_q, + s_job_id_q + }; assign snapshot_resp_data_o = s_snap_payload_q; always_ff @(posedge clk_hp_i or negedge rst_hp_n_i) begin if (!rst_hp_n_i) begin - s_state_q <= CoreIdle; - s_snap_state_q <= SnapIdle; - s_job_base_q <= '0; - s_job_id_q <= '0; - s_timeout_q <= '0; - s_job_count_q <= '0; - s_term_job_id_q <= '0; - s_fault_seen_q <= 1'b0; - s_fault_code_q <= '0; - s_fault_addr_q <= '0; - s_fault_info_q <= '0; - s_fault_desc_q <= `APB4_NPU__FAULT_DESCRIPTOR_RESET; - s_res_code_q <= '0; - s_res_irq_q <= '0; + s_state_q <= CoreIdle; + s_snap_state_q <= SnapIdle; + s_job_base_q <= '0; + s_job_id_q <= '0; + s_timeout_q <= '0; + s_job_count_q <= '0; + s_term_job_id_q <= '0; + s_fault_seen_q <= 1'b0; + s_fault_code_q <= '0; + s_fault_addr_q <= '0; + s_fault_info_q <= '0; + s_fault_desc_q <= `APB4_NPU__FAULT_DESCRIPTOR_RESET; + s_res_code_q <= '0; + s_res_irq_q <= '0; s_res_completed_q <= '0; - s_snap_payload_q <= '0; - s_all_done_q <= 1'b0; + s_snap_payload_q <= '0; + s_all_done_q <= 1'b0; end else begin - s_state_q <= s_state_d; - s_snap_state_q <= s_snap_state_d; - s_snap_payload_q <= s_snap_payload_d; - s_fault_seen_q <= s_fault_seen_d; - s_fault_code_q <= s_fault_code_d; - s_fault_addr_q <= s_fault_addr_d; - s_fault_info_q <= s_fault_info_d; - s_fault_desc_q <= s_fault_desc_d; - s_res_code_q <= s_res_code_d; - s_res_irq_q <= s_res_irq_d; + s_state_q <= s_state_d; + s_snap_state_q <= s_snap_state_d; + s_snap_payload_q <= s_snap_payload_d; + s_fault_seen_q <= s_fault_seen_d; + s_fault_code_q <= s_fault_code_d; + s_fault_addr_q <= s_fault_addr_d; + s_fault_info_q <= s_fault_info_d; + s_fault_desc_q <= s_fault_desc_d; + s_res_code_q <= s_res_code_d; + s_res_irq_q <= s_res_irq_d; s_res_completed_q <= s_res_completed_d; if (s_launch_accept) begin - s_job_base_q <= launch_data_i[`APB4_NPU__LAUNCH_JOB_BASE+:32]; - s_job_id_q <= launch_data_i[`APB4_NPU__LAUNCH_JOB_ID+:32]; - s_timeout_q <= launch_data_i[`APB4_NPU__LAUNCH_TIMEOUT_CYCLES+:32]; - s_job_count_q <= launch_data_i[`APB4_NPU__LAUNCH_JOB_COUNT+:16]; + s_job_base_q <= launch_data_i[`APB4_NPU__LAUNCH_JOB_BASE+:32]; + s_job_id_q <= launch_data_i[`APB4_NPU__LAUNCH_JOB_ID+:32]; + s_timeout_q <= launch_data_i[`APB4_NPU__LAUNCH_TIMEOUT_CYCLES+:32]; + s_job_count_q <= launch_data_i[`APB4_NPU__LAUNCH_JOB_COUNT+:16]; s_fault_seen_q <= 1'b0; s_fault_desc_q <= `APB4_NPU__FAULT_DESCRIPTOR_RESET; end @@ -693,160 +707,160 @@ module npu_core #( ); npu_job_decoder u_job_decoder ( - .clk_hp_i (clk_hp_i), - .rst_hp_n_i (rst_hp_n_i), - .clear_i (s_stop), - .block_new_i (block_new_i), - .pause_ok_o (s_dec_pause_ok), - .job_start_i (s_dec_job_start), - .job_base_i (launch_data_i[`APB4_NPU__LAUNCH_JOB_BASE+:32]), - .job_count_i (launch_data_i[`APB4_NPU__LAUNCH_JOB_COUNT+:16]), - .read_req_valid_o (s_dec_read_req_valid), - .read_req_ready_i (s_dec_read_req_ready), - .read_addr_o (s_dec_read_addr), - .read_bytes_o (s_dec_read_bytes), - .read_data_valid_i (s_dec_read_data_valid), - .read_data_ready_o (s_dec_read_data_ready), - .read_data_i (dma_read_data_i), - .read_last_i (dma_read_last_i), - .dma_read_busy_i (dma_read_busy_i), - .dma_fault_i (dma_fault_i), - .dma_fault_code_i (dma_fault_code_i), - .dma_fault_addr_i (dma_fault_addr_i), - .dma_fault_resp_i (dma_fault_resp_i), - .rec_valid_o (s_rec_valid), - .rec_ready_i (s_rec_ready), - .rec_opcode_o (s_rec_opcode), - .rec_h_o (s_rec_h), - .rec_w_o (s_rec_w), - .rec_cin_o (s_rec_cin), - .rec_cout_o (s_rec_cout), - .rec_oh_o (s_rec_oh), - .rec_ow_o (s_rec_ow), - .rec_input0_base_o (s_rec_input0_base), - .rec_output_base_o (s_rec_output_base), - .rec_weight_base_o (s_rec_weight_base), - .rec_param_base_o (s_rec_param_base), + .clk_hp_i (clk_hp_i), + .rst_hp_n_i (rst_hp_n_i), + .clear_i (s_stop), + .block_new_i (block_new_i), + .pause_ok_o (s_dec_pause_ok), + .job_start_i (s_dec_job_start), + .job_base_i (launch_data_i[`APB4_NPU__LAUNCH_JOB_BASE+:32]), + .job_count_i (launch_data_i[`APB4_NPU__LAUNCH_JOB_COUNT+:16]), + .read_req_valid_o (s_dec_read_req_valid), + .read_req_ready_i (s_dec_read_req_ready), + .read_addr_o (s_dec_read_addr), + .read_bytes_o (s_dec_read_bytes), + .read_data_valid_i (s_dec_read_data_valid), + .read_data_ready_o (s_dec_read_data_ready), + .read_data_i (dma_read_data_i), + .read_last_i (dma_read_last_i), + .dma_read_busy_i (dma_read_busy_i), + .dma_fault_i (dma_fault_i), + .dma_fault_code_i (dma_fault_code_i), + .dma_fault_addr_i (dma_fault_addr_i), + .dma_fault_resp_i (dma_fault_resp_i), + .rec_valid_o (s_rec_valid), + .rec_ready_i (s_rec_ready), + .rec_opcode_o (s_rec_opcode), + .rec_h_o (s_rec_h), + .rec_w_o (s_rec_w), + .rec_cin_o (s_rec_cin), + .rec_cout_o (s_rec_cout), + .rec_oh_o (s_rec_oh), + .rec_ow_o (s_rec_ow), + .rec_input0_base_o (s_rec_input0_base), + .rec_output_base_o (s_rec_output_base), + .rec_weight_base_o (s_rec_weight_base), + .rec_param_base_o (s_rec_param_base), .rec_input0_row_bytes_o(s_rec_irow), .rec_output_row_bytes_o(s_rec_orow), - .rec_kh_o (s_rec_kh), - .rec_kw_o (s_rec_kw), - .rec_sh_o (s_rec_sh), - .rec_sw_o (s_rec_sw), - .rec_pad_top_o (s_rec_pad_top), - .rec_pad_left_o (s_rec_pad_left), - .rec_input0_zero_o (s_rec_in0_zero), - .rec_tile_h_o (s_rec_tile_h), - .rec_tile_w_o (s_rec_tile_w), - .rec_k_slice_o (s_rec_k_slice), - .rec_input1_base_o (s_rec_input1_base), + .rec_kh_o (s_rec_kh), + .rec_kw_o (s_rec_kw), + .rec_sh_o (s_rec_sh), + .rec_sw_o (s_rec_sw), + .rec_pad_top_o (s_rec_pad_top), + .rec_pad_left_o (s_rec_pad_left), + .rec_input0_zero_o (s_rec_in0_zero), + .rec_tile_h_o (s_rec_tile_h), + .rec_tile_w_o (s_rec_tile_w), + .rec_k_slice_o (s_rec_k_slice), + .rec_input1_base_o (s_rec_input1_base), .rec_input1_row_bytes_o(s_rec_input1_row_bytes), - .rec_input1_zero_o (s_rec_in1_zero), - .rec_output_zero_o (s_rec_out_zero), - .rec_act_min_o (s_rec_act_min), - .rec_act_max_o (s_rec_act_max), - .rec_weight_bytes_o(s_rec_weight_bytes), - .rec_param_bytes_o (s_rec_param_bytes), - .rec_desc_index_o (s_rec_desc_index), - .retired_i (s_dec_retired), - .all_done_o (s_dec_all_done), - .busy_o (s_dec_busy), - .cur_desc_index_o (s_dec_cur_index), - .progress_o (s_dec_progress), - .fault_req_o (s_dec_fault_req), - .fault_code_o (s_dec_fault_code), - .fault_addr_o (s_dec_fault_addr), - .fault_info_o (s_dec_fault_info), - .fault_desc_o (s_dec_fault_desc) + .rec_input1_zero_o (s_rec_in1_zero), + .rec_output_zero_o (s_rec_out_zero), + .rec_act_min_o (s_rec_act_min), + .rec_act_max_o (s_rec_act_max), + .rec_weight_bytes_o (s_rec_weight_bytes), + .rec_param_bytes_o (s_rec_param_bytes), + .rec_desc_index_o (s_rec_desc_index), + .retired_i (s_dec_retired), + .all_done_o (s_dec_all_done), + .busy_o (s_dec_busy), + .cur_desc_index_o (s_dec_cur_index), + .progress_o (s_dec_progress), + .fault_req_o (s_dec_fault_req), + .fault_code_o (s_dec_fault_code), + .fault_addr_o (s_dec_fault_addr), + .fault_info_o (s_dec_fault_info), + .fault_desc_o (s_dec_fault_desc) ); npu_scheduler u_scheduler ( - .clk_hp_i (clk_hp_i), - .rst_hp_n_i (rst_hp_n_i), - .clear_i (s_clear), - .stop_i (s_stop), - .block_new_i (block_new_i), - .pause_ok_o (s_sch_pause_ok), - .launch_i (s_sch_launch), - .timeout_cycles_i (launch_data_i[`APB4_NPU__LAUNCH_TIMEOUT_CYCLES+:32]), - .job_active_i (s_state_q == CoreRun), - .pause_active_i (pause_active_o), - .rec_valid_i (s_rec_valid), - .rec_ready_o (s_rec_ready), - .rec_opcode_i (s_rec_opcode), - .rec_h_i (s_rec_h), - .rec_w_i (s_rec_w), - .rec_cin_i (s_rec_cin), - .rec_cout_i (s_rec_cout), - .rec_oh_i (s_rec_oh), - .rec_ow_i (s_rec_ow), - .rec_input0_base_i (s_rec_input0_base), - .rec_output_base_i (s_rec_output_base), - .rec_weight_base_i (s_rec_weight_base), - .rec_param_base_i (s_rec_param_base), + .clk_hp_i (clk_hp_i), + .rst_hp_n_i (rst_hp_n_i), + .clear_i (s_clear), + .stop_i (s_stop), + .block_new_i (block_new_i), + .pause_ok_o (s_sch_pause_ok), + .launch_i (s_sch_launch), + .timeout_cycles_i (launch_data_i[`APB4_NPU__LAUNCH_TIMEOUT_CYCLES+:32]), + .job_active_i (s_state_q == CoreRun), + .pause_active_i (pause_active_o), + .rec_valid_i (s_rec_valid), + .rec_ready_o (s_rec_ready), + .rec_opcode_i (s_rec_opcode), + .rec_h_i (s_rec_h), + .rec_w_i (s_rec_w), + .rec_cin_i (s_rec_cin), + .rec_cout_i (s_rec_cout), + .rec_oh_i (s_rec_oh), + .rec_ow_i (s_rec_ow), + .rec_input0_base_i (s_rec_input0_base), + .rec_output_base_i (s_rec_output_base), + .rec_weight_base_i (s_rec_weight_base), + .rec_param_base_i (s_rec_param_base), .rec_input0_row_bytes_i(s_rec_irow), .rec_output_row_bytes_i(s_rec_orow), - .rec_kh_i (s_rec_kh), - .rec_kw_i (s_rec_kw), - .rec_sh_i (s_rec_sh), - .rec_sw_i (s_rec_sw), - .rec_pad_top_i (s_rec_pad_top), - .rec_pad_left_i (s_rec_pad_left), - .rec_input0_zero_i (s_rec_in0_zero), - .rec_tile_h_i (s_rec_tile_h), - .rec_tile_w_i (s_rec_tile_w), - .rec_k_slice_i (s_rec_k_slice), - .rec_input1_base_i (s_rec_input1_base), + .rec_kh_i (s_rec_kh), + .rec_kw_i (s_rec_kw), + .rec_sh_i (s_rec_sh), + .rec_sw_i (s_rec_sw), + .rec_pad_top_i (s_rec_pad_top), + .rec_pad_left_i (s_rec_pad_left), + .rec_input0_zero_i (s_rec_in0_zero), + .rec_tile_h_i (s_rec_tile_h), + .rec_tile_w_i (s_rec_tile_w), + .rec_k_slice_i (s_rec_k_slice), + .rec_input1_base_i (s_rec_input1_base), .rec_input1_row_bytes_i(s_rec_input1_row_bytes), - .rec_input1_zero_i (s_rec_in1_zero), - .rec_output_zero_i (s_rec_out_zero), - .rec_act_min_i (s_rec_act_min), - .rec_act_max_i (s_rec_act_max), - .rec_weight_bytes_i (s_rec_weight_bytes), - .rec_param_bytes_i (s_rec_param_bytes), - .rec_desc_index_i (s_rec_desc_index), - .retired_o (s_sch_retired), - .completed_o (s_sch_completed), - .read_req_valid_o (s_sch_read_req_valid), - .read_req_ready_i (s_sch_read_req_ready), - .read_addr_o (s_sch_read_addr), - .read_bytes_o (s_sch_read_bytes), - .read_data_valid_i (s_sch_read_data_valid), - .read_data_ready_o (s_sch_read_data_ready), - .read_data_i (dma_read_data_i), - .read_keep_i (dma_read_keep_i), - .read_last_i (dma_read_last_i), - .write_req_valid_o (s_sch_write_req_valid), - .write_req_ready_i (dma_write_req_ready_i), - .write_addr_o (s_sch_write_addr), - .write_bytes_o (s_sch_write_bytes), - .write_data_valid_o (s_sch_write_data_valid), - .write_data_ready_i (dma_write_data_ready_i), - .write_data_o (s_sch_write_data), - .write_keep_o (s_sch_write_keep), - .write_last_o (s_sch_write_last), - .write_done_i (dma_write_done_i), - .dma_read_busy_i (dma_read_busy_i), - .dma_write_busy_i (dma_write_busy_i), - .dma_pause_ack_i (dma_pause_ack_i), - .dma_fault_i (dma_fault_i), - .dma_fault_code_i (dma_fault_code_i), - .dma_fault_addr_i (dma_fault_addr_i), - .dma_fault_resp_i (dma_fault_resp_i), - .dma_read_bytes_i (dma_read_bytes_i), - .dma_write_bytes_i (dma_write_bytes_i), - .dma_stall_cycles_i (dma_stall_cycles_i), - .progress_i (s_dec_progress), - .terminal_i (s_sch_terminal), - .counters_o (s_sch_counters), - .term_counters_o (s_sch_term_counters), - .fault_req_o (s_sch_fault_req), - .fault_code_o (s_sch_fault_code), - .fault_addr_o (s_sch_fault_addr), - .fault_info_o (s_sch_fault_info), - .fault_desc_o (s_sch_fault_desc), - .busy_o (s_sch_busy), - .drained_o (s_sch_drained) + .rec_input1_zero_i (s_rec_in1_zero), + .rec_output_zero_i (s_rec_out_zero), + .rec_act_min_i (s_rec_act_min), + .rec_act_max_i (s_rec_act_max), + .rec_weight_bytes_i (s_rec_weight_bytes), + .rec_param_bytes_i (s_rec_param_bytes), + .rec_desc_index_i (s_rec_desc_index), + .retired_o (s_sch_retired), + .completed_o (s_sch_completed), + .read_req_valid_o (s_sch_read_req_valid), + .read_req_ready_i (s_sch_read_req_ready), + .read_addr_o (s_sch_read_addr), + .read_bytes_o (s_sch_read_bytes), + .read_data_valid_i (s_sch_read_data_valid), + .read_data_ready_o (s_sch_read_data_ready), + .read_data_i (dma_read_data_i), + .read_keep_i (dma_read_keep_i), + .read_last_i (dma_read_last_i), + .write_req_valid_o (s_sch_write_req_valid), + .write_req_ready_i (dma_write_req_ready_i), + .write_addr_o (s_sch_write_addr), + .write_bytes_o (s_sch_write_bytes), + .write_data_valid_o (s_sch_write_data_valid), + .write_data_ready_i (dma_write_data_ready_i), + .write_data_o (s_sch_write_data), + .write_keep_o (s_sch_write_keep), + .write_last_o (s_sch_write_last), + .write_done_i (dma_write_done_i), + .dma_read_busy_i (dma_read_busy_i), + .dma_write_busy_i (dma_write_busy_i), + .dma_pause_ack_i (dma_pause_ack_i), + .dma_fault_i (dma_fault_i), + .dma_fault_code_i (dma_fault_code_i), + .dma_fault_addr_i (dma_fault_addr_i), + .dma_fault_resp_i (dma_fault_resp_i), + .dma_read_bytes_i (dma_read_bytes_i), + .dma_write_bytes_i (dma_write_bytes_i), + .dma_stall_cycles_i (dma_stall_cycles_i), + .progress_i (s_dec_progress), + .terminal_i (s_sch_terminal), + .counters_o (s_sch_counters), + .term_counters_o (s_sch_term_counters), + .fault_req_o (s_sch_fault_req), + .fault_code_o (s_sch_fault_code), + .fault_addr_o (s_sch_fault_addr), + .fault_info_o (s_sch_fault_info), + .fault_desc_o (s_sch_fault_desc), + .busy_o (s_sch_busy), + .drained_o (s_sch_drained) ); end endmodule diff --git a/rtl/ip/security/crypto_aes_sram_engine.sv b/rtl/ip/security/crypto_aes_sram_engine.sv index cd66d2b9..f45a1c6e 100644 --- a/rtl/ip/security/crypto_aes_sram_engine.sv +++ b/rtl/ip/security/crypto_aes_sram_engine.sv @@ -27,7 +27,7 @@ module crypto_aes_sram_engine ( output logic [ 3:0] output_keep_o, output logic output_last_o, output logic busy_o, - done_o, + output logic done_o, error_o, output logic [31:0] bytes_in_o, bytes_out_o, diff --git a/rtl/mini/formal/apu_p9_formal.sv b/rtl/mini/formal/apu_p9_formal.sv index 036e9534..23cb0eb6 100644 --- a/rtl/mini/formal/apu_p9_formal.sv +++ b/rtl/mini/formal/apu_p9_formal.sv @@ -22,17 +22,17 @@ module apu_p9_formal_design ( output logic store_write, output logic [13:0] store_addr ); - logic s_start_q; - (* anyseq *) logic s_abort; - (* anyseq *) logic s_dma_request_ready; - (* anyseq *) logic s_dma_valid; - (* anyseq *) logic s_dma_done; - (* anyseq *) logic s_dma_error; - (* anyseq *) logic [31:0] s_dma_data; - (* anyseq *) logic s_store_ready; - (* anyseq *) logic s_store_valid; - (* anyseq *) logic [31:0] s_store_data; - (* anyseq *) logic s_store_fault; + logic s_start_q; + (* anyseq *)logic s_abort; + (* anyseq *)logic s_dma_request_ready; + (* anyseq *)logic s_dma_valid; + (* anyseq *)logic s_dma_done; + (* anyseq *)logic s_dma_error; + (* anyseq *)logic [31:0] s_dma_data; + (* anyseq *)logic s_store_ready; + (* anyseq *)logic s_store_valid; + (* anyseq *)logic [31:0] s_store_data; + (* anyseq *)logic s_store_fault; apu_kws_coeff_loader u_dut ( .clk_i (clk_i), diff --git a/rtl/mini/formal/apu_p9_formal_props.sv b/rtl/mini/formal/apu_p9_formal_props.sv index 769a47f2..a6ee0b97 100644 --- a/rtl/mini/formal/apu_p9_formal_props.sv +++ b/rtl/mini/formal/apu_p9_formal_props.sv @@ -2,24 +2,24 @@ // SPDX-License-Identifier: MulanPSL-2.0 module apu_p9_formal; - (* anyseq *) (* gclk *) reg clk_i; - wire rst_n_i; - wire f_past_valid; - wire busy; - wire valid; - wire lock; + (* anyseq *) (* gclk *)reg clk_i; + wire rst_n_i; + wire f_past_valid; + wire busy; + wire valid; + wire lock; wire [31:0] actual_crc; wire [63:0] coefficient_id; wire [31:0] status; - wire [5:0] error_code; - wire done; - wire abort_done; - wire dma_request_valid; + wire [ 5:0] error_code; + wire done; + wire abort_done; + wire dma_request_valid; wire [31:0] dma_request_address; wire [31:0] dma_request_bytes; - wire store_active; - wire store_req; - wire store_write; + wire store_active; + wire store_req; + wire store_write; wire [13:0] store_addr; apu_p9_formal_design u_design (.*); diff --git a/rtl/mini/mk/formal.mk b/rtl/mini/mk/formal.mk index e773d1f6..521c8a93 100644 --- a/rtl/mini/mk/formal.mk +++ b/rtl/mini/mk/formal.mk @@ -252,14 +252,14 @@ $(FORMAL_DIR)/%/prove.sby: $(FORMAL_DIR)/%/design.v \ $(FORMAL_SBY_GENERATOR) python3 $(FORMAL_SBY_GENERATOR) --top $(FORMAL_TARGET_TOP)_formal --input $< \ --properties $(FORMAL_PROPERTIES_SOURCE) $(FORMAL_PROPERTIES_DEFINE) --solver $(FORMAL_SOLVER) \ - --mode $(if $(filter ga2d,$*),bmc,$(if $(filter dma npu_dma npu_context npu_control apu apu_codec apu_kws apu_p9 apu_primitives apu_sequencer $(FORMAL_APU_LOADER_TARGETS) $(FORMAL_APU_PRIMITIVE_TARGETS) gateway_a sdio onchip_ram,$*),bmc,prove)) --depth $(if $(filter ga2d,$*),$(FORMAL_GA2D_DEPTH),$(if $(filter pll_rcu,$*),$(FORMAL_PLL_RCU_DEPTH),$(if $(filter npu_dma,$*),$(FORMAL_NPU_DMA_DEPTH),$(if $(filter npu_context,$*),$(FORMAL_NPU_CONTEXT_DEPTH),$(if $(filter npu_control,$*),$(FORMAL_NPU_CONTROL_DEPTH),$(if $(filter dma,$*),$(FORMAL_DMA_DEPTH),$(if $(filter apu apu_codec apu_kws apu_p9 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 ga2d,$*),bmc,$(if $(filter dma npu_dma npu_context npu_control apu apu_codec apu_kws apu_p9 apu_primitives apu_sequencer $(FORMAL_APU_LOADER_TARGETS) $(FORMAL_APU_PRIMITIVE_TARGETS) gateway_a sdio onchip_ram,$*),bmc,prove)) --depth $(if $(filter ga2d,$*),$(FORMAL_GA2D_DEPTH),$(if $(filter pll_rcu,$*),$(FORMAL_PLL_RCU_DEPTH),$(if $(filter npu_dma,$*),$(FORMAL_NPU_DMA_DEPTH),$(if $(filter npu_context,$*),$(FORMAL_NPU_CONTEXT_DEPTH),$(if $(filter npu_control,$*),$(FORMAL_NPU_CONTROL_DEPTH),$(if $(filter dma,$*),$(FORMAL_DMA_DEPTH),$(if $(filter apu apu_codec apu_kws apu_p9 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 $(FORMAL_PROPERTIES_SOURCE) $(FORMAL_PROPERTIES_DEFINE) --solver $(FORMAL_SOLVER) \ - --mode cover --depth $(if $(filter ga2d,$*),$(FORMAL_GA2D_COVER_DEPTH),$(if $(filter pll_rcu,$*),$(FORMAL_PLL_RCU_DEPTH),$(if $(filter npu_dma,$*),$(FORMAL_NPU_DMA_COVER_DEPTH),$(if $(filter npu_context,$*),$(FORMAL_NPU_CONTEXT_DEPTH),$(if $(filter npu_control,$*),$(FORMAL_NPU_CONTROL_DEPTH),$(if $(filter dma,$*),$(FORMAL_DMA_COVER_DEPTH),$(if $(filter apu apu_codec apu_kws apu_p9 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 ga2d,$*),$(FORMAL_GA2D_COVER_DEPTH),$(if $(filter pll_rcu,$*),$(FORMAL_PLL_RCU_DEPTH),$(if $(filter npu_dma,$*),$(FORMAL_NPU_DMA_COVER_DEPTH),$(if $(filter npu_context,$*),$(FORMAL_NPU_CONTEXT_DEPTH),$(if $(filter npu_control,$*),$(FORMAL_NPU_CONTROL_DEPTH),$(if $(filter dma,$*),$(FORMAL_DMA_COVER_DEPTH),$(if $(filter apu apu_codec apu_kws apu_p9 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_APU_P5_LOADER_TARGETS),$*),--skip $(FORMAL_APU_P5_LOADER_COVER_SKIP)) \ $(if $(filter $(FORMAL_COMPACT_COVER_TARGETS),$*),--no-vcd) --output $@ @if [ "$*" = opipsram ]; then sed -i '/^async2sync/i clk2fflogic' $@; fi @@ -390,4 +390,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-ga2d formal-apu formal-apu-kws formal-apu-p9 formal-apu-loader formal-apu-loader-p5 formal-apu-sequencer formal-gateway-a formal-sdio formal-npu_dma formal-npu-context formal-npu-control formal-npu-p6 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-ga2d formal-apu formal-apu-kws formal-apu-p9 formal-apu-loader formal-apu-loader-p5 formal-apu-sequencer formal-gateway-a formal-sdio formal-npu_dma formal-npu-context formal-npu-control formal-npu-p6 formal-doctor formal-clean \ No newline at end of file diff --git a/rtl/mk/software.mk b/rtl/mk/software.mk index 60b1e0ce..f3d01b9f 100644 --- a/rtl/mk/software.mk +++ b/rtl/mk/software.mk @@ -186,7 +186,7 @@ CRT_SRCS += $(ROOT_PATH)/crt/arch/riscv/libgcc/muldi3.S CRT_SRCS += $(ROOT_PATH)/crt/arch/riscv/libgcc/mulsi3.c endif -INC_PATH := -I$(SW_BUILD_DIR)/include \ +INC_PATH := -I$(SW_BUILD_DIR)/include \ -I$(MEMORY_MAP_C_DIR) \ -I$(SOC_TOPOLOGY_INCLUDE_DIR) \ -I$(USER_EXTENSIONS_DIR)/include \ @@ -200,28 +200,28 @@ INC_PATH := -I$(SW_BUILD_DIR)/include \ -I$(ROOT_PATH)/rtl/managed/clusterip/ps2/sw/include \ -I$(ROOT_PATH)/crt/include \ $(addprefix -I,$(APP_INC_DIRS)) -SRC_PATH := $(CRT_SRCS) $(APP_SRCS) -LDS_PATH := $(ROOT_PATH)/crt/linker/$(LINK_TYPE).lds -MEMORY_REGIONS_LD := $(MEMORY_MAP_LINKER_DIR)/memory_regions.ld -VERSION_HEADER := $(SW_BUILD_DIR)/include/socver.h +SRC_PATH := $(CRT_SRCS) $(APP_SRCS) +LDS_PATH := $(ROOT_PATH)/crt/linker/$(LINK_TYPE).lds +MEMORY_REGIONS_LD := $(MEMORY_MAP_LINKER_DIR)/memory_regions.ld +VERSION_HEADER := $(SW_BUILD_DIR)/include/socver.h CRYPTO_CONSTANTS_HEADER := $(SW_BUILD_DIR)/include/crypto_constants.h -FIRMWARE_ELF := $(SW_BUILD_DIR)/firmware -ASM_FIRMWARE_NAME ?= retrosoc_asm -SW_HEADERS := $(shell find $(ROOT_PATH)/crt/include $(ROOT_PATH)/app -type f \ +FIRMWARE_ELF := $(SW_BUILD_DIR)/firmware +ASM_FIRMWARE_NAME ?= retrosoc_asm +SW_HEADERS := $(shell find $(ROOT_PATH)/crt/include $(ROOT_PATH)/app -type f \ \( -name '*.h' -o -name '*.hpp' \) 2>/dev/null) -SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/archinfo/sw/include \ +SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/archinfo/sw/include \ -type f -name '*.h' 2>/dev/null) -SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/crc/sw/include \ +SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/crc/sw/include \ -type f -name '*.h' 2>/dev/null) -SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/rng/sw/include \ +SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/rng/sw/include \ -type f -name '*.h' 2>/dev/null) -SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/rtc/sw/include \ +SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/rtc/sw/include \ -type f -name '*.h' 2>/dev/null) -SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/wdg/sw/include \ +SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/wdg/sw/include \ -type f -name '*.h' 2>/dev/null) -SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/pwm/sw/include \ +SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/pwm/sw/include \ -type f -name '*.h' 2>/dev/null) -SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/ps2/sw/include \ +SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/ps2/sw/include \ -type f -name '*.h' 2>/dev/null) $(VERSION_HEADER): FORCE_VERSION $(ROOT_PATH)/crt/ver.py $(ROOT_PATH)/crt/ver.tmpl @@ -266,4 +266,4 @@ firmware: $(FIRMWARE_ELF) firmware asm: | manifest -.PHONY: FORCE_VERSION +.PHONY: FORCE_VERSION \ No newline at end of file diff --git a/scripts/README.md b/scripts/README.md index 94ac7567..2b3ace72 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -123,8 +123,9 @@ SRAM CoreMark quick report into `meta/coremark.json`; it requires one valid `COREMARK_RESULT` record and `COREMARK_PASS`. Both reports complement, rather than replace, the common `SIM_TEST_PASS` simulation verdict. -`generate_vexiiriscv.py` verifies the locked VexiiRiscv revision and generates -the fixed HP core below `build/`; generated RTL is never tracked. +`generate_vexiiriscv.py` verifies the locked VexiiRiscv revision, rejects local +source changes before and after generation, and generates the fixed HP core +below `build/`; generated RTL is never tracked. `setup_hp_linux.py` installs the locked OpenSBI, Linux, and Buildroot revisions and can resume a checkout left without `HEAD` by an interrupted fetch. `build_hp_linux.py` builds the RV64 `lp64d` userspace/OpenSBI image set with the repo-owned diff --git a/scripts/generate_vexiiriscv.py b/scripts/generate_vexiiriscv.py index bbe80b24..7be7fe66 100644 --- a/scripts/generate_vexiiriscv.py +++ b/scripts/generate_vexiiriscv.py @@ -46,14 +46,22 @@ def locked_revision(lock_path: Path) -> str: return source["revision"] +def validate_locked_source(source: Path, expected: str) -> str: + actual = git_revision(source) + if actual != expected: + raise ValueError(f"VexiiRiscv revision mismatch: expected {expected}, found {actual}") + status = git_status(source) + if status: + raise ValueError("VexiiRiscv source has local changes:\n" + "\n".join(status)) + return actual + + def generate(args: argparse.Namespace) -> None: root = args.root.resolve() source = args.source.resolve() output = args.output.resolve() expected = locked_revision(args.lock.resolve()) - actual = git_revision(source) - if actual != expected: - raise ValueError(f"VexiiRiscv revision mismatch: expected {expected}, found {actual}") + actual = validate_locked_source(source, expected) scala_dir = root / "scripts" / "vexiiriscv" output.mkdir(parents=True, exist_ok=True) @@ -81,6 +89,7 @@ def generate(args: argparse.Namespace) -> None: generated = output / "vexii_riscv_hp_generated.v" if not generated.is_file(): raise FileNotFoundError(f"VexiiRiscv generator did not create {generated}") + validate_locked_source(source, expected) submodules = run(["git", "submodule", "status", "--recursive"], source).splitlines() manifest = { @@ -91,7 +100,7 @@ def generate(args: argparse.Namespace) -> None: "physical_address_width": 32, "mmu": "sv39", "vexiiriscv_revision": actual, - "source_status": git_status(source), + "source_status": [], "submodules": submodules, "generator": str((scala_dir / "GenerateRetroSocHp.scala").relative_to(root)), "files": {generated.name: sha256(generated)}, diff --git a/scripts/regress.py b/scripts/regress.py index 92c8b4fc..caa742f4 100644 --- a/scripts/regress.py +++ b/scripts/regress.py @@ -33,9 +33,9 @@ CI_SMOKE_SIM_VALUES = ( CI_SMOKE_SDRAM_SIM_VALUES = ( CI_SMOKE_APP_VALUE, "LINK_TYPE=ld2_sdram", - # Hosted Verilator executes the expanded GA2D acceptance workload more + # Hosted Verilator executes the expanded peripheral acceptance workload # slowly when LP code and accelerator traffic share the SDRAM target. - "SOC_SIM_TIME=1800", + "SOC_SIM_TIME=3600", *CI_SMOKE_VERILATOR_VALUES, ) RTL_LINT_VALUES = ("SIMU=VERILATOR", "HAVE_SVA=YES", "rtl-lint") diff --git a/tests/rtl/apu_kws_coeff_fixture.sv b/tests/rtl/apu_kws_coeff_fixture.sv index c44ab6f3..8bfc63ab 100644 --- a/tests/rtl/apu_kws_coeff_fixture.sv +++ b/tests/rtl/apu_kws_coeff_fixture.sv @@ -68,7 +68,7 @@ module apu_kws_coeff_fixture ( ); initial begin - initialized_o = 1'b0; + initialized_o = 1'b0; s_loader_active = 1'b0; s_loader_req = 1'b0; s_loader_addr = 14'd0; diff --git a/tests/rtl/apu_kws_engine_tb.sv b/tests/rtl/apu_kws_engine_tb.sv index baa18e70..084e050c 100644 --- a/tests/rtl/apu_kws_engine_tb.sv +++ b/tests/rtl/apu_kws_engine_tb.sv @@ -52,10 +52,10 @@ module apu_kws_engine_tb; logic [ 5:0][ 3:0] scratch_write_strb; logic scratch_access_err; logic coeff_front_req, coeff_front_ready, coeff_front_resp_valid, coeff_front_resp_ready; - logic [3:0] coeff_front_kind; + logic [ 3:0] coeff_front_kind; logic [13:0] coeff_front_index; logic [63:0] coeff_front_data; - logic coeff_front_fault; + logic coeff_front_fault; logic coeff_infer_req, coeff_infer_ready, coeff_infer_resp_valid, coeff_infer_resp_ready; logic [ 6:0] coeff_infer_index; logic [31:0] coeff_infer_data; diff --git a/tests/rtl/apu_p7_accuracy_tb.sv b/tests/rtl/apu_p7_accuracy_tb.sv index d2b0eb58..bbc97f32 100644 --- a/tests/rtl/apu_p7_accuracy_tb.sv +++ b/tests/rtl/apu_p7_accuracy_tb.sv @@ -58,10 +58,10 @@ module apu_p7_accuracy_tb; logic [ 5:0][ 3:0] scratch_write_strb; logic scratch_access_err; logic coeff_front_req, coeff_front_ready, coeff_front_resp_valid, coeff_front_resp_ready; - logic [3:0] coeff_front_kind; + logic [ 3:0] coeff_front_kind; logic [13:0] coeff_front_index; logic [63:0] coeff_front_data; - logic coeff_front_fault; + logic coeff_front_fault; logic coeff_infer_req, coeff_infer_ready, coeff_infer_resp_valid, coeff_infer_resp_ready; logic [ 6:0] coeff_infer_index; logic [31:0] coeff_infer_data; diff --git a/tests/rtl/apu_p7_frontend_dump_tb.sv b/tests/rtl/apu_p7_frontend_dump_tb.sv index 03ff8486..2fc86848 100644 --- a/tests/rtl/apu_p7_frontend_dump_tb.sv +++ b/tests/rtl/apu_p7_frontend_dump_tb.sv @@ -61,16 +61,16 @@ module apu_p7_frontend_dump_tb; logic [ 5:0][ 3:0] scratch_write_strb; logic scratch_access_err; logic coeff_front_req, coeff_front_ready, coeff_front_resp_valid, coeff_front_resp_ready; - logic [3:0] coeff_front_kind; + logic [ 3:0] coeff_front_kind; logic [13:0] coeff_front_index; logic [63:0] coeff_front_data; - logic coeff_front_fault; + logic coeff_front_fault; logic coeff_infer_req, coeff_infer_ready, coeff_infer_resp_valid, coeff_infer_resp_ready; logic [ 6:0] coeff_infer_index; logic [31:0] coeff_infer_data; logic coeff_infer_fault, coeff_initialized; - int unsigned debug_commit_count; - logic [31:0] pcm_mem[0:PcmWords-1]; + int unsigned debug_commit_count; + logic [31:0] pcm_mem [0:PcmWords-1]; always #5 clk_i = ~clk_i; diff --git a/tests/rtl/apu_p9_storage_tb.sv b/tests/rtl/apu_p9_storage_tb.sv index 4a8e44cb..a58a0fd0 100644 --- a/tests/rtl/apu_p9_storage_tb.sv +++ b/tests/rtl/apu_p9_storage_tb.sv @@ -109,24 +109,24 @@ module apu_p9_storage_tb; initial begin loader_active = 1'b0; - loader_req = 1'b0; - loader_write = 1'b1; - loader_addr = 14'd0; - loader_data = 32'd0; - front_req = 1'b0; - front_kind = 4'd0; - front_index = 14'd0; + loader_req = 1'b0; + loader_write = 1'b1; + loader_addr = 14'd0; + loader_data = 32'd0; + front_req = 1'b0; + front_kind = 4'd0; + front_index = 14'd0; front_consume = 1'b0; - infer_req = 1'b0; - infer_index = 7'd0; + infer_req = 1'b0; + infer_index = 7'd0; infer_consume = 1'b0; - memo_clear = 1'b0; - memo_lookup = 1'b0; - memo_insert = 1'b0; - memo_addr = 13'd0; - memo_key = 64'd0; + memo_clear = 1'b0; + memo_lookup = 1'b0; + memo_insert = 1'b0; + memo_addr = 13'd0; + memo_key = 64'd0; repeat (3) @(negedge clk_i); - rst_n_i = 1'b1; + rst_n_i = 1'b1; loader_active = 1'b1; write_coefficient(14'(1024 + 5), 32'h1111_1111); @@ -159,9 +159,9 @@ module apu_p9_storage_tb; front_consume = 1'b0; infer_consume = 1'b0; - front_kind = 4'd9; - front_index = 14'd0; - front_req = 1'b1; + front_kind = 4'd9; + front_index = 14'd0; + front_req = 1'b1; @(negedge clk_i); front_req = 1'b0; wait (front_valid); diff --git a/tests/rtl/ga2d_netlist_tb.sv b/tests/rtl/ga2d_netlist_tb.sv index 91b5b741..14da0bb4 100644 --- a/tests/rtl/ga2d_netlist_tb.sv +++ b/tests/rtl/ga2d_netlist_tb.sv @@ -14,6 +14,10 @@ module ga2d_netlist_tb; localparam int unsigned MemoryBytes = 32768; localparam logic [2:0] IrqDoneMask = 3'b001 << `APB4_GA2D__IRQ_DONE; localparam logic [2:0] IrqErrorMask = 3'b001 << `APB4_GA2D__IRQ_ERROR; + localparam logic [2:0] FormatRgb565 = `APB4_GA2D__FORMAT_RGB565; + localparam logic [2:0] FormatRgb888 = `APB4_GA2D__FORMAT_RGB888; + localparam logic [2:0] FormatXrgb8888 = `APB4_GA2D__FORMAT_XRGB8888; + localparam logic [2:0] FormatArgb8888 = `APB4_GA2D__FORMAT_ARGB8888; logic clk_i = 1'b0; logic rst_n_i = 1'b0; @@ -83,7 +87,7 @@ module ga2d_netlist_tb; logic [ 3:0] ga2d_axi4_ruser; logic ga2d_axi4_rvalid; logic ga2d_axi4_rready; - logic [ 7:0] s_memory [0:MemoryBytes-1]; + logic [ 7:0] s_memory [0:MemoryBytes-1]; logic s_rvalid_q; logic [31:0] s_raddr_q; logic [63:0] s_rdata_q; @@ -280,12 +284,12 @@ module ga2d_netlist_tb; end end if (s_wbeats_q == 9'd1) begin - s_aw_pending_q <= 1'b0; - s_wbeats_q <= '0; - s_bvalid_q <= 1'b1; - s_b_delay_q <= s_lfsr_q[1:0]; - s_lfsr_q <= next_delay_lfsr(s_lfsr_q); - s_w_delay_pending_q <= 1'b0; + s_aw_pending_q <= 1'b0; + s_wbeats_q <= '0; + s_bvalid_q <= 1'b1; + s_b_delay_q <= s_lfsr_q[1:0]; + s_lfsr_q <= next_delay_lfsr(s_lfsr_q); + s_w_delay_pending_q <= 1'b0; end else begin s_awaddr_q <= s_awaddr_q + 32'd8; s_wbeats_q <= s_wbeats_q - 1'b1; @@ -373,446 +377,446 @@ module ga2d_netlist_tb; // This mapping re-bundles them into the vectors used by this testbench; // it must track physical/smoke/syn/yosys/apb4_ga2d_block_top.sv. apb4_ga2d_block_top u_dut ( - .clk_i(clk_i), - .rst_n_i(rst_n_i), - .resource_quiesce_i(resource_quiesce_i), - .resource_reset_i(resource_reset_i), - .source_stop_i(source_stop_i), - .source_safe_idle_i(source_safe_idle_i), - .block_ack_i(block_ack_i), - .bridge_clear_busy_i(bridge_clear_busy_i), - .bridge_epoch_i_0_(bridge_epoch_i[0]), - .bridge_epoch_i_1_(bridge_epoch_i[1]), - .bridge_epoch_i_2_(bridge_epoch_i[2]), - .bridge_epoch_i_3_(bridge_epoch_i[3]), - .bridge_epoch_i_4_(bridge_epoch_i[4]), - .bridge_epoch_i_5_(bridge_epoch_i[5]), - .bridge_epoch_i_6_(bridge_epoch_i[6]), - .bridge_epoch_i_7_(bridge_epoch_i[7]), - .data_ready_i(data_ready_i), - .mem_pad_mode_i_0_(mem_pad_mode_i[0]), - .mem_pad_mode_i_1_(mem_pad_mode_i[1]), - .idle_o(idle_o), - .core_safe_idle_o(core_safe_idle_o), - .irq_o(irq_o), - .apb4_paddr_0_(apb4_paddr[0]), - .apb4_paddr_1_(apb4_paddr[1]), - .apb4_paddr_2_(apb4_paddr[2]), - .apb4_paddr_3_(apb4_paddr[3]), - .apb4_paddr_4_(apb4_paddr[4]), - .apb4_paddr_5_(apb4_paddr[5]), - .apb4_paddr_6_(apb4_paddr[6]), - .apb4_paddr_7_(apb4_paddr[7]), - .apb4_paddr_8_(apb4_paddr[8]), - .apb4_paddr_9_(apb4_paddr[9]), - .apb4_paddr_10_(apb4_paddr[10]), - .apb4_paddr_11_(apb4_paddr[11]), - .apb4_paddr_12_(apb4_paddr[12]), - .apb4_paddr_13_(apb4_paddr[13]), - .apb4_paddr_14_(apb4_paddr[14]), - .apb4_paddr_15_(apb4_paddr[15]), - .apb4_paddr_16_(apb4_paddr[16]), - .apb4_paddr_17_(apb4_paddr[17]), - .apb4_paddr_18_(apb4_paddr[18]), - .apb4_paddr_19_(apb4_paddr[19]), - .apb4_paddr_20_(apb4_paddr[20]), - .apb4_paddr_21_(apb4_paddr[21]), - .apb4_paddr_22_(apb4_paddr[22]), - .apb4_paddr_23_(apb4_paddr[23]), - .apb4_paddr_24_(apb4_paddr[24]), - .apb4_paddr_25_(apb4_paddr[25]), - .apb4_paddr_26_(apb4_paddr[26]), - .apb4_paddr_27_(apb4_paddr[27]), - .apb4_paddr_28_(apb4_paddr[28]), - .apb4_paddr_29_(apb4_paddr[29]), - .apb4_paddr_30_(apb4_paddr[30]), - .apb4_paddr_31_(apb4_paddr[31]), - .apb4_pprot_0_(apb4_pprot[0]), - .apb4_pprot_1_(apb4_pprot[1]), - .apb4_pprot_2_(apb4_pprot[2]), - .apb4_psel(apb4_psel), - .apb4_penable(apb4_penable), - .apb4_pwrite(apb4_pwrite), - .apb4_pwdata_0_(apb4_pwdata[0]), - .apb4_pwdata_1_(apb4_pwdata[1]), - .apb4_pwdata_2_(apb4_pwdata[2]), - .apb4_pwdata_3_(apb4_pwdata[3]), - .apb4_pwdata_4_(apb4_pwdata[4]), - .apb4_pwdata_5_(apb4_pwdata[5]), - .apb4_pwdata_6_(apb4_pwdata[6]), - .apb4_pwdata_7_(apb4_pwdata[7]), - .apb4_pwdata_8_(apb4_pwdata[8]), - .apb4_pwdata_9_(apb4_pwdata[9]), - .apb4_pwdata_10_(apb4_pwdata[10]), - .apb4_pwdata_11_(apb4_pwdata[11]), - .apb4_pwdata_12_(apb4_pwdata[12]), - .apb4_pwdata_13_(apb4_pwdata[13]), - .apb4_pwdata_14_(apb4_pwdata[14]), - .apb4_pwdata_15_(apb4_pwdata[15]), - .apb4_pwdata_16_(apb4_pwdata[16]), - .apb4_pwdata_17_(apb4_pwdata[17]), - .apb4_pwdata_18_(apb4_pwdata[18]), - .apb4_pwdata_19_(apb4_pwdata[19]), - .apb4_pwdata_20_(apb4_pwdata[20]), - .apb4_pwdata_21_(apb4_pwdata[21]), - .apb4_pwdata_22_(apb4_pwdata[22]), - .apb4_pwdata_23_(apb4_pwdata[23]), - .apb4_pwdata_24_(apb4_pwdata[24]), - .apb4_pwdata_25_(apb4_pwdata[25]), - .apb4_pwdata_26_(apb4_pwdata[26]), - .apb4_pwdata_27_(apb4_pwdata[27]), - .apb4_pwdata_28_(apb4_pwdata[28]), - .apb4_pwdata_29_(apb4_pwdata[29]), - .apb4_pwdata_30_(apb4_pwdata[30]), - .apb4_pwdata_31_(apb4_pwdata[31]), - .apb4_pstrb_0_(apb4_pstrb[0]), - .apb4_pstrb_1_(apb4_pstrb[1]), - .apb4_pstrb_2_(apb4_pstrb[2]), - .apb4_pstrb_3_(apb4_pstrb[3]), - .apb4_pready(apb4_pready), - .apb4_prdata_0_(apb4_prdata[0]), - .apb4_prdata_1_(apb4_prdata[1]), - .apb4_prdata_2_(apb4_prdata[2]), - .apb4_prdata_3_(apb4_prdata[3]), - .apb4_prdata_4_(apb4_prdata[4]), - .apb4_prdata_5_(apb4_prdata[5]), - .apb4_prdata_6_(apb4_prdata[6]), - .apb4_prdata_7_(apb4_prdata[7]), - .apb4_prdata_8_(apb4_prdata[8]), - .apb4_prdata_9_(apb4_prdata[9]), - .apb4_prdata_10_(apb4_prdata[10]), - .apb4_prdata_11_(apb4_prdata[11]), - .apb4_prdata_12_(apb4_prdata[12]), - .apb4_prdata_13_(apb4_prdata[13]), - .apb4_prdata_14_(apb4_prdata[14]), - .apb4_prdata_15_(apb4_prdata[15]), - .apb4_prdata_16_(apb4_prdata[16]), - .apb4_prdata_17_(apb4_prdata[17]), - .apb4_prdata_18_(apb4_prdata[18]), - .apb4_prdata_19_(apb4_prdata[19]), - .apb4_prdata_20_(apb4_prdata[20]), - .apb4_prdata_21_(apb4_prdata[21]), - .apb4_prdata_22_(apb4_prdata[22]), - .apb4_prdata_23_(apb4_prdata[23]), - .apb4_prdata_24_(apb4_prdata[24]), - .apb4_prdata_25_(apb4_prdata[25]), - .apb4_prdata_26_(apb4_prdata[26]), - .apb4_prdata_27_(apb4_prdata[27]), - .apb4_prdata_28_(apb4_prdata[28]), - .apb4_prdata_29_(apb4_prdata[29]), - .apb4_prdata_30_(apb4_prdata[30]), - .apb4_prdata_31_(apb4_prdata[31]), - .apb4_pslverr(apb4_pslverr), - .ga2d_axi4_awid_0_(ga2d_axi4_awid[0]), - .ga2d_axi4_awid_1_(ga2d_axi4_awid[1]), - .ga2d_axi4_awid_2_(ga2d_axi4_awid[2]), - .ga2d_axi4_awid_3_(ga2d_axi4_awid[3]), - .ga2d_axi4_awaddr_0_(ga2d_axi4_awaddr[0]), - .ga2d_axi4_awaddr_1_(ga2d_axi4_awaddr[1]), - .ga2d_axi4_awaddr_2_(ga2d_axi4_awaddr[2]), - .ga2d_axi4_awaddr_3_(ga2d_axi4_awaddr[3]), - .ga2d_axi4_awaddr_4_(ga2d_axi4_awaddr[4]), - .ga2d_axi4_awaddr_5_(ga2d_axi4_awaddr[5]), - .ga2d_axi4_awaddr_6_(ga2d_axi4_awaddr[6]), - .ga2d_axi4_awaddr_7_(ga2d_axi4_awaddr[7]), - .ga2d_axi4_awaddr_8_(ga2d_axi4_awaddr[8]), - .ga2d_axi4_awaddr_9_(ga2d_axi4_awaddr[9]), - .ga2d_axi4_awaddr_10_(ga2d_axi4_awaddr[10]), - .ga2d_axi4_awaddr_11_(ga2d_axi4_awaddr[11]), - .ga2d_axi4_awaddr_12_(ga2d_axi4_awaddr[12]), - .ga2d_axi4_awaddr_13_(ga2d_axi4_awaddr[13]), - .ga2d_axi4_awaddr_14_(ga2d_axi4_awaddr[14]), - .ga2d_axi4_awaddr_15_(ga2d_axi4_awaddr[15]), - .ga2d_axi4_awaddr_16_(ga2d_axi4_awaddr[16]), - .ga2d_axi4_awaddr_17_(ga2d_axi4_awaddr[17]), - .ga2d_axi4_awaddr_18_(ga2d_axi4_awaddr[18]), - .ga2d_axi4_awaddr_19_(ga2d_axi4_awaddr[19]), - .ga2d_axi4_awaddr_20_(ga2d_axi4_awaddr[20]), - .ga2d_axi4_awaddr_21_(ga2d_axi4_awaddr[21]), - .ga2d_axi4_awaddr_22_(ga2d_axi4_awaddr[22]), - .ga2d_axi4_awaddr_23_(ga2d_axi4_awaddr[23]), - .ga2d_axi4_awaddr_24_(ga2d_axi4_awaddr[24]), - .ga2d_axi4_awaddr_25_(ga2d_axi4_awaddr[25]), - .ga2d_axi4_awaddr_26_(ga2d_axi4_awaddr[26]), - .ga2d_axi4_awaddr_27_(ga2d_axi4_awaddr[27]), - .ga2d_axi4_awaddr_28_(ga2d_axi4_awaddr[28]), - .ga2d_axi4_awaddr_29_(ga2d_axi4_awaddr[29]), - .ga2d_axi4_awaddr_30_(ga2d_axi4_awaddr[30]), - .ga2d_axi4_awaddr_31_(ga2d_axi4_awaddr[31]), - .ga2d_axi4_awlen_0_(ga2d_axi4_awlen[0]), - .ga2d_axi4_awlen_1_(ga2d_axi4_awlen[1]), - .ga2d_axi4_awlen_2_(ga2d_axi4_awlen[2]), - .ga2d_axi4_awlen_3_(ga2d_axi4_awlen[3]), - .ga2d_axi4_awlen_4_(ga2d_axi4_awlen[4]), - .ga2d_axi4_awlen_5_(ga2d_axi4_awlen[5]), - .ga2d_axi4_awlen_6_(ga2d_axi4_awlen[6]), - .ga2d_axi4_awlen_7_(ga2d_axi4_awlen[7]), - .ga2d_axi4_awsize_0_(ga2d_axi4_awsize[0]), - .ga2d_axi4_awsize_1_(ga2d_axi4_awsize[1]), - .ga2d_axi4_awsize_2_(ga2d_axi4_awsize[2]), - .ga2d_axi4_awburst_0_(ga2d_axi4_awburst[0]), - .ga2d_axi4_awburst_1_(ga2d_axi4_awburst[1]), - .ga2d_axi4_awlock(ga2d_axi4_awlock), - .ga2d_axi4_awcache_0_(ga2d_axi4_awcache[0]), - .ga2d_axi4_awcache_1_(ga2d_axi4_awcache[1]), - .ga2d_axi4_awcache_2_(ga2d_axi4_awcache[2]), - .ga2d_axi4_awcache_3_(ga2d_axi4_awcache[3]), - .ga2d_axi4_awprot_0_(ga2d_axi4_awprot[0]), - .ga2d_axi4_awprot_1_(ga2d_axi4_awprot[1]), - .ga2d_axi4_awprot_2_(ga2d_axi4_awprot[2]), - .ga2d_axi4_awqos_0_(ga2d_axi4_awqos[0]), - .ga2d_axi4_awqos_1_(ga2d_axi4_awqos[1]), - .ga2d_axi4_awqos_2_(ga2d_axi4_awqos[2]), - .ga2d_axi4_awqos_3_(ga2d_axi4_awqos[3]), + .clk_i (clk_i), + .rst_n_i (rst_n_i), + .resource_quiesce_i (resource_quiesce_i), + .resource_reset_i (resource_reset_i), + .source_stop_i (source_stop_i), + .source_safe_idle_i (source_safe_idle_i), + .block_ack_i (block_ack_i), + .bridge_clear_busy_i (bridge_clear_busy_i), + .bridge_epoch_i_0_ (bridge_epoch_i[0]), + .bridge_epoch_i_1_ (bridge_epoch_i[1]), + .bridge_epoch_i_2_ (bridge_epoch_i[2]), + .bridge_epoch_i_3_ (bridge_epoch_i[3]), + .bridge_epoch_i_4_ (bridge_epoch_i[4]), + .bridge_epoch_i_5_ (bridge_epoch_i[5]), + .bridge_epoch_i_6_ (bridge_epoch_i[6]), + .bridge_epoch_i_7_ (bridge_epoch_i[7]), + .data_ready_i (data_ready_i), + .mem_pad_mode_i_0_ (mem_pad_mode_i[0]), + .mem_pad_mode_i_1_ (mem_pad_mode_i[1]), + .idle_o (idle_o), + .core_safe_idle_o (core_safe_idle_o), + .irq_o (irq_o), + .apb4_paddr_0_ (apb4_paddr[0]), + .apb4_paddr_1_ (apb4_paddr[1]), + .apb4_paddr_2_ (apb4_paddr[2]), + .apb4_paddr_3_ (apb4_paddr[3]), + .apb4_paddr_4_ (apb4_paddr[4]), + .apb4_paddr_5_ (apb4_paddr[5]), + .apb4_paddr_6_ (apb4_paddr[6]), + .apb4_paddr_7_ (apb4_paddr[7]), + .apb4_paddr_8_ (apb4_paddr[8]), + .apb4_paddr_9_ (apb4_paddr[9]), + .apb4_paddr_10_ (apb4_paddr[10]), + .apb4_paddr_11_ (apb4_paddr[11]), + .apb4_paddr_12_ (apb4_paddr[12]), + .apb4_paddr_13_ (apb4_paddr[13]), + .apb4_paddr_14_ (apb4_paddr[14]), + .apb4_paddr_15_ (apb4_paddr[15]), + .apb4_paddr_16_ (apb4_paddr[16]), + .apb4_paddr_17_ (apb4_paddr[17]), + .apb4_paddr_18_ (apb4_paddr[18]), + .apb4_paddr_19_ (apb4_paddr[19]), + .apb4_paddr_20_ (apb4_paddr[20]), + .apb4_paddr_21_ (apb4_paddr[21]), + .apb4_paddr_22_ (apb4_paddr[22]), + .apb4_paddr_23_ (apb4_paddr[23]), + .apb4_paddr_24_ (apb4_paddr[24]), + .apb4_paddr_25_ (apb4_paddr[25]), + .apb4_paddr_26_ (apb4_paddr[26]), + .apb4_paddr_27_ (apb4_paddr[27]), + .apb4_paddr_28_ (apb4_paddr[28]), + .apb4_paddr_29_ (apb4_paddr[29]), + .apb4_paddr_30_ (apb4_paddr[30]), + .apb4_paddr_31_ (apb4_paddr[31]), + .apb4_pprot_0_ (apb4_pprot[0]), + .apb4_pprot_1_ (apb4_pprot[1]), + .apb4_pprot_2_ (apb4_pprot[2]), + .apb4_psel (apb4_psel), + .apb4_penable (apb4_penable), + .apb4_pwrite (apb4_pwrite), + .apb4_pwdata_0_ (apb4_pwdata[0]), + .apb4_pwdata_1_ (apb4_pwdata[1]), + .apb4_pwdata_2_ (apb4_pwdata[2]), + .apb4_pwdata_3_ (apb4_pwdata[3]), + .apb4_pwdata_4_ (apb4_pwdata[4]), + .apb4_pwdata_5_ (apb4_pwdata[5]), + .apb4_pwdata_6_ (apb4_pwdata[6]), + .apb4_pwdata_7_ (apb4_pwdata[7]), + .apb4_pwdata_8_ (apb4_pwdata[8]), + .apb4_pwdata_9_ (apb4_pwdata[9]), + .apb4_pwdata_10_ (apb4_pwdata[10]), + .apb4_pwdata_11_ (apb4_pwdata[11]), + .apb4_pwdata_12_ (apb4_pwdata[12]), + .apb4_pwdata_13_ (apb4_pwdata[13]), + .apb4_pwdata_14_ (apb4_pwdata[14]), + .apb4_pwdata_15_ (apb4_pwdata[15]), + .apb4_pwdata_16_ (apb4_pwdata[16]), + .apb4_pwdata_17_ (apb4_pwdata[17]), + .apb4_pwdata_18_ (apb4_pwdata[18]), + .apb4_pwdata_19_ (apb4_pwdata[19]), + .apb4_pwdata_20_ (apb4_pwdata[20]), + .apb4_pwdata_21_ (apb4_pwdata[21]), + .apb4_pwdata_22_ (apb4_pwdata[22]), + .apb4_pwdata_23_ (apb4_pwdata[23]), + .apb4_pwdata_24_ (apb4_pwdata[24]), + .apb4_pwdata_25_ (apb4_pwdata[25]), + .apb4_pwdata_26_ (apb4_pwdata[26]), + .apb4_pwdata_27_ (apb4_pwdata[27]), + .apb4_pwdata_28_ (apb4_pwdata[28]), + .apb4_pwdata_29_ (apb4_pwdata[29]), + .apb4_pwdata_30_ (apb4_pwdata[30]), + .apb4_pwdata_31_ (apb4_pwdata[31]), + .apb4_pstrb_0_ (apb4_pstrb[0]), + .apb4_pstrb_1_ (apb4_pstrb[1]), + .apb4_pstrb_2_ (apb4_pstrb[2]), + .apb4_pstrb_3_ (apb4_pstrb[3]), + .apb4_pready (apb4_pready), + .apb4_prdata_0_ (apb4_prdata[0]), + .apb4_prdata_1_ (apb4_prdata[1]), + .apb4_prdata_2_ (apb4_prdata[2]), + .apb4_prdata_3_ (apb4_prdata[3]), + .apb4_prdata_4_ (apb4_prdata[4]), + .apb4_prdata_5_ (apb4_prdata[5]), + .apb4_prdata_6_ (apb4_prdata[6]), + .apb4_prdata_7_ (apb4_prdata[7]), + .apb4_prdata_8_ (apb4_prdata[8]), + .apb4_prdata_9_ (apb4_prdata[9]), + .apb4_prdata_10_ (apb4_prdata[10]), + .apb4_prdata_11_ (apb4_prdata[11]), + .apb4_prdata_12_ (apb4_prdata[12]), + .apb4_prdata_13_ (apb4_prdata[13]), + .apb4_prdata_14_ (apb4_prdata[14]), + .apb4_prdata_15_ (apb4_prdata[15]), + .apb4_prdata_16_ (apb4_prdata[16]), + .apb4_prdata_17_ (apb4_prdata[17]), + .apb4_prdata_18_ (apb4_prdata[18]), + .apb4_prdata_19_ (apb4_prdata[19]), + .apb4_prdata_20_ (apb4_prdata[20]), + .apb4_prdata_21_ (apb4_prdata[21]), + .apb4_prdata_22_ (apb4_prdata[22]), + .apb4_prdata_23_ (apb4_prdata[23]), + .apb4_prdata_24_ (apb4_prdata[24]), + .apb4_prdata_25_ (apb4_prdata[25]), + .apb4_prdata_26_ (apb4_prdata[26]), + .apb4_prdata_27_ (apb4_prdata[27]), + .apb4_prdata_28_ (apb4_prdata[28]), + .apb4_prdata_29_ (apb4_prdata[29]), + .apb4_prdata_30_ (apb4_prdata[30]), + .apb4_prdata_31_ (apb4_prdata[31]), + .apb4_pslverr (apb4_pslverr), + .ga2d_axi4_awid_0_ (ga2d_axi4_awid[0]), + .ga2d_axi4_awid_1_ (ga2d_axi4_awid[1]), + .ga2d_axi4_awid_2_ (ga2d_axi4_awid[2]), + .ga2d_axi4_awid_3_ (ga2d_axi4_awid[3]), + .ga2d_axi4_awaddr_0_ (ga2d_axi4_awaddr[0]), + .ga2d_axi4_awaddr_1_ (ga2d_axi4_awaddr[1]), + .ga2d_axi4_awaddr_2_ (ga2d_axi4_awaddr[2]), + .ga2d_axi4_awaddr_3_ (ga2d_axi4_awaddr[3]), + .ga2d_axi4_awaddr_4_ (ga2d_axi4_awaddr[4]), + .ga2d_axi4_awaddr_5_ (ga2d_axi4_awaddr[5]), + .ga2d_axi4_awaddr_6_ (ga2d_axi4_awaddr[6]), + .ga2d_axi4_awaddr_7_ (ga2d_axi4_awaddr[7]), + .ga2d_axi4_awaddr_8_ (ga2d_axi4_awaddr[8]), + .ga2d_axi4_awaddr_9_ (ga2d_axi4_awaddr[9]), + .ga2d_axi4_awaddr_10_ (ga2d_axi4_awaddr[10]), + .ga2d_axi4_awaddr_11_ (ga2d_axi4_awaddr[11]), + .ga2d_axi4_awaddr_12_ (ga2d_axi4_awaddr[12]), + .ga2d_axi4_awaddr_13_ (ga2d_axi4_awaddr[13]), + .ga2d_axi4_awaddr_14_ (ga2d_axi4_awaddr[14]), + .ga2d_axi4_awaddr_15_ (ga2d_axi4_awaddr[15]), + .ga2d_axi4_awaddr_16_ (ga2d_axi4_awaddr[16]), + .ga2d_axi4_awaddr_17_ (ga2d_axi4_awaddr[17]), + .ga2d_axi4_awaddr_18_ (ga2d_axi4_awaddr[18]), + .ga2d_axi4_awaddr_19_ (ga2d_axi4_awaddr[19]), + .ga2d_axi4_awaddr_20_ (ga2d_axi4_awaddr[20]), + .ga2d_axi4_awaddr_21_ (ga2d_axi4_awaddr[21]), + .ga2d_axi4_awaddr_22_ (ga2d_axi4_awaddr[22]), + .ga2d_axi4_awaddr_23_ (ga2d_axi4_awaddr[23]), + .ga2d_axi4_awaddr_24_ (ga2d_axi4_awaddr[24]), + .ga2d_axi4_awaddr_25_ (ga2d_axi4_awaddr[25]), + .ga2d_axi4_awaddr_26_ (ga2d_axi4_awaddr[26]), + .ga2d_axi4_awaddr_27_ (ga2d_axi4_awaddr[27]), + .ga2d_axi4_awaddr_28_ (ga2d_axi4_awaddr[28]), + .ga2d_axi4_awaddr_29_ (ga2d_axi4_awaddr[29]), + .ga2d_axi4_awaddr_30_ (ga2d_axi4_awaddr[30]), + .ga2d_axi4_awaddr_31_ (ga2d_axi4_awaddr[31]), + .ga2d_axi4_awlen_0_ (ga2d_axi4_awlen[0]), + .ga2d_axi4_awlen_1_ (ga2d_axi4_awlen[1]), + .ga2d_axi4_awlen_2_ (ga2d_axi4_awlen[2]), + .ga2d_axi4_awlen_3_ (ga2d_axi4_awlen[3]), + .ga2d_axi4_awlen_4_ (ga2d_axi4_awlen[4]), + .ga2d_axi4_awlen_5_ (ga2d_axi4_awlen[5]), + .ga2d_axi4_awlen_6_ (ga2d_axi4_awlen[6]), + .ga2d_axi4_awlen_7_ (ga2d_axi4_awlen[7]), + .ga2d_axi4_awsize_0_ (ga2d_axi4_awsize[0]), + .ga2d_axi4_awsize_1_ (ga2d_axi4_awsize[1]), + .ga2d_axi4_awsize_2_ (ga2d_axi4_awsize[2]), + .ga2d_axi4_awburst_0_ (ga2d_axi4_awburst[0]), + .ga2d_axi4_awburst_1_ (ga2d_axi4_awburst[1]), + .ga2d_axi4_awlock (ga2d_axi4_awlock), + .ga2d_axi4_awcache_0_ (ga2d_axi4_awcache[0]), + .ga2d_axi4_awcache_1_ (ga2d_axi4_awcache[1]), + .ga2d_axi4_awcache_2_ (ga2d_axi4_awcache[2]), + .ga2d_axi4_awcache_3_ (ga2d_axi4_awcache[3]), + .ga2d_axi4_awprot_0_ (ga2d_axi4_awprot[0]), + .ga2d_axi4_awprot_1_ (ga2d_axi4_awprot[1]), + .ga2d_axi4_awprot_2_ (ga2d_axi4_awprot[2]), + .ga2d_axi4_awqos_0_ (ga2d_axi4_awqos[0]), + .ga2d_axi4_awqos_1_ (ga2d_axi4_awqos[1]), + .ga2d_axi4_awqos_2_ (ga2d_axi4_awqos[2]), + .ga2d_axi4_awqos_3_ (ga2d_axi4_awqos[3]), .ga2d_axi4_awregion_0_(ga2d_axi4_awregion[0]), .ga2d_axi4_awregion_1_(ga2d_axi4_awregion[1]), .ga2d_axi4_awregion_2_(ga2d_axi4_awregion[2]), .ga2d_axi4_awregion_3_(ga2d_axi4_awregion[3]), - .ga2d_axi4_awuser_0_(ga2d_axi4_awuser[0]), - .ga2d_axi4_awuser_1_(ga2d_axi4_awuser[1]), - .ga2d_axi4_awuser_2_(ga2d_axi4_awuser[2]), - .ga2d_axi4_awuser_3_(ga2d_axi4_awuser[3]), - .ga2d_axi4_awvalid(ga2d_axi4_awvalid), - .ga2d_axi4_awready(ga2d_axi4_awready), - .ga2d_axi4_wdata_0_(ga2d_axi4_wdata[0]), - .ga2d_axi4_wdata_1_(ga2d_axi4_wdata[1]), - .ga2d_axi4_wdata_2_(ga2d_axi4_wdata[2]), - .ga2d_axi4_wdata_3_(ga2d_axi4_wdata[3]), - .ga2d_axi4_wdata_4_(ga2d_axi4_wdata[4]), - .ga2d_axi4_wdata_5_(ga2d_axi4_wdata[5]), - .ga2d_axi4_wdata_6_(ga2d_axi4_wdata[6]), - .ga2d_axi4_wdata_7_(ga2d_axi4_wdata[7]), - .ga2d_axi4_wdata_8_(ga2d_axi4_wdata[8]), - .ga2d_axi4_wdata_9_(ga2d_axi4_wdata[9]), - .ga2d_axi4_wdata_10_(ga2d_axi4_wdata[10]), - .ga2d_axi4_wdata_11_(ga2d_axi4_wdata[11]), - .ga2d_axi4_wdata_12_(ga2d_axi4_wdata[12]), - .ga2d_axi4_wdata_13_(ga2d_axi4_wdata[13]), - .ga2d_axi4_wdata_14_(ga2d_axi4_wdata[14]), - .ga2d_axi4_wdata_15_(ga2d_axi4_wdata[15]), - .ga2d_axi4_wdata_16_(ga2d_axi4_wdata[16]), - .ga2d_axi4_wdata_17_(ga2d_axi4_wdata[17]), - .ga2d_axi4_wdata_18_(ga2d_axi4_wdata[18]), - .ga2d_axi4_wdata_19_(ga2d_axi4_wdata[19]), - .ga2d_axi4_wdata_20_(ga2d_axi4_wdata[20]), - .ga2d_axi4_wdata_21_(ga2d_axi4_wdata[21]), - .ga2d_axi4_wdata_22_(ga2d_axi4_wdata[22]), - .ga2d_axi4_wdata_23_(ga2d_axi4_wdata[23]), - .ga2d_axi4_wdata_24_(ga2d_axi4_wdata[24]), - .ga2d_axi4_wdata_25_(ga2d_axi4_wdata[25]), - .ga2d_axi4_wdata_26_(ga2d_axi4_wdata[26]), - .ga2d_axi4_wdata_27_(ga2d_axi4_wdata[27]), - .ga2d_axi4_wdata_28_(ga2d_axi4_wdata[28]), - .ga2d_axi4_wdata_29_(ga2d_axi4_wdata[29]), - .ga2d_axi4_wdata_30_(ga2d_axi4_wdata[30]), - .ga2d_axi4_wdata_31_(ga2d_axi4_wdata[31]), - .ga2d_axi4_wdata_32_(ga2d_axi4_wdata[32]), - .ga2d_axi4_wdata_33_(ga2d_axi4_wdata[33]), - .ga2d_axi4_wdata_34_(ga2d_axi4_wdata[34]), - .ga2d_axi4_wdata_35_(ga2d_axi4_wdata[35]), - .ga2d_axi4_wdata_36_(ga2d_axi4_wdata[36]), - .ga2d_axi4_wdata_37_(ga2d_axi4_wdata[37]), - .ga2d_axi4_wdata_38_(ga2d_axi4_wdata[38]), - .ga2d_axi4_wdata_39_(ga2d_axi4_wdata[39]), - .ga2d_axi4_wdata_40_(ga2d_axi4_wdata[40]), - .ga2d_axi4_wdata_41_(ga2d_axi4_wdata[41]), - .ga2d_axi4_wdata_42_(ga2d_axi4_wdata[42]), - .ga2d_axi4_wdata_43_(ga2d_axi4_wdata[43]), - .ga2d_axi4_wdata_44_(ga2d_axi4_wdata[44]), - .ga2d_axi4_wdata_45_(ga2d_axi4_wdata[45]), - .ga2d_axi4_wdata_46_(ga2d_axi4_wdata[46]), - .ga2d_axi4_wdata_47_(ga2d_axi4_wdata[47]), - .ga2d_axi4_wdata_48_(ga2d_axi4_wdata[48]), - .ga2d_axi4_wdata_49_(ga2d_axi4_wdata[49]), - .ga2d_axi4_wdata_50_(ga2d_axi4_wdata[50]), - .ga2d_axi4_wdata_51_(ga2d_axi4_wdata[51]), - .ga2d_axi4_wdata_52_(ga2d_axi4_wdata[52]), - .ga2d_axi4_wdata_53_(ga2d_axi4_wdata[53]), - .ga2d_axi4_wdata_54_(ga2d_axi4_wdata[54]), - .ga2d_axi4_wdata_55_(ga2d_axi4_wdata[55]), - .ga2d_axi4_wdata_56_(ga2d_axi4_wdata[56]), - .ga2d_axi4_wdata_57_(ga2d_axi4_wdata[57]), - .ga2d_axi4_wdata_58_(ga2d_axi4_wdata[58]), - .ga2d_axi4_wdata_59_(ga2d_axi4_wdata[59]), - .ga2d_axi4_wdata_60_(ga2d_axi4_wdata[60]), - .ga2d_axi4_wdata_61_(ga2d_axi4_wdata[61]), - .ga2d_axi4_wdata_62_(ga2d_axi4_wdata[62]), - .ga2d_axi4_wdata_63_(ga2d_axi4_wdata[63]), - .ga2d_axi4_wstrb_0_(ga2d_axi4_wstrb[0]), - .ga2d_axi4_wstrb_1_(ga2d_axi4_wstrb[1]), - .ga2d_axi4_wstrb_2_(ga2d_axi4_wstrb[2]), - .ga2d_axi4_wstrb_3_(ga2d_axi4_wstrb[3]), - .ga2d_axi4_wstrb_4_(ga2d_axi4_wstrb[4]), - .ga2d_axi4_wstrb_5_(ga2d_axi4_wstrb[5]), - .ga2d_axi4_wstrb_6_(ga2d_axi4_wstrb[6]), - .ga2d_axi4_wstrb_7_(ga2d_axi4_wstrb[7]), - .ga2d_axi4_wlast(ga2d_axi4_wlast), - .ga2d_axi4_wuser_0_(ga2d_axi4_wuser[0]), - .ga2d_axi4_wuser_1_(ga2d_axi4_wuser[1]), - .ga2d_axi4_wuser_2_(ga2d_axi4_wuser[2]), - .ga2d_axi4_wuser_3_(ga2d_axi4_wuser[3]), - .ga2d_axi4_wvalid(ga2d_axi4_wvalid), - .ga2d_axi4_wready(ga2d_axi4_wready), - .ga2d_axi4_bid_0_(ga2d_axi4_bid[0]), - .ga2d_axi4_bid_1_(ga2d_axi4_bid[1]), - .ga2d_axi4_bid_2_(ga2d_axi4_bid[2]), - .ga2d_axi4_bid_3_(ga2d_axi4_bid[3]), - .ga2d_axi4_bresp_0_(ga2d_axi4_bresp[0]), - .ga2d_axi4_bresp_1_(ga2d_axi4_bresp[1]), - .ga2d_axi4_buser_0_(ga2d_axi4_buser[0]), - .ga2d_axi4_buser_1_(ga2d_axi4_buser[1]), - .ga2d_axi4_buser_2_(ga2d_axi4_buser[2]), - .ga2d_axi4_buser_3_(ga2d_axi4_buser[3]), - .ga2d_axi4_bvalid(ga2d_axi4_bvalid), - .ga2d_axi4_bready(ga2d_axi4_bready), - .ga2d_axi4_arid_0_(ga2d_axi4_arid[0]), - .ga2d_axi4_arid_1_(ga2d_axi4_arid[1]), - .ga2d_axi4_arid_2_(ga2d_axi4_arid[2]), - .ga2d_axi4_arid_3_(ga2d_axi4_arid[3]), - .ga2d_axi4_araddr_0_(ga2d_axi4_araddr[0]), - .ga2d_axi4_araddr_1_(ga2d_axi4_araddr[1]), - .ga2d_axi4_araddr_2_(ga2d_axi4_araddr[2]), - .ga2d_axi4_araddr_3_(ga2d_axi4_araddr[3]), - .ga2d_axi4_araddr_4_(ga2d_axi4_araddr[4]), - .ga2d_axi4_araddr_5_(ga2d_axi4_araddr[5]), - .ga2d_axi4_araddr_6_(ga2d_axi4_araddr[6]), - .ga2d_axi4_araddr_7_(ga2d_axi4_araddr[7]), - .ga2d_axi4_araddr_8_(ga2d_axi4_araddr[8]), - .ga2d_axi4_araddr_9_(ga2d_axi4_araddr[9]), - .ga2d_axi4_araddr_10_(ga2d_axi4_araddr[10]), - .ga2d_axi4_araddr_11_(ga2d_axi4_araddr[11]), - .ga2d_axi4_araddr_12_(ga2d_axi4_araddr[12]), - .ga2d_axi4_araddr_13_(ga2d_axi4_araddr[13]), - .ga2d_axi4_araddr_14_(ga2d_axi4_araddr[14]), - .ga2d_axi4_araddr_15_(ga2d_axi4_araddr[15]), - .ga2d_axi4_araddr_16_(ga2d_axi4_araddr[16]), - .ga2d_axi4_araddr_17_(ga2d_axi4_araddr[17]), - .ga2d_axi4_araddr_18_(ga2d_axi4_araddr[18]), - .ga2d_axi4_araddr_19_(ga2d_axi4_araddr[19]), - .ga2d_axi4_araddr_20_(ga2d_axi4_araddr[20]), - .ga2d_axi4_araddr_21_(ga2d_axi4_araddr[21]), - .ga2d_axi4_araddr_22_(ga2d_axi4_araddr[22]), - .ga2d_axi4_araddr_23_(ga2d_axi4_araddr[23]), - .ga2d_axi4_araddr_24_(ga2d_axi4_araddr[24]), - .ga2d_axi4_araddr_25_(ga2d_axi4_araddr[25]), - .ga2d_axi4_araddr_26_(ga2d_axi4_araddr[26]), - .ga2d_axi4_araddr_27_(ga2d_axi4_araddr[27]), - .ga2d_axi4_araddr_28_(ga2d_axi4_araddr[28]), - .ga2d_axi4_araddr_29_(ga2d_axi4_araddr[29]), - .ga2d_axi4_araddr_30_(ga2d_axi4_araddr[30]), - .ga2d_axi4_araddr_31_(ga2d_axi4_araddr[31]), - .ga2d_axi4_arlen_0_(ga2d_axi4_arlen[0]), - .ga2d_axi4_arlen_1_(ga2d_axi4_arlen[1]), - .ga2d_axi4_arlen_2_(ga2d_axi4_arlen[2]), - .ga2d_axi4_arlen_3_(ga2d_axi4_arlen[3]), - .ga2d_axi4_arlen_4_(ga2d_axi4_arlen[4]), - .ga2d_axi4_arlen_5_(ga2d_axi4_arlen[5]), - .ga2d_axi4_arlen_6_(ga2d_axi4_arlen[6]), - .ga2d_axi4_arlen_7_(ga2d_axi4_arlen[7]), - .ga2d_axi4_arsize_0_(ga2d_axi4_arsize[0]), - .ga2d_axi4_arsize_1_(ga2d_axi4_arsize[1]), - .ga2d_axi4_arsize_2_(ga2d_axi4_arsize[2]), - .ga2d_axi4_arburst_0_(ga2d_axi4_arburst[0]), - .ga2d_axi4_arburst_1_(ga2d_axi4_arburst[1]), - .ga2d_axi4_arlock(ga2d_axi4_arlock), - .ga2d_axi4_arcache_0_(ga2d_axi4_arcache[0]), - .ga2d_axi4_arcache_1_(ga2d_axi4_arcache[1]), - .ga2d_axi4_arcache_2_(ga2d_axi4_arcache[2]), - .ga2d_axi4_arcache_3_(ga2d_axi4_arcache[3]), - .ga2d_axi4_arprot_0_(ga2d_axi4_arprot[0]), - .ga2d_axi4_arprot_1_(ga2d_axi4_arprot[1]), - .ga2d_axi4_arprot_2_(ga2d_axi4_arprot[2]), - .ga2d_axi4_arqos_0_(ga2d_axi4_arqos[0]), - .ga2d_axi4_arqos_1_(ga2d_axi4_arqos[1]), - .ga2d_axi4_arqos_2_(ga2d_axi4_arqos[2]), - .ga2d_axi4_arqos_3_(ga2d_axi4_arqos[3]), + .ga2d_axi4_awuser_0_ (ga2d_axi4_awuser[0]), + .ga2d_axi4_awuser_1_ (ga2d_axi4_awuser[1]), + .ga2d_axi4_awuser_2_ (ga2d_axi4_awuser[2]), + .ga2d_axi4_awuser_3_ (ga2d_axi4_awuser[3]), + .ga2d_axi4_awvalid (ga2d_axi4_awvalid), + .ga2d_axi4_awready (ga2d_axi4_awready), + .ga2d_axi4_wdata_0_ (ga2d_axi4_wdata[0]), + .ga2d_axi4_wdata_1_ (ga2d_axi4_wdata[1]), + .ga2d_axi4_wdata_2_ (ga2d_axi4_wdata[2]), + .ga2d_axi4_wdata_3_ (ga2d_axi4_wdata[3]), + .ga2d_axi4_wdata_4_ (ga2d_axi4_wdata[4]), + .ga2d_axi4_wdata_5_ (ga2d_axi4_wdata[5]), + .ga2d_axi4_wdata_6_ (ga2d_axi4_wdata[6]), + .ga2d_axi4_wdata_7_ (ga2d_axi4_wdata[7]), + .ga2d_axi4_wdata_8_ (ga2d_axi4_wdata[8]), + .ga2d_axi4_wdata_9_ (ga2d_axi4_wdata[9]), + .ga2d_axi4_wdata_10_ (ga2d_axi4_wdata[10]), + .ga2d_axi4_wdata_11_ (ga2d_axi4_wdata[11]), + .ga2d_axi4_wdata_12_ (ga2d_axi4_wdata[12]), + .ga2d_axi4_wdata_13_ (ga2d_axi4_wdata[13]), + .ga2d_axi4_wdata_14_ (ga2d_axi4_wdata[14]), + .ga2d_axi4_wdata_15_ (ga2d_axi4_wdata[15]), + .ga2d_axi4_wdata_16_ (ga2d_axi4_wdata[16]), + .ga2d_axi4_wdata_17_ (ga2d_axi4_wdata[17]), + .ga2d_axi4_wdata_18_ (ga2d_axi4_wdata[18]), + .ga2d_axi4_wdata_19_ (ga2d_axi4_wdata[19]), + .ga2d_axi4_wdata_20_ (ga2d_axi4_wdata[20]), + .ga2d_axi4_wdata_21_ (ga2d_axi4_wdata[21]), + .ga2d_axi4_wdata_22_ (ga2d_axi4_wdata[22]), + .ga2d_axi4_wdata_23_ (ga2d_axi4_wdata[23]), + .ga2d_axi4_wdata_24_ (ga2d_axi4_wdata[24]), + .ga2d_axi4_wdata_25_ (ga2d_axi4_wdata[25]), + .ga2d_axi4_wdata_26_ (ga2d_axi4_wdata[26]), + .ga2d_axi4_wdata_27_ (ga2d_axi4_wdata[27]), + .ga2d_axi4_wdata_28_ (ga2d_axi4_wdata[28]), + .ga2d_axi4_wdata_29_ (ga2d_axi4_wdata[29]), + .ga2d_axi4_wdata_30_ (ga2d_axi4_wdata[30]), + .ga2d_axi4_wdata_31_ (ga2d_axi4_wdata[31]), + .ga2d_axi4_wdata_32_ (ga2d_axi4_wdata[32]), + .ga2d_axi4_wdata_33_ (ga2d_axi4_wdata[33]), + .ga2d_axi4_wdata_34_ (ga2d_axi4_wdata[34]), + .ga2d_axi4_wdata_35_ (ga2d_axi4_wdata[35]), + .ga2d_axi4_wdata_36_ (ga2d_axi4_wdata[36]), + .ga2d_axi4_wdata_37_ (ga2d_axi4_wdata[37]), + .ga2d_axi4_wdata_38_ (ga2d_axi4_wdata[38]), + .ga2d_axi4_wdata_39_ (ga2d_axi4_wdata[39]), + .ga2d_axi4_wdata_40_ (ga2d_axi4_wdata[40]), + .ga2d_axi4_wdata_41_ (ga2d_axi4_wdata[41]), + .ga2d_axi4_wdata_42_ (ga2d_axi4_wdata[42]), + .ga2d_axi4_wdata_43_ (ga2d_axi4_wdata[43]), + .ga2d_axi4_wdata_44_ (ga2d_axi4_wdata[44]), + .ga2d_axi4_wdata_45_ (ga2d_axi4_wdata[45]), + .ga2d_axi4_wdata_46_ (ga2d_axi4_wdata[46]), + .ga2d_axi4_wdata_47_ (ga2d_axi4_wdata[47]), + .ga2d_axi4_wdata_48_ (ga2d_axi4_wdata[48]), + .ga2d_axi4_wdata_49_ (ga2d_axi4_wdata[49]), + .ga2d_axi4_wdata_50_ (ga2d_axi4_wdata[50]), + .ga2d_axi4_wdata_51_ (ga2d_axi4_wdata[51]), + .ga2d_axi4_wdata_52_ (ga2d_axi4_wdata[52]), + .ga2d_axi4_wdata_53_ (ga2d_axi4_wdata[53]), + .ga2d_axi4_wdata_54_ (ga2d_axi4_wdata[54]), + .ga2d_axi4_wdata_55_ (ga2d_axi4_wdata[55]), + .ga2d_axi4_wdata_56_ (ga2d_axi4_wdata[56]), + .ga2d_axi4_wdata_57_ (ga2d_axi4_wdata[57]), + .ga2d_axi4_wdata_58_ (ga2d_axi4_wdata[58]), + .ga2d_axi4_wdata_59_ (ga2d_axi4_wdata[59]), + .ga2d_axi4_wdata_60_ (ga2d_axi4_wdata[60]), + .ga2d_axi4_wdata_61_ (ga2d_axi4_wdata[61]), + .ga2d_axi4_wdata_62_ (ga2d_axi4_wdata[62]), + .ga2d_axi4_wdata_63_ (ga2d_axi4_wdata[63]), + .ga2d_axi4_wstrb_0_ (ga2d_axi4_wstrb[0]), + .ga2d_axi4_wstrb_1_ (ga2d_axi4_wstrb[1]), + .ga2d_axi4_wstrb_2_ (ga2d_axi4_wstrb[2]), + .ga2d_axi4_wstrb_3_ (ga2d_axi4_wstrb[3]), + .ga2d_axi4_wstrb_4_ (ga2d_axi4_wstrb[4]), + .ga2d_axi4_wstrb_5_ (ga2d_axi4_wstrb[5]), + .ga2d_axi4_wstrb_6_ (ga2d_axi4_wstrb[6]), + .ga2d_axi4_wstrb_7_ (ga2d_axi4_wstrb[7]), + .ga2d_axi4_wlast (ga2d_axi4_wlast), + .ga2d_axi4_wuser_0_ (ga2d_axi4_wuser[0]), + .ga2d_axi4_wuser_1_ (ga2d_axi4_wuser[1]), + .ga2d_axi4_wuser_2_ (ga2d_axi4_wuser[2]), + .ga2d_axi4_wuser_3_ (ga2d_axi4_wuser[3]), + .ga2d_axi4_wvalid (ga2d_axi4_wvalid), + .ga2d_axi4_wready (ga2d_axi4_wready), + .ga2d_axi4_bid_0_ (ga2d_axi4_bid[0]), + .ga2d_axi4_bid_1_ (ga2d_axi4_bid[1]), + .ga2d_axi4_bid_2_ (ga2d_axi4_bid[2]), + .ga2d_axi4_bid_3_ (ga2d_axi4_bid[3]), + .ga2d_axi4_bresp_0_ (ga2d_axi4_bresp[0]), + .ga2d_axi4_bresp_1_ (ga2d_axi4_bresp[1]), + .ga2d_axi4_buser_0_ (ga2d_axi4_buser[0]), + .ga2d_axi4_buser_1_ (ga2d_axi4_buser[1]), + .ga2d_axi4_buser_2_ (ga2d_axi4_buser[2]), + .ga2d_axi4_buser_3_ (ga2d_axi4_buser[3]), + .ga2d_axi4_bvalid (ga2d_axi4_bvalid), + .ga2d_axi4_bready (ga2d_axi4_bready), + .ga2d_axi4_arid_0_ (ga2d_axi4_arid[0]), + .ga2d_axi4_arid_1_ (ga2d_axi4_arid[1]), + .ga2d_axi4_arid_2_ (ga2d_axi4_arid[2]), + .ga2d_axi4_arid_3_ (ga2d_axi4_arid[3]), + .ga2d_axi4_araddr_0_ (ga2d_axi4_araddr[0]), + .ga2d_axi4_araddr_1_ (ga2d_axi4_araddr[1]), + .ga2d_axi4_araddr_2_ (ga2d_axi4_araddr[2]), + .ga2d_axi4_araddr_3_ (ga2d_axi4_araddr[3]), + .ga2d_axi4_araddr_4_ (ga2d_axi4_araddr[4]), + .ga2d_axi4_araddr_5_ (ga2d_axi4_araddr[5]), + .ga2d_axi4_araddr_6_ (ga2d_axi4_araddr[6]), + .ga2d_axi4_araddr_7_ (ga2d_axi4_araddr[7]), + .ga2d_axi4_araddr_8_ (ga2d_axi4_araddr[8]), + .ga2d_axi4_araddr_9_ (ga2d_axi4_araddr[9]), + .ga2d_axi4_araddr_10_ (ga2d_axi4_araddr[10]), + .ga2d_axi4_araddr_11_ (ga2d_axi4_araddr[11]), + .ga2d_axi4_araddr_12_ (ga2d_axi4_araddr[12]), + .ga2d_axi4_araddr_13_ (ga2d_axi4_araddr[13]), + .ga2d_axi4_araddr_14_ (ga2d_axi4_araddr[14]), + .ga2d_axi4_araddr_15_ (ga2d_axi4_araddr[15]), + .ga2d_axi4_araddr_16_ (ga2d_axi4_araddr[16]), + .ga2d_axi4_araddr_17_ (ga2d_axi4_araddr[17]), + .ga2d_axi4_araddr_18_ (ga2d_axi4_araddr[18]), + .ga2d_axi4_araddr_19_ (ga2d_axi4_araddr[19]), + .ga2d_axi4_araddr_20_ (ga2d_axi4_araddr[20]), + .ga2d_axi4_araddr_21_ (ga2d_axi4_araddr[21]), + .ga2d_axi4_araddr_22_ (ga2d_axi4_araddr[22]), + .ga2d_axi4_araddr_23_ (ga2d_axi4_araddr[23]), + .ga2d_axi4_araddr_24_ (ga2d_axi4_araddr[24]), + .ga2d_axi4_araddr_25_ (ga2d_axi4_araddr[25]), + .ga2d_axi4_araddr_26_ (ga2d_axi4_araddr[26]), + .ga2d_axi4_araddr_27_ (ga2d_axi4_araddr[27]), + .ga2d_axi4_araddr_28_ (ga2d_axi4_araddr[28]), + .ga2d_axi4_araddr_29_ (ga2d_axi4_araddr[29]), + .ga2d_axi4_araddr_30_ (ga2d_axi4_araddr[30]), + .ga2d_axi4_araddr_31_ (ga2d_axi4_araddr[31]), + .ga2d_axi4_arlen_0_ (ga2d_axi4_arlen[0]), + .ga2d_axi4_arlen_1_ (ga2d_axi4_arlen[1]), + .ga2d_axi4_arlen_2_ (ga2d_axi4_arlen[2]), + .ga2d_axi4_arlen_3_ (ga2d_axi4_arlen[3]), + .ga2d_axi4_arlen_4_ (ga2d_axi4_arlen[4]), + .ga2d_axi4_arlen_5_ (ga2d_axi4_arlen[5]), + .ga2d_axi4_arlen_6_ (ga2d_axi4_arlen[6]), + .ga2d_axi4_arlen_7_ (ga2d_axi4_arlen[7]), + .ga2d_axi4_arsize_0_ (ga2d_axi4_arsize[0]), + .ga2d_axi4_arsize_1_ (ga2d_axi4_arsize[1]), + .ga2d_axi4_arsize_2_ (ga2d_axi4_arsize[2]), + .ga2d_axi4_arburst_0_ (ga2d_axi4_arburst[0]), + .ga2d_axi4_arburst_1_ (ga2d_axi4_arburst[1]), + .ga2d_axi4_arlock (ga2d_axi4_arlock), + .ga2d_axi4_arcache_0_ (ga2d_axi4_arcache[0]), + .ga2d_axi4_arcache_1_ (ga2d_axi4_arcache[1]), + .ga2d_axi4_arcache_2_ (ga2d_axi4_arcache[2]), + .ga2d_axi4_arcache_3_ (ga2d_axi4_arcache[3]), + .ga2d_axi4_arprot_0_ (ga2d_axi4_arprot[0]), + .ga2d_axi4_arprot_1_ (ga2d_axi4_arprot[1]), + .ga2d_axi4_arprot_2_ (ga2d_axi4_arprot[2]), + .ga2d_axi4_arqos_0_ (ga2d_axi4_arqos[0]), + .ga2d_axi4_arqos_1_ (ga2d_axi4_arqos[1]), + .ga2d_axi4_arqos_2_ (ga2d_axi4_arqos[2]), + .ga2d_axi4_arqos_3_ (ga2d_axi4_arqos[3]), .ga2d_axi4_arregion_0_(ga2d_axi4_arregion[0]), .ga2d_axi4_arregion_1_(ga2d_axi4_arregion[1]), .ga2d_axi4_arregion_2_(ga2d_axi4_arregion[2]), .ga2d_axi4_arregion_3_(ga2d_axi4_arregion[3]), - .ga2d_axi4_aruser_0_(ga2d_axi4_aruser[0]), - .ga2d_axi4_aruser_1_(ga2d_axi4_aruser[1]), - .ga2d_axi4_aruser_2_(ga2d_axi4_aruser[2]), - .ga2d_axi4_aruser_3_(ga2d_axi4_aruser[3]), - .ga2d_axi4_arvalid(ga2d_axi4_arvalid), - .ga2d_axi4_arready(ga2d_axi4_arready), - .ga2d_axi4_rid_0_(ga2d_axi4_rid[0]), - .ga2d_axi4_rid_1_(ga2d_axi4_rid[1]), - .ga2d_axi4_rid_2_(ga2d_axi4_rid[2]), - .ga2d_axi4_rid_3_(ga2d_axi4_rid[3]), - .ga2d_axi4_rdata_0_(ga2d_axi4_rdata[0]), - .ga2d_axi4_rdata_1_(ga2d_axi4_rdata[1]), - .ga2d_axi4_rdata_2_(ga2d_axi4_rdata[2]), - .ga2d_axi4_rdata_3_(ga2d_axi4_rdata[3]), - .ga2d_axi4_rdata_4_(ga2d_axi4_rdata[4]), - .ga2d_axi4_rdata_5_(ga2d_axi4_rdata[5]), - .ga2d_axi4_rdata_6_(ga2d_axi4_rdata[6]), - .ga2d_axi4_rdata_7_(ga2d_axi4_rdata[7]), - .ga2d_axi4_rdata_8_(ga2d_axi4_rdata[8]), - .ga2d_axi4_rdata_9_(ga2d_axi4_rdata[9]), - .ga2d_axi4_rdata_10_(ga2d_axi4_rdata[10]), - .ga2d_axi4_rdata_11_(ga2d_axi4_rdata[11]), - .ga2d_axi4_rdata_12_(ga2d_axi4_rdata[12]), - .ga2d_axi4_rdata_13_(ga2d_axi4_rdata[13]), - .ga2d_axi4_rdata_14_(ga2d_axi4_rdata[14]), - .ga2d_axi4_rdata_15_(ga2d_axi4_rdata[15]), - .ga2d_axi4_rdata_16_(ga2d_axi4_rdata[16]), - .ga2d_axi4_rdata_17_(ga2d_axi4_rdata[17]), - .ga2d_axi4_rdata_18_(ga2d_axi4_rdata[18]), - .ga2d_axi4_rdata_19_(ga2d_axi4_rdata[19]), - .ga2d_axi4_rdata_20_(ga2d_axi4_rdata[20]), - .ga2d_axi4_rdata_21_(ga2d_axi4_rdata[21]), - .ga2d_axi4_rdata_22_(ga2d_axi4_rdata[22]), - .ga2d_axi4_rdata_23_(ga2d_axi4_rdata[23]), - .ga2d_axi4_rdata_24_(ga2d_axi4_rdata[24]), - .ga2d_axi4_rdata_25_(ga2d_axi4_rdata[25]), - .ga2d_axi4_rdata_26_(ga2d_axi4_rdata[26]), - .ga2d_axi4_rdata_27_(ga2d_axi4_rdata[27]), - .ga2d_axi4_rdata_28_(ga2d_axi4_rdata[28]), - .ga2d_axi4_rdata_29_(ga2d_axi4_rdata[29]), - .ga2d_axi4_rdata_30_(ga2d_axi4_rdata[30]), - .ga2d_axi4_rdata_31_(ga2d_axi4_rdata[31]), - .ga2d_axi4_rdata_32_(ga2d_axi4_rdata[32]), - .ga2d_axi4_rdata_33_(ga2d_axi4_rdata[33]), - .ga2d_axi4_rdata_34_(ga2d_axi4_rdata[34]), - .ga2d_axi4_rdata_35_(ga2d_axi4_rdata[35]), - .ga2d_axi4_rdata_36_(ga2d_axi4_rdata[36]), - .ga2d_axi4_rdata_37_(ga2d_axi4_rdata[37]), - .ga2d_axi4_rdata_38_(ga2d_axi4_rdata[38]), - .ga2d_axi4_rdata_39_(ga2d_axi4_rdata[39]), - .ga2d_axi4_rdata_40_(ga2d_axi4_rdata[40]), - .ga2d_axi4_rdata_41_(ga2d_axi4_rdata[41]), - .ga2d_axi4_rdata_42_(ga2d_axi4_rdata[42]), - .ga2d_axi4_rdata_43_(ga2d_axi4_rdata[43]), - .ga2d_axi4_rdata_44_(ga2d_axi4_rdata[44]), - .ga2d_axi4_rdata_45_(ga2d_axi4_rdata[45]), - .ga2d_axi4_rdata_46_(ga2d_axi4_rdata[46]), - .ga2d_axi4_rdata_47_(ga2d_axi4_rdata[47]), - .ga2d_axi4_rdata_48_(ga2d_axi4_rdata[48]), - .ga2d_axi4_rdata_49_(ga2d_axi4_rdata[49]), - .ga2d_axi4_rdata_50_(ga2d_axi4_rdata[50]), - .ga2d_axi4_rdata_51_(ga2d_axi4_rdata[51]), - .ga2d_axi4_rdata_52_(ga2d_axi4_rdata[52]), - .ga2d_axi4_rdata_53_(ga2d_axi4_rdata[53]), - .ga2d_axi4_rdata_54_(ga2d_axi4_rdata[54]), - .ga2d_axi4_rdata_55_(ga2d_axi4_rdata[55]), - .ga2d_axi4_rdata_56_(ga2d_axi4_rdata[56]), - .ga2d_axi4_rdata_57_(ga2d_axi4_rdata[57]), - .ga2d_axi4_rdata_58_(ga2d_axi4_rdata[58]), - .ga2d_axi4_rdata_59_(ga2d_axi4_rdata[59]), - .ga2d_axi4_rdata_60_(ga2d_axi4_rdata[60]), - .ga2d_axi4_rdata_61_(ga2d_axi4_rdata[61]), - .ga2d_axi4_rdata_62_(ga2d_axi4_rdata[62]), - .ga2d_axi4_rdata_63_(ga2d_axi4_rdata[63]), - .ga2d_axi4_rresp_0_(ga2d_axi4_rresp[0]), - .ga2d_axi4_rresp_1_(ga2d_axi4_rresp[1]), - .ga2d_axi4_rlast(ga2d_axi4_rlast), - .ga2d_axi4_ruser_0_(ga2d_axi4_ruser[0]), - .ga2d_axi4_ruser_1_(ga2d_axi4_ruser[1]), - .ga2d_axi4_ruser_2_(ga2d_axi4_ruser[2]), - .ga2d_axi4_ruser_3_(ga2d_axi4_ruser[3]), - .ga2d_axi4_rvalid(ga2d_axi4_rvalid), - .ga2d_axi4_rready(ga2d_axi4_rready) + .ga2d_axi4_aruser_0_ (ga2d_axi4_aruser[0]), + .ga2d_axi4_aruser_1_ (ga2d_axi4_aruser[1]), + .ga2d_axi4_aruser_2_ (ga2d_axi4_aruser[2]), + .ga2d_axi4_aruser_3_ (ga2d_axi4_aruser[3]), + .ga2d_axi4_arvalid (ga2d_axi4_arvalid), + .ga2d_axi4_arready (ga2d_axi4_arready), + .ga2d_axi4_rid_0_ (ga2d_axi4_rid[0]), + .ga2d_axi4_rid_1_ (ga2d_axi4_rid[1]), + .ga2d_axi4_rid_2_ (ga2d_axi4_rid[2]), + .ga2d_axi4_rid_3_ (ga2d_axi4_rid[3]), + .ga2d_axi4_rdata_0_ (ga2d_axi4_rdata[0]), + .ga2d_axi4_rdata_1_ (ga2d_axi4_rdata[1]), + .ga2d_axi4_rdata_2_ (ga2d_axi4_rdata[2]), + .ga2d_axi4_rdata_3_ (ga2d_axi4_rdata[3]), + .ga2d_axi4_rdata_4_ (ga2d_axi4_rdata[4]), + .ga2d_axi4_rdata_5_ (ga2d_axi4_rdata[5]), + .ga2d_axi4_rdata_6_ (ga2d_axi4_rdata[6]), + .ga2d_axi4_rdata_7_ (ga2d_axi4_rdata[7]), + .ga2d_axi4_rdata_8_ (ga2d_axi4_rdata[8]), + .ga2d_axi4_rdata_9_ (ga2d_axi4_rdata[9]), + .ga2d_axi4_rdata_10_ (ga2d_axi4_rdata[10]), + .ga2d_axi4_rdata_11_ (ga2d_axi4_rdata[11]), + .ga2d_axi4_rdata_12_ (ga2d_axi4_rdata[12]), + .ga2d_axi4_rdata_13_ (ga2d_axi4_rdata[13]), + .ga2d_axi4_rdata_14_ (ga2d_axi4_rdata[14]), + .ga2d_axi4_rdata_15_ (ga2d_axi4_rdata[15]), + .ga2d_axi4_rdata_16_ (ga2d_axi4_rdata[16]), + .ga2d_axi4_rdata_17_ (ga2d_axi4_rdata[17]), + .ga2d_axi4_rdata_18_ (ga2d_axi4_rdata[18]), + .ga2d_axi4_rdata_19_ (ga2d_axi4_rdata[19]), + .ga2d_axi4_rdata_20_ (ga2d_axi4_rdata[20]), + .ga2d_axi4_rdata_21_ (ga2d_axi4_rdata[21]), + .ga2d_axi4_rdata_22_ (ga2d_axi4_rdata[22]), + .ga2d_axi4_rdata_23_ (ga2d_axi4_rdata[23]), + .ga2d_axi4_rdata_24_ (ga2d_axi4_rdata[24]), + .ga2d_axi4_rdata_25_ (ga2d_axi4_rdata[25]), + .ga2d_axi4_rdata_26_ (ga2d_axi4_rdata[26]), + .ga2d_axi4_rdata_27_ (ga2d_axi4_rdata[27]), + .ga2d_axi4_rdata_28_ (ga2d_axi4_rdata[28]), + .ga2d_axi4_rdata_29_ (ga2d_axi4_rdata[29]), + .ga2d_axi4_rdata_30_ (ga2d_axi4_rdata[30]), + .ga2d_axi4_rdata_31_ (ga2d_axi4_rdata[31]), + .ga2d_axi4_rdata_32_ (ga2d_axi4_rdata[32]), + .ga2d_axi4_rdata_33_ (ga2d_axi4_rdata[33]), + .ga2d_axi4_rdata_34_ (ga2d_axi4_rdata[34]), + .ga2d_axi4_rdata_35_ (ga2d_axi4_rdata[35]), + .ga2d_axi4_rdata_36_ (ga2d_axi4_rdata[36]), + .ga2d_axi4_rdata_37_ (ga2d_axi4_rdata[37]), + .ga2d_axi4_rdata_38_ (ga2d_axi4_rdata[38]), + .ga2d_axi4_rdata_39_ (ga2d_axi4_rdata[39]), + .ga2d_axi4_rdata_40_ (ga2d_axi4_rdata[40]), + .ga2d_axi4_rdata_41_ (ga2d_axi4_rdata[41]), + .ga2d_axi4_rdata_42_ (ga2d_axi4_rdata[42]), + .ga2d_axi4_rdata_43_ (ga2d_axi4_rdata[43]), + .ga2d_axi4_rdata_44_ (ga2d_axi4_rdata[44]), + .ga2d_axi4_rdata_45_ (ga2d_axi4_rdata[45]), + .ga2d_axi4_rdata_46_ (ga2d_axi4_rdata[46]), + .ga2d_axi4_rdata_47_ (ga2d_axi4_rdata[47]), + .ga2d_axi4_rdata_48_ (ga2d_axi4_rdata[48]), + .ga2d_axi4_rdata_49_ (ga2d_axi4_rdata[49]), + .ga2d_axi4_rdata_50_ (ga2d_axi4_rdata[50]), + .ga2d_axi4_rdata_51_ (ga2d_axi4_rdata[51]), + .ga2d_axi4_rdata_52_ (ga2d_axi4_rdata[52]), + .ga2d_axi4_rdata_53_ (ga2d_axi4_rdata[53]), + .ga2d_axi4_rdata_54_ (ga2d_axi4_rdata[54]), + .ga2d_axi4_rdata_55_ (ga2d_axi4_rdata[55]), + .ga2d_axi4_rdata_56_ (ga2d_axi4_rdata[56]), + .ga2d_axi4_rdata_57_ (ga2d_axi4_rdata[57]), + .ga2d_axi4_rdata_58_ (ga2d_axi4_rdata[58]), + .ga2d_axi4_rdata_59_ (ga2d_axi4_rdata[59]), + .ga2d_axi4_rdata_60_ (ga2d_axi4_rdata[60]), + .ga2d_axi4_rdata_61_ (ga2d_axi4_rdata[61]), + .ga2d_axi4_rdata_62_ (ga2d_axi4_rdata[62]), + .ga2d_axi4_rdata_63_ (ga2d_axi4_rdata[63]), + .ga2d_axi4_rresp_0_ (ga2d_axi4_rresp[0]), + .ga2d_axi4_rresp_1_ (ga2d_axi4_rresp[1]), + .ga2d_axi4_rlast (ga2d_axi4_rlast), + .ga2d_axi4_ruser_0_ (ga2d_axi4_ruser[0]), + .ga2d_axi4_ruser_1_ (ga2d_axi4_ruser[1]), + .ga2d_axi4_ruser_2_ (ga2d_axi4_ruser[2]), + .ga2d_axi4_ruser_3_ (ga2d_axi4_ruser[3]), + .ga2d_axi4_rvalid (ga2d_axi4_rvalid), + .ga2d_axi4_rready (ga2d_axi4_rready) ); task automatic apb_write(input logic [11:0] offset_i, input logic [31:0] value_i, @@ -1044,22 +1048,22 @@ module ga2d_netlist_tb; blue = '0; alpha = 8'hff; case (format_i) - `APB4_GA2D__FORMAT_RGB565: begin + FormatRgb565: begin red = {pixel_i[15:11], pixel_i[15:13]}; green = {pixel_i[10:5], pixel_i[10:9]}; blue = {pixel_i[4:0], pixel_i[4:2]}; end - `APB4_GA2D__FORMAT_RGB888: begin + FormatRgb888: begin red = pixel_i[7:0]; green = pixel_i[15:8]; blue = pixel_i[23:16]; end - `APB4_GA2D__FORMAT_XRGB8888: begin + FormatXrgb8888: begin red = pixel_i[23:16]; green = pixel_i[15:8]; blue = pixel_i[7:0]; end - `APB4_GA2D__FORMAT_ARGB8888: begin + FormatArgb8888: begin red = pixel_i[23:16]; green = pixel_i[15:8]; blue = pixel_i[7:0]; @@ -1076,11 +1080,11 @@ module ga2d_netlist_tb; input logic [2:0] format_i); begin case (format_i) - `APB4_GA2D__FORMAT_RGB565: return {16'd0, rgba_i[23:19], rgba_i[15:10], rgba_i[7:3]}; - `APB4_GA2D__FORMAT_RGB888: return {8'd0, rgba_i[7:0], rgba_i[15:8], rgba_i[23:16]}; - `APB4_GA2D__FORMAT_XRGB8888: return {8'hff, rgba_i[23:0]}; - `APB4_GA2D__FORMAT_ARGB8888: return rgba_i; - default: return '0; + FormatRgb565: return {16'd0, rgba_i[23:19], rgba_i[15:10], rgba_i[7:3]}; + FormatRgb888: return {8'd0, rgba_i[7:0], rgba_i[15:8], rgba_i[23:16]}; + FormatXrgb8888: return {8'hff, rgba_i[23:0]}; + FormatArgb8888: return rgba_i; + default: return '0; endcase end endfunction @@ -1107,15 +1111,14 @@ module ga2d_netlist_tb; begin foreground_rgba = reference_unpack(foreground_i, foreground_format_i); background_rgba = reference_unpack(background_i, background_format_i); - alpha_product = {8'd0, foreground_rgba[31:24]} * {8'd0, global_alpha_i}; - alpha = (alpha_product + 16'd127) / 16'd255; + alpha_product = {8'd0, foreground_rgba[31:24]} * {8'd0, global_alpha_i}; + alpha = (alpha_product + 16'd127) / 16'd255; result_rgba[31:24] = 8'hff; result_rgba[23:16] = reference_blend_channel(foreground_rgba[23:16], background_rgba[23:16], alpha); result_rgba[15:8] = reference_blend_channel(foreground_rgba[15:8], background_rgba[15:8], alpha); - result_rgba[7:0] = - reference_blend_channel(foreground_rgba[7:0], background_rgba[7:0], alpha); + result_rgba[7:0] = reference_blend_channel(foreground_rgba[7:0], background_rgba[7:0], alpha); return reference_pack(result_rgba, destination_format_i); end endfunction @@ -1126,8 +1129,7 @@ module ga2d_netlist_tb; begin destination = SramBase + 32'h200; clear_memory(8'hd3); - configure_fill(`APB4_GA2D__FORMAT_XRGB8888, 16'd3, 16'd2, destination, 32'd16, - 32'h8012_3456); + configure_fill(FormatXrgb8888, 16'd3, 16'd2, destination, 32'd16, 32'h8012_3456); start_job(); wait_for_terminal(1'b1, 1'b0, 1'b0); check_done_event(); @@ -1138,9 +1140,15 @@ module ga2d_netlist_tb; $fatal(1, "GA2D netlist FILL changed the leading guard"); end for (int unsigned pixel = 0; pixel < 3; pixel++) begin - if ({memory_byte(row + pixel * 4 + 3), memory_byte(row + pixel * 4 + 2), - memory_byte(row + pixel * 4 + 1), memory_byte(row + pixel * 4)} != - 32'hff12_3456) begin + if ({memory_byte( + row + pixel * 4 + 3 + ), memory_byte( + row + pixel * 4 + 2 + ), memory_byte( + row + pixel * 4 + 1 + ), memory_byte( + row + pixel * 4 + )} != 32'hff12_3456) begin $fatal(1, "GA2D netlist FILL pixel mismatch: line=%0d pixel=%0d", line, pixel); end end @@ -1165,11 +1173,10 @@ module ga2d_netlist_tb; for (int unsigned line = 0; line < 2; line++) begin source_row = foreground + (line * 32'd8); for (int unsigned byte_index = 0; byte_index < 6; byte_index++) begin - s_memory[(source_row + byte_index) - SramBase] = (8'h31 * line) + byte_index + 8'd2; + s_memory[(source_row+byte_index)-SramBase] = (8'h31 * line) + byte_index + 8'd2; end end - configure_copy(`APB4_GA2D__FORMAT_RGB565, 16'd3, 16'd2, foreground, 32'd8, destination, - 32'd8); + configure_copy(FormatRgb565, 16'd3, 16'd2, foreground, 32'd8, destination, 32'd8); start_job(); wait_for_terminal(1'b1, 1'b0, 1'b0); check_done_event(); @@ -1205,12 +1212,12 @@ module ga2d_netlist_tb; logic [31:0] fg_pixel; logic [31:0] bg_pixel; logic [31:0] expected; - logic [ 7:0] alpha_table[0:5]; + logic [ 7:0] alpha_table [0:5]; logic [31:0] row; begin - foreground = SramBase + 32'h800; - background = SramBase + 32'ha00; - destination = SramBase + 32'hc00; + foreground = SramBase + 32'h800; + background = SramBase + 32'ha00; + destination = SramBase + 32'hc00; alpha_table[0] = 8'h00; alpha_table[1] = 8'h01; alpha_table[2] = 8'h7f; @@ -1219,8 +1226,12 @@ module ga2d_netlist_tb; alpha_table[5] = 8'hff; clear_memory(8'hd3); for (int unsigned index = 0; index < 6; index++) begin - fg_pixel = {alpha_table[index], 8'h10 + (index * 8'h13), 8'h20 + (index * 8'h07), - 8'h30 + (index * 8'h0b)}; + fg_pixel = { + alpha_table[index], + 8'h10 + (index * 8'h13), + 8'h20 + (index * 8'h07), + 8'h30 + (index * 8'h0b) + }; bg_pixel = {16'd0, 16'h1234 + (index * 16'h0317)}; for (int unsigned byte_index = 0; byte_index < 4; byte_index++) begin s_memory[(foreground + (index / 3) * 32'd16 + (index % 3) * 4 + byte_index) - @@ -1231,23 +1242,28 @@ module ga2d_netlist_tb; SramBase] = bg_pixel[byte_index*8+:8]; end end - configure_blend(`APB4_GA2D__FORMAT_ARGB8888, `APB4_GA2D__FORMAT_RGB565, - `APB4_GA2D__FORMAT_RGB565, 16'd3, 16'd2, foreground, 32'd16, background, - 32'd8, destination, 32'd8, global_alpha_i, 32'd0); + configure_blend(FormatArgb8888, FormatRgb565, FormatRgb565, 16'd3, 16'd2, foreground, 32'd16, + background, 32'd8, destination, 32'd8, global_alpha_i, 32'd0); start_job(); wait_for_terminal(1'b1, 1'b0, 1'b0); check_done_event(); check_terminal_counters(64'd36, 64'd12, 16'd2); for (int unsigned index = 0; index < 6; index++) begin - fg_pixel = {alpha_table[index], 8'h10 + (index * 8'h13), 8'h20 + (index * 8'h07), - 8'h30 + (index * 8'h0b)}; + fg_pixel = { + alpha_table[index], + 8'h10 + (index * 8'h13), + 8'h20 + (index * 8'h07), + 8'h30 + (index * 8'h0b) + }; bg_pixel = {16'd0, 16'h1234 + (index * 16'h0317)}; - expected = reference_blend(fg_pixel, bg_pixel, global_alpha_i, - `APB4_GA2D__FORMAT_ARGB8888, `APB4_GA2D__FORMAT_RGB565, - `APB4_GA2D__FORMAT_RGB565); + expected = reference_blend(fg_pixel, bg_pixel, global_alpha_i, FormatArgb8888, FormatRgb565, + FormatRgb565); row = destination + ((index / 3) * 32'd8); - if ({memory_byte(row + (index % 3) * 2 + 1), memory_byte(row + (index % 3) * 2)} != - expected[15:0]) begin + if ({memory_byte( + row + (index % 3) * 2 + 1 + ), memory_byte( + row + (index % 3) * 2 + )} != expected[15:0]) begin $fatal(1, "GA2D netlist BLEND pixel mismatch: pixel=%0d global_alpha=%h expected=%h", index, global_alpha_i, expected[15:0]); end @@ -1267,15 +1283,14 @@ module ga2d_netlist_tb; endtask task automatic run_validation_error_case; - int unsigned ar_count_before; - int unsigned aw_count_before; - logic [31:0] error_status; - logic [31:0] error_address; + int unsigned ar_count_before; + int unsigned aw_count_before; + logic [31:0] error_status; + logic [31:0] error_address; begin ar_count_before = s_ar_count; aw_count_before = s_aw_count; - configure_fill(`APB4_GA2D__FORMAT_XRGB8888, 16'd0, 16'd1, SramBase + 32'he00, 32'd16, - 32'h8012_3456); + configure_fill(FormatXrgb8888, 16'd0, 16'd1, SramBase + 32'he00, 32'd16, 32'h8012_3456); start_job(); wait_for_terminal(1'b0, 1'b1, 1'b0); apb_read(`APB4_GA2D__ERROR_STATUS, error_status); @@ -1298,13 +1313,13 @@ module ga2d_netlist_tb; endtask initial begin - apb4_paddr = '0; - apb4_pprot = '0; - apb4_psel = 1'b0; - apb4_penable = 1'b0; - apb4_pwrite = 1'b0; - apb4_pwdata = '0; - apb4_pstrb = '0; + apb4_paddr = '0; + apb4_pprot = '0; + apb4_psel = 1'b0; + apb4_penable = 1'b0; + apb4_pwrite = 1'b0; + apb4_pwdata = '0; + apb4_pstrb = '0; repeat (3) @(posedge clk_i); rst_n_i = 1'b1; diff --git a/tests/test_publication_boot_acceptance.py b/tests/test_publication_boot_acceptance.py index 941a7862..9ad5fe98 100644 --- a/tests/test_publication_boot_acceptance.py +++ b/tests/test_publication_boot_acceptance.py @@ -58,9 +58,8 @@ def test_mailbox_purposes_follow_registers_in_the_actual_write_order(): "message->code = *rs_hp_mailbox_register(RS_HP_MAILBOX_HP_ARG0_OFFSET);", "field semantics"), (br.MAILBOX_SOURCE, "`APB4_HP_MAILBOX__HP_DOORBELL: s_lp_intr_state_d = 1'b1;", "`APB4_HP_MAILBOX__HP_DOORBELL: s_hp_intr_state_d = 1'b1;", "LP interrupt"), - (br.READY_SOURCE, "0x10019024 32 0x4C4E5801", "0x10019024 32 0x4C4E5802", "sequence"), - (br.READY_SOURCE, " ;;", " start_ga2d_responder\n ;;", "ready-only"), - (br.READY_SOURCE, " ;;", " devmem 0x10019020 32 2\n ;;", "sequence"), + (br.READY_SOURCE, "for (;;) {", "return 0;\n for (;;) {", "ready-only"), + (br.READY_SOURCE, "mailbox[11] = 1U;", "mailbox[8] = 2U;\n mailbox[11] = 1U;", "sequence"), ]) def test_mailbox_or_service_drift_requires_new_review(source_tree, relative, old, new, match): replace(source_tree, relative, old, new) @@ -68,9 +67,54 @@ def test_mailbox_or_service_drift_requires_new_review(source_tree, relative, old br.ready_mailbox(source_tree) +@pytest.mark.parametrize("old,new", [ + ("mailbox[8] = (error == 0U) ? 1U : 3U;", "mailbox[8] = (error == 0U) ? 2U : 3U;"), + ("UINT32_C(0x4C4E5801) : error", "UINT32_C(0x4C4E5802) : error"), + ("mailbox[10] = 1U;", "mailbox[10] = 2U;"), + ("mailbox[11] = 1U;", "mailbox[11] = 2U;"), +]) +def test_each_linux_ready_value_must_match_the_lp_contract(source_tree, old, new): + replace(source_tree, br.READY_SOURCE, old, new) + with pytest.raises(ValueError, match="values differ"): + br.ready_mailbox(source_tree) + + +@pytest.mark.parametrize("old,new", [ + ("RS_HP_BOOT_READY_EVENT UINT32_C(1)", + "RS_HP_BOOT_READY_EVENT UINT32_C(2)"), + ("RS_HP_BOOT_READY_ARG UINT32_C(0x4C4E5801)", + "RS_HP_BOOT_READY_ARG UINT32_C(0x4C4E5802)"), + ("RS_HP_BOOT_MAILBOX_READY_SEQUENCE UINT32_C(1)", + "RS_HP_BOOT_MAILBOX_READY_SEQUENCE UINT32_C(2)"), +]) +def test_each_lp_ready_constant_must_match_the_linux_helper(source_tree, old, new): + replace(source_tree, br.BOOT_SOURCE, old, new) + with pytest.raises(ValueError, match="values differ"): + br.ready_mailbox(source_tree) + + +def test_coordinated_hal_rtl_offset_change_cannot_hide_a_stale_linux_helper(source_tree): + replace(source_tree, br.HAL_SOURCE, + "RS_HP_MAILBOX_HP_EVENT_OFFSET UINT32_C(0x020)", + "RS_HP_MAILBOX_HP_EVENT_OFFSET UINT32_C(0x024)") + replace(source_tree, br.REGISTER_SOURCE, + "`define APB4_HP_MAILBOX__HP_EVENT 12'h020", + "`define APB4_HP_MAILBOX__HP_EVENT 12'h024") + with pytest.raises(ValueError, match="addresses differ"): + br.ready_mailbox(source_tree) + + +def test_rtl_doorbell_offset_change_cannot_hide_a_stale_linux_helper(source_tree): + replace(source_tree, br.REGISTER_SOURCE, + "`define APB4_HP_MAILBOX__HP_DOORBELL 12'h02C", + "`define APB4_HP_MAILBOX__HP_DOORBELL 12'h050") + with pytest.raises(ValueError, match="addresses differ"): + br.ready_mailbox(source_tree) + + @pytest.mark.parametrize("old,new,match", [ ("timeout < RS_HP_BOOT_EVENT_TIMEOUT; ++timeout", "; ++timeout", "bounded poll"), - ("if (message.sequence == sequence)", "if (message.sequence != sequence)", "token/error"), + ("if (status == 1U)", "if (status != 1U)", "token/error"), ("if (!s_hp_boot_ga2d_owned_by_hp)", "if (s_hp_boot_ga2d_owned_by_hp)", "reset ownership"), ("rs_hp_boot_fail(UINT8_C(13));", "rs_hp_boot_fail(UINT8_C(11));", "completion condition"), ("cache_clean_completed = true;", "cache_clean_completed = false;", "phase or ordering"), @@ -144,7 +188,7 @@ def test_mailbox_address_is_derived_from_the_memory_map(source_tree): mailbox = next(row for row in source["regions"] if row["symbol"] == "APB4_HP_MAILBOX") mailbox["base"] = "0x1001A000" path.write_text(json.dumps(source), encoding="utf-8") - replace(source_tree, br.READY_SOURCE, "0x100190", "0x1001A0") + replace(source_tree, br.READY_SOURCE, "0x10019000", "0x1001A000") rows = br.ready_mailbox(source_tree) assert rows[0]["address"] == "0x1001A020" assert rows[0]["purpose"] == "Linux-ready event" diff --git a/tests/test_publication_diagrams.py b/tests/test_publication_diagrams.py index 7d8f22a1..720a464b 100644 --- a/tests/test_publication_diagrams.py +++ b/tests/test_publication_diagrams.py @@ -83,6 +83,7 @@ def test_protocol_field_order_is_checked_even_with_complete_coverage(data): ("scripts/apu_isa.py", "(self.dst, 4, 48)", "(self.dst, 4, 47)"), ("scripts/apu_isa.py", "APUMC_MAX_INSTRUCTIONS = APUMC_MAX_INSTRUCTIONS_V1", "APUMC_MAX_INSTRUCTIONS = 4096"), ("app/ports/linux/linux/retrosoc_hp.dts", "riscv,cbom-block-size = <64>", "riscv,cbom-block-size = <128>"), + ("rtl/ip/security/apb4_crypto.sv", "logic [31:0] s_wdata;", "logic [63:0] s_wdata;"), ]) def test_source_drift_requires_diagram_review(source_tree, data, relative, old, new): replace(source_tree, relative, old, new) @@ -90,6 +91,15 @@ def test_source_drift_requires_diagram_review(source_tree, data, relative, old, dr.collect_diagrams(source_tree, SPEC, data["regions"], data["system_reference"]) +def test_rsa_limb_width_is_independent_of_dma_alignment(source_tree, data): + replace(source_tree, "crt/include/retrosoc/hal/crypto_regs.h", + "RS_CRYPTO_DMA_ALIGNMENT 4U", "RS_CRYPTO_DMA_ALIGNMENT 8U") + diagrams = dr.collect_diagrams(source_tree, SPEC, data["regions"], data["system_reference"]) + assert [(row["depth"], row["bits"]) for row in diagrams["storage"]["rsa-vectors"]["stores"]] == [ + (64, 32), (64, 32), (64, 32), (64, 32) + ] + + @pytest.mark.parametrize("mutation", ["node", "port", "endpoint", "direction", "width", "binding", "duplicate-edge"]) def test_circuit_records_reject_invented_or_inconsistent_connections(mutation): circuit = copy.deepcopy(SPEC["circuits"]["uart0"]) diff --git a/tests/test_publication_environment.py b/tests/test_publication_environment.py index 456751b9..86641c03 100644 --- a/tests/test_publication_environment.py +++ b/tests/test_publication_environment.py @@ -9,13 +9,23 @@ from publications.environment_reference import ENVIRONMENT_SOURCES, development_ ROOT = Path(__file__).resolve().parents[1] -def test_environment_reports_current_locked_runtime_versions(): +def test_environment_reports_current_locked_launcher_and_runtime_versions(): result = development_environment(ROOT) - assert (result["platform"], result["ubuntu"], result["python"], result["java"], result["sbt"]) == ( - "Linux x86_64", "22.04", "3.10", "17", "1.10.0") + assert (result["platform"], result["ubuntu"], result["python"], result["java"], + result["sbt_launcher"]) == ( + "Linux x86_64", "22.04", "3.10", "17", "2.0.5") assert not {"passed", "qualified", "performance"} & result.keys() +def test_environment_labels_sbt_as_a_launcher(): + section = (ROOT / "publications/datasheets/sections/development-environment.typ").read_text( + encoding="utf-8" + ) + assert "SBT launcher #environment.sbt_launcher" in section + assert "version is not an engine-version claim" in section + assert "#environment.sbt toolchain" not in section + + @pytest.mark.parametrize("path,old,new,reason", [ ("docker/Dockerfile", "openjdk-17-jre-headless", "openjdk-21-jre-headless", "runtime/platform"), ("flake.nix", "python310Full", "python3Full", "runtime/platform"), diff --git a/tests/test_publication_full_diagrams.py b/tests/test_publication_full_diagrams.py index 71f1e01e..1bc351d1 100644 --- a/tests/test_publication_full_diagrams.py +++ b/tests/test_publication_full_diagrams.py @@ -116,6 +116,7 @@ def test_storage_geometry_preserves_product_overrides_and_sidebands(diagrams): assert [(s["depth"], s["bits"]) for s in stores["dma-channel-fifos"]["stores"]] == [(32, 32)] assert [(s["depth"], s["bits"]) for s in stores["sdio-pio"]["stores"]] == [(4, 36), (1, 32)] assert [(s["depth"], s["bits"]) for s in stores["apu-fifos"]["stores"]] == [(64, 41), (64, 41)] + assert [(s["depth"], s["bits"]) for s in stores["rsa-vectors"]["stores"]] == [(64, 32)] * 4 assert [(s["depth"], s["bits"]) for s in stores["opi-lines"]["stores"]] == [(4, 256)] assert sum(row["bytes"] for row in stores["apu-local"]["ranges"]) == 114688 assert stores["linker-ld2_psram"]["stack_region"] == "PSRAM" diff --git a/tests/test_publication_registers.py b/tests/test_publication_registers.py index 6fd0a27e..396c9843 100644 --- a/tests/test_publication_registers.py +++ b/tests/test_publication_registers.py @@ -114,9 +114,12 @@ def test_composite_fields_and_multiline_capability_keep_the_real_layout(referenc assert next(f for f in apu["fields"] if f["name"] == "CODE")["msb"] == 6 for item in reference.values(): for register in item["registers"]: - assert all( - "BEGIN" not in f["name"] and ";" not in f["name"] for f in register["fields"] - ) + for field in register["fields"]: + assert ";" not in field["name"] + if "BEGIN" in field["name"]: + assert (item["id"], register["key"], field["name"]) == ( + "crypto", "main.MEM_CONTROL", "BEGIN" + ) def test_read_predicate_is_not_mistaken_for_a_field_assignment(): @@ -133,6 +136,33 @@ def test_secret_apertures_do_not_claim_readback(reference): assert "PSLVERR" in entry["description"] +def test_crypto_interrupt_registers_publish_all_six_events(reference): + registers = {entry["key"]: entry for entry in reference["crypto"]["registers"]} + expected = ["AES_DONE", "SHA_DONE", "RSA_DONE", "ERROR", "ZEROIZED", "MEMORY_READY"] + for key in ("main.IRQ_STATE", "main.IRQ_ENABLE", "main.IRQ_TEST"): + fields = registers[key]["fields"] + assert [field["name"] for field in fields[:6]] == expected + assert [(field["lsb"], field["msb"]) for field in fields[:6]] == [ + (bit, bit) for bit in range(6) + ] + assert (fields[6]["name"], fields[6]["lsb"], fields[6]["msb"]) == ( + "Reserved", 6, 31 + ) + + +def test_crypto_lifecycle_annotations_preserve_security_boundaries(reference): + registers = {entry["key"]: entry for entry in reference["crypto"]["registers"]} + mem_status = {field["name"]: field for field in registers["main.MEM_STATUS"]["fields"]} + lock_description = mem_status["TABLE_LOCKED"]["description"] + assert "hard/PCLK reset" in lock_description + assert "zeroize does not unlock" in lock_description + + irq_test = {field["name"]: field for field in registers["main.IRQ_TEST"]["fields"]} + test_description = irq_test["MEMORY_READY"]["description"] + assert "interrupt-path testing" in test_description + assert "not initialization or physical-erasure completion evidence" in test_description + + def test_exact_register_description_wins_over_grouped_name_fragments(reference): status = next(r for r in reference["xpi"]["registers"] if r["key"] == "main.STATUS") assert "enable/busy/FIFO" in status["description"] diff --git a/tests/test_script_tools.py b/tests/test_script_tools.py index e40bcd8a..8b9863e2 100644 --- a/tests/test_script_tools.py +++ b/tests/test_script_tools.py @@ -37,6 +37,7 @@ from scripts.development_environment import ( # noqa: E402 write_stamp, ) from scripts.generate_mpw import render_active_manifest, validate_extension_bindings # noqa: E402 +from scripts import generate_vexiiriscv # noqa: E402 from scripts.install_toolchain import make_tree_world_readable, safe_extract # noqa: E402 from scripts.package import make_sbom # noqa: E402 from scripts.prepare_mpw import patch_serv # noqa: E402 @@ -1097,10 +1098,10 @@ def test_dependency_lock_and_config_key_include_a_fixed_timestamp(tmp_path: Path assert lock["container_images"]["ubuntu_22_04"]["image"] == "ubuntu" assert lock["nix_inputs"]["nixpkgs"]["revision"] == "50ab793786d9de88ee30ec4e4c24fb4236fc2674" assert lock["toolchains"]["ubuntu-22.04"]["sbt"] == { - "version": "1.10.0", - "url": "https://github.com/sbt/sbt/releases/download/v1.10.0/sbt-1.10.0.tgz", - "sha256": "154b7de6c19207c73d0a304f901c8c4b6ead9a9c3a99a98a9d72ac19419d2640", - "archive": "sbt-1.10.0.tgz", + "version": "2.0.5", + "url": "https://github.com/sbt/sbt/releases/download/v2.0.5/sbt-2.0.5.tgz", + "sha256": "2a53c95403cb7fccd5da05d48cfe03ff4be573a3f3d0295a41963b109e756a18", + "archive": "sbt-2.0.5.tgz", "path": "sbt/bin", "download_timeout_seconds": 600, "resume": True, @@ -1527,7 +1528,7 @@ def test_behavioral_only_excludes_synthesis_and_netlist_consumers() -> None: def test_hosted_regression_keeps_tools_but_skips_synthesis_execution() -> None: workflow = (ROOT / ".github/workflows/_regression.yml").read_text(encoding="utf-8") - assert "default: verilator sv2v iverilog yosys opensta openocd riscv_gnu" in workflow + assert "default: verilator sv2v iverilog yosys opensta openocd sbt riscv_gnu" in workflow assert "SIMU=IVERILOG SYNTH=YOSYS STA=NONE doctor" in workflow assert "--behavioral-only" in workflow @@ -1538,6 +1539,7 @@ def test_hosted_smoke_formal_check_is_doctor_only() -> None: software_makefile = (ROOT / "rtl/mk/software.mk").read_text(encoding="utf-8") assert "timeout_minutes: 60" in smoke + assert "toolset: verilator sv2v iverilog yosys sby bitwuzla sbt riscv_gnu" in smoke assert "formal_checks: true" in smoke assert "make CONFIG=${{ inputs.profile }} formal-doctor" in workflow assert "make CONFIG=${{ inputs.profile }} formal\n" not in workflow @@ -1545,6 +1547,23 @@ def test_hosted_smoke_formal_check_is_doctor_only() -> None: assert "$(DUMP) -D" not in software_makefile +@pytest.mark.parametrize("revision,status,match", [ + ("different", [], "revision mismatch"), + ("expected", [" M tracked.scala", "?? local/"], "local changes"), +]) +def test_vexii_generation_rejects_unlocked_or_dirty_sources( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, + revision: str, + status: list[str], + match: str, +) -> None: + monkeypatch.setattr(generate_vexiiriscv, "git_revision", lambda _source: revision) + monkeypatch.setattr(generate_vexiiriscv, "git_status", lambda _source: status) + with pytest.raises(ValueError, match=match): + generate_vexiiriscv.validate_locked_source(tmp_path, "expected") + + def test_pdk_pr_regressions_cover_firmware_rtl_and_selected_netlist_target() -> None: assert set(PDK_PR_PROFILES) == {"GF180", "IHP130", "ICS55", "SKY130"} for pdk, profile in PDK_PR_PROFILES.items(): @@ -1564,7 +1583,7 @@ def test_pdk_pr_regressions_cover_firmware_rtl_and_selected_netlist_target() -> else: assert "LINK_TYPE=ld2_sdram" in verilator_values assert "VERILATOR_SIM_ARGS=--fast-flash" in verilator_values - assert "SOC_SIM_TIME=1800" in verilator_values + assert "SOC_SIM_TIME=3600" in verilator_values assert "HAVE_CSR=YES" in verilator_values assert any("SIMU=IVERILOG" in values and "sim-asm" in values for values in command_values) assert any("SYNTH=YOSYS" in values and "synth" in values for values in command_values)