Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,18 @@ sim/work-obj*.cf

# Captured simulation outputs (e.g. mesh_impulse_response.txt from the testbenches)
sim/*.txt
/hardware/_backups/
/hardware/panel_2row_work/
/hardware/panel_direct_stack_experiment/
/hardware/courant_direct_stack_experiment/
/RADIAN_PCBs_and_case_backup_*/
/model/outputs/
*.step
*.stp
*.zip
*.jar
*.png
*.pdf
*.pyc
**/__pycache__/
/src/tb/*_trace.txt
89 changes: 77 additions & 12 deletions MILESTONES.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,88 @@
# Milestones

## M0: Numerical reference model & stability study
- [ ] MATLAB/Octave reference model (`model/fdtd_ref.m`)
- [ ] CFL/stability sweep with plots
- [ ] Repository scaffolding: `src/`, `sim/`, `docs/` tree and GHDL CI
- [x] MATLAB/Octave reference model (`model/fdtd_ref.m`)
- [x] CFL/stability sweep with plots (`model/stability_study.m`)
- [x] Repository scaffolding: `src/`, `sim/`, `docs/` tree and GHDL CI
(`.github/workflows/ghdl-ci.yml` installs GHDL and runs `make -C sim`,
which wildcards every testbench)

## M1: Node PE RTL & unit test
- [ ] `src/rtl/fdtd_pkg.vhd` — Q1.23 types and `node_update` function
- [ ] `src/rtl/node_element.vhd` — single-node processing element
- [ ] `src/tb/node_element_tb.vhd` — unit testbench; passes `make -C sim`
- [x] `src/rtl/fdtd_pkg.vhd` — Q1.23 types and `node_update` function
- [x] `src/rtl/node_element.vhd` — single-node processing element
- [x] `src/tb/node_element_tb.vhd` — unit testbench

## M2: Full mesh and system testbench
- [ ] `src/rtl/grid_mesh.vhd` — NX×NY structural mesh with boundary wiring
- [ ] `src/tb/top_resonator_tb.vhd` — impulse-response and stability tests
- [x] `src/rtl/grid_mesh.vhd` — NX×NY structural mesh with boundary wiring
- [x] `src/tb/top_resonator_tb.vhd` — impulse-response and stability tests

## M3: I/O integration
- [ ] `src/rtl/i2s_transceiver.vhd` — I2S RX/TX + sample-strobe
- [ ] `src/rtl/top_resonator.vhd` — top-level with control bus and CDC
- [x] `src/rtl/i2s_transceiver.vhd` — I2S RX/TX + sample-strobe
- [x] `src/rtl/top_resonator.vhd` — top-level with control bus and CDC

## M4: Board bring-up
- [ ] Synthesis for Digilent Arty A7 (Artix-7 + PMOD I2S2)
- [ ] Resource budget documented in `docs/resource_budget.md`
- [x] Synthesis for Digilent Arty A7 (`syn/vivado/arty_synth.vhd`,
`build_arty.tcl`, `arty_a7.xdc`)
- [x] Resource budget documented in `docs/resource_budget.md`

## M5: Standalone instrument board
- [x] `hardware/courant/` — tscircuit schematic for the Rev A board
- [x] Device pinouts checked against manufacturer datasheets
- [x] Board-specific electrical rule checks (`npm run check`)
- [x] Vivado pin constraints generated from the board's own `io` map
- [x] Route the board. 2192 segments, 4436.7 mm, 313 vias on six layers, both
ground planes uncut, no track under 0.15 mm: **0 DRC errors, 0
unconnected**. tscircuit places it; KiCad writes the Specctra DSN and
Freerouting cuts most of the copper (`npm run route`).
- [x] Finish the last connections. The nine that no router could close were not
a routing problem: the back-side decoupling array was 0402 centred on the
ball grid, and a 0402 land spans 1.56 mm on a 1.0 mm pitch, so each
capacitor covered all four of its ball's escape slots — ten of the twenty
slots needed. `design.ts` now places them as 0201, offset half a pitch
diagonally onto a slot and turned 45 degrees, which costs one slot per
capacitor instead of four. `scripts/reland_decaps.py` moves that onto the
routed board without re-routing it; `scripts/close.py` then closes what
is left with a real grid search, since every earlier tool could only draw
straight lines, Ls and mitres and the survivors needed 20-36 segment
paths. The two 0.1373 mm clearance violations are fixed by shifting the
offending segment 0.02 mm, not by moving components.
- [ ] Measure the actual 5 V draw on a real board. Estimated at ~0.30 A against
the 3 A the source specifies; that one number decides whether a Eurorack
case's +5 V rail can run it (see `deliverables/courant-eurorack.md`).
- [ ] Eurorack, if wanted: an adapter cable with a fuse and reverse-polarity
diode is enough for power, and one 10 kOhm resistor per CV channel from
VREF25 converts the front end to +/-5 V bipolar exactly. Only modular-level
audio output needs new circuitry — the board is 4.5 dB below it and has no
bipolar rail to swing into.
- [x] Panel board integrated at `hardware/panel/` (RADIAN Panel P1): 180.6 ×
108 mm, 4 layers, carrying the panel controls and the 12 V → 5.08 V
inlet. Ground planes filled (they had outlines but no fill, so there was
no plane), DRC run for the first time and cleared 2 → 0 by moving SW3
0.6 mm off two header courtyards, Gerbers and drills generated, and all
45 harness pins verified against the mainboard interface net for net.
Three `power_pin_not_driven` ERC findings remain by choice — see
`hardware/panel/INTEGRATION.md`.
- [ ] Fabricate and bring up: rails, JTAG, configuration, audio
- [x] SPI master RTL for the MCP3208 panel/CV ADC — `src/rtl/adc_mcp3208.vhd`
with `src/tb/adc_mcp3208_tb.vhd`. Scans CH0-2 (pots, to panel_ctrl) and
CH3-4 (pitch/mod CV, to cv_frontend) round-robin at 1 MHz SCLK, which is
the MCP3208's 2.7 V figure rather than its 5 V one because this board runs
it at VDD 3.3 V. **Not simulated here — GHDL is not installed in this
environment; the GHDL CI job is what verifies it.**
Integration note: the board's CV divider is 20k/20k into a 2.5 V
reference, so one volt is 819.2 codes, not the 4096 codes per volt
`cv_frontend`'s defaults assume. Instantiate it with CV_SCALE = 960,
CV_SHIFT = 16 for 1V/oct tracking.
- [x] Swap U1 to XC7A50T-1FTG256I. Done in `design.ts` and in the routed
board. The pin compatibility is now verified rather than assumed:
`reference/xc7a50tftg256pkg.txt` and `reference/xc7a35tftg256pkg.txt` are
byte-identical from line 2 to the end — all 256 balls, banks, I/O types
and no-connect flags — and differ only in the device name on the header
line. So the swap is a part number and nothing else: same footprint,
placement, copper, ball assignments and generated XDC. It is $51.74
cheaper (JLCPCB $67.01 against $118.75, 135 in stock against 175),
carries 52,160 logic cells against 33,280 and 120 DSP slices against 90 —
taking the 4-voice build off 82% DSP utilisation — and is industrial
temperature range rather than commercial. `npm run check` passes.
Still worth a Vivado synthesis run to confirm timing closes (same -1
speed grade, so it should).
57 changes: 57 additions & 0 deletions RADIAN_PCBs_and_case/06_final_actual_CAD_validation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"status": "PASS",
"final_assembly": "panel/cad/RADIAN_actual_parts_full_assembly.step",
"colored_step_children": 715,
"children_missing_explicit_color": [],
"near_white_default_children": [],
"u8": {
"reference": "U8 / H11L1M",
"native_footprint_center_mm": [
48.0,
139.0
],
"raw_kicad_step_expected_center_mm": [
48.0,
-139.0
],
"raw_kicad_step_actual_bbox_center_mm": [
48.0,
-139.0
],
"center_error_mm": [
0.0,
0.0
],
"model": "courant/deliverables/cad/models/DIP6_W7.62_U8_centered.step",
"pin_alignment": "PASS: six STEP lead centers map exactly to six native footprint pads under KiCad Y inversion"
},
"panel_drc": {
"violations": 0,
"unconnected": 0
},
"main_drc": {
"violations": 0,
"unconnected": 0
},
"direct_stack": {
"status": "PASS",
"checked": 40,
"matched": 40
},
"actual_part_collisions": {
"status": "PASS",
"panel_main_unintended_clashes": [],
"rear_guard_or_dock_clashes": [],
"intentional_stack_overlap": "P_STACK <-> M_STACK excluded; validated by direct-stack-validation.json"
},
"model_policy": {
"actual_or_package_geometry": "PTV09A family, PJ398SM, Omron B3F, LEDs, all normal IC/passive packages and selected Wurth/Molex models",
"explicit_drawing_derived_only": [
"PEC11R encoder",
"E-Switch MODE",
"Samtec stack pair",
"mainboard Molex J1-J4"
],
"generic_white_component_envelopes": "NONE"
}
}
13 changes: 13 additions & 0 deletions RADIAN_PCBs_and_case/07_kicad_actual_model_validation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"status": "PASS",
"renderer": "KiCad 10 high-quality 3D renderer",
"mainboard_models": {"total": 180, "colorless_or_missing": 0},
"panel_models": {"total": 59, "colorless_or_missing": 0},
"geometry_validation": "All changed representative 3D component bounding boxes matched before/after exactly.",
"electrical_geometry": "MATCH: footprint/pad/track/via/net signatures unchanged on both boards.",
"mainboard_drc": "0 violations, 0 unconnected items",
"panel_drc": "23 violations, 57 unconnected items; pre-change backup had 44 violations, 57 unconnected items",
"direct_stack": "PASS 40/40 contacts",
"collision_validation": "PASS: 0 enclosure clashes, 0 unintended panel/main clashes",
"j1_power_orientation": "preserved corrected orientation"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"status": "PASS",
"final_assembly": "panel/cad/RADIAN_actual_parts_full_assembly.step",
"colored_step_children": 715,
"children_missing_explicit_color": [],
"near_white_default_children": [],
"u8": {
"reference": "U8 / H11L1M",
"native_footprint_center_mm": [
48.0,
139.0
],
"raw_kicad_step_expected_center_mm": [
48.0,
-139.0
],
"raw_kicad_step_actual_bbox_center_mm": [
48.0,
-139.0
],
"center_error_mm": [
0.0,
0.0
],
"model": "courant/deliverables/cad/models/DIP6_W7.62_U8_centered.step",
"pin_alignment": "PASS: six STEP lead centers map exactly to six native footprint pads under KiCad Y inversion"
},
"panel_drc": {
"violations": 0,
"unconnected": 0
},
"main_drc": {
"violations": 0,
"unconnected": 0
},
"direct_stack": {
"status": "PASS",
"checked": 40,
"matched": 40
},
"actual_part_collisions": {
"status": "PASS",
"panel_main_unintended_clashes": [],
"rear_guard_or_dock_clashes": [],
"intentional_stack_overlap": "P_STACK <-> M_STACK excluded; validated by direct-stack-validation.json"
},
"model_policy": {
"actual_or_package_geometry": "PTV09A family, PJ398SM, Omron B3F, LEDs, all normal IC/passive packages and selected Wurth/Molex models",
"explicit_drawing_derived_only": [
"PEC11R encoder",
"E-Switch MODE",
"Samtec stack pair",
"mainboard Molex J1-J4"
],
"generic_white_component_envelopes": "NONE"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"status": "PASS",
"renderer": "KiCad 10 high-quality 3D renderer",
"mainboard_models": {"total": 180, "colorless_or_missing": 0},
"panel_models": {"total": 59, "colorless_or_missing": 0},
"geometry_validation": "All changed representative 3D component bounding boxes matched before/after exactly.",
"electrical_geometry": "MATCH: footprint/pad/track/via/net signatures unchanged on both boards.",
"mainboard_drc": "0 violations, 0 unconnected items",
"panel_drc": "23 violations, 57 unconnected items; pre-change backup had 44 violations, 57 unconnected items",
"direct_stack": "PASS 40/40 contacts",
"collision_validation": "PASS: 0 enclosure clashes, 0 unintended panel/main clashes",
"j1_power_orientation": "preserved corrected orientation"
}
16 changes: 16 additions & 0 deletions RADIAN_actual_parts_CAD/actual-parts-collision-validation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"status": "PASS",
"physical_pcb_faces": {
"panel_back_z_mm": -9.6,
"main_front_z_mm": -29.59,
"gap_mm": 19.99,
"target_mm": 19.99
},
"actual_components_vs_physical_enclosure_clashes": [],
"non_samtec_panel_vs_main_clashes": [],
"non_samtec_panel_vs_main_overlap_mm3": 0.0,
"notes": [
"Reference nuts, shims, standoffs, inks and PCB visualization layers are excluded from enclosure clash classification.",
"The intentionally mated Samtec J100/J101 to J17/J18 pair is excluded from panel-vs-main clash classification."
]
}
39 changes: 39 additions & 0 deletions RADIAN_actual_parts_CAD/actual-parts-full-assembly-validation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"status": "PASS",
"assembly": "panel/cad/RADIAN_actual_parts_full_assembly.step",
"renders": [
"panel/previews/actual_parts_full_assembly_iso.png",
"panel/previews/actual_parts_full_assembly_side.png",
"panel/previews/actual_parts_full_assembly_front.png"
],
"source_of_truth": "native KiCad component-filter STEP exports",
"color_persistence": "PASS: 715 colored children, 0 missing",
"u8_alignment": {
"reference": "U8 / H11L1M",
"native_footprint_center_mm": [
48.0,
139.0
],
"raw_kicad_step_expected_center_mm": [
48.0,
-139.0
],
"raw_kicad_step_actual_bbox_center_mm": [
48.0,
-139.0
],
"center_error_mm": [
0.0,
0.0
],
"model": "courant/deliverables/cad/models/DIP6_W7.62_U8_centered.step",
"pin_alignment": "PASS: six STEP lead centers map exactly to six native footprint pads under KiCad Y inversion"
},
"collision_validation": {
"status": "PASS",
"panel_main_unintended_clashes": [],
"rear_guard_or_dock_clashes": [],
"intentional_stack_overlap": "P_STACK <-> M_STACK excluded; validated by direct-stack-validation.json"
},
"placeholder_component_geometry_included": false
}
61 changes: 61 additions & 0 deletions RADIAN_actual_parts_CAD/actual_parts_report.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"status": "PASS",
"panel_native_board": "/home/ik/ChatGPT/Courant/hardware/panel/design/radian_panel.kicad_pcb",
"main_native_board": "/home/ik/ChatGPT/Courant/hardware/courant/deliverables/courant.kicad_pcb",
"dedicated_populated_board_cad": {
"panel": "panel/cad/RADIAN_actual_parts_panel_board.step",
"main": "panel/cad/RADIAN_actual_parts_main_board.step"
},
"dedicated_populated_board_renders": [
"panel/previews/actual_parts_panel_board_top.png",
"panel/previews/actual_parts_panel_board_bottom.png",
"panel/previews/actual_parts_main_board_top.png",
"panel/previews/actual_parts_main_board_bottom.png"
],
"panel_groups": {
"P_POTS": "RV1,RV2,RV3,RV4,RV5,RV6",
"P_ENCODER": "ENC1",
"P_MODE": "SW1",
"P_JACKS": "J301,J302,J303,J304,J305",
"P_LEDS": "D10,D11,D12,D13",
"P_STACK": "J100,J101",
"P_WURTH": "J200,JP1",
"P_MOLEX": "J201,J202,J306",
"P_BUTTONS": "SW3,SW4",
"P_ACTIVE": "U1,U2,D1,D2,D3,D4,L1,F1,F2",
"P_PASSIVES": "R*,C*"
},
"main_groups": {
"M_STACK": "J17,J18",
"M_MOLEX": "J1,J2,J3,J4",
"M_ICS": "U*,Y*",
"M_PASSIVES": "R*,C*",
"M_MAGNETICS": "L*",
"M_DIODES": "D*"
},
"collision_validation": "Use direct-stack-validation.json and case_direct_stack_update.json; this renderer preserves native KiCad placement.",
"panel_transform": {
"x": 0,
"y": 128.5,
"z": -9.6
},
"main_transform": {
"x": -12,
"y": 164.25,
"z": -31.1
},
"actual_or_package_models": [
"Bourns PTV09A family geometry aligned to PTV09A-4020F-B103 footprint/20 mm shaft",
"QingPu/Thonk PJ398SM open mechanical CAD with knurled nut",
"Omron B3F-1000 package geometry",
"3 mm green LED package geometry",
"all selected Wurth/Molex/Samtec and mainboard package STEP models already attached in KiCad"
],
"drawing_derived_remaining": [
"ENC1 Bourns PEC11R-4220F-S0024",
"SW1 E-Switch 100SP1T1B1M2REH",
"Samtec J100/J101/J17/J18",
"Molex mainboard J1-J4"
],
"note": "No generic white component envelopes are used in this final assembly; component placement comes from KiCad STEP export."
}
Loading
Loading