2017-02-11 14 views
1

2桁のBCDカウンタを0から99までカウントしようとしています。私が直面している問題は、ボード上の7セグメントの両方のディスペンスが同時。 scenairioは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部品番号は提供できますか?おそらく、毎秒50回の各LCDの更新が必要です。 – alexander

答えて

3

あなたのコードが持つ主な問題は、カウンターが100000000のときに同じサイクル内で両方のLCDセグメントをアクティブにしようとしていることです。論理的にはブロッキング割り当て '='を使用しており、 。

各セグメントをいつオンにするかを決める必要があります。

あなたの要件を考えれば、私は各セグメントを50%時間駆動する方法を見つけるでしょう。 10^8の最大2^nの除数が256であることを考えると、count [7]を使ってセグメント1とセグメント2を決めるので、各セグメントは128サイクルだけリフレッシュされてから別のセグメントに移動します。

さらに、構文ミスがあり、バイナリプレフィックス( 'b000010'ではなく0000010)を使用するのを忘れました。

これは動作させるための最小限のものです。

実際には、私はこれをさらに変更しているだろうと、いくつかの「常に」ブロックにそれを破る:カウンター表示iとjをインクリメントする
一つのため
一つのため
一つ。

また、整数型のカウンタをレジスタ型に置き換えることを選択しました。

デフォルト値をcase文に追加し、xを 'lcd'にするようにしました。これは、予期しないi、j値(10..15)の合成を最適化するのにも、シミュレーションのためにxを伝搬するのにも役立ちます。

また、リセット入力を追加し、クロック&リセット信号をモジュールインターフェイスの最初の信号に移動しました。リセットがなければ、カウントi、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(count == 10^6)のようないくつかの条件を与えても、切り替えは見えます。 – archity

+0

"if(count&128)"の理由は、連続して異なる桁を切り替えるためです。 countはクロックサイクルごとにインクリメントするので、 "count&128"は実際には "count&7'b1000000"と書くのに怠惰な方法です。つまり、128サイクルごとにこのビットがトグルするため、sel0とsel1の間で対称の切り替えが行われます。 2番目の考えでは、 "if(count [7])"を使用する方がより明確で、さらに優れています。 – udif

+0

また、「10^6」は、10進数10で10進数6を排他的論理和(XOR)し、1000000ではないことを意味します。また、 "count == 1000000"という形式の任意の条件は、count [7]よりも多くのFPGAリソースを無駄にします。 "count == 1000000"を実装するには、いくつかの反転入力を持つ巨大なANDゲートが必要です。実際には、一般的なFPGAアーキテクチャでは、これは10xLUT4セル、またはより少ないLUT5/LUT6セルに分解されます(27ビットカウントで与えられます)。 "count [7]"は、ANY論理を必要としない既存の信号です。 – udif