缩短版本以从模块参数中选择posedge / negedge灵敏度?

时间:2018-04-24 09:45:33

标签: verilog

我想构建一个Verilog模块,以便用户可以通过模块参数选择某些输入时钟信号的灵敏度。作为一个例子,我编写了以下计数器,它可以计算参数clockEdge选择的posedge或negedge。

module Counter (clk, reset, value);
parameter clockEdge = 1; // react to rising edge by default

input clk;
input reset;
output reg [7:0] value;

generate
    if(clockEdge == 1) begin
        always @(posedge clk or posedge reset) begin
            if (reset) begin
                value <= 0;
            end else begin
                value <= value + 1;
            end
        end
    end else begin
        always @(negedge clk or posedge reset) begin
            if (reset) begin
                value <= 0;
            end else begin
                value <= value + 1;
            end
        end
    end
endgenerate

endmodule

这个原则是有效的,但我不喜欢这两种变体的实现基本上是复制和粘贴。什么是没有重复的较短版本?

3 个答案:

答案 0 :(得分:2)

最简单的方法是使用exor门反转时钟。然后在always section中使用该时钟:

wire user_clock;
assign user_clock = clk ^ falling_edge;

always @(posedge user_clock) // or posedge/negedge reset/_n etc.
   test_signal <= ~ test_signal;

如果falling_edge为0,则user_clock和clk具有相同的极性,并且数据的计时时间与clk的上升沿几乎相同。
如果falling_edge为1,则user_clock和clk具有相反的极性,并且数据的时钟频率与clk的下降沿几乎相同。

更改falling_edge的极性时要小心,因为它会产生欠幅脉冲!最安全的是使用门控时钟:停止时钟,切换极性,然后再次启动。

在这两种情况下,user_clock都会滞后系统clk少量。数量取决于exor-gate的延迟。 这是一个模拟 + :        enter image description here

+ test_signal在初始语句中设置为零。

答案 1 :(得分:1)

我认为这个小例子中的cut-n-paste是可以的,尽管verilog有一些工具可以让它更容易处理更复杂的情况,即函数和宏。你也可以使用它们,即

{
    "error": {
        "name": "malformedRequestError",
        "message": "Missing required property: environment"
    }
}

另一种可能性是使用带或不带参数的宏。方法方面的宏通常比函数更糟糕,虽然这是一个极端的例子,但在我看来,它使代码的可读性降低,并且可能会出现调试工具的问题。

 function newValue(input reset, input reg[7:0] oldValue);
    if (reset) begin
       newValue = 0;
    end else begin
       newValue = value + 1;
    end
 endfunction

 generate
    if(clockEdge == 1) begin
       always @(posedge clk or posedge reset) begin
          value <= newValue(reset, value);
       end
    end else begin
       always @(negedge clk or posedge reset) begin
          value <= newValue(reset, value);
       end
    end
 endgenerate

答案 2 :(得分:0)

在clk的posedge或negedge之后实现自定义时钟reg可能是一种方法。这似乎在我的机器上运行良好:)

<p></p>