Skip to content

Shared block infrastructure, fixes to existing blocks and SysConfig test harness - #22

Open
pratheesh wants to merge 17 commits into
TexasInstruments:mainfrom
pratheesh:feat/block-infrastructure
Open

pratheesh wants to merge 17 commits into
TexasInstruments:mainfrom
pratheesh:feat/block-infrastructure

Conversation

@pratheesh

Copy link
Copy Markdown

Summary

Adds the shared infrastructure that the new PRU blocks in the following pull requests build on, fixes defects in
existing blocks, and adds a small pytest harness that generates designs with the SysConfig 1.28 CLI. Based on main
(38266985).

What changes

  • Register allocator (common/register_allocation/pru_register_allocator.js): a value's registers are released after
    its last data consumer (loop-invariant values included); Loop pre-initialisation, accumulator bindings and exported
    loop results; per-output-port routing, with a validation error for a connection to a port that owns no register;
    a recorded error when the register pool is exhausted; reservation of registers typed into block fields, with
    conflict detection; multi-output macro destinations. TI's 64-bit (lo/hi register) sources and outputs are kept.
  • Static module (common/pru_blocks_static_module.syscfg.js): validation of allocation failures, typed-register
    conflicts, unconnected required inputs, invalid port links, loop/container boundaries and macro arity; CTPPR0 setup
    (c28 to PRU shared RAM) and the SPI CS idle level at program start and at every group start; GUI warnings for
    GPO/GPI pads shared between blocks and for duplicate GPO drivers (warnings only, code generation still runs); a
    device-capability check for blocks that need a specific hardware widget, failing closed when the capability data is
    unavailable.
  • Generator templates (pru_syscfg.asm.xdt, pru_syscfg.inc.xdt): TEMP_REG3/TEMP_REG4 (R26/R27) and the prologue.
  • Shared helpers: pru_reserved_names.js (clpru reserved identifiers, checked with clpru 2.3.3),
    pru_spi_timing.js (SPI delay limits and program-memory budget), pru_device_caps.js (per-SoC hardware widgets),
    block_control_flow_data.js.
  • Fixes to existing blocks:
    • crc_block, access_look_up_table: the table index is scaled to the entry size.
    • pru_gpi_block: the mask is built in the result register, so pins above 7 work (3 cycles).
    • pru_spi_read / pru_spi_transfer: the result register is cleared before sampling; 17-24 bit packets use a full
      register.
    • pru_spi_*: CS / data delays above the per-site limit are refused; program-memory budget warning.
    • pru_spi_read, MODE1 and MODE3 with LSB-first: SCLK high and low now last the configured widths. MODE1 LSB
      advanced its bit counter in the low half, so SCLK ran one cycle short high and one cycle long low; MODE3 LSB took
      one more cycle to store a 1 than a 0, so the high half grew by a cycle on every 1 bit. Both now count in the half
      the MSB variant counts in, and both sample paths are two instructions. Both macros keep their instruction count.
    • conditional_block: an unconnected TRUE/FALSE branch is a validation error (it used to fail later in clpru with
      an undefined cmp_FALSE symbol).
    • loop_block: nested hardware LOOP is refused (a multi-count Delay inside a finite Loop is now a validation error);
      exported results and accumulators.
    • delay_block: exact cycle documentation. load_constant_block: explicit output width.
    • memory_access_block: warning for a shared memory variable.
    • reserved-name checks on emitted symbols; getPinUsage on the GPI/GPO/SPI blocks.
  • examples/uart_crc/firmware/main.asm and the two pru1 example.syscfg files: see "Changes to a TI example".
  • Example linker.cmd files (38 of the 39; the Tamagawa one already had them): .udmem is placed in the data RAM the
    file uses for .bss, and .usmem in PRU_SHAREDMEM. The Memory Variable block reserves its buffers in these two
    sections; with no rule clpru placed them in instruction RAM after .text. tests/test_linker_section_rules.py
    checks every tracked linker file (38 of 40 cases fail on main's files; all pass here).
  • Tests and runners: tests/test_syscfg_add_instance.py (every module adds an instance through the SysConfig CLI),
    tests/test_fail_closed_gating.py, tests/test_shared_memvar_rename.py,
    tests/test_conditional_unconnected_branch.py, tests/test_uart_crc_firmware.py,
    tests/test_linker_section_rules.py, with scripts/*_runner.js.
    .gitignore adds build_out/.

Overlap with the open pull request "Fix if/else block issues and other issues"

That pull request touches the same areas: the allocator's pushInstruction, the label loops in
pru_syscfg.asm.xdt, and validation / documentation of the conditional, loop and delay blocks. This change does not
switch longDescription to getAIContext and does not touch ai.component.js or label.syscfg.js. Whichever merges
second needs a rebase in those files.

Changes to a TI example

The generated code of examples/uart_crc changes register use: values are now released after their last consumer, so
R0 bytes are reused. The example's main.asm read allocator registers it did not own, so this change updates it:
registers are named once, and the received frame is kept live on the receiving core. tests/test_uart_crc_firmware.py
runs the example on both boards and both cores and checks the stored data byte and the CRC match / mismatch result.
With TI's unchanged example this test fails on this branch (6 of 7); with the update it passes (7 of 7).

How it was tested

Tools: SysConfig 1.28 (SYSCFG_PATH), TI PRU CGT 2.3.3 (CGT_TI_PRU_PATH), and for the firmware test a checkout of
TI pru-simulator (PRU_SIMULATOR_PATH; run here against its main branch, 544d5ea).

python -m pytest tests -q -p no:cacheprovider
  • with SysConfig 1.28, clpru and PRU_SIMULATOR_PATH: 67 passed, 0 failed, 0 skipped;
  • without PRU_SIMULATOR_PATH: 61 passed, 0 failed, 6 skipped (the six uart_crc firmware cases);
  • with PRU_SIMULATOR_PATH, gmake on PATH and a repository-root imports.mak: 67 passed, 0 failed, 0 skipped.

Every TI firmware example (39 projects under examples/**/firmware/**/ti-pru-cgt/makefile) was built with its own
makefile (gmake all, SysConfig 1.28, clpru 2.3.3, DEVICE set to the project's EXPECTED_DEVICE), which links it
with its linker.cmd: 39 of 39 on main and 39 of 39 on this branch.

SysConfig Sanity Tests: the eight contexts of make syscfg-tests-am243x, syscfg-tests-am64x and
syscfg-tests-am261x (AM243x_ALX_beta, AM243x_ALV_beta and AM64x icss_g0_pru0 / icss_g0_pru1, AM261x
icss_m0_pru0 / icss_m0_pru1), each run as the makefile runs it with SysConfig 1.27.0
(sanityTests.js -s .metadata/product.json -d <device> -c <core> --excludeTests="migrateToAnyTarget"): every context
reports Total 0 error(s) and no line containing "failed", which is the workflow's pass condition.

Where the fixes are tested

  • In this pull request: fail-closed capability gating, SysConfig add-instance for every module, shared memory variable
    rename, unconnected If/Else branch, uart_crc firmware.
  • In the device-model / simulator pull request (they need its harness): crc and access-LUT index scaling, SPI
    read/transfer zero-extend, loop accumulators, Load Constant width, register-pool exhaustion, fan-out register alias,
    nested hardware LOOP, SPI CS timing, and the SPI read SCLK widths (tests/test_spi_sclk_duty.py: every read,
    write and transfer variant in all four modes and both bit orders; without the SPI read fix
    the MODE1 and MODE3 LSB read cases fail, 2 of 24).
  • In the core-blocks pull request: GPI pins above 7, group entry, Memory Variable placement in a linked map
    (tests/test_memory_placement.py). In the application pull request: CTPPR0 setup,
    reserved names. In the documentation pull request: delay cycles, SPI CS idle prologue.

Known limitations

  • AM263Px support is not part of this change set.
  • UART op blocks have no getPinUsage, so the pad-sharing warnings do not see UART pins.
  • TEMP_REG3/TEMP_REG4 are R26/R27, but the allocator pool is still R0-R27; a design that fills the pool can be handed
    R26/R27.
  • The GUI simulator (common/simulation/pru_core.js) in this pull request does not execute ZERO; the
    device-model / simulator pull request adds it.
  • No test checks that the SPI transfer TX word survives the ldi r_dataReg, 0 that clears the result register.
  • Nothing here is verified on silicon.

🤖 Generated with Claude Code

…module


Register allocator:
- release a block's registers after its last data consumer, including
  values produced outside a loop and read inside it
- keep pre-initialized loop values in their own register and support
  explicit loop accumulator bindings and exported loop results
- route each consumer input from the output port it is wired to and
  refuse connections to ports that own no register
- record register-pool exhaustion per block so validation can name it
- reserve user-typed registers that blocks emit verbatim and report
  overlapping ones
- give multi-result macros one destination register per output
- keep 64-bit (two register) sources and outputs

Static module and templates:
- report allocation failures, pinned-register conflicts, unconnected
  required inputs, invalid port connections, loop/container boundary
  violations and macro arity mismatches at validation time
- program CTPPR0 so c28 points at shared RAM when a block uses c28, and
  drive SPI controller CS pins to their idle level, at every entry into
  generated code
- warn in the GUI when a GPO/GPI pad is shared or a GPO has two drivers
- gate blocks that need a hardware widget on the device capability table
- define TEMP_REG3/TEMP_REG4 (R26/R27) for macros
- expand multi-line instructions in the simulator path

New shared scripts: pru_reserved_names.js (clpru reserved identifiers),
pru_spi_timing.js (SPI delay limits and IRAM budget), pru_device_caps.js
(per-SoC hardware widgets), block_control_flow_data.js.
- CRC16/CRC32: scale the table index to the entry size before the load
  (the byte offset does not fit the LBBO offset operand); 13 cycles
- Access Lookup Table: scale the index for ushort/uint tables (7 cycles)
- PRU GPI: build the bit mask in the result register so pins above 7
  work; 3 cycles, 4-byte output
- PRU SPI Read/Transfer: clear the result register before sampling so
  short packets are zero-extended; reserve the whole register for
  17-24 bit packets; one extra overhead cycle
- PRU SPI Read/Write/Transfer: refuse CS/data delays above 256 cycles,
  warn when the SPI blocks exceed the PRU IRAM budget
- If/Else: an unconnected true/false branch is an error (the generated
  code would reference an undefined label)
- Load Constant: optional explicit output width
- Loop: reject a hardware LOOP nested in a finite loop body; add
  exported result blocks and accumulator bindings
- Delay: document the exact cycle count and the nesting restriction
- Memory Access: warn when two blocks share one auto-created Memory
  Variable
- CRC, Lookup Table, Memory Variable, Group, If/Else: reject symbols that
  clash with clpru reserved identifiers
- PRU GPI/GPO and SPI blocks: declare the pins they use (getPinUsage)
- tests/test_syscfg_add_instance.py: every block module adds an instance
  through the SysConfig CLI (skipped when SysConfig is not installed)
- tests/test_fail_closed_gating.py: the device-capability gate fails
  closed on every degraded path
- tests/test_shared_memvar_rename.py, tests/test_conditional_unconnected_branch.py
- scripts/static_module_validate_runner.js, scripts/block_validate_runner.js,
  scripts/shared_memvar_runner.js: run block validators under node
… test

The register allocator now releases a register once its last reader has run,
so main.asm can no longer rely on a released register still holding its value.
Name the registers once in main.asm, and keep the received frame live on the
receiving core by reading it into an otherwise unused block output.

Add a firmware test that runs the example on the simulator for both boards and
both cores, checking the stored data byte and the CRC match/mismatch result.
The MODE1 LSB loop advanced its bit counter in the low half, where the delay
formulas assume none, so SCLK ran one cycle short high and one cycle long low.
The MODE3 LSB loop sampled a 1 bit one instruction slower than a 0 bit, so
its high half grew by a cycle on every 1. Both variants now count in the half
the MSB variant counts in, and both sample paths take two instructions.
The Memory Variable block reserves buffers in .udmem (data RAM) and .usmem
(shared RAM). With no rule for either section clpru placed them in
instruction RAM after .text. Each example linker file now places .udmem in
the data RAM its .bss uses and .usmem in PRU_SHAREDMEM, and a test checks
every tracked linker file.
@pratheesh-ti

Copy link
Copy Markdown
Collaborator

/agentic_describe

@pratheesh-ti

Copy link
Copy Markdown
Collaborator

/agentic_review

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add shared PRU block infrastructure and fix generated firmware

✨ Enhancement 🐞 Bug fix 🧪 Tests ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Improve register allocation and validation so invalid designs fail before generating incorrect
 firmware.
• Fix SPI, lookup-table, GPIO, loop, and UART/CRC behavior in existing blocks and examples.
• Add shared-memory linker rules and test harnesses for SysConfig validation and firmware.
Diagram

graph TD
  Design["SysConfig design"] --> Blocks["PRU blocks"] --> Allocator["Register allocator"] --> Validator["Static validation"] --> Templates["Assembly templates"] --> Firmware["PRU firmware"]
  Helpers["Shared helpers"] --> Blocks
  Helpers --> Validator
  Allocator --> Templates
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Precompute graph-wide register liveness
  • ➕ Could make last-use and loop-boundary rules easier to reason about as one analysis.
  • ➖ Requires a larger allocator redesign and explicit modeling of callable groups, loop-carried values, and emission order.

Recommendation: The incremental allocator changes fit the existing generator and preserve its allocation model. Prefer this approach for the shared-infrastructure PR, but prioritize generated-code regression tests for loop-carried values, multi-output routing, and register reuse; those are the highest-risk interactions.

Files changed (78) +3715 / -191

Enhancement (12) +2247 / -77
block_control_flow_data.jsClassify block control flow for pin checks +33/-0

Classify block control flow for pin checks

• Introduces shared sequential and continuous block classifications used by design-wide pin-sharing warnings.

.metadata/sysconfig/.meta/pru_blocks/common/block_control_flow_data.js

pru_blocks_static_module.syscfg.jsValidate designs and initialize shared hardware state +751/-15

Validate designs and initialize shared hardware state

• Reports allocation, graph, macro, symbol, pin-sharing, and device-capability issues. Adds c28 shared-RAM pointer and SPI CS idle setup at generated entry points, plus support for multiline instructions and additional temporary registers.

.metadata/sysconfig/.meta/pru_blocks/common/pru_blocks_static_module.syscfg.js

pru_device_caps.jsCentralize PRU widget availability +144/-0

Centralize PRU widget availability

• Defines per-SoC hardware capabilities and lookup functions that treat missing or unknown SoCs as unsupported.

.metadata/sysconfig/.meta/pru_blocks/common/pru_device_caps.js

pru_reserved_names.jsShare clpru reserved-name validation +160/-0

Share clpru reserved-name validation

• Adds assembler-checked identifier rules and validators for instance names, fields, and derived symbols.

.metadata/sysconfig/.meta/pru_blocks/common/pru_reserved_names.js

pru_spi_timing.jsCentralize SPI timing and IRAM checks +153/-0

Centralize SPI timing and IRAM checks

• Converts nanosecond delays to PRU cycles, rejects excessive per-site delays, and warns when estimated SPI code size exceeds the instruction-memory budget.

.metadata/sysconfig/.meta/pru_blocks/common/pru_spi_timing.js

pru_syscfg.asm.xdtEmit startup setup at generated entry points +16/-0

Emit startup setup at generated entry points

• Defines additional macro temporaries and emits c28 pointer and SPI CS idle setup at the main entry and group starts.

.metadata/sysconfig/.meta/pru_blocks/common/pru_syscfg.asm.xdt

pru_syscfg.inc.xdtDefine two additional macro temporaries +2/-0

Define two additional macro temporaries

• Adds TEMP_REG3 and TEMP_REG4 aliases for R26 and R27.

.metadata/sysconfig/.meta/pru_blocks/common/pru_syscfg.inc.xdt

pru_register_allocator.jsTrack register liveness, ports, and loop values +785/-49

Track register liveness, ports, and loop values

• Releases values after their last data consumer while preserving loop-live values; supports accumulator bindings, exported results, and distinct output-port registers. Records exhaustion, invalid routes, boundary violations, and typed-register conflicts for validation.

.metadata/sysconfig/.meta/pru_blocks/common/register_allocation/pru_register_allocator.js

load_constant_block.syscfg.jsAllow explicit constant output widths +37/-3

Allow explicit constant output widths

• Adds selectable one-, two-, and four-byte register widths and rejects widths too small for the configured constant.

.metadata/sysconfig/.meta/pru_blocks/data_handling/load_constant_block.syscfg.js

loop_block.syscfg.jsDefine safe loop exports and accumulators +142/-6

Define safe loop exports and accumulators

• Adds validated accumulator bindings and exported result selections. Rejects nested hardware LOOP use, including eligible Delay blocks, and corrects loop guidance.

.metadata/sysconfig/.meta/pru_blocks/program_control/loop_block.syscfg.js

pru_gpo_block.syscfg.jsExpose GPO pin usage +7/-1

Expose GPO pin usage

• Reports the configured output pin to the design-wide pin-collision validator.

.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/pru_gpo_block.syscfg.js

pru_spi_write.syscfg.jsApply shared SPI checks to writes +17/-3

Apply shared SPI checks to writes

• Adds delay-limit and IRAM-budget validation and exposes the block's pin usage.

.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/pru_spi_write.syscfg.js

Bug fix (14) +350 / -110
crc_block.syscfg.jsScale CRC table offsets +44/-13

Scale CRC table offsets

• Scales CRC16 and CRC32 lookup indices to entry size, updates cycle counts, and validates reserved table-symbol names.

.metadata/sysconfig/.meta/pru_blocks/application_specific/crc_block.syscfg.js

conditional_block.syscfg.jsReject unconnected conditional branches +11/-4

Reject unconnected conditional branches

• Makes missing true or false branches validation errors instead of warnings and checks derived branch labels against reserved names.

.metadata/sysconfig/.meta/pru_blocks/program_control/conditional_block.syscfg.js

group_block.syscfg.jsValidate derived group entry labels +8/-1

Validate derived group entry labels

• Checks generated group-start symbols against the shared reserved-name rules.

.metadata/sysconfig/.meta/pru_blocks/program_control/group_block.syscfg.js

pru_gpi_block.syscfg.jsBuild GPI masks in the destination register +24/-14

Build GPI masks in the destination register

• Generates a full-register mask before reading R31 so higher-numbered pins work, updates the output width and cycle count, and exposes pin usage.

.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/pru_gpi_block.syscfg.js

pru_spi_read.syscfg.jsCorrect SPI read results and LSB clock timing +60/-17

Correct SPI read results and LSB clock timing

• Clears receive results, reserves a full register for 17–24-bit packets, and balances MODE1/MODE3 LSB sampling timing. Adds shared timing checks and pin usage.

.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/pru_spi_read.syscfg.js

pru_spi_transfer.syscfg.jsInitialize SPI transfer receive results +41/-8

Initialize SPI transfer receive results

• Clears the receive destination before sampling, reserves full-width results above 16 bits, adjusts cycle estimates, and adds shared timing and pin checks.

.metadata/sysconfig/.meta/pru_blocks/pru_io_blocks/pru_spi_transfer.syscfg.js

access_look_up_table.syscfg.jsScale multi-byte lookup-table indices +34/-8

Scale multi-byte lookup-table indices

• Converts ushort and uint entry indices to byte offsets before loading and updates their cycle estimates.

.metadata/sysconfig/.meta/pru_blocks/utils/access_look_up_table.syscfg.js

delay_block.syscfg.jsIdentify hardware-loop delays +21/-36

Identify hardware-loop delays

• Marks delays longer than one cycle as hardware-LOOP users for enclosing-loop validation and corrects timing and nesting guidance.

.metadata/sysconfig/.meta/pru_blocks/utils/delay_block.syscfg.js

look_up_table.syscfg.jsValidate lookup-table symbol names +8/-1

Validate lookup-table symbol names

• Rejects instance names reserved by clpru before emitting lookup-table data symbols.

.metadata/sysconfig/.meta/pru_blocks/utils/look_up_table.syscfg.js

memory_access_block.syscfg.jsWarn about shared memory-variable renames +55/-0

Warn about shared memory-variable renames

• Detects Memory Access instances sharing one auto-created memory-variable object and documents how to use separate instances.

.metadata/sysconfig/.meta/pru_blocks/utils/memory_access_block.syscfg.js

memory_variable_block.syscfg.jsValidate memory reservation labels +7/-0

Validate memory reservation labels

• Rejects reserved assembler identifiers used as .usect labels.

.metadata/sysconfig/.meta/pru_blocks/utils/memory_variable_block.syscfg.js

example.syscfgRetain the received frame as a final result +8/-1

Retain the received frame as a final result

• Adds a final memory-read block so the PRU1 example retains the received frame registers for main.asm.

examples/uart_crc/firmware/am243x-lp/icss_g0_pru1_fw/example.syscfg

example.syscfgRetain the received frame as a final result +8/-1

Retain the received frame as a final result

• Adds a final memory-read block so the PRU1 example retains the received frame registers for main.asm.

examples/uart_crc/firmware/am261x-lp/icss_m1_pru1_fw/example.syscfg

main.asmRead the UART/CRC example's allocated registers +21/-6

Read the UART/CRC example's allocated registers

• Names the TX data, received frame, and computed CRC registers and uses those names for shared-memory stores and CRC comparison.

examples/uart_crc/firmware/main.asm

Refactor (3) +3 / -3
arithmetic_block.syscfg.jsNormalize arithmetic block file ending +1/-1

Normalize arithmetic block file ending

• Adds a final newline without changing block behavior.

.metadata/sysconfig/.meta/pru_blocks/data_handling/arithmetic_block.syscfg.js

bitwise_block.syscfg.jsNormalize bitwise block file ending +1/-1

Normalize bitwise block file ending

• Adds a final newline without changing block behavior.

.metadata/sysconfig/.meta/pru_blocks/data_handling/bitwise_block.syscfg.js

flow_control_block.syscfg.jsNormalize flow-control block file ending +1/-1

Normalize flow-control block file ending

• Adds a final newline without changing block behavior.

.metadata/sysconfig/.meta/pru_blocks/program_control/flow_control_block.syscfg.js

Tests (10) +1037 / -0
block_validate_runner.jsAdd reusable block-validator runner +309/-0

Add reusable block-validator runner

• Loads block validators in a mocked SysConfig runtime, accepts JSON instance inputs, and reports validation results or a validator inventory.

scripts/block_validate_runner.js

shared_memvar_runner.jsExercise shared memory-variable validation +68/-0

Exercise shared memory-variable validation

• Runs real Memory Access validation against shared, separate, and explicitly selected memory-variable scenarios.

scripts/shared_memvar_runner.js

static_module_validate_runner.jsExercise device-capability failure paths +136/-0

Exercise device-capability failure paths

• Loads the real static validator with mocked SysConfig dependencies and simulates unavailable capability data and lookup failures.

scripts/static_module_validate_runner.js

conftest.pyMake repository imports available to pytest +7/-0

Make repository imports available to pytest

• Adds the repository root to the test import path.

tests/conftest.py

test_conditional_unconnected_branch.pyTest conditional branch validation +56/-0

Test conditional branch validation

• Checks that disconnected true and false branches are errors while a fully connected conditional remains valid.

tests/test_conditional_unconnected_branch.py

test_fail_closed_gating.pyTest fail-closed device gating +126/-0

Test fail-closed device gating

• Exercises capability lookup failures, missing or unknown SoCs, an unavailable table, and a known-good control.

tests/test_fail_closed_gating.py

test_linker_section_rules.pyCheck linker placement across examples +41/-0

Check linker placement across examples

• Verifies tracked linker scripts place .udmem with .bss and .usmem in PRU shared RAM.

tests/test_linker_section_rules.py

test_shared_memvar_rename.pyTest shared memory-variable warnings +53/-0

Test shared memory-variable warnings

• Checks the shared-object rename warning, unaffected cases, and guidance for separate memory variables.

tests/test_shared_memvar_rename.py

test_syscfg_add_instance.pyProbe block instantiation with SysConfig CLI +81/-0

Probe block instantiation with SysConfig CLI

• Attempts addInstance for each discovered block module and confirms an invalid module path is rejected; skips when SysConfig 1.28 is unavailable.

tests/test_syscfg_add_instance.py

test_uart_crc_firmware.pyTest generated UART/CRC firmware behavior +160/-0

Test generated UART/CRC firmware behavior

• Generates, links, and simulates the example for supported cores to check received-frame CRC outcomes and TX data; tool-dependent cases skip when dependencies are missing.

tests/test_uart_crc_firmware.py

Other (39) +78 / -1
.gitignoreIgnore generated build output +2/-1

Ignore generated build output

• Adds build_out/ to the ignore list.

.gitignore

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local and shared memory section rules for this firmware target.

examples/conditional/firmware/am243x-lp/icss_g0_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local and shared memory section rules for this firmware target.

examples/conditional/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Maps .udmem to local data RAM and .usmem to PRU shared RAM.

examples/empty/firmware/am243x-evm/icss_g0_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local and shared memory section placement for this PRU1 target.

examples/empty/firmware/am243x-evm/icss_g0_pru1_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local and shared memory section placement for this RTU target.

examples/empty/firmware/am243x-evm/icss_g0_rtu_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local and shared memory section placement for this RTU target.

examples/empty/firmware/am243x-evm/icss_g0_rtu_pru1_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local and shared memory section placement for this TX PRU target.

examples/empty/firmware/am243x-evm/icss_g0_tx_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local and shared memory section placement for this TX PRU target.

examples/empty/firmware/am243x-evm/icss_g0_tx_pru1_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds explicit local data RAM and shared RAM placement for reserved variables.

examples/empty/firmware/am243x-lp/icss_g0_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds explicit local data RAM and shared RAM placement for reserved variables.

examples/empty/firmware/am243x-lp/icss_g0_pru1_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local and shared RAM section rules for this RTU target.

examples/empty/firmware/am243x-lp/icss_g0_rtu_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local and shared RAM section rules for this RTU target.

examples/empty/firmware/am243x-lp/icss_g0_rtu_pru1_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local and shared RAM section rules for this TX PRU target.

examples/empty/firmware/am243x-lp/icss_g0_tx_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local and shared RAM section rules for this TX PRU target.

examples/empty/firmware/am243x-lp/icss_g0_tx_pru1_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds .udmem and .usmem placement for this ICSSM firmware target.

examples/empty/firmware/am261x-lp/icss_m0_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds .udmem and .usmem placement for this ICSSM firmware target.

examples/empty/firmware/am261x-lp/icss_m0_pru1_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds .udmem and .usmem placement for this ICSSM firmware target.

examples/empty/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds .udmem and .usmem placement for this ICSSM firmware target.

examples/empty/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local data RAM and shared RAM section rules.

examples/empty/firmware/am64x-evm/icss_g0_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local data RAM and shared RAM section rules.

examples/empty/firmware/am64x-evm/icss_g0_pru1_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local data RAM and shared RAM section rules for this RTU target.

examples/empty/firmware/am64x-evm/icss_g0_rtu_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local data RAM and shared RAM section rules for this RTU target.

examples/empty/firmware/am64x-evm/icss_g0_rtu_pru1_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local data RAM and shared RAM section rules for this TX PRU target.

examples/empty/firmware/am64x-evm/icss_g0_tx_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local data RAM and shared RAM section rules for this TX PRU target.

examples/empty/firmware/am64x-evm/icss_g0_tx_pru1_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local and shared RAM placement to the encoder example linker script.

examples/gray_encoder_4_bit/firmware/am243x-lp/icss_g0_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local and shared RAM placement to the encoder example linker script.

examples/gray_encoder_4_bit/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds explicit placement for local and shared memory variables.

examples/incremental_spi/firmware/am243x-lp/icss_g0_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds explicit placement for local and shared memory variables.

examples/incremental_spi/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds .udmem and .usmem section rules to the SPI example.

examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds .udmem and .usmem section rules to the SPI example.

examples/spi_10mhz/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local and shared memory section rules to the loopback example.

examples/spi_loopback/firmware/am243x-lp/icss_g0_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local and shared memory section rules to the loopback example.

examples/spi_loopback/firmware/am243x-lp/icss_g0_pru1_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local and shared memory section rules to the loopback example.

examples/spi_loopback/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds local and shared memory section rules to the loopback example.

examples/spi_loopback/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds explicit local and shared memory placement for the UART/CRC example.

examples/uart_crc/firmware/am243x-lp/icss_g0_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds explicit local and shared memory placement for the UART/CRC example.

examples/uart_crc/firmware/am243x-lp/icss_g0_pru1_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds explicit local and shared memory placement for the UART/CRC example.

examples/uart_crc/firmware/am261x-lp/icss_m1_pru0_fw/ti-pru-cgt/linker.cmd

linker.cmdPlace memory-variable sections +2/-0

Place memory-variable sections

• Adds shared RAM placement and a local-memory section rule to this PRU1 linker script.

examples/uart_crc/firmware/am261x-lp/icss_m1_pru1_fw/ti-pru-cgt/linker.cmd

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo


View medium (2)
Remediation recommended
1. Missing pad data suppresses sharing warnings 🐞
Description
getDevicePadSharing returns an empty Set when device data has neither a usable runtime pin
interface nor pinCommonInfos, treating unavailable metadata as evidence that no pads are shared.
When a design has GPO and GPI claims under that condition, validation emits neither a collision
warning nor the warning that pad sharing could not be checked.
Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Unavailable device pin metadata is treated as a valid empty sharing map, so designs with GPO and GPI claims receive no warning that sharing could not be checked.
## Fix Focus Areas
- .metadata/sysconfig/.meta/pru_blocks/common/pru_blocks_static_module.syscfg.js[1225-1279]
- .metadata/sysconfig/.meta/pru_blocks/common/pru_blocks_static_module.syscfg.js[1373-1385]
## Recommended Fix
Return `null` when none of the supported pin-data sources is available, while retaining an empty set when available data genuinely contains no shared pads. Add a validation case with GPO and GPI claims and missing pin metadata.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗

2. Validator script ignores the instance-file flag 🐞
Description
main() in scripts/block_validate_runner.js recognizes only --block and --inst, so its
positional fallback assigns --inst-file to blockPath or instJson before the file-reading
branch can run. With --inst-file f.json first, it looks for a block named --inst-file and exits
with “Block not found”; after a block path, it tries to parse --inst-file as JSON instead of
validating the instance in the file.
Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`--inst-file <path>` is consumed as a positional argument, preventing the runner from reading and validating the instance file.

## Fix Focus Areas
- scripts/block_validate_runner.js[277-301]

## Recommended Fix
Handle `--inst-file` and its following path in the argument loop before the positional fallbacks. After the loop, read and parse the specified file into `inst` with try/catch rather than parsing the option name as JSON; add the flag to the usage text and a CLI test for a file-based invocation.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗


View low (1)
Informational
3. Wide secondary outputs lose their upper half 🐞
Description
For multi-output macros, the allocator reserves width bytes for each outputN with N ≥ 2, but it
emits only getPruRegister(extraOffset, width). For widths above 4 bytes that returns just the
starting register. Consumers wired to those ports go through sourceRegisterToken(), which also
returns a single token, whereas output1 gets explicit lo/hi register pairs, so any 64-bit second
output passes only its low 32 bits to the macro and to downstream blocks.
Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Extra outputs (output2 and up) wider than 4 bytes are allocated 8 bytes but passed as one register, both as macro destinations and to their consumers.

## Fix Focus Areas
- .metadata/sysconfig/.meta/pru_blocks/common/register_allocation/pru_register_allocator.js[1396-1406]
- .metadata/sysconfig/.meta/pru_blocks/common/register_allocation/pru_register_allocator.js[1193-1196]

## Recommended Fix
When `width > 4`, push `getPruRegister(extraOffset,4) + ", " + getPruRegister(extraOffset+4,4)`. In `sourceRegisterToken` (or at the call site), emit lo and hi tokens when `alloc.numBytes > 4`, the same way the output1 path does. Alternatively, reject widths above 4 for non-output1 ports with a validation error.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗



// 2. Raw JSON device data structure (ICSSM devices, stubs and test harnesses). ICSSG pads carry a
// PRGx_PRUy_GPOn + PRGx_PRUy_GPIn pair; ICSSM pads carry one two-way PRx_PRUy_GPIOn signal.
const infos = deviceData.pinCommonInfos || {};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Missing pad data suppresses sharing warnings 🐞 Bug ◔ Observability

getDevicePadSharing returns an empty Set when device data has neither a usable runtime pin
interface nor pinCommonInfos, treating unavailable metadata as evidence that no pads are shared.
When a design has GPO and GPI claims under that condition, validation emits neither a collision
warning nor the warning that pad sharing could not be checked.
Agent Prompt
## Issue description
Unavailable device pin metadata is treated as a valid empty sharing map, so designs with GPO and GPI claims receive no warning that sharing could not be checked.
## Fix Focus Areas
- .metadata/sysconfig/.meta/pru_blocks/common/pru_blocks_static_module.syscfg.js[1225-1279]
- .metadata/sysconfig/.meta/pru_blocks/common/pru_blocks_static_module.syscfg.js[1373-1385]
## Recommended Fix
Return `null` when none of the supported pin-data sources is available, while retaining an empty set when available data genuinely contains no shared pads. Add a validation case with GPO and GPI claims and missing pin metadata.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 84aaee1: getDevicePadSharing now returns null when the device data has no usable pin source, so the "pad sharing could not be checked" warning is emitted; an empty set is kept only when available data has no shared pad. Added tests for missing, empty, shared-pad and no-shared-pad data.

Comment on lines +1397 to +1405
const width = parseInt(instance["output" + output + "Size"] || maxBytesUsed);
const extraOffset = getFreeByteOffset(width);
if (extraOffset === -1) {
recordAllocationFailure(instance, width, "result output" + output);
return -1;
}
moduleInstanceRegisterMap[instanceName]["byteOffsetOfOutput" + output] = extraOffset;
moduleInstanceRegisterMap[instanceName]["numOfBytesReqByOutput" + output] = width;
macroOutputRegisters.push(getPruRegister(extraOffset, width));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Informational

3. Wide secondary outputs lose their upper half 🐞 Bug ≡ Correctness

For multi-output macros, the allocator reserves width bytes for each outputN with N ≥ 2, but it
emits only getPruRegister(extraOffset, width). For widths above 4 bytes that returns just the
starting register. Consumers wired to those ports go through sourceRegisterToken(), which also
returns a single token, whereas output1 gets explicit lo/hi register pairs, so any 64-bit second
output passes only its low 32 bits to the macro and to downstream blocks.
Agent Prompt
## Issue description
Extra outputs (output2 and up) wider than 4 bytes are allocated 8 bytes but passed as one register, both as macro destinations and to their consumers.

## Fix Focus Areas
- .metadata/sysconfig/.meta/pru_blocks/common/register_allocation/pru_register_allocator.js[1396-1406]
- .metadata/sysconfig/.meta/pru_blocks/common/register_allocation/pru_register_allocator.js[1193-1196]

## Recommended Fix
When `width > 4`, push `getPruRegister(extraOffset,4) + ", " + getPruRegister(extraOffset+4,4)`. In `sourceRegisterToken` (or at the call site), emit lo and hi tokens when `alloc.numBytes > 4`, the same way the output1 path does. Alternatively, reject widths above 4 for non-output1 ports with a validation error.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in bb61cac: for output2 and up wider than 4 bytes the macro destination and the consumer's source now carry both registers (lo, hi), as output1 already does. Added an allocator test.

Comment thread scripts/block_validate_runner.js Outdated
Comment on lines +297 to +300
} else if (args.includes('--inst-file')) {
const idx = args.indexOf('--inst-file');
const fp = args[idx + 1];
inst = JSON.parse(fs.readFileSync(fp, 'utf8'));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

2. Validator script ignores the instance-file flag 🐞 Bug ≡ Correctness

main() in scripts/block_validate_runner.js recognizes only --block and --inst, so its
positional fallback assigns --inst-file to blockPath or instJson before the file-reading
branch can run. With --inst-file f.json first, it looks for a block named --inst-file and exits
with “Block not found”; after a block path, it tries to parse --inst-file as JSON instead of
validating the instance in the file.
Agent Prompt
## Issue description
`--inst-file <path>` is consumed as a positional argument, preventing the runner from reading and validating the instance file.

## Fix Focus Areas
- scripts/block_validate_runner.js[277-301]

## Recommended Fix
Handle `--inst-file` and its following path in the argument loop before the positional fallbacks. After the loop, read and parse the specified file into `inst` with try/catch rather than parsing the option name as JSON; add the flag to the usage text and a CLI test for a file-based invocation.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 498fcb0: --inst-file is parsed in the argument loop, the file is read and parsed (with an error and exit code 2 if it cannot be), and it is listed in the usage text. Added CLI tests for both argument orders.

manojKoppolu
manojKoppolu previously approved these changes Oct 29, 2026

@manojKoppolu manojKoppolu left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

The option was not recognised in the argument loop, so its name was taken as the
block path or the instance JSON and the file was never read. It is now parsed
with its path, read and parsed with a clear error on failure, and listed in the
usage text.
getDevicePadSharing returned an empty set when the device data had neither a
usable runtime pin interface nor pin common info, which the validator read as
"no pad is shared" and so emitted neither a collision warning nor the
"could not be checked" warning. It now returns null in that case, keeping an
empty set only when available data holds no shared pad.
…ry ports

A multi-output macro reserved the full width for output2 and up but emitted only
the first register of the pair, and consumers wired to such a port read only that
register, so a 64-bit second result lost its upper half. The macro destination and
the consumer's source token now carry both registers, as output1 already did.
TEMP_REG3 and TEMP_REG4 alias R26 and R27, which were still in the allocatable pool,
so a macro writing them could overwrite a live value or its own result. Before
allocation the pool now drops R26 and/or R27 when any block's macro text names
TEMP_REG3 and/or TEMP_REG4; designs that use neither keep the full 28-register
pool. The summary comments list the scratch registers in use and the out-of-registers
error mentions the bytes held for them.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants