Files
NewInstrCalBoard/3.FW_Docs/CPLD_Firmware_Architecture.md
T

17 KiB

CPLD Firmware Architecture Reference

Project: NewCalBoard DIG
Toolchain: Lattice Diamond (CPLD1/2/3), Xilinx Vivado 2023.2 (NewExtInst_Debug)
Note: This firmware is NOT fully complete — several features are stubbed out or incomplete.


1. System Overview

The system uses a Zynq SoC (ARM + FPGA) architecture with 3 external Lattice CPLDs communicating via SPI:

┌─────────────────────────────────────────────────────────────────┐
│                    Zynq SoC (ARM + FPGA)                         │
│  ┌──────────┐    AXI    ┌──────────────┐    SPI    ┌─────────┐ │
│  │  ARM     │◄────────►│NewExtInst_TOP│◄────────►│  CPLDs   │ │
│  │  (Linux) │  GP0     │  (Vivado BD)   │  SPI_Con │  (3x)   │ │
│  └──────────┘           └──────────────┘          └─────────┘ │
│       ▲                        │                              │
│       │                        ▼                              │
│       │              ┌─────────────────┐                      │
│       │              │  clk_wiz (PLL)   │  → 100MHz CPLD clk │
│       │              │  proc_sys_reset  │                      │
│       │              └─────────────────┘                      │
│       │                        │                              │
│       │                        ▼                              │
│       │              ┌─────────────────┐                      │
│       │              │  ps7_axi_periph  │  (1→3 split)       │
│       │              └─────────────────┘                      │
└─────────────────────────────────────────────────────────────────┘

Key Components

