Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
60342a6
Add shared block infrastructure to the register allocator and static …
pratheesh Oct 21, 2026
cb33194
Fix existing blocks: validation, cycle counts and register use
pratheesh Oct 21, 2026
e12969c
Add SysConfig test harness and block validator runners
pratheesh Oct 21, 2026
7b21a2e
Remove internal references from comments; neutral tool-path defaults …
pratheesh Oct 21, 2026
cef2e67
uart_crc example: read registers the allocator owns, and add firmware…
pratheesh Oct 21, 2026
5f6cb5b
Ignore build_out/ test output and remove trailing whitespace
pratheesh Oct 21, 2026
e545b30
Neutral comments; do not reference scripts and blocks added later
pratheesh Oct 21, 2026
de6f812
Improve validation descriptions and test coverage
pratheesh Oct 21, 2026
6bb6e12
Pin-sharing warnings describe the conflict instead of a check that do…
pratheesh Oct 21, 2026
469fc53
uart_crc firmware test: accept CGT_TI_PRU_PATH as used by imports.mak
pratheesh Oct 21, 2026
7e4cb23
Neutral comment wording in allocator, SPI read and validator runner
pratheesh Oct 21, 2026
8058a62
SPI read: MODE1 and MODE3 LSB SCLK halves match the configured widths
pratheesh Oct 21, 2026
e76b0e8
Example linker files place .udmem and .usmem
pratheesh Oct 21, 2026
498fcb0
Block validator runner reads the instance from --inst-file
pratheesh Nov 6, 2026
84aaee1
Pad sharing check reports unavailable device pin data as unknown
pratheesh Nov 6, 2026
bb61cac
Allocator passes lo/hi registers for outputs above 4 bytes on seconda…
pratheesh Nov 6, 2026
3ea5fee
Allocator holds back R26/R27 when block macros use TEMP_REG3/TEMP_REG4
pratheesh Nov 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@ mcusdk_tagfile
__pycache__/
!*boardcfg_*.bin
source/sysconfig/
source/board/pmic/pmic_lld/
source/board/pmic/pmic_lld/
build_out/
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ function getLookUptable(instance)
}

