2017-02-11 107 views
1

我正在試圖製作一個2位數的BCD計數器,它將從0到99進行計數。我面臨的問題是,板上的7段顯示器正在更改數字同時。情景是這樣的 - 00,11,22 ... 99。FPGA上的2位BCD計數器

這裏的主要邏輯代碼:

module PartD(
output reg[0:6] lcd, //for one particular 7 segment LCD. 
input clock, 
output reg[0:7] sel // for selecting which LCD to be used 
); 
integer count=0; 
//integer i=0, j=0; 

reg[3:0] i, j; //4 bit reg for counting 

[email protected](posedge clock) 
begin 
    if(count==100000000) //(100MHz) count till 100M cycles...(1 sec delay) 
    begin 
     count = 0; 

     sel=00000001; //selecting the most significant digit 
     case (i) 
       0: lcd = 7'b0000001; 
       1: lcd = 7'b1001111; 
       2: lcd = 7'b0010010; 
       3: lcd = 7'b0000110; 
       4: lcd = 7'b1001100; 
       5: lcd = 7'b0100100; 
       6: lcd = 7'b0100000; 
       7: lcd = 7'b0001111; 
       8: lcd = 7'b0000000; 
       9: lcd = 7'b0000100; 
     endcase 


     sel=00000010; //selecting the least significant digit 
     case (j) 
       0: lcd = 7'b0000001; 
       1: lcd = 7'b1001111; 
       2: lcd = 7'b0010010; 
       3: lcd = 7'b0000110; 
       4: lcd = 7'b1001100; 
       5: lcd = 7'b0100100; 
       6: lcd = 7'b0100000; 
       7: lcd = 7'b0001111; 
       8: lcd = 7'b0000000; 
       9: lcd = 7'b0000100; 
     endcase 
     j = j+1; 
     if(j>9) 
     begin 
      j=0; 
      i = i+1; //increment i only when j overflows. 
      if(i>9) 
      i = 0; 
     end 
    end 
    else count = count + 1; 
end 
endmodule 

由於兩個顯示器可以同時改變,似乎有一些邏輯上的錯誤。會是什麼呢。我是否犯了不考慮硬件的錯誤?

+0

爲什麼你有i,j作爲整數和寄存器在同一時間? – Laleh

+0

這是一個錯誤...已糾正它。 – archity

+0

你能提供LCD零件編號?可能你應該更新每個LCD每秒50次或更多。 – alexander

回答

3

您的代碼存在的主要問題是,當您的計數器爲100000000時,您嘗試在同一週期內同時激活兩個LCD段。邏輯上,您正在使用阻塞賦值「=」,第二個賦值有效地覆蓋第一個。

您需要決定何時打開每個段。

根據您的要求,我會找到一種方法來驅動每段50%的時間。考慮到10^8中最大的2^n除數是256,我選擇使用count [7]來決定片段1和片段2,以便每個片段在移動到另一片之前刷新128個週期。

此外,您有一個語法錯誤,忘記在sel賦值(0000010而不是'b000010)上使用二進制前綴。

這是最基本的工作。

在實踐中,我會這進一步改變和打破它分成幾個「總是」塊:
一個用於反
一個用於顯示
一個遞增i和j。

我還選擇將計數器從整數類型替換爲寄存器類型。保留非硬件結構的整數(用於循環計數器等)

爲case語句添加了一個默認值,將x的值驅動爲'lcd'。這有助於優化意外i,j值(10..15)的綜合以及傳播x進行仿真。

我還增加了一個復位輸入並將時鐘復位信號移動到模塊接口上的第一個信號。沒有重置,你的計數,我,j從隨機值開始。在你的情況下,他們最終會變得合法,但它使模擬更難,因爲它們以'x'值開始。另外,請記住阻塞('=')和非阻塞('< =')賦值之間的區別。儘量避免使用阻塞分配來保持時鐘始終阻塞。

module PartD(
    input clock, 
    input reset, 
    output reg[0:6] lcd, //for one particular 7 segment LCD. 
    output reg[0:7] sel // for selecting which LCD to be used 
); 
reg [26:0]count; 
reg[3:0] i, j; //4 bit reg for counting 

[email protected](posedge clock) 
begin 
    count <= reset ? 'd0 : (count == 100000000) ? 'd0 : (count + 1); 
end 

[email protected](posedge clock) 
begin 
    j <= reset ? 'b0 : (j < 9) ? j+1 : 'b0; 
    i <= reset ? 'b0 : (j < 9) ? i : (i < 9) ? (i + 1) : 'b0; 
end 

[email protected](posedge clock) 
begin 
    if (count & 128) 
    begin 
     sel <= 'b00000001; //selecting the most significant digit 
     case (i) 
       0: lcd <= 7'b0000001; 
       1: lcd <= 7'b1001111; 
       2: lcd <= 7'b0010010; 
       3: lcd <= 7'b0000110; 
       4: lcd <= 7'b1001100; 
       5: lcd <= 7'b0100100; 
       6: lcd <= 7'b0100000; 
       7: lcd <= 7'b0001111; 
       8: lcd <= 7'b0000000; 
       9: lcd <= 7'b0000100; 
       default: 
       lcd <= 'bx; 
     endcase 
    end 
    else 
    begin 
     sel <= 'b00000010; //selecting the least significant digit 
     case (j) 
       0: lcd <= 7'b0000001; 
       1: lcd <= 7'b1001111; 
       2: lcd <= 7'b0010010; 
       3: lcd <= 7'b0000110; 
       4: lcd <= 7'b1001100; 
       5: lcd <= 7'b0100100; 
       6: lcd <= 7'b0100000; 
       7: lcd <= 7'b0001111; 
       8: lcd <= 7'b0000000; 
       9: lcd <= 7'b0000100; 
       default: 
       lcd <= 'bx; 
     endcase 
    end 
end 

endmodule 
+0

行「if(count&128)」對我來說似乎沒有意義。這是否正確,因爲當我嘗試在FPGA上實現時,它不工作。另一方面,給if if(count == 10^6)這樣的條件確實有效,但是可以看到切換。 – archity

+0

「if(count&128)」的原因是因爲您想要在不同的數字之間連續切換。由於count在每個時鐘週期遞增,因此「count&128」實際上是寫入「count&7'b1000000」的懶惰方式。這意味着每128個週期,該位將切換,因此您將在sel0和sel1之間有一個對稱的開關。在第二個想法中,使用「if(count [7])」更清晰甚至更好。 – udif

+0

另請注意:「10^6」表示十進制10與十進制6異或,而不是您預期的1000000。也意識到形式「count == 1000000」的任何條件浪費了比計數[7]多得多的FPGA資源。實現「count == 1000000」需要一個帶有一些反相輸入的大門。在實踐中,在普通的FPGA架構上,這會破壞(給定您的27位計數)到10xLUT4單元,或更少的LUT5/LUT6單元。 otehr手上的「count [7]」是一個不需要任何邏輯的現有信號。 – udif