简体   繁体   English

Verilog代码模拟但未按FPGA预期运行

[英]Verilog code simulates but does not run as predicted on FPGA

I did a behavioral simulation of my code, and it works perfectly. 我对代码进行了行为模拟,并且效果很好。 The results are as predicted. 结果如预期的那样。 When I synthesize my code and upload it to a spartan 3e FPGA and try to analyze using chipscope, the results are not even close to what I would have expected. 当我合成我的代码并将其上传到spartan 3e FPGA并尝试使用Chipscope进行分析时,结果甚至无法达到我的预期。 What have I done incorrectly? 我做错了什么? http://pastebin.com/XWMekL7r http://pastebin.com/XWMekL7r

Your problem is with lines 13-16, where you set initial values for state registers: 您的问题出在第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; 

This is an equivalent to writing an "initial" statement assigning these values, which isn't synthesizable -- there is no such thing as a default value in hardware. 这等效于编写分配这些值的“初始”语句,该语句无法综合-硬件中没有默认值之类的东西。 When you put your design inside an FPGA, all of these registers will take on random values. 当您将设计放入FPGA中时,所有这些寄存器都将具有随机值。

Instead, you need to initialize these counters/states inside your always block, when reset is high. 相反,当重置为高电平时,您需要在Always块中初始化这些计数器/状态。

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

Answer to the follow-up questions: 回答以下问题:

When you initialize code like that, nothing at all happens in hardware -- it gets completely ignored, just as if you've put in a $display statement. 当您像这样初始化代码时,硬件中什么也没有发生-就像您放入$ display语句一样,它会被完全忽略。 The synthesis tool skips over all simulation-only constructs, while usually giving you some kind of a warning about it (that really depends on the tool). 综合工具会跳过所有仅用于模拟的结构,而通常会向您发出某种警告(这实际上取决于工具)。

Now, blocking and non-blocking question requires a very long answer :). 现在,阻塞和非阻塞问题需要很长的答案:)。 I will direct you to this paper from SNUG-2000 which is probably the best paper ever written on the subject. 我将指导您阅读SNUG-2000上的这篇论文,这可能是有史以来有关该主题的最佳论文。 It answers your question, as well as many others on the topic. 它回答了您的问题,以及有关该主题的许多其他问题。 Afterward, you will understand why using blocking statements in sequential logic is considered bad practice, and why your code works fine with blocking statements anyway. 之后,您将理解为什么在顺序逻辑中使用阻塞语句被认为是不好的做法,以及为什么您的代码无论如何都可以与阻塞语句一起正常工作。

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


More answers: 更多答案:

The usual "pattern" to creating logic like yours is to have two always blocks, one defining the logic, and one defining the flops. 创建像您这样的逻辑的通常“模式”是有两个总是块,一个定义逻辑,另一个定义触发器。 In the former, you use blocking statements to implement logic, and in the latter you latch in (or reset) the generated value. 在前者中,您使用阻塞语句来实现逻辑,而在后者中,您锁存(或重置)生成的值。 So, something like this: 因此,如下所示:

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;

Note that I'm using a synchronous reset, but you can use async if needed. 请注意,我正在使用同步重置,但是如果需要,您可以使用异步。

Lines 13-16 are correct. 13-16行是正确的。 "reg [6:0] fib_number_cnt = 1;" “ reg [6:0] fib_number_cnt = 1;” is not the same as using "initial" statement. 与使用“ initial”语句不同。 Read Xilinx synthesis guide for more detailed description of how to initialize the registers. 阅读Xilinx综合指南,了解有关如何初始化寄存器的更多详细说明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM