除拖尾矫正功能没完成,其他均完成
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