Compare commits

..

No commits in common. "0b09e35575b98d61c061f47463f6ce8459023186" and "5ea3213682f521d57e920ca281b6425d44f99eef" have entirely different histories.

26 changed files with 379 additions and 834 deletions

View File

@ -36,8 +36,8 @@ jobs:
WEBDAV_PASS: ${{ secrets.WEBDAV_PASS }} WEBDAV_PASS: ${{ secrets.WEBDAV_PASS }}
run: | run: |
for f in output/*.html; do for f in output/*.html; do
echo "上传: $(basename "$f") → /manual/manual-readout-program.html" echo "上传: $(basename "$f")"
curl -sS --retries 3 -u "${WEBDAV_USER}:${WEBDAV_PASS}" \ curl -sS --retries 3 -u "${WEBDAV_USER}:${WEBDAV_PASS}" \
-T "$f" "${WEBDAV_URL}/manual/manual-readout-program.html" -T "$f" "${WEBDAV_URL}/$(basename "$f")"
done done
echo "部署完成" echo "部署完成"

View File

@ -85,7 +85,6 @@ python doc_builder/build.py
| §5.5 | `chapters/05-05-exc-upconversion.md` | EXC 上变频电路配置 | | §5.5 | `chapters/05-05-exc-upconversion.md` | EXC 上变频电路配置 |
| §5.6 | `chapters/05-06-pump-config.md` | Pump 模拟电路配置 | | §5.6 | `chapters/05-06-pump-config.md` | Pump 模拟电路配置 |
| §5.7 | `chapters/05-07-exc-pipeline-demo.md` | EXC-Pump 全流程控制示例 | | §5.7 | `chapters/05-07-exc-pipeline-demo.md` | EXC-Pump 全流程控制示例 |
| 附录A | `chapters/80-appendix-ids-table.md` | IDS 寄存器索引表DAQ_REG / AWG_REG / 地址映射) |
## 编辑工作流 ## 编辑工作流

View File

@ -3,7 +3,7 @@
<!-- CI/CD 状态徽章 — 请将下面的 URL 中的 gitea.example.com 和仓库路径替换为你的实际地址 --> <!-- CI/CD 状态徽章 — 请将下面的 URL 中的 gitea.example.com 和仓库路径替换为你的实际地址 -->
[![Build Status](http://114.214.202.87:9030/readout/readout_program/actions/workflows/deploy.yml/badge.svg)](http://114.214.202.87:9030/readout/readout_program/actions) [![Build Status](http://114.214.202.87:9030/readout/readout_program/actions/workflows/deploy.yml/badge.svg)](http://114.214.202.87:9030/readout/readout_program/actions)
> 📖 **在线文档**: [https://gc-home.top/manual/manual-readout-program.html](https://gc-home.top/manual/manual-readout-program.html) > 📖 **在线文档**: [https://gc-home.top/manual-doc-readout/](https://gc-home.top/manual-doc-readout/)
本项目为 ez-Q 2.5 读出子系统的编程控制模型文档。采用 **"文档即代码" (Docs as Code)** 工作方式, 本项目为 ez-Q 2.5 读出子系统的编程控制模型文档。采用 **"文档即代码" (Docs as Code)** 工作方式,
通过 Markdown 纯文本写作、Git 版本控制和 Python 构建管道生成自包含 HTML 报告。 通过 Markdown 纯文本写作、Git 版本控制和 Python 构建管道生成自包含 HTML 报告。

View File

@ -26,7 +26,7 @@ ez-Q 2.5测控系统包含5种物理通道对应5类硬件接口分别是A
- 测控系统的寄存器、配置数据和模拟电路配置返回数据统一采用**大端字节序**。 - 测控系统的寄存器、配置数据和模拟电路配置返回数据统一采用**大端字节序**。
通道寄存器配置数据支持微控制器实时修改,从而让通道的输入/输出控制具备动态控制能力。 通道寄存器配置数据支持微控制器实时修改,从而让通道的输入/输出控制具备动态控制能力。
ACQ和EXC-Pump通道配置寄存器的地址索引定义详见[附录A. IDS寄存器索引表](#a-ids)的 [A.2 DAQ_REG](#a2-daq_reg-acq) 和 [A.3 AWG_REG](#a3-awg_reg-exc-pump) 节 ACQ和EXC-Pump通道配置寄存器定义参考[读出子系统IDS表.xls](TODO)的`DAQ_REG`和`AWG_REG`页
本文档通过对不同编程模型下码字指令、通道寄存器配置数据、通道SRAM配置数据和通道模拟电路配置进行介绍 本文档通过对不同编程模型下码字指令、通道寄存器配置数据、通道SRAM配置数据和通道模拟电路配置进行介绍
旨在让用户掌握对读出激励信号的产生和采集信号处理的编程方法。 旨在让用户掌握对读出激励信号的产生和采集信号处理的编程方法。
@ -35,10 +35,10 @@ ACQ和EXC-Pump通道配置寄存器的地址索引定义详见[附录A. IDS寄
* ACQ通道和EXC-Pump通道使用**相同MCU** * ACQ通道和EXC-Pump通道使用**相同MCU**
* MCU分别使用**16 KB**的ITCM和DTCM * MCU分别使用**16 KB**的ITCM和DTCM
* FPGA平台MCU主时钟频率为**250 MHz** * FPGA平台MCU主时钟频率为**250 MHz**
* ASIC平台MCU主时钟频率为**750 MHz** * ASIC平台MCU主钟频率暂定**750 MHz**
* MCU以固定的**3个时钟周期每指令**的速度运行; * MCU以固定的**3个时钟周期每指令**的速度运行;
* MCU通过**0x100000**地址访问MCU数据空间 * MCU通过**0x100000**地址访问MCU数据空间
* MCU通**0x200000**地址访问通道配置寄存器空间; * MCU通**0x200000**地址访问通道配置寄存器空间;
针对具体的指令定义和使用方法, 针对具体的指令定义和使用方法,
读者可查看[《量子编程指令集》](TODO)了解相关信息。 读者可查看[《量子编程指令集》](TODO)了解相关信息。
@ -60,16 +60,16 @@ ez-Q 2.5 ASIC平台读出子系统由读出基带板、读出混频板和读出
当软件需要对不同通道编程时其通过ip地址指定机箱、通过槽位号指定板卡、 当软件需要对不同通道编程时其通过ip地址指定机箱、通过槽位号指定板卡、
通过扩展地址指定同一个板卡内的多个通道、通过地址指定一个通道内的不同配置项。 通过扩展地址指定同一个板卡内的多个通道、通过地址指定一个通道内的不同配置项。
索引基地址定义详见[附录A. IDS寄存器索引表](#a-ids)的 [A.1 地址空间映射](#a1) 节。 ```
索引基地址由《读出子系统IDS表.xls》的mapping页定义本文不对地址翻译进行赘述。
```
本文所述的三类编程通道具体定义如下: 本文所述的三类编程通道具体定义如下:
* ACQ 编程通道定义从混频板`rf_in`输入端口到基带板卡内部DAQ模块 * ACQ 编程通道定义从混频板`rf_in`输入端口到基带板卡内部DAQ模块
* EXC 编程通道定义为从基带板内部AWG模块混频板到`rf_out`接口; * EXC 编程通道定义为从基带板内部AWG模块混频板到`rf_out`接口;
* Pump 编程通道定义为从基带板卡内部AWG模块到泵浦板`pump_out`接口; * Pump 编程通道定义为从基带板卡内部AWG模块到泵浦板`pump_out`接口;
ASIC和FPGA平台具有以下区别 ASIC和FPGA平台具有以下区别
* ez-Q 2.5 FPGA平台读出子系统混频板和泵浦板复用同一个硬件板卡。 * ez-Q 2.5 FPGA平台读出子系统混频板和泵浦板复用同一个硬件板卡。
* ez-Q 2.5 FPGA平台将读出基带芯片RBPU和FPGA集成在一个FPGA中。 * ez-Q 2.5 FPGA平台将读出基带芯片RBPU和FPGA集成在一个FPGA中。
* ez-Q 2.5 FPGA平台使用外部商用ADC、DAC和PLL来替换RBPU的对应功能。 * ez-Q 2.5 FPGA平台使用外部商用ADC、DAC和PLL来替换RBPU的对应功能。

View File

@ -1,22 +1,18 @@
# 4. 处理器ACQ通道编程模型 # 4. 处理器ACQ通道编程模型
来自量子芯片RO端口的射频信号首先经过混频板调理后再进入读出基带处理单元采集处理。 来自量子芯片RO端口的射频信号首先经过混频板模拟电路调理后进入读出基带处理单元采集处理。
混频板负责将输入功率和频率的信号转换成基带板卡能够处理的频率功率合适的信号, 混频板模拟调理电路主要负责将输入功率和频率的信号转换成基带板卡能够处理的中频信号,
因此对混频板的编程主要包括`变频增益`和变频`本振频率`。 对模拟调理电路的编程包括变频增益控制和变频本振频率控制。
模拟信号进入基带处理单元后先经过巴伦将单端信号转换成ADC所需的差分信号。 模拟信号进入基带处理单元后先经过巴伦将单端信号转换成ADC所需的差分信号。
接着基带板上的读出芯片`RBPU`利用ADC(FPGA平台为8 bit@4 GspsASIC 平台为8 bit@6 Gsps采样, 接着读出芯片`RBPU`利用ADC(FPGA平台为8 bit@4 GspsASIC 平台为8 bit@6 Gsps采样输入信号并给到数字电路。
然后将量化后的数字信号送到数字电路进行处理。 数字电路对数据进行处理后将结果通过数据推送接口`rslt_push`发送到上位机。
数字电路对数据进行处理后将结果通过推送接口`rslt_push`发送到上位机。 对读出基带单元RO通道数字电路的编程包括MCU的指令、MCU的数据、ACQ通道控制寄存器、解模参数、模拟电路配置5类数据。
对读出数字电路的编程包括MCU的指令、MCU的数据、ACQ通道控制寄存器、解模参数结合模拟电路配置则ACQ通道编程项如下
- MCU指令+MCU数据可用于编程发出触发码字以及实时修改控制寄存器 - MCU指令+MCU数据可用于编程发出触发码字以及实时修改控制寄存器
- DAQ控制寄存器用于指定解模频率、相位、权重/系数数据的索引等参数; - ACQ通道控制寄存器用于指定解模频率、相位、权重/系数数据的索引等参数;
- 解模参数数据定义了具体的权重数据和量子态判断参数等数据。 - 解模参数数据定义了具体的权重数据和量子态判断参数等数据。
- 模拟电路配置用于设置变频增益和本振频率。 - 模拟电路配置用于设置变频增益和本振频率。
目前模拟电路采用固定变频增益仅支持设置本振频率。下图是ASIC平台ACQ通道数字部分编程控制模型。 目前FPGA平台模拟电路无需配置下图是FPGA平台ACQ通道数字部分编程控制模型。
![读出ACQ通道控制模型](../assets/readout_ro.png) ![读出ACQ通道控制模型](../assets/readout_ro.png)
@ -28,8 +24,8 @@
上述过程中,数据①②③④⑤都可以在数据转发模块缓存后通过`rslt_push`接口发送出去, 上述过程中,数据①②③④⑤都可以在数据转发模块缓存后通过`rslt_push`接口发送出去,
需要注意到的是数据②是解模求和数据③在求和次数为1的特殊情况。 需要注意到的是数据②是解模求和数据③在求和次数为1的特殊情况。
ACQ通道有且仅有基带处理单元存在状态机 由于ACQ通道有且仅有基带处理单元存在状态机
考虑到异常状态恢复需要ACQ通道提供了软复位功能。 因此需要考虑到异常状态恢复因此ACQ通道提供了软复位功能
当RO通道由于上位机强制中断或者MCU配置了错误指令而产生异常时 当RO通道由于上位机强制中断或者MCU配置了错误指令而产生异常时
可以通过调用驱动API函数执行复位操作 可以通过调用驱动API函数执行复位操作
其能够将状态机从异常中复位(同时也复位部分寄存器的默认值), 其能够将状态机从异常中复位(同时也复位部分寄存器的默认值),

View File

@ -6,9 +6,9 @@
|配置名|描述| |配置名|描述|
|:-:|:-:| |:-:|:-:|
|lo_freq|变频本振频率设置| |lo_freq|变频本振频率设置|
|dn_gain|下变频增益设置| |mix_gain|下变频增益设置|
* lo_freq32比特整数范围[5400000, 5600000]单位是kHz ```
目前ez-Q 2.5 FPGA平台暂不支持下变频增益
>目前ez-Q 2.5 FPGA平台暂不支持下变频增益dn_gain 设置; mix_gain 设置;仅支持 lo_freq 变频本振频率设置
仅支持 lo_freq 变频本振频率设置单板上下变频通道共享lo_freq设置 ```

View File

@ -1,11 +1,11 @@
## 4.2. ACQ码字功能定义 ## 4.2. ACQ码字功能定义
ACQ通道利用MCU产生32位的码字来控制读出行为32位的操控码字功能定义如下表所示。 ACQ通道通过产生32位的码字来控制读出行为32位的操控码字功能定义如下表所示。
|比特位|名字|功能描述| |比特位|名字|功能描述|
|:-|:-|:-| |:-|:-|:-|
|[31:16]|QUBIT_EN| 16个量子比特使能高电平使能对应位量子比特| |[31:16]|QUBIT_EN| 16个量子比特使能高电平使能对应位量子比特|
|[15]|COUNT_SAVE_EN| 态计数据存储使能, 高电平使能态计数存储| |[15]|COUNT_SAVE_EN| 态计数据存储使能, 高电平使能态计数存储|
|[14]|STATE_SAVE_EN| 态数据存储使能, 高电平使能态数据存储| |[14]|STATE_SAVE_EN| 态数据存储使能, 高电平使能态数据存储|
|[13]|IQ_SAVE_EN| 解模数据存储使能, 高电平使能解模数据存储| |[13]|IQ_SAVE_EN| 解模数据存储使能, 高电平使能解模数据存储|
|[12]|WAVE_SAVE_EN| 波形数据存储使能, 高电平使能波形数据存储| |[12]|WAVE_SAVE_EN| 波形数据存储使能, 高电平使能波形数据存储|
@ -32,7 +32,6 @@ ACQ通道利用MCU产生32位的码字来控制读出行为32位的操控码
- 码字比特[3:0]用于选择要实时从存储中加载的解模和态判断参数总共支持16组参数进行快速切换 - 码字比特[3:0]用于选择要实时从存储中加载的解模和态判断参数总共支持16组参数进行快速切换
**注意码字存在优先级和时序:** **注意码字存在优先级和时序:**
* 当同一个指令中同时对多个量子比特解模/读出时, * 当同一个指令中同时对多个量子比特解模/读出时,
* 解模时间等于最长那个比特的解模时间 * 解模时间等于最长那个比特的解模时间
* 读出时间等于最长那个比特的读出时间 * 读出时间等于最长那个比特的读出时间
@ -42,9 +41,9 @@ ACQ通道利用MCU产生32位的码字来控制读出行为32位的操控码
1. 态判断数据 1. 态判断数据
1. 态计数数据 1. 态计数数据
* 在一个指令中同时使能了解模求和清零、解模求和和求和存储时,顺序为: * 在一个指令中同时使能了解模求和清零、解模求和和求和存储时,顺序为:
1. 先执行IQ结果清零, 1. 先执行求和清零,
1. 再执行IQ结果求和 1. 再执行求和
1. 最后执行IQ结果存储 1. 最后执行求和结果存储
* 在一个指令中同时使能了态计数清零、态计数和计数存储时,顺序为: * 在一个指令中同时使能了态计数清零、态计数和计数存储时,顺序为:
1. 先执行态计数清零 1. 先执行态计数清零
1. 再执行态计数 1. 再执行态计数

View File

@ -2,9 +2,10 @@
ACQ通道寄存器的地址空间可以被SPI和MCU同时访问 ACQ通道寄存器的地址空间可以被SPI和MCU同时访问
因此用户可通过SPI或者MCU设置参数建议 因此用户可通过SPI或者MCU设置参数建议
```
>**建议:** 静态参数通过SPI配置完成就保持不变 静态参数通过SPI配置完成就保持不变
需要动态控制的参数通过MCU来实时更新。 需要动态控制的参数通过MCU来实时更新。
```
|名字|功能描述| |名字|功能描述|
|:-|:-| |:-|:-|
@ -19,7 +20,7 @@ ACQ通道寄存器的地址空间可以被SPI和MCU同时访问
- 低16比特对应索引长度单位是时钟周期 - 低16比特对应索引长度单位是时钟周期
- dds_fpw_q在使能寄存器控制情况下用于控制解模载波的频率和相位 - dds_fpw_q在使能寄存器控制情况下用于控制解模载波的频率和相位
- 高20位对应载波频率控制字fcw$F_{c}=fcw/2^{20}*sample\\_rate$ - 高20位对应载波频率控制字fcw$F_{c}=fcw/2^{20}*sample\\_rate$
- 低12位对应载波相位控制字pcw$\phi_{c} = pcw/2^{12}*2*\pi$ - 低12位对应载波相位控制字pcw$\\phi_{c} = pcw/2^{12}*2*\\pi$
- function用来控制整个读出基带板数据处理行为 - function用来控制整个读出基带板数据处理行为
function功能寄存器与实验控制相关的具体控制位包括 function功能寄存器与实验控制相关的具体控制位包括
@ -49,10 +50,10 @@ function功能寄存器与实验控制相关的具体控制位包括
- `TWO_STA_EN==0` 默认三态读出 - `TWO_STA_EN==0` 默认三态读出
- `TWO_STA_EN==1` 使能二态读出 - `TWO_STA_EN==1` 使能二态读出
```
> **注意:** ez-Q 2.5 FPGA平台采用系数直读模式因此不支持系数生产相关功能。 ez-Q 2.5 FPGA平台采用系数直读模式因此不支持系数生产相关功能。
即在ez-Q 2.5 FPGA平台下dds_fpw 寄存器无实际效果; 即在ez-Q 2.5 FPGA平台下dds_fpw 寄存器无实际效果;
function寄存器WEIGHT_IQCONST_EN, STEP_CTRL 位无实际效果 function寄存器WEIGHT_IQCONST_EN, STEP_CTRL 位无实际效果
```
解模完成后,可以通过`TWO_STA_EN`来控制是否启动2态判定 解模完成后,可以通过`TWO_STA_EN`来控制是否启动2态判定
当`TWO_STA_EN=1`时,可以只配置一组直线方程系数进行态判断。 当`TWO_STA_EN=1`时,可以只配置一组直线方程系数进行态判断。

View File

@ -1,60 +1,25 @@
## 4.4. 匹配滤波器 ## 4.4. 匹配滤波器
匹配滤波器在FPGA/ASIC两种平台下由于资源不同实现的形式也不同区别如下 匹配滤波器在FPGA/ASIC两种平台下由于资源不同实现的形式也不同区别如下
* 由于ASIC多计算少存储因而ASIC平台使用系数计算模式以节省存储资源。 * 由于ASIC多计算少存储因而ASIC平台使用系数计算模式以节省存储资源。
* 由于FPGA 多存储少计算因此FPGA平台使用系数直读模式以节省DSP资源。 * 由于FPGA 多存储少计算因此FPGA平台使用系数直读模式以节省DSP资源。
### 4.4.1. 读出参数存储 ### 4.4.1. 读出参数存储
DAQ_PAR 模块(基地址 `0x00500000`,总容量 32 KB存储解模所需的全部参数 系数计算模式下匹配滤波器的系数由DDS生成的载波乘以权重参数得到。
每个量子比特独占 2 KB 子空间(控制区 512 B + 权重区 1536 B - 载波的频率和相位由dds_pfd控制其高20为作为频率控制字低12位作为相位控制字。
- 权重参数的选择由mtf_idx控制其高16位作为地址低16位作为长度。
- mtf_idx索引得到的权重数据颗粒度是权重数据点一个数据点可对应多个周期采样点
- 寄存器dds_pfw_q 和mtf_idx_q 的详细定义与查找表中定义保持相同。
$$ \text{Qubit }N\text{ DAQ\_PAR 基地址} = \mathtt{0x00500000} + N \times \mathtt{0x800},\quad N = 0,1,\ldots,15 $$ 读出系统的的读出参数存储格式如下图所示。
FPGA平台下的系数直读模式只使用`Ctrl`部分中的数据,并忽略`dds_pfw`控制字.
**控制区**(每比特偏移 0x000 ~ 0x1FF共 512 字节) ![读出ACQ通道控制模型](../assets/readout_para.png)
控制区最多支持 16 组参数PARA_ID = 0~15每组占用 8 个 32 位寄存器32 字节),
各组基地址 = Qubit 基地址 + PARA_ID × `0x20`
每组包含以下 8 个寄存器:
|组内偏移|寄存器|位段|说明|
|:-|:-|:-|:-|
|`0x00`|dds_fpw|[31:12] fcw|解模载波频率控制字:$F_c = fcw / 2^{20} \times F_s$|
|^|^|[11:0] pcw|解模载波相位控制字:$\phi_c = pcw / 2^{12} \times 2\pi$|
|`0x04`|mtf_idx|[31:16] addr|权重数据起始地址(单位:时钟周期)|
|^|^|[15:0] len|权重数据样本长度(单位:时钟周期)|
|`0x08`|line0_ab|[31:16] a0|直线0 斜率系数 a16位有符号数|
|^|^|[15:0] b0|直线0 斜率系数 b16位有符号数|
|`0x0C`|line0_c|[31:0] c0|直线0 截距系数 c32位有符号数|
|`0x10`|line1_ab|[31:16] a1|直线1 斜率系数 a|
|^|^|[15:0] b1|直线1 斜率系数 b|
|`0x14`|line1_c|[31:0] c1|直线1 截距系数 c|
|`0x18`|line2_ab|[31:16] a2|直线2 斜率系数 a|
|^|^|[15:0] b2|直线2 斜率系数 b|
|`0x1C`|line2_c|[31:0] c2|直线2 截距系数 c|
> 三组直线方程用于三态判断,将 IQ 平面划分为三个区间。判定公式:$a \times I < c \times 2^4 - b \times Q$。三条直线的交点应重合于一点否则产生错误态3态)。详见 [§4.5.3](#453-采集态数据)
**权重区**(每比特偏移 0x200 起,共 1536 字节)
权重区存储匹配滤波器权重系数,最大 1536 个 8 位有符号系数I 路和 Q 路权重分开存储。
详细布局见下方存储格式图。
- 系数的粒度由 `func_ctrl.step_ctrl` 控制,一个权重样本点可对应 1/2/4/8/16 个时钟周期采样点;
- 权重数据由 `mtf_idx` 中的 addr 和 len 字段索引。
**读出参数存储格式**如下图所示。
![读出参数存储格式](../assets/readout_para.png)
> 系数计算模式ASIC匹配滤波器系数 = DDS 载波 × 权重参数。FPGA 平台使用系数直读模式,仅使用 `Ctrl` 部分mtf_idx索引 DAQ_FLT`0x00580000`)中预存储的匹配滤波器系数,忽略 dds_fpw 控制字。
### 4.4.2. 匹配滤波器系数 ### 4.4.2. 匹配滤波器系数
ez-Q 2.5 FPGA平台使用系数直读模式其需要额外的存储空间来配置匹配滤波器系数。 ez-Q 2.5 FPGA平台使用系数直读模式其需要额外的存储空间来配置匹配滤波器系数。
- 其中mtf_idx的含义从索引权重数据变为索引匹配滤波器系数。 - 其中mtf_idx的含义从索引权重数据变为索引匹配滤波器系数。
- 匹配滤波器系数索引的粒度是时钟周期, - 匹配滤波器系数索引的粒度是时钟周期,
- 在FPGA平台下每个时钟周期对应16个采样点数据。 - 在FPGA平台下每个时钟周期对应16个采样点数据。
@ -64,4 +29,4 @@ ez-Q 2.5 FPGA平台使用系数直读模式其需要额外的存储空间来
- 匹配滤波器的I和Q数据分开存储每个比特的I、Q数据容量分别为16 KB。 - 匹配滤波器的I和Q数据分开存储每个比特的I、Q数据容量分别为16 KB。
- I路数据偏移地址为x*32KBQ路数据偏移地址为x*32KB+16 KB其中x为Qubit序号范围为0~15。 - I路数据偏移地址为x*32KBQ路数据偏移地址为x*32KB+16 KB其中x为Qubit序号范围为0~15。
![匹配滤波器系数存储结构](../assets/readout_mtf.png) ![读出ACQ通道控制模型](../assets/readout_mtf.png)

View File

@ -19,25 +19,22 @@ ACQ通道采集的数据以流的形式按照先后顺序缓存
### 4.5.2. 采集IQ数据 ### 4.5.2. 采集IQ数据
解模计算公式如下: 解模计算公式如下:
$$ $$
I = \sum_{i=1}^{m}{\sum_{j=1}^n{\frac{S_{i,j} * iw_{i,j} * \cos(\omega_i t+\phi_i)}{scale_i} }} I = \\sum_{i=1}^{m}{\\sum_{j=1}^n{\\frac{S_{i,j} * iw_{i,j} * \\cos(\\omega_i t+\\phi_i)}{scale_i} }}
$$ $$
$$ $$
Q = \sum_{i=1}^{m}{\sum_{j=1}^n{\frac{S_{i,j} * qw_{i,j} * \sin(\omega_i t+\phi_i)}{scale_i} }} Q = \\sum_{i=1}^{m}{\\sum_{j=1}^n{\\frac{S_{i,j} * qw_{i,j} * \\sin(\\omega_i t+\\phi_i)}{scale_i} }}
$$ $$
* $m$表示解模次数,$n$表示解模的采样点个数; * $m$表示解模次数,$n$表示解模的采样点个数;
* $S_{i,j}$为输入波形的第i次解模第j个采样点8比特有符号数 * $S_{i,j}$为输入波形的第i次解模第j个采样点8比特有符号数
* $iw_{i,j}$、$qw_{i,j}$为i、q权重的第i次解模第j个采样点8比特有符号数 * $iw_{i,j}$、$qw_{i,j}$为i、q权重的第i次解模第j个采样点8比特有符号数
* $\omega_i$、$\phi_i$分别为第i次解模的频率和相位 * $\\omega_i$、$\\phi_i$分别为第i次解模的频率和相位
* $scale_i$为第i次解模的范围选择可设置为1或者16 * $scale_i$为第i次解模的范围选择可设置为1或者16
>解模频率应设置为输入波形对应频率使得解模结果频率为0 解模频率应设置为输入波形对应频率一遍使得解模结果频率为0
解模结果相位等于解模设置相位设置减去输入波形相位。 解模结果相位等于解模设置相位设置减去输入波形相位。
若解模相位为0则结果相位等于波形相位取反。 若解模相位为0则结果相位等于波形相位取反。
解模求和结果I、Q分别用32比特二进制补码表示解模的结果存储格式如下 解模求和结果I、Q分别用32比特二进制补码表示解模的结果存储格式如下
* 1个完整的数据包含I,Q8字节 * 1个完整的数据包含I,Q8字节
@ -46,40 +43,9 @@ $$
### 4.5.3. 采集态数据 ### 4.5.3. 采集态数据
#### 态判断计算
态判断利用解模IQ数据通过三组直线方程将 IQ 平面划分为三个区域,判定量子比特状态。
三组直线方程定义在 DAQ_PAR 参数区(见 [§4.4.1](#441-读出参数存储)
每组包含三个系数a, b, c直线方程为 $ax + by = c$
其中 a、b 为 16 位有符号数c 为 32 位有符号数I、Q 为 20 位截位后的解模结果。
对于每条直线,位置判定公式为:
$$
compare[i] = (a_i \times I < c_i \times 2^4 - b_i \times Q),\quad i = 0, 1, 2
$$
得到三条直线的位置判定结果后,通过优先级电路确定态信息:
|优先级|态值|判定条件|
|:-|:-|:-|
|1|0|compare[0] = 1 且 compare[1] = 0|
|2|1|compare[1] = 1 且 compare[2] = 0|
|3|2|compare[2] = 1 且 compare[0] = 0|
|—|3错误态|其它情况|
```
三态判断要求三条直线交于同一点,否则 IQ 平面被划分为 4 个以上区域,
部分 IQ 点将落入未定义区域产生错误态3态
仅需两态判断时,设置 func_ctrl.TWO_STA_EN = 1仅使用一组直线方程。
```
#### 态数据存储格式
* 1个完整数据包含16个qubit态信息4字节 * 1个完整数据包含16个qubit态信息4字节
* 每个量子比特态信息用2个比特表示 * 每个量子比特态信息用2个比特表示
* 高位表示高序号即32比特对应 {q15, q14, ..., q0} * 高位表示高序号即32比特对应{q15,q14,...,q0};
### 4.5.4. 采态计数数据 ### 4.5.4. 采态计数数据

View File

@ -1,154 +1,109 @@
## 4.6. ACQ通道全流程控制示例 ## 4.6. ACQ通道全流程控制示例
本节通过一个完整的端到端示例说明ACQ通道的编程配置流程 本节通过一个完整的示例演示ACQ通道从码字生成到采集数据获取的全流程编程控制
示例基于 **ASIC 平台**ADC 8 bit@6 Gsps场景为对2个量子比特q0, q1执行单次读出采集解模IQ数据。 示例场景:对2个量子比特q0, q1执行单次读出采集解模IQ数据。
### 4.6.1. 端到端配置流程 ### 4.6.1. 流程总览
ACQ通道的工作流程如下 ACQ通道读出全流程包含以下步骤
|阶段|操作|说明| 1. **配置模拟前端** — 设置下变频本振频率
2. **加载解模参数** — 配置匹配滤波器权重和DDS参数查找表
3. **配置ACQ寄存器** — 设置解模频率/相位/缩放等控制参数
4. **生成并发送码字** — MCU发出采集触发码字
5. **接收处理数据** — 固件打包上传上位机解帧获取IQ数据
![ACQ全流程控制](../assets/readout_ro.png)
### 4.6.2. 步骤1配置模拟前端
配置混频板下变频本振频率,将射频信号转换到中频:
|配置项|值|说明|
|:-|:-|:-| |:-|:-|:-|
|初始化|配置模拟前端、解模参数、ACQ寄存器|通过SPI写入步骤1~3无先后顺序要求| |lo_freq|5_500_000|本振频率 5.5 GHz单位 kHz|
|初始化|加载MCU程序|写入MCU_INS定义触发后要发出的码字|
|运行|外部触发 → MCU执行 → 产生码字|触发由其它硬件发出MCU响应后执行程序并生成32位码字|
|运行|码字解码 → 采集 → 解模 → 推送数据|硬件自动流水线执行|
|运行|上位机接收数据|从 `rslt_push` 接口读取并解帧|
``` ```
关键理解: 本振频率需根据目标量子比特频率确定。
触发信号来自外部硬件非MCUMCU是被动响应方。 例如量子比特频率为 6.7 GHz则下变频后中频为 1.2 GHz。
MCU 程序加载到 MCU_INS 后处于待命状态,收到触发后执行并生成码字。
初始化配置可在任意时刻通过 SPI 完成,只需在触发前生效即可。
``` ```
### 4.6.2. 地址空间速查 ### 4.6.3. 步骤2加载解模参数
以下配置基于ACQ通道0Exaddr=0各模块基地址如下完整地址映射见 [附录A.1.1](#a11-acq) 将解模参数匹配滤波器权重、DDS频率/相位控制字)写入参数查找表。
本例配置2组参数对应2个量子比特
|模块|基地址|用途| **权重数据(匹配滤波器系数)**
|参数索引|目标比特|权重长度|iw示例 |qw示例 |
|:-|:-|:-|:-|:-|
|0|q0|128 采样点|`cos(ω·t)` 包络采样|`sin(ω·t)` 包络采样|
|1|q1|128 采样点|`cos(ω·t)` 包络采样|`sin(ω·t)` 包络采样|
**DDS参数频率/相位控制字)**
|参数索引|fcw (频率控制字)|pcw (相位控制字)|scale|
|:-|:-|:-|:-|
|0|`fcw_q0` = $F_{if} / F_s \times 2^{32}$|0|1|
|1|`fcw_q1` = $F_{if} / F_s \times 2^{32}$|0|1|
```
参数查找表共支持16组参数PARA_ID = 0~15
每组包含独立的权重系数和DDS参数。
MCU可通过修改PARA_ID在运行时快速切换目标比特。
```
### 4.6.4. 步骤3配置ACQ寄存器
配置解模相关寄存器通过SPI或MCU写入
|寄存器|值|说明|
|:-|:-|:-| |:-|:-|:-|
|MCU_INS|`0x00200000`|MCU指令存储| |`demod_len`|128|解模采样点数,与权重长度一致|
|MCU_DAT|`0x00300000`|MCU数据存储| |`result_scale`|1|解模结果缩放因子1 或 16|
|DAQ_REG|`0x00400000`|DAQ控制寄存器| |`dds_fcw`|`fcw_q0`|初始DDS频率控制字可通过查找表覆盖|
|DAQ_PAR|`0x00500000` + N×`0x800`|解模参数查找表(每比特 2 KBN = qubit 序号)| |`dds_pcw`|0|初始DDS相位控制字可通过查找表覆盖|
|MIXER_REG|`0x00100000`|混频板本振配置|
> FPGA 平台额外使用 DAQ_FLT`0x00580000`存储匹配滤波器系数系数直读模式。ASIC 平台使用系数计算模式,无需此项。
### 4.6.3. 步骤1配置模拟前端
通过SPI写混频板本振频率寄存器
|地址|寄存器|字段|值|说明|
|:-|:-|:-|:-|:-|
|`0x00100000`|lo_freq|fcw [31:0]|`5_500_000`|本振 5.5 GHz单位 kHz|
本振频率根据目标量子比特频率确定:中频 = 量子比特频率 本振频率。同一混频板4个通道共享本振。
### 4.6.4. 步骤2加载解模参数
DAQ_PAR 每比特独占 2 KB 子空间q0 基地址 = `0x00500000`q1 基地址 = `0x00500800`),详见 [§4.4.1](#441-读出参数存储)。
**控制区配置**(每组 8 × 32 bit = 32 字节PARA_ID 对应基地址 = Qubit 基地址 + PARA_ID × `0x20`
配置 q0 和 q1 各一组参数(均使用 PARA_ID=0
|地址|寄存器|字段|值|说明|
|:-|:-|:-|:-|:-|
|`0x00500000`|dds_fpw|fcw [31:12]|$\lfloor F_{if} / F_s \times 2^{20} \rfloor$|q0 解模频率控制字|
|^|^|pcw [11:0]|`0`|q0 解模相位控制字|
|`0x00500004`|mtf_idx|addr [31:16]|`0`|q0 权重起始地址(单位:时钟周期)|
|^|^|len [15:0]|`16`|q0 权重长度 16 时钟周期(= 128 采样点 / 8|
|`0x00500008`|line0_ab|a0 [31:16]|校准值|q0 态判断直线0 系数 a|
|^|^|b0 [15:0]|校准值|q0 态判断直线0 系数 b|
|`0x0050000C`|line0_c|c0 [31:0]|校准值|q0 态判断直线0 系数 c|
|`0x00500010`|line1_ab|a1 / b1|校准值|q0 态判断直线1 系数|
|`0x00500014`|line1_c|c1 [31:0]|校准值|q0 态判断直线1 系数|
|`0x00500018`|line2_ab|a2 / b2|校准值|q0 态判断直线2 系数|
|`0x0050001C`|line2_c|c2 [31:0]|校准值|q0 态判断直线2 系数|
|`0x00500800`|dds_fpw|fcw [31:12]|$\lfloor F_{if} / F_s \times 2^{20} \rfloor$|q1 解模频率控制字|
|`0x00500804`|mtf_idx|addr [31:16]|`0`|q1 权重起始地址(单位:时钟周期)|
|^|^|len [15:0]|`16`|q1 权重长度 16 时钟周期|
|`0x00500808`|line0_ab|a0 / b0|校准值|q1 态判断直线0 系数|
|`0x0050080C`|line0_c|c0 [31:0]|校准值|q1 态判断直线0 系数 c|
|`0x00500810`|line1_ab|a1 / b1|校准值|q1 态判断直线1 系数|
|`0x00500814`|line1_c|c1 [31:0]|校准值|q1 态判断直线1 系数 c|
|`0x00500818`|line2_ab|a2 / b2|校准值|q1 态判断直线2 系数|
|`0x0050081C`|line2_c|c2 [31:0]|校准值|q1 态判断直线2 系数 c|
``` ```
三组直线方程系数a,b,c需通过量子比特校准实验确定此处以"校准值"代替。 当码字中 DDS_FPW_SEL = 0查找表模式
若实验不需要态判断(如仅采集 IQ 数据),直线方程系数可填 0。 实际解模参数由 PARA_ID 索引的查找表决定,
寄存器中的初始值作为 fallback。
``` ```
**权重区配置**(偏移 `0x200` 起,布局见 [§4.4.1](#441-读出参数存储) 存储格式图): ### 4.6.5. 步骤4生成并发送码字
本例 q0 使用 16 个时钟周期的权重数据(写入 q0 权重区 `0x00500200` 起), MCU生成32位ACQ码字触发一次完整的读出采集
q1 同样 16 个时钟周期(写入 q1 权重区 `0x00500A00` 起)。
权重系数为 8 位有符号数I 路和 Q 路分开存储,具体偏移以 `readout_para.png` 图示为准。
``` |码字位段|字段名|配置值|说明|
ASIC 平台下匹配滤波器系数 = DDS 载波 × 权重参数(系数计算模式),
权重数据只需存储缓变包络,一个权重点可对应多个时钟周期采样点(由 `step_ctrl` 控制)。
MCU 可通过切换 PARA_ID 在运行时快速切换目标比特。
mtf_idx 的 addr 和 len 单位为时钟周期ASIC 平台每周期 8 采样点)。
本例 len=16 时钟周期 = 128 采样点。
```
### 4.6.5. 步骤3配置ACQ寄存器
通过SPI写DAQ控制寄存器
|地址|寄存器|字段|值|说明|
|:-|:-|:-|:-|:-|
|`0x00400044`|func_ctrl|iq_scale [3]|`0`|IQ 结果截位 [27:8]|
|^|^|two_sta_en [2]|`0`|三态读出模式|
|^|^|const_en [7]|`0`|使用查找表权重(非常数权重)|
|`0x00400080`|mtf_idx_q0|addr [31:16] / len [15:0]|fallback 值|q0 匹配滤波器索引(查找表模式的 fallback|
|`0x004000C0`|dds_fpw_q0|fcw [31:12] / pcw [11:0]|fallback 值|q0 DDS参数查找表模式的 fallback|
```
func_ctrl 寄存器中与 ASIC 系数计算模式相关的位const_en、step_ctrl、weight_iq
必须按上表配置,否则可能导致解模结果错误。
```
### 4.6.6. 步骤4MCU程序与触发
MCU程序加载到 MCU_INS`0x00200000`触发后MCU执行程序并生成32位码字。
**触发信号由外部硬件发出**MCU响应后自动执行。
码字示例(使能 q0、q1 解模仅存储IQ数据
|位段|字段名|值|说明|
|:-|:-|:-|:-| |:-|:-|:-|:-|
|[31:16]|QUBIT_EN|`0x0003`|使能 q0, q1bit0=1, bit1=1| |[31:16]|QUBIT_EN|`0x0003`|使能 q0, q1bit0=1, bit1=1|
|[15]|COUNT_SAVE_EN|`0`|不存储态计数| |[15]|COUNT_SAVE_EN|0|不存储态计数|
|[14]|STATE_SAVE_EN|`0`|不存储态数据| |[14]|STATE_SAVE_EN|0|不存储态数据|
|[13]|IQ_SAVE_EN|`1`|存储解模IQ数据| |[13]|IQ_SAVE_EN|1|存储解模IQ数据|
|[12]|WAVE_SAVE_EN|`0`|不存储原始波形| |[12]|WAVE_SAVE_EN|0|不存储原始波形|
|[11]|MTF_IDX_SEL|`0`|匹配滤波器参数来自查找表| |[11]|MTF_IDX_SEL|0|匹配滤波器参数来自查找表|
|[10]|DDS_FPW_SEL|`0`|DDS参数来自查找表| |[10]|DDS_FPW_SEL|0|DDS参数来自查找表|
|[9]|STATE_CLR_VAL|`0`|不清零态计数| |[9]|STATE_CLR_VAL|0|不清理态计数|
|[8]|DEMOD_CLR_VAL|`0`|不清零解模求和| |[8]|DEMOD_CLR_VAL|0|不清理解模求和|
|[7:4]|FB/STATE/SUM|`0`|不触发反馈/态统计/求和| |[7:4]|FB/STATE/SUM|0|不触发反馈/态统计/求和|
|[3:0]|PARA_ID|`0`|参数组索引(各比特独立查找| |[3:0]|PARA_ID|0|使用参数组0q0参数|
完整码字值:**`0x0003_2000`** 完整码字值:`0x0003_2000`
``` ```
一个码字可同时使能多个比特(通过 QUBIT_EN 位段), 上述码字使能了 q0 和 q1 同时解模并仅存储 IQ 数据。
各比特使用各自的 DAQ_PAR 子空间(基地址 = 0x00500000 + N×0x800 若需对不同比特使用不同参数,需发送多个码字并切换 PARA_ID。
因此 q0 和 q1 可共用 PARA_ID=0 且互不干扰。 例如:
码字1: PARA_ID=0, QUBIT_EN=q0 → 使用参数组0读出q0
若同一比特需要使用不同的解模参数(如不同频率/权重), 码字2: PARA_ID=1, QUBIT_EN=q1 → 使用参数组1读出q1
可在不同触发中切换 PARA_ID 来实现。
``` ```
### 4.6.7. 步骤5数据接收 ### 4.6.6. 步骤5接收处理数据
采集完成后硬件通过 `rslt_push` 推送上位机。IQ数据帧格式2比特 × 8字节 ACQ通道完成采集后将数据打包成帧通过`rslt_push`接口推送上位机。
上位机驱动解帧后按流模式返回:
**IQ数据帧格式**
|字节偏移|字段|长度|格式| |字节偏移|字段|长度|格式|
|:-|:-|:-|:-| |:-|:-|:-|:-|
@ -158,19 +113,22 @@ MCU程序加载到 MCU_INS`0x00200000`触发后MCU执行程序并生成
|12|Q (q1)|4 字节|32位有符号整数大端| |12|Q (q1)|4 字节|32位有符号整数大端|
``` ```
若码字同时使能多种数据存储,帧内顺序为 若码字同时使能多种数据存储,帧内数据按以下顺序排列
波形数据 → 解模IQ数据 → 态判断数据 → 态计数数据 波形数据 → 解模IQ数据 → 态判断数据 → 态计数数据
推荐每次仅使能一种数据类型以简化解析。 推荐每次仅使能一种数据类型以简化上位机解析。
``` ```
### 4.6.8. 配置清单汇总 ### 4.6.7. 时序总结
|地址|寄存器/区域|关键值| 单次ACQ读出的完整时序
|:-|:-|:-|
|`0x00100000`|lo_freq|`5_500_000`| 1. **T0**: MCU 发出32位码字 `0x0003_2000`
|`0x00500000` ~ `0x0050001F`|DAQ_PAR q0 控制区PARA_ID=0|dds_fpw, mtf_idx, 3×line_coeff| 2. **T0 + 1 cycle**: 码字解码,使能 q0, q1 的解模通路
|`0x00500800` ~ `0x0050081F`|DAQ_PAR q1 控制区PARA_ID=0|同上结构| 3. **T0 + 2~129 cycles**: ADC采集128个采样点并行送入匹配滤波器
|`0x00500200` 起|DAQ_PAR q0 权重区|q0 的 I/Q 权重(见存储格式图)| 4. **T0 + 130 cycle**: 解模完成IQ数据写入结果缓存
|`0x00500A00` 起|DAQ_PAR q1 权重区|q1 的 I/Q 权重(见存储格式图)| 5. **T0 + 131 cycle**: 数据打包,通过 `rslt_push` 推送上位机
|`0x00400044`|func_ctrl|`0x0000`(见 [§4.6.5](#465-步骤3配置acq寄存器)|
|`0x00200000`|MCU_INS|MCU程序 → 码字 `0x0003_2000`| ```
实际解模时间取决于使能比特中最长的解模长度。
若 q0 解模128点、q1 解模256点则解模耗时 = 256 cycles。
```

View File

@ -1,18 +1,14 @@
# 5. 处理器EXC-Pump编程模型 # 5. 处理器EXC-Pump编程模型
EXC-Pump通道的编程包括 EXC-Pump通道的编程包括
MCU的指令、MCU的数据、控制寄存器、波形索引表、波形仓库、混频板与泵浦板配置7类数据。 MCU的指令、MCU的数据、控制寄存器、波形索性表、波形仓库和模拟电路配置6类数据。
- MCU指令+MCU数据可用于编程发出触发码字以及实时修改控制寄存器 - MCU指令+MCU数据可用于编程发出触发码字以及实时修改控制寄存器
- 控制寄存器可用于指定调制频率、调制相位、工作模式等参数; - 控制寄存器可用于指定调制频率、调制相位、工作模式等参数;
- 波形索引表定义了从波形ID到波形地址和长度的映射 - 波形索引表定义了从波形ID到波形地址和长度的映射波形仓库定义了波形具体的采样点数据。
- 波形仓库定义了波形具体的采样点数据; - 模拟电路配置用于设置变频增益和本振频率以及Pump通道的频率和功率等。
- 混频板配置用于设置变频增益和本振频率;
- 泵浦板配置用于配置Pump通道的频率和功率等
> 混频板上变频不支持增益设置,只能设置本振频率,并且上下变频通道共享同一个本振设置,这里不额外赘述了 当前模拟电路仅需配置Pump参数下图是EXC-Pump通道数字部分的编程控制模型。
数字部分MCU的指令、MCU的数据、控制寄存器、波形索性表、波形仓库的编程模型如下图所示
![读出RI-Pump通道控制模型](../assets/readout_ri.png) ![读出RI-Pump通道控制模型](../assets/readout_ri.png)
1. EXC-Pump通道的波形输出由AWG模块MCU发出的码字触发。 1. EXC-Pump通道的波形输出由AWG模块MCU发出的码字触发。
@ -25,7 +21,6 @@ MCU的指令、MCU的数据、控制寄存器、波形索引表、波形仓库
1. 最后数字信号经过DAC转换后输出基带信号基带信号经过上变频输出读出系统 1. 最后数字信号经过DAC转换后输出基带信号基带信号经过上变频输出读出系统
上述过程中模式选择器可以选择原始波形数据、希尔伯特虚部数据、正交调制数据以及NCO自身产生的单音数据。 上述过程中模式选择器可以选择原始波形数据、希尔伯特虚部数据、正交调制数据以及NCO自身产生的单音数据。
- 原始波形模式:用于量子实验,通过直接输出包含多个读出频率的波形,可以实现对多个量子比特的并行读出; - 原始波形模式:用于量子实验,通过直接输出包含多个读出频率的波形,可以实现对多个量子比特的并行读出;
- 正交调制模式用于腔频扫描等应用通过实时修改NCO频率可以实时改变输出频率配合DAQ进行实时读取可以实现扫频功能。若基带信号包含多个频点还能实现多频点并行扫描功能 - 正交调制模式用于腔频扫描等应用通过实时修改NCO频率可以实时改变输出频率配合DAQ进行实时读取可以实现扫频功能。若基带信号包含多个频点还能实现多频点并行扫描功能
- NCO Only模式可以输出连续波形方便连接外部仪器上进行测试用于芯片本身性能的测试。 - NCO Only模式可以输出连续波形方便连接外部仪器上进行测试用于芯片本身性能的测试。
@ -48,10 +43,12 @@ MCU的指令、MCU的数据、控制寄存器、波形索引表、波形仓库
Pump通道输出的使能信号由MCU码字触发输出 Pump通道输出的使能信号由MCU码字触发输出
当MCU输出码字的对应位使能后脉冲发生模块从寄存器或波形索引表得到脉冲长度控制数据 当MCU输出码字的对应位使能后脉冲发生模块从寄存器或波形索引表得到脉冲长度控制数据
并将指定长度的脉冲信号通过I/O直接输出。 并将指定长度的脉冲信号通过I/O直接输出。
```
ez-Q 2.5 FPGA平台的Pump通道需要提前配置频率、功率和输出使能
```
> ez-Q 2.5 FPGA/ASIC平台的Pump通道需要提前配置频率、功率和输出使能 由于EXC-Pump通道有且仅有基带处理单元存在状态机
当EXC-Pump通道由于上位机强制中断程序或者MCU配置了错误指令而产生异常时
由于EXC-Pump通道有且仅有数字部分存在状态机 为了清除EXC-Pump通道的异常状态
为了清除EXC-Pump通道由于上位机强制中断程序或者MCU配置了错误指令而产生异常
EXC-Pump通道提供了软复位功能支持通过调用驱动API来执行软复位操作 EXC-Pump通道提供了软复位功能支持通过调用驱动API来执行软复位操作
软复位可使得状态机从异常中恢复,从而使得下一次历史无关配置项能够正确执行。 其能够使得状态机从异常中恢复,从而使得下一次历史无关配置项能够正确执行。

View File

@ -10,7 +10,7 @@ AWG模块仅使用码字指令的低13位其余位保留
|[10]|NCO_CLR_EN| NCO清零使能, 高有效| |[10]|NCO_CLR_EN| NCO清零使能, 高有效|
|[9]|MARK_EN| 标记脉冲输出使能, 高有效| |[9]|MARK_EN| 标记脉冲输出使能, 高有效|
|[8]|PUMP_EN| 泵浦脉冲输出使能, 高有效| |[8]|PUMP_EN| 泵浦脉冲输出使能, 高有效|
|[7:0]|WAVE_ID| 波形编号, 最大索256个波形输出| |[7:0]|WAVE_ID| 波形编号, 最大索256个波形输出|
- 码字比特[12]用于禁用波形输出通过使能该比特可以仅输出Pump或者Marker脉冲而不输出该指令码字[7:0]索引的波形。 - 码字比特[12]用于禁用波形输出通过使能该比特可以仅输出Pump或者Marker脉冲而不输出该指令码字[7:0]索引的波形。
- 码字比特[11]用于使能动态波形输出功能该功能直接使用wave_ctrl寄存器中来索引波形暂不使用该功能 - 码字比特[11]用于使能动态波形输出功能该功能直接使用wave_ctrl寄存器中来索引波形暂不使用该功能

View File

@ -15,14 +15,14 @@ EXC-Pump通道的全部寄存器可以被SPI和MCU同时访问
- `wave_ctrl`波形输出直接控制,可直接从波形仓库取采样点输出。 - `wave_ctrl`波形输出直接控制,可直接从波形仓库取采样点输出。
- 高16位为索引地址单位是时钟周期 - 高16位为索引地址单位是时钟周期
- 低16位为索引长度,单位是时钟周期 - 低16为为索引长度,单位是时钟周期
- `amplitude`调制幅度控制字 - `amplitude`调制幅度控制字
- 高16位为幅度控制字acw范围-32768~32767归一化幅度$Amp = acw/2^{14}$ - 高16为幅度控制字acw范围0~16384归一化幅度$Amp = acw/2^{16}$
- `frequency`调制频率控制 - `frequency`调制频率控制
- 32比特频率控制字fcw$F_{nco}= fcw/2^{32}*F_s$,其中$F_s$是输出采样率。 - 32比特频率控制字fcw$F_{nco}= fcw/2^{32}*F_s$,其中$F_s$是输出采样率。
- `phase`调制相位控制 - `phase`调制相位控制
- 高16位相位控制字pcw $\phi_{nco} = pcw/2^{16}*2*\pi$。 - 高16位相位控制字pcw $\\phi_{nco} = pcw/2^{16}*2*\\pi$。
- `function`寄存器用于设置AWG的工作模式 - `funciton`寄存器用于设置AWG的工作模式
- `pump_ctrl`泵浦脉冲使能控制 - `pump_ctrl`泵浦脉冲使能控制
- 高16位控制输出延迟时钟周期范围1~65535 - 高16位控制输出延迟时钟周期范围1~65535
- 低16位控制附加持续时钟周期范围1~65535 - 低16位控制附加持续时钟周期范围1~65535

View File

@ -2,8 +2,8 @@
* ASIC平台下每个时钟周期对应8个采样点采样点个数需要为8的整数倍数据更新率为6 Gsps每个采样点持续时间为167 皮秒(6 GS/s)。 * ASIC平台下每个时钟周期对应8个采样点采样点个数需要为8的整数倍数据更新率为6 Gsps每个采样点持续时间为167 皮秒(6 GS/s)。
* 在FPGA平台下每个时钟周期对应16个采样点采样点个数需要为16的整数倍数据更新率为 4 GSps每个采样点持续时间为250皮秒。 * 在FPGA平台下每个时钟周期对应16个采样点采样点个数需要为16的整数倍数据更新率为 4 GSps每个采样点持续时间为250皮秒。
* 每个采样点通过16比特的二进制补码数据表示 * 每个采样点为16比特的二进制补码数据
* 波形仓库的容量为128 KB在FPGA平台和ASIC平台下最大分别支持16 us和10 us波形输出。 * 波形仓库的容量为128 KB在FPGA平台和ASIC平台下最大分别支持16 us和10 us波形输出。
对于EXC输出频率$F_{out}$例如6.7 GHz在本振为$F_{LO}$(例如5.5GHz)本振频率下, 对于EXC输出频率$F_{out}$例如6.7 GHz在本振为$F_{LO}$(例如5.5GHz)本振频率下,
则存储区描绘的基带波形频率$F_{IF}$为1.2 GHz $F_{IF} = F_{out} - F_{LO}$。 则存储区描绘的基带波形频率$F_{s}$为1.2 GHz $F_s = F_{out} - F_{LO}$。

View File

@ -2,10 +2,10 @@
来自读出基带板输出端口的中频信号需要经过混频板上变频电路处理后才能够被发送到量子芯片。 来自读出基带板输出端口的中频信号需要经过混频板上变频电路处理后才能够被发送到量子芯片。
前端上变频电路包括增益和本振,这里需要注意同一个混频板上四个通道上下变频使用同一个本振信号。 前端上变频电路包括增益和本振,这里需要注意同一个混频板上四个通道上下变频使用同一个本振信号。
目前ez-Q 2.5 FPGA平台硬件暂不支持变频增益设置。
|配置名|描述| |配置名|描述|
|:-:|:-:| |:-:|:-:|
|lo_freq|变频本振频率设置| |lo_freq|变频本振频率设置|
|up_gain|上变频增益设置|
> 目前ez-Q 2.5 FPGA平台硬件暂不支持变频增益设置。 * lo_freq32比特整数范围[5400000, 5600000]单位是kHz

View File

@ -12,4 +12,4 @@ Pump输出时需要使能输出并配置好输出频率和功率以下是
* pump_freq: 32比特整数范围[7000000, 9000000], 单位是kHz * pump_freq: 32比特整数范围[7000000, 9000000], 单位是kHz
* pump_power: 32比特整数范围[-1100, -300] 具体映射关系取决于硬件 * pump_power: 32比特整数范围[-1100, -300] 具体映射关系取决于硬件
* pump_enable: `32'h11` 为使能(开),`32'h00` 为关闭(关) * pump_enable: 0x11 为使能0x00为关闭

View File

@ -1,162 +1,182 @@
## 5.7. EXC-Pump通道全流程控制示例 ## 5.7. EXC-Pump通道全流程控制示例
本节通过一个完整的端到端示例说明EXC-Pump通道的编程配置流程 本节通过一个完整的示例演示EXC-Pump通道从码字生成到激励信号与Pump信号输出的全流程编程控制
示例基于 **ASIC 平台**DAC 8 bit@6 Gsps8 采样点/时钟周期),场景为输出一个 6.7 GHz 读出激励脉冲,同时触发 Pump 使能信号。 示例场景输出一个6.7 GHz读出激励脉冲同时触发Pump使能信号。
### 5.7.1. 端到端配置流程 ### 5.7.1. 流程总览
EXC-Pump通道的工作流程如下 EXC-Pump通道全流程包含以下步骤
|阶段|操作|说明| 1. **加载波形数据** — 将波形采样点写入波形仓库
|:-|:-|:-| 2. **配置波形索引表** — 建立波形ID到地址/长度的映射
|初始化|加载波形数据、配置索引表、配置寄存器、配置上变频、配置Pump|通过SPI写入步骤1~5无先后顺序要求| 3. **配置EXC寄存器** — 设置NCO参数、幅度、工作模式
|初始化|加载MCU程序|写入MCU_INS定义触发后要发出的码字| 4. **配置上变频电路** — 设置混频板本振频率
|运行|外部触发 → MCU执行 → 产生码字|触发由其它硬件发出MCU响应后执行程序并生成13位码字| 5. **配置Pump模拟电路** — 设置Pump频率、功率
|运行|码字解码 → 波形输出 + Pump脉冲|硬件自动流水线执行输出RF信号和使能脉冲| 6. **生成并发送码字** — MCU发出波形触发码字 + Pump使能
7. **输出激励信号与Pump脉冲** — 硬件执行输出RF信号和使能脉冲
``` ![EXC-Pump全流程控制](../assets/readout_ri.png)
关键理解:
触发信号来自外部硬件非MCUMCU是被动响应方。
MCU 程序加载到 MCU_INS 后处于待命状态,收到触发后执行并生成码字。
初始化配置可在任意时刻通过 SPI 完成,只需在触发前生效即可。
```
### 5.7.2. 地址空间速查 ### 5.7.2. 步骤1加载波形数据到波形仓库
以下配置基于EXC通道0Exaddr=0各模块基地址如下完整地址映射见 [附录A.1.2](#a12-exc) 将预计算的基带波形采样点写入波形仓库SRAM
|模块|基地址|用途|
|:-|:-|:-|
|MCU_INS|`0x00700000`|MCU指令存储|
|MCU_DAT|`0x00800000`|MCU数据存储|
|AWG_REG|`0x00900000`|AWG控制寄存器|
|AWG_IDX|`0x00A00000`|波形索引表256条 × 32位|
|AWG_WVE|`0x00B00000`|波形仓库128 KB|
|MIXER_REG|`0x00100000`|混频板本振配置|
|PUMP_REG|`0x00000000`|Pump通道寄存器ch0基址|
### 5.7.3. 步骤1加载波形数据
将预计算的基带波形采样点写入 AWG_WVE
|参数|值|说明| |参数|值|说明|
|:-|:-|:-| |:-|:-|:-|
|基带频率|1.2 GHz|$F_{baseband} = 6.7 - 5.5$ GHz| |基带频率|1.2 GHz|$F_s = 6.7 - 5.5$ GHz|
|波形长度|256 采样点|ASIC: 32 cycles × 8 samples/cycle| |采样率|4 GSps (FPGA)|16采样点/时钟周期|
|写入地址|`0x00B00000` 起|AWG_WVE 基地址,连续写入 256 × 16 bit| |波形长度|256 采样点|16个时钟周期FPGA$256 \times 250\text{ps} = 64\text{ns}$|
|起始地址|`0x0000`|波形仓库中的偏移地址|
波形采样点数据示例16位有符号整数大端字节序
``` ```
ASIC 平台每时钟周期 8 个采样点6 Gsps采样点个数需为 8 的整数倍。 地址 0x0000: 0x0000, 0x0C8C, 0x18C8, 0x2400, ... (共256个采样点)
FPGA 平台每时钟周期 16 个采样点4 Gsps采样点个数需为 16 的整数倍。
每个采样点为 16 位有符号整数(二进制补码),大端字节序。
波形仓库总容量 128 KB。
``` ```
### 5.7.4. 步骤2配置波形索引表 ```
ASIC平台下每个时钟周期对应8个采样点采样点个数需为8的整数倍。
FPGA平台下每个时钟周期对应16个采样点采样点个数需为16的整数倍。
波形仓库总容量128 KBFPGA平台最大支持16 μs输出ASIC平台最大支持10 μs输出。
```
在 AWG_IDX 中建立波形ID到存储参数的映射深度256条每条32位 ### 5.7.3. 步骤2配置波形索引表
|WAVE_ID|AWG_IDX地址|addr [31:16]|len [15:0]|说明| 在波形索引表LUT中建立波形ID到波形参数的映射
|:-|:-|:-|:-|:-|
|0|`0x00A00000`|`0x0000`|`0x0020`|起始地址 0x0000长度 32 cycles| |波形ID (WAVE_ID)|addr (高16位)|len (低16位)|说明|
|1|`0x00A00004`|`0x0020`|`0x0010`|起始地址 0x0020长度 16 cycles| |:-|:-|:-|:-|
|0|`0x0000`|`0x0010`|起始地址0x0000长度16个时钟周期|
|1|`0x0010`|`0x0008`|起始地址0x0010长度8个时钟周期|
``` ```
波形索引表深度256条1 kB每条目录宽32位。
addr 和 len 均以时钟周期为单位。 addr 和 len 均以时钟周期为单位。
AWG_IDX 每条目占用 4 字节WAVE_ID=N 的地址 = 0x00A00000 + N × 4 通过切换 WAVE_ID 可以在不同波形之间快速切换
``` ```
### 5.7.5. 步骤3配置EXC寄存器 ### 5.7.4. 步骤3配置EXC寄存器
通过SPI写AWG控制寄存器基带直出NRZ模式 配置AWG模块寄存器通过SPI或MCU写入
|地址|寄存器|字段|值|说明| |寄存器|值|说明|
|:-|:-|:-|:-|:-| |:-|:-|:-|
|`0x00900034`|amplitude|acw [31:16]|`16384`|归一化幅度 $16384 / 2^{14} = 1$| |`amplitude`|`acw = 8192`|归一化幅度 $8192 / 2^{16} \approx 0.125$|
|`0x00900038`|frequency|fcw [31:0]|`0`|基带直出模式NCO不生效| |`frequency`|`fcw = 0`|NCO频率控制字基带直出模式NCO不生效|
|`0x0090003C`|phase|pcw [31:16]|`0`|基带直出模式NCO不生效| |`phase`|`pcw = 0`|NCO相位控制字基带直出模式不生效|
|`0x00900044`|func_ctrl|awg_mode [1:0]|`0`(直出)|原始波形不经调制| |`function`|`0x0` (INTP_SEL=0, MIX_MODE=0, AWG_MODE=00)|基带直出模式NRZ|
|`0x00900044`|func_ctrl|mix_mode [2]|`0`(基带)|使用外部模拟混频|
|`0x00900044`|func_ctrl|intp_sel [3]|`0`(邻近插值)|ASIC 可设为 `1` 使用半带插值优化平坦度|
|`0x00900048`|pump_ctrl|delay [31:16]|`2`|Pump 脉冲延迟(单位时钟周期)|
|`0x00900048`|pump_ctrl|width [15:0]|`32`|Pump 脉冲持续宽度(与波形长度对齐)|
> 若需正交调制模式(如扫频应用),将 `awg_mode` 设为 `1`(调制),并配置 `frequency``phase`。详见 [§5.2](#52-寄存器功能定义)。
### 5.7.6. 步骤4配置上变频
通过SPI写混频板本振频率寄存器
|地址|寄存器|字段|值|说明|
|:-|:-|:-|:-|:-|
|`0x00100000`|lo_freq|fcw [31:0]|`5_500_000`|本振 5.5 GHz单位 kHz|
同一混频板4个通道共享本振。输出频率 = 基带频率 + 本振频率 = 6.7 GHz。
### 5.7.7. 步骤5配置Pump
配置泵浦板寄存器ch0基址 `0x00000000`
|地址|寄存器|字段|值|说明|
|:-|:-|:-|:-|:-|
|`0x00200000`|pump_freq|pump_freq [31:0]|`7_800_000`|Pump 频率 7.8 GHz单位 kHz|
|`0x00300000`|pump_power|pump_power [31:0]|`-600`|功率设定(具体映射取决于硬件校准)|
|`0x00400000`|pump_enable|pump_enable [31:0]|`32'h11`|硬件级使能(`32'h00` = 关闭)|
``` ```
pump_enable = 32'h11 为硬件级使能,配置后方可响应码字 PUMP_EN 位。 function 寄存器模式选择:
pump_enable = 32'h00 时无论码字如何设置Pump 均无输出。 [3] INTP_SEL=0: 邻近插值FPGA平台仅支持此模式
[2] MIX_MODE=0: 基带模式(使用外部模拟混频)
[1:0] AWG_MODE=00: 直出模式(原始波形不经调制)
``` ```
### 5.7.8. 步骤6MCU程序与触发 若需要使用正交调制模式(扫频应用),配置如下:
MCU程序加载到 MCU_INS`0x00700000`触发后MCU执行程序并生成13位码字。 |寄存器|值|说明|
**触发信号由外部硬件发出**MCU响应后自动执行。 |:-|:-|:-|
|`amplitude`|`acw = 16384`|归一化幅度 0.25|
|`frequency`|`fcw` = $F_{mod} / F_s \times 2^{32}$|调制频率控制字|
|`phase`|`pcw = 0`|初始相位 0|
|`function`|`0x1` (INTP_SEL=0, MIX_MODE=0, AWG_MODE=01)|正交调制模式|
### 5.7.5. 步骤4配置上变频电路
设置混频板本振频率:
|配置项|值|说明|
|:-|:-|:-|
|lo_freq|5_500_000|本振频率 5.5 GHz单位 kHz|
```
同一个混频板上4个通道共享同一个本振信号。
输出频率 = 基带频率 + 本振频率。
本例: 1.2 GHz + 5.5 GHz = 6.7 GHz。
```
### 5.7.6. 步骤5配置Pump模拟电路
配置Pump通道输出参数
|配置项|值|说明|
|:-|:-|:-|
|pump_freq|7_800_000|Pump信号频率 7.8 GHz单位 kHz|
|pump_power|-600|Pump信号功率具体映射关系取决于硬件校准|
|pump_enable|0x11|Pump输出使能需先配置再使能否则输出无效|
```
Pump信号为连续波单音信号其开关由MCU码字的PUMP_EN比特实时控制。
pump_enable = 0x11 为硬件级使能配置后方可响应PUMP_EN码字位。
pump_enable = 0x00 时无论码字如何设置Pump均无输出。
```
### 5.7.7. 步骤6生成并发送码字
MCU生成码字同时触发波形输出和Pump脉冲
**场景A同时输出波形和Pump脉冲** **场景A同时输出波形和Pump脉冲**
|位段|字段名|值|说明| |码字位段|字段名|配置值|说明|
|:-|:-|:-|:-| |:-|:-|:-|:-|
|[12]|PULSE_ONLY|`0`|正常输出波形| |[12]|PULSE_ONLY|0|正常输出波形|
|[11]|PARAMETER_SEL|`0`|波形索引来自查找表| |[11]|PARAMETER_SEL|0|波形索引来自查找表WAVE_ID|
|[10]|NCO_CLR_EN|`0`|不复位NCO| |[10]|NCO_CLR_EN|0|不复位NCO|
|[9]|MARK_EN|`0`|不触发Marker| |[9]|MARK_EN|0|不触发Marker脉冲|
|[8]|PUMP_EN|`1`|触发Pump脉冲| |[8]|PUMP_EN|1|触发Pump脉冲输出|
|[7:0]|WAVE_ID|`0`|索引波形ID=032 cycles 读出脉冲)| |[7:0]|WAVE_ID|0|索引波形ID=016个时钟周期的读出脉冲)|
完整码字值:**`0x0100`** 完整码字值:`0x0100`
**场景B仅输出Pump脉冲无波形** **场景B仅输出Pump脉冲不输出波形)**
|位段|字段名|值|说明| |码字位段|字段名|配置值|说明|
|:-|:-|:-|:-| |:-|:-|:-|:-|
|[12]|PULSE_ONLY|`1`|禁用波形输出| |[12]|PULSE_ONLY|1|禁用波形输出|
|[11:9]|—|`0`|—| |[11:9]|-|0|—|
|[8]|PUMP_EN|`1`|触发Pump脉冲| |[8]|PUMP_EN|1|触发Pump脉冲输出|
|[7:0]|WAVE_ID|`0`|被忽略PULSE_ONLY=1| |[7:0]|WAVE_ID|0|波形索引PULSE_ONLY=1时被忽略|
完整码字值:**`0x1100`** 完整码字值:`0x1100`
```
PUMP_EN 触发后Pump使能脉冲由 pump_ctrl 寄存器的延迟和持续参数控制:
- 高16位延迟: 脉冲在码字解码后延迟N个时钟周期开始
- 低16位持续: 脉冲持续M个时钟周期
将延迟和持续设为相同值可实现"跟随波形长度"的效果。
```
### 5.7.8. 步骤7硬件执行与输出
码字解码后,硬件按以下流水线执行:
1. **T0**: MCU 发出码字 `0x0100`
2. **T0 + 1 cycle**: 码字解码 — WAVE_ID=0 索引波形索引表 → 获取 addr=0x0000, len=16
3. **T0 + 2 cycle**: 波形仓库从 addr=0x0000 开始读取,持续 len=16 个时钟周期
4. **T0 + 2~17 cycles**: 原始波形数据流经模式选择器直出模式旁路希尔伯特和NCO
5. **T0 + 3 cycle**: 幅度调制 → 半带插值FPGA旁路→ MIX模块基带模式旁路→ DAC
6. **T0 + 4 cycle**: Pump脉冲开始输出假设pump_ctrl延迟=2
7. **T0 + 18 cycle**: 波形输出完成
8. **T0 + 20 cycle**: Pump脉冲结束假设pump_ctrl持续=16
最终射频输出基带波形经DAC转换后通过混频板与本振(5.5 GHz)模拟混频产生6.7 GHz读出激励信号。
### 5.7.9. 时序图
```
CLK : _/‾\_/‾\_/‾\_/‾\_/‾\_/‾\_/‾\_/‾\_/‾\_/‾\_/‾\_/‾\_/‾\_/‾\_/‾\_/‾\_/‾\_/‾\_/‾\_
码字 : ___/────────‾‾‾‾‾‾‾‾\_______________________________________________
WAVE_ID: ___/────0────\_____________________________________________________
波形输出: _____________/─────── 16 cycles 波形 ──────\_______________________
Pump脉冲: ______________________/─ delay ─\_________/─ 持续 ─\_____________
RF_OUT : _______________________/──── 6.7 GHz 激励脉冲 ────\________________
```
``` ```
注意事项: 注意事项:
1. 连续触发时需确保前一码字的波形输出完成,否则波形索引表可能被覆盖。 1. Pump使能脉冲的延迟参数需确保与波形输出上升沿对齐。
2. 调试阶段建议使用 MARK_EN 触发Marker脉冲辅助示波器触发捕获。 2. 多个码字连续发送时,需确保前一码字的波形输出完成后再发下一码字,
3. 码字字段定义详见 [§5.1](#51-码字功能定义),具体 MCU 指令编程参见《量子编程指令集》。 否则波形索引表可能被覆盖导致输出异常。
3. 调试阶段建议使用 MARK_EN 触发Marker脉冲来辅助示波器触发捕获。
``` ```
### 5.7.9. 配置清单汇总
|步骤|地址|寄存器|关键字段|值|
|:-|:-|:-|:-|:-|
|1|`0x00B00000`|AWG_WVE|波形采样点|256 × 16 bit|
|2|`0x00A00000`|AWG_IDX[0]|addr / len|`0x0000` / `0x0020`|
|3|`0x00900034`|amplitude|acw|`16384`|
|3|`0x00900038`|frequency|fcw|`0`|
|3|`0x0090003C`|phase|pcw|`0`|
|3|`0x00900044`|func_ctrl|awg_mode, mix_mode, intp_sel|`0x0`|
|3|`0x00900048`|pump_ctrl|delay / width|`2` / `32`|
|4|`0x00100000`|lo_freq|fcw|`5_500_000`|
|5|`0x00200000`|pump_freq|pump_freq|`7_800_000`|
|5|`0x00300000`|pump_power|pump_power|`-600`|
|5|`0x00400000`|pump_enable|pump_enable|`32'h11`|
|6|`0x00700000`|MCU_INS|MCU程序|产生码字 `0x0100`|

View File

@ -1,61 +0,0 @@
# 附录A. IDS寄存器索引表
本附录提供读出子系统通道配置寄存器的地址索引IDS, Index Data Sheet
供软件编程时通过基地址 + 偏移地址访问具体寄存器。
以下所有表格数据来源于 IDS JSON 数据文件对应2509批次读出芯片
由构建时自动渲染生成,确保与硬件设计数据库保持同步。
## A.1. 地址空间映射
读出子系统的配置访问采用四级寻址层级,从网络到寄存器的完整链路如下:
1. **网络地址IP** — 定位机箱。软件通过指定目标机箱的 IP 地址来确定与哪个机箱内的板卡通信。一个机箱内可安装多块 PXIe 板卡IP 地址是整个通信链路的起点。
2. **扩展地址Exaddr** — 定位槽位和总线。[7:3]对应槽位号exaddr[2:0]对应总线号。读出基带板允许安装在4或者15槽泵浦板和混频板分别在左右相邻位置因此软件仅需指定基带板槽位号即可定位全部三个板卡。
3. **片选地址Cid** — 定位总线上芯片ID。采用5比特编码最大支持32颗芯片挂载到同一个spi总线上在当前的实现中直接使用总线编址通道号每个芯片独占一个总线因此Cid固定为0。
4. **配置基地址Base** — 定位具体配置项。采用25比特编码其中高5比特用来定位不同模块配合20比特的偏移地址用来具体指定配置项目。
芯片控制存在MCU视角和配置视角区别是基地址不同。从MCU操控视角来看AWG和DAQ模块寄存器统一映射在对应 MCU 的 **`0x200000`** 地址空间。从上位机配置视角看,基地址和偏移地址定义如下表所示:
### A.1.1. ACQ 通道模块基地址
对应 `msmt_acq` 通道类型(采集通道),共 4 个通道ch0~ch3
每个通道包含 5 个功能模块:
@import "../../rbpu_datasheet/data/ids.json" using render_ids_acq_map
### A.1.2. EXC 通道模块基地址
对应 `msmt_exc` 通道类型(激励通道),共 4 个通道ch0~ch3
每个通道包含 5 个功能模块:
@import "../../rbpu_datasheet/data/ids.json" using render_ids_exc_map
## A.2. DAQ_REG — ACQ 寄存器
ACQ 通道配置寄存器,对应采集通道的 DAQ 模块。寄存器基地址参见
[A.1.1 节](#a11-acq) 中 `DAQ_REG` 行。
各寄存器通过偏移地址在模块内部索引,如下表所示。
@import "../../rbpu_datasheet/data/ids.json" using render_ids_daq_reg
## A.3. AWG_REG — EXC-Pump 寄存器
EXC-Pump 通道配置寄存器,对应激励通道的 AWG 模块。寄存器基地址参见
[A.1.2 节](#a12-exc) 中 `AWG_REG` 行。
各寄存器通过偏移地址在模块内部索引,如下表所示。
@import "../../rbpu_datasheet/data/ids.json" using render_ids_awg_reg
## A.4. 寄存器访问说明
- 所有寄存器支持 **SPI****MCU** 双端口访问
- 静态参数建议通过 SPI 配置后保持不变,动态参数通过 MCU 实时更新
- 寄存器位宽均为 **32 位**(不足 32 位的高位保留)
- 返回数据统一采用 **大端字节序**
- MCU 以固定 **3 个时钟周期/指令** 的速率执行
- 权限缩写:`RW` = 读写,`RO` = 只读,`WC` = 只写(写清除)

View File

@ -72,15 +72,11 @@ def load_plugin_modules(directory):
if spec is None or spec.loader is None: if spec is None or spec.loader is None:
continue continue
mod = importlib.util.module_from_spec(spec) mod = importlib.util.module_from_spec(spec)
# 注册到 sys.modules 以支持插件间交叉导入
sys.modules[py_file.stem] = mod
spec.loader.exec_module(mod) spec.loader.exec_module(mod)
modules[py_file.stem] = mod modules[py_file.stem] = mod
print(f" 已加载: {py_file.stem}") print(f" 已加载: {py_file.stem}")
except Exception as e: except Exception as e:
print(f" 警告: 加载 {py_file.name} 失败: {e}") print(f" 警告: 加载 {py_file.name} 失败: {e}")
# 加载失败时清理 sys.modules
sys.modules.pop(py_file.stem, None)
return modules return modules
@ -213,49 +209,26 @@ def process_image_attrs(text):
# ---------- KaTeX 预处理 ---------- # ---------- KaTeX 预处理 ----------
# 公式占位符存储preprocess → postprocess 传递)
_MATH_PLACEHOLDERS = {}
def preprocess_katex(text): def preprocess_katex(text):
""" """
Markdown 中的 LaTeX 公式替换为唯一占位符 Markdown 中的 LaTeX 公式包装为原始 HTML
防止 Markdown 解析器错误解释公式中的 _ * 等字符 防止 Markdown 解析器错误解释公式中的 _ * 等字符
占位符在 postprocess_katex 中还原为 HTML 包装的公式
""" """
_MATH_PLACEHOLDERS.clear()
# 块级公式 $$...$$ # 块级公式 $$...$$
def protect_display(match): def protect_display(match):
latex = match.group(1).strip() latex = match.group(1)
idx = len(_MATH_PLACEHOLDERS) return f'<div class="math-display">$${latex}$$</div>'
key = f"\x00MATH_DISPLAY_{idx}\x00"
_MATH_PLACEHOLDERS[key] = f'<div class="math-display">$${latex}$$</div>'
return key
text = re.sub(r'\$\$\s*(.+?)\s*\$\$', protect_display, text, flags=re.DOTALL) text = re.sub(r'\$\$\s*(.+?)\s*\$\$', protect_display, text, flags=re.DOTALL)
# 行内公式 $...$ # 行内公式 $...$
def protect_inline(match): def protect_inline(match):
latex = match.group(1) latex = match.group(1)
idx = len(_MATH_PLACEHOLDERS) return f'<span class="math-inline">${latex}$</span>'
key = f"\x00MATH_INLINE_{idx}\x00"
_MATH_PLACEHOLDERS[key] = f'<span class="math-inline">${latex}$</span>'
return key
text = re.sub(r'(?<!\d)\$([^$\s].*?[^$\s])\$(?!\d)', protect_inline, text) text = re.sub(r'(?<!\d)\$([^$\s].*?[^$\s])\$(?!\d)', protect_inline, text)
return text return text
def postprocess_katex(html):
"""将占位符还原为 HTML 包装的 LaTeX 公式。"""
result = html
for key, replacement in _MATH_PLACEHOLDERS.items():
result = result.replace(key, replacement)
return result
# ---------- 自定义代码块渲染 ---------- # ---------- 自定义代码块渲染 ----------
FENCED_CODEBLOCK_OPEN_RE = re.compile(r'^```(\w+)(?:\s+[^\n]*)?$') FENCED_CODEBLOCK_OPEN_RE = re.compile(r'^```(\w+)(?:\s+[^\n]*)?$')
@ -315,11 +288,8 @@ def render_custom_codeblocks_md(text, renderers):
# ^ : 与上方单元格合并rowspan # ^ : 与上方单元格合并rowspan
# < : 与左侧单元格合并colspan本单元格被吸收 # < : 与左侧单元格合并colspan本单元格被吸收
# > : 与右侧单元格合并colspan右侧单元格被吸收 # > : 与右侧单元格合并colspan右侧单元格被吸收
# 策略:展平时将合并标记替换为被合并单元格的内容并附加哨兵标记, # 策略:展平时将合并标记替换为被合并单元格的内容,
# 再由 postprocess_table_rowspan 根据哨兵标记生成 rowspan/colspan。 # 再由 postprocess_table_rowspan 检测重复内容生成 rowspan/colspan。
# 仅显式标记了 ^ / < / > 的单元格才会参与合并,避免跨逻辑组的过度合并。
MERGE_MARKER = "<!--MPEMERGE-->"
# 表格行: | cell | cell | ... | # 表格行: | cell | cell | ... |
TABLE_ROW_RE = re.compile(r'^\|.+\|$') TABLE_ROW_RE = re.compile(r'^\|.+\|$')
@ -413,26 +383,22 @@ def _flatten_mpe_table(table_lines):
for row in parsed: for row in parsed:
for col in range(num_cols - 2, -1, -1): for col in range(num_cols - 2, -1, -1):
if row[col].strip() == ">": if row[col].strip() == ">":
row[col] = MERGE_MARKER + row[col + 1] row[col] = row[col + 1]
# 第 2 遍:处理 <(左→右,复制左侧单元格内容) # 第 2 遍:处理 <(左→右,复制左侧单元格内容)
for row in parsed: for row in parsed:
for col in range(1, num_cols): for col in range(1, num_cols):
if row[col].strip() == "<": if row[col].strip() == "<":
row[col] = MERGE_MARKER + row[col - 1] row[col] = row[col - 1]
# 第 3 遍:处理 ^(上→下,复制上方单元格内容,清除旧哨兵避免重复 # 第 3 遍:处理 ^(上→下,复制上方单元格内容
prev_cells = _split_table_cells(header) prev_cells = _split_table_cells(header)
while len(prev_cells) < num_cols: while len(prev_cells) < num_cols:
prev_cells.append("") prev_cells.append("")
for row in parsed: for row in parsed:
for col in range(num_cols): for col in range(num_cols):
if row[col].strip() == "^": if row[col].strip() == "^":
content = prev_cells[col] if col < len(prev_cells) else row[col] row[col] = prev_cells[col] if col < len(prev_cells) else row[col]
# 剥离 prev_cells 中已有的哨兵标记,避免链式累积
if content.startswith(MERGE_MARKER):
content = content[len(MERGE_MARKER):]
row[col] = MERGE_MARKER + content
prev_cells = list(row) prev_cells = list(row)
# 重建表格行 # 重建表格行
@ -453,25 +419,20 @@ TBODY_RE = re.compile(r'(<tbody>.*?</tbody>)', re.DOTALL)
def postprocess_table_rowspan(html): def postprocess_table_rowspan(html):
""" """
扫描 HTML 表格的 <tbody>将带有 MERGE_MARKER 哨兵的单元格合并 扫描 HTML 表格的 <tbody>将连续内容相同的单元格合并
- 同一列上下连续相同且下方含哨兵 rowspan - 同一列上下连续相同 rowspan
- 同一行左右连续相同且右侧含哨兵 colspan - 同一行左右连续相同 colspan
preprocess_mpe_tables 配合仅显式标记了 ^ / < / > 的单元格生成哨兵 preprocess_mpe_tables 配合MPE 标记展平后产生重复内容此处恢复为视觉合并
避免跨逻辑组的过度合并
带有 class="no-rowspan" <table> 会被跳过不进行合并处理
注意仅处理 <tbody> 内的 <tr>Python markdown tables 扩展的输出格式 注意仅处理 <tbody> 内的 <tr>Python markdown tables 扩展的输出格式
""" """
# 匹配整个 <table> 元素,检查其 class 属性
TABLE_RE = re.compile(r'(<table[^>]*>)(.*?)(</table>)', re.DOTALL)
def merge_tbody(match): def merge_tbody(match):
tbody = match.group(1) tbody = match.group(1)
rows = TR_RE.findall(tbody) rows = TR_RE.findall(tbody)
if len(rows) < 2: if len(rows) < 2:
return tbody return tbody
# 解析所有单元格(统一补齐到最大列数,处理 rowspan 导致的列数不一致) # 解析所有单元格
row_cells = [] row_cells = []
for row_html in rows: for row_html in rows:
cells = [] cells = []
@ -487,74 +448,61 @@ def postprocess_table_rowspan(html):
if num_cols == 0: if num_cols == 0:
return tbody return tbody
# 统一补齐:不足 num_cols 的行用空单元格补齐
for row in row_cells:
while len(row) < num_cols:
row.append({"attrs": "", "text": ""})
# covered[r][c]:该单元格已被 rowspan 或 colspan 覆盖,渲染时跳过 # covered[r][c]:该单元格已被 rowspan 或 colspan 覆盖,渲染时跳过
covered = [[False] * num_cols for _ in range(num_rows)] covered = [[False] * num_cols for _ in range(num_rows)]
rowspan = [[1] * num_cols for _ in range(num_rows)] rowspan = [[1] * num_cols for _ in range(num_rows)]
colspan = [[1] * num_cols for _ in range(num_rows)] colspan = [[1] * num_cols for _ in range(num_rows)]
# ---- 计算 rowspan逐列扫描 ---- # ---- 计算 rowspan逐列扫描 ----
# 仅当下方单元格带 MERGE_MARKER 哨兵且内容匹配时才合并
for col in range(num_cols): for col in range(num_cols):
row = 0 row = 0
while row < num_rows: while row < num_rows:
if col >= len(row_cells[row]):
row += 1
continue
count = 1 count = 1
r = row + 1 r = row + 1
while r < num_rows: while r < num_rows:
below_text = row_cells[r][col]["text"] if (col < len(row_cells[r])
above_text = row_cells[row][col]["text"] and row_cells[r][col]["text"] == row_cells[row][col]["text"]
# 下方单元格必须带哨兵标记,且去除哨兵后与上方内容一致 and row_cells[row][col]["text"] != ""):
if (below_text.startswith(MERGE_MARKER)
and below_text[len(MERGE_MARKER):] == above_text
and above_text != ""):
count += 1 count += 1
covered[r][col] = True covered[r][col] = True
# 将合并单元格的内容统一为去除哨兵的版本
row_cells[r][col]["text"] = above_text
r += 1 r += 1
else: else:
break break
if count > 1: if count > 1:
rowspan[row][col] = count rowspan[row][col] = count
row = r row = r # 跳过已被当前 rowspan 覆盖的行
# ---- 计算 colspan逐行扫描跳过已覆盖单元格 ---- # ---- 计算 colspan逐行扫描跳过已覆盖单元格 ----
for row in range(num_rows): for row in range(num_rows):
col = 0 col = 0
while col < num_cols: while col < len(row_cells[row]):
if covered[row][col]: if covered[row][col]:
col += 1 col += 1
continue continue
count = 1 count = 1
c = col + 1 c = col + 1
while c < num_cols: while c < num_cols and c < len(row_cells[row]):
right_text = row_cells[row][c]["text"]
left_text = row_cells[row][col]["text"]
# 右侧单元格必须带哨兵标记,且去除哨兵后与左侧内容一致
if (not covered[row][c] if (not covered[row][c]
and right_text.startswith(MERGE_MARKER) and row_cells[row][c]["text"] == row_cells[row][col]["text"]
and right_text[len(MERGE_MARKER):] == left_text and row_cells[row][col]["text"] != ""):
and left_text != ""):
count += 1 count += 1
covered[row][c] = True covered[row][c] = True
row_cells[row][c]["text"] = left_text
c += 1 c += 1
else: else:
break break
if count > 1: if count > 1:
colspan[row][col] = count colspan[row][col] = count
col = c col = c # 跳过已被当前 colspan 覆盖的列
# ---- 生成带 rowspan / colspan 的 HTML ---- # ---- 生成带 rowspan / colspan 的 HTML ----
new_rows = [] new_rows = []
for row in range(num_rows): for row in range(num_rows):
new_cells = [] new_cells = []
for col in range(num_cols): for col in range(num_cols):
if covered[row][col]: if covered[row][col] or col >= len(row_cells[row]):
continue continue
cell = row_cells[row][col] cell = row_cells[row][col]
rs = rowspan[row][col] rs = rowspan[row][col]
@ -564,27 +512,12 @@ def postprocess_table_rowspan(html):
attrs += f' rowspan="{rs}"' attrs += f' rowspan="{rs}"'
if cs > 1: if cs > 1:
attrs += f' colspan="{cs}"' attrs += f' colspan="{cs}"'
# 修复: attrs 非空时加前导空格,避免 <tdrowspan="..."> 畸形标签 new_cells.append(f'<td{attrs}>{cell["text"]}</td>')
if attrs:
new_cells.append(f'<td {attrs}>{cell["text"]}</td>')
else:
new_cells.append(f'<td>{cell["text"]}</td>')
new_rows.append("<tr>" + "".join(new_cells) + "</tr>") new_rows.append("<tr>" + "".join(new_cells) + "</tr>")
return "<tbody>" + "".join(new_rows) + "</tbody>" return "<tbody>" + "".join(new_rows) + "</tbody>"
def process_table(match): return TBODY_RE.sub(merge_tbody, html)
table_open = match.group(1)
body = match.group(2)
table_close = match.group(3)
# 跳过带有 no-rowspan class 的表格
if 'no-rowspan' in table_open:
return match.group(0)
# 处理表格内的 <tbody>
body = TBODY_RE.sub(merge_tbody, body)
return table_open + body + table_close
return TABLE_RE.sub(process_table, html)
# ---------- Markdown → HTML ---------- # ---------- Markdown → HTML ----------
@ -664,28 +597,21 @@ def slugify(text):
def generate_toc(html): def generate_toc(html):
"""从 HTML 中提取 H1-H4 标题,生成目录。 """从 HTML 中提取 H1-H4 标题,生成目录。"""
锚点直接从标题已有的 id 属性读取确保与 HTML 中的实际 ID 一致"""
toc = [] toc = []
# 匹配带 id 属性的标题标签 for m in re.finditer(r'<h([1-4])[^>]*>(.*?)</h\1>', html, re.DOTALL):
for m in re.finditer(r'<h([1-4])\s+[^>]*\bid="([^"]*)"[^>]*>(.*?)</h\1>', html, re.DOTALL):
level = int(m.group(1)) level = int(m.group(1))
anchor = m.group(2) text = re.sub(r'<.*?>', '', m.group(2)).strip()
text = re.sub(r'<.*?>', '', m.group(3)).strip() toc.append({"level": level, "text": text, "anchor": slugify(text)})
toc.append({"level": level, "text": text, "anchor": anchor})
return toc return toc
def inject_anchors(html): def inject_anchors(html):
"""为所有 H1-H4 标签注入 id 属性,使侧边栏目录可跳转。 """为所有 H1-H4 标签注入 id 属性,使侧边栏目录可跳转。"""
如果标题已有 id 属性如自定义渲染器预设的锚点则保留原 id"""
def repl(match): def repl(match):
level = match.group(1) level = match.group(1)
attrs = match.group(2) attrs = match.group(2)
inner = match.group(3) inner = match.group(3)
# 保留已有的 id 属性(例如渲染器手动设置的锚点)
if re.search(r'\bid\s*=', attrs):
return f'<h{level}{attrs}>{inner}</h{level}>'
anchor = slugify(re.sub(r'<.*?>', '', inner).strip()) anchor = slugify(re.sub(r'<.*?>', '', inner).strip())
return f'<h{level} id="{anchor}"{attrs}>{inner}</h{level}>' return f'<h{level} id="{anchor}"{attrs}>{inner}</h{level}>'
return re.sub( return re.sub(
@ -851,9 +777,6 @@ def main():
# Markdown → HTML # Markdown → HTML
chapter_html = markdown_to_html(text) chapter_html = markdown_to_html(text)
# KaTeX 还原(占位符 → HTML 包装的公式)
chapter_html = postprocess_katex(chapter_html)
# 图片 base64 内嵌 # 图片 base64 内嵌
base_dirs = [ch_path.parent, ASSETS_DIR, PROJECT_ROOT] base_dirs = [ch_path.parent, ASSETS_DIR, PROJECT_ROOT]
chapter_html = embed_images(chapter_html, base_dirs) chapter_html = embed_images(chapter_html, base_dirs)

View File

@ -1,185 +0,0 @@
"""IDS 数据共享模块。
提供 JSON 加载和 HTML 表格渲染函数
render_ids_acq_map / render_ids_exc_map / render_ids_daq_reg / render_ids_awg_reg 复用
"""
import json
from pathlib import Path
from collections import OrderedDict
# 输出顺序(先列出的模块排在前面)
ACQ_MODULE_ORDER = ["MCU_INS", "MCU_DAT", "DAQ_REG", "DAQ_PAR", "DAQ_FLT"]
EXC_MODULE_ORDER = ["MCU_INS", "MCU_DAT", "AWG_REG", "AWG_IDX", "AWG_WVE"]
# ---------- 数据加载 ----------
def _load_ids(filepath: str) -> dict:
"""加载 IDS JSON 文件并返回解析后的 dict。"""
path = Path(filepath)
if not path.exists():
raise FileNotFoundError(f"IDS 文件不存在: {path}")
with open(path, "r", encoding="utf-8") as f:
return json.load(f)
# ---------- HTML 工具 ----------
def _td(text: str, **kwargs) -> str:
"""生成 <td> 单元格,支持 rowspan / style 等属性。"""
attrs = " ".join(f'{k}="{v}"' for k, v in kwargs.items() if v is not None)
return f"<td {attrs}>{text}</td>" if attrs else f"<td>{text}</td>"
def _th(text: str) -> str:
return f"<th>{text}</th>"
def _bit_range_str(bits: list) -> str:
"""将 [15, 8] 或 [7] 转为位段字符串。"""
if len(bits) == 1:
return str(bits[0])
return f"{bits[0]}:{bits[-1]}"
# ---------- 映射表渲染 ----------
def render_mapping_acq_table(data: dict) -> str:
"""渲染 msmt_acq 通道模块基地址表。"""
mi = data.get("MappingInfo", {}).get("msmt_acq", {})
return _render_mapping_table(mi, ACQ_MODULE_ORDER, "ACQ")
def render_mapping_exc_table(data: dict) -> str:
"""渲染 msmt_exc 通道模块基地址表。"""
mi = data.get("MappingInfo", {}).get("msmt_exc", {})
return _render_mapping_table(mi, EXC_MODULE_ORDER, "EXC")
def _render_mapping_table(mapping: dict, module_order: list, label: str) -> str:
"""通用的通道模块基地址渲染。"""
rows = []
# 收集所有模块名
all_modules = set()
for ch_info in mapping.values():
all_modules.update(ch_info.get("Modules", {}).keys())
# 按 module_order 排序,未在列表中的放最后
ordered = [m for m in module_order if m in all_modules]
ordered += sorted(all_modules - set(module_order))
for mod_name in ordered:
for ch in sorted(mapping.keys(), key=int):
info = mapping[ch]
modules = info.get("Modules", {})
if mod_name not in modules:
continue
m = modules[mod_name]
exaddr = info.get("Exaddr", "")
cid = info.get("Cid", "")
rows.append(
"<tr>"
f"<td>ch{ch}</td>"
f"<td>{exaddr}</td>"
f"<td>{cid}</td>"
f"<td><code>{mod_name}</code></td>"
f"<td><code>{m.get('StartAddress', '')}</code></td>"
f"<td>{m.get('Size', '')}</td>"
f"<td>{m.get('Info', '')}</td>"
"</tr>"
)
if not rows:
return "<p>(无映射数据)</p>"
header = (
"<tr>"
"<th>通道</th><th>Exaddr</th><th>Cid</th>"
"<th>模块</th><th>起始地址</th><th>大小</th><th>说明</th>"
"</tr>"
)
return f"<table>{header}{''.join(rows)}</table>"
# ---------- 寄存器表渲染 ----------
def render_daq_reg_table(data: dict) -> str:
"""渲染 DAQ_REG 寄存器汇总表 + 位域明细。"""
regs = data.get("Modules", {}).get("DAQ_REG", {})
return _render_reg_table(regs, "DAQ_REG")
def render_awg_reg_table(data: dict) -> str:
"""渲染 AWG_REG 寄存器汇总表 + 位域明细。"""
regs = data.get("Modules", {}).get("AWG_REG", {})
return _render_reg_table(regs, "AWG_REG")
def _render_reg_table(regs: dict, label: str) -> str:
"""通用寄存器表渲染(汇总表 + 每位域明细)。"""
if not regs:
return "<p>(无寄存器数据)</p>"
# 按偏移地址排序
sorted_regs = sorted(regs.values(), key=lambda r: int(r.get("OffsetAddress", "0x0"), 16))
# ---- 汇总表 ----
summary_rows = []
for r in sorted_regs:
name = list(regs.keys())[list(regs.values()).index(r)]
offset = r.get("OffsetAddress", "")
perm = r.get("Permission", "")
desc = r.get("SegDescription", "")
summary_rows.append(
"<tr>"
f"<td><strong>{name}</strong></td>"
f"<td><code>{offset}</code></td>"
f"<td>{perm}</td>"
f"<td>{desc}</td>"
"</tr>"
)
summary = (
"<table>"
"<tr><th>寄存器名</th><th>偏移地址</th><th>权限</th><th>描述</th></tr>"
f"{''.join(summary_rows)}"
"</table>"
)
# ---- 位域明细表(仅含字段数 > 0 的寄存器) ----
detail_parts = []
for r in sorted_regs:
fields = r.get("Fields", [])
if not fields:
continue
name = list(regs.keys())[list(regs.values()).index(r)]
offset = r.get("OffsetAddress", "")
field_rows = []
for f in fields:
bits = f.get("Bits", [])
field_name = f.get("FieldName", "")
fdesc = (f.get("FieldDescription", "") or "").replace("\n", "<br>")
reset = f.get("ResetValue", "")
field_rows.append(
"<tr>"
f"<td><code>[{_bit_range_str(bits)}]</code></td>"
f"<td><strong>{field_name}</strong></td>"
f"<td>{reset}</td>"
f"<td>{fdesc}</td>"
"</tr>"
)
if field_rows:
detail_parts.append(
f"<h4>{name}{offset}</h4>"
"<table>"
"<tr><th>位段</th><th>字段名</th><th>复位值</th><th>描述</th></tr>"
f"{''.join(field_rows)}"
"</table>"
)
if detail_parts:
return f"{summary}<br>{''.join(detail_parts)}"
return summary

View File

@ -1,8 +0,0 @@
"""ACQ 通道模块基地址表渲染器。"""
from render_ids import _load_ids, render_mapping_acq_table
def render(filepath):
"""返回 ACQ 通道模块基地址 HTML 表格(不含标题和描述)。"""
data = _load_ids(filepath)
return render_mapping_acq_table(data)

View File

@ -1,8 +0,0 @@
"""AWG_REG 寄存器表渲染器。"""
from render_ids import _load_ids, render_awg_reg_table
def render(filepath):
"""返回 AWG_REG 寄存器汇总表 + 位域明细 HTML不含标题和描述"""
data = _load_ids(filepath)
return render_awg_reg_table(data)

View File

@ -1,8 +0,0 @@
"""DAQ_REG 寄存器表渲染器。"""
from render_ids import _load_ids, render_daq_reg_table
def render(filepath):
"""返回 DAQ_REG 寄存器汇总表 + 位域明细 HTML不含标题和描述"""
data = _load_ids(filepath)
return render_daq_reg_table(data)

View File

@ -1,8 +0,0 @@
"""EXC 通道模块基地址表渲染器。"""
from render_ids import _load_ids, render_mapping_exc_table
def render(filepath):
"""返回 EXC 通道模块基地址 HTML 表格(不含标题和描述)。"""
data = _load_ids(filepath)
return render_mapping_exc_table(data)

View File

@ -26,4 +26,3 @@ chapters:
- 05-05-exc-upconversion.md - 05-05-exc-upconversion.md
- 05-06-pump-config.md - 05-06-pump-config.md
- 05-07-exc-pipeline-demo.md - 05-07-exc-pipeline-demo.md
- 80-appendix-ids-table.md