Component Tool Purpose
NewExtInst_TOP Vivado 2023.2 Top-level block design (Zynq PS + AXI peripherals)
CPLD1/2/3 Lattice Diamond CPLD firmware (Verilog)
Release/*.jed Programming files for CPLDs

2. CPLD Architecture (CPLD1/2/3)

Each CPLD has the same 3-module internal structure:

RelayConTop (Top)
├── BUS_Con       — SPI master interface (Mode 0)
├── Reg_file      — Register file + FSM
└── CPLD_Con      — Relay control logic

2.1 Module: BUS_Con (SPI Interface)

Purpose: Implements a SPI Mode 0 (CPOL=0, CPHA=0) master interface.

SPI Protocol:

  • CS active LOW
  • MOSI sampled on rising edge of SCLK
  • MISO shifted on falling edge of SCLK
  • 32-bit transaction: [Bit31: WR] [Bit30:24: Addr(7bit)] [Bit23:0: Data(24bit)]

FSM States:

IDLE → CMD_SENT → DONE → IDLE
       ↑          ↓
    WAIT_BUSY   (waits for reg_busy to clear)

Key Signals:

Signal Direction Description
i_sclk input SPI clock
i_mosi input SPI data in
i_cs input Chip select (active LOW)
o_miso output SPI data out (tri-state)
o_cmd_valid output Command valid pulse
o_addr[6:0] output Register address
o_data[23:0] output Write data
o_wr output 1=write, 0=read
o_wready output Ready to accept new command
o_err output Bit count error flag

Important Notes:

  • o_rvalid is hardcoded to 1'b0 (not implemented)
  • Typo in original: o_rvaild vs o_rvalid in LPF
  • MISO is tri-stated when CS is HIGH: assign o_miso = cs_active ? miso_shift[31] : 1'bz;

2.2 Module: Reg_file (Register File)

Purpose: 16-register file (0-15) with read/write FSM.

Register Map:

Addr Name R/W Description
0 IDENT R/W Identity: 24'h200000 (CPLD3=0, CPLD2=0, CPLD1=1, Major=2, Minor=0, Rev=0)
1 STATE R/W State/Execution control. Bit 0 = EXEC trigger, Bit 23 = RDY, Bits 22:20 = Level
2 Freq_Slot1 R/W Frequency slot 1 relay control
3 Freq_Slot2 R/W Frequency slot 2 relay control
4 Freq_Slot3 R/W Frequency slot 3 relay control
5 Freq_Slot4 R/W Frequency slot 4 relay control
6 DC_Slot1 R/W DC slot 1 control
7 DC_Slot2 W DC slot 2 control (write-only per Excel)
8 DC_Slot3 W DC slot 3 control (write-only per Excel)
9 DC_Slot4 W DC slot 4 control (write-only per Excel)
10-15 Reserved/Unused

Register Bit Layout (24 bits):

Freq_Slot N (Addr 2-5):

Bit 23:8:   Per Relay_Control (1=Switch, 0=Not Switch)
Bit 17:12:  RC_Tx (for Slot 4 only) — 6 bits (T27-T32), updated from [14:10]
Bit 9:1:    Channel_Number (1-256)
Bit 0:      Slot_EN (1=Enable)

Relay Control Bits per Slot (from Excel Freq_CPLD sheet):

Slot RC_F RC_S RC_T
1 RC_F1, RC_F2 RC_S1-RC_S4 RC_T1-RC_T8
2 RC_F3, RC_F4 RC_S5-RC_S8 RC_T9-RC_T16
3 RC_F5, RC_F6 RC_S9-RC_S12 RC_T17-RC_T24
4 RC_F7, RC_F8 RC_S13-RC_S16 RC_T25-RC_T32

RC_Tx Mapping (CPLD1):

RC_Tx Bit Output Pin
[5] o_RC_T27
[4] o_RC_T28
[3] o_RC_T29
[2] o_RC_T30
[1] o_RC_T31
[0] o_RC_T32

Source: i_freq_relay4[17:12]RC_Tx[5:0] (updated from [14:10] in old version)

DC_Slot N (Addr 6-9):

Bit 23:     PMU(0)/DPS(1) — PMU or DPS mode select
Bit 22:     V(0)/I(1) — Voltage or Current select
Bit 21:17:  Rload_Sel (0-31) — Resistor selection (5-bit, 0-31 range)
Bit 16:     Reserved
Bit 9:1:    Channel_Number (1-256)
Bit 0:      Slot_EN (1=Enable)

FSM States:

IDLE → BUSY → EXEC_ACK → EXEC_WAIT → IDLE
                ↑
         (crash recovery: if exec_bit==1 at reset)

Execution Protocol:

  1. Write STATE register with bit 0 = 1
  2. Register FSM enters EXEC_ACK, waits for con_done to go LOW (controller busy)
  3. Enters EXEC_WAIT, waits for con_done to go HIGH (controller done)
  4. Auto-clears exec bit, sets ready bit
  5. Cannot write if controller is already running (exec_bit==1 → error)

2.3 Module: CPLD_Con (Control Logic)

Purpose: Decodes register values and generates relay control outputs.

Key Logic:

  • Sanity check: Only ONE enable bit should be active (en_t > 1 → error)
  • Freq mode: Routes channel numbers to OC_x01/OC_x17/DMM_EN based on channel range
  • DC mode: Selects resistor, PMU/DPS, V/I mode

Freq Slot Decoding (per slot, from CPLD_Con.v code):

Channel Range OC_x01 OC_x17 DMM_EN
1-8 Set 0 DMM1
9-72 0 0 DMM2/DMM3/DMM4
73-136 0 Set DMM3/DMM4
137-200 0 0 DMM4

Note: Code uses < 9, < 72, < 137, < 201 for ranges. Excel Freq_CPLD sheet shows actual channel groupings are more complex (e.g., "1-4&65-68||5-8&69-72").

ARM_CPLD Pin Assignments (from Excel ARM_CPLD sheet):

Signal CPLD1 Pin CPLD2 Pin CPLD3 Pin Notes
SCLK AA16 AA10 AA16 LPF discrepancy: CPLD1 LPF says AA10
CS AB11 Y15 AB11
MOSI AB12 AB12 AB12 Shared across all CPLDs
MISO AA14 AA14 AA14 Shared across all CPLDs
RST_N Y14 Y14 Y14
ERR AB16 AB16 AB16
WVAILD AA15 AA15 AA15
RREADY AB15 AA10 AB15 CPLD2: AA10 same as SCLK?
WREADY Y15 Y15 Y15
CLK AA10 AA16 AA10 CPLD1/3: AA10, CPLD2: AA16
RVAILD AA16 AB15 AA16 CPLD2: AB15 same as RREADY?

⚠ Critical Note: CPLD1 and CPLD3 share identical SPI pins (SCLK=AA16, CS=AB11, MOSI=AB12, MISO=AA14). This requires external multiplexing or the LPF is incorrect. The LPF file may need review.

DC Slot Decoding (per slot):

  • Bit 22: V(0)/I(1) select → RC_VSel / RC_ISel
  • Bit 21:17: Resistor selection → RC_RLSel (18-bit one-hot)
  • Bit 23: PMU(0)/DPS(1) — DPS path is STUBBED OUT (empty branch)

Output Signals:

Signal Width Description
o_OC_x01 4:0 OC relay selector (CPLD1: 4-bit, CPLD2: 4-bit)
o_OC_x17 4:0 OC relay selector (CPLD1: 4-bit, CPLD2: 4-bit)
o_RC_F[7:0] 8:0 RC_F relays (CPLD2 only)
o_RC_S[15:0] 16:0 RC_S relays (CPLD2 only)
o_RC_T[5:0] 6:0 RC_T relays (CPLD1: 6 bits T27-T32, CPLD2: 26 bits)
o_RC_T27-T32 6:0 RC_T relays (CPLD1 only, expanded from 5 bits)
o_RC_RLSel[17:0] 18:0 Resistor load select (CPLD1 only)
o_RC_VSel 1:0 Voltage select (CPLD1 only)
o_RC_ISel 1:0 Current select (CPLD1 only)
o_RC_LOF[1:0] 2:0 DMM_N port relay LOF (CPLD1 only)
o_RC_LOS[1:0] 2:0 DMM_N port relay LOS (CPLD1 only)
o_PMU_OC_[1-4][31:0] 32:0 PMU output channel (CPLD1 only)
o_PMU_RC[3:0] 4:0 PMU relay control (CPLD3 only)
o_DMM_EN[18:0] 19:0 DMM enable signals (CPLD1 only)
o_IO_RC1 1:0 IO relay control (CPLD1 only)
o_con_done 1:0 Execution done flag
o_err 1:0 Error flag

3. CPLD Differences

CPLD1 (Most Complete)

  • Role: Main relay control + PMU output + DMM enable
  • Outputs: Full set including PMU_OC, DMM_EN, RC_RLSel, RC_V/I Sel, RC_LOF/LOS, IO_RC1
  • RC_Tx: Expanded from 5 bits to 6 bits (T27-T32), source [17:12]
  • RC_LOF/LOS: 2-bit outputs for DMM_N port relays — o_RC_LOF = (RC_VSel==1)? 2'b01 : 2'b10
  • SPI Pins: SCLK=AA16, CS=AB11, MOSI=AB12, MISO=AA14 (per ARM_CPLD sheet)
  • Clock: B9, Reset: Y14
  • Note: LPF file has SCLK=AA10 (discrepancy with ARM_CPLD sheet which says AA16)

CPLD2 (Partial)

  • Role: RC_F/RC_S/RC_T relay control + OC channels
  • Outputs: RC_F[7:0], RC_S[15:0], RC_T[25:0], OC_[1-4][31:0]
  • Missing: No DC control, no DMM_EN, no RC_RLSel
  • SPI Pins: SCLK=AA10, CS=Y15, MOSI=AB12, MISO=AA14 (per ARM_CPLD sheet)
  • Note: i_wvaild typo (should be i_wvalid)
  • Note: No CPLD_Con DC handling — only Freq relay logic

CPLD3 (Minimal)

  • Role: PMU relay control only
  • Outputs: PMU_RC[3:0] only
  • SPI Pins: SCLK=AA16, CS=AB11, MOSI=AB12, MISO=AA14 (per ARM_CPLD sheet)
  • Note: No DC control, no Freq relay logic
  • Note: i_rvalid typo (should be i_rvalid — consistent with CPLD1)

4. System Interconnect (Vivado Block Design)

NewExtInst_TOP Architecture

Zynq PS (M_AXI_GP0)
    │
    ▼
ps7_0_axi_periph (1→3 split)
    ├── M00 → SPI_Con_0 → CPLD1
    ├── M01 → SPI_Con_1 → CPLD2
    └── M02 → SPI_Con_2 → CPLD3

Clock Tree

Zynq FCLK_CLK0 → clk_wiz_0 → clk_out1 (100MHz) → CPLD SPI_Con IP
                          ↓
                    rst_clk_wiz_0_100M → peripheral reset

SPI_Con IP (Custom AXI Peripheral)

  • 3 instances (one per CPLD)
  • AXI4-Lite slave interface
  • 7-bit address space (matches CPLD register count)
  • Maps AXI writes to CPLD SPI commands

5. Known Issues & Incomplete Features

Critical Incomplete Features

  1. DPS Path Not ImplementedCPLD_Con.v lines 266-268, 288-290, 310-312, 332-334: DPS selection branch is empty (all 4 DC slots). When i_DC_Con[N][23] == 1'b1, no output is driven.
  2. CPLD_Con Slot 4 BugCPLD_Con.v line 328: i_DC_Con1[23] should be i_DC_Con4[23] for slot 4 PMU/DPS selection
  3. CPLD2 Missing DC Control — No i_DC_Con inputs, no DC handling in CPLD_Con
  4. CPLD3 Minimal — Only PMU_RC output, no relay logic
  5. o_rvalid HardcodedBUS_Con.v line 211: assign o_rvalid = 1'b0; (but commented out in CPLD1 top module)
  6. IDENT Constant BugReg_file.v line 38: uses || (logical OR) instead of | (bitwise OR): 24'h200000 || 12'b0001_0000_0000 evaluates to 1'b1, not the intended bit pattern

Typos Found

File Typo Should Be
BUS_Con.v:92 o_cmd_vaild o_cmd_valid
CPLD1/RelayConTop.v:105 cmd_vaild cmd_valid
CPLD2/RelayConTop.v:11 i_wvaild i_wvalid
CPLD2/RelayConTop.v:56 i_rvaild i_rvalid
CPLD3/RelayConTop.v:25 cmd_vaild cmd_valid
LPF files o_rvaild o_rvalid

Design Concerns

  1. No timeout on execution FSM — If controller hangs, FSM can hang forever (line 139 in Reg_file.v: "Optional: Timeout counter here")
  2. No concurrent execution — Only one slot can execute at a time (en_t > 1 → error)
  3. Channel range validation incomplete — DC slot checks 1-18 for resistor but 1-256 for channel
  4. CPLD1/3 share same SPI pins — Need external multiplexing or different pin assignment (see ARM_CPLD sheet)
  5. LPF vs ARM_CPLD sheet discrepancy — CPLD1 SCLK: LPF=AA10, ARM_CPLD=AA16. LPF may be outdated.
  6. CPLD_Con channel range mismatch — Code uses < 9, < 72, < 137, < 201 but Excel Freq_CPLD shows complex groupings like "1-4&65-68||5-8&69-72"

6. File Inventory

Source Files (Verilog)

File Location Lines Purpose
RelayConTop.v CPLD1/ 194 Top module (CPLD1)
RelayConTop.v CPLD2/ 118 Top module (CPLD2)
RelayConTop.v CPLD3/ 98 Top module (CPLD3)
BUS_Con.v CPLD1/ 213 SPI interface (shared)
BUS_Con.v CPLD2/ Same as CPLD1
BUS_Con.v CPLD3/ Same as CPLD1
Reg_file.v CPLD1/ 179 Register file (shared)
Reg_file.v CPLD2/ Same as CPLD1
Reg_file.v CPLD3/ Same as CPLD1
CPLD_Con.v CPLD1/ 376 Control logic (CPLD1 only)
RelayConTop_tf.v CPLD1/ 93 Test fixture template

Constraints (LPF)

File Location Lines Purpose
NewExtIns_CPLD1.lpf CPLD1/ 283 Pin assignments (CPLD1)
NewExtIns_CPLD2.lpf CPLD2/ 322 Pin assignments (CPLD2)
NewExtIns_CPLD3.lpf CPLD3/ 29 Pin assignments (CPLD3)

Programming Files

File Size Date
Release/NewExtIns_CPLD1.jed 1.4 MB Jan 19
Release/NewExtIns_CPLD2.jed 1.4 MB Jan 19
Release/NewExtIns_CPLD3.jed 1.4 MB Jan 19

Vivado Block Design

File Location Purpose
NewExtInst_TOP.v NewExtInst_Debug/.../sim/ Top-level netlist
SPI_Con_v1_0.v .../ipshared/8878/hdl/ Custom SPI AXI IP
processing_system7_v5_5.v .../ipshared/8fd3/ Zynq PS IP

7. Register Protocol Summary

Write Sequence (ARM → CPLD)

  1. ARM writes to AXI address via M_AXI_GP0
  2. SPI_Con IP converts to SPI transaction
  3. BUS_Con receives 32-bit SPI frame
  4. Reg_file stores data in register table
  5. If bit 0 of STATE register set → triggers execution

Read Sequence (CPLD → ARM)

  1. ARM reads AXI address
  2. SPI_Con initiates SPI transaction
  3. BUS_Con shifts out 32-bit response: [8'h00][24-bit rdata]
  4. Note: o_rvalid is hardcoded to 0 — read acknowledgment not implemented

Execution Sequence

  1. ARM writes STATE register with bit 0 = 1
  2. Reg_file FSM → EXEC_ACK (waits for con_done LOW)
  3. CPLD_Con decodes register values, drives outputs
  4. CPLD_Con sets con_done HIGH when complete
  5. Reg_file FSM → EXEC_WAIT (waits for con_done HIGH)
  6. Auto-clears exec bit, returns to IDLE

8. Key Bit Fields Reference

IDENT Register (Addr 0)

 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
  CPLD3  CPLD2  CPLD1  Reserved  Major Version  Minor Version  Reversion
  • CPLD3, CPLD2, CPLD1: Board identity flags (CPLD1=1 means board has CPLD1)
  • Major Version: 2
  • Minor Version: 0
  • Reversion: 0

Freq_Slot Register (Addr 2-5)

 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
  Per Relay_Control (1=Switch, 0=Not Switch)  Reserved  Channel_Number  Slot_EN

DC_Slot Register (Addr 6-9)

 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
  DPS  V/I  Rload_Sel (0-31)  Reserved  Channel_Number  Slot_EN

STATE Register (Addr 1)

 23 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
  RDY  Reserved                              EXEC  Level1  Level2  Level3
  • Bit 23: RDY (ready flag)
  • Bits 22:20: Reserved
  • Bit 0: EXEC (1=start execution)
  • Bits 2:0: Level (Level1=MSB, Level2, Level3=LSB)

Document generated from source code analysis. Last updated: May 2026