2013-07-15 227 views
1

我正在嘗試在Verilog中編寫一個應該「移動」LED陣列上的LED燈的程序。用一個按鈕,燈應該移動到左邊,而另一個燈應該移動到右邊。這是我的代碼:如果使用三元運算符 - Verilog

module led_shift(UP, DOWN, RES, CLK, LED); 
input UP, DOWN, RES, CLK; 
output reg [7:0] LED; 
reg [7:0] STATE; 

[email protected](negedge DOWN or negedge UP or negedge RES) 
begin 
    if(!RES) 
    begin 
     STATE <= 8'b00010000; 
    end 
    else 
    begin 
     STATE <= UP ? STATE>>1 : STATE<<1; 
    end 
end 

always @ (posedge CLK) 
begin 
    LED <= STATE; 
end 
endmodule 

的問題是在STATE < = UP?狀態>> 1:狀態< < 1;以及以下錯誤:

錯誤(10200):led_shift.v處的Verilog HDL條件語句錯誤(34):無法將條件中的操作數與始終包含的事件控件中的對應邊相匹配構建

我試圖修改代碼,而無需使用那種如果:

[email protected](negedge DOWN or negedge UP or negedge RES) 
begin 
    if(!RES) 
     STATE <= 8'b00010000; 
    else 
    begin 
     if(!DOWN) 
      STATE <= STATE<<1; 
     else 
     begin 
      if(!UP) 
       STATE <= STATE>>1; 
      else 
       STATE <= STATE; 
     end 
    end 
end 

它編譯,但不工作:LED的「動作」只到左邊,當我按下另一個按鈕全部LED關閉。可能在我的代碼中存在問題,但我不明白爲什麼我的第一個代碼根本不能編譯。 謝謝你的幫助!

harrym

回答

2

目前尚不清楚的合成知道如何控制STATE與3個異步控制信號。

很可能您的合成器試圖將STATE映射到具有異步低電平有效置位和復位的D觸發器。例如,它可能是想合成的東西,如:

dff state_0_(.Q(STATE[0], .CLK(DOWN), .SET_N(UP), .RST_N(RES(, .D(/*...*/)); 

在實際的翻牌異步設置和重置,默認應該是同意的,並會解釋錯誤在你的第一個代碼。在第二次嘗試中,UPDOWN一起成爲組合邏輯雲的一部分。 DOWN也被用作時鐘。由於UP不是時鐘,所以在UP低的情況下連續發生移位,並立即將開位完全移出。第二種情況的另一個錯誤實際上會更合適。

要使合成器做得更好,首先需要同步異步控制信號。使用與CDC相同的技術(時鐘域交叉; Cliff Cummings的論文進入拘留here)。一個基本的例子:

always @(posedge clk) begin 
    pre_sync_DOWN <= DOWN; 
    sync_DOWN <= pre_sync_DOWN; 
end 

現在,控制信號是同步的,使你的STATE組合邏輯的輸出。例如:

always @* begin 
    if(!sync_RES) 
     STATE = 8'b00010000; 
    else 
     case({sync_UP,sync_DOWN}) 
     2'b01 : STATE = LED>>1; 
     2'b10 : STATE = LED<<1; 
     default: STATE = LED; 
     endcase 
end 

隨着對一個時鐘域和顯式定義的組合邏輯運行的一切,合成器可使用觸發器和基本柵極構造等效邏輯。


FYI:

要在negedge事件中,你需要保持上次同步值,並檢查是否有高到低的過渡只轉移。請記得在驅動STATE的組合邏輯中將sync_do_對換。

always @(posedge clk) 
    keep_DOWN <= sync_DOWN; 
always @* 
    do_DOWN = (keep_DOWN && !sync_DOWN); 
+0

謝謝!完美的答案。該項目仍然不起作用(我按下的每個按鈕,LED關閉,可能轉換太快),但至少它編譯。我將在模擬中檢查信號。我沒有得到的是,在我的第二個代碼中,當UP很低時,連續發生移位的原因。只有當靈敏度列表中的一個信號下降,當UP較低時才應該移動? – harrym

+0

嘗試使用門進行繪圖或編寫代碼,'STATE'是異步低電平置位和復位的內部DFF的輸出。 'UP'將是電平敏感的(不邊沿敏感),所以高位將立即移出(只有潛在的減速是蠕動延遲)。 – Greg

+0

我用一個邊緣檢測的例子更新了我的答案。它會根據每個惡性事件​​轉移一次。 – Greg