9.3 KiB
温度计数字模块设计方案
需求分析
模拟端vout输出方波信号,接入数字芯片,数字芯片分析方波频率,再根据频率和温度关系曲线图,得到实时温度,再输出温度量。
设计细节确定
通信方式:串口通信,为115200波特率, 不可更改。采用如下指定数据帧结构配置寄存器,帧传输为大端序。
| 数据结构 | 子字段 | 位宽 | 比特序 | 功能描述 | 备注 |
|---|---|---|---|---|---|
| CMD | W/R | 1 bit | [63] | 读写标识,0:写;1:读 | / |
| ^ | 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]freq,valid。作用是统计10ms内方波的上升沿,获得其频率。
统计出来的频率和时钟周期,设置采用间隔有关系,所以要告诉这个模块,
其次,设计digital_thermometer。input为clk,rst_n, vin, mode(为0时线性输出,为1时使用映射表输出), output 为[15:0]temp_out,[19:0]freq,valid等。
在模式0,就是线性输出freq如果是500(50.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 的设置 |
使用说明:
- 写操作:通过 UART 发送对应的地址和数据即可修改配置(如标定值、测量窗口)。
- 读操作:读取
0x14地址可获取当前最新的温度或频率数据,读取前建议先检查Bit[31]是否为 1。 - 字节序:寄存器内部采用大端或小端取决于您的
uart_ctrl逻辑,通常在 FPGA 中建议保持与总线一致。
总结
用verilog做一个温度计的数字设计,模拟端vout输出的是方波信号,方波波形低电平是0,高电平是1.2v,波形可能会有极短时间的小下冲,方波的频率代表温度信息,频率越高温度越高,频率范围是50kHz到130KHz之间,对应的温度范围是-40°到85°。方波接入到数字芯片,数字芯片分析方波频率,再根据频率和温度关系图(近似正比),得到实时温度,再输出温度量。