verilog - 从模块参数中选择 posedge/negedge 灵敏度的最短版本?

标签 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

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

最佳答案

最简单的方法是用异或门反转时钟。然后在 always 部分使用该时钟:

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 都会稍微滞后系统时钟。数量取决于异或门的延迟。 这是一个模拟+: enter image description here

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

关于verilog - 从模块参数中选择 posedge/negedge 灵敏度的最短版本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49998405/

相关文章:

Verilog,我可以为always block 内的多个位分配一个位值吗

verilog - 如何在Verilog中将长语句分成几行

verilog - "<signal> is not a constant"if 语句中的错误

verilog - 在(系统)verilog 仿真中从命令行定义参数

verilog - 如何在verilog中给二维数组一个初始值

Verilog在for循环中指定 block

verilog 生成 if/else

verilog - 在 Verilog 中使用静态值

function - 在 2 个 Verilog 模块中重用相同的函数

vhdl - 是否可以使用Quartus在VHDL代码中调用Verilog函数