2012-05-15 86 views
1

我目前正在編寫Verilog代碼來構建「拔河」遊戲。下面的模塊代表15個LED的中央LED,代表比賽場地。中心燈必須亮起直到比賽開始,例如當它接收到某種輸入時(輸入由L和R給出,其中L是向左移動一次,R向右移動一次)。Verilog始終在時間= 0時阻止

但是,我遇到了一個奇怪的bug。雖然我在施工時給enabled值1,並且L和R在施工時爲0(或應該是),但是當我運行代碼enabled時立刻變爲0.

我的問題是,爲什麼會發生這種情況?我怎樣才能讓變量保持1的值,直到看到輸入爲止?

module centerLight(Clock, reset, L, R, NL, NR, lightOn); 
    input Clock, reset, L, R, NL, NR; 
    output reg lightOn; 

    reg gameStart = 0; 
    reg enabled = 1; 

    [email protected](L or R) 
    if (L | R) begin 
     gameStart = 1; 
     enabled = 0; 
    end 
    else if (enabled) 
     gameStart = 0; 
    wire PS; 
    reg NS; 

    [email protected](PS or L or R or NL or NR) 
    if((NL && R) || (NR && L)) NS = ~PS; 
    else    NS = PS; 

    [email protected](PS or gameStart) 
    case(PS || !gameStart) 
     0: lightOn = 0; 
     1: lightOn = 1; 
    endcase 

    D_FF cl (PS, NS, reset, Clock); 

endmodule 

module D_FF (q, d, reset, clk); 
    input d, reset, clk; 
    output reg q; 

    [email protected](posedge clk or posedge reset) 
    if (reset) 
     q = 0; 
    else 
     q = d; 

endmodule 
+0

你決定通過模擬器啓用的狀態?它應該能夠告訴你爲什麼它的狀態可能L或R有問題或有斷言 – Tim

+0

是的,它確實看起來像L和R正在做其中的一個(我不知道如何區分差異;對不起,這是新的!)。我是否阻止Verilog執行此操作?如果有幫助的話,我在FPGA板上運行它,其中L和R被分配兩個Keys的反向輸入。 – cjspook

+0

不可能說沒有看到電路本身。我不清楚,這是發生在**模擬**中,還是在您爲fpga啓動時發生這種情況?如果是第一種情況,您應該可以轉儲波形,或者如果是後者,請顯示分配L和R的包裝模塊。 – Tim

回答

1

在你設計的enable是一個鎖存器,如果LR很高(或可能浮動)最短的時間,enable將打開。

將整個設計順序化,然後使用重置確保gameStart爲低可能會更好。

這是我會怎麼做它:

module centerLight(Clock, reset, L, R, NL, NR, lightOn); 
    input Clock, reset, L, R, NL, NR; 
    output reg lightOn; 

    reg lightOn_d; 
    reg gameStart, gameStart_d; 
    reg PN, NS; 

    always @ (posedge Clock or posedge reset) 
     if(reset) 
      begin 
       gameStart <= 1'b0; 
       PS  <= 1'b0; 
       lightOn <= 1'b0; 
      end 
     else 
      begin 
       gameStart <= gameStart_d; 
       PS  <= NS; 
       lightOn <= lightOn_d; 
      end 

    always @ * 
     begin 
      if(L || R) 
       gameStart_d = 1'b1; 
      else 
       gameStart_d = gameStart; 

      if((NL && R) || (NR && L)) 
       NS = ~PS; 
      else 
       NS = PS; 

      if(PS || !gameStart) 
       lightOn_d = 1'b1; 
      else 
       lightOn_d = 1'b0; 
     end 

endmodule 

我希望幫助。

0

在代碼的啓動值被分配給0當L | R = 1。如果您的測試平臺中L和R的初始值或您的FPGS上這些引腳的值初始爲1,則啓用將切換爲0.懸空L和R引腳也可評估爲1。

模擬器(如Modelsim)允許您在「enabled = 0;」時在行上設置斷點。

1

這可能是由於編譯器開關。由於初始塊不可合成(Altera的Quartus可以直接讀取它們來設置上電條件,但是根據Doulos的說法,它們不支持合成),那麼它就是一個初始塊不應影響FPGA邏輯的結果。

雖然這應該模擬爲RTL。但我知道Altera器件,例如,除非「Powerup do not care」開關設置爲on,否則所有邏輯在啓動時都會上電爲零,在這種情況下,它會查看邏輯並將寄存器設置爲最小化邏輯的值。

在這種情況下,它將設爲啓用爲邏輯0,因爲這會產生最小的邏輯,因此不需要(因爲您的代碼從未將啓用設置爲1,除了在技術上應該忽略的初始構造中,即使它是讀取最初的構造,然後用該開關就可以)。

我也嘗試添加一個復位通過一直在增加的,並把到支持那裏的所有任務(保持它作爲一個鎖存器)

總是啓用@(復位) 如果(復位) 啓用< = 1 「B1; else if(L | R) enabled < = 1'b0;

通過這樣做,我可以看到功能的啓用被保留下來的邏輯。

在不同的筆記我會建議去一個同步註冊的方法,而不是鎖存。

還建議Verilog與整個代碼中的情況保持一致,因爲最終您將陷入困境(經典錯誤是將模塊連接起來,如果語句'default_nettype none'未被使用(I' d看看像克利福德孜然的從旭日技術,或者杜勒斯靈感)代碼。

我希望這有助於!