Skip to main content

u280_shell_rhdl/
abi.rs

1//! Frozen host/kernel ABI constants and terminal diagnostics.
2
3use rhdl::prelude::*;
4
5/// Maximum number of jobs in one launch.
6pub const MAX_BATCH: u32 = 65_535;
7/// Input bytes consumed for each job.
8pub const INPUT_BYTES_PER_JOB: u64 = 64;
9/// Valid output bytes produced for each successful job.
10pub const OUTPUT_PAYLOAD_BYTES: u64 = 2_208;
11/// AXI4 payload beats in one output frame.
12pub const OUTPUT_AXI_BEATS: u8 = 35;
13/// Reserved bytes in each independently addressable output slot.
14pub const OUTPUT_SLOT_BYTES: u64 = 4_096;
15/// Complete-frame block-RAM slots.
16pub const FRAME_BUFFER_SLOTS: usize = 2;
17/// Maximum signer jobs represented by the shell scoreboard.
18pub const LIVE_JOB_SLOTS: usize = 12;
19/// Host-provided ABI guard word.
20pub const HASHSIGS_HBM_ABI_V1: u32 = 0x4853_0001;
21/// Binary summary revision stored in summary bytes 4 and 5.
22pub const SUMMARY_ABI_REVISION: u16 = 1;
23/// Wire tag for `HASHSIGS_SHA256_GENERIC_V1`.
24pub const SHA256_PROFILE_WIRE_TAG: u8 = 1;
25
26// These typed constants are the synthesizable counterparts of the host-facing
27// native integers above.  A pinned RHDL kernel may reference `Bits` and `u128`
28// constants, but native `u8`/`u16`/`u32`/`u64` values are not `Digital`.
29pub(crate) const MAX_BATCH_BITS: b32 = b32(MAX_BATCH as u128);
30pub(crate) const INPUT_ALIGNMENT_MASK: b64 = b64(INPUT_BYTES_PER_JOB as u128 - 1);
31pub(crate) const OUTPUT_ALIGNMENT_MASK: b64 = b64(OUTPUT_SLOT_BYTES as u128 - 1);
32pub(crate) const OUTPUT_AXI_LEN: b8 = b8(OUTPUT_AXI_BEATS as u128 - 1);
33pub(crate) const ABI_WORD_BITS: b32 = b32(HASHSIGS_HBM_ABI_V1 as u128);
34pub(crate) const SUMMARY_ABI_REVISION_LO_BITS: b8 = b8(SUMMARY_ABI_REVISION as u128 & 0xff);
35pub(crate) const SUMMARY_ABI_REVISION_HI_BITS: b8 = b8(SUMMARY_ABI_REVISION as u128 >> 8);
36pub(crate) const SHA256_PROFILE_WIRE_TAG_BITS: b8 = b8(SHA256_PROFILE_WIRE_TAG as u128);
37
38/// Successful completion.
39pub const TERMINAL_SUCCESS: u8 = 0;
40/// Static launch arguments failed validation.
41pub const TERMINAL_CONFIGURATION: u8 = 1;
42/// Software requested a fail-closed abort.
43pub const TERMINAL_ABORTED: u8 = 2;
44/// HBM0 returned a malformed or failing read response.
45pub const TERMINAL_INPUT_AXI: u8 = 3;
46/// A payload HBM1 write returned a malformed or failing response.
47pub const TERMINAL_OUTPUT_AXI: u8 = 4;
48/// The signer reported an error completion or reset-only fault.
49pub const TERMINAL_SIGNER: u8 = 5;
50/// Internal framing, ownership, or count invariants failed.
51pub const TERMINAL_PROTOCOL: u8 = 6;
52/// The terminal summary write itself failed.
53pub const TERMINAL_SUMMARY_AXI: u8 = 7;
54
55pub(crate) const TERMINAL_SUCCESS_BITS: b8 = b8(TERMINAL_SUCCESS as u128);
56pub(crate) const TERMINAL_CONFIGURATION_BITS: b8 = b8(TERMINAL_CONFIGURATION as u128);
57pub(crate) const TERMINAL_ABORTED_BITS: b8 = b8(TERMINAL_ABORTED as u128);
58pub(crate) const TERMINAL_INPUT_AXI_BITS: b8 = b8(TERMINAL_INPUT_AXI as u128);
59pub(crate) const TERMINAL_OUTPUT_AXI_BITS: b8 = b8(TERMINAL_OUTPUT_AXI as u128);
60pub(crate) const TERMINAL_SIGNER_BITS: b8 = b8(TERMINAL_SIGNER as u128);
61pub(crate) const TERMINAL_PROTOCOL_BITS: b8 = b8(TERMINAL_PROTOCOL as u128);
62pub(crate) const TERMINAL_SUMMARY_AXI_BITS: b8 = b8(TERMINAL_SUMMARY_AXI as u128);
63
64/// Configuration validation failed.
65pub const ERROR_CONFIGURATION: u128 = 1 << 0;
66/// HBM0 read-channel contract failed.
67pub const ERROR_INPUT_AXI: u128 = 1 << 1;
68/// HBM1 payload write-channel contract failed.
69pub const ERROR_OUTPUT_AXI: u128 = 1 << 2;
70/// The signer produced an explicit error completion.
71pub const ERROR_SIGNER_COMPLETION: u128 = 1 << 3;
72/// The signer asserted a reset-only structural fault.
73pub const ERROR_SIGNER_FAULT: u128 = 1 << 4;
74/// A captured output beat was not canonical.
75pub const ERROR_FRAME: u128 = 1 << 5;
76/// Scoreboard ownership was missing, duplicated, or in the wrong state.
77pub const ERROR_SCOREBOARD: u128 = 1 << 6;
78/// Software requested a soft abort.
79pub const ERROR_SOFT_ABORT: u128 = 1 << 7;
80/// Terminal counters or queue state did not close exactly.
81pub const ERROR_COUNT: u128 = 1 << 8;
82/// Terminal summary write-channel contract failed.
83pub const ERROR_SUMMARY_AXI: u128 = 1 << 9;
84/// An impossible local buffer state was observed.
85pub const ERROR_BUFFER: u128 = 1 << 10;
86
87/// Configuration register addresses.
88pub mod register {
89    /// HLS-compatible start/done/idle/ready register.
90    pub const AP_CTRL: u128 = 0x00;
91    /// Global interrupt enable.
92    pub const GIER: u128 = 0x04;
93    /// Per-source interrupt enable.
94    pub const IP_IER: u128 = 0x08;
95    /// Toggle-on-write interrupt status.
96    pub const IP_ISR: u128 = 0x0c;
97    /// Input HBM base, low half.
98    pub const INPUTS_LO: u128 = 0x10;
99    /// Input HBM base, high half.
100    pub const INPUTS_HI: u128 = 0x14;
101    /// Reserved argument lane.
102    pub const INPUTS_RESERVED: u128 = 0x18;
103    /// Output HBM base, low half.
104    pub const OUTPUTS_LO: u128 = 0x1c;
105    /// Output HBM base, high half.
106    pub const OUTPUTS_HI: u128 = 0x20;
107    /// Reserved argument lane.
108    pub const OUTPUTS_RESERVED: u128 = 0x24;
109    /// Summary HBM pointer, low half.
110    pub const SUMMARY_LO: u128 = 0x28;
111    /// Summary HBM pointer, high half.
112    pub const SUMMARY_HI: u128 = 0x2c;
113    /// Reserved argument lane.
114    pub const SUMMARY_RESERVED: u128 = 0x30;
115    /// Number of sequential jobs.
116    pub const BATCH: u128 = 0x34;
117    /// Required ABI guard word.
118    pub const ABI_WORD: u128 = 0x38;
119    /// Opaque host nonce, low half.
120    pub const NONCE_LO: u128 = 0x3c;
121    /// Opaque host nonce, high half.
122    pub const NONCE_HI: u128 = 0x40;
123    /// Reserved argument lane.
124    pub const NONCE_RESERVED: u128 = 0x44;
125    /// Write-one-pulse soft abort command.
126    pub const COMMAND: u128 = 0x48;
127    /// Terminal code and sticky error flags.
128    pub const LAST_STATUS: u128 = 0x4c;
129    /// Signer admissions and complete-frame capture progress.
130    pub const PROGRESS0: u128 = 0x50;
131    /// Canonical memory completions and signer-error progress.
132    pub const PROGRESS1: u128 = 0x54;
133    /// Signer-output stall cycles, low half.
134    pub const OUTPUT_STALL_LO: u128 = 0x58;
135    /// Signer-output stall cycles, high half.
136    pub const OUTPUT_STALL_HI: u128 = 0x5c;
137    /// Scoreboard, frame queue, reader, and writer occupancy.
138    pub const QUEUE_STATUS: u128 = 0x60;
139    /// First failing job, or `0xffff_ffff` when no job was identified.
140    pub const FIRST_ERROR_JOB: u128 = 0x64;
141    /// First failure detail word.
142    pub const FIRST_ERROR_DETAIL: u128 = 0x68;
143    /// First canonical payload B retirement cycle, low half.
144    pub const MEMORY_FIRST_LO: u128 = 0x6c;
145    /// First canonical payload B retirement cycle, high half.
146    pub const MEMORY_FIRST_HI: u128 = 0x70;
147    /// Most recent canonical payload B retirement cycle, low half.
148    pub const MEMORY_LAST_LO: u128 = 0x74;
149    /// Most recent canonical payload B retirement cycle, high half.
150    pub const MEMORY_LAST_HI: u128 = 0x78;
151    /// First-to-last canonical payload B retirement span, low half.
152    pub const MEMORY_SPAN_LO: u128 = 0x7c;
153    /// First-to-last canonical payload B retirement span, high half.
154    pub const MEMORY_SPAN_HI: u128 = 0x80;
155}
156
157/// Return the 32-bit ABI guard as an RHDL value.
158#[must_use]
159pub const fn abi_word() -> b32 {
160    ABI_WORD_BITS
161}
162
163const _: () = {
164    assert!(OUTPUT_PAYLOAD_BYTES == 34 * 64 + 32);
165    assert!(OUTPUT_AXI_BEATS == 35);
166    assert!(OUTPUT_SLOT_BYTES.is_power_of_two());
167    assert!(INPUT_BYTES_PER_JOB.is_power_of_two());
168    assert!(FRAME_BUFFER_SLOTS == 2);
169    assert!(LIVE_JOB_SLOTS == 12);
170    assert!(MAX_BATCH_BITS.raw() == MAX_BATCH as u128);
171    assert!(INPUT_ALIGNMENT_MASK.raw() == INPUT_BYTES_PER_JOB as u128 - 1);
172    assert!(OUTPUT_ALIGNMENT_MASK.raw() == OUTPUT_SLOT_BYTES as u128 - 1);
173    assert!(OUTPUT_AXI_LEN.raw() + 1 == OUTPUT_AXI_BEATS as u128);
174    assert!(ABI_WORD_BITS.raw() == HASHSIGS_HBM_ABI_V1 as u128);
175    assert!(SUMMARY_ABI_REVISION_LO_BITS.raw() == SUMMARY_ABI_REVISION as u128 & 0xff);
176    assert!(SUMMARY_ABI_REVISION_HI_BITS.raw() == SUMMARY_ABI_REVISION as u128 >> 8);
177    assert!(SHA256_PROFILE_WIRE_TAG_BITS.raw() == SHA256_PROFILE_WIRE_TAG as u128);
178    assert!(TERMINAL_SUCCESS_BITS.raw() == TERMINAL_SUCCESS as u128);
179    assert!(TERMINAL_CONFIGURATION_BITS.raw() == TERMINAL_CONFIGURATION as u128);
180    assert!(TERMINAL_ABORTED_BITS.raw() == TERMINAL_ABORTED as u128);
181    assert!(TERMINAL_INPUT_AXI_BITS.raw() == TERMINAL_INPUT_AXI as u128);
182    assert!(TERMINAL_OUTPUT_AXI_BITS.raw() == TERMINAL_OUTPUT_AXI as u128);
183    assert!(TERMINAL_SIGNER_BITS.raw() == TERMINAL_SIGNER as u128);
184    assert!(TERMINAL_PROTOCOL_BITS.raw() == TERMINAL_PROTOCOL as u128);
185    assert!(TERMINAL_SUMMARY_AXI_BITS.raw() == TERMINAL_SUMMARY_AXI as u128);
186};