如何编写可以计算信号上升和下降的可综合RTL

时间:2016-07-12 21:05:10

标签: verilog system-verilog register-transfer-level

我想测量信号的上升转换和下降转换的数量。我使用信号作为时钟并实现了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

1 个答案:

答案 0 :(得分:3)

这种方法在理论上没有任何错误,但使用信号作为时钟并不是标准做法。这为您的时钟生成引入了逻辑,这对于物理设计或后端流程和工具来说是繁琐的(并非不可能)。

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

以下链接中的示例 - Proper way for signal edge detection in Verilog

如果信号是异步的并且是从外部模块生成的,您可以同步它,然后使用边沿检测器逻辑。然后使用该输出来触发计数。 https://www.doulos.com/knowhow/fpga/synchronisation/

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

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

最后,输出(计数器)的使用将在同步块中,因此最好在clock_edge_counter中使用结果块的时钟。