我的是12位adc
目录
1.vpp_calc测量峰峰值
2.freq_calc等精度数字频率计
3.脉冲生成模块
模块3是配合1,2使用的
// 峰峰值测量模块 12位adc 单位用mV
module vpp_calc(
input ad_clk, // AD时钟
input clk_50,
input rst_n, // 复位信号
input [11:0] ad_data, // AD输入数据
input ad_pulse, // 由AD波形得到的脉冲信号
output reg [11:0] ad_vpp, // AD峰峰值 单位是mv
output reg [11:0] ad_max, // AD最大值
output reg [11:0] ad_min // AD最小值
);
reg vpp_flag; // 测量峰峰值标志信号
reg vpp_flag_d; // vpp_flag 滞后一个ad_clk周期
reg [11:0] ad_data_max; // AD一个周期内的 当前 最大值
reg [11:0] ad_data_min; // AD一个周期内的 当前 最小值
wire vpp_flag_pos; // vpp_flag上升沿标志信号
wire vpp_flag_neg; // vpp_flag下降沿标志信号
//边沿检测
//捕获信号上升沿
assign vpp_flag_pos = (~vpp_flag_d) & vpp_flag;
//下降沿
assign vpp_flag_neg = vpp_flag_d & (~vpp_flag);
//利用vpp_flag标志一个被测时钟周期 ----------------- ad_pulse是待测信号同频率的一个方波(比较后得到的)
always @(posedge ad_pulse or negedge rst_n) begin
if(!rst_n)
vpp_flag <= 1'b0;
else
vpp_flag <= ~vpp_flag;
end
//将vpp_flag延时一个AD时钟周期
always @(posedge ad_clk or negedge rst_n) begin
if(!rst_n)
vpp_flag_d <= 1'b0;
else
vpp_flag_d <= vpp_flag;
end
//筛选一个被测时钟周期内的最大/最小值
always @(posedge ad_clk or negedge rst_n) begin
if(!rst_n) begin
ad_data_max <= 11'd0;
ad_data_min <= 11'd0;
end
else if(vpp_flag_pos)begin //测试开始时,默认比较值都为当前adc值
ad_data_max <= ad_data;
ad_data_min <= ad_data;
end
else if(vpp_flag_d) begin
if(ad_data > ad_data_max)
ad_data_max <= ad_data; //计算最大值
if(ad_data < ad_data_min)
ad_data_min <= ad_data; //计算最小值
end
end
//计算被测时钟周期内的峰峰值
always @(posedge ad_clk or negedge rst_n) begin
if(!rst_n) begin
ad_vpp <= 12'd0;
ad_max <= 12'd0;
ad_min <= 12'd0;
end
else if(vpp_flag_neg) begin // 测量结束时结算
ad_vpp <= ((ad_data_max - ad_data_min)*1000)/968; //根据ADC来调整 vpp=1v对应968
ad_max <= ad_data_max;
ad_min <= ad_data_min;
end
end
endmodule
测正弦波频率,直接拿最高位给数字频率计,相当于trigger为0,也可以自己设置trigger的值,每次比较产生一个方波,然后给数字频率计测频率
module freq_calc
(
input wire sys_clk , // 50MHz
input wire sys_rst_n ,
input wire clk_test , // 待测信号
input wire stand_clk , // 100MHz
output reg [33:0] freq
);
parameter CNT_GATE_S_MAX = 28'd74_999_999 ,
CNT_RISE_MAX = 28'd12_500_000 ;
parameter CLK_STAND_FREQ = 28'd100_000_000 ;
wire clk_stand ;
wire gate_a_fall_s ;
wire gate_a_fall_t ;
reg [27:0] cnt_gate_s ;
reg gate_s ;
reg gate_a ;
reg gate_a_stand ;
reg gate_a_test ;
reg [47:0] cnt_clk_stand ;
reg [47:0] cnt_clk_stand_reg ;
reg [47:0] cnt_clk_test ;
reg [47:0] cnt_clk_test_reg ;
reg calc_flag ;
reg [63:0] freq_reg ;
reg calc_flag_reg ;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_gate_s <= 28'd0;
else if(cnt_gate_s == CNT_GATE_S_MAX)
cnt_gate_s <= 28'd0;
else
cnt_gate_s <= cnt_gate_s + 1'b1;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
gate_s <= 1'b0;
else if((cnt_gate_s>= CNT_RISE_MAX)
&& (cnt_gate_s <= (CNT_GATE_S_MAX - CNT_RISE_MAX)))
gate_s <= 1'b1;
else
gate_s <= 1'b0;
always@(posedge clk_test or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
gate_a <= 1'b0;
else
gate_a <= gate_s;
always@(posedge clk_stand or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_clk_stand <= 48'd0;
else if(gate_a == 1'b0)
cnt_clk_stand <= 48'd0;
else if(gate_a == 1'b1)
cnt_clk_stand <= cnt_clk_stand + 1'b1;
always@(posedge clk_test or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_clk_test <= 48'd0;
else if(gate_a == 1'b0)
cnt_clk_test <= 48'd0;
else if(gate_a == 1'b1)
cnt_clk_test <= cnt_clk_test + 1'b1;
always@(posedge clk_stand or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
gate_a_stand <= 1'b0;
else
gate_a_stand <= gate_a;
assign gate_a_fall_s = ((gate_a_stand == 1'b1) && (gate_a == 1'b0))
? 1'b1 : 1'b0;
always@(posedge clk_stand or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_clk_stand_reg <= 32'd0;
else if(gate_a_fall_s == 1'b1)
cnt_clk_stand_reg <= cnt_clk_stand;
always@(posedge clk_test or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
gate_a_test <= 1'b0;
else
gate_a_test <= gate_a;
assign gate_a_fall_t = ((gate_a_test == 1'b1) && (gate_a == 1'b0))
? 1'b1 : 1'b0;
always@(posedge clk_test or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_clk_test_reg <= 32'd0;
else if(gate_a_fall_t == 1'b1)
cnt_clk_test_reg <= cnt_clk_test;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
calc_flag <= 1'b0;
else if(cnt_gate_s == (CNT_GATE_S_MAX - 1'b1))
calc_flag <= 1'b1;
else
calc_flag <= 1'b0;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
freq_reg <= 64'd0;
else if(calc_flag == 1'b1)
freq_reg <= (CLK_STAND_FREQ * cnt_clk_test_reg / cnt_clk_stand_reg ) + 1'd1;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
calc_flag_reg <= 1'b0;
else
calc_flag_reg <= calc_flag;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
freq <= 34'd0;
else if(calc_flag_reg == 1'b1)
freq <= freq_reg;
assign clk_stand = stand_clk;
endmodule
module pulse_gen(
input rst_n, //系统复位,低电平有效
input [11:0] trig_level,
input ad_clk, //ADC模块驱动时钟
input [11:0] ad_data, //AD输入数据 12位
output ad_pulse //输出的脉冲信号
);
parameter CNT_MAX = 10'd20;
//reg define
reg [12:0] cnt;
reg pulse;
reg pulse_delay;
reg pulse_delay2;
reg pulse_delay3;
assign ad_pulse = pulse & pulse_delay & pulse_delay2 & pulse_delay3;
//根据触发电平,将输入的AD采样值转换成高低电平
always @ (posedge ad_clk or negedge rst_n)begin
if(!rst_n)
pulse <= 1'b0;
else
if(ad_data < trig_level)
pulse <= 1'b0;
else
pulse <= 1'b1;
end
always@(posedge ad_clk or negedge rst_n)
if(rst_n == 1'b0)
cnt <= 20'b0;
else if(pulse == 1'b0)
cnt <= 20'b0;
else if(cnt == CNT_MAX && pulse == 1'b1)
cnt <= cnt;
else
cnt <= cnt + 1'b1;
//延时一个时钟周期,用于消除抖动
always @ (posedge ad_clk or negedge rst_n)begin
if(!rst_n)
pulse_delay <= 1'b0;
else
pulse_delay <= pulse;
end
//延时一个时钟周期,用于消除抖动
always @ (posedge ad_clk or negedge rst_n)begin
if(!rst_n)
pulse_delay2 <= 1'b0;
else
pulse_delay2 <= pulse_delay;
end
//延时一个时钟周期,用于消除抖动
always @ (posedge ad_clk or negedge rst_n)begin
if(!rst_n)
pulse_delay3 <= 1'b0;
else
pulse_delay3 <= pulse_delay2;
end
endmodule