Verilog 如何编写一个能够计算信号上升和下降的可合成RTL

Verilog 如何编写一个能够计算信号上升和下降的可合成RTL,verilog,system-verilog,register-transfer-level,Verilog,System Verilog,Register Transfer Level,我想测量信号的上升跃迁和下降跃迁的数量。我使用该信号作为时钟,并实现了2个计数器。一个计数器在每个上升沿上递增,另一个计数器在每个下降沿上递增。我将这两个计数器的结果相加,以获得最终的计数值 有没有更好的方法来实现这个逻辑?最稳健的方法是什么 module clock_edge_counter ( clock_edge_count, // Output of the counter , clk , // clock Input stop , reset

我想测量信号的上升跃迁和下降跃迁的数量。我使用该信号作为时钟,并实现了2个计数器。一个计数器在每个上升沿上递增,另一个计数器在每个下降沿上递增。我将这两个计数器的结果相加,以获得最终的计数值

有没有更好的方法来实现这个逻辑?最稳健的方法是什么

module clock_edge_counter    (
clock_edge_count,    // Output of the counter  , 
clk     ,          // clock Input
stop ,
reset 
);

parameter CNTR_WIDTH = 16;

input clk ;
input stop ;
input reset ;

output [CNTR_WIDTH:0] clock_edge_count;
wire [CNTR_WIDTH:0] clock_edge_count;


reg [CNTR_WIDTH-1:0] clock_negedge_edge_count;
reg [CNTR_WIDTH-1:0] clock_posedge_edge_count;


always @(posedge clk or posedge reset)
 if (reset) begin
   clock_posedge_edge_count <= 0;
 end
 else if (!stop) begin
   clock_posedge_edge_count <= clock_posedge_edge_count + 1;
 end

always @(negedge clk or posedge reset)
 if (reset) begin
   clock_negedge_edge_count <= 0;
 end
 else if (!stop) begin
   clock_negedge_edge_count <= clock_negedge_edge_count + 1;
 end


assign clock_edge_count = clock_negedge_edge_count + clock_posedge_edge_count;

endmodule
模块时钟边缘计数器(
时钟\u边缘\u计数,//计数器的输出,
时钟,//时钟输入
停止
重置
);
参数CNTR_WIDTH=16;
输入时钟;
输入停止;
输入复位;
输出[CNTR_宽度:0]时钟边缘计数;
导线[CNTR_宽度:0]时钟边缘计数;
reg[CNTR_宽度-1:0]时钟负边缘计数;
reg[CNTR\u WIDTH-1:0]时钟边缘边缘边缘计数;
始终@(posedge clk或posedge重置)
如果(重置)开始

clock_posedge_edge_count从理论上讲,这种方法没有错,但将信号用作时钟并不是一种标准做法。这将逻辑引入到时钟生成中,这对于物理设计或后端流和工具来说是很麻烦的(并非不可能)

[至少有一个额外的逆变器以及输入信号将带来的逻辑]

以下链接中的示例-

如果信号是异步的,并且是从外部模块生成的,则可以对其进行同步,然后使用边缘检测器逻辑。然后使用该输出触发计数。

如果可以访问时钟,那么最好让时钟检测信号的下降沿和上升沿,并使用它进行计数。 下面是示例代码

module clock_edge_counter    (
clock_edge_count,    // Output of the counter  ,
clk     ,          // clock
detect ,  // signal to be checked
stop ,
reset
);

parameter CNTR_WIDTH = 16;

input clk ;
input detect;
input stop ;
input reset ;

output [CNTR_WIDTH:0] clock_edge_count;
reg [CNTR_WIDTH:0] clock_edge_count;


reg                  detect_d;

always @(posedge clk or posedge reset)
 begin
 if (reset)
   detect_d <= 0 ; 
  else
   detect_d <= detect; // delay signal by one cycle
 end

always @(posedge clk or posedge reset)
 if (reset) begin
   clock_edge_count <= 0;
 end
//                       rising edge        or    falling edge      ( xor logic )
 else if (!stop && ( (!detect && detect_d ) || (detect && !detect_d ) ) )
    begin
   clock_edge_count <= clock_edge_count + 1;
 end

endmodule
模块时钟边缘计数器(
时钟\u边缘\u计数,//计数器的输出,
时钟,//时钟
检测,//要检查的信号
停止
重置
);
参数CNTR_WIDTH=16;
输入时钟;
输入检测;
输入停止;
输入复位;
输出[CNTR_宽度:0]时钟边缘计数;
reg[CNTR_宽度:0]时钟边缘计数;
注册检测;
始终@(posedge clk或posedge重置)
开始
如果(重置)

谢谢你的解释,拉胡尔。