logo资料库

频率测量的Verilog代码.doc

第1页 / 共4页
第2页 / 共4页
第3页 / 共4页
第4页 / 共4页
资料共4页,全文预览结束
//测量输入信号的正、负脉宽 //输出数据为脉冲所占时钟周期数 `define WIDTH 16 module pulse_width_detect ( //输入标准时钟 //输入复位信号 //输入使能输出 //输入待测信号 //输入选择输出 input i_clk, input i_rstn, input i_en_o, input i_sig, input i_sel, output o_data_ok, output [`WIDTH-1:0]o_data //输出数据 //输出数据有效 ); //r_sig 输入信号寄存器 //将输入信号与系统时钟同步化 reg r_sig; always @(posedge i_clk) if(!i_rstn) r_sig<=0; else r_sig<=i_sig; //r_rstn 复位信号寄存器 //用于检测复位信号的变化沿 reg r_rstn; always @(posedge i_clk) r_rstn <= i_rstn; //r_start、r_end 输入信号边沿寄存器 //有效时分别表示 i_sig 的上升沿、下降沿 reg r_start; reg r_end; always @(posedge i_clk) if(!i_rstn) begin r_start<=0; r_end <= 0; end else begin r_start<=(i_sig ==1 && r_sig == 0 && r_rstn == 1) ? 'b1 :'b0;//上升沿 r_end <=(i_sig ==0 && r_sig == 1 && r_rstn == 1) ? 'b1 :'b0;//下跳沿 end reg [`WIDTH-1:0]r_pos; reg [`WIDTH-1:0]r_neg;
//r_start_pos、r_start_neg 高、低电平计时器开关 //有效时分别表示允许对高、低电平计时器计时 reg r_start_pos; reg r_start_neg; always @(posedge i_clk) if(!i_rstn) begin r_start_pos<=0; r_start_neg<=0; end else begin if(r_start) begin//在上升沿开始测量高电平周期 if(r_pos ==0) r_start_pos <= 1; r_start_neg <= 0; end else if(r_end) begin//在下降沿开始测量低电平周期 r_start_pos <= 0; if(r_neg ==0) r_start_neg <= 1; end end //每个时钟上升沿对有效输入信号计时 always @(posedge i_clk) if(!i_rstn) r_pos<=0; else if(r_start_pos) r_pos <= r_pos + 1; //每个时钟上升沿对有效输入信号计时 always @(posedge i_clk) if(!i_rstn) r_neg<=0; else if(r_start_neg) r_neg <= r_neg + 1; //测量时输出无效、不测量时输出有效 assign o_data_ok = ( r_start_pos |r_start_neg ) ? 'b0 : 'b1 ; //当禁止输出时输出高阻;允许输出时,根据 i_sel 确定输出数据 assign o_data = i_en_o ? (i_sel ? r_pos : r_neg ): 'bz ; endmodule
; 测量向量 `define WIDTH 16 module freq_tb ; ; ; ; ; i_sel o_data_ok i_en_o ; i_clk [`WIDTH-1:0] o_data i_sig i_rstn reg wire reg reg wire reg reg ; pulse_width_detect DUT ( .i_sel (i_sel ) , .o_data_ok (o_data_ok ) , .i_en_o (i_en_o ) , .i_clk (i_clk ) , .o_data (o_data ) , .i_sig (i_sig ) , .i_rstn (i_rstn ) ); initial begin i_clk = 0; i_sig = 0; i_rstn = 0; i_sel = 0; #200 i_rstn = 1; end initial begin i_en_o = 1; #2000 i_en_o = 0; #1000 i_en_o = 1; end always #50 i_clk = ~i_clk ; reg [8:0]cnt; always @(posedge i_clk) if(!i_rstn) cnt<=0; else cnt<=cnt+ 1;
reg [12:0]cnt1; always @(posedge i_clk) if(!i_rstn) cnt1<=0; else cnt1<=cnt1+ 1; always @(posedge i_clk) if(cnt1 == 12'hfff) begin i_rstn = 0; #200 i_rstn = 1; end always @(posedge i_clk) if(cnt == 128) i_sig <= {$random}%2; always @(posedge i_clk) if(cnt == 10 ) i_sel <= ~ i_sel ; endmodule
分享到:
收藏