2016-09-15 25 views
0
預期

`時間表1ns的/ 1ps的的Verilog代碼的行爲得到模擬的正確,但不工作的FPGA

module StateMachine(
    input [1:0] OP, 
    input [1:0] RESULT_COM, 
    input clk, 
    input rst, 
    output reg [1:0] CONTROL_AS=0, 
    output reg RESET_C, 
    output reg CONTROL_C, 
    output reg [1:0] state=0 
    ); 

    parameter toLOWER=2'b01,toUPPER=2'b10,IDLE=0; 
    reg [1:0] n_state = IDLE; 
    //reg [1:0] state = IDLE; 
    reg [1:0] p_state = IDLE; 
    reg [1:0] prevOP = 2'b00; 
    reg [1:0] p_state_copy = 2'b00; 
    reg [15:0] count = 0; 

    always @ (posedge clk) 
    begin 
    if(rst == 1) 
     RESET_C = 1; 
    else 
     RESET_C = 0; 

     if(OP == 2'b01) 
     n_state = toLOWER; 
     else 
     if(OP == 2'b10) 
     n_state = toUPPER; 
     else 
     n_state = IDLE; 

     if(prevOP == OP) 
     p_state = state; 

     if((OP != prevOP && OP[0] != OP[1]) || (rst == 1 && (OP != 2'b00 && OP != 2'b11))) 
     CONTROL_C = 1; 
     else 
     CONTROL_C = 0; 

     if(state != n_state)  
     prevOP = OP; 

     state = n_state; 
    end 

    always @ (n_state) 
    begin 
     p_state_copy = p_state;  
    end 

    always @ (p_state) 
    begin 
     case(p_state) 
     toLOWER: 
     begin 
      if(RESULT_COM == 2'b10) 
      CONTROL_AS <= 2'b10; 
      else 
      CONTROL_AS <= 2'b00; 
     end 

     toUPPER: 
     begin 
      if(RESULT_COM == 2'b01) 
      CONTROL_AS <= 2'b01; 
      else 
      CONTROL_AS <= 2'b00; 
     end 

     IDLE: 
     begin 
      if(p_state_copy == toUPPER && RESULT_COM == 2'b01) 
       CONTROL_AS <= 2'b01; 
      else if(p_state_copy == toLOWER && RESULT_COM == 2'b10) 
       CONTROL_AS <= 2'b10; 
      else if(p_state_copy == toUPPER && RESULT_COM == 2'b10) 
       CONTROL_AS <= 2'b0; 
      else if(p_state_copy == toLOWER && RESULT_COM == 2'b01) 
       CONTROL_AS <= 2'b0; 
      else if(p_state_copy == toUPPER && RESULT_COM == 2'b0) 
       CONTROL_AS <= 2'b0; 
      //(p_state_copy == toLOWER && RESULT_COM == 2'b0) 
      else CONTROL_AS <= 2'b0; 
     end 

     endcase 
    end 
endmodule  

這是一個字母轉換器。 OP是2位輸入。 11和00意味着什麼都不做。 01加載ROM中的下一個字母(使用計數器更新地址)並轉換爲小寫。 10加載下一個字母並轉換爲小寫。如果字母不是大寫或小寫,或者字母小寫,但OP要將其轉換爲小寫字母等,則字母不會被轉換。如果沒有輸入(00或11)或有效輸入始終置位(01或10) ,那麼輸出仍然存在。

我使用p_state_copy來保存之前的狀態,並且當下一個clk上升沿到來時,它與狀態有一些部分重疊。因此它可以檢查以前的狀態是否爲IDDLE(輸入00或11)。 RESULT_COM是比較器的結果,用於檢查字母狀態。在圖中,RESULT中的隱藏部分是0,因爲復位被聲明。 enter image description here

我可以模擬,綜合和實現它。但我無法在電路板上運行它。我可以知道問題是什麼嗎?謝謝。

回答

0
always @ (n_state) 
begin 
    p_state_copy = p_state;  
end 

該邏輯不能合成。對於邏輯信號的變化(如n_state),FPGA沒有實際的方法鎖存一個值(如p_state_copy)。

一般來說,always塊代碼用於合成在FPGA應該是要麼posedge clk(或一些其他時鐘信號)同步塊,或爲*隨機邏輯敏感。指定單個信號只會讓你陷入困境。

0

這段代碼有幾個錯誤會阻止它正確合成。

always @ (posedge clk) 
begin 
    if(rst == 1) 
    RESET_C = 1; 

應該更像

always @ (posedge clk or posedge rst) 
if(rst == 1) 
    RESET_C = 1; 
else 
begin 

有幾個總是@(...)的敏感性清單不完整。例如

always @ (p_state) 
begin 
    case(p_state) 
    toLOWER: 

缺少我到目前爲止發現的p_state_copy和RESULT_COM。 如果您的工具允許always_comb

,我建議可維護性要麼始終使用@(*),要麼更好,但是如果您的工具允許不正確的敏感性列表,它幾乎肯定會模擬不正確。 (模擬工具將只評估指定輸入變化時的代碼塊,而不是真正的組合邏輯,而不會產生該限制)。由於這個原因,許多綜合引擎忽略了敏感列表。

您還在梳狀邏輯塊中使用非阻塞賦值,並阻止梳狀邏輯塊中的賦值。

您正在使用變量定義的初始語句。這些將被合成引擎忽略。

此外,(RST == 1 & &(OP!= 2'b00 & & OP!=爲2'b11))將不正確地合成。如果你希望它正常運行,你需要堅持使用標準的觸發器verilog模板。

這些都將導致真正令人毛骨悚然的模擬結果。我認爲你需要先解決這些問題,並檢查你的模擬是否仍然按照你的預期行事。

相關問題