【问题标题】:Crossing clock domain for rarly changing data跨越时钟域以处理很少变化的数据
【发布时间】:2017-06-26 15:32:52
【问题描述】:

我需要将配置模块(以较慢的时钟运行)连接到以较高速度运行的工作人员。标准答案似乎是一个 FIFO,但我想我想出了一个更简单的解决方案,它消耗更少的资源 - 具有更高延迟的缺点。对我来说好处是我不需要为每种可能的数据大小重新生成 FIFO IP。在 RTL 模拟中它似乎有效(我在使用与问题无关的综合后遇到了麻烦)。

是我遗漏了什么还是以下代码正确:

module fifo_int#( // This is bad name. I haven't come up with better yet
    parameter type DATA = logic [31:0]
    )(
    input  logic rst,
    input  logic clk_in,
    input  DATA  din,
    input  logic clk_out,
    output DATA  dout
    );
    DATA dreg;

    enum logic [1:0] {
        IN,
        STABLE,
        WAIT_OUT
    } in_state;
    enum logic [1:0] {
        WAIT_IN,
        WRITE,
        INV
    } out_state;
    logic in_output[3], out_output[3];
    initial begin
        in_state <= IN;
        out_state <= WAIT_IN;
        for (int i = 0; i < 3; i++) begin
            in_output[i] <= 0;
            out_output[i] <= 0;
        end
    end
    always @(posedge clk_in)
    begin
        case (in_state)
        IN: begin
            dreg <= din;
            in_state <= STABLE;
        end
        STABLE: begin
            in_state <= WAIT_OUT;
            in_output[0] <= ~in_output[0];
        end
        WAIT_OUT: begin
            in_state <= (in_output[0] == out_output[2]) ? IN : WAIT_OUT;
        end
        endcase
        out_output[1] <= out_output[0];
        out_output[2] <= out_output[1];
    end
    always @(posedge clk_out)
    begin
        case (out_state)
        WAIT_IN: begin
            out_state <= (in_output[2] == out_output[0]) ? WAIT_IN : WRITE;
        end
        WRITE: begin
            dout <= dreg;
            out_state <= INV;
        end
        INV: begin
            out_output[0] <= ~out_output[0];
            out_state <= WAIT_IN;
        end
        endcase
        in_output[1] <= in_output[0];
        in_output[2] <= in_output[1];
    end
endmodule

【问题讨论】:

  • 时钟是否同步?这是一个解释时钟域交叉基础知识的链接:eetimes.com/document.asp?doc_id=1279906
  • @TudorTimi 不。谢谢你的链接——我还没读过,但我会的。
  • 慢速一侧的一些波以及您希望快速一侧如何工作将有助于更好地理解问题。例如,您的快速端如何知道何时开始处理数据?
  • @TudorTimi 慢的一面是将与总线时钟一起运行的内存映射寄存器暴露给 CPU(包括“停止”位)。快端正在向另一条总线生成数据。

标签: clock system-verilog hdl


【解决方案1】:

如果您的时钟是异步的,那么您将需要同步。

对于同步时钟,由于您的慢侧是产生数据的一侧,因此您不需要任何缓冲。无论如何,数据在多个(快速)时钟周期内保持稳定,因此您实际上不需要域之间的任何逻辑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-30
    • 2013-06-09
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 1970-01-01
    • 2019-05-08
    • 2018-12-18
    相关资源
    最近更新 更多