除拖尾矫正功能没完成,其他均完成
This commit is contained in:
commit
a5a4bd1da5
|
|
@ -0,0 +1,8 @@
|
||||||
|
# 默认忽略的文件
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# 基于编辑器的 HTTP 客户端请求
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="jdk" jdkName="Python 3.11" jdkType="Python SDK" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
<component name="PyDocumentationSettings">
|
||||||
|
<option name="format" value="GOOGLE" />
|
||||||
|
<option name="myDocStringFormat" value="Google" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="PyPackageRequirementsInspection" enabled="false" level="WARNING" enabled_by_default="false">
|
||||||
|
<option name="ignoredPackages">
|
||||||
|
<value>
|
||||||
|
<list size="4">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="pyzmq" />
|
||||||
|
<item index="1" class="java.lang.String" itemvalue="matplotlib" />
|
||||||
|
<item index="2" class="java.lang.String" itemvalue="prometheus-client" />
|
||||||
|
<item index="3" class="java.lang.String" itemvalue="Pillow" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Black">
|
||||||
|
<option name="sdkName" value="Python 3.11" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/Z_case_Generator_V2.0.iml" filepath="$PROJECT_DIR$/.idea/Z_case_Generator_V2.0.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,323 @@
|
||||||
|
# from select import kevent
|
||||||
|
# from os import sync
|
||||||
|
# from select import kevent
|
||||||
|
from logging import config
|
||||||
|
import numpy as np
|
||||||
|
import re
|
||||||
|
from typing import List
|
||||||
|
# from chip_define.reg_define import reg_define['mcu_reg'], addr_base['DTCM0_BASE']
|
||||||
|
from reg_define import *
|
||||||
|
class AssemblyTemplateManager:
|
||||||
|
"""汇编指令模板管理器"""
|
||||||
|
|
||||||
|
def __init__(self, mk_instance, mk_instr, **kwargs):
|
||||||
|
self.mk = mk_instance
|
||||||
|
self.mk_instr = mk_instr
|
||||||
|
self.config_file = kwargs.get('config_file')
|
||||||
|
self.templates = {
|
||||||
|
'general_send_wait': self._generic_awg_control_template,
|
||||||
|
'ramp_fixed': self._ramp_mcu_fixed_template,
|
||||||
|
'ramp_step': self._ramp_mcu_template
|
||||||
|
}
|
||||||
|
|
||||||
|
def create_instructions(self, **kwargs):
|
||||||
|
template_type = kwargs.get('instr_type', str)
|
||||||
|
params = {**kwargs}
|
||||||
|
|
||||||
|
return self.templates[template_type](**params)
|
||||||
|
|
||||||
|
def _codeword_encode(self, **kwargs):
|
||||||
|
|
||||||
|
sendc = kwargs.pop('sendc' , 0)
|
||||||
|
wave_hold = kwargs.pop('wave_hold' , 0)
|
||||||
|
ff_amp_index = kwargs.pop('ff_amp_index', 0)
|
||||||
|
fm_amp_index = kwargs.pop('fm_amp_index', 0)
|
||||||
|
bias_index = kwargs.pop('bias_index' , 0)
|
||||||
|
fcw_index = kwargs.pop('fcw_index' , 0)
|
||||||
|
pcw_index = kwargs.pop('pcw_index' , 0)
|
||||||
|
code_clr = kwargs.pop('code_clr' , 0)
|
||||||
|
env_index = kwargs.pop('env_index' , 0)
|
||||||
|
|
||||||
|
codeword = 0
|
||||||
|
codeword |= sendc << 31
|
||||||
|
codeword |= wave_hold << 30
|
||||||
|
codeword |= ff_amp_index << 28
|
||||||
|
codeword |= fm_amp_index << 26
|
||||||
|
codeword |= bias_index << 24
|
||||||
|
codeword |= fcw_index << 22
|
||||||
|
codeword |= pcw_index << 19
|
||||||
|
codeword |= code_clr << 18
|
||||||
|
codeword |= env_index << 12
|
||||||
|
|
||||||
|
return codeword
|
||||||
|
|
||||||
|
def _codeword_gen(self, **kwargs):
|
||||||
|
codeword_configs = kwargs.pop('codeword_configs', [])
|
||||||
|
codeword_list = []
|
||||||
|
for config in codeword_configs:
|
||||||
|
codeword = self._codeword_encode(**config)
|
||||||
|
codeword_list.append(codeword)
|
||||||
|
return codeword_list
|
||||||
|
|
||||||
|
def write_register(self, address, value):
|
||||||
|
self.mk.rw_once('w', address, value, self.config_file)
|
||||||
|
|
||||||
|
def _generic_awg_control_template(self, **kwargs):
|
||||||
|
"""
|
||||||
|
通用 AWG汇编控制模版
|
||||||
|
支持扫参功能
|
||||||
|
"""
|
||||||
|
# ==========================================
|
||||||
|
# 1. 准备并打包 DTCM 数据 (Python 侧)
|
||||||
|
# ==========================================
|
||||||
|
codeword_list = self._codeword_gen(**kwargs)
|
||||||
|
send_interval_list = kwargs.get('send_interval', [100])
|
||||||
|
cycle_num = kwargs.get('cycle_num', 1)
|
||||||
|
# 提取扫参相关的参数配置
|
||||||
|
sweep_config = kwargs.get('sweep_config', {}) # 扫描参数包
|
||||||
|
sweep_num = sweep_config.get('sweep_num', 1) # 扫描次数,代表最外层大循环需要mcu参数重载的次数
|
||||||
|
sweep_offsets = sweep_config.get('offsets', []) # mcu_regfile中的偏移地址,代表需要重载的寄存器
|
||||||
|
sweep_steps = sweep_config.get('steps', []) # 增量步进
|
||||||
|
# 自动获取需要扫描的寄存器个数
|
||||||
|
sweep_reg_num = len(sweep_offsets)
|
||||||
|
|
||||||
|
# 构造 DTCM Payload 列表
|
||||||
|
# [宏观头部] -> [波形序列] -> [Offsets表] -> [Starts表] -> [Steps表]
|
||||||
|
# 宏观头部:重载次数,波形播放次数,码字个数,需要重载的寄存器个数
|
||||||
|
dtcm_payload = [sweep_num, cycle_num, len(codeword_list), sweep_reg_num]
|
||||||
|
|
||||||
|
# 压入波形序列:[码字0, 间隔0, 码字1, 间隔1 ...]
|
||||||
|
for cw, wait_clk in zip(codeword_list, send_interval_list):
|
||||||
|
dtcm_payload.append(cw)
|
||||||
|
dtcm_payload.append(wait_clk)
|
||||||
|
|
||||||
|
# 如果有扫参任务,压入地址表和步长表
|
||||||
|
if sweep_reg_num > 0:
|
||||||
|
dtcm_payload.extend(sweep_offsets)
|
||||||
|
dtcm_payload.extend([s & 0xFFFFFFFF for s in sweep_steps])
|
||||||
|
|
||||||
|
# 统一将这批动态参数写入到 DTFR(0xD8) 的下一个地址,即 0xDC 开始的内存中
|
||||||
|
target_addr = addr_base['DTCM0_BASE'] + reg_define['mcu_reg']['DTFR'] + 4
|
||||||
|
self.write_register(target_addr, dtcm_payload)
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# 2. 生成标准 RISC-V 汇编指令文本 (MCU 侧)
|
||||||
|
# ==========================================
|
||||||
|
return f"""
|
||||||
|
start:
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
# 基地址初始化
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
lui x1 , 0x100 # x1 = 数据内存 (DTCM) 基地址 (0x00100000)
|
||||||
|
lui x2 , 0x200 # x2 = 硬件控制寄存器基地址 (0x00200000)
|
||||||
|
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
# 批量搬移固化的 NCO 外设参数 (0x40 ~ 0x94)
|
||||||
|
# 包含 22 个寄存器:FCW0~3, CWPRR, GAPR0~7, LCPR, AMPR0~3, BIASR0~3
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
addi x3 , x0 , 4 # x3 = 4 (地址递增步长为 4 字节)
|
||||||
|
addi x4 , x0 , 22 # x4 = 22 (需要搬移的寄存器总数)
|
||||||
|
addi x5 , x1 , 0x40 # x5 = 数据源首地址 (DTCM 的 0x40 偏移)
|
||||||
|
addi x6 , x2 , 0x40 # x6 = 目标首地址 (外设的 0x40 偏移)
|
||||||
|
|
||||||
|
load_nco_params_loop:
|
||||||
|
addi x4 , x4 , -1 # 循环计数减 1
|
||||||
|
lw x31, 0x00(x5) # 从 DTCM 读出 1 个参数
|
||||||
|
sw x31, 0x00(x6) # 写入到控制寄存器
|
||||||
|
add x5 , x5 , x3 # 源地址 + 4
|
||||||
|
add x6 , x6 , x3 # 目标地址 + 4
|
||||||
|
bne x4 , x0 , load_nco_params_loop
|
||||||
|
|
||||||
|
# =========================================================
|
||||||
|
# 单独搬移 0xB4 地址的参数 (1000b4 -> 2000b4) FM_EN 。至此上述共23个参数搬移完成
|
||||||
|
# =========================================================
|
||||||
|
lw x31, 0xb4(x1) # 从 DTCM (0x1000b4) 读出参数到 x31
|
||||||
|
sw x31, 0xb4(x2) # 将 x31 写入到外设控制寄存器 (0x2000b4)
|
||||||
|
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
# 模块 A: 读取宏观参数 (0xDC)
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
lw x10, 0xdc(x1) # x10 = sweep_num (扫描总步数)
|
||||||
|
lw x11, 0xe0(x1) # x11 = cycle_num (系综平均次数)
|
||||||
|
lw x12, 0xe4(x1) # x12 = wave_num (波形数)
|
||||||
|
lw x17, 0xe8(x1) # x17 = sweep_reg_num (修改个数)
|
||||||
|
|
||||||
|
addi x13, x1 , 0xec # x13 = 波形序列首地址 (0xEC)
|
||||||
|
slli x14, x12, 3
|
||||||
|
add x18, x13, x14 # x18 = [Offsets] 地址表首地址
|
||||||
|
slli x14, x17, 2
|
||||||
|
add x20, x18, x14 # x20 = [Steps] 步长表首地址
|
||||||
|
|
||||||
|
# ==================== 主控执行入口 (Do-While 模式) ====================
|
||||||
|
run_sweep_iteration:
|
||||||
|
# ====== 1. 系综平均循环 ======
|
||||||
|
addi x28, x11, 0
|
||||||
|
middle_ensemble_loop:
|
||||||
|
addi x28, x28, -1
|
||||||
|
addi x26, x12, 0
|
||||||
|
addi x25, x13, 0
|
||||||
|
|
||||||
|
# ====== 2. 波形发送内循环 ======
|
||||||
|
inner_wave_send_loop:
|
||||||
|
addi x26, x26, -1
|
||||||
|
lw x31, 0x00(x25)
|
||||||
|
lw x30, 0x04(x25)
|
||||||
|
addi x25, x25, 8
|
||||||
|
|
||||||
|
send x0 , x31, 0
|
||||||
|
|
||||||
|
bne x26, x0 , inner_wait_branch
|
||||||
|
beq x0 , x0 , outer_wait_branch
|
||||||
|
|
||||||
|
inner_wait_branch:
|
||||||
|
wait x0 , x30, -24
|
||||||
|
bne x26, x0 , inner_wave_send_loop
|
||||||
|
|
||||||
|
outer_wait_branch:
|
||||||
|
wait x0 , x30, -36
|
||||||
|
bne x28, x0 , middle_ensemble_loop
|
||||||
|
|
||||||
|
# ====== 3. 扫参结束判断 ======
|
||||||
|
# 如果 sweep_num == 0,说明当前序列已经打完,直接下班!
|
||||||
|
beq x10, x0 , mcu_exit
|
||||||
|
addi x10, x10, -1 # 否则步数 -1,准备更新参数
|
||||||
|
wait x0 , x0 , 100 # 参数切换保护死时间
|
||||||
|
|
||||||
|
# ====== 4. 硬件 ALU 更新寄存器 ======
|
||||||
|
beq x17, x0 , run_sweep_iteration # 若没配寄存器(防呆),直接进入下一轮
|
||||||
|
addi x4 , x17, 0 # 循环次数
|
||||||
|
addi x21, x18, 0 # 游标 x21 -> Offsets
|
||||||
|
addi x23, x20, 0 # 游标 x23 -> Steps
|
||||||
|
|
||||||
|
update_param_loop:
|
||||||
|
addi x4 , x4 , -1
|
||||||
|
lw x29, 0(x21) # 读 相对偏移地址 (例如 0x78)
|
||||||
|
lw x24, 0(x23) # 读 步长 Step
|
||||||
|
|
||||||
|
add x5 , x1 , x29 # x5 = DTCM中该参数的地址 (x1 + 0x78)
|
||||||
|
lw x31, 0(x5) # 从 DTCM 读出当前真值!
|
||||||
|
add x31, x31, x24 # 当前值 = 当前值 + 步长
|
||||||
|
sw x31, 0(x5) # 将新值存回 DTCM,作为下一次的基准!
|
||||||
|
|
||||||
|
add x6 , x2 , x29 # x6 = 硬件物理地址 (x2 + 0x78)
|
||||||
|
sw x31, 0(x6) # 写入硬件生效
|
||||||
|
|
||||||
|
addi x21, x21, 4 # 游标下移
|
||||||
|
addi x23, x23, 4
|
||||||
|
bne x4 , x0 , update_param_loop
|
||||||
|
|
||||||
|
# 参数更新完毕,无条件跳回上面执行新一轮波形
|
||||||
|
beq x0 , x0 , run_sweep_iteration
|
||||||
|
|
||||||
|
mcu_exit:
|
||||||
|
exit x0 , x0 , 0
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def _ramp_mcu_template(self, **kwargs):
|
||||||
|
ramp_mcu_registers = []
|
||||||
|
ramp_mcu_registers.append(0 << 16)
|
||||||
|
ramp_mcu_registers += [1 << 31]
|
||||||
|
param_num = kwargs.pop('param_num')
|
||||||
|
ensemble_num = kwargs.pop('ensemble_num')
|
||||||
|
ramp_mcu_registers.append(param_num)
|
||||||
|
ramp_mcu_registers.append(ensemble_num)
|
||||||
|
height_list = kwargs.pop('height', 0)
|
||||||
|
length_list = kwargs.pop('step_time', 0)
|
||||||
|
for height, length in zip(height_list, length_list):
|
||||||
|
ramp_mcu_registers += [height << 16]
|
||||||
|
ramp_mcu_registers += [length]
|
||||||
|
wait = 65536 / height * length
|
||||||
|
ramp_mcu_registers += [wait]
|
||||||
|
self.write_register(addr_base['DTCM0_BASE'] + reg_define['mcu_reg']['DTFR'] + 4, ramp_mcu_registers)
|
||||||
|
# todo: configre step and width first, and then enable?
|
||||||
|
return f"""
|
||||||
|
start:
|
||||||
|
lui x1 , 0x100
|
||||||
|
lui x2 , 0x200
|
||||||
|
lw x31, 0xdc(x1)
|
||||||
|
sw x31, 0xb8(x2)
|
||||||
|
lw x28, 0xe0(x1)
|
||||||
|
addi x6 , x0, 12
|
||||||
|
lw x7 , 0xe8(x1)
|
||||||
|
ensemble_loop:
|
||||||
|
addi x7 , x7, -1
|
||||||
|
addi x8 , x1, 0
|
||||||
|
lw x5 , 0xe4(x1)
|
||||||
|
ramp_loop:
|
||||||
|
addi x5, x5, -1
|
||||||
|
lw x31, 0xec(x8)
|
||||||
|
lw x30, 0xf0(x8)
|
||||||
|
lw x29, 0xf4(x8)
|
||||||
|
add x8 , x8 , x6
|
||||||
|
sw x30, 0xc0(x2)
|
||||||
|
sw x31, 0xbc(x2)
|
||||||
|
sw x28, 0xc4(x2)
|
||||||
|
wait x0 , x29, -30
|
||||||
|
bne x5 , x0 , ramp_loop
|
||||||
|
bne x7 , x0 , ensemble_loop
|
||||||
|
sw x0, 0xc4(x2)
|
||||||
|
exit x0, x0, 0
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _ramp_mcu_fixed_template(self, **kwargs):
|
||||||
|
ramp_mcu_registers = []
|
||||||
|
ramp_mcu_registers += [1 << 31] # RAMPENR
|
||||||
|
ensemble_num = kwargs.pop('ensemble_num')
|
||||||
|
config_param_num = kwargs.pop('config_param_num')
|
||||||
|
ramp_mcu_registers.append(ensemble_num)
|
||||||
|
ramp_mcu_registers.append(config_param_num)
|
||||||
|
fixed_value_list = kwargs.pop('fixed_value')
|
||||||
|
wait_list = kwargs.pop('wait_clk')
|
||||||
|
for fixed_value, wait_clk in zip(fixed_value_list, wait_list):
|
||||||
|
ramp_mcu_registers += [fixed_value << 16 | 1 << 15]
|
||||||
|
ramp_mcu_registers += [wait_clk]
|
||||||
|
self.write_register(addr_base['DTCM0_BASE'] + reg_define['mcu_reg']['DTFR'] + 4, ramp_mcu_registers)
|
||||||
|
return f"""
|
||||||
|
start:
|
||||||
|
lui x1 , 0x100
|
||||||
|
lui x2 , 0x200
|
||||||
|
lw x31, 0xdc(x1)
|
||||||
|
sw x31, 0xc4(x2)
|
||||||
|
addi x3 , x0, 8
|
||||||
|
lw x4 , 0xe0(x1)
|
||||||
|
ensemble_loop:
|
||||||
|
addi x4 , x4, -1
|
||||||
|
addi x6 , x1, 0
|
||||||
|
lw x5 , 0xe4(x1)
|
||||||
|
ramp_loop:
|
||||||
|
addi x5, x5, -1
|
||||||
|
lw x31, 0xe8(x6)
|
||||||
|
lw x30, 0xec(x6)
|
||||||
|
sw x31, 0xb8(x2)
|
||||||
|
add x6 , x6 , x3
|
||||||
|
bne x5 , x0 , ramp_loop_wait
|
||||||
|
jal x0 , ensemble_loop_wait
|
||||||
|
ramp_loop_wait:
|
||||||
|
wait x0 , x30, -24
|
||||||
|
jal x0 , ramp_loop
|
||||||
|
ensemble_loop_wait:
|
||||||
|
wait x0 , x30, -36
|
||||||
|
bne x4 , x0 , ensemble_loop
|
||||||
|
exit:
|
||||||
|
wait x0 , x0, 15
|
||||||
|
sw x0, 0xb8(x2)
|
||||||
|
sw x0, 0xc4(x2)
|
||||||
|
exit x0, x0, 0
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def _write_machine_codes_to_chip(self, machine_codes: str, **kwargs):
|
||||||
|
channel_id = kwargs.get('channel_id', 0)
|
||||||
|
self.mk_instr.write(machine_codes, self.config_file, chip_id = channel_id, show=kwargs.pop('instr_show', False))
|
||||||
|
if 'inner_sync' in kwargs:
|
||||||
|
inner_sync = kwargs.pop('inner_sync')
|
||||||
|
if inner_sync:
|
||||||
|
self.write_register(addr_base['SYST_BASE']+reg_define['sys_reg']['SYNCR'], 3<<16 | 1)
|
||||||
|
self.mk.rw_once('r', addr_base['SYST_BASE']+reg_define['pll_reg']['INTPLL_CLKRXPD'], [0]*20, self.config_file)
|
||||||
|
self.mk.rw_once('r', addr_base['DBGM_BASE'], [0]*2048, self.config_file)
|
||||||
|
|
||||||
|
def instruction_config(mk_instance, mk_instr, **kwargs):
|
||||||
|
asm_templates = AssemblyTemplateManager(mk_instance, mk_instr, **kwargs)
|
||||||
|
machine_codes = asm_templates.create_instructions(**kwargs)
|
||||||
|
asm_templates._write_machine_codes_to_chip(machine_codes, **kwargs)
|
||||||
|
|
@ -0,0 +1,252 @@
|
||||||
|
import numpy as np
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import sys
|
||||||
|
# sys.path.append('D:/Work/EnvData')
|
||||||
|
# sys.path.append('D:/Work/EnvData/acz')
|
||||||
|
# sys.path.append('D:/Work/EnvData/accz')
|
||||||
|
|
||||||
|
from typing import Any, Dict, List, Optional, Union, Callable
|
||||||
|
from enum import Enum
|
||||||
|
from env_gen.flattop import flattop
|
||||||
|
from env_gen.acz import aczwave
|
||||||
|
from env_gen.accz_gen import accz_wave
|
||||||
|
from matplotlib import gridspec
|
||||||
|
from reg_define import *
|
||||||
|
class EnvelopeGenerator:
|
||||||
|
|
||||||
|
_axes_list: List[tuple] = []
|
||||||
|
|
||||||
|
PLOT_STYLES = [
|
||||||
|
'ggplot', 'bmh', 'fivethirtyeight', 'Solarize_Light2',
|
||||||
|
'fast', 'tableau-colorblind10', 'seaborn-poster', 'seaborn-bright'
|
||||||
|
]
|
||||||
|
PLOT_COLORS = ['C0', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7']
|
||||||
|
|
||||||
|
SINGLE_PLOT_CONFIG = {
|
||||||
|
'figsize': (8, 6),
|
||||||
|
'dpi': 220,
|
||||||
|
'style': 'seaborn-v0_8-poster',
|
||||||
|
'linewidth': 3,
|
||||||
|
'fontsize': {'xlabel': 22, 'ylabel': 22, 'title': 20, 'legend': 18, 'tick': 18}
|
||||||
|
}
|
||||||
|
|
||||||
|
MULTI_PLOT_CONFIG = {
|
||||||
|
'dpi': 200,
|
||||||
|
'fontsize': {'xlabel': 18, 'ylabel': 18, 'title': 16, 'tick': 16},
|
||||||
|
'grid_alpha': 0.3
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, mk_instance, **kwargs):
|
||||||
|
self.mk = mk_instance
|
||||||
|
self.config_file = kwargs.get('config_file')
|
||||||
|
|
||||||
|
def write_register(self, address, value):
|
||||||
|
self.mk.rw_once('w', address, value, self.config_file)
|
||||||
|
|
||||||
|
|
||||||
|
# def _show_envelope_subplot(self, all_data):
|
||||||
|
# n = len(all_data)
|
||||||
|
# if n == 1:
|
||||||
|
# EnvelopeGenerator._show_single_plot(all_data[0])
|
||||||
|
# else:
|
||||||
|
# EnvelopeGenerator._show_multi_plots(all_data)
|
||||||
|
|
||||||
|
# def _show_single_plot(self, plot_data):
|
||||||
|
# t, y, title, output_mode = plot_data
|
||||||
|
# config = EnvelopeGenerator.SINGLE_PLOT_CONFIG
|
||||||
|
|
||||||
|
# plt.figure(figsize=config['figsize'], dpi=config['dpi'])
|
||||||
|
# plt.style.use(config['style'])
|
||||||
|
|
||||||
|
# plt.plot(t, y, label=f'{output_mode} Mode',
|
||||||
|
# linewidth=config['linewidth'], color=EnvelopeGenerator.PLOT_COLORS[0])
|
||||||
|
# plt.xlabel('Time (ns)', fontsize=config['fontsize']['xlabel'])
|
||||||
|
# plt.ylabel('Amplitude', fontsize=config['fontsize']['ylabel'])
|
||||||
|
# plt.title(title, fontsize=config['fontsize']['title'])
|
||||||
|
# plt.grid(True, alpha=0.6)
|
||||||
|
# plt.legend(fontsize=config['fontsize']['legend'])
|
||||||
|
# plt.tick_params(axis='both', labelsize=config['fontsize']['tick'])
|
||||||
|
# plt.tight_layout(pad=2.0)
|
||||||
|
# plt.show()
|
||||||
|
|
||||||
|
# def _show_multi_plots(self, all_data):
|
||||||
|
# n = len(all_data)
|
||||||
|
# cols = int(np.ceil(np.sqrt(n)))
|
||||||
|
# rows = int(np.ceil(n / cols))
|
||||||
|
|
||||||
|
# config = EnvelopeGenerator.MULTI_PLOT_CONFIG
|
||||||
|
# fig = plt.figure(figsize=(5 * cols, 4 * rows), dpi=config['dpi'])
|
||||||
|
# gs = gridspec.GridSpec(rows, cols)
|
||||||
|
|
||||||
|
# for i, (t, y, title, output_mode) in enumerate(all_data):
|
||||||
|
# row = i // cols
|
||||||
|
# col = i % cols
|
||||||
|
|
||||||
|
# # 为每个子图分配不同风格和颜色
|
||||||
|
# style_idx = i % len(EnvelopeGenerator.PLOT_STYLES)
|
||||||
|
# color_idx = i % len(EnvelopeGenerator.PLOT_COLORS)
|
||||||
|
|
||||||
|
# with plt.style.context(EnvelopeGenerator.PLOT_STYLES[2]):
|
||||||
|
# ax = fig.add_subplot(gs[row, col])
|
||||||
|
# ax.plot(t, y, color=EnvelopeGenerator.PLOT_COLORS[color_idx])
|
||||||
|
# ax.set_xlabel('Time (ns)', fontsize=config['fontsize']['xlabel'])
|
||||||
|
# ax.set_ylabel('Amplitude', fontsize=config['fontsize']['ylabel'])
|
||||||
|
# ax.set_title(title, fontsize=config['fontsize']['title'])
|
||||||
|
# ax.grid(True, alpha=config['grid_alpha'])
|
||||||
|
# ax.tick_params(axis='both', labelsize=config['fontsize']['tick'])
|
||||||
|
# plt.tight_layout(pad=3.0)
|
||||||
|
# plt.show()
|
||||||
|
|
||||||
|
def _generate_rect_envelope(self, **kwargs):
|
||||||
|
amp = kwargs.pop('amp')
|
||||||
|
wave_time = kwargs.pop('wave_time')
|
||||||
|
rect_wave = [amp]*wave_time
|
||||||
|
return rect_wave
|
||||||
|
|
||||||
|
def _generate_rect_hold_envelope(self, **kwargs):
|
||||||
|
amp = kwargs.pop('amp')
|
||||||
|
rect_rising_edge = [amp]*4
|
||||||
|
rect_falling_edge = [0]*4
|
||||||
|
return rect_rising_edge, rect_falling_edge
|
||||||
|
|
||||||
|
def _generate_flattop_envelope(self, **kwargs):
|
||||||
|
amp = kwargs.pop('amp')
|
||||||
|
edge_time = kwargs.pop('edge_time')
|
||||||
|
wave_time = kwargs.pop('wave_time')
|
||||||
|
flattop_wave = flattop(float(amp), float(edge_time), float(wave_time), 1.0)
|
||||||
|
return flattop_wave
|
||||||
|
|
||||||
|
def _generate_flattop_hold_envelope(self, **kwargs):
|
||||||
|
amp = kwargs.pop('amp')
|
||||||
|
edge_time = kwargs.pop('edge_time')
|
||||||
|
wave_time = kwargs.pop('wave_time')
|
||||||
|
flattop_wave = flattop(float(amp), float(edge_time), float(wave_time), 1.0)
|
||||||
|
hold_value = flattop_wave.max()
|
||||||
|
hold_idx = np.where(flattop_wave == hold_value)[0]
|
||||||
|
rising_edge_end_idx = hold_idx[0]
|
||||||
|
falling_edge_start_idx = hold_idx[-1]
|
||||||
|
flattop_rising_edge = flattop_wave[:rising_edge_end_idx+1]
|
||||||
|
flattop_falling_edge = flattop_wave[falling_edge_start_idx:-2]
|
||||||
|
return flattop_rising_edge, flattop_falling_edge
|
||||||
|
|
||||||
|
def _generate_acz_envelope(self, **kwargs):
|
||||||
|
amp = kwargs.pop('amp')
|
||||||
|
wave_time = kwargs.pop('wave_time')
|
||||||
|
acz_wave = aczwave(amp, wave_time, 0.0, 0.0, 0.0, 0.864, 0.05, -0.18, 0.04)
|
||||||
|
acz_wave_real = [val.real for val in acz_wave]
|
||||||
|
return acz_wave_real
|
||||||
|
|
||||||
|
def _generate_accz_envelope(self, **kwargs):
|
||||||
|
wave_time = kwargs.pop('wave_time')
|
||||||
|
env_accz = accz_wave(T=wave_time, A=0.8, plot=False)
|
||||||
|
return env_accz
|
||||||
|
|
||||||
|
def _cosine_envelope(self, **kwargs):
|
||||||
|
alpha = kwargs.pop('alpha', 1)
|
||||||
|
phi = kwargs.pop('phi', np.pi)
|
||||||
|
amp = kwargs.pop('amp')
|
||||||
|
wave_time = kwargs.pop('wave_time')
|
||||||
|
t_norm = np.arange(wave_time) / wave_time
|
||||||
|
cosine_wave = amp * (1 + alpha * np.cos(2 * np.pi * t_norm + phi)) / 2
|
||||||
|
return cosine_wave
|
||||||
|
|
||||||
|
def _generate_envelope_data(self, envelope_type, **kwargs):
|
||||||
|
if envelope_type == 'rect':
|
||||||
|
env_data = self._generate_rect_envelope(**kwargs)
|
||||||
|
elif envelope_type == 'rect_hold':
|
||||||
|
env_data = self._generate_rect_hold_envelope(**kwargs)
|
||||||
|
elif envelope_type == 'flattop':
|
||||||
|
env_data = self._generate_flattop_envelope(**kwargs)
|
||||||
|
elif envelope_type == 'flattop_hold':
|
||||||
|
env_data = self._generate_flattop_hold_envelope(**kwargs)
|
||||||
|
elif envelope_type == 'acz':
|
||||||
|
env_data = self._generate_acz_envelope(**kwargs)
|
||||||
|
elif envelope_type == 'accz':
|
||||||
|
env_data = self._generate_accz_envelope(**kwargs)
|
||||||
|
elif envelope_type == 'cosine':
|
||||||
|
env_data = self._cosine_envelope(**kwargs)
|
||||||
|
elif envelope_type == 'file_read_direct':
|
||||||
|
env_data = kwargs.get('external_envelope_data', [])
|
||||||
|
elif envelope_type == 'file_read_txt':
|
||||||
|
file_path = kwargs.get('file_path')
|
||||||
|
if file_path is None:
|
||||||
|
raise ValueError("Missing 'file_path'")
|
||||||
|
|
||||||
|
txt_data = np.loadtxt(file_path)
|
||||||
|
env_data = np.asarray(txt_data, dtype=float).reshape(-1).tolist()
|
||||||
|
return env_data
|
||||||
|
|
||||||
|
def _next_env_idx(self, idx_num, env_idx_mem, envelope_length):
|
||||||
|
if idx_num == 0:
|
||||||
|
return envelope_length
|
||||||
|
else:
|
||||||
|
last_env_idx = env_idx_mem[-1]
|
||||||
|
env_base_addr = (last_env_idx >> 16) + ((last_env_idx & 0xFFFF) << 1)
|
||||||
|
return env_base_addr<<16 | envelope_length
|
||||||
|
|
||||||
|
def _env_data_pack(self, float_data_array):
|
||||||
|
|
||||||
|
data_int = np.round(float_data_array).astype(int)
|
||||||
|
data_int[data_int < 0] += 65536
|
||||||
|
hex_pairs = []
|
||||||
|
for data0, data1 in zip(data_int[::2], data_int[1::2]):
|
||||||
|
hex_pairs.append((data1 << 16) | data0)
|
||||||
|
|
||||||
|
return hex_pairs
|
||||||
|
|
||||||
|
def _generate_envelope_batch(self, **kwargs):
|
||||||
|
envelope_configs = kwargs.pop('envelope_configs')
|
||||||
|
env_data_mem = []
|
||||||
|
env_idx_mem = []
|
||||||
|
idx_num = 0
|
||||||
|
for envelope_config in envelope_configs:
|
||||||
|
envelope_type = envelope_config.pop('envelope_type')
|
||||||
|
env_data = self._generate_envelope_data(envelope_type, **envelope_config)
|
||||||
|
if isinstance(env_data, tuple):
|
||||||
|
retun_param_count = len(env_data)
|
||||||
|
else:
|
||||||
|
retun_param_count = 1
|
||||||
|
if retun_param_count == 1:
|
||||||
|
envelope = env_data
|
||||||
|
envelope_arr = np.asarray(envelope, dtype=float).reshape(-1)
|
||||||
|
if envelope_arr.size % 4 != 0:
|
||||||
|
raise ValueError("Envelope length must be multiple of 4")
|
||||||
|
env_data_mem += envelope_arr.astype(int).tolist()
|
||||||
|
envelope_length = int(envelope_arr.size)
|
||||||
|
current_env_idx = self._next_env_idx(idx_num, env_idx_mem, envelope_length)
|
||||||
|
env_idx_mem.append(current_env_idx)
|
||||||
|
idx_num += 1
|
||||||
|
elif retun_param_count == 2:
|
||||||
|
rising_edge, falling_edge = env_data
|
||||||
|
rising_edge_arr = np.asarray(rising_edge, dtype=float).reshape(-1)
|
||||||
|
falling_edge_arr = np.asarray(falling_edge, dtype=float).reshape(-1)
|
||||||
|
if rising_edge_arr.size % 4 != 0:
|
||||||
|
raise ValueError("Envelope length must be multiple of 4")
|
||||||
|
env_data_mem += rising_edge_arr.astype(int).tolist()
|
||||||
|
rising_edge_length = int(rising_edge_arr.size)
|
||||||
|
rising_edge_idx = self._next_env_idx(idx_num, env_idx_mem, rising_edge_length)
|
||||||
|
env_idx_mem.append(rising_edge_idx)
|
||||||
|
idx_num += 1
|
||||||
|
env_data_mem += falling_edge_arr.astype(int).tolist()
|
||||||
|
falling_edge_length = int(falling_edge_arr.size)
|
||||||
|
falling_edge_idx = self._next_env_idx(idx_num, env_idx_mem, falling_edge_length)
|
||||||
|
env_idx_mem.append(falling_edge_idx)
|
||||||
|
idx_num += 1
|
||||||
|
|
||||||
|
env2mem_format = self._env_data_pack(env_data_mem)
|
||||||
|
self.write_register(addr_base['ENVI0_BASE'], env_idx_mem)
|
||||||
|
self.write_register(addr_base['ENVM0_BASE'], env2mem_format)
|
||||||
|
# t = np.arange(len(processed_data)) / 3e9 * 1e9
|
||||||
|
# EnvelopeGenerator._axes_list.append((t, processed_data, f'Processed Envelope - {output_mode} Mode', output_mode))
|
||||||
|
# def _im_show(self, **kwargs):
|
||||||
|
# EnvelopeGenerator._axes_list = []
|
||||||
|
|
||||||
|
# if EnvelopeGenerator._axes_list:
|
||||||
|
# EnvelopeGenerator.show_envelope_subplot(EnvelopeGenerator._axes_list)
|
||||||
|
# EnvelopeGenerator._axes_list = []
|
||||||
|
def env_config(mk_instance, **kwargs):
|
||||||
|
env_gen = EnvelopeGenerator(mk_instance, **kwargs)
|
||||||
|
env_gen._generate_envelope_batch(**kwargs)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
class ParamsManager:
|
||||||
|
|
||||||
|
def __init__(self, params_dir='params'):
|
||||||
|
self.params_dir = params_dir
|
||||||
|
self._ensure_dir_exists()
|
||||||
|
|
||||||
|
def _ensure_dir_exists(self):
|
||||||
|
Path(self.params_dir).mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
def save(self, params, filename):
|
||||||
|
if not filename.endswith('.json'):
|
||||||
|
filename = filename + '.json'
|
||||||
|
|
||||||
|
filepath = os.path.join(self.params_dir, filename)
|
||||||
|
|
||||||
|
with open(filepath, 'w', encoding='utf-8') as f:
|
||||||
|
json.dump(params, f, indent=2, ensure_ascii=False)
|
||||||
|
|
||||||
|
def load(self, filename):
|
||||||
|
if not filename.endswith('.json'):
|
||||||
|
filename = filename + '.json'
|
||||||
|
|
||||||
|
filepath = os.path.join(self.params_dir, filename)
|
||||||
|
|
||||||
|
with open(filepath, 'r', encoding='utf-8') as f:
|
||||||
|
params = json.load(f)
|
||||||
|
return params
|
||||||
|
|
||||||
|
def save_multiple(self, params_dict):
|
||||||
|
filepaths = []
|
||||||
|
for filename, params in params_dict.items():
|
||||||
|
filepath = self.save(params, filename)
|
||||||
|
filepaths.append(filepath)
|
||||||
|
return filepaths
|
||||||
|
|
||||||
|
def load_multiple(self, filenames):
|
||||||
|
result = {}
|
||||||
|
for filename in filenames:
|
||||||
|
result[filename] = self.load(filename)
|
||||||
|
return result
|
||||||
|
|
||||||
|
# from ParamsManager import ParamsManager
|
||||||
|
|
||||||
|
# # 创建参数管理器实例
|
||||||
|
# pm = ParamsManager('params') # 参数保存在 params 文件夹中
|
||||||
|
|
||||||
|
# # 保存单个参数
|
||||||
|
# pm.save(params, 'AWG_NCO') # 自动添加 .json 后缀
|
||||||
|
|
||||||
|
# # 加载单个参数
|
||||||
|
# params = pm.load('AWG_NCO')
|
||||||
|
|
@ -0,0 +1,366 @@
|
||||||
|
import numpy as np
|
||||||
|
import os
|
||||||
|
from reg_define import *
|
||||||
|
|
||||||
|
|
||||||
|
class ZChipConfig(object):
|
||||||
|
CHANNEL_OFFSET = 0x00600000
|
||||||
|
SCALE_FACTOR = 2 ** 31
|
||||||
|
|
||||||
|
def __init__(self, mk_instance, channel_id=0, **kwargs):
|
||||||
|
self.mk = mk_instance
|
||||||
|
self.channel_id = channel_id
|
||||||
|
self.FolderName = kwargs.get('FolderName')
|
||||||
|
self.config_file = kwargs.get('config_file')
|
||||||
|
self._setup_environment()
|
||||||
|
self._init_logger()
|
||||||
|
|
||||||
|
def _setup_environment(self):
|
||||||
|
if self.FolderName:
|
||||||
|
os.makedirs(self.FolderName, exist_ok=True)
|
||||||
|
if self.config_file and os.path.exists(self.config_file):
|
||||||
|
os.remove(self.config_file)
|
||||||
|
|
||||||
|
def _init_logger(self):
|
||||||
|
import logging
|
||||||
|
self.logger = logging.getLogger(f"ChipConfig.ch{self.channel_id}")
|
||||||
|
if not self.logger.handlers:
|
||||||
|
handler = logging.StreamHandler()
|
||||||
|
formatter = logging.Formatter(
|
||||||
|
'%(name)s - %(levelname)s - %(message)s')
|
||||||
|
handler.setFormatter(formatter)
|
||||||
|
self.logger.addHandler(handler)
|
||||||
|
self.logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
def get_channel_addr(self, base_addr):
|
||||||
|
if isinstance(base_addr, str):
|
||||||
|
if base_addr.startswith('0x'):
|
||||||
|
base_addr = int(base_addr, 16)
|
||||||
|
else:
|
||||||
|
base_addr = int(base_addr)
|
||||||
|
|
||||||
|
if not hasattr(self, '_channel_offset'):
|
||||||
|
self._channel_offset = self.CHANNEL_OFFSET * self.channel_id
|
||||||
|
|
||||||
|
return hex(base_addr + self._channel_offset)
|
||||||
|
|
||||||
|
def _configure_tc_mode(self):
|
||||||
|
"""配置TC模式 - 分组配置系数"""
|
||||||
|
# self.logger.info(
|
||||||
|
# "Configuring TC mode with group-wise coefficient setup")
|
||||||
|
|
||||||
|
# 写入TC_BYPASS
|
||||||
|
self.write_register(
|
||||||
|
self.get_register_addr('BYPASS'),
|
||||||
|
self.REGISTER_VALUES['BYPASS_TC']
|
||||||
|
)
|
||||||
|
|
||||||
|
# 计算TC系数
|
||||||
|
coefficients = self._calculate_tc_coefficients()
|
||||||
|
|
||||||
|
# 分组配置TC系数并设置配置完成标志
|
||||||
|
self._configure_tc_coefficients_by_groups(coefficients)
|
||||||
|
|
||||||
|
# self.logger.info("TC mode configuration completed")
|
||||||
|
|
||||||
|
def _configure_tc_coefficients_by_groups(self, coefficients):
|
||||||
|
"""分组配置TC系数,每组配置完成后设置对应的配置完成标志"""
|
||||||
|
|
||||||
|
# 定义7个系数组,每组包含一个系数的4个寄存器(alpha_re, alpha_im, beta_re, beta_im)
|
||||||
|
tc_register_groups = self._build_tc_register_groups(coefficients)
|
||||||
|
|
||||||
|
for group_idx, group_registers in enumerate(tc_register_groups):
|
||||||
|
# 配置当前组的所有寄存器
|
||||||
|
# self.logger.info(f"配置系数组 {group_idx}")
|
||||||
|
self.write_registers_batch(group_registers)
|
||||||
|
|
||||||
|
# 设置当前组的配置完成标志
|
||||||
|
self._set_coef_config_done_for_group(group_idx)
|
||||||
|
|
||||||
|
# self.logger.info(f"系数组 {group_idx} 配置完成")
|
||||||
|
|
||||||
|
def set_tc_coefficient_set(self, coeff_set_name):
|
||||||
|
"""设置要使用的TC系数组"""
|
||||||
|
if coeff_set_name not in self.TC_COEFFICIENT_SETS:
|
||||||
|
available = list(self.TC_COEFFICIENT_SETS.keys())
|
||||||
|
raise ValueError(f"未知的系数组: {coeff_set_name}. 可用的系数组: {available}")
|
||||||
|
|
||||||
|
self.tc_coeff_set = coeff_set_name
|
||||||
|
# self.logger.info(
|
||||||
|
# f"切换到TC系数组: {coeff_set_name} - {self.TC_COEFFICIENT_SETS[coeff_set_name]['description']}")
|
||||||
|
|
||||||
|
def _calculate_tc_coefficients(self, **kwargs):
|
||||||
|
tc_coef_set = kwargs.pop('tc_coef_set')
|
||||||
|
coef_set = TC_COEFFICIENT_SETS[tc_coef_set]
|
||||||
|
|
||||||
|
amp_real = coef_set['amp_real']
|
||||||
|
amp_imag = coef_set['amp_imag']
|
||||||
|
time_real = coef_set['time_real']
|
||||||
|
time_imag = coef_set['time_imag']
|
||||||
|
|
||||||
|
sampling_rate = 3e9
|
||||||
|
coef1, coef2 = [], []
|
||||||
|
for ar, ai, tr, ti in zip(amp_real, amp_imag, time_real, time_imag):
|
||||||
|
amp_coef = ar + 1j * ai
|
||||||
|
time_coef = tr + 1j * ti
|
||||||
|
coef1.append(amp_coef * np.exp(1e9 / (sampling_rate) / 2 / (1 - amp_coef) * time_coef) /
|
||||||
|
(1 - amp_coef))
|
||||||
|
coef2.append(np.exp(1e9 / (sampling_rate) / (1 - amp_coef) * time_coef))
|
||||||
|
# print('coef1_real = ')
|
||||||
|
# for c in coef1:
|
||||||
|
# print(c.real)
|
||||||
|
# # print(hex(int(c.real*(2**31-1)) & 0xFFFFFFFF))
|
||||||
|
# print('coef1_imag = ')
|
||||||
|
# for c in coef1:
|
||||||
|
# # print(hex(int(c.imag*(2**31-1)) & 0xFFFFFFFF))
|
||||||
|
# print(c.imag)
|
||||||
|
# print('coef2_real = ')
|
||||||
|
# for c in coef2:
|
||||||
|
# # print(hex(int(c.real*(2**31-1)) & 0xFFFFFFFF))
|
||||||
|
# print(c.real)
|
||||||
|
# print('coef2_imag = ')
|
||||||
|
# for c in coef2:
|
||||||
|
# # print(hex(int(c.imag*(2**31-1)) & 0xFFFFFFFF))
|
||||||
|
# print(c.imag)
|
||||||
|
return {
|
||||||
|
'alpha_re': [int(c.real * self.SCALE_FACTOR) for c in coef1],
|
||||||
|
'alpha_im': [int(c.imag * self.SCALE_FACTOR) for c in coef1],
|
||||||
|
'beta_re': [int(c.real * self.SCALE_FACTOR) for c in coef2],
|
||||||
|
'beta_im': [int(c.imag * self.SCALE_FACTOR) for c in coef2]
|
||||||
|
}
|
||||||
|
|
||||||
|
def _build_tc_register_groups(self, coefficients):
|
||||||
|
"""构建分组的TC寄存器配置"""
|
||||||
|
tc_register_groups = []
|
||||||
|
|
||||||
|
# 获取所有寄存器地址
|
||||||
|
alpha_re_addrs = self.get_register_addr('TC_ALPHA_RE')
|
||||||
|
alpha_im_addrs = self.get_register_addr('TC_ALPHA_IM')
|
||||||
|
beta_re_addrs = self.get_register_addr('TC_BETA_RE')
|
||||||
|
beta_im_addrs = self.get_register_addr('TC_BETA_IM')
|
||||||
|
|
||||||
|
# 按组分配寄存器(假设有8个系数,但只使用前7组)
|
||||||
|
num_groups = len(coefficients['alpha_re'])
|
||||||
|
|
||||||
|
for i in range(num_groups):
|
||||||
|
group_registers = [
|
||||||
|
(alpha_re_addrs[i], coefficients['alpha_re'][i]),
|
||||||
|
(alpha_im_addrs[i], coefficients['alpha_im'][i]),
|
||||||
|
(beta_re_addrs[i], coefficients['beta_re'][i]),
|
||||||
|
(beta_im_addrs[i], coefficients['beta_im'][i])
|
||||||
|
]
|
||||||
|
tc_register_groups.append(group_registers)
|
||||||
|
|
||||||
|
return tc_register_groups
|
||||||
|
|
||||||
|
def _set_coef_config_done_for_group(self, group_idx):
|
||||||
|
"""为指定组设置配置完成标志"""
|
||||||
|
if not (0 <= group_idx <= 7): # 8组,索引0-7
|
||||||
|
self.logger.warning(f"无效的组索引: {group_idx}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 计算当前组的配置完成标志值:2^group_idx
|
||||||
|
config_done_value = 1 << group_idx
|
||||||
|
config_done_hex = f'0x{config_done_value:02x}'
|
||||||
|
|
||||||
|
# 读取当前配置完成寄存器的值,进行或运算以保留其他组的标志
|
||||||
|
try:
|
||||||
|
# 如果需要保留其他组的标志,这里需要先读取当前值
|
||||||
|
# current_value = self._read_register(self.get_register_addr('COEF_CONFIG_DONE'))
|
||||||
|
# new_value = current_value | config_done_value
|
||||||
|
|
||||||
|
# 简化版本:直接写入当前组的标志
|
||||||
|
self.write_register(
|
||||||
|
self.get_register_addr('COEF_CONFIG_DONE'),
|
||||||
|
config_done_hex
|
||||||
|
)
|
||||||
|
|
||||||
|
# self.logger.info(f"系数组 {group_idx} 配置完成标志已设置: {config_done_hex}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"设置系数组 {group_idx} 配置完成标志失败: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
def write_registers_batch(self, register_values):
|
||||||
|
"""
|
||||||
|
批量写入寄存器
|
||||||
|
|
||||||
|
参数:
|
||||||
|
register_values: [(address, value), ...] 或 {address: value, ...}
|
||||||
|
"""
|
||||||
|
if isinstance(register_values, dict):
|
||||||
|
register_values = register_values.items()
|
||||||
|
|
||||||
|
for address, value in register_values:
|
||||||
|
try:
|
||||||
|
self.mk.rw_once('w', address, value, self.config_file)
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"Failed to write register {address}: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
def write_register(self, address, value):
|
||||||
|
"""写入单个寄存器"""
|
||||||
|
try:
|
||||||
|
self.mk.rw_once('w', address, value, self.config_file)
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"Failed to write register {address}: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def _freq2hex(self, freq):
|
||||||
|
fs = 750
|
||||||
|
fcw = int(freq / fs / 4 * 2 ** 32)
|
||||||
|
return int(fcw)
|
||||||
|
|
||||||
|
def _deg2hex(self, deg):
|
||||||
|
return int(deg / 360 * (2 ** 16 - 1))
|
||||||
|
|
||||||
|
# def _system_reg_config(self, **kwargs):
|
||||||
|
# 中断屏蔽寄存器
|
||||||
|
# mk_instance.rw_once('w', '0x14', '0x10000000', config.config_file)
|
||||||
|
|
||||||
|
def _general_reg_config(self, **kwargs):
|
||||||
|
ctrl_registers = []
|
||||||
|
# 自定义寄存器配置支持(元组/字典/列表三种格式)
|
||||||
|
if 'custom_registers' in kwargs:
|
||||||
|
custom_registers = kwargs.pop('custom_registers')
|
||||||
|
first_item = custom_registers[0]
|
||||||
|
# 元组格式:[(addr, val), ...] 批量写入
|
||||||
|
if isinstance(first_item, tuple):
|
||||||
|
self.write_registers_batch(custom_registers)
|
||||||
|
# 字典格式:[{"addr": addr, "values": val}, ...] 单条写入
|
||||||
|
elif isinstance(first_item, dict):
|
||||||
|
for item in custom_registers:
|
||||||
|
addr = item['addr']
|
||||||
|
values = item['values']
|
||||||
|
self.write_register(addr, values)
|
||||||
|
# 列表格式:[[addr, val], ...] 单条写入
|
||||||
|
elif isinstance(first_item, list):
|
||||||
|
for item in custom_registers:
|
||||||
|
addr = item[0]
|
||||||
|
values = item[1]
|
||||||
|
self.write_register(addr, values)
|
||||||
|
|
||||||
|
# 芯片工作模式配置
|
||||||
|
if 'chip_mode' in kwargs:
|
||||||
|
# TODO: 部分模式可以合并,双频点与单音NCO
|
||||||
|
chip_mode = kwargs.pop('chip_mode')
|
||||||
|
if chip_mode == 'RAMP':
|
||||||
|
self._ramp_config(**kwargs)
|
||||||
|
elif chip_mode == 'AWG':
|
||||||
|
self._awg_config(**kwargs)
|
||||||
|
def _ramp_config(self, **kwargs):
|
||||||
|
self.write_register(addr_base['CTRL0_BASE'] + reg_define['ctrl_reg']['MODDOTR'], 8) # 切换到RAMP输出
|
||||||
|
ramp_ctrl = kwargs.pop('ramp_ctrl')
|
||||||
|
if ramp_ctrl == 'MCU': # RAMP连到 mcu_regfile
|
||||||
|
self.write_register(addr_base['CTRL0_BASE'] + reg_define['ctrl_reg']['SPI_RAMPENR'], 1 << 30)
|
||||||
|
# 之后来用汇编操作RAMP四个参数寄存器
|
||||||
|
elif ramp_ctrl == 'SPI': # RAMP连到 ctrl_regfile
|
||||||
|
ramp_spi_registers = []
|
||||||
|
fixed_enable = kwargs.pop('fixed_enable')
|
||||||
|
if fixed_enable: # 打开固定值使能位,把值填进去就好
|
||||||
|
fixed_value = kwargs.pop('fixed_value')
|
||||||
|
ramp_spi_registers += [1 << 15 | fixed_value << 16]
|
||||||
|
self.write_register(addr_base['CTRL0_BASE'] + reg_define['ctrl_reg']['SPI_RAMPFIXR'], # 常数寄存器
|
||||||
|
ramp_spi_registers)
|
||||||
|
else:
|
||||||
|
ramp_spi_registers += [0 << 15] # 不是固定值模式,常数寄存器给0就好
|
||||||
|
height = kwargs.pop('height', 0)
|
||||||
|
length = kwargs.pop('step_time', 0)
|
||||||
|
ramp_spi_registers += [height << 16]
|
||||||
|
ramp_spi_registers += [length]
|
||||||
|
self.write_register(addr_base['CTRL0_BASE'] + reg_define['ctrl_reg']['SPI_RAMPFIXR'],
|
||||||
|
ramp_spi_registers)
|
||||||
|
# 必须最后配使能
|
||||||
|
self.write_register(addr_base['CTRL0_BASE'] + reg_define['ctrl_reg']['SPI_RAMPENR'], 1 << 31 | 0 << 30)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def _awg_config(self, **kwargs):
|
||||||
|
#数据选择寄存器300108配置开始
|
||||||
|
# 模式与寄存器数值的映射字典 (Bit 2 和 Bit[1:0])
|
||||||
|
mode_map = {
|
||||||
|
'nco': 6,
|
||||||
|
'nco_fm': 7,
|
||||||
|
'env': 4,
|
||||||
|
'mod': 5
|
||||||
|
}
|
||||||
|
# 1. 在内存中先计算 mode 对应的基础寄存器值
|
||||||
|
mode = kwargs.pop('mode', None)
|
||||||
|
moddotr_val = mode_map.get(mode, 0) # 如果 mode 不在字典里,默认基础值为 0
|
||||||
|
# 2. DSP(拖尾矫正)开关配置
|
||||||
|
tail_en = kwargs.pop('tail_en', False)
|
||||||
|
if tail_en:
|
||||||
|
coefficients = self._calculate_tc_coefficients(**kwargs)
|
||||||
|
# 拼接系数列表
|
||||||
|
tc_coef_registers = (
|
||||||
|
coefficients['alpha_re'] +
|
||||||
|
coefficients['alpha_im'] +
|
||||||
|
coefficients['beta_re'] +
|
||||||
|
coefficients['beta_im']
|
||||||
|
)
|
||||||
|
self.write_register(addr_base['TCCO0_BASE'] + reg_define['tc_reg']['TCPARR0'], tc_coef_registers)
|
||||||
|
tccdr_addr = addr_base['TCCO0_BASE'] + reg_define['tc_reg']['TCCDR']
|
||||||
|
for i in range(8):
|
||||||
|
self.write_register(tccdr_addr, 1 << i)
|
||||||
|
# 如果开启了 tail_en,在内存里直接给第 4 位 (Bit 3) 置 1
|
||||||
|
moddotr_val &= ~4 #把[2]变0
|
||||||
|
|
||||||
|
# 3. 所有逻辑判断完毕后,只触发一次物理写操作!
|
||||||
|
moddotr_addr = addr_base['CTRL0_BASE'] + reg_define['ctrl_reg']['MODDOTR']
|
||||||
|
self.write_register(moddotr_addr, moddotr_val)
|
||||||
|
|
||||||
|
#调制使能寄存器300104配置开始
|
||||||
|
amp_mod_enable = kwargs.pop('amp_mod_enSable', False)
|
||||||
|
freq_mod_enable = kwargs.pop('freq_mod_enable', False)
|
||||||
|
bias_enable = kwargs.pop('bias_enable', False)
|
||||||
|
# 低电平使能逻辑:True(开启) -> 0,False(关闭) -> 1
|
||||||
|
mod_enable = (
|
||||||
|
(int(not bias_enable) << 0) # Bit 0: Bias (低电平有效)
|
||||||
|
| (int(not freq_mod_enable) << 1) # Bit 1: Freq (加括号,先取非再左移 1 位)
|
||||||
|
| (int(not amp_mod_enable) << 2) # Bit 2: Amp (加括号,先取非再左移 2 位)
|
||||||
|
)
|
||||||
|
self.write_register(addr_base['CTRL0_BASE'] + reg_define['ctrl_reg']['MODENR'], mod_enable)
|
||||||
|
|
||||||
|
#mcu_regfile配置开始
|
||||||
|
mcu_registers = []
|
||||||
|
fcw_list = kwargs.pop('fcw', 0)
|
||||||
|
mcu_reg_clr = kwargs.pop('mcu_reg_clr', 0)
|
||||||
|
pcw_list = kwargs.pop('pcw', 0)
|
||||||
|
fcw = int(fcw_list[0] / fs / 4 * 2 ** 32)
|
||||||
|
for fcw in fcw_list:
|
||||||
|
mcu_registers.append(int(fcw / fs / 4 * 2 ** 32))
|
||||||
|
if mcu_reg_clr:
|
||||||
|
mcu_registers += [1 << 31]
|
||||||
|
else:
|
||||||
|
mcu_registers += [0 << 31]
|
||||||
|
for pcw in pcw_list:
|
||||||
|
mcu_registers.append(int(pcw / 360 * (2 ** 16 - 1)) << 16)
|
||||||
|
rz_pha = kwargs.pop('rz_pha', 0)
|
||||||
|
mcu_registers.append(int(rz_pha / 360 * (2 ** 16 - 1)))
|
||||||
|
#幅度
|
||||||
|
ff_amp_list = kwargs.pop('ff_amp', 0)
|
||||||
|
fm_amp_list = kwargs.pop('fm_amp', 0)
|
||||||
|
for ff, fm in zip(ff_amp_list, fm_amp_list):
|
||||||
|
mcu_registers.append(((ff & 0xFFFF) << 16) | (fm & 0xFFFF))
|
||||||
|
#偏置
|
||||||
|
bias_list = kwargs.pop('bias', 0)
|
||||||
|
for bias in bias_list:
|
||||||
|
mcu_registers.append(bias << 16)
|
||||||
|
self.write_register(addr_base['DTCM0_BASE'] + reg_define['mcu_reg']['CWFR0'], mcu_registers)
|
||||||
|
#FMER
|
||||||
|
fm_en = kwargs.pop('fm_en', False)
|
||||||
|
if fm_en:
|
||||||
|
self.write_register(addr_base['DTCM0_BASE'] + reg_define['mcu_reg']['FMER'], 1 << 31)
|
||||||
|
elif not fm_en:
|
||||||
|
self.write_register(addr_base['DTCM0_BASE'] + reg_define['mcu_reg']['FMER'], 0 << 31)
|
||||||
|
#mcu_regfile配置到此完成
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def config_chip_reg(mk_instance, **kwargs):
|
||||||
|
config = ZChipConfig(mk_instance, **kwargs)
|
||||||
|
config._general_reg_config(**kwargs)
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,28 @@
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
# accz
|
||||||
|
T = 100 # ns
|
||||||
|
A = 0.8 # 归一化幅度
|
||||||
|
P = 0.16
|
||||||
|
omega_d = 100e6 # Hz
|
||||||
|
theta = 0
|
||||||
|
a2 = 0.1
|
||||||
|
phi = 0
|
||||||
|
sample_rate = 1e9 # Hz
|
||||||
|
|
||||||
|
N = int(100 / (1/sample_rate * 1e9)) # 采样点个数
|
||||||
|
A = A * 2**15
|
||||||
|
|
||||||
|
# 包络函数
|
||||||
|
t = np.linspace(0, N, N+1)
|
||||||
|
env = A/(np.sqrt(1 + P**2)) * (np.sin(np.pi * t / N) + P * np.sin(3*np.pi * t / N))
|
||||||
|
|
||||||
|
# 载波调制
|
||||||
|
f = env * (np.cos(omega_d * t + theta) + a2 * np.cos(2*omega_d*t + 2*theta + phi))
|
||||||
|
fint16 = np.int16(f)
|
||||||
|
#np.savetxt(r'D:\SynologyDrive\SynologyDrive\Work\SQC2.1\gene_wave_on_board\code\acczdata.txt',fint16,'%d')
|
||||||
|
|
||||||
|
plt.figure()
|
||||||
|
plt.plot(t,fint16)
|
||||||
|
plt.show()
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
def accz_wave(T=100, A=0.8, P=0.16, omega_d=100e6, theta=0, a2=0.1, phi=0, sample_rate=1e9, plot=False):
|
||||||
|
N = int(T / (1/sample_rate * 1e9))
|
||||||
|
A_scaled = A * 2**15
|
||||||
|
t = np.linspace(0, N, N)
|
||||||
|
env = A_scaled/(np.sqrt(1 + P**2)) * (np.sin(np.pi * t / N) + P * np.sin(3*np.pi * t / N))
|
||||||
|
f = env * (np.cos(omega_d * t + theta) + a2 * np.cos(2*omega_d*t + 2*theta + phi))
|
||||||
|
fint16 = np.int16(f)
|
||||||
|
if plot:
|
||||||
|
plt.figure()
|
||||||
|
plt.plot(t, env)
|
||||||
|
plt.show()
|
||||||
|
return env
|
||||||
|
|
||||||
|
# 示例:外部调用
|
||||||
|
# env = accz_wave(T=200, A=1.0, plot=True)
|
||||||
|
# print(env)
|
||||||
|
|
@ -0,0 +1,208 @@
|
||||||
|
import numpy as np
|
||||||
|
import math
|
||||||
|
from typing import List
|
||||||
|
import os
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
class Interp1d:
|
||||||
|
def __init__(self, xs : List[float], ys : List[float]):
|
||||||
|
xs, ys = np.array(xs), np.array(ys)
|
||||||
|
# ascending order
|
||||||
|
inds = np.argsort(xs)
|
||||||
|
self.xs, self.ys = xs[inds], ys[inds]
|
||||||
|
self.len = len(self.xs)
|
||||||
|
|
||||||
|
def __call__(self, x):
|
||||||
|
lowerboundp = 0
|
||||||
|
# optain the lowerbound
|
||||||
|
for i, xi in enumerate(self.xs):
|
||||||
|
if x >= xi:
|
||||||
|
lowerboundp = i
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
if lowerboundp < self.len - 1:
|
||||||
|
upperboundp = lowerboundp + 1
|
||||||
|
else:
|
||||||
|
lowerboundp, upperboundp = self.len - 2, self.len - 1
|
||||||
|
|
||||||
|
x0, y0, x1, y1 = self.xs[lowerboundp], self.ys[lowerboundp], self.xs[upperboundp], self.ys[upperboundp]
|
||||||
|
if x1 == x0:
|
||||||
|
return (y0 + y1) / 2.0
|
||||||
|
|
||||||
|
return y0 + (x-x0)/(x1-x0)*(y1-y0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def linspace(start : float, end : float, n : int):
|
||||||
|
samples = []
|
||||||
|
step = (end - start) / (n-1)
|
||||||
|
for i in range(n):
|
||||||
|
samples.append(start + float(i)*step)
|
||||||
|
return samples
|
||||||
|
|
||||||
|
def zeros(n : int):
|
||||||
|
return [0] * n
|
||||||
|
|
||||||
|
def aczwave(amplitude : float, length : int,
|
||||||
|
carrierFreq : float, carrierPhase : float, dragAlpha : float,
|
||||||
|
thf : float, thi : float, lam2 : float, lam3 : float):
|
||||||
|
|
||||||
|
t = linspace(0, 1, length)
|
||||||
|
han2 = []
|
||||||
|
for k, x in enumerate(t):
|
||||||
|
han2.append(
|
||||||
|
(1-lam3)*(1-math.cos(2.0*math.pi*x)) +
|
||||||
|
lam2*(1-math.cos(4*math.pi*x)) +
|
||||||
|
lam3*(1-math.cos(6*math.pi*x))
|
||||||
|
)
|
||||||
|
maxHan2 = max(han2)
|
||||||
|
|
||||||
|
ths1 = []
|
||||||
|
for k in range(length):
|
||||||
|
ths1.append(
|
||||||
|
thi + (thf-thi)*han2[k]/maxHan2
|
||||||
|
)
|
||||||
|
t1u = zeros(length)
|
||||||
|
for k, v in enumerate(t1u):
|
||||||
|
if k < (length - 1):
|
||||||
|
t1u[k+1] = v + math.sin(ths1[k])/float(length-1)
|
||||||
|
|
||||||
|
for k, v in enumerate(t):
|
||||||
|
t[k] = v * t1u[length-1]
|
||||||
|
|
||||||
|
th = Interp1d(t1u, ths1)
|
||||||
|
th0 = 1.0 / math.tan(th(t[0]))
|
||||||
|
|
||||||
|
thval = []
|
||||||
|
for k in range(length):
|
||||||
|
thval.append(
|
||||||
|
1.0/math.tan(th(t[k])) - th0
|
||||||
|
)
|
||||||
|
thmin = min(thval)
|
||||||
|
|
||||||
|
samples = []
|
||||||
|
for k in range(length):
|
||||||
|
env = thval[k] * amplitude / thmin
|
||||||
|
samples.append(complex(env, 0))
|
||||||
|
|
||||||
|
return samples
|
||||||
|
|
||||||
|
|
||||||
|
def test():
|
||||||
|
amplitude = 26214
|
||||||
|
length = 30
|
||||||
|
carrierFreq = 0
|
||||||
|
carrierPhase = 0.000000
|
||||||
|
dragAlpha = 0.000000
|
||||||
|
thf = 0.864
|
||||||
|
thi = 0.05
|
||||||
|
lam2 = -0.18
|
||||||
|
lam3 = 0.04
|
||||||
|
|
||||||
|
data = aczwave(
|
||||||
|
amplitude, length, carrierFreq,
|
||||||
|
carrierPhase, dragAlpha,
|
||||||
|
thf, thi, lam2, lam3,
|
||||||
|
)
|
||||||
|
for c in data:
|
||||||
|
print(c.real, c.imag)
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
class Benchmark:
|
||||||
|
def __init__(self, num_samplings : int):
|
||||||
|
self.data_dir = "data"
|
||||||
|
self.num_samplings = num_samplings
|
||||||
|
self.params_dict = {}
|
||||||
|
self.gt_dict = {}
|
||||||
|
self.load_params()
|
||||||
|
self.load_gt()
|
||||||
|
|
||||||
|
def load_params(self):
|
||||||
|
for i in range(self.num_samplings):
|
||||||
|
file = os.path.join(self.data_dir, "aczgo_param_{}.log".format(i))
|
||||||
|
with open(file, 'r') as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
params = {}
|
||||||
|
for line in lines:
|
||||||
|
key, value = line.split(", ")
|
||||||
|
if key=="length":
|
||||||
|
value = int(value)
|
||||||
|
else:
|
||||||
|
value = float(value)
|
||||||
|
params[key] = value
|
||||||
|
|
||||||
|
self.params_dict[i] = params
|
||||||
|
|
||||||
|
def eval(self, idx):
|
||||||
|
params = self.params_dict[idx]
|
||||||
|
|
||||||
|
amplitude = params["amplitude"]
|
||||||
|
length = params["length"]
|
||||||
|
carrierFreq = params["carrierFreq"]
|
||||||
|
carrierPhase = params["carrierPhase"]
|
||||||
|
dragAlpha = params["dragAlpha"]
|
||||||
|
thf = params["thf"]
|
||||||
|
thi = params["thi"]
|
||||||
|
lam2 = params["lam2"]
|
||||||
|
lam3 = params["lam3"]
|
||||||
|
|
||||||
|
data = aczwave(
|
||||||
|
amplitude, length, carrierFreq,
|
||||||
|
carrierPhase, dragAlpha,
|
||||||
|
thf, thi, lam2, lam3,
|
||||||
|
)
|
||||||
|
xs, ys = [], []
|
||||||
|
for c in data:
|
||||||
|
xs.append(c.real)
|
||||||
|
ys.append(c.imag)
|
||||||
|
|
||||||
|
return (xs, ys)
|
||||||
|
|
||||||
|
def load_gt(self):
|
||||||
|
for i in range(self.num_samplings):
|
||||||
|
file = os.path.join(self.data_dir, "aczgo_result_{}.log".format(i))
|
||||||
|
xs, ys = [], []
|
||||||
|
with open(file, 'r') as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
for line in lines:
|
||||||
|
x, y = line.split(", ")
|
||||||
|
x, y = float(x), float(y)
|
||||||
|
xs.append(x)
|
||||||
|
ys.append(y)
|
||||||
|
self.gt_dict[i] = (xs, ys)
|
||||||
|
|
||||||
|
def test(self, idx):
|
||||||
|
def check_valid(vs):
|
||||||
|
return all(map(lambda x:not np.isnan(x) and not np.isinf(x), vs))
|
||||||
|
def max_ab_dis(xs, bxs):
|
||||||
|
return np.abs(np.array(bxs) - np.array(xs)).max()
|
||||||
|
|
||||||
|
|
||||||
|
(bxs, bys) = self.gt_dict[idx]
|
||||||
|
if check_valid(bxs) and check_valid(bys):
|
||||||
|
xs, ys = self.eval(idx)
|
||||||
|
return (max_ab_dis(xs, bxs), max_ab_dis(ys, bys))
|
||||||
|
else:
|
||||||
|
return "not valid"
|
||||||
|
|
||||||
|
def test_all(self):
|
||||||
|
for i in range(self.num_samplings):
|
||||||
|
print(self.test(i))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
b = Benchmark(11)
|
||||||
|
print(b.test_all())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# data = test()
|
||||||
|
#
|
||||||
|
# np.savetxt('D:/Work/TailCorr/acz_750.csv', data, delimiter=' ')
|
||||||
|
# plt.figure()
|
||||||
|
# plt.plot(data)
|
||||||
|
# plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
from scipy.special import erf
|
||||||
|
|
||||||
|
def flattop(A, edge, length, fsn):
|
||||||
|
'''
|
||||||
|
生成平顶包络函数 (Python版本)
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
-----------
|
||||||
|
A : float
|
||||||
|
幅度
|
||||||
|
edge : float
|
||||||
|
边沿时间参数
|
||||||
|
length : int
|
||||||
|
长度(采样点数)
|
||||||
|
fsn : float
|
||||||
|
采样频率
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
--------
|
||||||
|
numpy.ndarray
|
||||||
|
平顶包络波形
|
||||||
|
'''
|
||||||
|
Ts = 0
|
||||||
|
r_sigma = 0.21230
|
||||||
|
|
||||||
|
T = length / fsn
|
||||||
|
t = np.arange(0, length + 2) / fsn
|
||||||
|
|
||||||
|
mu = 0.5 * edge
|
||||||
|
sigma = r_sigma * (edge - 1)
|
||||||
|
p = T - 1 - edge
|
||||||
|
|
||||||
|
x1 = (t - mu - Ts) / (np.sqrt(2) * sigma)
|
||||||
|
x2 = (t - mu - p + Ts) / (np.sqrt(2) * sigma)
|
||||||
|
|
||||||
|
f = A / 2 * (erf(x1) - erf(x2))
|
||||||
|
# f_padded = np.pad(f, (1, 1), mode='constant', constant_values=0)
|
||||||
|
|
||||||
|
return f
|
||||||
|
"""
|
||||||
|
# 使用示例
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# 测试参数
|
||||||
|
A = 1.0 # 幅度
|
||||||
|
edge = 0.1 # 边沿时间
|
||||||
|
length = 1000 # 长度
|
||||||
|
fsn = 10000 # 采样频率
|
||||||
|
|
||||||
|
# 生成平顶包络
|
||||||
|
envelope = flattop(A, edge, length, fsn)
|
||||||
|
|
||||||
|
print(f"生成的包络长度: {len(envelope)}")
|
||||||
|
print(f"最大值: {np.max(envelope):.6f}")
|
||||||
|
print(f"最小值: {np.min(envelope):.6f}")
|
||||||
|
|
||||||
|
# 可选:绘图显示
|
||||||
|
try:
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
plt.figure(figsize=(10, 6))
|
||||||
|
time_axis = np.arange(len(envelope)) / fsn
|
||||||
|
plt.plot(time_axis, envelope, 'b-', linewidth=2)
|
||||||
|
plt.xlabel('时间 (s)')
|
||||||
|
plt.ylabel('幅度')
|
||||||
|
plt.title('平顶包络波形')
|
||||||
|
plt.grid(True, alpha=0.3)
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
except ImportError:
|
||||||
|
print("matplotlib 未安装,跳过绘图")
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
from ctypes import Union
|
||||||
|
import numpy as np
|
||||||
|
import random
|
||||||
|
|
||||||
|
class make_case(object):
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
self = 0
|
||||||
|
|
||||||
|
def data_gen(
|
||||||
|
self,
|
||||||
|
mode = 'random',
|
||||||
|
length = 1,
|
||||||
|
params = {}
|
||||||
|
):
|
||||||
|
|
||||||
|
match mode:
|
||||||
|
case 'random':
|
||||||
|
data = [random.randint(0,2**32) for _ in range(length)]
|
||||||
|
case 'ones':
|
||||||
|
data = (2**32-1)*np.ones(length)
|
||||||
|
case 'amp':
|
||||||
|
amp = params['amp']
|
||||||
|
amp = int(amp,0) if isinstance(amp, str) else int(amp)
|
||||||
|
data = amp*np.ones(length)
|
||||||
|
case 'zeros':
|
||||||
|
data = np.zeros(length)
|
||||||
|
case 'value':
|
||||||
|
value = params['value']
|
||||||
|
if np.size(value) != length:
|
||||||
|
print("Warnning: Length Mismatch")
|
||||||
|
elif length ==1:
|
||||||
|
data = int(value,0) if isinstance(value, str) else int(value)
|
||||||
|
else:
|
||||||
|
data = np.zeros(length)
|
||||||
|
for i in range(0,length):
|
||||||
|
data[i] = int(value[i],0) if isinstance(value[i], str) else int(value[i])
|
||||||
|
case 'acc':
|
||||||
|
ini_data = params['ini_data']
|
||||||
|
ini_data = int(ini_data,0) if isinstance(ini_data, str) else int(ini_data)
|
||||||
|
step_size = params['step_size']
|
||||||
|
step_size = int(step_size,0) if isinstance(step_size, str) else int(step_size)
|
||||||
|
data = np.zeros(length)
|
||||||
|
for i in range(0,length):
|
||||||
|
data[i] = ini_data + i*step_size
|
||||||
|
case 'rd_file':
|
||||||
|
file_name = params['file_name']
|
||||||
|
with open(file_name, "r") as f:
|
||||||
|
data_bin = f.read()
|
||||||
|
data_bin = data_bin.split('\n')
|
||||||
|
data = []
|
||||||
|
for d in data_bin:
|
||||||
|
data.append((int(d,2)))
|
||||||
|
return data
|
||||||
|
|
||||||
|
def rw_once(
|
||||||
|
self,
|
||||||
|
op = 'w',
|
||||||
|
addr = 0x1F00044,
|
||||||
|
data = [0],
|
||||||
|
file_name = 'case.txt',
|
||||||
|
chip_id = 0,
|
||||||
|
exaddr = 1,
|
||||||
|
ard_flag = 0
|
||||||
|
):
|
||||||
|
|
||||||
|
with open(file_name, "a") as f:
|
||||||
|
cmd = 1 if (op=='r') or (op==1) else 0
|
||||||
|
if isinstance(addr, str):
|
||||||
|
addr = int(addr,0)
|
||||||
|
else:
|
||||||
|
addr = int(addr)
|
||||||
|
f.write(f"{((int(cmd)<<31) | (int(ard_flag)<<30) | (int(chip_id)<<25) | (addr)):08x}\n")
|
||||||
|
f.write(f"{((int(exaddr)<<20) | (int(np.size(data)*4))):08x}\n")
|
||||||
|
|
||||||
|
if op == 'w':
|
||||||
|
if np.size(data) == 1:
|
||||||
|
if isinstance(data, str):
|
||||||
|
dt = int(data,0)
|
||||||
|
else:
|
||||||
|
dt = int(np.round(data))
|
||||||
|
f.write(f"{(dt if dt>=0 else 2**32+dt):08x}\n")
|
||||||
|
else:
|
||||||
|
for i in range(0,np.size(data)):
|
||||||
|
if isinstance(data[i], str):
|
||||||
|
dt = int(data[i],0)
|
||||||
|
else:
|
||||||
|
dt = int(np.round(data[i]))
|
||||||
|
f.write(f"{(dt if dt>=0 else 2**32+dt):08x}\n")
|
||||||
|
f.write('\n')
|
||||||
|
|
||||||
|
|
@ -0,0 +1,319 @@
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
class make_inst(object):
|
||||||
|
|
||||||
|
def parse_instruction(self, instruction, labels, pc):
|
||||||
|
# 去掉所有逗号
|
||||||
|
instruction = instruction.replace(',', ' ')
|
||||||
|
parts = instruction.split()
|
||||||
|
opcode = parts[0].upper().strip()
|
||||||
|
|
||||||
|
if opcode.endswith(':'):
|
||||||
|
# 处理标签
|
||||||
|
label_name = opcode[:-1]
|
||||||
|
labels[label_name] = pc
|
||||||
|
return None
|
||||||
|
|
||||||
|
operands = [op.strip() for op in parts[1:]]
|
||||||
|
|
||||||
|
def parse_immediate(imm_str):
|
||||||
|
try:
|
||||||
|
if imm_str.startswith('0x') or imm_str.startswith('0X'):
|
||||||
|
return int(imm_str, 16)
|
||||||
|
elif imm_str.startswith('0b') or imm_str.startswith('0B'):
|
||||||
|
return int(imm_str, 2)
|
||||||
|
elif imm_str.startswith('-0x') or imm_str.startswith('-0X'):
|
||||||
|
return -int(imm_str[1:], 16)
|
||||||
|
elif imm_str.startswith('-0b') or imm_str.startswith('-0B'):
|
||||||
|
return -int(imm_str[1:], 2)
|
||||||
|
elif imm_str.startswith('-'):
|
||||||
|
return -int(imm_str[1:], 10)
|
||||||
|
else:
|
||||||
|
return int(imm_str, 10)
|
||||||
|
except ValueError:
|
||||||
|
raise ValueError(f"Invalid immediate value: {imm_str}")
|
||||||
|
|
||||||
|
if opcode == 'LUI':
|
||||||
|
rd, imm = operands
|
||||||
|
rd = int(rd[1:]) # 去掉寄存器名称前的 'x'
|
||||||
|
imm = parse_immediate(imm)
|
||||||
|
return format((self.opcode_map[opcode]) | (imm & 0xFFFFF) << 12 | (rd << 7), '032b')
|
||||||
|
|
||||||
|
elif opcode == 'AUIPC':
|
||||||
|
rd, imm = operands
|
||||||
|
rd = int(rd[1:]) # 去掉寄存器名称前的 'x'
|
||||||
|
imm = parse_immediate(imm)
|
||||||
|
return format((self.opcode_map[opcode]) | (imm & 0xFFFFF) << 12 | (rd << 7), '032b')
|
||||||
|
|
||||||
|
elif opcode == 'JAL':
|
||||||
|
rd, label_or_imm = operands
|
||||||
|
rd = int(rd[1:]) # 去掉寄存器名称前的 'x'
|
||||||
|
if label_or_imm.lstrip('-').isdigit() or label_or_imm.startswith(('0x', '0X', '0b', '0B', '-0x', '-0X', '-0b', '-0B')):
|
||||||
|
imm = parse_immediate(label_or_imm)
|
||||||
|
else:
|
||||||
|
imm = labels.get(label_or_imm.upper().strip(), 0) - pc
|
||||||
|
imm_bits = (((imm >> 20) & 0x1) << 19) | (((imm >> 1) & 0x3FF) << 9) | (((imm >> 11) & 0x1) << 8) | ((imm >> 12) & 0xFF)
|
||||||
|
return format((self.opcode_map[opcode]) | (imm_bits) << 12 | (rd << 7), '032b')
|
||||||
|
|
||||||
|
elif opcode == 'JALR':
|
||||||
|
rd = operands[0]
|
||||||
|
operands[1] = operands[1].rstrip(')')
|
||||||
|
imm, rs1 = operands[1].split('(')
|
||||||
|
rd = int(rd[1:]) # 去掉寄存器名称前的 'x'
|
||||||
|
rs1 = int(rs1[1:]) # 去掉寄存器名称前的 'x'
|
||||||
|
imm = parse_immediate(imm)
|
||||||
|
funct3 = self.opcode_funct3_map[opcode]
|
||||||
|
return format((self.opcode_map[opcode]) | (imm & 0xFFF) << 20 | (rs1 << 15) | (funct3 << 12) | (rd << 7), '032b')
|
||||||
|
|
||||||
|
elif opcode in ['BEQ', 'BNE', 'BLT', 'BGE', 'BLTU', 'BGEU']:
|
||||||
|
rs1, rs2, label_or_imm = operands
|
||||||
|
rs1 = int(rs1[1:]) # 去掉寄存器名称前的 'x'
|
||||||
|
rs2 = int(rs2[1:]) # 去掉寄存器名称前的 'x'
|
||||||
|
if label_or_imm.lstrip('-').isdigit() or label_or_imm.startswith(('0x', '0X', '0b', '0B', '-0x', '-0X', '-0b', '-0B')):
|
||||||
|
imm = parse_immediate(label_or_imm)
|
||||||
|
else:
|
||||||
|
imm = labels.get(label_or_imm.upper().strip(), 0) - pc
|
||||||
|
imm_high_bits = (((imm >> 12) & 0x1) << 6) | (((imm >> 5 ) & 0x3F))
|
||||||
|
imm_low_bits = (((imm >> 1 ) & 0xF) << 1) | (((imm >> 11) & 0x1 ))
|
||||||
|
funct3 = self.opcode_funct3_map[opcode]
|
||||||
|
return format((self.opcode_map[opcode]) | (imm_high_bits << 25) | (rs2 << 20) | (rs1 << 15) | (funct3 << 12) | (imm_low_bits << 7), '032b')
|
||||||
|
|
||||||
|
elif opcode in ['LB', 'LH', 'LW', 'LBU', 'LHU']:
|
||||||
|
rd = operands[0]
|
||||||
|
operands[1] = operands[1].rstrip(')')
|
||||||
|
imm, rs1 = operands[1].split('(')
|
||||||
|
rd = int(rd[1:]) # 去掉寄存器名称前的 'x'
|
||||||
|
rs1 = int(rs1[1:]) # 去掉寄存器名称前的 'x'
|
||||||
|
imm = parse_immediate(imm)
|
||||||
|
funct3 = self.opcode_funct3_map[opcode]
|
||||||
|
return format((self.opcode_map[opcode]) | ((imm & 0xFFF) << 20) | (rs1 << 15) | (funct3 << 12) | (rd << 7), '032b')
|
||||||
|
|
||||||
|
elif opcode in ['SB', 'SH', 'SW']:
|
||||||
|
rs2 = operands[0]
|
||||||
|
operands[1] = operands[1].rstrip(')')
|
||||||
|
imm, rs1 = operands[1].split('(')
|
||||||
|
rs2 = int(rs2[1:]) # 去掉寄存器名称前的 'x'
|
||||||
|
rs1 = int(rs1[1:]) # 去掉寄存器名称前的 'x'
|
||||||
|
imm = parse_immediate(imm)
|
||||||
|
funct3 = self.opcode_funct3_map[opcode]
|
||||||
|
return format((self.opcode_map[opcode]) | (((imm >> 5) & 0x7F) << 25) | (rs2 << 20) | (rs1 << 15) | (funct3 << 12) | ((imm & 0x1F) << 7), '032b')
|
||||||
|
|
||||||
|
elif opcode in ['ADDI', 'SLTI', 'SLTIU', 'XORI', 'ORI', 'ANDI']:
|
||||||
|
rd, rs1, imm = operands
|
||||||
|
rd = int(rd[1:]) # 去掉寄存器名称前的 'x'
|
||||||
|
rs1 = int(rs1[1:]) # 去掉寄存器名称前的 'x'
|
||||||
|
imm = parse_immediate(imm)
|
||||||
|
funct3 = self.opcode_funct3_map[opcode]
|
||||||
|
return format((self.opcode_map[opcode]) | ((imm & 0xFFF) << 20) | (rs1 << 15) | (funct3 << 12) | (rd << 7), '032b')
|
||||||
|
|
||||||
|
elif opcode in ['SLLI', 'SRLI', 'SRAI']:
|
||||||
|
rd, rs1, shamt = operands
|
||||||
|
rd = int(rd[1:]) # 去掉寄存器名称前的 'x'
|
||||||
|
rs1 = int(rs1[1:]) # 去掉寄存器名称前的 'x'
|
||||||
|
shamt = parse_immediate(shamt)
|
||||||
|
funct3 = self.opcode_funct3_map[opcode]
|
||||||
|
funct7 = self.opcode_funct7_map[opcode]
|
||||||
|
return format((self.opcode_map[opcode]) | (funct7 << 25) | ((shamt & 0x1F) << 20) | (rs1 << 15) | (funct3 << 12) | (rd << 7), '032b')
|
||||||
|
|
||||||
|
elif opcode in ['ADD', 'SUB', 'SLL', 'SLT', 'SLTU', 'XOR', 'SRL', 'SRA', 'OR', 'AND']:
|
||||||
|
rd, rs1, rs2 = operands
|
||||||
|
rd = int(rd[1:]) # 去掉寄存器名称前的 'x'
|
||||||
|
rs1 = int(rs1[1:]) # 去掉寄存器名称前的 'x'
|
||||||
|
rs2 = int(rs2[1:]) # 去掉寄存器名称前的 'x'
|
||||||
|
funct3 = self.opcode_funct3_map[opcode]
|
||||||
|
funct7 = self.opcode_funct7_map[opcode]
|
||||||
|
return format((self.opcode_map[opcode]) | (funct7 << 25) | (rs2 << 20) | (rs1 << 15) | (funct3 << 12) | (rd << 7), '032b')
|
||||||
|
|
||||||
|
elif opcode in ['WAIT', 'SEND', 'SENDC']:
|
||||||
|
rd, rs1, imm = operands
|
||||||
|
rd = int(rd[1:]) # 去掉寄存器名称前的 'x'
|
||||||
|
rs1 = int(rs1[1:]) # 去掉寄存器名称前的 'x'
|
||||||
|
imm = parse_immediate(imm)
|
||||||
|
funct3 = self.opcode_funct3_map[opcode]
|
||||||
|
return format((self.opcode_map[opcode]) | ((imm & 0xFFF) << 20) | (rs1 << 15) | (funct3 << 12) | (rd << 7), '032b')
|
||||||
|
|
||||||
|
elif opcode in ['EXIT']:
|
||||||
|
return format((self.opcode_map[opcode]), '032b')
|
||||||
|
|
||||||
|
elif opcode in ['EXIT_IR']:
|
||||||
|
return '00000000000000000001000000101011'
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Unsupported opcode: {opcode}")
|
||||||
|
|
||||||
|
def write(self, instructions, file_name, exaddr = 1, chip_id = 0, channel_id = 0, pc_start = 0, ard_flag = 0, show = False):
|
||||||
|
if instructions == "":
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
labels = {}
|
||||||
|
binary_instructions = []
|
||||||
|
|
||||||
|
# 将整段汇编代码拆成多条指令组成的字符串数组
|
||||||
|
inst_list = instructions.split('\n')
|
||||||
|
instructions = []
|
||||||
|
for this_inst in inst_list:
|
||||||
|
this_inst = this_inst.split('#')
|
||||||
|
if this_inst[0].strip() != '':
|
||||||
|
instructions.append(this_inst[0].strip())
|
||||||
|
|
||||||
|
# 第一遍扫描:记录标签位置
|
||||||
|
pc = pc_start
|
||||||
|
for instr in instructions:
|
||||||
|
binary = self.parse_instruction(instr, labels, pc)
|
||||||
|
if binary is not None:
|
||||||
|
binary_instructions.append(binary)
|
||||||
|
pc += 4
|
||||||
|
else:
|
||||||
|
# 如果是标签,不增加pc
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 第二遍扫描:生成最终的二进制代码
|
||||||
|
pc = pc_start
|
||||||
|
final_binary_instructions = []
|
||||||
|
for instr in instructions:
|
||||||
|
binary = self.parse_instruction(instr, labels, pc)
|
||||||
|
if binary is not None:
|
||||||
|
final_binary_instructions.append(binary)
|
||||||
|
if show:
|
||||||
|
print(f"{instr}: {binary}")
|
||||||
|
pc += 4
|
||||||
|
else:
|
||||||
|
# 如果是标签,不增加pc
|
||||||
|
pass
|
||||||
|
|
||||||
|
with open(file_name, "a") as f:
|
||||||
|
base_addr = 0x010_0000 + pc_start + channel_id * 0x060_0000
|
||||||
|
length = np.size(final_binary_instructions)
|
||||||
|
f.write(f"{((ard_flag << 30) | (chip_id << 25) | (base_addr)):08x}\n")
|
||||||
|
f.write(f"{((exaddr << 20) | (length<<2)):08x}\n")
|
||||||
|
for binary_instr in final_binary_instructions:
|
||||||
|
f.write(f"{int(binary_instr,2):08x}\n")
|
||||||
|
f.write("\n")
|
||||||
|
|
||||||
|
return final_binary_instructions
|
||||||
|
|
||||||
|
opcode_map = {
|
||||||
|
'LUI': 0x37,
|
||||||
|
'AUIPC': 0x17,
|
||||||
|
'JAL': 0x6F,
|
||||||
|
'JALR': 0x67,
|
||||||
|
'BEQ': 0x63,
|
||||||
|
'BNE': 0x63,
|
||||||
|
'BLT': 0x63,
|
||||||
|
'BGE': 0x63,
|
||||||
|
'BLTU': 0x63,
|
||||||
|
'BGEU': 0x63,
|
||||||
|
'LB': 0x03,
|
||||||
|
'LH': 0x03,
|
||||||
|
'LW': 0x03,
|
||||||
|
'LBU': 0x03,
|
||||||
|
'LHU': 0x03,
|
||||||
|
'SB': 0x23,
|
||||||
|
'SH': 0x23,
|
||||||
|
'SW': 0x23,
|
||||||
|
'ADDI': 0x13,
|
||||||
|
'SLTI': 0x13,
|
||||||
|
'SLTIU': 0x13,
|
||||||
|
'XORI': 0x13,
|
||||||
|
'ORI': 0x13,
|
||||||
|
'ANDI': 0x13,
|
||||||
|
'SLLI': 0x13,
|
||||||
|
'SRLI': 0x13,
|
||||||
|
'SRAI': 0x13,
|
||||||
|
'ADD': 0x33,
|
||||||
|
'SUB': 0x33,
|
||||||
|
'SLL': 0x33,
|
||||||
|
'SLT': 0x33,
|
||||||
|
'SLTU': 0x33,
|
||||||
|
'XOR': 0x33,
|
||||||
|
'SRL': 0x33,
|
||||||
|
'SRA': 0x33,
|
||||||
|
'OR': 0x33,
|
||||||
|
'AND': 0x33,
|
||||||
|
'WAIT': 0x0B,
|
||||||
|
'SEND': 0x0B,
|
||||||
|
'SENDC': 0x0B,
|
||||||
|
'EXIT': 0x2B,
|
||||||
|
}
|
||||||
|
|
||||||
|
opcode_funct3_map = {
|
||||||
|
'JALR': 0x0,
|
||||||
|
'BEQ': 0x0,
|
||||||
|
'BNE': 0x1,
|
||||||
|
'BLT': 0x4,
|
||||||
|
'BGE': 0x5,
|
||||||
|
'BLTU': 0x6,
|
||||||
|
'BGEU': 0x7,
|
||||||
|
'LB': 0x0,
|
||||||
|
'LH': 0x1,
|
||||||
|
'LW': 0x2,
|
||||||
|
'LBU': 0x4,
|
||||||
|
'LHU': 0x5,
|
||||||
|
'SB': 0x0,
|
||||||
|
'SH': 0x1,
|
||||||
|
'SW': 0x2,
|
||||||
|
'ADDI': 0x0,
|
||||||
|
'SLTI': 0x2,
|
||||||
|
'SLTIU': 0x3,
|
||||||
|
'XORI': 0x4,
|
||||||
|
'ORI': 0x6,
|
||||||
|
'ANDI': 0x7,
|
||||||
|
'SLLI': 0x1,
|
||||||
|
'SRLI': 0x5,
|
||||||
|
'SRAI': 0x5,
|
||||||
|
'ADD': 0x0,
|
||||||
|
'SUB': 0x0,
|
||||||
|
'SLL': 0x1,
|
||||||
|
'SLT': 0x2,
|
||||||
|
'SLTU': 0x3,
|
||||||
|
'XOR': 0x4,
|
||||||
|
'SRL': 0x5,
|
||||||
|
'SRA': 0x5,
|
||||||
|
'OR': 0x6,
|
||||||
|
'AND': 0x7,
|
||||||
|
'WAIT': 0x0,
|
||||||
|
'SEND': 0x2,
|
||||||
|
'SENDC': 0x3,
|
||||||
|
'EXIT': 0x0,
|
||||||
|
}
|
||||||
|
|
||||||
|
opcode_funct7_map = {
|
||||||
|
'JALR': 0x00,
|
||||||
|
'BEQ': 0x00,
|
||||||
|
'BNE': 0x00,
|
||||||
|
'BLT': 0x00,
|
||||||
|
'BGE': 0x00,
|
||||||
|
'BLTU': 0x00,
|
||||||
|
'BGEU': 0x00,
|
||||||
|
'LB': 0x00,
|
||||||
|
'LH': 0x00,
|
||||||
|
'LW': 0x00,
|
||||||
|
'LBU': 0x00,
|
||||||
|
'LHU': 0x00,
|
||||||
|
'SB': 0x00,
|
||||||
|
'SH': 0x00,
|
||||||
|
'SW': 0x00,
|
||||||
|
'ADDI': 0x00,
|
||||||
|
'SLTI': 0x00,
|
||||||
|
'SLTIU': 0x00,
|
||||||
|
'XORI': 0x00,
|
||||||
|
'ORI': 0x00,
|
||||||
|
'ANDI': 0x00,
|
||||||
|
'SLLI': 0x00,
|
||||||
|
'SRLI': 0x00,
|
||||||
|
'SRAI': 0x20,
|
||||||
|
'ADD': 0x00,
|
||||||
|
'SUB': 0x20,
|
||||||
|
'SLL': 0x00,
|
||||||
|
'SLT': 0x00,
|
||||||
|
'SLTU': 0x00,
|
||||||
|
'XOR': 0x00,
|
||||||
|
'SRL': 0x00,
|
||||||
|
'SRA': 0x20,
|
||||||
|
'OR': 0x00,
|
||||||
|
'AND': 0x00,
|
||||||
|
'WAIT': 0x00,
|
||||||
|
'SEND': 0x00,
|
||||||
|
'SENDC': 0x00,
|
||||||
|
'EXIT': 0x00,
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,289 @@
|
||||||
|
# TODO: 寄存器统一由excel表格维护
|
||||||
|
# TODO: 寄存由excel表格生成
|
||||||
|
reg_define = {
|
||||||
|
'sys_reg': {
|
||||||
|
'IDR': 0x00,
|
||||||
|
'VIDR': 0x04,
|
||||||
|
'DATER': 0x08,
|
||||||
|
'VERR': 0x0C,
|
||||||
|
'TESTR': 0x10,
|
||||||
|
'IMR': 0x14,
|
||||||
|
'ISR': 0x18,
|
||||||
|
'SFRTR': 0x1C,
|
||||||
|
'SFRR': 0x20,
|
||||||
|
'CH0RSTR': 0x24,
|
||||||
|
'CH1RSTR': 0x28,
|
||||||
|
'CH2RSTR': 0x2C,
|
||||||
|
'CH3RSTR': 0x30,
|
||||||
|
'DBGCFGR': 0x34,
|
||||||
|
'MISR': 0x40,
|
||||||
|
'SYNCR': 0x44,
|
||||||
|
'MSDENR': 0x48,
|
||||||
|
'MSDPCNTR': 0x4C,
|
||||||
|
},
|
||||||
|
'ctrl_reg': {
|
||||||
|
'MCUPARAR0': 0x00,
|
||||||
|
'MCUPARAR1': 0x04,
|
||||||
|
'MCUPARAR2': 0x08,
|
||||||
|
'MCUPARAR3': 0x0C,
|
||||||
|
'MCURESR0': 0x10,
|
||||||
|
'MCURESR1': 0x14,
|
||||||
|
'MCURESR2': 0x18,
|
||||||
|
'MCURESR3': 0x1C,
|
||||||
|
'RTIMR': 0x98,
|
||||||
|
'ICNTR': 0x9C,
|
||||||
|
'FSIR': 0xA0,
|
||||||
|
'MODMR': 0x100,
|
||||||
|
'MODENR': 0x104,
|
||||||
|
'MODDOTR': 0x108,
|
||||||
|
'MIXODFR': 0x10C,
|
||||||
|
'STR': 0x110,
|
||||||
|
'NCOAOR': 0x114,
|
||||||
|
'SPI_RAMPFIXR': 0x118,
|
||||||
|
'SPI_RAMPSR': 0x11C,
|
||||||
|
'SPI_RAMPIFSR': 0x120,
|
||||||
|
'SPI_RAMPENR': 0x124,
|
||||||
|
'TSTIMER': 0x130,
|
||||||
|
'TSITVLR': 0x134,
|
||||||
|
'TSENR': 0x138,
|
||||||
|
'TSVALR': 0x13C,
|
||||||
|
},
|
||||||
|
'mcu_reg': {
|
||||||
|
'CWFR0': 0x40,
|
||||||
|
'CWFR1': 0x44,
|
||||||
|
'CWFR2': 0x48,
|
||||||
|
'CWFR3': 0x4C,
|
||||||
|
'CWPRR': 0x50,
|
||||||
|
'GAPR0': 0x54,
|
||||||
|
'GAPR1': 0x58,
|
||||||
|
'GAPR2': 0x5C,
|
||||||
|
'GAPR3': 0x60,
|
||||||
|
'GAPR4': 0x64,
|
||||||
|
'GAPR5': 0x68,
|
||||||
|
'GAPR6': 0x6C,
|
||||||
|
'GAPR7': 0x70,
|
||||||
|
'LCPR': 0x74,
|
||||||
|
'AMPR0': 0x78,
|
||||||
|
'AMPR1': 0x7C,
|
||||||
|
'AMPR2': 0x80,
|
||||||
|
'AMPR3': 0x84,
|
||||||
|
'BIASR0': 0x88,
|
||||||
|
'BIASR1': 0x8C,
|
||||||
|
'BIASR2': 0x90,
|
||||||
|
'BIASR3': 0x94,
|
||||||
|
'RTIMR': 0x98, # Note: Same as in ctrl_reg
|
||||||
|
'ICNTR': 0x9C, # Note: Same as in ctrl_reg
|
||||||
|
'FSIR': 0xA0, # Note: Same as in ctrl_reg
|
||||||
|
'DCBVR': 0xA4,
|
||||||
|
'FMER': 0xB4,
|
||||||
|
'MCU_RAMPFIXR': 0xB8,
|
||||||
|
'MCU_RAMPSR': 0xBC,
|
||||||
|
'MCU_RAMPIFSR': 0xC0,
|
||||||
|
'MCU_RAMPENR': 0xC4,
|
||||||
|
'PRNGSDR': 0xC8,
|
||||||
|
'PRNGRESR': 0xCC,
|
||||||
|
'MULTR0': 0xD0,
|
||||||
|
'MULTR1': 0xD4,
|
||||||
|
'DTFR': 0xD8,
|
||||||
|
},
|
||||||
|
'tc_reg': {
|
||||||
|
'TCPARR0': 0x000,
|
||||||
|
'TCPARR1': 0x004,
|
||||||
|
'TCPARR2': 0x008,
|
||||||
|
'TCPARR3': 0x00C,
|
||||||
|
'TCPARR4': 0x010,
|
||||||
|
'TCPARR5': 0x014,
|
||||||
|
'TCPARR6': 0x018,
|
||||||
|
'TCPARR7': 0x01C,
|
||||||
|
'TCPAIR0': 0x020,
|
||||||
|
'TCPAIR1': 0x024,
|
||||||
|
'TCPAIR2': 0x028,
|
||||||
|
'TCPAIR3': 0x02C,
|
||||||
|
'TCPAIR4': 0x030,
|
||||||
|
'TCPAIR5': 0x034,
|
||||||
|
'TCPAIR6': 0x038,
|
||||||
|
'TCPAIR7': 0x03C,
|
||||||
|
'TCPBRR0': 0x040,
|
||||||
|
'TCPBRR1': 0x044,
|
||||||
|
'TCPBRR2': 0x048,
|
||||||
|
'TCPBRR3': 0x04C,
|
||||||
|
'TCPBRR4': 0x050,
|
||||||
|
'TCPBRR5': 0x054,
|
||||||
|
'TCPBRR6': 0x058,
|
||||||
|
'TCPBRR7': 0x05C,
|
||||||
|
'TCPBIR0': 0x060,
|
||||||
|
'TCPBIR1': 0x064,
|
||||||
|
'TCPBIR2': 0x068,
|
||||||
|
'TCPBIR3': 0x06C,
|
||||||
|
'TCPBIR4': 0x070,
|
||||||
|
'TCPBIR5': 0x074,
|
||||||
|
'TCPBIR6': 0x078,
|
||||||
|
'TCPBIR7': 0x07C,
|
||||||
|
'TCBPR': 0x080,
|
||||||
|
'TCCER': 0x084,
|
||||||
|
'TCOVR': 0x088,
|
||||||
|
'TCCDR': 0x08C,
|
||||||
|
},
|
||||||
|
'pll_reg': {
|
||||||
|
'INTPLL_REFCTRL' : 0x00,
|
||||||
|
'INTPLL_PCNT' : 0x04,
|
||||||
|
'INTPLL_PFDCTRL' : 0x08,
|
||||||
|
'INTPLL_SPDCTRL' : 0x0C,
|
||||||
|
'INTPLL_PTATCTRL' : 0x10,
|
||||||
|
'INTPLL_SELCTRL' : 0x14,
|
||||||
|
'INTPLL_VCOCTRL' : 0x18,
|
||||||
|
'INTPLL_TCCTRL' : 0x1C,
|
||||||
|
'INTPLL_AFCCTRL' : 0x20,
|
||||||
|
'INTPLL_AFCFBCTRL': 0x24,
|
||||||
|
'INTPLL_AFCLDCNT' : 0x28,
|
||||||
|
'INTPLL_DIVRSTSEL': 0x2C,
|
||||||
|
'INTPLL_TESTCLK' : 0x30,
|
||||||
|
'INTPLL_DIGCLKSEL': 0x34,
|
||||||
|
'INTPLL_STATUS' : 0x38,
|
||||||
|
'INTPLL_SYNC' : 0x3C,
|
||||||
|
'INTPLL_UPDATE' : 0x40,
|
||||||
|
'INTPLL_CLKRXPD' : 0x44,
|
||||||
|
'INTPLL_RESV' : 0x48,
|
||||||
|
'CCALRSTR' : 0x4C,
|
||||||
|
'CCALATENR' : 0x50,
|
||||||
|
'CCALSELALNR' : 0x54,
|
||||||
|
'CCALDCCQECR' : 0x58,
|
||||||
|
'CCALQECCT0R' : 0x5C,
|
||||||
|
'CCALQECCT1R' : 0x60,
|
||||||
|
'CCALDCCCT0R' : 0x64,
|
||||||
|
'CCALDCCCT1R' : 0x68,
|
||||||
|
'DIVSYNCDCR' : 0x6C,
|
||||||
|
'SYNCCLRENR' : 0x70,
|
||||||
|
'CCALDCCCT2R' : 0x74,
|
||||||
|
'CCALSTR' : 0x78,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Usage example:
|
||||||
|
# value = reg_define['sys_reg']['DATER'] # Gets 0x00
|
||||||
|
# print(f"IDR value: {value}")
|
||||||
|
# import reg_define
|
||||||
|
|
||||||
|
# 预定义的TC系数组
|
||||||
|
TC_COEFFICIENT_SETS = {
|
||||||
|
'default': {
|
||||||
|
'amp_real': [0.025, 0.015, 0.0002, 0.2, 0, 0, 0, 0],
|
||||||
|
'amp_imag': [0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
'time_real': [-1/250, -1/650, -1/1600, -1/20, 0, 0, 0, 0],
|
||||||
|
'time_imag': [0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
'description': '默认TC系数组'
|
||||||
|
},
|
||||||
|
'coef1': {
|
||||||
|
'amp_real': [0.025, 0.015, 0.0002, 0.2, 0, 0, 0, 0],
|
||||||
|
'amp_imag': [0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
'time_real': [-1/250, -1/650, -1/1600, -1/20, 0, 0, 0, 0],
|
||||||
|
'time_imag': [0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
'description': 'lsw - coef1'
|
||||||
|
},
|
||||||
|
'coef2': {
|
||||||
|
'amp_real': [0.025, 0.015, 0.0002, 0.2, 0, 0, 0, 0],
|
||||||
|
'amp_imag': [0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
'time_real': [-1/250, -1/650, -1/1600, -1/20, 0, 0, 0, 0],
|
||||||
|
'time_imag': [0, -1/300, -1/500, 0, 0, 0, 0, 0],
|
||||||
|
'description': 'lsw - coef2'
|
||||||
|
},
|
||||||
|
'coef3': {
|
||||||
|
'amp_real': [0.025, 0.009, 0.0002, 0.2, 0, 0, 0, 0],
|
||||||
|
'amp_imag': [0, 0.012, 0, 0, 0, 0, 0, 0],
|
||||||
|
'time_real': [-1/250, -1/650, -1/1600, -1/20, 0, 0, 0, 0],
|
||||||
|
'time_imag': [0, -1/300, -1/500, 0, 0, 0, 0, 0],
|
||||||
|
|
||||||
|
'description': 'lsw - coef3'
|
||||||
|
},
|
||||||
|
'coef4': {
|
||||||
|
'amp_real': [0.025, 0.015, 0.0002, 0.2, 0, 0, 0, 0],
|
||||||
|
'amp_imag': [0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
'time_real': [-1/250, -1/2000, -1/1600, -1/20, 0, 0, 0, 0],
|
||||||
|
'time_imag': [0, -1/15, -1/50, 0, 0, 0, 0, 0],
|
||||||
|
'description': 'lsw - coef4'
|
||||||
|
},
|
||||||
|
'coef5': {
|
||||||
|
'amp_real': [0.0281, 0.0024, 0.0021, 0.0011, 0, 0, 0, 0],
|
||||||
|
'amp_imag': [0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
'time_real': [-0.0033, -0.0027, -0.0027, -0.0002, 0, 0, 0, 0],
|
||||||
|
'time_imag': [0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
'description': 'czy - coef5'
|
||||||
|
},
|
||||||
|
'coef6': {
|
||||||
|
'amp_real': [0.0314, 0.0132, 0.0055, 0.0017, 0, 0, 0, 0],
|
||||||
|
'amp_imag': [0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
'time_real': [-0.0096, -0.0021, -0.0009, -0.0002, 0, 0, 0, 0],
|
||||||
|
'time_imag': [0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
'description': 'czy - coef6'
|
||||||
|
},
|
||||||
|
'coef7': {
|
||||||
|
'amp_real': [0, 0.0282, 0, 0.0130, 0, 0, 0, 0],
|
||||||
|
'amp_imag': [0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
'time_real': [-0.0193, -0.0051, -0.0012, -0.0020, 0, 0, 0, 0],
|
||||||
|
'time_imag': [0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
'description': 'czy - coef7'
|
||||||
|
},
|
||||||
|
'coef8': {
|
||||||
|
'amp_real': [0.0314*1, 0.0132*1, 0.0055*1, 0.0017*1, 0.0282*1, 0.0130*1, 0.0024*1, 0.0021*1],
|
||||||
|
'amp_imag': [0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
'time_real': [-0.0096, -0.0021, -0.0009, -0.0002, -0.0051, -0.0020, -0.0027, -0.0027],
|
||||||
|
'time_imag': [0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
'description': 'thfu - coef8'
|
||||||
|
},
|
||||||
|
'coef9': {
|
||||||
|
'amp_real': [0.0314*1, 0.0132*1, 0.0055*1, 0.0017*1, 0.0282*1, 0.0130*1, 0.0024*1, 0.0021*1],
|
||||||
|
'amp_imag': [0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012],
|
||||||
|
'time_real': [-0.0096, -0.0021, -0.0009, -0.0011, -0.0051, -0.0020, -0.0027, -0.0027],
|
||||||
|
'time_imag': [-1/300, -1/500, -1/15, -1/20, -1/100, -1/200, -1/400, -1/800],
|
||||||
|
'description': 'thfu - coef9'
|
||||||
|
},
|
||||||
|
'custom': {
|
||||||
|
'amp_real': [0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
'amp_imag': [0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
'time_real': [0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
'time_imag': [0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
'description': '自定义系数组 - 需要手动设置'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#### regfile base address ####
|
||||||
|
addr_base = {
|
||||||
|
'SYST_BASE': 0x0000000,
|
||||||
|
'ITCM0_BASE': 0x0100000,
|
||||||
|
'DTCM0_BASE': 0x0200000,
|
||||||
|
'CTRL0_BASE': 0x0300000,
|
||||||
|
'TCCO0_BASE': 0x0301000,
|
||||||
|
'ENVI0_BASE': 0x0400000,
|
||||||
|
'ENVM0_BASE': 0x0500000,
|
||||||
|
'DACR0_BASE': 0x0600000,
|
||||||
|
'DCBI0_BASE': 0x0601000,
|
||||||
|
'ITCM1_BASE': 0x0700000,
|
||||||
|
'DTCM1_BASE': 0x0800000,
|
||||||
|
'CTRL1_BASE': 0x0900000,
|
||||||
|
'TCCO1_BASE': 0x0901000,
|
||||||
|
'ENVI1_BASE': 0x0A00000,
|
||||||
|
'ENVM1_BASE': 0x0B00000,
|
||||||
|
'DACR1_BASE': 0x0C00000,
|
||||||
|
'DCBI1_BASE': 0x0C01000,
|
||||||
|
'ITCM2_BASE': 0x0D00000,
|
||||||
|
'DTCM2_BASE': 0x0E00000,
|
||||||
|
'CTRL2_BASE': 0x0F00000,
|
||||||
|
'TCCO2_BASE': 0x0F01000,
|
||||||
|
'ENVI2_BASE': 0x1000000,
|
||||||
|
'ENVM2_BASE': 0x1100000,
|
||||||
|
'DACR2_BASE': 0x1200000,
|
||||||
|
'DCBI2_BASE': 0x1201000,
|
||||||
|
'ITCM3_BASE': 0x1300000,
|
||||||
|
'DTCM3_BASE': 0x1400000,
|
||||||
|
'CTRL3_BASE': 0x1500000,
|
||||||
|
'TCCO3_BASE': 0x1501000,
|
||||||
|
'ENVI3_BASE': 0x1600000,
|
||||||
|
'ENVM3_BASE': 0x1700000,
|
||||||
|
'DACR3_BASE': 0x1800000,
|
||||||
|
'DCBI3_BASE': 0x1801000,
|
||||||
|
'DBGM_BASE': 0x1900000,
|
||||||
|
'INTP_BASE': 0x1F00000
|
||||||
|
}
|
||||||
|
|
||||||
|
fs = 750 #MHz
|
||||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue