基于FPGA的数字示波器采样/触发通道 参考设计
信号的时域测量技术在信号处理领域中有着广泛的应用, 例如,在数字通信系统中, 当接收机捕获到同步信号波形后, 会启动后续的信号处理流程对接收波形进行波形分析和信息提取。 而雷达接收机则会以发送脉冲的时间点作为基准时刻,测量出捕获到的回波脉冲和发送脉冲之间的相对时延, 进而解算出目标距离。
时域测量的另一个重要应用是无线电定位系统,这种系统常见的体制有单发多收和单收多发两种制式, 其测量原理均是先测量出无线电波在多个时间同步的收发机之间的多组传播延迟时间差, 然后根据多个已知的收/发机坐标解算出一个未知的收/发机坐标。(类似于中学几何中的三角测量法)
在上面描述的所有信号处理设备中,都存在着一个共同的相似过程,就是首先在时间轴上对输入信号进行处理, 然后根据处理结果得到一个时间节点,进而保存输入信号在该时间节点之后的一段足够长的波形数据, 作为后续处理的原始数据波形。 从电路行为上来看,上述过程就是一个带有时间触发功能的数字示波器的电路行为。
时域触发技术是示波器的重要的概念 ,例如,假设存在一个用电压表示的具有无穷时间长度的正弦信号, 并且我们有某种技术手段可以把时域上的一段电压信号显示在一个电子屏幕上。 如果我们需要在屏幕上显示 该正弦信号时间长度为1秒的一段时域波形,那么 请思考以下问题:
所谓自由触发是指,在任意的时刻,把待观测信号依照时间顺序,切成小的时域段落,然后绘制到显示器屏幕上。
下图给出了一个具有无穷时间长度的正弦信号,截取出5秒的时域信号样本作为测试信号s0,然后将信号s0连续 的分割为1秒的信号段落,再把这些信号段落绘制到显示图形终端上。
自由触发仿真结果 |
% trigger_show_free.m close all; clc;clear; freq_s0 = 1.47 ; % frequency in Hz fs = 1E3 ; % sample rate in Hz init_phase = pi/2 ; % init phase time_span = 1 ; % time span in second time_signal_len = 5 ; % total signal length % signal sample amount N_sample_span = time_span * fs ; N_sample_signal = time_signal_len * fs; % index idx_span = [0:(N_sample_span -1) ]; idx_signal = [0:(N_sample_signal-1)]; % time axis t_idx_span = idx_span /fs; t_idx_signal = idx_signal/fs; % signal s0 = sin(2*pi*freq_s0/fs*idx_signal + init_phase); % time base time_base = zeros(N_sample_signal, 1); for(ii = 1: N_sample_signal) time_base(ii) = mod(ii, N_sample_span)/fs; end % plot figure; % signal tt_str = ['Signal S0, Freq : ',num2str(freq_s0),' Hz, ', 'Fs: ', num2str(fs), ' Hz, ', ... 'Signal Len: ', num2str(time_signal_len), ' sec' ]; subplot(3,1,1); plot(t_idx_signal, s0, 'LineWidth', 1.2); grid on; title(tt_str, 'fontsize', 12); tt_str = ['Time Base Line: 0 to ', num2str(time_span), ' sec']; subplot(3,1,2); plot(t_idx_signal, time_base, 'LineWidth', 1.2);grid on; title(tt_str,'fontsize', 12 ); tt_str = ['Free Trigger Signal Plot, Time Span : ',num2str(time_span),' sec' ]; subplot(3,1,3); plot(time_base, s0, '.');grid on; title(tt_str, 'fontsize', 12);
在实际工作中,示波器的常用触发方式是带有方向性的电平触发方式,比如:
在设计示波器时,触发电路有模拟触发和数字触发两种方式,即
下图展示了一种正向电平触发的仿真结果, 在该仿真中,触发电平被设定为一个电平区间 当有信号样值落入电平值区间,并且信号以正向方式进入该区间时,产生触发信号,启动TimeBase时基信号增长。 图中正弦波形子图中的两条横线,表示的是电平触发区间的边界电平值。
正向电平触发仿真结果 |
同样,也可以有负向通过电平区间的触发方式,如下图所示:
负向电平触发仿真结果 |
以及, 如下图所示的,双向进入触发区间的触发方式,这种方式在观察数字基带传输信号的眼图时,比较有用。
双向电平触发仿真结果 |
以下是可以设定触发模式的Matlab仿真代码
% trigger_show_mode.m close all; clc;clear; POS_TRIGGER = 0; NEG_TRIGGER = 1; BTH_TRIGGER = 2; % config parameter freq_s0 = 1.13 ; % frequency in Hz fs = 1E3 ; % sample rate in Hz init_phase = pi/2 ; % init phase time_span = 1 ; % time span in second time_signal_len = 5 ; % total signal length trig_max_val = 0.302 ; trig_min_val = 0.1 ; mode = POS_TRIGGER ; % mode = NEG_TRIGGER ; % mode = BTH_TRIGGER ; % signal sample amount N_sample_span = time_span * fs ; N_sample_signal = time_signal_len * fs; % trigger line trig_max_line = trig_max_val * ones(N_sample_signal,1); trig_min_line = trig_min_val * ones(N_sample_signal,1); % index idx_span = [0:(N_sample_span -1) ]; idx_signal = [0:N_sample_signal-1]; % time axis t_idx_span = idx_span /fs; t_idx_signal = idx_signal/fs; % signal s0 = sin(2*pi*freq_s0/fs*idx_signal + init_phase); % time base time_base = zeros(N_sample_signal, 1); time_base(1) = 0; ii = 2; time_base(1) = 0; while(ii <= N_sample_signal) trigger_on = 0; % check trigger condition is_data_up = (s0(ii) > s0(ii-1)); is_data_down = (s0(ii) < s0(ii-1)); is_in_range = (s0(ii) > trig_min_val) && (s0(ii) < trig_max_val); if((mode == POS_TRIGGER) && is_data_up && is_in_range) trigger_on = 1; end if((mode == NEG_TRIGGER) && is_data_down && is_in_range) trigger_on = 1; end if((mode == BTH_TRIGGER) && 1 && is_in_range) trigger_on = 1; end if(trigger_on) for(jj = 0:N_sample_span-1) if((ii+jj) > N_sample_signal) break; end time_base(ii+jj) = mod(time_base(ii+jj-1) + 1, N_sample_span); end ii = ii + N_sample_span; else time_base(ii) = 0; ii = ii + 1; end % else trigger_on end time_base = time_base /fs; s0_show = s0; for(ii= 1:N_sample_signal) if(time_base(ii) == 0) s0_show(ii) = 0; end end % plot figure; % signal tt_str = ['Signal S0, Freq : ',num2str(freq_s0),' Hz, ', 'Fs: ', num2str(fs), ' Hz, ', ... 'Signal Len: ', num2str(time_signal_len), ' sec' ]; subplot(3,1,1); plot(t_idx_signal, s0, t_idx_signal, trig_max_line, t_idx_signal, trig_min_line, 'LineWidth', 1.5); grid on; title(tt_str, 'fontsize', 12); tt_str = ['Time Base Line: 0 to ', num2str(time_span), ' sec']; subplot(3,1,2); plot(t_idx_signal, time_base, 'LineWidth', 1.2);grid on; title(tt_str,'fontsize', 12 ); if(mode == POS_TRIGGER) mode_str = 'Pos Trigger Mode'; end if(mode == NEG_TRIGGER) mode_str = 'Neg Trigger Mode'; end if(mode == BTH_TRIGGER) mode_str = 'Both Trigger Mode'; end tt_str = [mode_str, ' Signal Plot, Time Span : ',num2str(time_span),' sec' ]; subplot(3,1,3); plot(time_base, s0_show, '.');grid on; title(tt_str, 'fontsize', 12);
电路总体结构 |
激励模块的用途是,根据输入的模式配置数据,输出正弦波或循环计数三角波,激励信号源模块的接口如下:
激励信号源模块 |
信号源激励模块电路结构如下图所示
激励信号源模块结构 |
首先由工作分频计数器模块,根据输入的工作周期分配参数,输出单周期、高电平有效的工作使能信号,该信号周期为 I_N_CLKNUM,占空比为1/ I_N_CLKNUM.
后级的相位累加计数器根据工作使能信号,在使能有效的周期动作一次,生成ROM的读取地址。
根据模式MODE信号配置,选择把地址计数信号或是ROM的读取数据信号输出作为激励信号。地址计数信号作为输出数据时, 需要使用D触发器(DFF)进行流水线延迟匹配
工作使能信号经过D触发器(DFF)进行流水延迟适配后,输出至外部作为输出有效信号
正弦激励信号整体波形图 |
计数激励信号整体波形图 |
局部时序图 |
触发模块的作用是,对每个数据样点进行检测,如果当前输出样点满足触发条件,则将其标识为“触发有效”,触发模块的接口如下:
触发模块接口 |
触发模块的工作原理如下 :
触发模块电路结构如下图所示:
触发模块电路结构 |
首先采用 Modelsim 仿真进行测试,测试执行过程如下:
Trigger 模块 Modelsim 仿真 1 |
Trigger 模块 Modelsim 仿真 2 |
触发模块的仿真代码同样支持 FPGA平台的编译, 下载编译结果后, 使用 SignalTap 作为测试工具。 为保持代码文件的可以同时兼容仿真与电路编译, 需要在testbench文件中, 使用以下编译开关
// synopsys translate_off 需要进行仿真,但不需要进行电路编译 的HDL代码 // synopsys translate_on
SignalTap的测试结果如下
Trigger 模块 SignatTap 验证 1 |
Trigger 模块 SignatTap 验证 2 |
时间基准的用途是,在主控器的控制下,把满足触发条件的波形数据写入到双口RAM中, 模块的工作过程如下:
时基模块的输入输出接口,如下图所示
时基模块接口 |
时基模块的工作状态变迁逻辑描述如下:
上述状态迁移过程如下图所示:
时基模块状态迁移逻辑 |
时基模块的电路结构由状态机 和 计数器 2部分构成。 其中状态机模块用于进行状态切换和生成计数器的控制信号,以及对输入数据进行流水线延迟适配, 使得计数器模块的输入数据和其控制信号的流水延迟时序对齐。
计数器模块由状态机启动其工作, 启动计数后,每次输入一个有效数据,计数器则生成数据RAM的写入数据及地址和写使能信号。 当RAM写满后,计数器停止动作并且置位“存储器写满”标志位信号,状态机得到此信号后,更新内部状态及输出信号, 并通知时基模块的主控信号读取RAM中的波形数据。
时基模块电路结构如下图所示
时基模块电路结构 |
时基模块电路代码经过Quartus编译后,工具提取出的 RTL View 如下图所示
时基模块电路 RTL View |
由于时基电路模块中,包含有状态机代码,因此可以使用Quartus工具的FSM View 工具对编译后的电路结果进行分析, 如下图所示,编译工具能够推断分析出代码中的状态机(图中黄色模块)。
时基模块电路 RTL View |
以及编译工具分析出的状态及迁移流程如下图所示:
时基模块电路 RTL View |
时基模块的测试方案和触发模块类似,首先使用ModelSim工具进行仿真测试, 子目录 modelsim 下 的 测试脚本 :build.do, sim_quit.do, sim_run.do 的使用方法类似,此处不再赘述。
时基模块的Testbench代码在整个仿真周期中,产生若干次的START信号,启动时基模块捕获数据。 以下是以不同的时间尺度观察的时基模块的ModelSim的仿真结果。
时基模块 ModelSim 仿真结果 1 |
时基模块 ModelSim 仿真结果 2 |
时基模块 ModelSim 仿真结果 3 |
时基模块的仿真代码同样支持在 FPGA 平台的编译, 和ModelSim仿真不同的是, 使用FPGA测试时, START启动信号上跳沿通过拨动一个拨码开关SW来输入。 使用 SignalTap 作为测试工具时,可以采用WE信号的上跳沿作为触发信号, 然后把 SignalTap的trigger position参数设定为 Pre 模式。 SignalTap 工具捕获的数据结果 以不同分辨率观察如下图所示。
时基模块 数据捕获结果 1 |
时基模块 数据捕获结果 2 |