时钟边沿上的 verilog 多路复用器

Posted

技术标签:

【中文标题】时钟边沿上的 verilog 多路复用器【英文标题】:verilog mux on clock edge 【发布时间】:2012-06-01 03:29:57 【问题描述】:

如何使用时钟边沿作为多路复用器的选择器, 我想做什么:

input clk, in1, in2;
output out;
always@ (posedge clk) begin out<=in1; end
always@(negedge clk) begin out<=in2; end

但是,这是不可综合的,因为多个驱动程序位于单独的 always 块中。有什么解决办法吗?

【问题讨论】:

像这样使用时钟作为数据通常是个坏主意,对于 ASIC 可能会导致平衡时钟树的问题。 这是用时钟作为数据吗?在我看来,这就像在某些时间点捕获价值。因此与提供的其他答案有点不同。不过我对verilog的经验并不是很丰富,所以我可能错了。 @JohnB 它使用时钟作为数据路径锥体的输入,所以我想说这与使用时钟作为数据相同。时钟通常应仅用于计时。 如果您想获得 DDR 信号,您可以在许多 FPGA 上这样做,但您必须直接实例化这些原语。 我之前也遇到过类似的问题。您可以使用边沿检测电路检测信号或时钟的边沿,以避免合成器的抱怨。这是我的问题的链接。 ***.com/questions/8413661/… 【参考方案1】:

这应该可以得到你想要的。这是否是一个好主意取决于你在做什么。

input clk, in1, in2;
output out;
assign out = clk ? in1 : in2;

【讨论】:

根据我的经验,所有使用双边触发器的答案都不会通过合成器。只有这个答案提供了一个可综合的解决方案。在组合电路中使用时钟肯定是不好的,但是这个很管用。【参考方案2】:

正如其他人提到的,使用时钟作为数据并不常见。使用 dwikle 的答案可以实现组合多路复用器,但是如果您真的想以失败告终(在这种情况下, out 应该是 reg 或 logic 类型,这在您的原始代码),然后您可以编写:

always@(edge clk) 
begin
    unique case(clk)
        1'b0:    out <= in1;
        1'b1:    out <= in2;
    endcase
end

或者等效地你可以使用@(negedge clk or posedge clk) 代替edge。 然而,这可能会混淆您的综合工具。可能,以下内容更简单:

always@(posedge clk) 
    out1 <= in1;
always@(negedge clk) 
    out2 <= in2;
assign out = clk ? out1 : out2;

【讨论】:

【参考方案3】:

像这样:

module mux1_2(input clk, d0, d1,
              input sel,
              output reg y);

    always@(posedge clk)
    begin
        case(sel)
            1'b0:    y <= d0;
            1'b1:    y <= d1;
        endcase
    end

endmodule

但是,您应该听从其他人的建议。多路复用器是非常基本的组合设备,我看不到任何需要在其上放置时钟的情况。

【讨论】:

以上是关于时钟边沿上的 verilog 多路复用器的主要内容,如果未能解决你的问题,请参考以下文章

VHDL:当涉及时钟信号时,多路复用器输出不跟随输入

行为verilog:使用1个模块创建多个多路复用器

hdl 中的管道多路复用器

Verilog 没有给出预期的结果

TCA9548A-I2C多路复用器介绍

VHDL:11 条总线之间的多路复用器 8 位宽输出