2016-12-08 58 views
0

我正在創建一個有4個空的4位寄存器的寄存器文件,並且在每個時鐘週期內,寄存器獲取一個值,然後使用該值顯示一個7段解碼器。如果寄存器是空的,不應該有顯示,但是一旦一個值被加載到寄存器,那麼應​​該有一個顯示。我試圖編寫7段解碼器的verilog代碼,如果En = 1,那麼應該只有一個輸出。我的問題是,代替不顯示任何內容,7段解碼器將顯示0,直到值被添加到寄存器,這種情況下,解碼器將顯示加載的值。這裏是verilog代碼。寫入一個只有輸出的Verilog代碼時啓用

module seven_seg_decoder(S, Z, Y, X, W,En); 
input Z,Y,X,W,En; 
output [6:0] S; 
reg [6:0] S; 

always @(En) 
    begin 
     case({Z,Y,X,W,En}) 
      5'b00001: S = 'b0000001; 
      5'b00011: S = 'b1001111; 
      5'b00101: S = 'b0010010; 
      5'b00111: S = 'b0000110; 
      5'b01001: S = 'b1001100; 
      5'b01011: S = 'b0100100; 
      5'b01101: S = 'b0100000; 
      5'b01111: S = 'b0001111; 
      5'b10001: S = 'b0000000; 
      5'b10011: S = 'b0000100; 
      5'b10101: S = 'b0001000; 
      5'b10111: S = 'b1100000; 
      5'b11001: S = 'b0110001; 
      5'b11011: S = 'b1000010; 
      5'b11101: S = 'b0110000; 
      5'b11111: S = 'b0111000; 

     endcase 
    end 
endmodule 

當寄存器加載的值,我已經輸出來自寄存器說,它被加載,並且被用作輸入對這個解碼器的使能

回答

1

看的的{Z, Y, X, W, En}可能的編碼,你已經列舉:

En值的
5'b00001: S = 'b0000001; 
5'b00011: S = 'b1001111; 
5'b00101: S = 'b0010010; 
5'b00111: S = 'b0000110; 
5'b01001: S = 'b1001100; 
5'b01011: S = 'b0100100; 
5'b01101: S = 'b0100000; 
5'b01111: S = 'b0001111; 
5'b10001: S = 'b0000000; 
5'b10011: S = 'b0000100; 
5'b10101: S = 'b0001000; 
5'b10111: S = 'b1100000; 
5'b11001: S = 'b0110001; 
5'b11011: S = 'b1000010; 
5'b11101: S = 'b0110000; 
5'b11111: S = 'b0111000; 
// ^Look here 

全部都1!如果En0,您從未告訴模塊該做什麼。它不知道清空顯示。在這種情況下,你需要給它做點什麼。

您有幾種選擇:

簡單的解決方案
您可以添加空白還沒有被列舉在所有情況下,顯示器的違約條款:

default: S = 'b0000000; //change to whatever means "turn everything off" 

不必要的複雜性解決方案
通過使用5'bxxxx0作爲子句和casex語句,可以獲得更精確的結果:

casex ({Z,Y,X,W,En}) 
    // all other enumerated cases 
    5'bxxxx0: S = 'b0000000; //change to "everything off" 
    default: S = 'b0000000; //change to "everything off" 

但是知道casex有一些潛在的缺陷,可能會使其難以正確使用並導致令人驚訝的行爲。還要注意,這最終與第一個簡單的解決方案相同。現在我會避免它。

(我的)首選的解決方案

這實際上是一樣的前兩個,但我認爲其目的是更清楚:

always @(*) 
    begin 
     if (!En) 
      S = 'b0000000; // change to "everything off" 

     else 
      case({Z,Y,X,W,En}) 
       5'b00001: S = 'b0000001; 
       5'b00011: S = 'b1001111; 
       5'b00101: S = 'b0010010; 
       5'b00111: S = 'b0000110; 
       5'b01001: S = 'b1001100; 
       5'b01011: S = 'b0100100; 
       5'b01101: S = 'b0100000; 
       5'b01111: S = 'b0001111; 
       5'b10001: S = 'b0000000; 
       5'b10011: S = 'b0000100; 
       5'b10101: S = 'b0001000; 
       5'b10111: S = 'b1100000; 
       5'b11001: S = 'b0110001; 
       5'b11011: S = 'b1000010; 
       5'b11101: S = 'b0110000; 
       5'b11111: S = 'b0111000; 
       default: S = 'b0000000; // change to some error code 
      endcase  
    end 

這種解決方案的優點是,你的代碼的目標更加清晰:如果En不是真的,那麼其餘的信號並不重要。我們清除顯示。其他解決方案也會發生這種情況,但這種結構使得它更加明顯。

這裏的default這種情況在技術上是沒有必要的。不應有任何En爲真的未列舉的情況。但這是很多數字輸出。如果你輸錯了,在這些情況下,有一個強制顯示錯誤的默認值(可能只是7seg顯示的中心線?)將幫助你識別錯誤。

其他一些注意事項:

  1. 您應該避免使用XZ作爲變量名。他們可能會因爲「不關心」和「高阻抗」而感到困惑。它使代碼更難以遵循它的需要。

  2. 我已經更改了您的敏感列表。 Greg correctly pointed out如果希望在輸入W,X,YZ發生更改時正確更新輸出,則需要在更改always塊時觸發塊。運算符會告訴Verilog編譯器根據always塊的內容推斷正確的靈敏度列表。 (請注意,這不會考慮任務或功能來決定敏感列表。)

  3. 我強烈建議您將所有位模式放在parameters之內,以使您的代碼更具可讀性。

+0

我明白你在說什麼了,但如果我確實在你提到的那個條款中加入了,那麼它是不是還會顯示8?默認原因創建相同的輸出作爲案件5'b10001 – Zebs

+0

對不起,我不小心打入太快。我編輯了評論 – Zebs

+0

我不知道你的輸出編碼是什麼。改變它的意思是「什麼都不顯示」 – skrrgwasme

相關問題