thermometer_digital/doc/设计报告/温度计数字模块设计报告.md

178 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# **温度计数字模块设计方案**
## 需求分析
模拟端vout输出方波信号接入数字芯片数字芯片分析方波频率再根据频率和温度关系曲线图得到实时温度再输出温度量。
<img src="./温度计数字模块设计报告.assets/局部截取_20260311_125312.png" alt="局部截取_20260311_125312" />
<img src="./温度计数字模块设计报告.assets/局部截取_20260311_125339.png" alt="局部截取_20260311_125339" style="zoom: 67%;" />
# 设计细节确定
**通信方式**串口通信为115200波特率 不可更改。采用如下指定数据帧结构配置寄存器,帧传输为大端序。
| 数据结构 | 子字段 | 位宽 | 比特序 | 功能描述 | 备注 |
| -------- | -------- | --------- | ------- | -------------------------------- | ------------------------------------------------------------ |
| **CMD** | W/R | 1 bit | [63] | 读写标识01读 | / |
| ^ | ARD FLAG | 1 bit | [62] | 0 | 主动回读模块根据读出芯片请求读出实验数据 |
| ^ | CID | 5 bits | [61:57] | 0 | 包括量子测控芯片组及其他需要配置的芯片组 |
| ^ | ADDR | 25 bits | [56:32] | 低 25 位地址 | 可与 EXADDR 拼接使用,或直接映射到量子测控芯片的偏移地址 |
| ^ | EXADDR | 12 bits | [31:20] | 0 | 可与 ADDR 拼接使用此时寻址空间为 128GByte该 4096K 的地址空间可按照需求映射给集控中心和外部 SIP 芯片组 |
| ^ | LENGTH | 20 bits | [19:0] | 指示读写数据长度,以 Byte 为单位 | 最大支持 1MByte |
| **DATA** | - | N*4 bytes | [31:0] | 数据 | 读操作时,无需包含该项 |
**温度精度**温度分辨率为小数点后2位-4032表示-40.32度
**系统时钟周期**50MHz。
**标定方式**:线性标定。**范围**:默认为-40°C对应160kHz, 85°C对应600kHz.
**输出**支持输出类型为3种温度频率和单位采用窗口脉冲上升沿数。
**采样窗口时长**默认1ms, 支持配置
**主动回传模式**默认关闭。可通过配置0x10上报寄存器开启数据回传间隔可配置。
# 设计细节
首先需要设计一个pulse_freq_10ms模块需要将方波的Vin的频率统计出来这个模块的input 为clk rst_n ,vin , output为 [19:0]freqvalid。作用是统计10ms内方波的上升沿获得其频率。
统计出来的频率和时钟周期,设置采用间隔有关系,所以要告诉这个模块,
其次设计digital_thermometer。input为clk,rst_n, vin, mode(为0时线性输出为1时使用映射表输出) output 为[15:0]temp_out[19:0]freqvalid等。
在模式0就是线性输出freq如果是50050.0khz)对应的就是-40° 如果是1300 就是85°C 通过temp_out输出。 如果是1模式则使用一个映射表标定映射表默认初始化也是线性的但能够修改
freq_valid拉高下一个周期就把freq_valid也拉高同时freq_x100hz更新tenp_out也要跟着变。
**设计通信模块**
使用串口通信,需要用串口简单的读写寄存器,选择是定时输出温度,还是频率, 允许设置更新时间间隔等等。
要实现用固定的指令写寄存器需要做很多事情。
首先要规定帧结构。固定CMD为64bit,data为32bit。 到时候通过解析帧操作经典5口。
其次需要一个tb模块比如uart_driver 这个东西需要能够把txt变成电平通过vif喂进去。 uart_driver.do_drive( case.txt) 然后 vif = 真实接口 然后new一个类my_drv.itf = vif; 我觉得不需要这么麻烦,反正是仿真用的。
要一个能把物理接口rx tx 的数据 转为经典5口的模块 。经典5口和systemregfile通信就行读写寄存器了。
需要一个状态机,
空闲状态 ,一直等待接收数据, 此状态可接收到cmd h32
接收cmd L32 状态 此状态拿到 cmd l32 ,和上面拼凑一下拿到完整 cmd
parse状态 基于上面拿到的cmd ,解析,可以知道是读还是写, 地址是什么 ,数据是什么。 同时还可拿到data32吗不需要在这边拿要拿的话需要if(rx_done)卡一下才行。结束拉高标志位
写状态 可以拿到下一个data32 。 进来的时候先判断当前还剩多少没写。
读状态 此时i_rddata准备好了吗并没有o_rden拉高一个时钟周期下一个时钟周期对面把数据放上去下下个周期才能稳定锁存。所以要读别人发请求要事情别人放数据也要时间第三个时钟周期才能拿到数据。
需要被锁存进来发送缓冲区同时拉高go
现在uart_ctrl_systemreg 和和简单版的systemregflie写完了
现在要用串口控制 温度传感器了, 用一个串口比较好,因为到时候和上位机通信连一个串口调试助手就行。
# 寄存器设置
根据刚才补全的 `system_regfile` 模块逻辑,为您整理的寄存器说明表格如下。这些寄存器地址采用 **32位4字节对齐** 方式。
### 1. 寄存器地址映射表 (Register Map)
| **偏移地址 (Offset)** | **寄存器名称** | **属性** | **复位值** | **描述** |
| --------------------- | -------------- | -------- | -------------- | -------------------------- |
| `16'h00` | **TESTR** | R/W | `32'h1234567` | 芯片 ID / 测试寄存器 |
| `16'h04` | **DATER** | R/W | `32'h20260406` | 生产日期寄存器 |
| `16'h08` | **WIN_MODE_R** | R/W | `32'h000003E8` | 测量窗口时间与输出模式配置 |
| `16'h0C` | **CALIB_R** | R/W | `32'h025800A0` | 温度计频率标定参数 |
| `16'h10` | **REPORT_R** | R/W | `32'h0000c350` | 自动上报使能与间隔配置 |
| `16'h14` | **STATUS** | **RO** | `32'h00000000` | 当前温度计状态与测量结果 |
------
### 2. 寄存器位域详细说明
#### **WIN_MODE_R (Offset: 0x08)**
| **位域** | **名称** | **属性** | **描述** |
| --------- | ------------ | -------- | ------------------------------------------------------------ |
| `[31:26]` | RESERVED | - | 保留 |
| `[25:24]` | **out_mode** | R/W | 输出模式选择: 00: 温度值0 01: 原始频率值(1) 10: 单位窗口脉冲计数(2) |
| `[23:0]` | **win_us** | R/W | 测量窗口时间,单位为微秒 (us)。默认值 1000us |
#### **CALIB_R (Offset: 0x0C)**
| **位域** | **名称** | **属性** | **描述** |
| --------- | --------------------- | -------- | ---------------------------------------------------- |
| `[31:16]` | **temp_85_fre_k** | R/W | 85°C 时对应的传感器频率 (kHz)。默认 600kHz (0x0258) |
| `[15:0]` | **temp_neg_40_fre_k** | R/W | -40°C 时对应的传感器频率 (kHz)。默认 160kHz (0x00A0) |
#### **REPORT_R (Offset: 0x10)**
| **位域** | **名称** | **属性** | **描述** |
| --------- | -------------- | -------- | ------------------------------------ |
| `[31]` | **report_en** | R/W | 自动上报使能开关。1: 开启0: 关闭 |
| `[30:24]` | RESERVED | - | 保留 |
| `[23:0]` | **rep_gap_us** | R/W | 自动上报的时间间隔 (us)。默认值 50ms |
#### **RESULT_R(Offset: 0x14)**
| **位域** | **名称** | **属性** | **描述** |
| --------- | ------------- | -------- | ---------------------------------------------------- |
| `[31:24]` | RESERVED | - | 保留 |
| `[23:0]` | **therm_out** | **RO** | 温度计实时输出结果。具体定义取决于 `out_mode` 的设置 |
------
### 使用说明:
1. **写操作**:通过 UART 发送对应的地址和数据即可修改配置(如标定值、测量窗口)。
2. **读操作**:读取 `0x14` 地址可获取当前最新的温度或频率数据,读取前建议先检查 `Bit[31]` 是否为 1。
3. **字节序**:寄存器内部采用大端或小端取决于您的 `uart_ctrl` 逻辑,通常在 FPGA 中建议保持与总线一致。
# 总结
用verilog做一个温度计的数字设计模拟端vout输出的是方波信号方波波形低电平是0高电平是1.2v,波形可能会有极短时间的小下冲方波的频率代表温度信息频率越高温度越高频率范围是50kHz到130KHz之间对应的温度范围是-40°到85°。方波接入到数字芯片数字芯片分析方波频率再根据频率和温度关系图近似正比得到实时温度再输出温度量。