2010-03-12 49 views
0

我對我的代碼做了一個行爲模擬,它完美地工作。結果如預測。當我合成我的代碼並將其上傳到斯巴達3e FPGA並嘗試使用芯片進行分析時,結果甚至不是我所期望的。我做錯了什麼? http://pastebin.com/XWMekL7rVerilog代碼模擬,但不能按照FPGA上的預測運行

+0

當你說「行爲」時,我假設你的意思是RTL。您的綜合工具是否創建Verilog門網表文件和SDF文件?如果是這樣,你是否使用反註釋的SDF延遲進行門模擬?那也通過了?您的工具鏈是否包含等效檢查器或靜態時序分析工具?這些將幫助您確定您是否有功能錯誤或計時問題。 – toolic 2010-03-12 20:55:47

+0

我還沒有做過任何STA。我正在使用Xilinx ISE,無法訪問Primetime或其他STA分析工具。我將嘗試使用Xilinx Timing Analyzer並查看可以提取的信息。 – 2010-03-13 00:45:52

回答

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 @(posedge clk or posedge reset) 
    if (reset) begin 
    previousstate <= 0; 
    presentstate <= 1; 
    ... etc ... 
    end 

應答傳送至後續問題:

當初始化這樣的代碼,什麼都沒有發生在硬件 - 它被完全忽略,就好像你已經投入了$顯示聲明。綜合工具跳過所有僅用於模擬的構造,而通常會給你一些警告(這實際上取決於工具)。

現在,阻塞和非阻塞問題需要很長的回答:)。我將引導你閱讀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; 

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

+0

有趣的一點!當我如代碼中所示初始化我的寄存器時,合成器沒有抱怨。當這樣的事情發生時,硬件究竟發生了什麼? – 2010-03-13 15:20:16

+0

另外,當我使用always塊中的非阻塞語句進行模擬時,我得到的數字與阻塞語句不同。爲什麼? (阻塞語句提供正確的結果) – 2010-03-13 15:59:41

+0

嗨,感謝您的額外輸入。 閱讀第11節,我發現我必須在靈敏度列表中添加額外的元素,才能使非阻塞賦值正確工作。但是我不能在靈敏度列表中混合邊緣觸發和電平觸發元素。我也不能讓另一個總是阻塞與水平觸發元素,因爲這將做多個分配到多個總是相同的元素塊(記住根據您的建議我使用邊緣觸發塊初始化元素時,在復位狀態)。你會建議什麼?堅持阻止? – 2010-03-14 02:41:13

0

13-16行是正確的。 「reg [6:0] fib_number_cnt = 1;」與使用「初始」語句不同。請閱讀Xilinx綜合指南以獲取如何初始化寄存器的更詳細說明。

相關問題