Verilog HDL 测量相位差

源程序:

//测量两路信号相位差
//要求两路信号除相位不同外,其他信息必须完全一致
`define WIDTH 16
module phase_diff_detect
(
	input i_clk,	//输入标准时钟
	input i_rstn,	//输入复位信号
	input i_en_o,	//输入使能输出
	input i_sig1,	//输入待测信号1
	input i_sig2,	//输入待测信号2
	output o_data_ok,	//输出数据有效
	output [`WIDTH - 1:0]o_data	//输出数据
);

//r_sig1 输入信号1寄存器
//将输入信号1与系统时钟同步化
reg r_sig1;
always @(posedge i_clk)
	if(!i_rstn)
		r_sig1<=0;
	else
		r_sig1<=i_sig1;

//r_sig2 输入信号2寄存器
//将输入信号2与系统时钟同步化
reg r_sig2;
always @(posedge i_clk)
	if(!i_rstn)
		r_sig2<=0;
	else
		r_sig2<=i_sig2;
		
//r_rstn 复位信号寄存器
//用于检测复位信号的变化沿		
reg r_rstn;
always @(posedge i_clk)
	r_rstn <= i_rstn;
	
//r_start1输入信号1上升沿寄存器
reg r_start1;
always @(posedge i_clk)
	if(!i_rstn)
		r_start1<=0;
	else
		r_start1<=(i_sig1 ==1 && r_sig1 == 0 && r_rstn == 1) ? 'b1 :'b0;//上升沿

//r_start2输入信号2上升沿寄存器		
reg r_start2;
always @(posedge i_clk)
	if(!i_rstn)
		r_start2<=0;
	else
		r_start2<=(i_sig2 ==1 && r_sig2 == 0 && r_rstn == 1) ? 'b1 :'b0;//上升沿

//r_data数据寄存器
reg [`WIDTH - 1:0] r_data;

//r_detect_avail 测量相位差计时允许开关
//当处于两个信号上升沿之间时开关打开,其他情况下开关关闭
reg r_detect_avail;
always @(posedge i_clk)
	if(!i_rstn)
		r_detect_avail<=0 ;
	else
		if(r_start1 && r_data == 0)
			r_detect_avail <= 1 ;
		else if(r_start2)
			r_detect_avail <= 0 ;
		else
			r_detect_avail <= r_detect_avail ;

//相位差计时
always @(posedge i_clk)
	if(!i_rstn)
		r_data<=0 ;
	else
		if(r_detect_avail)
			r_data <= r_data + 1;
			
//测量时输出无效、不测量时输出有效
assign o_data_ok = r_detect_avail ? 'b0 : 'b1;

assign o_data = i_en_o ? r_data : 'bz;

endmodule

 

测试向量:

 

`define WIDTH 16

module phase_tb  ; 
 
  reg    i_sig1   ; 
  wire    o_data_ok   ; 
  reg    i_sig2   ; 
  reg    i_en_o   ; 
  reg    i_clk   ; 
  wire  [`WIDTH - 1:0]  o_data  ; 
  reg    i_rstn   ; 
  phase_diff_detect  
   DUT  ( 
       .i_sig1 (i_sig1 ) ,
      .o_data_ok (o_data_ok ) ,
      .i_sig2 (i_sig2 ) ,
      .i_en_o (i_en_o ) ,
      .i_clk (i_clk ) ,
      .o_data (o_data ) ,
      .i_rstn (i_rstn ) ); 
initial begin
    i_clk = 0;
    i_sig1 = 0;
    i_rstn = 0;
    #200
    i_rstn = 1;
end
initial begin
    i_en_o = 1;
    #20000
    i_en_o = 0;
    #30000
    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;
      
always @(posedge i_clk)
   if(!i_rstn) 
      i_sig1<= 0;
   else
     if(cnt == 10)
         i_sig1 <= {$random}%2;

always @(posedge i_clk)
   if(!i_rstn) 
      i_sig2<= 0;
   else
      i_sig2 <= #8000 i_sig1;
   
endmodule


功能仿真波形:

  • 2
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sanzhong104204

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值