mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-06 14:55:14 +00:00
feat: refactor RIB to APB bridge and update related components
- Changed the interface from ribp to rib in soc_topology.json and related files. - Updated formal.mk to reflect the new rib2apb naming convention. - Implemented rib2apb module to handle RIB to APB communication. - Modified bus.sv to integrate the new rib2apb module and adjust signal assignments accordingly. - Updated testbench files to use the new rib interface and validate the RIB to APB functionality. - Created rib2apb_tb for testing the direct RIB to APB bridge. - Adjusted script tools and test scripts to accommodate the new naming and structure.
This commit is contained in:
27 files changed
+950
-454
No files matched your search
@@ -210,7 +210,7 @@ endif
|
|||||||
benchmark-report \
|
benchmark-report \
|
||||||
pin-map check-pin-map soc-topology check-soc-topology user-extensions check-user-extensions \
|
pin-map check-pin-map soc-topology check-soc-topology user-extensions check-user-extensions \
|
||||||
check-clock-reset-domains tech-cell-test rtl-lint check-rtl-lint \
|
check-clock-reset-domains tech-cell-test rtl-lint check-rtl-lint \
|
||||||
formal formal-bus formal-rib-adapter formal-ribp2apb formal-clean formal-doctor
|
formal formal-bus formal-rib-adapter formal-rib2apb formal-clean formal-doctor
|
||||||
.NOTPARALLEL: setup
|
.NOTPARALLEL: setup
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@@ -235,7 +235,7 @@ help:
|
|||||||
' check-user-extensions validate the canonical user-extension map' \
|
' check-user-extensions validate the canonical user-extension map' \
|
||||||
' check-clock-reset-domains validate the root clock/reset and CDC inventory' \
|
' check-clock-reset-domains validate the root clock/reset and CDC inventory' \
|
||||||
' rtl-lint | check-rtl-lint run/check strict Verilator RTL lint warnings' \
|
' rtl-lint | check-rtl-lint run/check strict Verilator RTL lint warnings' \
|
||||||
' formal | formal-bus | formal-rib-adapter | formal-ribp2apb run SBY protocol proofs' \
|
' formal | formal-bus | formal-rib-adapter | formal-rib2apb run SBY protocol proofs' \
|
||||||
' formal-sysctrl | formal-pll-rcu | formal-gpio-user run SBY peripheral-control proofs' \
|
' formal-sysctrl | formal-pll-rcu | formal-gpio-user run SBY peripheral-control proofs' \
|
||||||
' formal-doctor check the SBY, Yosys, sv2v, and Bitwuzla formal toolchain' \
|
' formal-doctor check the SBY, Yosys, sv2v, and Bitwuzla formal toolchain' \
|
||||||
' benchmark-report run the benchmark profile and write meta/performance.json' \
|
' benchmark-report run the benchmark profile and write meta/performance.json' \
|
||||||
@@ -383,4 +383,4 @@ regress-nightly:
|
|||||||
|
|
||||||
sim-asm: asm
|
sim-asm: asm
|
||||||
$(MAKE) SIM_FIRMWARE_NAME=$(ASM_FIRMWARE_NAME) \
|
$(MAKE) SIM_FIRMWARE_NAME=$(ASM_FIRMWARE_NAME) \
|
||||||
SIM_SUCCESS_MARKER='Mem wr/rd test success' sim
|
SIM_SUCCESS_MARKER='Mem wr/rd test success' sim
|
||||||
+1
-1
@@ -111,7 +111,7 @@ Verilator regressions.
|
|||||||
|
|
||||||
`make CONFIG=configs/ci/ihp130.mk formal` proves selected
|
`make CONFIG=configs/ci/ihp130.mk formal` proves selected
|
||||||
protocol invariants with SymbiYosys, Yosys, `sv2v`, and Bitwuzla. The current
|
protocol invariants with SymbiYosys, Yosys, `sv2v`, and Bitwuzla. The current
|
||||||
targets are `bus`, `rib_adapter`, `ribp2apb`, `sysctrl`, `pll_rcu`, and
|
targets are `bus`, `rib_adapter`, `rib2apb`, `sysctrl`, `pll_rcu`, and
|
||||||
`gpio_user`; each uses
|
`gpio_user`; each uses
|
||||||
the SBY `prove` task for bounded model checking and k-induction, plus a
|
the SBY `prove` task for bounded model checking and k-induction, plus a
|
||||||
`cover` task, at depth 20. `sysctrl` checks register side effects, PLL request
|
`cover` task, at depth 20. `sysctrl` checks register side effects, PLL request
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ digraph mini_soc_block_diagram {
|
|||||||
];
|
];
|
||||||
apb_adapter [
|
apb_adapter [
|
||||||
fillcolor="#E5E7EB",
|
fillcolor="#E5E7EB",
|
||||||
label="RIB2RIBP\nAPB bridge"
|
label="RIB2APB\ndirect APB bridge"
|
||||||
];
|
];
|
||||||
sysctrl [
|
sysctrl [
|
||||||
fillcolor="#F9E1E7",
|
fillcolor="#F9E1E7",
|
||||||
@@ -124,7 +124,7 @@ digraph mini_soc_block_diagram {
|
|||||||
];
|
];
|
||||||
irq [
|
irq [
|
||||||
fillcolor="#FCE7F3",
|
fillcolor="#FCE7F3",
|
||||||
label="Interrupt aggregation\nRIBP and APB sources to management core"
|
label="Interrupt aggregation\nRIBP and APB target IRQs to management core"
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -149,7 +149,7 @@ digraph mini_soc_block_diagram {
|
|||||||
fabric -> apb_adapter [label="RIB"];
|
fabric -> apb_adapter [label="RIB"];
|
||||||
ribp_adapter -> sysctrl [label="RIBP"];
|
ribp_adapter -> sysctrl [label="RIBP"];
|
||||||
ribp_adapter -> ribp_targets [label="RIBP"];
|
ribp_adapter -> ribp_targets [label="RIBP"];
|
||||||
apb_adapter -> apb_targets [label="RIBP / APB"];
|
apb_adapter -> apb_targets [label="APB"];
|
||||||
|
|
||||||
ribp_targets -> gpio_bridge [label="GPIO alternate functions"];
|
ribp_targets -> gpio_bridge [label="GPIO alternate functions"];
|
||||||
apb_targets -> gpio_bridge [label="user_gpio"];
|
apb_targets -> gpio_bridge [label="user_gpio"];
|
||||||
|
|||||||
@@ -44,10 +44,10 @@
|
|||||||
<!-- ext_io -->
|
<!-- ext_io -->
|
||||||
<g id="node2" class="node">
|
<g id="node2" class="node">
|
||||||
<title>ext_io</title>
|
<title>ext_io</title>
|
||||||
<path fill="#f3f4f6" stroke="#4b5563" stroke-width="1.1" d="M986,-45C986,-45 794,-45 794,-45 788,-45 782,-39 782,-33 782,-33 782,-12 782,-12 782,-6 788,0 794,0 794,0 986,0 986,0 992,0 998,-6 998,-12 998,-12 998,-33 998,-33 998,-39 992,-45 986,-45"/>
|
<path fill="#f3f4f6" stroke="#4b5563" stroke-width="1.1" d="M989,-45C989,-45 797,-45 797,-45 791,-45 785,-39 785,-33 785,-33 785,-12 785,-12 785,-6 791,0 797,0 797,0 989,0 989,0 995,0 1001,-6 1001,-12 1001,-12 1001,-33 1001,-33 1001,-39 995,-45 989,-45"/>
|
||||||
<text text-anchor="middle" x="890" y="-31" font-family="Arial" font-size="10.00" fill="#111827">External I/O and memory</text>
|
<text text-anchor="middle" x="893" y="-31" font-family="Arial" font-size="10.00" fill="#111827">External I/O and memory</text>
|
||||||
<text text-anchor="middle" x="890" y="-20" font-family="Arial" font-size="10.00" fill="#111827">GPIO, UART0, XPI Flash, SDRAM, PSRAM</text>
|
<text text-anchor="middle" x="893" y="-20" font-family="Arial" font-size="10.00" fill="#111827">GPIO, UART0, XPI Flash, SDRAM, PSRAM</text>
|
||||||
<text text-anchor="middle" x="890" y="-9" font-family="Arial" font-size="10.00" fill="#111827">SD card, I2C, I2S, DVP and serial I/O</text>
|
<text text-anchor="middle" x="893" y="-9" font-family="Arial" font-size="10.00" fill="#111827">SD card, I2C, I2S, DVP and serial I/O</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- fabric -->
|
<!-- fabric -->
|
||||||
<g id="node8" class="node">
|
<g id="node8" class="node">
|
||||||
@@ -152,22 +152,22 @@
|
|||||||
<!-- ribp_adapter -->
|
<!-- ribp_adapter -->
|
||||||
<g id="node11" class="node">
|
<g id="node11" class="node">
|
||||||
<title>ribp_adapter</title>
|
<title>ribp_adapter</title>
|
||||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M753.5,-346C753.5,-346 712.5,-346 712.5,-346 706.5,-346 700.5,-340 700.5,-334 700.5,-334 700.5,-322 700.5,-322 700.5,-316 706.5,-310 712.5,-310 712.5,-310 753.5,-310 753.5,-310 759.5,-310 765.5,-316 765.5,-322 765.5,-322 765.5,-334 765.5,-334 765.5,-340 759.5,-346 753.5,-346"/>
|
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M756.5,-346C756.5,-346 715.5,-346 715.5,-346 709.5,-346 703.5,-340 703.5,-334 703.5,-334 703.5,-322 703.5,-322 703.5,-316 709.5,-310 715.5,-310 715.5,-310 756.5,-310 756.5,-310 762.5,-310 768.5,-316 768.5,-322 768.5,-322 768.5,-334 768.5,-334 768.5,-340 762.5,-346 756.5,-346"/>
|
||||||
<text text-anchor="middle" x="733" y="-325.5" font-family="Arial" font-size="10.00" fill="#111827">RIB2RIBP</text>
|
<text text-anchor="middle" x="736" y="-325.5" font-family="Arial" font-size="10.00" fill="#111827">RIB2RIBP</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- fabric->ribp_adapter -->
|
<!-- fabric->ribp_adapter -->
|
||||||
<g id="edge9" class="edge">
|
<g id="edge9" class="edge">
|
||||||
<title>fabric->ribp_adapter</title>
|
<title>fabric->ribp_adapter</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M626.94,-400.87C651.88,-383.97 680.76,-364.4 702.08,-349.95"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M627.94,-400.87C653.35,-383.97 682.77,-364.4 704.49,-349.95"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="703.46,-351.98 707.88,-346.02 700.71,-347.92 703.46,-351.98"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="705.93,-351.94 710.41,-346.02 703.22,-347.86 705.93,-351.94"/>
|
||||||
<text text-anchor="middle" x="679" y="-371.6" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
<text text-anchor="middle" x="681" y="-371.6" font-family="Arial" font-size="8.00" fill="#374151">RIB</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- apb_adapter -->
|
<!-- apb_adapter -->
|
||||||
<g id="node12" class="node">
|
<g id="node12" class="node">
|
||||||
<title>apb_adapter</title>
|
<title>apb_adapter</title>
|
||||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M564,-346C564,-346 520,-346 520,-346 514,-346 508,-340 508,-334 508,-334 508,-322 508,-322 508,-316 514,-310 520,-310 520,-310 564,-310 564,-310 570,-310 576,-316 576,-322 576,-322 576,-334 576,-334 576,-340 570,-346 564,-346"/>
|
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M577,-346C577,-346 507,-346 507,-346 501,-346 495,-340 495,-334 495,-334 495,-322 495,-322 495,-316 501,-310 507,-310 507,-310 577,-310 577,-310 583,-310 589,-316 589,-322 589,-322 589,-334 589,-334 589,-340 583,-346 577,-346"/>
|
||||||
<text text-anchor="middle" x="542" y="-331" font-family="Arial" font-size="10.00" fill="#111827">RIB2RIBP</text>
|
<text text-anchor="middle" x="542" y="-331" font-family="Arial" font-size="10.00" fill="#111827">RIB2APB</text>
|
||||||
<text text-anchor="middle" x="542" y="-320" font-family="Arial" font-size="10.00" fill="#111827">APB bridge</text>
|
<text text-anchor="middle" x="542" y="-320" font-family="Arial" font-size="10.00" fill="#111827">direct APB bridge</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- fabric->apb_adapter -->
|
<!-- fabric->apb_adapter -->
|
||||||
<g id="edge10" class="edge">
|
<g id="edge10" class="edge">
|
||||||
@@ -179,91 +179,91 @@
|
|||||||
<!-- sysctrl -->
|
<!-- sysctrl -->
|
||||||
<g id="node13" class="node">
|
<g id="node13" class="node">
|
||||||
<title>sysctrl</title>
|
<title>sysctrl</title>
|
||||||
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M814.5,-255C814.5,-255 651.5,-255 651.5,-255 645.5,-255 639.5,-249 639.5,-243 639.5,-243 639.5,-222 639.5,-222 639.5,-216 645.5,-210 651.5,-210 651.5,-210 814.5,-210 814.5,-210 820.5,-210 826.5,-216 826.5,-222 826.5,-222 826.5,-243 826.5,-243 826.5,-249 820.5,-255 814.5,-255"/>
|
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M817.5,-255C817.5,-255 654.5,-255 654.5,-255 648.5,-255 642.5,-249 642.5,-243 642.5,-243 642.5,-222 642.5,-222 642.5,-216 648.5,-210 654.5,-210 654.5,-210 817.5,-210 817.5,-210 823.5,-210 829.5,-216 829.5,-222 829.5,-222 829.5,-243 829.5,-243 829.5,-249 823.5,-255 817.5,-255"/>
|
||||||
<text text-anchor="middle" x="733" y="-241" font-family="Arial" font-size="10.00" fill="#111827">SYSCTRL and CLINT</text>
|
<text text-anchor="middle" x="736" y="-241" font-family="Arial" font-size="10.00" fill="#111827">SYSCTRL and CLINT</text>
|
||||||
<text text-anchor="middle" x="733" y="-230" font-family="Arial" font-size="10.00" fill="#111827">PLL, user-core select/reset/bus enable</text>
|
<text text-anchor="middle" x="736" y="-230" font-family="Arial" font-size="10.00" fill="#111827">PLL, user-core select/reset/bus enable</text>
|
||||||
<text text-anchor="middle" x="733" y="-219" font-family="Arial" font-size="10.00" fill="#111827">fault and performance control</text>
|
<text text-anchor="middle" x="736" y="-219" font-family="Arial" font-size="10.00" fill="#111827">fault and performance control</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- ribp_adapter->sysctrl -->
|
<!-- ribp_adapter->sysctrl -->
|
||||||
<g id="edge11" class="edge">
|
<g id="edge11" class="edge">
|
||||||
<title>ribp_adapter->sysctrl</title>
|
<title>ribp_adapter->sysctrl</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M733,-309.85C733,-296.62 733,-278.02 733,-262.49"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M736,-309.85C736,-296.62 736,-278.02 736,-262.49"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="735.45,-262.15 733,-255.15 730.55,-262.15 735.45,-262.15"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="738.45,-262.15 736,-255.15 733.55,-262.15 738.45,-262.15"/>
|
||||||
<text text-anchor="middle" x="742.5" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
<text text-anchor="middle" x="745.5" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- ribp_targets -->
|
<!-- ribp_targets -->
|
||||||
<g id="node14" class="node">
|
<g id="node14" class="node">
|
||||||
<title>ribp_targets</title>
|
<title>ribp_targets</title>
|
||||||
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M1055,-255C1055,-255 865,-255 865,-255 859,-255 853,-249 853,-243 853,-243 853,-222 853,-222 853,-216 859,-210 865,-210 865,-210 1055,-210 1055,-210 1061,-210 1067,-216 1067,-222 1067,-222 1067,-243 1067,-243 1067,-249 1061,-255 1055,-255"/>
|
<path fill="#f9e1e7" stroke="#4b5563" stroke-width="1.1" d="M1058,-255C1058,-255 868,-255 868,-255 862,-255 856,-249 856,-243 856,-243 856,-222 856,-222 856,-216 862,-210 868,-210 868,-210 1058,-210 1058,-210 1064,-210 1070,-216 1070,-222 1070,-222 1070,-243 1070,-243 1070,-249 1064,-255 1058,-255"/>
|
||||||
<text text-anchor="middle" x="960" y="-241" font-family="Arial" font-size="10.00" fill="#111827">RIBP target wrapper</text>
|
<text text-anchor="middle" x="963" y="-241" font-family="Arial" font-size="10.00" fill="#111827">RIBP target wrapper</text>
|
||||||
<text text-anchor="middle" x="960" y="-230" font-family="Arial" font-size="10.00" fill="#111827">XPI/Flash, SDRAM, PSRAM, SPI-SD, DVP</text>
|
<text text-anchor="middle" x="963" y="-230" font-family="Arial" font-size="10.00" fill="#111827">XPI/Flash, SDRAM, PSRAM, SPI-SD, DVP</text>
|
||||||
<text text-anchor="middle" x="960" y="-219" font-family="Arial" font-size="10.00" fill="#111827">GPIO, UART0, timers, I2C, I2S and 1-Wire</text>
|
<text text-anchor="middle" x="963" y="-219" font-family="Arial" font-size="10.00" fill="#111827">GPIO, UART0, timers, I2C, I2S and 1-Wire</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- ribp_adapter->ribp_targets -->
|
<!-- ribp_adapter->ribp_targets -->
|
||||||
<g id="edge12" class="edge">
|
<g id="edge12" class="edge">
|
||||||
<title>ribp_adapter->ribp_targets</title>
|
<title>ribp_adapter->ribp_targets</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M765.52,-313.6C800.74,-299.1 857.65,-275.66 900.84,-257.87"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M768.52,-313.6C803.74,-299.1 860.65,-275.66 903.84,-257.87"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="901.83,-260.11 907.37,-255.18 899.97,-255.58 901.83,-260.11"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="904.83,-260.11 910.37,-255.18 902.97,-255.58 904.83,-260.11"/>
|
||||||
<text text-anchor="middle" x="855.5" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
<text text-anchor="middle" x="858.5" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- apb_targets -->
|
<!-- apb_targets -->
|
||||||
<g id="node15" class="node">
|
<g id="node15" class="node">
|
||||||
<title>apb_targets</title>
|
<title>apb_targets</title>
|
||||||
<path fill="#e6f4ea" stroke="#4b5563" stroke-width="1.1" d="M600.5,-255C600.5,-255 409.5,-255 409.5,-255 403.5,-255 397.5,-249 397.5,-243 397.5,-243 397.5,-222 397.5,-222 397.5,-216 403.5,-210 409.5,-210 409.5,-210 600.5,-210 600.5,-210 606.5,-210 612.5,-216 612.5,-222 612.5,-222 612.5,-243 612.5,-243 612.5,-249 606.5,-255 600.5,-255"/>
|
<path fill="#e6f4ea" stroke="#4b5563" stroke-width="1.1" d="M603.5,-255C603.5,-255 412.5,-255 412.5,-255 406.5,-255 400.5,-249 400.5,-243 400.5,-243 400.5,-222 400.5,-222 400.5,-216 406.5,-210 412.5,-210 412.5,-210 603.5,-210 603.5,-210 609.5,-210 615.5,-216 615.5,-222 615.5,-222 615.5,-243 615.5,-243 615.5,-249 609.5,-255 603.5,-255"/>
|
||||||
<text text-anchor="middle" x="505" y="-241" font-family="Arial" font-size="10.00" fill="#111827">APB target wrapper</text>
|
<text text-anchor="middle" x="508" y="-241" font-family="Arial" font-size="10.00" fill="#111827">APB target wrapper</text>
|
||||||
<text text-anchor="middle" x="505" y="-230" font-family="Arial" font-size="10.00" fill="#111827">Archinfo, RNG, UART1, PWM, PS/2, RTC</text>
|
<text text-anchor="middle" x="508" y="-230" font-family="Arial" font-size="10.00" fill="#111827">Archinfo, RNG, UART1, PWM, PS/2, RTC</text>
|
||||||
<text text-anchor="middle" x="505" y="-219" font-family="Arial" font-size="10.00" fill="#111827">watchdog, CRC, advanced timer and user IP</text>
|
<text text-anchor="middle" x="508" y="-219" font-family="Arial" font-size="10.00" fill="#111827">watchdog, CRC, advanced timer and user IP</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- apb_adapter->apb_targets -->
|
<!-- apb_adapter->apb_targets -->
|
||||||
<g id="edge13" class="edge">
|
<g id="edge13" class="edge">
|
||||||
<title>apb_adapter->apb_targets</title>
|
<title>apb_adapter->apb_targets</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M535.21,-309.85C529.93,-296.5 522.48,-277.68 516.3,-262.07"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M535.76,-309.85C530.91,-296.5 524.07,-277.68 518.39,-262.07"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="518.42,-260.76 513.57,-255.15 513.86,-262.56 518.42,-260.76"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="520.57,-260.89 515.87,-255.15 515.96,-262.56 520.57,-260.89"/>
|
||||||
<text text-anchor="middle" x="545.5" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">RIBP / APB</text>
|
<text text-anchor="middle" x="535" y="-280.6" font-family="Arial" font-size="8.00" fill="#374151">APB</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- ribp_targets->ext_io -->
|
<!-- ribp_targets->ext_io -->
|
||||||
<g id="edge16" class="edge">
|
<g id="edge16" class="edge">
|
||||||
<title>ribp_targets->ext_io</title>
|
<title>ribp_targets->ext_io</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M952.24,-203.09C940.61,-160.49 920,-85 920,-85 920,-85 911.54,-67.66 903.6,-51.39"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M955.24,-203.09C943.61,-160.49 923,-85 923,-85 923,-85 914.54,-67.66 906.6,-51.39"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="949.89,-203.78 954.1,-209.88 954.62,-202.49 949.89,-203.78"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="952.89,-203.78 957.1,-209.88 957.62,-202.49 952.89,-203.78"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="905.76,-50.23 900.49,-45.01 901.36,-52.38 905.76,-50.23"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="908.76,-50.23 903.49,-45.01 904.36,-52.38 908.76,-50.23"/>
|
||||||
<text text-anchor="middle" x="968" y="-135.1" font-family="Arial" font-size="8.00" fill="#374151">device interfaces</text>
|
<text text-anchor="middle" x="971" y="-135.1" font-family="Arial" font-size="8.00" fill="#374151">device interfaces</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- gpio_bridge -->
|
<!-- gpio_bridge -->
|
||||||
<g id="node16" class="node">
|
<g id="node16" class="node">
|
||||||
<title>gpio_bridge</title>
|
<title>gpio_bridge</title>
|
||||||
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M894,-155C894,-155 746,-155 746,-155 740,-155 734,-149 734,-143 734,-143 734,-131 734,-131 734,-125 740,-119 746,-119 746,-119 894,-119 894,-119 900,-119 906,-125 906,-131 906,-131 906,-143 906,-143 906,-149 900,-155 894,-155"/>
|
<path fill="#e5e7eb" stroke="#4b5563" stroke-width="1.1" d="M897,-155C897,-155 749,-155 749,-155 743,-155 737,-149 737,-143 737,-143 737,-131 737,-131 737,-125 743,-119 749,-119 749,-119 897,-119 897,-119 903,-119 909,-125 909,-131 909,-131 909,-143 909,-143 909,-149 903,-155 897,-155"/>
|
||||||
<text text-anchor="middle" x="820" y="-140" font-family="Arial" font-size="10.00" fill="#111827">GPIO pad bridge</text>
|
<text text-anchor="middle" x="823" y="-140" font-family="Arial" font-size="10.00" fill="#111827">GPIO pad bridge</text>
|
||||||
<text text-anchor="middle" x="820" y="-129" font-family="Arial" font-size="10.00" fill="#111827">software, alternate and user modes</text>
|
<text text-anchor="middle" x="823" y="-129" font-family="Arial" font-size="10.00" fill="#111827">software, alternate and user modes</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- ribp_targets->gpio_bridge -->
|
<!-- ribp_targets->gpio_bridge -->
|
||||||
<g id="edge14" class="edge">
|
<g id="edge14" class="edge">
|
||||||
<title>ribp_targets->gpio_bridge</title>
|
<title>ribp_targets->gpio_bridge</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M907.58,-209.9C880.06,-198.56 852,-187 852,-187 852,-187 843.45,-173.9 835.19,-161.25"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M910.58,-209.9C883.06,-198.56 855,-187 855,-187 855,-187 846.45,-173.9 838.19,-161.25"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="837.07,-159.66 831.19,-155.14 832.97,-162.34 837.07,-159.66"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="840.07,-159.66 834.19,-155.14 835.97,-162.34 840.07,-159.66"/>
|
||||||
<text text-anchor="middle" x="896" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">GPIO alternate functions</text>
|
<text text-anchor="middle" x="899" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">GPIO alternate functions</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- apb_targets->gpio_bridge -->
|
<!-- apb_targets->gpio_bridge -->
|
||||||
<g id="edge15" class="edge">
|
<g id="edge15" class="edge">
|
||||||
<title>apb_targets->gpio_bridge</title>
|
<title>apb_targets->gpio_bridge</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M577.66,-209.93C631.48,-193.96 704.14,-172.39 755.82,-157.05"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M580.66,-209.93C634.48,-193.96 707.14,-172.39 758.82,-157.05"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="756.64,-159.36 762.65,-155.02 755.24,-154.67 756.64,-159.36"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="759.64,-159.36 765.65,-155.02 758.24,-154.67 759.64,-159.36"/>
|
||||||
<text text-anchor="middle" x="699" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">user_gpio</text>
|
<text text-anchor="middle" x="702" y="-180.6" font-family="Arial" font-size="8.00" fill="#374151">user_gpio</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- gpio_bridge->ext_io -->
|
<!-- gpio_bridge->ext_io -->
|
||||||
<g id="edge17" class="edge">
|
<g id="edge17" class="edge">
|
||||||
<title>gpio_bridge->ext_io</title>
|
<title>gpio_bridge->ext_io</title>
|
||||||
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M834.43,-112.81C845.49,-95.04 860.79,-70.44 872.54,-51.56"/>
|
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M837.43,-112.81C848.49,-95.04 863.79,-70.44 875.54,-51.56"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="832.25,-111.68 830.63,-118.91 836.41,-114.26 832.25,-111.68"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="835.25,-111.68 833.63,-118.91 839.41,-114.26 835.25,-111.68"/>
|
||||||
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="874.76,-52.63 876.38,-45.39 870.6,-50.04 874.76,-52.63"/>
|
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="877.76,-52.63 879.38,-45.39 873.6,-50.04 877.76,-52.63"/>
|
||||||
<text text-anchor="middle" x="881" y="-70.6" font-family="Arial" font-size="8.00" fill="#374151">pad control</text>
|
<text text-anchor="middle" x="884" y="-70.6" font-family="Arial" font-size="8.00" fill="#374151">pad control</text>
|
||||||
</g>
|
</g>
|
||||||
<!-- irq -->
|
<!-- irq -->
|
||||||
<g id="node17" class="node">
|
<g id="node17" class="node">
|
||||||
<title>irq</title>
|
<title>irq</title>
|
||||||
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M646,-155C646,-155 456,-155 456,-155 450,-155 444,-149 444,-143 444,-143 444,-131 444,-131 444,-125 450,-119 456,-119 456,-119 646,-119 646,-119 652,-119 658,-125 658,-131 658,-131 658,-143 658,-143 658,-149 652,-155 646,-155"/>
|
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M655,-155C655,-155 449,-155 449,-155 443,-155 437,-149 437,-143 437,-143 437,-131 437,-131 437,-125 443,-119 449,-119 449,-119 655,-119 655,-119 661,-119 667,-125 667,-131 667,-131 667,-143 667,-143 667,-149 661,-155 655,-155"/>
|
||||||
<text text-anchor="middle" x="551" y="-140" font-family="Arial" font-size="10.00" fill="#111827">Interrupt aggregation</text>
|
<text text-anchor="middle" x="552" y="-140" font-family="Arial" font-size="10.00" fill="#111827">Interrupt aggregation</text>
|
||||||
<text text-anchor="middle" x="551" y="-129" font-family="Arial" font-size="10.00" fill="#111827">RIBP and APB sources to management core</text>
|
<text text-anchor="middle" x="552" y="-129" font-family="Arial" font-size="10.00" fill="#111827">RIBP and APB target IRQs to management core</text>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
@@ -1,84 +0,0 @@
|
|||||||
// Copyright (c) 2023-2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
|
||||||
// retroSoC is licensed under Mulan PSL v2.
|
|
||||||
// You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
||||||
// You may obtain a copy of Mulan PSL v2 at:
|
|
||||||
// http://license.coscl.org.cn/MulanPSL2
|
|
||||||
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
||||||
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
||||||
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
||||||
// See the Mulan PSL v2 for more details.
|
|
||||||
|
|
||||||
`include "mmap_define.svh"
|
|
||||||
|
|
||||||
module ribp2apb (
|
|
||||||
// verilog_format: off
|
|
||||||
input logic clk_i,
|
|
||||||
input logic rst_n_i,
|
|
||||||
ribp_if.slave ribp,
|
|
||||||
`include "soc_apb_ports.svh"
|
|
||||||
// verilog_format: on
|
|
||||||
);
|
|
||||||
|
|
||||||
localparam FSM_IDLE = 2'd0;
|
|
||||||
localparam FSM_SETP = 2'd1;
|
|
||||||
localparam FSM_ENAB = 2'd2;
|
|
||||||
|
|
||||||
logic [31:0] s_rd_data;
|
|
||||||
logic s_xfer_valid, s_xfer_ready, s_xfer_error;
|
|
||||||
logic s_mem_valid_re;
|
|
||||||
logic [1:0] s_fsm_d, s_fsm_q;
|
|
||||||
|
|
||||||
// Registered slave-select one-hot for response mux
|
|
||||||
`include "soc_apb_declarations.svh"
|
|
||||||
|
|
||||||
|
|
||||||
// Generated APB request routing retains the scalar interface protocol.
|
|
||||||
`include "soc_apb_request_routes.svh"
|
|
||||||
|
|
||||||
// verilog_format: off
|
|
||||||
edge_det_sync_re #(1) u_mem_valid_edge_det_sync_re (
|
|
||||||
clk_i,
|
|
||||||
rst_n_i,
|
|
||||||
ribp.valid,
|
|
||||||
s_mem_valid_re
|
|
||||||
);
|
|
||||||
// verilog_format: on
|
|
||||||
|
|
||||||
assign s_xfer_valid = ((s_fsm_q == FSM_IDLE) && s_mem_valid_re) ||
|
|
||||||
(s_fsm_q == FSM_SETP) || (s_fsm_q == FSM_ENAB);
|
|
||||||
|
|
||||||
always_comb begin
|
|
||||||
s_fsm_d = s_fsm_q;
|
|
||||||
unique case (s_fsm_q)
|
|
||||||
FSM_IDLE: if (s_mem_valid_re) s_fsm_d = FSM_SETP;
|
|
||||||
FSM_SETP: s_fsm_d = FSM_ENAB;
|
|
||||||
FSM_ENAB: if (s_xfer_ready) s_fsm_d = FSM_IDLE;
|
|
||||||
default: s_fsm_d = s_fsm_q;
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
dffr #(2) u_fsm_dffr (
|
|
||||||
clk_i,
|
|
||||||
rst_n_i,
|
|
||||||
s_fsm_d,
|
|
||||||
s_fsm_q
|
|
||||||
);
|
|
||||||
|
|
||||||
assign ribp.ready = ribp.valid && (s_fsm_q == FSM_ENAB) && s_xfer_ready;
|
|
||||||
assign ribp.rdata = {32{ribp.ready}} & s_rd_data;
|
|
||||||
assign ribp.resp_err = ribp.ready && s_xfer_error;
|
|
||||||
|
|
||||||
// Capture slave-select one-hot at FSM_SETP for cleaner response mux.
|
|
||||||
`include "soc_apb_select_routes.svh"
|
|
||||||
|
|
||||||
assign s_psel_d = (s_fsm_q == FSM_IDLE && s_mem_valid_re) ? s_psel_comb : s_psel_q;
|
|
||||||
dffr #(NSLV) u_psel_dffr (
|
|
||||||
clk_i,
|
|
||||||
rst_n_i,
|
|
||||||
s_psel_d,
|
|
||||||
s_psel_q
|
|
||||||
);
|
|
||||||
|
|
||||||
// Generated response mux uses the registered one-hot target selection.
|
|
||||||
`include "soc_apb_response_mux.svh"
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
@@ -61,25 +61,34 @@ module rib2apb_sva #(
|
|||||||
input logic rst_n_i,
|
input logic rst_n_i,
|
||||||
input logic [NSLV-1:0] psel_comb_i,
|
input logic [NSLV-1:0] psel_comb_i,
|
||||||
input logic [NSLV-1:0] psel_q_i,
|
input logic [NSLV-1:0] psel_q_i,
|
||||||
input logic rib_ready_i,
|
input logic [ 2:0] fsm_q_i,
|
||||||
|
input logic rsp_valid_i,
|
||||||
|
input logic [ 1:0] rsp_beat_i,
|
||||||
|
input logic rsp_last_i,
|
||||||
input logic xfer_ready_i
|
input logic xfer_ready_i
|
||||||
);
|
);
|
||||||
|
|
||||||
// Address regions are disjoint and only the registered select drives a response.
|
// Address regions are disjoint and only the registered select drives a response.
|
||||||
assert property (@(posedge clk_i) disable iff (!rst_n_i) $onehot0(psel_comb_i));
|
assert property (@(posedge clk_i) disable iff (!rst_n_i) $onehot0(psel_comb_i));
|
||||||
assert property (@(posedge clk_i) disable iff (!rst_n_i) $onehot0(psel_q_i));
|
assert property (@(posedge clk_i) disable iff (!rst_n_i) $onehot0(psel_q_i));
|
||||||
assert property (@(posedge clk_i) disable iff (!rst_n_i) rib_ready_i |-> xfer_ready_i);
|
assert property (@(posedge clk_i) disable iff (!rst_n_i)
|
||||||
|
fsm_q_i == 3'd3 && !xfer_ready_i |=> fsm_q_i == 3'd3);
|
||||||
|
assert property (@(posedge clk_i) disable iff (!rst_n_i)
|
||||||
|
rsp_valid_i |-> rsp_beat_i == 2'd0 && rsp_last_i);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
bind ribp2apb rib2apb_sva #(
|
bind rib2apb rib2apb_sva #(
|
||||||
.NSLV(NSLV)
|
.NSLV(NSLV)
|
||||||
) u_rib2apb_sva (
|
) u_rib2apb_sva (
|
||||||
.clk_i (clk_i),
|
.clk_i (clk_i),
|
||||||
.rst_n_i (rst_n_i),
|
.rst_n_i (rst_n_i),
|
||||||
.psel_comb_i (s_psel_comb),
|
.psel_comb_i (s_psel_comb),
|
||||||
.psel_q_i (s_psel_q),
|
.psel_q_i (s_psel_q),
|
||||||
.rib_ready_i (ribp.ready),
|
.fsm_q_i (s_fsm_q),
|
||||||
|
.rsp_valid_i (rib.rsp_valid),
|
||||||
|
.rsp_beat_i (rib.rsp_beat),
|
||||||
|
.rsp_last_i (rib.rsp_last),
|
||||||
.xfer_ready_i(s_xfer_ready)
|
.xfer_ready_i(s_xfer_ready)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,6 @@
|
|||||||
/ip/ribp/peripheral/timer.sv
|
/ip/ribp/peripheral/timer.sv
|
||||||
/ip/ribp/serial/uart.sv
|
/ip/ribp/serial/uart.sv
|
||||||
/ip/ribp/peripheral/gpio.sv
|
/ip/ribp/peripheral/gpio.sv
|
||||||
/ip/ribp/interconnect/ribp2apb.sv
|
|
||||||
/top/ahbl2ribp.sv
|
/top/ahbl2ribp.sv
|
||||||
/ip/ribp/interconnect/axi4l2ribp.sv
|
/ip/ribp/interconnect/axi4l2ribp.sv
|
||||||
/ip/ribp/util/async_fifo.sv
|
/ip/ribp/util/async_fifo.sv
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
/top/gpio_pad_bridge.sv
|
/top/gpio_pad_bridge.sv
|
||||||
/top/ribp2rib.sv
|
/top/ribp2rib.sv
|
||||||
/top/rib2ribp.sv
|
/top/rib2ribp.sv
|
||||||
|
/top/rib2apb.sv
|
||||||
/top/rib_error_slave.sv
|
/top/rib_error_slave.sv
|
||||||
/top/rib2ram.sv
|
/top/rib2ram.sv
|
||||||
/top/core_wrapper.sv
|
/top/core_wrapper.sv
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ module bus_formal_design (
|
|||||||
rib_if user_rib ();
|
rib_if user_rib ();
|
||||||
rib_if dma_rib ();
|
rib_if dma_rib ();
|
||||||
rib_if rib ();
|
rib_if rib ();
|
||||||
ribp_if apb_ribp ();
|
rib_if apb_rib ();
|
||||||
|
|
||||||
(* anyseq *)logic f_mgmt_valid;
|
(* anyseq *)logic f_mgmt_valid;
|
||||||
(* anyseq *)logic [31:0] f_mgmt_addr;
|
(* anyseq *)logic [31:0] f_mgmt_addr;
|
||||||
@@ -64,6 +64,9 @@ module bus_formal_design (
|
|||||||
logic target_write_done_q;
|
logic target_write_done_q;
|
||||||
logic [ 1:0] target_len_q;
|
logic [ 1:0] target_len_q;
|
||||||
logic [ 1:0] target_beat_q;
|
logic [ 1:0] target_beat_q;
|
||||||
|
logic apb_active_q;
|
||||||
|
logic apb_write_q;
|
||||||
|
logic apb_write_done_q;
|
||||||
logic [31:0] fault_addr;
|
logic [31:0] fault_addr;
|
||||||
logic [ 3:0] fault_wstrb;
|
logic [ 3:0] fault_wstrb;
|
||||||
logic fault_reserved;
|
logic fault_reserved;
|
||||||
@@ -138,27 +141,52 @@ module bus_formal_design (
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
assign apb_ribp.ready = apb_ribp.valid;
|
assign apb_rib.cmd_ready = ~apb_active_q;
|
||||||
assign apb_ribp.rdata = 32'h1234_5678;
|
assign apb_rib.w_ready = apb_active_q && apb_write_q && ~apb_write_done_q;
|
||||||
assign apb_ribp.resp_err = 1'b0;
|
assign apb_rib.rsp_valid = apb_active_q && (~apb_write_q || apb_write_done_q);
|
||||||
|
assign apb_rib.rdata = 32'h1234_5678;
|
||||||
|
assign apb_rib.resp_err = 1'b0;
|
||||||
|
assign apb_rib.resp_code = `RIB_RESP_OK;
|
||||||
|
assign apb_rib.rsp_beat = '0;
|
||||||
|
assign apb_rib.rsp_last = 1'b1;
|
||||||
|
|
||||||
assign mgmt_valid = mgmt_ribp.valid;
|
always_ff @(posedge clk_i) begin
|
||||||
assign mgmt_addr = mgmt_ribp.addr;
|
if (!rst_n_i) begin
|
||||||
assign mgmt_wstrb = mgmt_ribp.wstrb;
|
apb_active_q <= 1'b0;
|
||||||
assign mgmt_ready = mgmt_ribp.ready;
|
apb_write_q <= 1'b0;
|
||||||
assign user_cmd_valid = user_rib.cmd_valid;
|
apb_write_done_q <= 1'b0;
|
||||||
assign user_cmd_ready = user_rib.cmd_ready;
|
end else begin
|
||||||
assign user_cmd_addr = user_rib.cmd_addr;
|
if (apb_rib.cmd_valid && apb_rib.cmd_ready) begin
|
||||||
assign user_cmd_write = user_rib.cmd_write;
|
apb_active_q <= 1'b1;
|
||||||
assign user_cmd_len = user_rib.cmd_len;
|
apb_write_q <= apb_rib.cmd_write;
|
||||||
assign dma_cmd_valid = dma_rib.cmd_valid;
|
apb_write_done_q <= 1'b0;
|
||||||
assign dma_cmd_ready = dma_rib.cmd_ready;
|
end
|
||||||
assign dma_cmd_addr = dma_rib.cmd_addr;
|
if (apb_rib.w_valid && apb_rib.w_ready && apb_rib.wlast) begin
|
||||||
assign dma_cmd_write = dma_rib.cmd_write;
|
apb_write_done_q <= 1'b1;
|
||||||
assign dma_cmd_len = dma_rib.cmd_len;
|
end
|
||||||
assign rib_cmd_valid = rib.cmd_valid;
|
if (apb_rib.rsp_valid && apb_rib.rsp_ready) begin
|
||||||
assign rib_cmd_len = rib.cmd_len;
|
apb_active_q <= 1'b0;
|
||||||
assign apb_valid = apb_ribp.valid;
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign mgmt_valid = mgmt_ribp.valid;
|
||||||
|
assign mgmt_addr = mgmt_ribp.addr;
|
||||||
|
assign mgmt_wstrb = mgmt_ribp.wstrb;
|
||||||
|
assign mgmt_ready = mgmt_ribp.ready;
|
||||||
|
assign user_cmd_valid = user_rib.cmd_valid;
|
||||||
|
assign user_cmd_ready = user_rib.cmd_ready;
|
||||||
|
assign user_cmd_addr = user_rib.cmd_addr;
|
||||||
|
assign user_cmd_write = user_rib.cmd_write;
|
||||||
|
assign user_cmd_len = user_rib.cmd_len;
|
||||||
|
assign dma_cmd_valid = dma_rib.cmd_valid;
|
||||||
|
assign dma_cmd_ready = dma_rib.cmd_ready;
|
||||||
|
assign dma_cmd_addr = dma_rib.cmd_addr;
|
||||||
|
assign dma_cmd_write = dma_rib.cmd_write;
|
||||||
|
assign dma_cmd_len = dma_rib.cmd_len;
|
||||||
|
assign rib_cmd_valid = rib.cmd_valid;
|
||||||
|
assign rib_cmd_len = rib.cmd_len;
|
||||||
|
assign apb_valid = apb_rib.cmd_valid;
|
||||||
|
|
||||||
bus u_dut (
|
bus u_dut (
|
||||||
.clk_i (clk_i),
|
.clk_i (clk_i),
|
||||||
@@ -169,7 +197,7 @@ module bus_formal_design (
|
|||||||
.user_bus_enable_i(1'b1),
|
.user_bus_enable_i(1'b1),
|
||||||
.user_bus_idle_o (user_idle),
|
.user_bus_idle_o (user_idle),
|
||||||
.rib (rib),
|
.rib (rib),
|
||||||
.apb_ribp (apb_ribp),
|
.apb_rib (apb_rib),
|
||||||
.perf_enable_i (1'b0),
|
.perf_enable_i (1'b0),
|
||||||
.perf_clear_i (1'b0),
|
.perf_clear_i (1'b0),
|
||||||
.fault_valid_o (fault_valid),
|
.fault_valid_o (fault_valid),
|
||||||
|
|||||||
@@ -51,14 +51,14 @@ def source_files(target: str) -> list[Path]:
|
|||||||
TOP / "rib2ribp.sv",
|
TOP / "rib2ribp.sv",
|
||||||
SCRIPT_DIR / "rib_adapter_formal.sv",
|
SCRIPT_DIR / "rib_adapter_formal.sv",
|
||||||
]
|
]
|
||||||
if target == "ribp2apb":
|
if target == "rib2apb":
|
||||||
return [
|
return [
|
||||||
COMMON_RTL / "interface/ribp_if.sv",
|
|
||||||
COMMON_RTL / "interface/apb4_pure_if.sv",
|
COMMON_RTL / "interface/apb4_pure_if.sv",
|
||||||
COMMON_RTL / "utils/register.sv",
|
COMMON_RTL / "utils/register.sv",
|
||||||
COMMON_RTL / "utils/edge_det.sv",
|
COMMON_RTL / "utils/spill_register.sv",
|
||||||
INTERCONNECT / "ribp2apb.sv",
|
TOP / "rib_if.sv",
|
||||||
SCRIPT_DIR / "ribp2apb_formal.sv",
|
TOP / "rib2apb.sv",
|
||||||
|
SCRIPT_DIR / "rib2apb_formal.sv",
|
||||||
]
|
]
|
||||||
if target == "sysctrl":
|
if target == "sysctrl":
|
||||||
return [
|
return [
|
||||||
@@ -122,7 +122,7 @@ def parse_args() -> argparse.Namespace:
|
|||||||
choices=(
|
choices=(
|
||||||
"bus",
|
"bus",
|
||||||
"rib_adapter",
|
"rib_adapter",
|
||||||
"ribp2apb",
|
"rib2apb",
|
||||||
"sysctrl",
|
"sysctrl",
|
||||||
"pll_rcu",
|
"pll_rcu",
|
||||||
"gpio_user",
|
"gpio_user",
|
||||||
|
|||||||
@@ -0,0 +1,153 @@
|
|||||||
|
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||||
|
// retroSoC is licensed under Mulan PSL v2.
|
||||||
|
// You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
// You may obtain a copy of the Mulan PSL v2 at:
|
||||||
|
// http://license.coscl.org.cn/MulanPSL2
|
||||||
|
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
// See the Mulan PSL v2 for more details.
|
||||||
|
|
||||||
|
module formal_apb_slave (
|
||||||
|
apb4_pure_if.slave apb
|
||||||
|
);
|
||||||
|
|
||||||
|
(* anyseq *)logic f_ready;
|
||||||
|
(* anyseq *)logic [31:0] f_rdata;
|
||||||
|
(* anyseq *)logic f_slverr;
|
||||||
|
|
||||||
|
assign apb.pready = f_ready;
|
||||||
|
assign apb.prdata = f_rdata;
|
||||||
|
assign apb.pslverr = f_slverr;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
module rib2apb_formal_design (
|
||||||
|
input logic clk_i,
|
||||||
|
output logic rst_n_i,
|
||||||
|
output logic f_past_valid,
|
||||||
|
output logic rib_cmd_valid,
|
||||||
|
output logic [31:0] rib_cmd_addr,
|
||||||
|
output logic rib_cmd_write,
|
||||||
|
output logic [ 1:0] rib_cmd_len,
|
||||||
|
output logic rib_cmd_ready,
|
||||||
|
output logic rib_w_valid,
|
||||||
|
output logic [31:0] rib_wdata,
|
||||||
|
output logic [ 3:0] rib_wstrb,
|
||||||
|
output logic rib_wlast,
|
||||||
|
output logic rib_w_ready,
|
||||||
|
output logic rib_rsp_valid,
|
||||||
|
output logic [31:0] rib_rdata,
|
||||||
|
output logic rib_resp_err,
|
||||||
|
output logic [ 2:0] rib_resp_code,
|
||||||
|
output logic [ 1:0] rib_rsp_beat,
|
||||||
|
output logic rib_rsp_last,
|
||||||
|
output logic rib_rsp_ready,
|
||||||
|
output logic [ 9:0] psel_comb,
|
||||||
|
output logic [ 9:0] psel_q,
|
||||||
|
output logic xfer_ready,
|
||||||
|
output logic xfer_error,
|
||||||
|
output logic rsp_input_valid,
|
||||||
|
output logic rsp_input_ready,
|
||||||
|
output logic [38:0] rsp_input_data,
|
||||||
|
output logic [ 2:0] fsm_q
|
||||||
|
);
|
||||||
|
|
||||||
|
rib_if rib ();
|
||||||
|
apb4_pure_if archinfo ();
|
||||||
|
apb4_pure_if rng ();
|
||||||
|
apb4_pure_if uart ();
|
||||||
|
apb4_pure_if pwm ();
|
||||||
|
apb4_pure_if ps2 ();
|
||||||
|
apb4_pure_if rtc ();
|
||||||
|
apb4_pure_if wdg ();
|
||||||
|
apb4_pure_if crc ();
|
||||||
|
apb4_pure_if tmr ();
|
||||||
|
apb4_pure_if user_ip ();
|
||||||
|
|
||||||
|
(* anyseq *)logic f_rib_cmd_valid;
|
||||||
|
(* anyseq *)logic [31:0] f_rib_cmd_addr;
|
||||||
|
(* anyseq *)logic f_rib_cmd_write;
|
||||||
|
(* anyseq *)logic [ 1:0] f_rib_cmd_len;
|
||||||
|
(* anyseq *)logic f_rib_w_valid;
|
||||||
|
(* anyseq *)logic [31:0] f_rib_wdata;
|
||||||
|
(* anyseq *)logic [ 3:0] f_rib_wstrb;
|
||||||
|
(* anyseq *)logic f_rib_wlast;
|
||||||
|
(* anyseq *)logic f_rib_rsp_ready;
|
||||||
|
|
||||||
|
assign rib.cmd_valid = f_rib_cmd_valid;
|
||||||
|
assign rib.cmd_addr = f_rib_cmd_addr;
|
||||||
|
assign rib.cmd_write = f_rib_cmd_write;
|
||||||
|
assign rib.cmd_len = f_rib_cmd_len;
|
||||||
|
assign rib.w_valid = f_rib_w_valid;
|
||||||
|
assign rib.wdata = f_rib_wdata;
|
||||||
|
assign rib.wstrb = f_rib_wstrb;
|
||||||
|
assign rib.wlast = f_rib_wlast;
|
||||||
|
assign rib.rsp_ready = f_rib_rsp_ready;
|
||||||
|
|
||||||
|
assign rib_cmd_valid = rib.cmd_valid;
|
||||||
|
assign rib_cmd_addr = rib.cmd_addr;
|
||||||
|
assign rib_cmd_write = rib.cmd_write;
|
||||||
|
assign rib_cmd_len = rib.cmd_len;
|
||||||
|
assign rib_cmd_ready = rib.cmd_ready;
|
||||||
|
assign rib_w_valid = rib.w_valid;
|
||||||
|
assign rib_wdata = rib.wdata;
|
||||||
|
assign rib_wstrb = rib.wstrb;
|
||||||
|
assign rib_wlast = rib.wlast;
|
||||||
|
assign rib_w_ready = rib.w_ready;
|
||||||
|
assign rib_rsp_valid = rib.rsp_valid;
|
||||||
|
assign rib_rdata = rib.rdata;
|
||||||
|
assign rib_resp_err = rib.resp_err;
|
||||||
|
assign rib_resp_code = rib.resp_code;
|
||||||
|
assign rib_rsp_beat = rib.rsp_beat;
|
||||||
|
assign rib_rsp_last = rib.rsp_last;
|
||||||
|
assign rib_rsp_ready = rib.rsp_ready;
|
||||||
|
|
||||||
|
formal_apb_slave u_archinfo_slave (.apb(archinfo));
|
||||||
|
formal_apb_slave u_rng_slave (.apb(rng));
|
||||||
|
formal_apb_slave u_uart_slave (.apb(uart));
|
||||||
|
formal_apb_slave u_pwm_slave (.apb(pwm));
|
||||||
|
formal_apb_slave u_ps2_slave (.apb(ps2));
|
||||||
|
formal_apb_slave u_rtc_slave (.apb(rtc));
|
||||||
|
formal_apb_slave u_wdg_slave (.apb(wdg));
|
||||||
|
formal_apb_slave u_crc_slave (.apb(crc));
|
||||||
|
formal_apb_slave u_tmr_slave (.apb(tmr));
|
||||||
|
formal_apb_slave u_user_ip_slave (.apb(user_ip));
|
||||||
|
|
||||||
|
rib2apb u_dut (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i (rst_n_i),
|
||||||
|
.rib (rib),
|
||||||
|
.archinfo(archinfo),
|
||||||
|
.rng (rng),
|
||||||
|
.uart (uart),
|
||||||
|
.pwm (pwm),
|
||||||
|
.ps2 (ps2),
|
||||||
|
.rtc (rtc),
|
||||||
|
.wdg (wdg),
|
||||||
|
.crc (crc),
|
||||||
|
.tmr (tmr),
|
||||||
|
.user_ip (user_ip)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign psel_comb = u_dut.s_psel_comb;
|
||||||
|
assign psel_q = u_dut.s_psel_q;
|
||||||
|
assign xfer_ready = u_dut.s_xfer_ready;
|
||||||
|
assign xfer_error = u_dut.s_xfer_error;
|
||||||
|
assign rsp_input_valid = u_dut.s_rsp_input_valid;
|
||||||
|
assign rsp_input_ready = u_dut.s_rsp_input_ready;
|
||||||
|
assign rsp_input_data = u_dut.s_rsp_input_data;
|
||||||
|
assign fsm_q = u_dut.s_fsm_q;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
rst_n_i = 1'b0;
|
||||||
|
f_past_valid = 1'b0;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge clk_i) begin
|
||||||
|
rst_n_i <= 1'b1;
|
||||||
|
f_past_valid <= 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||||
|
// retroSoC is licensed under Mulan PSL v2.
|
||||||
|
// You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
// You may obtain a copy of the Mulan PSL v2 at:
|
||||||
|
// http://license.coscl.org.cn/MulanPSL2
|
||||||
|
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
// See the Mulan PSL v2 for more details.
|
||||||
|
|
||||||
|
module rib2apb_formal;
|
||||||
|
|
||||||
|
localparam logic [2:0] FSM_ENAB = 3'd3;
|
||||||
|
localparam logic [2:0] FSM_ERR = 3'd5;
|
||||||
|
localparam logic [2:0] RIB_RESP_OK = 3'd0;
|
||||||
|
localparam logic [2:0] RIB_RESP_SLVERR = 3'd3;
|
||||||
|
|
||||||
|
(* anyseq *) (* gclk *)reg clk_i;
|
||||||
|
wire rst_n_i;
|
||||||
|
wire f_past_valid;
|
||||||
|
wire rib_cmd_valid;
|
||||||
|
wire [31:0] rib_cmd_addr;
|
||||||
|
wire rib_cmd_write;
|
||||||
|
wire [ 1:0] rib_cmd_len;
|
||||||
|
wire rib_cmd_ready;
|
||||||
|
wire rib_w_valid;
|
||||||
|
wire [31:0] rib_wdata;
|
||||||
|
wire [ 3:0] rib_wstrb;
|
||||||
|
wire rib_wlast;
|
||||||
|
wire rib_w_ready;
|
||||||
|
wire rib_rsp_valid;
|
||||||
|
wire [31:0] rib_rdata;
|
||||||
|
wire rib_resp_err;
|
||||||
|
wire [ 2:0] rib_resp_code;
|
||||||
|
wire [ 1:0] rib_rsp_beat;
|
||||||
|
wire rib_rsp_last;
|
||||||
|
wire rib_rsp_ready;
|
||||||
|
wire [ 9:0] psel_comb;
|
||||||
|
wire [ 9:0] psel_q;
|
||||||
|
wire xfer_ready;
|
||||||
|
wire xfer_error;
|
||||||
|
wire rsp_input_valid;
|
||||||
|
wire rsp_input_ready;
|
||||||
|
wire [38:0] rsp_input_data;
|
||||||
|
wire [ 2:0] fsm_q;
|
||||||
|
|
||||||
|
rib2apb_formal_design u_design (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i (rst_n_i),
|
||||||
|
.f_past_valid (f_past_valid),
|
||||||
|
.rib_cmd_valid (rib_cmd_valid),
|
||||||
|
.rib_cmd_addr (rib_cmd_addr),
|
||||||
|
.rib_cmd_write (rib_cmd_write),
|
||||||
|
.rib_cmd_len (rib_cmd_len),
|
||||||
|
.rib_cmd_ready (rib_cmd_ready),
|
||||||
|
.rib_w_valid (rib_w_valid),
|
||||||
|
.rib_wdata (rib_wdata),
|
||||||
|
.rib_wstrb (rib_wstrb),
|
||||||
|
.rib_wlast (rib_wlast),
|
||||||
|
.rib_w_ready (rib_w_ready),
|
||||||
|
.rib_rsp_valid (rib_rsp_valid),
|
||||||
|
.rib_rdata (rib_rdata),
|
||||||
|
.rib_resp_err (rib_resp_err),
|
||||||
|
.rib_resp_code (rib_resp_code),
|
||||||
|
.rib_rsp_beat (rib_rsp_beat),
|
||||||
|
.rib_rsp_last (rib_rsp_last),
|
||||||
|
.rib_rsp_ready (rib_rsp_ready),
|
||||||
|
.psel_comb (psel_comb),
|
||||||
|
.psel_q (psel_q),
|
||||||
|
.xfer_ready (xfer_ready),
|
||||||
|
.xfer_error (xfer_error),
|
||||||
|
.rsp_input_valid(rsp_input_valid),
|
||||||
|
.rsp_input_ready(rsp_input_ready),
|
||||||
|
.rsp_input_data (rsp_input_data),
|
||||||
|
.fsm_q (fsm_q)
|
||||||
|
);
|
||||||
|
|
||||||
|
always @(posedge clk_i) begin
|
||||||
|
if (f_past_valid && $past(rst_n_i && rib_cmd_valid && !rib_cmd_ready)) begin
|
||||||
|
assume (rib_cmd_valid);
|
||||||
|
assume (rib_cmd_addr == $past(rib_cmd_addr));
|
||||||
|
assume (rib_cmd_write == $past(rib_cmd_write));
|
||||||
|
assume (rib_cmd_len == $past(rib_cmd_len));
|
||||||
|
end
|
||||||
|
if (f_past_valid && $past(rst_n_i && rib_w_valid && !rib_w_ready)) begin
|
||||||
|
assume (rib_w_valid);
|
||||||
|
assume (rib_wdata == $past(rib_wdata));
|
||||||
|
assume (rib_wstrb == $past(rib_wstrb));
|
||||||
|
assume (rib_wlast == $past(rib_wlast));
|
||||||
|
end
|
||||||
|
|
||||||
|
if (rst_n_i) begin
|
||||||
|
assert ($onehot0(psel_comb));
|
||||||
|
if (f_past_valid && $past(rst_n_i && fsm_q == FSM_ENAB && !xfer_ready)) begin
|
||||||
|
assert (fsm_q == FSM_ENAB);
|
||||||
|
assert (psel_q == $past(psel_q));
|
||||||
|
end
|
||||||
|
if (fsm_q == FSM_ENAB && xfer_ready) begin
|
||||||
|
assert (rsp_input_valid);
|
||||||
|
assert (rsp_input_data[38:36] == 3'b100);
|
||||||
|
assert (rsp_input_data[32] == xfer_error);
|
||||||
|
assert (rsp_input_data[35:33] == (xfer_error ? RIB_RESP_SLVERR : RIB_RESP_OK));
|
||||||
|
end
|
||||||
|
if (fsm_q == FSM_ERR) begin
|
||||||
|
assert (rsp_input_valid);
|
||||||
|
assert (rsp_input_data[38:36] == 3'b100);
|
||||||
|
assert (rsp_input_data[32]);
|
||||||
|
end
|
||||||
|
cover (fsm_q == FSM_ENAB && xfer_ready && rsp_input_ready);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
|
||||||
// retroSoC is licensed under Mulan PSL v2.
|
|
||||||
// You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
||||||
// You may obtain a copy of Mulan PSL v2 at:
|
|
||||||
// http://license.coscl.org.cn/MulanPSL2
|
|
||||||
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
||||||
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
||||||
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
// See the Mulan PSL v2 for more details.
|
|
||||||
|
|
||||||
module formal_apb_slave (
|
|
||||||
apb4_pure_if.slave apb
|
|
||||||
);
|
|
||||||
|
|
||||||
(* anyseq *)logic f_ready;
|
|
||||||
(* anyseq *)logic [31:0] f_rdata;
|
|
||||||
(* anyseq *)logic f_slverr;
|
|
||||||
|
|
||||||
assign apb.pready = f_ready;
|
|
||||||
assign apb.prdata = f_rdata;
|
|
||||||
assign apb.pslverr = f_slverr;
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
module ribp2apb_formal_design (
|
|
||||||
input logic clk_i,
|
|
||||||
output logic rst_n_i,
|
|
||||||
output logic f_past_valid,
|
|
||||||
output logic rib_valid,
|
|
||||||
output logic [31:0] rib_addr,
|
|
||||||
output logic [31:0] rib_wdata,
|
|
||||||
output logic [ 3:0] rib_wstrb,
|
|
||||||
output logic rib_ready,
|
|
||||||
output logic rib_resp_err,
|
|
||||||
output logic [ 9:0] psel_comb,
|
|
||||||
output logic [ 9:0] psel_q,
|
|
||||||
output logic xfer_ready,
|
|
||||||
output logic xfer_error,
|
|
||||||
output logic [ 1:0] fsm_q
|
|
||||||
);
|
|
||||||
|
|
||||||
ribp_if rib ();
|
|
||||||
apb4_pure_if archinfo ();
|
|
||||||
apb4_pure_if rng ();
|
|
||||||
apb4_pure_if uart ();
|
|
||||||
apb4_pure_if pwm ();
|
|
||||||
apb4_pure_if ps2 ();
|
|
||||||
apb4_pure_if rtc ();
|
|
||||||
apb4_pure_if wdg ();
|
|
||||||
apb4_pure_if crc ();
|
|
||||||
apb4_pure_if tmr ();
|
|
||||||
apb4_pure_if user_ip ();
|
|
||||||
|
|
||||||
(* anyseq *)logic f_rib_valid;
|
|
||||||
(* anyseq *)logic [31:0] f_rib_addr;
|
|
||||||
(* anyseq *)logic [31:0] f_rib_wdata;
|
|
||||||
(* anyseq *)logic [ 3:0] f_rib_wstrb;
|
|
||||||
|
|
||||||
assign rib.valid = f_rib_valid;
|
|
||||||
assign rib.addr = f_rib_addr;
|
|
||||||
assign rib.wdata = f_rib_wdata;
|
|
||||||
assign rib.wstrb = f_rib_wstrb;
|
|
||||||
assign rib_valid = rib.valid;
|
|
||||||
assign rib_addr = rib.addr;
|
|
||||||
assign rib_wdata = rib.wdata;
|
|
||||||
assign rib_wstrb = rib.wstrb;
|
|
||||||
assign rib_ready = rib.ready;
|
|
||||||
assign rib_resp_err = rib.resp_err;
|
|
||||||
|
|
||||||
formal_apb_slave u_archinfo_slave (.apb(archinfo));
|
|
||||||
formal_apb_slave u_rng_slave (.apb(rng));
|
|
||||||
formal_apb_slave u_uart_slave (.apb(uart));
|
|
||||||
formal_apb_slave u_pwm_slave (.apb(pwm));
|
|
||||||
formal_apb_slave u_ps2_slave (.apb(ps2));
|
|
||||||
formal_apb_slave u_rtc_slave (.apb(rtc));
|
|
||||||
formal_apb_slave u_wdg_slave (.apb(wdg));
|
|
||||||
formal_apb_slave u_crc_slave (.apb(crc));
|
|
||||||
formal_apb_slave u_tmr_slave (.apb(tmr));
|
|
||||||
formal_apb_slave u_user_ip_slave (.apb(user_ip));
|
|
||||||
|
|
||||||
ribp2apb u_dut (
|
|
||||||
.clk_i (clk_i),
|
|
||||||
.rst_n_i (rst_n_i),
|
|
||||||
.ribp (rib),
|
|
||||||
.archinfo(archinfo),
|
|
||||||
.rng (rng),
|
|
||||||
.uart (uart),
|
|
||||||
.pwm (pwm),
|
|
||||||
.ps2 (ps2),
|
|
||||||
.rtc (rtc),
|
|
||||||
.wdg (wdg),
|
|
||||||
.crc (crc),
|
|
||||||
.tmr (tmr),
|
|
||||||
.user_ip (user_ip)
|
|
||||||
);
|
|
||||||
|
|
||||||
assign psel_comb = u_dut.s_psel_comb;
|
|
||||||
assign psel_q = u_dut.s_psel_q;
|
|
||||||
assign xfer_ready = u_dut.s_xfer_ready;
|
|
||||||
assign xfer_error = u_dut.s_xfer_error;
|
|
||||||
assign fsm_q = u_dut.s_fsm_q;
|
|
||||||
|
|
||||||
initial begin
|
|
||||||
rst_n_i = 1'b0;
|
|
||||||
f_past_valid = 1'b0;
|
|
||||||
end
|
|
||||||
|
|
||||||
always_ff @(posedge clk_i) begin
|
|
||||||
rst_n_i <= 1'b1;
|
|
||||||
f_past_valid <= 1'b1;
|
|
||||||
end
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
|
||||||
// retroSoC is licensed under Mulan PSL v2.
|
|
||||||
// You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
||||||
// You may obtain a copy of Mulan PSL v2 at:
|
|
||||||
// http://license.coscl.org.cn/MulanPSL2
|
|
||||||
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
||||||
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
||||||
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
// See the Mulan PSL v2 for more details.
|
|
||||||
|
|
||||||
module ribp2apb_formal;
|
|
||||||
|
|
||||||
localparam [1:0] FSM_SETP = 2'd1;
|
|
||||||
localparam [1:0] FSM_ENAB = 2'd2;
|
|
||||||
|
|
||||||
(* anyseq *) (* gclk *)reg clk_i;
|
|
||||||
wire rst_n_i;
|
|
||||||
wire f_past_valid;
|
|
||||||
wire rib_valid;
|
|
||||||
wire [31:0] rib_addr;
|
|
||||||
wire [31:0] rib_wdata;
|
|
||||||
wire [ 3:0] rib_wstrb;
|
|
||||||
wire rib_ready, rib_resp_err;
|
|
||||||
wire [9:0] psel_comb;
|
|
||||||
wire [9:0] psel_q;
|
|
||||||
wire xfer_ready, xfer_error;
|
|
||||||
wire [1:0] fsm_q;
|
|
||||||
|
|
||||||
ribp2apb_formal_design u_design (
|
|
||||||
.clk_i (clk_i),
|
|
||||||
.rst_n_i (rst_n_i),
|
|
||||||
.f_past_valid(f_past_valid),
|
|
||||||
.rib_valid (rib_valid),
|
|
||||||
.rib_addr (rib_addr),
|
|
||||||
.rib_wdata (rib_wdata),
|
|
||||||
.rib_wstrb (rib_wstrb),
|
|
||||||
.rib_ready (rib_ready),
|
|
||||||
.rib_resp_err(rib_resp_err),
|
|
||||||
.psel_comb (psel_comb),
|
|
||||||
.psel_q (psel_q),
|
|
||||||
.xfer_ready (xfer_ready),
|
|
||||||
.xfer_error (xfer_error),
|
|
||||||
.fsm_q (fsm_q)
|
|
||||||
);
|
|
||||||
|
|
||||||
always @(posedge clk_i) begin
|
|
||||||
if (f_past_valid && $past(rst_n_i && rib_valid && !rib_ready)) begin
|
|
||||||
assume (rib_valid);
|
|
||||||
assume (rib_addr == $past(rib_addr));
|
|
||||||
assume (rib_wdata == $past(rib_wdata));
|
|
||||||
assume (rib_wstrb == $past(rib_wstrb));
|
|
||||||
end
|
|
||||||
|
|
||||||
if (rst_n_i) begin
|
|
||||||
assert ($onehot0(psel_comb));
|
|
||||||
assert ($onehot0(psel_q));
|
|
||||||
if (rib_ready) begin
|
|
||||||
assert (xfer_ready);
|
|
||||||
assert (fsm_q == FSM_ENAB);
|
|
||||||
assert (rib_resp_err == xfer_error);
|
|
||||||
end else begin
|
|
||||||
assert (!rib_resp_err);
|
|
||||||
end
|
|
||||||
if (f_past_valid && $past(rst_n_i && fsm_q == FSM_SETP)) begin
|
|
||||||
assert (psel_q == $past(psel_q));
|
|
||||||
end
|
|
||||||
if (f_past_valid && $past(rst_n_i && fsm_q == FSM_ENAB && !xfer_ready)) begin
|
|
||||||
assert (fsm_q == FSM_ENAB);
|
|
||||||
assert (psel_q == $past(psel_q));
|
|
||||||
end
|
|
||||||
cover (fsm_q == FSM_ENAB && rib_ready);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
@@ -5,7 +5,7 @@ that is not part of the software address-map ABI or the package pad map.
|
|||||||
|
|
||||||
The topology generator validates rib RIB and APB target ownership against
|
The topology generator validates rib RIB and APB target ownership against
|
||||||
`../address_map/memory_map.json` and emits generated SystemVerilog include
|
`../address_map/memory_map.json` and emits generated SystemVerilog include
|
||||||
files for `ip_ribp_wrapper.sv`, `ip_apb_wrapper.sv`, `ribp2apb.sv`, and
|
files for `ip_ribp_wrapper.sv`, `ip_apb_wrapper.sv`, `rib2apb.sv`, and
|
||||||
`retrosoc.sv`. The output retains scalar interface instances and ports, so it
|
`retrosoc.sv`. The output retains scalar interface instances and ports, so it
|
||||||
does not depend on interface-array support in FPGA or netlist simulation tools.
|
does not depend on interface-array support in FPGA or netlist simulation tools.
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ FABRIC_PROTOCOLS = {
|
|||||||
"user": "rib",
|
"user": "rib",
|
||||||
"dma": "rib",
|
"dma": "rib",
|
||||||
"rib": "rib",
|
"rib": "rib",
|
||||||
"apb": "ribp",
|
"apb": "rib",
|
||||||
}
|
}
|
||||||
IRQ_GROUP_NAMES = ("ribp", "apb")
|
IRQ_GROUP_NAMES = ("ribp", "apb")
|
||||||
IRQ_VECTOR_WIDTH = 32
|
IRQ_VECTOR_WIDTH = 32
|
||||||
@@ -657,7 +657,7 @@ def render_apb_declarations(targets: list[ApbTarget]) -> str:
|
|||||||
[
|
[
|
||||||
"// Generated by rtl/mini/integration/generate_soc_topology.py; do not edit.",
|
"// Generated by rtl/mini/integration/generate_soc_topology.py; do not edit.",
|
||||||
f" localparam int NSLV = {count};",
|
f" localparam int NSLV = {count};",
|
||||||
" logic [NSLV-1:0] s_psel_comb, s_psel_d, s_psel_q;",
|
" logic [NSLV-1:0] s_psel_comb, s_psel_q;",
|
||||||
"",
|
"",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@@ -668,13 +668,13 @@ def render_apb_request_routes(targets: list[ApbTarget]) -> str:
|
|||||||
for target in targets:
|
for target in targets:
|
||||||
lines.extend(
|
lines.extend(
|
||||||
[
|
[
|
||||||
f" assign {target.name}.paddr = ribp.addr;",
|
f" assign {target.name}.paddr = s_addr_q;",
|
||||||
f" assign {target.name}.pprot = '0;",
|
f" assign {target.name}.pprot = '0;",
|
||||||
f" assign {target.name}.psel = s_xfer_valid && `SOC_ADDR_IS_{target.region}(ribp.addr);",
|
f" assign {target.name}.psel = s_xfer_valid && s_psel_q[{target.slot}];",
|
||||||
f" assign {target.name}.penable = s_fsm_q == FSM_ENAB;",
|
f" assign {target.name}.penable = s_fsm_q == FSM_ENAB;",
|
||||||
f" assign {target.name}.pwrite = |ribp.wstrb;",
|
f" assign {target.name}.pwrite = s_write_q;",
|
||||||
f" assign {target.name}.pwdata = ribp.wdata;",
|
f" assign {target.name}.pwdata = s_wdata_q;",
|
||||||
f" assign {target.name}.pstrb = ribp.wstrb;",
|
f" assign {target.name}.pstrb = s_wstrb_q;",
|
||||||
"",
|
"",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@@ -684,7 +684,7 @@ def render_apb_request_routes(targets: list[ApbTarget]) -> str:
|
|||||||
def render_apb_select_routes(targets: list[ApbTarget]) -> str:
|
def render_apb_select_routes(targets: list[ApbTarget]) -> str:
|
||||||
lines = ["// Generated by rtl/mini/integration/generate_soc_topology.py; do not edit."]
|
lines = ["// Generated by rtl/mini/integration/generate_soc_topology.py; do not edit."]
|
||||||
lines.extend(
|
lines.extend(
|
||||||
f" assign s_psel_comb[{target.slot}] = `SOC_ADDR_IS_{target.region}(ribp.addr);"
|
f" assign s_psel_comb[{target.slot}] = `SOC_ADDR_IS_{target.region}(rib.cmd_addr);"
|
||||||
for target in targets
|
for target in targets
|
||||||
)
|
)
|
||||||
return "\n".join(lines) + "\n"
|
return "\n".join(lines) + "\n"
|
||||||
@@ -736,7 +736,7 @@ def render_bus_fabric_connections(links: list[FabricLink]) -> str:
|
|||||||
"user": "user_rib",
|
"user": "user_rib",
|
||||||
"dma": "dma_rib",
|
"dma": "dma_rib",
|
||||||
"rib": "rib",
|
"rib": "rib",
|
||||||
"apb": "apb_ribp",
|
"apb": "apb_rib",
|
||||||
}
|
}
|
||||||
interfaces = {link.name: link.interface for link in links}
|
interfaces = {link.name: link.interface for link in links}
|
||||||
lines = ["// Generated by rtl/mini/integration/generate_soc_topology.py; do not edit."]
|
lines = ["// Generated by rtl/mini/integration/generate_soc_topology.py; do not edit."]
|
||||||
@@ -905,7 +905,7 @@ def generate(topology_path: Path, memory_map_path: Path, output_dir: Path) -> No
|
|||||||
)
|
)
|
||||||
atomic_write(
|
atomic_write(
|
||||||
rtl_dir / "soc_ip_apb_wrapper_fabric.svh",
|
rtl_dir / "soc_ip_apb_wrapper_fabric.svh",
|
||||||
render_fabric_connection(fabric_links, "apb", "ribp"),
|
render_fabric_connection(fabric_links, "apb", "rib"),
|
||||||
)
|
)
|
||||||
atomic_write(rtl_dir / "soc_gpio_alt_bindings.svh", render_gpio_bindings(gpio_functions))
|
atomic_write(rtl_dir / "soc_gpio_alt_bindings.svh", render_gpio_bindings(gpio_functions))
|
||||||
atomic_write(rtl_dir / "soc_irq_config.svh", render_irq_config(irq_vector_width, irq_groups))
|
atomic_write(rtl_dir / "soc_irq_config.svh", render_irq_config(irq_vector_width, irq_groups))
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
{"name": "user", "interface": "u_user_rib_if", "protocol": "rib"},
|
{"name": "user", "interface": "u_user_rib_if", "protocol": "rib"},
|
||||||
{"name": "dma", "interface": "u_dma_rib_if", "protocol": "rib"},
|
{"name": "dma", "interface": "u_dma_rib_if", "protocol": "rib"},
|
||||||
{"name": "rib", "interface": "u_rib_if", "protocol": "rib"},
|
{"name": "rib", "interface": "u_rib_if", "protocol": "rib"},
|
||||||
{"name": "apb", "interface": "u_apb_ribp_if", "protocol": "ribp"}
|
{"name": "apb", "interface": "u_apb_rib_if", "protocol": "rib"}
|
||||||
],
|
],
|
||||||
"apb_targets": [
|
"apb_targets": [
|
||||||
{"slot": 0, "name": "archinfo", "timed_interface": "u_archinfo_apb_if", "pure_interface": "u_archinfo_apb_pure_if", "region": "APB_ARCHINFO"},
|
{"slot": 0, "name": "archinfo", "timed_interface": "u_archinfo_apb_if", "pure_interface": "u_archinfo_apb_pure_if", "region": "APB_ARCHINFO"},
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ FORMAL_SOLVER_DIR := $(FORMAL_DIR)/bin
|
|||||||
FORMAL_SOLVER_WRAPPER := $(FORMAL_SOLVER_DIR)/bitwuzla
|
FORMAL_SOLVER_WRAPPER := $(FORMAL_SOLVER_DIR)/bitwuzla
|
||||||
FORMAL_DEPTH ?= 20
|
FORMAL_DEPTH ?= 20
|
||||||
FORMAL_TIMEOUT ?= 60
|
FORMAL_TIMEOUT ?= 60
|
||||||
FORMAL_TARGETS := bus rib_adapter ribp2apb sysctrl pll_rcu gpio_user
|
FORMAL_TARGETS := bus rib_adapter rib2apb sysctrl pll_rcu gpio_user
|
||||||
FORMAL_FILELIST_GENERATOR := $(RTL_PATH)/formal/generate_formal_filelist.py
|
FORMAL_FILELIST_GENERATOR := $(RTL_PATH)/formal/generate_formal_filelist.py
|
||||||
FORMAL_SBY_GENERATOR := $(RTL_PATH)/formal/generate_sby_config.py
|
FORMAL_SBY_GENERATOR := $(RTL_PATH)/formal/generate_sby_config.py
|
||||||
FORMAL_RESULT_GENERATOR := $(RTL_PATH)/formal/formal_results.py
|
FORMAL_RESULT_GENERATOR := $(RTL_PATH)/formal/formal_results.py
|
||||||
@@ -14,8 +14,8 @@ FORMAL_SOURCE_FILES := $(RTL_PATH)/formal/bus_formal.sv \
|
|||||||
$(RTL_PATH)/formal/bus_formal_props.sv \
|
$(RTL_PATH)/formal/bus_formal_props.sv \
|
||||||
$(RTL_PATH)/formal/rib_adapter_formal.sv \
|
$(RTL_PATH)/formal/rib_adapter_formal.sv \
|
||||||
$(RTL_PATH)/formal/rib_adapter_formal_props.sv \
|
$(RTL_PATH)/formal/rib_adapter_formal_props.sv \
|
||||||
$(RTL_PATH)/formal/ribp2apb_formal.sv \
|
$(RTL_PATH)/formal/rib2apb_formal.sv \
|
||||||
$(RTL_PATH)/formal/ribp2apb_formal_props.sv \
|
$(RTL_PATH)/formal/rib2apb_formal_props.sv \
|
||||||
$(RTL_PATH)/formal/sysctrl_formal.sv \
|
$(RTL_PATH)/formal/sysctrl_formal.sv \
|
||||||
$(RTL_PATH)/formal/sysctrl_formal_props.sv \
|
$(RTL_PATH)/formal/sysctrl_formal_props.sv \
|
||||||
$(RTL_PATH)/formal/pll_rcu_formal.sv \
|
$(RTL_PATH)/formal/pll_rcu_formal.sv \
|
||||||
@@ -27,8 +27,8 @@ FORMAL_SOURCE_FILES := $(RTL_PATH)/formal/bus_formal.sv \
|
|||||||
$(RTL_PATH)/top/rib_if.sv \
|
$(RTL_PATH)/top/rib_if.sv \
|
||||||
$(RTL_PATH)/top/rib2ram.sv \
|
$(RTL_PATH)/top/rib2ram.sv \
|
||||||
$(RTL_PATH)/top/rib2ribp.sv \
|
$(RTL_PATH)/top/rib2ribp.sv \
|
||||||
|
$(RTL_PATH)/top/rib2apb.sv \
|
||||||
$(RTL_PATH)/top/ribp2rib.sv \
|
$(RTL_PATH)/top/ribp2rib.sv \
|
||||||
$(ROOT_PATH)/rtl/ip/ribp/interconnect/ribp2apb.sv \
|
|
||||||
$(ROOT_PATH)/rtl/ip/ribp/interconnect/ribp_regslice.sv \
|
$(ROOT_PATH)/rtl/ip/ribp/interconnect/ribp_regslice.sv \
|
||||||
$(ROOT_PATH)/rtl/ip/ribp/peripheral/gpio.sv \
|
$(ROOT_PATH)/rtl/ip/ribp/peripheral/gpio.sv \
|
||||||
$(ROOT_PATH)/rtl/ip/ribp/peripheral/pll_ctrl_if.sv \
|
$(ROOT_PATH)/rtl/ip/ribp/peripheral/pll_ctrl_if.sv \
|
||||||
@@ -117,7 +117,7 @@ formal-bus: $(FORMAL_DIR)/bus/.stamp | manifest
|
|||||||
|
|
||||||
formal-rib-adapter: $(FORMAL_DIR)/rib_adapter/.stamp | manifest
|
formal-rib-adapter: $(FORMAL_DIR)/rib_adapter/.stamp | manifest
|
||||||
|
|
||||||
formal-ribp2apb: $(FORMAL_DIR)/ribp2apb/.stamp | manifest
|
formal-rib2apb: $(FORMAL_DIR)/rib2apb/.stamp | manifest
|
||||||
|
|
||||||
formal-sysctrl: $(FORMAL_DIR)/sysctrl/.stamp | manifest
|
formal-sysctrl: $(FORMAL_DIR)/sysctrl/.stamp | manifest
|
||||||
|
|
||||||
@@ -131,4 +131,4 @@ formal-doctor:
|
|||||||
formal-clean:
|
formal-clean:
|
||||||
python3 $(ROOT_PATH)/scripts/clean.py --root $(ROOT_PATH) --path $(FORMAL_DIR)
|
python3 $(ROOT_PATH)/scripts/clean.py --root $(ROOT_PATH) --path $(FORMAL_DIR)
|
||||||
|
|
||||||
.PHONY: formal formal-bus formal-rib-adapter formal-ribp2apb formal-sysctrl formal-pll-rcu formal-gpio-user formal-doctor formal-clean
|
.PHONY: formal formal-bus formal-rib-adapter formal-rib2apb formal-sysctrl formal-pll-rcu formal-gpio-user formal-doctor formal-clean
|
||||||
+24
-34
@@ -18,13 +18,13 @@ module bus (
|
|||||||
`ifdef HAVE_SRAM_IF
|
`ifdef HAVE_SRAM_IF
|
||||||
ram_if.master ram,
|
ram_if.master ram,
|
||||||
`endif
|
`endif
|
||||||
ribp_if.slave mgmt_ribp,
|
ribp_if.slave mgmt_ribp,
|
||||||
rib_if.slave user_rib,
|
rib_if.slave user_rib,
|
||||||
rib_if.slave dma_rib,
|
rib_if.slave dma_rib,
|
||||||
input logic user_bus_enable_i,
|
input logic user_bus_enable_i,
|
||||||
output logic user_bus_idle_o,
|
output logic user_bus_idle_o,
|
||||||
rib_if.master rib,
|
rib_if.master rib,
|
||||||
ribp_if.master apb_ribp,
|
rib_if.master apb_rib,
|
||||||
input logic perf_enable_i,
|
input logic perf_enable_i,
|
||||||
input logic perf_clear_i,
|
input logic perf_clear_i,
|
||||||
output logic fault_valid_o,
|
output logic fault_valid_o,
|
||||||
@@ -56,7 +56,6 @@ module bus (
|
|||||||
|
|
||||||
rib_if u_mgmt_rib_if ();
|
rib_if u_mgmt_rib_if ();
|
||||||
rib_if u_mstr_rib_if ();
|
rib_if u_mstr_rib_if ();
|
||||||
rib_if u_apb_rib_if ();
|
|
||||||
rib_if u_ram_rib_if ();
|
rib_if u_ram_rib_if ();
|
||||||
rib_if u_fault_rib_if ();
|
rib_if u_fault_rib_if ();
|
||||||
|
|
||||||
@@ -97,13 +96,6 @@ module bus (
|
|||||||
.rib (u_mgmt_rib_if)
|
.rib (u_mgmt_rib_if)
|
||||||
);
|
);
|
||||||
|
|
||||||
rib2ribp u_apb_rib2ribp (
|
|
||||||
.clk_i (clk_i),
|
|
||||||
.rst_n_i(rst_n_i),
|
|
||||||
.rib (u_apb_rib_if),
|
|
||||||
.ribp (apb_ribp)
|
|
||||||
);
|
|
||||||
|
|
||||||
rib_error_slave u_fault_slave (
|
rib_error_slave u_fault_slave (
|
||||||
.clk_i (clk_i),
|
.clk_i (clk_i),
|
||||||
.rst_n_i (rst_n_i),
|
.rst_n_i (rst_n_i),
|
||||||
@@ -368,10 +360,10 @@ module bus (
|
|||||||
assign rib.cmd_addr = u_mstr_rib_if.cmd_addr;
|
assign rib.cmd_addr = u_mstr_rib_if.cmd_addr;
|
||||||
assign rib.cmd_write = u_mstr_rib_if.cmd_write;
|
assign rib.cmd_write = u_mstr_rib_if.cmd_write;
|
||||||
assign rib.cmd_len = u_mstr_rib_if.cmd_len;
|
assign rib.cmd_len = u_mstr_rib_if.cmd_len;
|
||||||
assign u_apb_rib_if.cmd_valid = s_apb_sel;
|
assign apb_rib.cmd_valid = s_apb_sel;
|
||||||
assign u_apb_rib_if.cmd_addr = u_mstr_rib_if.cmd_addr;
|
assign apb_rib.cmd_addr = u_mstr_rib_if.cmd_addr;
|
||||||
assign u_apb_rib_if.cmd_write = u_mstr_rib_if.cmd_write;
|
assign apb_rib.cmd_write = u_mstr_rib_if.cmd_write;
|
||||||
assign u_apb_rib_if.cmd_len = u_mstr_rib_if.cmd_len;
|
assign apb_rib.cmd_len = u_mstr_rib_if.cmd_len;
|
||||||
assign u_ram_rib_if.cmd_valid = s_ram_sel;
|
assign u_ram_rib_if.cmd_valid = s_ram_sel;
|
||||||
assign u_ram_rib_if.cmd_addr = u_mstr_rib_if.cmd_addr;
|
assign u_ram_rib_if.cmd_addr = u_mstr_rib_if.cmd_addr;
|
||||||
assign u_ram_rib_if.cmd_write = u_mstr_rib_if.cmd_write;
|
assign u_ram_rib_if.cmd_write = u_mstr_rib_if.cmd_write;
|
||||||
@@ -386,7 +378,7 @@ module bus (
|
|||||||
if (s_ribp_sel) begin
|
if (s_ribp_sel) begin
|
||||||
u_mstr_rib_if.cmd_ready = rib.cmd_ready;
|
u_mstr_rib_if.cmd_ready = rib.cmd_ready;
|
||||||
end else if (s_apb_sel) begin
|
end else if (s_apb_sel) begin
|
||||||
u_mstr_rib_if.cmd_ready = u_apb_rib_if.cmd_ready;
|
u_mstr_rib_if.cmd_ready = apb_rib.cmd_ready;
|
||||||
end else if (s_ram_sel) begin
|
end else if (s_ram_sel) begin
|
||||||
u_mstr_rib_if.cmd_ready = u_ram_rib_if.cmd_ready;
|
u_mstr_rib_if.cmd_ready = u_ram_rib_if.cmd_ready;
|
||||||
end else if (s_fault_sel) begin
|
end else if (s_fault_sel) begin
|
||||||
@@ -424,15 +416,13 @@ module bus (
|
|||||||
assign rib.rsp_ready = s_mstr_lock_q && s_cmd_accepted_q && (s_target_q == TARGET_RIBP) ?
|
assign rib.rsp_ready = s_mstr_lock_q && s_cmd_accepted_q && (s_target_q == TARGET_RIBP) ?
|
||||||
u_mstr_rib_if.rsp_ready : 1'b0;
|
u_mstr_rib_if.rsp_ready : 1'b0;
|
||||||
|
|
||||||
assign u_apb_rib_if.w_valid = s_mstr_lock_q && s_cmd_accepted_q &&
|
assign apb_rib.w_valid = s_mstr_lock_q && s_cmd_accepted_q &&
|
||||||
(s_target_q == TARGET_APB) ?
|
(s_target_q == TARGET_APB) ? u_mstr_rib_if.w_valid : 1'b0;
|
||||||
u_mstr_rib_if.w_valid : 1'b0;
|
assign apb_rib.wdata = u_mstr_rib_if.wdata;
|
||||||
assign u_apb_rib_if.wdata = u_mstr_rib_if.wdata;
|
assign apb_rib.wstrb = u_mstr_rib_if.wstrb;
|
||||||
assign u_apb_rib_if.wstrb = u_mstr_rib_if.wstrb;
|
assign apb_rib.wlast = u_mstr_rib_if.wlast;
|
||||||
assign u_apb_rib_if.wlast = u_mstr_rib_if.wlast;
|
assign apb_rib.rsp_ready = s_mstr_lock_q && s_cmd_accepted_q &&
|
||||||
assign u_apb_rib_if.rsp_ready = s_mstr_lock_q && s_cmd_accepted_q &&
|
(s_target_q == TARGET_APB) ? u_mstr_rib_if.rsp_ready : 1'b0;
|
||||||
(s_target_q == TARGET_APB) ?
|
|
||||||
u_mstr_rib_if.rsp_ready : 1'b0;
|
|
||||||
|
|
||||||
assign u_ram_rib_if.w_valid = s_mstr_lock_q && s_cmd_accepted_q &&
|
assign u_ram_rib_if.w_valid = s_mstr_lock_q && s_cmd_accepted_q &&
|
||||||
(s_target_q == TARGET_RAM) ?
|
(s_target_q == TARGET_RAM) ?
|
||||||
@@ -473,13 +463,13 @@ module bus (
|
|||||||
u_mstr_rib_if.rsp_last = rib.rsp_last;
|
u_mstr_rib_if.rsp_last = rib.rsp_last;
|
||||||
end
|
end
|
||||||
TARGET_APB: begin
|
TARGET_APB: begin
|
||||||
u_mstr_rib_if.w_ready = s_cmd_accepted_q && u_apb_rib_if.w_ready;
|
u_mstr_rib_if.w_ready = s_cmd_accepted_q && apb_rib.w_ready;
|
||||||
u_mstr_rib_if.rsp_valid = s_cmd_accepted_q && u_apb_rib_if.rsp_valid;
|
u_mstr_rib_if.rsp_valid = s_cmd_accepted_q && apb_rib.rsp_valid;
|
||||||
u_mstr_rib_if.rdata = u_apb_rib_if.rdata;
|
u_mstr_rib_if.rdata = apb_rib.rdata;
|
||||||
u_mstr_rib_if.resp_err = u_apb_rib_if.resp_err;
|
u_mstr_rib_if.resp_err = apb_rib.resp_err;
|
||||||
u_mstr_rib_if.resp_code = u_apb_rib_if.resp_code;
|
u_mstr_rib_if.resp_code = apb_rib.resp_code;
|
||||||
u_mstr_rib_if.rsp_beat = u_apb_rib_if.rsp_beat;
|
u_mstr_rib_if.rsp_beat = apb_rib.rsp_beat;
|
||||||
u_mstr_rib_if.rsp_last = u_apb_rib_if.rsp_last;
|
u_mstr_rib_if.rsp_last = apb_rib.rsp_last;
|
||||||
end
|
end
|
||||||
TARGET_RAM: begin
|
TARGET_RAM: begin
|
||||||
u_mstr_rib_if.w_ready = s_cmd_accepted_q && u_ram_rib_if.w_ready;
|
u_mstr_rib_if.w_ready = s_cmd_accepted_q && u_ram_rib_if.w_ready;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ module ip_apb_wrapper (
|
|||||||
input logic clk_aud_i,
|
input logic clk_aud_i,
|
||||||
input logic rst_aud_n_i,
|
input logic rst_aud_n_i,
|
||||||
input logic tmr_capch_i,
|
input logic tmr_capch_i,
|
||||||
ribp_if.slave ribp,
|
rib_if.slave rib,
|
||||||
uart_if.dut uart,
|
uart_if.dut uart,
|
||||||
pwm_if.dut pwm,
|
pwm_if.dut pwm,
|
||||||
ps2_if.dut ps2,
|
ps2_if.dut ps2,
|
||||||
@@ -62,10 +62,10 @@ module ip_apb_wrapper (
|
|||||||
// Generated IRQ ownership and core-vector bit assignments are topology checked.
|
// Generated IRQ ownership and core-vector bit assignments are topology checked.
|
||||||
`include "soc_apb_irq_bindings.svh"
|
`include "soc_apb_irq_bindings.svh"
|
||||||
|
|
||||||
ribp2apb u_ribp2apb (
|
rib2apb u_rib2apb (
|
||||||
.clk_i (clk_i),
|
.clk_i (clk_i),
|
||||||
.rst_n_i(rst_n_i),
|
.rst_n_i(rst_n_i),
|
||||||
.ribp (ribp),
|
.rib (rib),
|
||||||
`include "soc_apb_connections.svh"
|
`include "soc_apb_connections.svh"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,177 @@
|
|||||||
|
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
|
||||||
|
// retroSoC is licensed under Mulan PSL v2.
|
||||||
|
// You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
// You may obtain a copy of the Mulan PSL v2 at:
|
||||||
|
// http://license.coscl.org.cn/MulanPSL2
|
||||||
|
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
// See the Mulan PSL v2 for more details.
|
||||||
|
|
||||||
|
`include "mmap_define.svh"
|
||||||
|
`include "rib_defs.svh"
|
||||||
|
|
||||||
|
module rib2apb (
|
||||||
|
// verilog_format: off
|
||||||
|
input logic clk_i,
|
||||||
|
input logic rst_n_i,
|
||||||
|
rib_if.slave rib,
|
||||||
|
`include "soc_apb_ports.svh"
|
||||||
|
// verilog_format: on
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam logic [2:0] FSM_CMD = 3'd0;
|
||||||
|
localparam logic [2:0] FSM_WDATA = 3'd1;
|
||||||
|
localparam logic [2:0] FSM_SETP = 3'd2;
|
||||||
|
localparam logic [2:0] FSM_ENAB = 3'd3;
|
||||||
|
localparam logic [2:0] FSM_DROP_WDATA = 3'd4;
|
||||||
|
localparam logic [2:0] FSM_ERR = 3'd5;
|
||||||
|
localparam int RSP_WIDTH = 39;
|
||||||
|
|
||||||
|
logic [31:0] s_rd_data;
|
||||||
|
logic s_xfer_valid, s_xfer_ready, s_xfer_error;
|
||||||
|
logic [2:0] s_fsm_d, s_fsm_q;
|
||||||
|
logic [31:0] s_addr_q, s_wdata_q;
|
||||||
|
logic [3:0] s_wstrb_q;
|
||||||
|
logic s_write_q;
|
||||||
|
logic [2:0] s_error_code_d, s_error_code_q;
|
||||||
|
logic s_cmd_hdshk, s_w_hdshk, s_rsp_hdshk;
|
||||||
|
logic s_psel_valid;
|
||||||
|
logic s_rsp_input_valid, s_rsp_input_ready;
|
||||||
|
logic [RSP_WIDTH-1:0] s_rsp_input_data, s_rsp_output_data;
|
||||||
|
|
||||||
|
// Registered slave-select one-hot and APB response mux.
|
||||||
|
`include "soc_apb_declarations.svh"
|
||||||
|
|
||||||
|
assign s_cmd_hdshk = rib.cmd_valid && rib.cmd_ready;
|
||||||
|
assign s_w_hdshk = rib.w_valid && rib.w_ready;
|
||||||
|
|
||||||
|
assign rib.cmd_ready = (s_fsm_q == FSM_CMD) && !rib.rsp_valid;
|
||||||
|
assign rib.w_ready = (s_fsm_q == FSM_WDATA) || (s_fsm_q == FSM_DROP_WDATA);
|
||||||
|
|
||||||
|
assign s_xfer_valid = (s_fsm_q == FSM_SETP) || (s_fsm_q == FSM_ENAB);
|
||||||
|
|
||||||
|
// Generated APB routing uses the latched RIB request and selected target.
|
||||||
|
`include "soc_apb_request_routes.svh"
|
||||||
|
`include "soc_apb_select_routes.svh"
|
||||||
|
`include "soc_apb_response_mux.svh"
|
||||||
|
|
||||||
|
assign s_psel_valid = |s_psel_comb;
|
||||||
|
|
||||||
|
assign s_rsp_input_valid = ((s_fsm_q == FSM_ENAB) && s_xfer_ready) || (s_fsm_q == FSM_ERR);
|
||||||
|
assign s_rsp_input_data = (s_fsm_q == FSM_ENAB) ?
|
||||||
|
{1'b1, 2'd0, s_xfer_error ? `RIB_RESP_SLVERR : `RIB_RESP_OK, s_xfer_error,
|
||||||
|
s_write_q ? 32'd0 : s_rd_data} :
|
||||||
|
{1'b1, 2'd0, s_error_code_q, 1'b1, 32'd0};
|
||||||
|
assign s_rsp_hdshk = s_rsp_input_valid && s_rsp_input_ready;
|
||||||
|
|
||||||
|
spill_register #(
|
||||||
|
.DATA_WIDTH(RSP_WIDTH),
|
||||||
|
.BYPASS (1'b0)
|
||||||
|
) u_rsp_spill_register (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i(rst_n_i),
|
||||||
|
.flush_i(1'b0),
|
||||||
|
.valid_i(s_rsp_input_valid),
|
||||||
|
.ready_o(s_rsp_input_ready),
|
||||||
|
.data_i (s_rsp_input_data),
|
||||||
|
.valid_o(rib.rsp_valid),
|
||||||
|
.ready_i(rib.rsp_ready),
|
||||||
|
.data_o (s_rsp_output_data)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign rib.rdata = s_rsp_output_data[31:0];
|
||||||
|
assign rib.resp_err = s_rsp_output_data[32];
|
||||||
|
assign rib.resp_code = s_rsp_output_data[35:33];
|
||||||
|
assign rib.rsp_beat = s_rsp_output_data[37:36];
|
||||||
|
assign rib.rsp_last = s_rsp_output_data[38];
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
s_fsm_d = s_fsm_q;
|
||||||
|
s_error_code_d = s_error_code_q;
|
||||||
|
unique case (s_fsm_q)
|
||||||
|
FSM_CMD: begin
|
||||||
|
if (s_cmd_hdshk) begin
|
||||||
|
if (rib.cmd_len != `RIB_LEN_INCR1) begin
|
||||||
|
s_error_code_d = `RIB_RESP_BURSTERR;
|
||||||
|
s_fsm_d = rib.cmd_write ? FSM_DROP_WDATA : FSM_ERR;
|
||||||
|
end else if (!s_psel_valid) begin
|
||||||
|
s_error_code_d = `RIB_RESP_DECERR;
|
||||||
|
s_fsm_d = rib.cmd_write ? FSM_DROP_WDATA : FSM_ERR;
|
||||||
|
end else begin
|
||||||
|
s_fsm_d = rib.cmd_write ? FSM_WDATA : FSM_SETP;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
FSM_WDATA: begin
|
||||||
|
if (s_w_hdshk) begin
|
||||||
|
if (rib.wlast) begin
|
||||||
|
s_fsm_d = FSM_SETP;
|
||||||
|
end else begin
|
||||||
|
s_error_code_d = `RIB_RESP_BURSTERR;
|
||||||
|
s_fsm_d = FSM_ERR;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
FSM_SETP: s_fsm_d = FSM_ENAB;
|
||||||
|
FSM_ENAB: begin
|
||||||
|
if (s_xfer_ready && s_rsp_input_ready) s_fsm_d = FSM_CMD;
|
||||||
|
end
|
||||||
|
FSM_DROP_WDATA: begin
|
||||||
|
if (s_w_hdshk && rib.wlast) s_fsm_d = FSM_ERR;
|
||||||
|
end
|
||||||
|
FSM_ERR: begin
|
||||||
|
if (s_rsp_hdshk) s_fsm_d = FSM_CMD;
|
||||||
|
end
|
||||||
|
default: s_fsm_d = FSM_CMD;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
dffr #(3) u_fsm_dffr (
|
||||||
|
clk_i,
|
||||||
|
rst_n_i,
|
||||||
|
s_fsm_d,
|
||||||
|
s_fsm_q
|
||||||
|
);
|
||||||
|
dffer #(32) u_addr_dffer (
|
||||||
|
clk_i,
|
||||||
|
rst_n_i,
|
||||||
|
s_cmd_hdshk,
|
||||||
|
rib.cmd_addr,
|
||||||
|
s_addr_q
|
||||||
|
);
|
||||||
|
dffer #(1) u_write_dffer (
|
||||||
|
clk_i,
|
||||||
|
rst_n_i,
|
||||||
|
s_cmd_hdshk,
|
||||||
|
rib.cmd_write,
|
||||||
|
s_write_q
|
||||||
|
);
|
||||||
|
dffer #(32) u_wdata_dffer (
|
||||||
|
clk_i,
|
||||||
|
rst_n_i,
|
||||||
|
s_w_hdshk && (s_fsm_q == FSM_WDATA),
|
||||||
|
rib.wdata,
|
||||||
|
s_wdata_q
|
||||||
|
);
|
||||||
|
dffer #(4) u_wstrb_dffer (
|
||||||
|
clk_i,
|
||||||
|
rst_n_i,
|
||||||
|
s_w_hdshk && (s_fsm_q == FSM_WDATA),
|
||||||
|
rib.wstrb,
|
||||||
|
s_wstrb_q
|
||||||
|
);
|
||||||
|
dffr #(3) u_error_code_dffr (
|
||||||
|
clk_i,
|
||||||
|
rst_n_i,
|
||||||
|
s_error_code_d,
|
||||||
|
s_error_code_q
|
||||||
|
);
|
||||||
|
dffr #(NSLV) u_psel_dffr (
|
||||||
|
clk_i,
|
||||||
|
rst_n_i,
|
||||||
|
s_cmd_hdshk ? s_psel_comb : s_psel_q,
|
||||||
|
s_psel_q
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
||||||
+20
-14
@@ -15,20 +15,26 @@ module bus_fault_tb;
|
|||||||
rib_if user_rib ();
|
rib_if user_rib ();
|
||||||
rib_if dma_rib ();
|
rib_if dma_rib ();
|
||||||
rib_if rib ();
|
rib_if rib ();
|
||||||
ribp_if apb_ribp ();
|
rib_if apb_rib ();
|
||||||
|
|
||||||
always #5 clk_i = ~clk_i;
|
always #5 clk_i = ~clk_i;
|
||||||
|
|
||||||
assign rib.cmd_ready = 1'b1;
|
assign rib.cmd_ready = 1'b1;
|
||||||
assign rib.w_ready = 1'b1;
|
assign rib.w_ready = 1'b1;
|
||||||
assign rib.rsp_valid = 1'b0;
|
assign rib.rsp_valid = 1'b0;
|
||||||
assign rib.rdata = 32'hCAFE_BABE;
|
assign rib.rdata = 32'hCAFE_BABE;
|
||||||
assign rib.resp_err = 1'b0;
|
assign rib.resp_err = 1'b0;
|
||||||
assign rib.resp_code = `RIB_RESP_OK;
|
assign rib.resp_code = `RIB_RESP_OK;
|
||||||
assign rib.rsp_beat = '0;
|
assign rib.rsp_beat = '0;
|
||||||
assign rib.rsp_last = 1'b0;
|
assign rib.rsp_last = 1'b0;
|
||||||
assign apb_ribp.ready = 1'b1;
|
assign apb_rib.cmd_ready = 1'b1;
|
||||||
assign apb_ribp.rdata = 32'h1234_5678;
|
assign apb_rib.w_ready = 1'b1;
|
||||||
|
assign apb_rib.rsp_valid = 1'b0;
|
||||||
|
assign apb_rib.rdata = 32'h1234_5678;
|
||||||
|
assign apb_rib.resp_err = 1'b0;
|
||||||
|
assign apb_rib.resp_code = `RIB_RESP_OK;
|
||||||
|
assign apb_rib.rsp_beat = '0;
|
||||||
|
assign apb_rib.rsp_last = 1'b1;
|
||||||
|
|
||||||
bus u_bus (
|
bus u_bus (
|
||||||
.clk_i (clk_i),
|
.clk_i (clk_i),
|
||||||
@@ -39,7 +45,7 @@ module bus_fault_tb;
|
|||||||
.user_bus_enable_i(1'b1),
|
.user_bus_enable_i(1'b1),
|
||||||
.user_bus_idle_o (user_bus_idle_o),
|
.user_bus_idle_o (user_bus_idle_o),
|
||||||
.rib (rib),
|
.rib (rib),
|
||||||
.apb_ribp (apb_ribp),
|
.apb_rib (apb_rib),
|
||||||
.perf_enable_i (1'b0),
|
.perf_enable_i (1'b0),
|
||||||
.perf_clear_i (1'b0),
|
.perf_clear_i (1'b0),
|
||||||
.fault_valid_o (fault_valid_o),
|
.fault_valid_o (fault_valid_o),
|
||||||
@@ -62,7 +68,7 @@ module bus_fault_tb;
|
|||||||
while (!fault_valid_o) @(posedge clk_i);
|
while (!fault_valid_o) @(posedge clk_i);
|
||||||
if (fault_addr_o !== address || fault_wstrb_o !== write_strobes ||
|
if (fault_addr_o !== address || fault_wstrb_o !== write_strobes ||
|
||||||
fault_reserved_o !== reserved || fault_access_o || fault_code_o !== expected_code ||
|
fault_reserved_o !== reserved || fault_access_o || fault_code_o !== expected_code ||
|
||||||
rib.cmd_valid || apb_ribp.valid) begin
|
rib.cmd_valid || apb_rib.cmd_valid) begin
|
||||||
$fatal(1, "unexpected fault response for address %h", address);
|
$fatal(1, "unexpected fault response for address %h", address);
|
||||||
end
|
end
|
||||||
while (!mgmt_ribp.ready) @(posedge clk_i);
|
while (!mgmt_ribp.ready) @(posedge clk_i);
|
||||||
@@ -95,7 +101,7 @@ module bus_fault_tb;
|
|||||||
user_rib.w_valid = 1'b0;
|
user_rib.w_valid = 1'b0;
|
||||||
end
|
end
|
||||||
while (!fault_valid_o) @(posedge clk_i);
|
while (!fault_valid_o) @(posedge clk_i);
|
||||||
if (!fault_access_o || fault_master_o != 2'd1 || rib.cmd_valid || apb_ribp.valid) begin
|
if (!fault_access_o || fault_master_o != 2'd1 || rib.cmd_valid || apb_rib.cmd_valid) begin
|
||||||
$fatal(1, "user access was not denied locally");
|
$fatal(1, "user access was not denied locally");
|
||||||
end
|
end
|
||||||
if (user_rib.rdata !== 32'd0 || !user_rib.resp_err || !user_rib.rsp_last ||
|
if (user_rib.rdata !== 32'd0 || !user_rib.resp_err || !user_rib.rsp_last ||
|
||||||
|
|||||||
@@ -0,0 +1,197 @@
|
|||||||
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
|
`include "rib_defs.svh"
|
||||||
|
|
||||||
|
module rib2apb_tb;
|
||||||
|
logic clk_i = 1'b0;
|
||||||
|
logic rst_n_i = 1'b0;
|
||||||
|
logic rng_ready = 1'b0;
|
||||||
|
logic rng_slverr = 1'b0;
|
||||||
|
logic [31:0] rng_rdata = 32'h1234_5678;
|
||||||
|
|
||||||
|
rib_if rib ();
|
||||||
|
apb4_pure_if archinfo ();
|
||||||
|
apb4_pure_if rng ();
|
||||||
|
apb4_pure_if uart ();
|
||||||
|
apb4_pure_if pwm ();
|
||||||
|
apb4_pure_if ps2 ();
|
||||||
|
apb4_pure_if rtc ();
|
||||||
|
apb4_pure_if wdg ();
|
||||||
|
apb4_pure_if crc ();
|
||||||
|
apb4_pure_if tmr ();
|
||||||
|
apb4_pure_if user_ip ();
|
||||||
|
|
||||||
|
always #5 clk_i = ~clk_i;
|
||||||
|
|
||||||
|
assign archinfo.pready = 1'b0;
|
||||||
|
assign archinfo.prdata = '0;
|
||||||
|
assign archinfo.pslverr = 1'b0;
|
||||||
|
assign rng.pready = rng_ready;
|
||||||
|
assign rng.prdata = rng_rdata;
|
||||||
|
assign rng.pslverr = rng_slverr;
|
||||||
|
assign uart.pready = 1'b0;
|
||||||
|
assign uart.prdata = '0;
|
||||||
|
assign uart.pslverr = 1'b0;
|
||||||
|
assign pwm.pready = 1'b0;
|
||||||
|
assign pwm.prdata = '0;
|
||||||
|
assign pwm.pslverr = 1'b0;
|
||||||
|
assign ps2.pready = 1'b0;
|
||||||
|
assign ps2.prdata = '0;
|
||||||
|
assign ps2.pslverr = 1'b0;
|
||||||
|
assign rtc.pready = 1'b0;
|
||||||
|
assign rtc.prdata = '0;
|
||||||
|
assign rtc.pslverr = 1'b0;
|
||||||
|
assign wdg.pready = 1'b0;
|
||||||
|
assign wdg.prdata = '0;
|
||||||
|
assign wdg.pslverr = 1'b0;
|
||||||
|
assign crc.pready = 1'b0;
|
||||||
|
assign crc.prdata = '0;
|
||||||
|
assign crc.pslverr = 1'b0;
|
||||||
|
assign tmr.pready = 1'b0;
|
||||||
|
assign tmr.prdata = '0;
|
||||||
|
assign tmr.pslverr = 1'b0;
|
||||||
|
assign user_ip.pready = 1'b0;
|
||||||
|
assign user_ip.prdata = '0;
|
||||||
|
assign user_ip.pslverr = 1'b0;
|
||||||
|
|
||||||
|
rib2apb u_rib2apb (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_n_i (rst_n_i),
|
||||||
|
.rib (rib),
|
||||||
|
.archinfo(archinfo),
|
||||||
|
.rng (rng),
|
||||||
|
.uart (uart),
|
||||||
|
.pwm (pwm),
|
||||||
|
.ps2 (ps2),
|
||||||
|
.rtc (rtc),
|
||||||
|
.wdg (wdg),
|
||||||
|
.crc (crc),
|
||||||
|
.tmr (tmr),
|
||||||
|
.user_ip (user_ip)
|
||||||
|
);
|
||||||
|
|
||||||
|
task automatic send_command(input logic [31:0] address, input logic write,
|
||||||
|
input logic [1:0] length);
|
||||||
|
begin
|
||||||
|
@(negedge clk_i);
|
||||||
|
rib.cmd_addr = address;
|
||||||
|
rib.cmd_write = write;
|
||||||
|
rib.cmd_len = length;
|
||||||
|
rib.cmd_valid = 1'b1;
|
||||||
|
while (!rib.cmd_ready) @(posedge clk_i);
|
||||||
|
@(negedge clk_i);
|
||||||
|
rib.cmd_valid = 1'b0;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task automatic send_write(input logic [31:0] data, input logic [3:0] strobes, input logic last);
|
||||||
|
begin
|
||||||
|
@(negedge clk_i);
|
||||||
|
rib.wdata = data;
|
||||||
|
rib.wstrb = strobes;
|
||||||
|
rib.wlast = last;
|
||||||
|
rib.w_valid = 1'b1;
|
||||||
|
while (!rib.w_ready) @(posedge clk_i);
|
||||||
|
@(negedge clk_i);
|
||||||
|
rib.w_valid = 1'b0;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task automatic wait_for_rng_enable;
|
||||||
|
begin
|
||||||
|
while (!(rng.psel && rng.penable)) @(posedge clk_i);
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task automatic expect_response(input logic expected_error, input logic [2:0] expected_code,
|
||||||
|
input logic [31:0] expected_data);
|
||||||
|
begin
|
||||||
|
while (!rib.rsp_valid) @(posedge clk_i);
|
||||||
|
#1;
|
||||||
|
if (rib.resp_err !== expected_error || rib.resp_code !== expected_code ||
|
||||||
|
rib.rdata !== expected_data || rib.rsp_beat !== 2'd0 || !rib.rsp_last) begin
|
||||||
|
$fatal(1, "unexpected RIB response error=%b/%b code=%0d/%0d data=%h/%h fsm=%0d",
|
||||||
|
rib.resp_err, expected_error, rib.resp_code, expected_code, rib.rdata,
|
||||||
|
expected_data, u_rib2apb.s_fsm_q);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
rib.cmd_valid = 1'b0;
|
||||||
|
rib.cmd_addr = '0;
|
||||||
|
rib.cmd_write = 1'b0;
|
||||||
|
rib.cmd_len = `RIB_LEN_INCR1;
|
||||||
|
rib.w_valid = 1'b0;
|
||||||
|
rib.wdata = '0;
|
||||||
|
rib.wstrb = '0;
|
||||||
|
rib.wlast = 1'b0;
|
||||||
|
rib.rsp_ready = 1'b1;
|
||||||
|
|
||||||
|
repeat (2) @(posedge clk_i);
|
||||||
|
rst_n_i = 1'b1;
|
||||||
|
|
||||||
|
send_command(32'h2000_1000, 1'b0, `RIB_LEN_INCR1);
|
||||||
|
while (!(rng.psel && !rng.penable)) @(posedge clk_i);
|
||||||
|
wait_for_rng_enable();
|
||||||
|
if (rng.paddr !== 32'h2000_1000 || rng.pwrite || rng.pstrb !== 4'd0) begin
|
||||||
|
$fatal(1, "read APB setup was not held from the RIB command");
|
||||||
|
end
|
||||||
|
repeat (2) begin
|
||||||
|
@(posedge clk_i);
|
||||||
|
if (!(rng.psel && rng.penable) || rng.paddr !== 32'h2000_1000) begin
|
||||||
|
$fatal(1, "APB read request changed while PREADY was low");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rib.rsp_ready = 1'b0;
|
||||||
|
@(negedge clk_i);
|
||||||
|
rng_ready = 1'b1;
|
||||||
|
expect_response(1'b0, `RIB_RESP_OK, 32'h1234_5678);
|
||||||
|
repeat (2) begin
|
||||||
|
@(posedge clk_i);
|
||||||
|
if (!rib.rsp_valid || rib.rdata !== 32'h1234_5678) begin
|
||||||
|
$fatal(1, "response did not remain stable under RIB backpressure");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rib.rsp_ready = 1'b1;
|
||||||
|
@(posedge clk_i);
|
||||||
|
@(negedge clk_i);
|
||||||
|
rng_ready = 1'b0;
|
||||||
|
|
||||||
|
send_command(32'h2000_1000, 1'b1, `RIB_LEN_INCR1);
|
||||||
|
send_write(32'hA5A5_5A5A, 4'hC, 1'b1);
|
||||||
|
wait_for_rng_enable();
|
||||||
|
if (!rng.pwrite || rng.pwdata !== 32'hA5A5_5A5A || rng.pstrb !== 4'hC) begin
|
||||||
|
$fatal(1, "APB write data was not held from the RIB write channel");
|
||||||
|
end
|
||||||
|
@(negedge clk_i);
|
||||||
|
rng_ready = 1'b1;
|
||||||
|
expect_response(1'b0, `RIB_RESP_OK, 32'd0);
|
||||||
|
@(posedge clk_i);
|
||||||
|
@(negedge clk_i);
|
||||||
|
rng_ready = 1'b0;
|
||||||
|
|
||||||
|
rng_slverr = 1'b1;
|
||||||
|
send_command(32'h2000_1000, 1'b0, `RIB_LEN_INCR1);
|
||||||
|
wait_for_rng_enable();
|
||||||
|
@(negedge clk_i);
|
||||||
|
rng_ready = 1'b1;
|
||||||
|
expect_response(1'b1, `RIB_RESP_SLVERR, 32'h1234_5678);
|
||||||
|
@(posedge clk_i);
|
||||||
|
@(negedge clk_i);
|
||||||
|
rng_ready = 1'b0;
|
||||||
|
rng_slverr = 1'b0;
|
||||||
|
|
||||||
|
send_command(32'h2000_1000, 1'b1, `RIB_LEN_INCR4);
|
||||||
|
send_write(32'h0000_0001, 4'hF, 1'b0);
|
||||||
|
send_write(32'h0000_0002, 4'hF, 1'b0);
|
||||||
|
send_write(32'h0000_0003, 4'hF, 1'b0);
|
||||||
|
send_write(32'h0000_0004, 4'hF, 1'b1);
|
||||||
|
if (rng.psel) $fatal(1, "illegal RIB burst reached the APB target");
|
||||||
|
expect_response(1'b1, `RIB_RESP_BURSTERR, 32'd0);
|
||||||
|
@(posedge clk_i);
|
||||||
|
|
||||||
|
$display("RIB2APB direct bridge test passed");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
+11
-5
@@ -20,7 +20,7 @@ module rib_bus_tb;
|
|||||||
rib_if user_rib ();
|
rib_if user_rib ();
|
||||||
rib_if dma_rib ();
|
rib_if dma_rib ();
|
||||||
rib_if rib ();
|
rib_if rib ();
|
||||||
ribp_if apb_ribp ();
|
rib_if apb_rib ();
|
||||||
|
|
||||||
always #5 clk_i = ~clk_i;
|
always #5 clk_i = ~clk_i;
|
||||||
always @(posedge clk_i) cycle_count <= cycle_count + 1;
|
always @(posedge clk_i) cycle_count <= cycle_count + 1;
|
||||||
@@ -57,8 +57,14 @@ module rib_bus_tb;
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
assign apb_ribp.ready = apb_ribp.valid;
|
assign apb_rib.cmd_ready = 1'b1;
|
||||||
assign apb_ribp.rdata = 32'h1234_5678;
|
assign apb_rib.w_ready = 1'b1;
|
||||||
|
assign apb_rib.rsp_valid = 1'b0;
|
||||||
|
assign apb_rib.rdata = 32'h1234_5678;
|
||||||
|
assign apb_rib.resp_err = 1'b0;
|
||||||
|
assign apb_rib.resp_code = `RIB_RESP_OK;
|
||||||
|
assign apb_rib.rsp_beat = '0;
|
||||||
|
assign apb_rib.rsp_last = 1'b1;
|
||||||
|
|
||||||
bus u_bus (
|
bus u_bus (
|
||||||
.clk_i (clk_i),
|
.clk_i (clk_i),
|
||||||
@@ -69,7 +75,7 @@ module rib_bus_tb;
|
|||||||
.user_bus_enable_i(1'b1),
|
.user_bus_enable_i(1'b1),
|
||||||
.user_bus_idle_o (user_bus_idle_o),
|
.user_bus_idle_o (user_bus_idle_o),
|
||||||
.rib (rib),
|
.rib (rib),
|
||||||
.apb_ribp (apb_ribp),
|
.apb_rib (apb_rib),
|
||||||
.perf_enable_i (1'b0),
|
.perf_enable_i (1'b0),
|
||||||
.perf_clear_i (1'b0),
|
.perf_clear_i (1'b0),
|
||||||
.fault_valid_o (fault_valid_o),
|
.fault_valid_o (fault_valid_o),
|
||||||
@@ -163,7 +169,7 @@ module rib_bus_tb;
|
|||||||
issue_read(32'h1000_0000, `RIB_LEN_INCR4, 1'b1);
|
issue_read(32'h1000_0000, `RIB_LEN_INCR4, 1'b1);
|
||||||
issue_read(32'h2000_0000, `RIB_LEN_INCR4, 1'b1);
|
issue_read(32'h2000_0000, `RIB_LEN_INCR4, 1'b1);
|
||||||
issue_read(32'h3800_1000, 2'd2, 1'b1);
|
issue_read(32'h3800_1000, 2'd2, 1'b1);
|
||||||
if (rib_command_count != 1 || apb_ribp.valid) begin
|
if (rib_command_count != 1 || apb_rib.cmd_valid) begin
|
||||||
$fatal(1, "illegal burst reached a downstream target");
|
$fatal(1, "illegal burst reached a downstream target");
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
"""RTL test for the direct RIB-to-APB bridge."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
|
||||||
|
|
||||||
|
def test_rib2apb_preserves_apb_and_rib_handshakes(tmp_path: Path) -> None:
|
||||||
|
iverilog = shutil.which("iverilog")
|
||||||
|
sv2v = shutil.which("sv2v")
|
||||||
|
vvp = shutil.which("vvp")
|
||||||
|
if iverilog is None or sv2v is None or vvp is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
memory_map = tmp_path / "memory_map"
|
||||||
|
topology = tmp_path / "soc_topology"
|
||||||
|
subprocess.run(
|
||||||
|
[
|
||||||
|
sys.executable,
|
||||||
|
str(ROOT / "rtl/mini/address_map/generate_memory_map.py"),
|
||||||
|
"--map",
|
||||||
|
str(ROOT / "rtl/mini/address_map/memory_map.json"),
|
||||||
|
"--output-dir",
|
||||||
|
str(memory_map),
|
||||||
|
"--have-sram-if",
|
||||||
|
"NO",
|
||||||
|
],
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
subprocess.run(
|
||||||
|
[
|
||||||
|
sys.executable,
|
||||||
|
str(ROOT / "rtl/mini/integration/generate_soc_topology.py"),
|
||||||
|
"--map",
|
||||||
|
str(ROOT / "rtl/mini/integration/soc_topology.json"),
|
||||||
|
"--memory-map",
|
||||||
|
str(ROOT / "rtl/mini/address_map/memory_map.json"),
|
||||||
|
"--output-dir",
|
||||||
|
str(topology),
|
||||||
|
],
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
source_list = tmp_path / "rib2apb.fl"
|
||||||
|
source_list.write_text(
|
||||||
|
"\n".join(
|
||||||
|
[
|
||||||
|
"+define+SV_ASSRT_DISABLE",
|
||||||
|
f"+incdir+{memory_map / 'rtl'}",
|
||||||
|
f"+incdir+{topology / 'rtl'}",
|
||||||
|
f"+incdir+{ROOT / 'rtl/mini/top'}",
|
||||||
|
f"+incdir+{ROOT / 'rtl/managed/clusterip/common/rtl'}",
|
||||||
|
str(ROOT / "rtl/managed/clusterip/common/rtl/interface/apb4_pure_if.sv"),
|
||||||
|
str(ROOT / "rtl/managed/clusterip/common/rtl/utils/register.sv"),
|
||||||
|
str(ROOT / "rtl/managed/clusterip/common/rtl/utils/spill_register.sv"),
|
||||||
|
str(ROOT / "rtl/mini/top/rib_if.sv"),
|
||||||
|
str(ROOT / "rtl/mini/top/rib2apb.sv"),
|
||||||
|
str(ROOT / "tests/rtl/rib2apb_tb.sv"),
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
),
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
converted = tmp_path / "rib2apb_tb.v"
|
||||||
|
subprocess.run(
|
||||||
|
[
|
||||||
|
sys.executable,
|
||||||
|
str(ROOT / "rtl/mini/script/convt_sv2v.py"),
|
||||||
|
"-f",
|
||||||
|
str(source_list),
|
||||||
|
"--output",
|
||||||
|
str(converted),
|
||||||
|
],
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
simulation = tmp_path / "rib2apb_tb"
|
||||||
|
subprocess.run(
|
||||||
|
[iverilog, "-g2012", "-s", "rib2apb_tb", "-o", str(simulation), str(converted)],
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
result = subprocess.run([vvp, str(simulation)], text=True, capture_output=True, check=True)
|
||||||
|
|
||||||
|
assert "RIB2APB direct bridge test passed" in result.stdout
|
||||||
@@ -181,7 +181,7 @@ def test_formal_filelists_are_scoped_to_the_protocol_duts(tmp_path: Path) -> Non
|
|||||||
|
|
||||||
bus_filelist = tmp_path / "bus.fl"
|
bus_filelist = tmp_path / "bus.fl"
|
||||||
rib_adapter_filelist = tmp_path / "rib_adapter.fl"
|
rib_adapter_filelist = tmp_path / "rib_adapter.fl"
|
||||||
rib2apb_filelist = tmp_path / "ribp2apb.fl"
|
rib2apb_filelist = tmp_path / "rib2apb.fl"
|
||||||
sysctrl_filelist = tmp_path / "sysctrl.fl"
|
sysctrl_filelist = tmp_path / "sysctrl.fl"
|
||||||
pll_rcu_filelist = tmp_path / "pll_rcu.fl"
|
pll_rcu_filelist = tmp_path / "pll_rcu.fl"
|
||||||
gpio_user_filelist = tmp_path / "gpio_user.fl"
|
gpio_user_filelist = tmp_path / "gpio_user.fl"
|
||||||
@@ -190,7 +190,7 @@ def test_formal_filelists_are_scoped_to_the_protocol_duts(tmp_path: Path) -> Non
|
|||||||
"rib_adapter", rib_adapter_filelist, memory_map, topology, user_extensions
|
"rib_adapter", rib_adapter_filelist, memory_map, topology, user_extensions
|
||||||
)
|
)
|
||||||
assert generate_formal_filelist(
|
assert generate_formal_filelist(
|
||||||
"ribp2apb", rib2apb_filelist, memory_map, topology, user_extensions
|
"rib2apb", rib2apb_filelist, memory_map, topology, user_extensions
|
||||||
)
|
)
|
||||||
assert generate_formal_filelist(
|
assert generate_formal_filelist(
|
||||||
"sysctrl", sysctrl_filelist, memory_map, topology, user_extensions
|
"sysctrl", sysctrl_filelist, memory_map, topology, user_extensions
|
||||||
@@ -204,7 +204,7 @@ def test_formal_filelists_are_scoped_to_the_protocol_duts(tmp_path: Path) -> Non
|
|||||||
|
|
||||||
bus = parse_filelists([bus_filelist], require_files=False)
|
bus = parse_filelists([bus_filelist], require_files=False)
|
||||||
rib_adapter = parse_filelists([rib_adapter_filelist], require_files=False)
|
rib_adapter = parse_filelists([rib_adapter_filelist], require_files=False)
|
||||||
ribp2apb = parse_filelists([rib2apb_filelist], require_files=False)
|
rib2apb = parse_filelists([rib2apb_filelist], require_files=False)
|
||||||
sysctrl = parse_filelists([sysctrl_filelist], require_files=False)
|
sysctrl = parse_filelists([sysctrl_filelist], require_files=False)
|
||||||
pll_rcu = parse_filelists([pll_rcu_filelist], require_files=False)
|
pll_rcu = parse_filelists([pll_rcu_filelist], require_files=False)
|
||||||
gpio_user = parse_filelists([gpio_user_filelist], require_files=False)
|
gpio_user = parse_filelists([gpio_user_filelist], require_files=False)
|
||||||
@@ -216,9 +216,9 @@ def test_formal_filelists_are_scoped_to_the_protocol_duts(tmp_path: Path) -> Non
|
|||||||
assert ROOT / "rtl/mini/formal/bus_formal.sv" in bus.files
|
assert ROOT / "rtl/mini/formal/bus_formal.sv" in bus.files
|
||||||
assert ROOT / "rtl/mini/top/rib2ribp.sv" in rib_adapter.files
|
assert ROOT / "rtl/mini/top/rib2ribp.sv" in rib_adapter.files
|
||||||
assert ROOT / "rtl/mini/formal/rib_adapter_formal.sv" in rib_adapter.files
|
assert ROOT / "rtl/mini/formal/rib_adapter_formal.sv" in rib_adapter.files
|
||||||
assert ROOT / "rtl/ip/ribp/interconnect/ribp2apb.sv" in ribp2apb.files
|
assert ROOT / "rtl/mini/top/rib2apb.sv" in rib2apb.files
|
||||||
assert ROOT / "rtl/mini/formal/ribp2apb_formal.sv" in ribp2apb.files
|
assert ROOT / "rtl/mini/formal/rib2apb_formal.sv" in rib2apb.files
|
||||||
assert ROOT / "rtl/managed/clusterip/common/rtl/interface/apb4_pure_if.sv" in ribp2apb.files
|
assert ROOT / "rtl/managed/clusterip/common/rtl/interface/apb4_pure_if.sv" in rib2apb.files
|
||||||
assert ROOT / "rtl/ip/ribp/peripheral/sysctrl.sv" in sysctrl.files
|
assert ROOT / "rtl/ip/ribp/peripheral/sysctrl.sv" in sysctrl.files
|
||||||
assert ROOT / "rtl/mini/formal/sysctrl_formal.sv" in sysctrl.files
|
assert ROOT / "rtl/mini/formal/sysctrl_formal.sv" in sysctrl.files
|
||||||
assert ROOT / "rtl/mini/top/rcu.sv" in pll_rcu.files
|
assert ROOT / "rtl/mini/top/rcu.sv" in pll_rcu.files
|
||||||
@@ -270,7 +270,7 @@ def test_fatfs_release_script_uses_the_locked_archive_contract() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_formal_result_summary_requires_every_passing_step(tmp_path: Path) -> None:
|
def test_formal_result_summary_requires_every_passing_step(tmp_path: Path) -> None:
|
||||||
proofs = ("bus", "ribp2apb", "sysctrl", "pll_rcu", "gpio_user")
|
proofs = ("bus", "rib2apb", "sysctrl", "pll_rcu", "gpio_user")
|
||||||
for proof in proofs:
|
for proof in proofs:
|
||||||
directory = tmp_path / proof
|
directory = tmp_path / proof
|
||||||
directory.mkdir()
|
directory.mkdir()
|
||||||
@@ -292,7 +292,7 @@ def test_formal_result_summary_requires_every_passing_step(tmp_path: Path) -> No
|
|||||||
"--proof",
|
"--proof",
|
||||||
f"bus={tmp_path / 'bus'}",
|
f"bus={tmp_path / 'bus'}",
|
||||||
"--proof",
|
"--proof",
|
||||||
f"ribp2apb={tmp_path / 'ribp2apb'}",
|
f"rib2apb={tmp_path / 'rib2apb'}",
|
||||||
"--proof",
|
"--proof",
|
||||||
f"sysctrl={tmp_path / 'sysctrl'}",
|
f"sysctrl={tmp_path / 'sysctrl'}",
|
||||||
"--proof",
|
"--proof",
|
||||||
|
|||||||
@@ -86,14 +86,14 @@ def test_topology_generates_complete_rib_apb_and_gpio_bindings(tmp_path: Path) -
|
|||||||
assert "assign u_gpio_if.alt1_do_i[22] = u_psram_if.nss_o[0];" in gpio
|
assert "assign u_gpio_if.alt1_do_i[22] = u_psram_if.nss_o[0];" in gpio
|
||||||
assert apb_interfaces.count("apb4_if u_") == 10
|
assert apb_interfaces.count("apb4_if u_") == 10
|
||||||
assert "apb4_pure_if u_archinfo_apb_pure_if ();" in apb_interfaces
|
assert "apb4_pure_if u_archinfo_apb_pure_if ();" in apb_interfaces
|
||||||
assert "assign tmr.paddr = ribp.addr;" in apb_routes
|
assert "assign tmr.paddr = s_addr_q;" in apb_routes
|
||||||
assert "({32{s_psel_q[8]}} & tmr.prdata)" in apb_response
|
assert "({32{s_psel_q[8]}} & tmr.prdata)" in apb_response
|
||||||
assert "localparam int NSLV = 10;" in apb_declarations
|
assert "localparam int NSLV = 10;" in apb_declarations
|
||||||
assert fabric.count("ribp_if u_") == 2
|
assert fabric.count("ribp_if u_") == 1
|
||||||
assert fabric.count("rib_if u_") == 3
|
assert fabric.count("rib_if u_") == 4
|
||||||
assert ".mgmt_ribp(u_mgmt_ribp_if)" in bus_fabric
|
assert ".mgmt_ribp(u_mgmt_ribp_if)" in bus_fabric
|
||||||
assert ".user_rib(u_user_rib_if)" in bus_fabric
|
assert ".user_rib(u_user_rib_if)" in bus_fabric
|
||||||
assert ".apb_ribp(u_apb_ribp_if)" in bus_fabric
|
assert ".apb_rib(u_apb_rib_if)" in bus_fabric
|
||||||
assert ".rib(u_rib_if)" in bus_fabric
|
assert ".rib(u_rib_if)" in bus_fabric
|
||||||
assert "`define SOC_IRQ_VECTOR_WIDTH 32" in irq_config
|
assert "`define SOC_IRQ_VECTOR_WIDTH 32" in irq_config
|
||||||
assert "`define SOC_IRQ_RIBP_WIDTH 10" in irq_config
|
assert "`define SOC_IRQ_RIBP_WIDTH 10" in irq_config
|
||||||
@@ -147,8 +147,8 @@ def test_topology_always_adds_the_user_apb_target(tmp_path: Path) -> None:
|
|||||||
interfaces = (tmp_path / "rtl/soc_apb_interfaces.svh").read_text(encoding="utf-8")
|
interfaces = (tmp_path / "rtl/soc_apb_interfaces.svh").read_text(encoding="utf-8")
|
||||||
declarations = (tmp_path / "rtl/soc_apb_declarations.svh").read_text(encoding="utf-8")
|
declarations = (tmp_path / "rtl/soc_apb_declarations.svh").read_text(encoding="utf-8")
|
||||||
response = (tmp_path / "rtl/soc_apb_response_mux.svh").read_text(encoding="utf-8")
|
response = (tmp_path / "rtl/soc_apb_response_mux.svh").read_text(encoding="utf-8")
|
||||||
formal_design = (ROOT / "rtl/mini/formal/ribp2apb_formal.sv").read_text(encoding="utf-8")
|
formal_design = (ROOT / "rtl/mini/formal/rib2apb_formal.sv").read_text(encoding="utf-8")
|
||||||
formal_properties = (ROOT / "rtl/mini/formal/ribp2apb_formal_props.sv").read_text(
|
formal_properties = (ROOT / "rtl/mini/formal/rib2apb_formal_props.sv").read_text(
|
||||||
encoding="utf-8"
|
encoding="utf-8"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ def test_topology_always_adds_the_user_apb_target(tmp_path: Path) -> None:
|
|||||||
assert "apb4_pure_if user_ip ();" in formal_design
|
assert "apb4_pure_if user_ip ();" in formal_design
|
||||||
assert ".user_ip (user_ip)" in formal_design
|
assert ".user_ip (user_ip)" in formal_design
|
||||||
assert "logic [ 9:0] psel_comb" in formal_design
|
assert "logic [ 9:0] psel_comb" in formal_design
|
||||||
assert "wire [9:0] psel_comb" in formal_properties
|
assert "wire [ 9:0] psel_comb" in formal_properties
|
||||||
|
|
||||||
|
|
||||||
def test_topology_rejects_unknown_or_non_rib_regions(tmp_path: Path) -> None:
|
def test_topology_rejects_unknown_or_non_rib_regions(tmp_path: Path) -> None:
|
||||||
|
|||||||
Reference in new issue
Block a user