【问题标题】:Verilog case statement is always trueVerilog 案例陈述始终为真
【发布时间】:2019-07-17 04:07:34
【问题描述】:

Verilog case statmenet 表达式始终为真

module test(input clk,
input reset,
output reg[3:0] ledss

);

reg[31:0] dataread;

always @(posedge clk)
begin

case(dataread)

    32'b1010101010101010101:ledss='b1010;

endcase


 end
endmodule

不明白为什么要执行这一行

32'b1010101010101010101:ledss='b1010;

leds 是相同的模式 1010

同样在执行此代码后,指示灯不亮

module test(input clk,
input reset,
output reg[3:0] ledss

);

reg[31:0] dataread;

always @(posedge clk)
begin


    if(dataread==32'b1010101010101010101)   ledss='b1010;




 end
endmodule

但如果我执行此操作,leds 会亮起,模式 1010

module test(input clk,
input reset,
output reg[3:0] ledss

);

reg[31:0] dataread;

always @(posedge clk)
begin

case(dataread)

    32'b101010101010:
    begin
    if(dataread==32'b101010101010)  ledss='b1010;
    end
endcase



 end
endmodule

不明白 case 语句在 verilog 中是如何工作的

【问题讨论】:

  • 我可以看到你没有给dataread 任何值,所以它都是XXX-es。阅读 Verilog 规则以判断数据是否为 ​​1 或 0。
  • @Oldfart 感谢您的回答,是的,您是对的,但为什么要在 LED 上使用第三个代码? if(dataread==32'b101010101010) ledss='b1010;这条规则是否也适用于 if 语句?如果是,为什么这条规则不适用于第二个代码?
  • 1.你到底想达到什么目的?您的代码似乎比它可能更复杂。 2.你应该在always块中使用非阻塞赋值。 3. 请注意,您的比较(最后一段代码)导致1-bit uknown value。因此,大多数工具将consider it false。在我使用 LED 的工具中不会打开。
  • @Qiu 我想从 1 个端口 ram ip 读取。添加 if 语句后的结果相同。用于测试的 Ram 充满了 1s。还是不明白为什么会亮。代码pastebin.com/8snsegVx
  • 我认为是硬件问题或编译器错误,无法解释为什么会发生这种情况。即使在执行此pastebin.com/VL1FuiZD 之后,leds 仍处于模式 1010

标签: case verilog


【解决方案1】:

我相信您正在跳过 Verilog 仿真并将代码直接加载到 FPGA。

在模拟中。 ledss 将是 X,直到满足模式匹配(caseif)。在提供的代码中,dataread 从未分配过,因此它将为 X,因此在模拟中ledss 将始终为 X。在您的 pastebin 链接中,您有由 ROM 输出驱动的dataread,因此它将有一个已知的输出可能符合检查条件。

FPGA 会综合您的 RTL,并且通常会进行一些优化。 ledss 没有显式初始化,如果曾经分配过,它只有一个可能的值。因此,优化器可能会假设初始值是无关紧要的,然后通过选择与可以分配给它的唯一可能值相同的初始值来简化逻辑。或者它可能假设初始值为 0 并保持逻辑。对于这种情况,一般情况下,case 倾向于遵循前者,if 倾向于遵循后者。尽管您的代码在功能上是等效的,但只有一个条件的 case 语句并不常见。

我建议您改进您的编码风格,以便合成器和阅读您代码的任何人更明确地理解您的预期行为。下面是一些建议。请记住将dataread 分配给一个已知值。 (注意:为了便于阅读,将 32'b1010101010101010101 替换为等效的 32'h0005_5555

always @(posedge clk)
begin
  case(dataread)
    32'h0005_5555 : ledss <= 4'b1010;
    default : ledss <= 4'b1111;
  endcase
end

或等价物:

always @(posedge clk)
begin
  if (dataread == 32'h0005_5555)
    ledss <= 4'b1010;
  else
    ledss <= 4'b1111;
end

如果您希望ledss 在分配后保留 1010 模式,那么您可以这样做:

always @(posedge clk)
begin
  if (reset) begin
    ledss <= 4'b1111;
  end
  case(dataread)
    32'h0005_5555 : ledss <= 4'b1010;
  endcase
end

或等价物:

always @(posedge clk)
begin
  if (reset) begin
    ledss <= 4'b1111;
  end
  else if (dataread == 32'h0005_5555) begin
    ledss <= 4'b1010;
  end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-24
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 2010-10-30
    • 2016-05-13
    • 2016-02-21
    • 2012-09-08
    相关资源
    最近更新 更多