Verilog代码模拟但不像FPGA上预测的那样运行

时间:2010-03-12 19:55:47

标签: verilog fpga synthesis xilinx hdl

我对我的代码进行了行为模拟,它完美无缺。结果如预测。当我合成我的代码并将其上传到spartan 3e FPGA并尝试使用chipcope进行分析时,结果甚至不如我预期的那样接近。我做错了什么? http://pastebin.com/XWMekL7r

2 个答案:

答案 0 :(得分: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


更多答案:

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

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;

请注意,我正在使用同步重置,但如果需要,您可以使用async。

答案 1 :(得分:0)

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