gpt4 book ai didi

verilog - 在 Verilog 中混合阻塞和非阻塞分配(或不!)

转载 作者:行者123 更新时间:2023-12-04 14:55:34 24 4
gpt4 key购买 nike

我在 Verilog 中实现了一个简单的序列化程序,但我不明白阻塞分配何时会导致问题的细微差别。我特别难以理解 this answer 的一部分. “但是,您永远不应该将阻塞分配用于同步通信,因为这是不确定的。”

我正在构建一个 block ,作为输入:

  • 一个位时钟
  • 5位并行数据输入(要序列化的值)
  • 存在表示有效 5 位数据的“数据有效”信号

  • 作为输出,我有:
  • 串口数据输出
  • 一个“完成”信号,表示是时候使用新的 5 位值
  • 每当总线上有有效的串行数据输出时,“传输”信号就为高电平

  • 每当数据有效变高时,模块开始输出 5 位值,每次一位,从位时钟的下一个上升沿开始。当最后一位在线时,模块发出“完成”信号,因此可以提供新的 5 位值。

    省略一些重置逻辑,执行此操作的代码如下所示:
    always @ (posedge clk) begin
    if(shiftIndex == 0) begin
    if(dataValid == 1) transmitting = 1; //Blocking assign
    else transmitting = 0; //Blocking assign
    end

    //Need the blocking assign up above to get this part to run
    //for the 1st bit
    if(transmitting == 1) begin
    shiftIndex <= shiftIndex + 1;
    dataOut <= data5b[shiftIndex];

    if(shiftIndex == 4) begin
    complete <= 1;
    shiftIndex <= 0;
    end
    else begin
    complete <= 0;
    end
    end
    end

    现在,我可以使用所有非阻塞分配来编写 block ,但我觉得这会损害可读性。看起来像这样:
    always @ (posedge clk) begin
    if(shiftIndex == 0) begin
    if(dataValid == 1) begin
    transmitting <= 1; //Non-blocking now
    shiftIndex <= shiftIndex + 1; //Duplicated code
    dataOut <= data5b[shiftIndex]; //Duplicated code
    complete <= 0; //Duplicated code
    end
    else transmitting <= 0;
    end

    //Now, this only runs for the 2nd, 3rd, 4th, and 5th bit.
    else if(transmitting == 1) begin
    shiftIndex <= shiftIndex + 1;
    dataOut <= data5b[shiftIndex];

    if(shiftIndex == 4) begin
    complete <= 1;
    shiftIndex <= 0;
    end
    else begin
    complete <= 0;
    end
    end
    end

    两者似乎都在模拟中做我想要的,我喜欢第一个,因为它更容易阅读,但由于我不明白为什么使用阻塞分配进行同步通信是不确定的,我担心我已经编码了滴答作响的定时炸弹

    问题:当我尝试合成它时,我是否在第一个代码中做错了什么?尽管阅读起来有点困难(无论如何对我来说),第二个代码是否更可取?我应该做第三件事吗?

    最佳答案

    当使用阻塞( = )赋值时,该值可用于下一行代码。这意味着它是组合的,而不是由触发器驱动的。

    在模拟中,它看起来像是由触发器驱动的,因为该模块仅在时钟正沿评估,实际上它不会破坏接口(interface)。

    我属于那种说永远不要混合样式的派别,因为这可能是代码审查和重构中的一个问题。重构,如果一个模块需要输出一个新的信号并且它已经存在,它们只是改变为一个输出。乍一看,它像是一个触发器,因为它位于 always @(posedge clk 中。堵塞。

    因此,我建议不要混合样式,而是拉出组合部分并将其放在自己的 block 中。这仍然符合您的要求吗?如果没有,那么你会有问题。

    我看不出如何控制数据有效,但它可以改变输出传输,潜在的传输也可能出现故障,因为它来自组合解码,而不是从触发器干净地驱动。接收接口(interface)可能是异步的,故障可能导致锁定等。

    always @* begin
    if(shiftIndex == 0) begin
    if(dataValid == 1) transmitting = 1; //Blocking assign
    else transmitting = 0; //Blocking assign
    end
    end

    always @ (posedge clk) begin
    if(transmitting == 1) begin
    shiftIndex <= shiftIndex + 1;
    dataOut <= data5b[shiftIndex];

    if(shiftIndex == 4) begin
    complete <= 1;
    shiftIndex <= 0;
    end
    else begin
    complete <= 0;
    end
    end
    end

    关于verilog - 在 Verilog 中混合阻塞和非阻塞分配(或不!),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28599018/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com