function validate(inst, report) {
// $name is emitted as the CRC lookup-table symbol ("<name> .byte/.ushort/.uint ..." in .initdmem); reject clpru reserved identifiers via the shared helper.
if (typeof system !== "undefined" && system.getScript) {
var reservedNames = system.getScript("/pru_blocks/common/pru_reserved_names.js");
if (reservedNames && typeof reservedNames.validateInstanceName === "function") {
reservedNames.validateInstanceName(inst, report, "This block emits the instance name as the CRC lookup-table symbol in .initdmem.");
}
}
if(inst["input1"].length == 0)
{
report.logWarning("crc is not intialized",inst)
Expand Down Expand Up @@ -153,17 +160,33 @@ function getMacro(pruInstructionMacro, opCode)
}

if (macroName && macroName.trim().startsWith("m_calculate_crc16")) {
// LUT entries are 2 bytes: the byte offset is index*2, which does not
// fit in a .b0 operand, so the scaled offset is added into the base
// and the LBBO offset register is zeroed (LDI TEMP_REG2, 0) first. The
// LDI is required on every model: without it the .b0 offset left in
// TEMP_REG2 is added a second time on top of the scaled base.
macroBody += ` LDI32 TEMP_REG1, ${lutAddress}
LSR TEMP_REG2.b0, ${crcInit}, 8
XOR TEMP_REG2.b0, TEMP_REG2.b0, ${dataByte}
AND TEMP_REG2, TEMP_REG2, 0xFF
LSL TEMP_REG2, TEMP_REG2, 1
ADD TEMP_REG1, TEMP_REG1, TEMP_REG2
LDI TEMP_REG2, 0
LBBO &${crcResult}, TEMP_REG1, TEMP_REG2.b0, 2
LSL TEMP_REG2, ${crcInit}, 8
XOR ${crcResult}, TEMP_REG2.w0, ${crcResult}`;
}
if (macroName && macroName.trim().startsWith("m_calculate_crc32")) {
// LUT entries are 4 bytes: the byte offset is index*4 (up to 1020),
// which does not fit in a .b0 operand, so the scaled offset is added
// into the base and the LBBO offset register is zeroed first.
macroBody += ` LDI32 TEMP_REG1, ${lutAddress}
LSR TEMP_REG2.b0, ${crcInit}, 24
XOR TEMP_REG2.b0, TEMP_REG2.b0, ${dataByte}
AND TEMP_REG2, TEMP_REG2, 0xFF
LSL TEMP_REG2, TEMP_REG2, 2
ADD TEMP_REG1, TEMP_REG1, TEMP_REG2
LDI TEMP_REG2, 0
LBBO &${crcResult}, TEMP_REG1, TEMP_REG2.b0, 4
LSL TEMP_REG2, ${crcInit}, 8
XOR ${crcResult}, TEMP_REG2, ${crcResult}`;
Expand Down Expand Up @@ -302,22 +325,30 @@ Calculates CRC checksums for error detection in data transmission and storage. C
- LDI32 TEMP_REG1, CRC_LUT_address ; Load LUT address
- LSR TEMP_REG2.b0, init, 8 ; Extract high byte
- XOR TEMP_REG2.b0, TEMP_REG2.b0, dataByte ; XOR with data
- AND TEMP_REG2, TEMP_REG2, 0xFF ; Zero-extend the table index
- LSL TEMP_REG2, TEMP_REG2, 1 ; Scale: entries are 2 bytes (index*2)
- ADD TEMP_REG1, TEMP_REG1, TEMP_REG2 ; Base += scaled byte offset
- LDI TEMP_REG2, 0 ; Zero the LBBO offset register
- LBBO &result, TEMP_REG1, TEMP_REG2.b0, 2 ; Lookup
- LSL TEMP_REG2, init, 8 ; Shift init left
- XOR result, TEMP_REG2.w0, result ; XOR with lookup (9 cycles)
- XOR result, TEMP_REG2.w0, result ; XOR with lookup (13 cycles)

**Generated Assembly** (CRC32 example):
- LDI32 TEMP_REG1, CRC_LUT_address ; Load LUT address
- LSR TEMP_REG2.b0, init, 24 ; Extract high byte
- XOR TEMP_REG2.b0, TEMP_REG2.b0, dataByte ; XOR with data
- AND TEMP_REG2, TEMP_REG2, 0xFF ; Zero-extend the table index
- LSL TEMP_REG2, TEMP_REG2, 2 ; Scale: entries are 4 bytes (index*4)
- ADD TEMP_REG1, TEMP_REG1, TEMP_REG2 ; Base += scaled byte offset
- LDI TEMP_REG2, 0 ; Zero the LBBO offset register
- LBBO &result, TEMP_REG1, TEMP_REG2.b0, 4 ; Lookup
- LSL TEMP_REG2, init, 8 ; Shift init left
- XOR result, TEMP_REG2, result ; XOR with lookup (9 cycles)
- XOR result, TEMP_REG2, result ; XOR with lookup (13 cycles)

**Performance**:
- CRC8: 6 PRU cycles per byte
- CRC16: 9 PRU cycles per byte
- CRC32: 9 PRU cycles per byte
- CRC16: 13 PRU cycles per byte
- CRC32: 13 PRU cycles per byte

**Lookup Table**: Automatically generated 256-entry table based on polynomial
- CRC8: 256 bytes (256 × 1 byte)
Expand Down Expand Up @@ -589,14 +620,14 @@ exports = {
{
return 6
}
if(inst["opCode"] == "m_calculate_crc16")
{
return 9
}
if(inst["opCode"] == "m_calculate_crc32")
{
return 9
}
if(inst["opCode"] == "m_calculate_crc16")
{
return 13
}
if(inst["opCode"] == "m_calculate_crc32")
{
return 13
}
}
}
],
Expand Down Expand Up @@ -627,4 +658,4 @@ exports = {
getMacro,
getDataSize,
getLookUptable
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Control-flow class ("sequential" or "continuous") of each block, used by the GUI pin-sharing check in
// pru_blocks_static_module: instances of one sequential module may share a two-way pad, and a GPO driven by
// two instances is flagged when either block is continuous. A block that is not listed is treated as
// continuous (the check fails closed). blockControlFlowBound names a config that makes a continuous block
// sequential when it is > 0.
exports = {
blockControlFlow: {
"access_look_up_table": "sequential",
"arithmetic_block": "sequential",
"bitwise_block": "sequential",
"conditional_block": "continuous",
"crc_block": "sequential",
"delay_block": "continuous",
"flow_control_block": "continuous",
"group_block": "continuous",
"label": "continuous",
"load_constant_block": "sequential",
"look_up_table": "continuous",
"loop_block": "continuous",
"memory_access_block": "continuous",
"memory_variable_block": "continuous",
"pru_gpi_block": "sequential",
"pru_gpo_block": "sequential",
"pru_spi_read": "sequential",
"pru_spi_transfer": "sequential",
"pru_spi_write": "sequential",
},
blockControlFlowBound: {
}
};
if (typeof module !== 'undefined') {
module.exports = exports;
}
Loading