除拖尾矫正功能没完成,其他均完成

This commit is contained in:
yangshenbo 2026-07-25 23:02:18 +08:00
commit a5a4bd1da5
23 changed files with 3257 additions and 0 deletions

View File

@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@ -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>

View File

@ -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>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

View File

@ -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>

View File

@ -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>

View File

@ -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)

View File

@ -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)

View File

@ -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')

View File

@ -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(开启) -> 0False(关闭) -> 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)

View File

@ -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()

View File

@ -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)

View File

@ -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()

View File

@ -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 未安装,跳过绘图")
"""

View File

@ -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')

View File

@ -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,
}

View File

@ -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