0

我对我的代码进行了行为模拟,它运行良好。结果如预期。当我合成我的代码并将其上传到 spartan 3e FPGA 并尝试使用chipscope 进行分析时,结果甚至与我的预期不相近。我做错了什么? http://pastebin.com/XWMekL7r

4

2 回答 2

5

您的问题出在第 13-16 行,您在其中为状态寄存器设置初始值:

 reg    [OUTPUT_WIDTH-1:0] previousstate = 0;              
 reg    [OUTPUT_WIDTH-1:0] presentstate = 1;
 reg    [6:0] fib_number_cnt = 1;  
 reg    [OUTPUT_WIDTH-1:0] nextstate = 1; 

这相当于编写一个“初始”语句来分配这些值,这是不可综合的——硬件中没有默认值这样的东西。当您将设计放入 FPGA 中时,所有这些寄存器都将采用随机值。

相反,当重置为高时,您需要在 always 块中初始化这些计数器/状态。

always @(posedge clk or posedge reset)
  if (reset) begin
     previousstate <= 0;
     presentstate <= 1;
     ... etc ...
  end

回答后续问题:

当你像这样初始化代码时,硬件中什么也没有发生——它被完全忽略,就像你放入了一个 $display 语句一样。综合工具会跳过所有仅用于模拟的结构,同时通常会给您一些警告(这实际上取决于工具)。

现在,阻塞和非阻塞问题需要很长的答案:)。我将引导您阅读 SNUG-2000 中的这篇论文,这可能是关于该主题的最佳论文。它回答了您以及该主题的许多其他问题。之后,您将了解为什么在顺序逻辑中使用阻塞语句被认为是不好的做法,以及为什么您的代码无论如何都可以正常使用阻塞语句。

http://cs.haifa.ac.il/courses/verilog/cummings-nonblocking-snug99.pdf


更多答案:

创建像您这样的逻辑的通常“模式”是有两个 always 块,一个定义逻辑,一个定义翻牌。在前者中,您使用阻塞语句来实现逻辑,而在后者中,您锁定(或重置)生成的值。所以,像这样:

wire some_input;

// Main logic (use blocking statements)
reg state, next_state;
always @*
  if (reset) next_state = 1'b0;
  else begin
    // your state logic
    if (state) next_state = some_input;
    else next_state = 1'b0;
  end

// Flops (use non-blocking)
always @(posedge clock)
  if (reset) state <= 1'b0;
  else state <= next_state;

请注意,我使用的是同步重置,但如果需要,您可以使用异步。

于 2010-03-13T05:23:27.257 回答
0

第 13-16 行是正确的。“注册 [6:0] fib_number_cnt = 1;” 与使用“初始”语句不同。阅读 Xilinx 综合指南,了解如何初始化寄存器的更详细说明。

于 2010-04-08T09:38:02.380 回答