【问题标题】:Value not distributed in time价值未及时分配
【发布时间】:2018-04-12 17:21:18
【问题描述】:

我做了一个非常简单的模块,我在时钟的位置上分配了新的值:

module block_entry(
    input logic clk, 
    input entry entry_write,
    output entry entry_this
);
always_ff @(posedge clk)
begin
    entry_this <= entry_write;
    display("value of entry_write.add = %b", entry_write.address);
    display("value of entry_write.value = %b", entry_write.value);
end
endmodule

当我测试这个模块时,它工作正常,分配了新值,但是在更高级的架构中,新值没有及时设置为在 posedge 写入,即使 modelsim 显示它已设置

这是我的测试模块:

module entry_tst ();
    logic clk;
    entry entry_write, entry_this;
    block_entry entry (.*);

initial begin
    #10 clk = 1; entry_write = '0; 
end
endmodule

这是结果-> wavedataflow

测试区块时,结果是:

entry_write.add 的值 = 0000000000000000

entry_write.value 的值 = 0000000000000000

如您所见,clk 在输入值更改的同时从 x 转换为 1 - 结果,输出值被覆盖

但问题是当我在我的架构中使用这个模块时,它的行为不一样 - 输入是相同的,但值没有被覆盖,好像没有触发 posedge,但实际上看起来值不是定的时间。 我的架构包括:

  • 入口块

  • 控制块(我的架构的“大脑”,选择应该将哪个值写入入口块,生成信号“cont”到多路复用器,还生成信号“clk”到入口块何时从多路器分配值, 'clk' 是逻辑,所以默认值是 x 开头)

  • mux(多路复用器,根据来自控制块的信号选择将什么值写入入口块)

最初我想将入口值设置为0,所以我有一个'init'信号,当init等于1时,控制相应地设置'cont'信号,所以mux选择设置为0的流并设置'clk ' 所以入口块会将旧值重写为新值(0)

always_ff @(posedge init) 
    if (init)
    begin   
    cont <= 2'b00;
    clk <= 1;
end

一切正常 - 入口块到达新值并设置“clk”信号,但新值被忽略,这将入口块的波动行为描述为架构的一部分: wave dataflow

在测试整个架构时,结果是:

entry_write.add 的值 = xxxxxxxxxxxxxxxx

entry_write.value 的值 = xxxxxxxxxxxxxxxx

怎么了?我真的很绝望,我是一个systemverilog新手。

时间刻度可以改变一些东西吗(它设置为默认的 1ns/1ns)?有时当我观察数据流时,在变化的那一刻, clk 设置为 1 但要写入的值未设置为 0 - 这可能是问题吗? clk 和 value 的变化实际上并不是同时发生的,当 posedge 被触发时 value 仍然是旧的?

为什么值没有及时分布,我该如何解决?还有,为什么 wave 和 dataflow 看起来不错?

编辑:

我认为问题出在赛车条件上,并且基本上没有及时写入该值:

我创建了一个图表来显示我的实现,我怎样才能实现 entry_write 在 clk 之前及时存在?

【问题讨论】:

  • 两个明确的问题:1) 有问题的代码在哪里分配了entry_write? 2)您是否尝试制作异步电路(因为如果这应该是同步设计,您会遇到很多错误)?
  • 能否请您看一下我的图表,它显示了我如何分配每个值? (在我帖子的编辑部分)非常感谢任何能导致 entry_this 正确的帮助。

标签: system-verilog modelsim


【解决方案1】:

您的代码中的以下表达式创建了竞争条件:

always_ff @(posedge init) 
    if (init)
        clk <= 1;

如果结合

always_ff @(posedge clk)
    entry_this <= entry_write;

它会在 NBA 街区引起一场比赛,并且这里的分配结果是不可预测的。

经验法则是永远不要在时钟中使用非阻塞分配。

【讨论】:

  • 是的,我认为我对阻塞和非阻塞分配的目的非常错误(我只是认为阻塞用于 always_comb 块而非阻塞用于 always_ff - 这很愚蠢)。但基本上这是我的问题:prnt.sc/j4tsrv 请查看带有新数据流图的已编辑帖子,因为我的问题在将 prnt.sc/j4uasd
  • “init”是否也被非阻塞赋值改变了?
  • 如图所示,否:#10 init =1;
  • clk 应该 not 分配非阻塞,实际上它应该 not 是翻牌的输出。 always_comb clk = init; 是您真正需要的。触发器中的其余信号必须是非阻塞的。根据图表,您也更改了它们。这是错误的。此外,您的代码中不需要if (init)。 Posdge 已经处理好了。
  • 这不是所有代码,只有我有问题的部分,除了 init 我还有其他信号,所以如果需要 - 我需要实现这个:在任何信号 的 posedge initinsdel,我要设置contdecide是否 clk 会被设置,因为不是每次我都想写新的值,所以我觉得 comb 不合适
猜你喜欢
  • 2017-05-23
  • 1970-01-01
  • 2013-11-06
  • 2021-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-27
相关资源
最近更新 更多