
だから私たちは:
1)ボードにCyclone IVを搭載したTerasic DE0-Nanoデバッグボード。

2)7セグメントインジケーターがハンダ付けされたブレッドボード。時間と分を表示します/
これらの2つのポイントについては、ほぼすべてのFPGAが完全に選択の自由を持ち、誰もがインディケーターと同じようにモックアップを行います。
次にプロジェクトについて。
順番に行きます。 まず第一に、私たちは自分自身に問いかけます。時計とは何ですか? 時計は時間をカウントするデバイスです。 それを数えるためには、正確なソースが必要です。 ボードには50 MHzのクロックがあります。 多すぎるため、1 Hzの周波数(1秒間に1つの「ティック」)を得るには、50,000,000で除算する必要があります。 共有する方法は? これを2段階で行いました。PLLを50で割って、カウンターを100万で割って使用しました。
PLLとは何ですか? 大まかに言って、これはクロック信号を変更できるものです。乗算、除算、位相シフト、デューティサイクルの変更。 Cyclone IVには4つありますので、1つを使用してみてください...
これを行うには、MegaWizard Plugin Managerを開き、IOセクションからALT_PLLを使用します。
1)入力周波数を50 MHzに設定します。

2)不要な入力を無効にします。

3)[次へ]を3回クリックし、信号パラメーターを選択するウィンドウに移動します。ここで、除算係数50を設定します。

その後、安全に「完了」をクリックし、保存してプロジェクトに貼り付けることができます。
私たちが受け取った美しさは次のとおりです。

左側の入力は50 MHz、右側の入力は1 MHzです。
ここで、さらに100万で割る必要があります-このために、1,000,000を法とするカウンターを使用します。カウントモジュールは、カウンターの可能な状態の数です。
LPM_Counterを使用して、同じMegaWizardを使用して作成します。
ビット長を20ビットに設定し、10000のカウントモジュラスでモジュラスを選択します。
これを取得します。

これで、1ヘルツになりました。これは、シニア(19)放電から取得できます。
次に、2つのモジュロ60(分と秒)と1つのモジュロ24(明らかに時間)の3つのカウンタのカスケードを実装する必要があります。
2番目のカウンター-非同期リセットで、いずれかのボタンが押されたときに発生します(設定時間/分):

ご覧のとおり、キャリーアウト出力が使用され(オーバーフロー中に次のカウンターに転送されます)、LEDに秒が表示されます。
次の2つのカウンターは同じように構成されますが、1つ例外があります。時間を設定するには、チューニング中にスリープ状態にならないように、1 Hzより速いクロック信号を適用する必要があります。 :)
これを行うには、ボタン制御マルチプレクサーを使用します。

上のマルチプレクサは、カウンタの入力に適用する周波数を選択するために使用され、下のマルチプレクサは、入力cinに適用するものを選択します。2番目のカウンタのcoutからの転送、または単にログレベル。 「1」。
入力cinの本質は、この入力に論理ユニットレベルがある場合にのみカウンタがカウントすることです。 つまり、2番目のカウンターがオーバーフローすると、coutを1に上げます。 この「1」は次のカウンターの入力cinに移動し、1分を報告します。
したがって、キー[0]を離すと、分カウンターは1分あたり1回(論理的に)カウントされ、押されると1秒あたり約4回カウントします。
同様に、時間計の場合:

上のマルチプレクサーは転送を管理し、1つの瞬間を除いて低い周波数を管理します:キー[0]ボタンが押されたとき、クロック信号はカウンター水に到達しません(分を設定するときに迷わないように行われます)。 これは、入力にクロック信号とキー[0]が供給されるAND要素のために行われます。 キー[0]のボタンを放すと、ハイレベルとq [19]が通過し、押すとレベルが「0」になり、出力も「0」になります。 原則として、カウンタ入力の「カウントイネーブル」をオンにし、それを介してカウンタをオフにすることができます。このタスクでは、これは原則的ではありません。
次に、カウンターのデータを表示する必要があります。 これを行うには、2進数から2進数の10進数へのコンバーターを作成する必要があります。 これは、各10進数字が別々の4つの2進数字で指定されている場合の、2進コードでの10進数のそのような表現です。
例:
738 = 0111 0011 1000。
この変換には、ダブルダブルアルゴリズムを使用します。
アルゴリズムの本質:
1)2進数を1桁左にシフトします。
2)4シフトの場合-「10」列と「単位」列のBCDの数。 アルゴリズムの終わり
3)いずれかの列の数が4を超える場合-3を追加します。
手順1に進みます。
以下に図を示します。

そして、この変換が遅延なく実行されるように実装する必要があるものは次のとおりです。
s16.radikal.ru/i191/1107/a4/59618e3101ca.png
入力に4より大きい数がある場合、各モジュールCは入力に3を追加します。
ここに彼と彼の作品の真理値表があります:

この経済全体を実装するために、verilogでこのようなモジュールを2つ作成します。
module add3(in,out);
input [3:0] in;
output [3:0] out;
reg [3:0] out;
always @ (in)
case (in)
4'b0000: out <= 4'b0000;
4'b0001: out <= 4'b0001;
4'b0010: out <= 4'b0010;
4'b0011: out <= 4'b0011;
4'b0100: out <= 4'b0100;
4'b0101: out <= 4'b1000;
4'b0110: out <= 4'b1001;
4'b0111: out <= 4'b1010;
4'b1000: out <= 4'b1011;
4'b1001: out <= 4'b1100;
default: out <= 4'b0000;
endcase
endmodule
module binary_to_BCD(A,ONES,TENS);
input [5:0] A;
output [3:0] ONES, TENS;
wire [3:0] c1,c2,c3;
wire [3:0] d1,d2,d3;
assign d1 = {1'b0,A[5:3]};
assign d2 = {c1[2:0],A[2]};
assign d3 = {c2[2:0],A[1]};
add3 m1(d1,c1);
add3 m2(d2,c2);
add3 m3(d3,c3);
assign ONES = {c3[2:0],A[0]};
assign TENS = {1'b0,c1[3],c2[3],c3[3]};
endmodule
次の2つの部分を保存してプロジェクトに挿入します。

1つは数時間、もう1つは分です。
今、あなたは私たちの指標で余談をする必要があります。
Lite-On ltc-4727jsを使用しました。
データシートによると、各桁に共通のカソードを持つセグメントがあり、各桁のセグメントのアノードの入力が組み合わされています。 これは、一度に1桁しか点灯できないことを意味します。 重要ではありません。1つずつ点灯します。非常に迅速に切り替えます。 チャック・ノリスでさえちらつきに気付かないほど速いので;-)
データシートの最も興味深い部分:

そして

どのようにすべてを接続しましたか?
しかし、これらのピンを使用して:

セグメントでは、すべてがはっきりしていると思いますが、神秘的な数字[4..0]は何ですか...簡単です-数字[4..1]-
これらは数字であり、数字[0]は補助セグメント(2〜3桁のコロン)です。 最も難しいのは、すべてを正しく接続し、FPGA出力とピンを正しく一致させることです。
次に、インジケーターの出力メカニズムを分析します。
このモンスターデザインはこれを行っています。

左側には、ビンからBCDへのコンバーターがあります。 焦点は5入力4ビットマルチプレクサーです。 最初の4つの入力は数字で、5番目の入力はドットに点火するためのものです(1秒に1回点滅します)。 以下に、この2番目の入力に1111または1110を送信する図を示します。 マルチプレクサの制御入力にどの組み合わせが来るかに応じて、必要なビットをデコーダー(少し後で検討するデバイス)に出力します。 その上には、どのカソードに「0」を供給して所望のセグメントを点灯させるかを選択するデバイスがあります。 彼の内面は次のとおりです。
module segment_select (in,out,sel);
input in;
output reg [4:0] out;
output reg [2:0] sel;
always @ (posedge in)
if (sel == 4)
sel = 0;
else sel = sel + 1;
always @(*)
case (sel)
0: out <= 5'b0zzzz;
1: out <= 5'bz0zzz;
2: out <= 5'bzz0zz;
3: out <= 5'bzzz0z;
4: out <= 5'bzzzz0;
default: out <= 5'bzzzzz;
endcase
endmodule
5'b0zzzzのようなレコードに注意してください。 ここで5'bは、5ビットをバイナリ形式で指定することを意味します。0はゼロレベル、zは高抵抗状態です(電流はピンに流れません)。 そして、なぜ正確に0なのでしょうか? はい、桁に共通のカソードがあるため、電流はアノードからカソード、または1から0に流れます。ここでは、カソードに0を設定し、アノードに1を設定します。
デコーダーデバイス:
module decoder_7seg (BCD, segA, segB, segC, segD, segE, segF, segG, segDP);
input [3:0] BCD;
output segA, segB, segC, segD, segE, segF, segG, segDP;
reg [7:0] SevenSeg;
always @(BCD)
case(BCD)
4'h0: SevenSeg = 8'b11111100;
4'h1: SevenSeg = 8'b01100000;
4'h2: SevenSeg = 8'b11011010;
4'h3: SevenSeg = 8'b11110010;
4'h4: SevenSeg = 8'b01100110;
4'h5: SevenSeg = 8'b10110110;
4'h6: SevenSeg = 8'b10111110;
4'h7: SevenSeg = 8'b11100000;
4'h8: SevenSeg = 8'b11111110;
4'h9: SevenSeg = 8'b11110110;
4'b1111: SevenSeg = 8'b11000000;
default: SevenSeg = 8'b00000000;
endcase
assign {segA、segB、segC、segD、segE、segF、segG、segDP} = SevenSeg;
終了モジュール
ここでは、必要な数字に応じて、どのセグメントを照らすかが選択されます。
デフォルトと数値1111の2つのポイントが重要です。BCDが指定された値(前述の1110)と異なる値をとると、すべてのセグメントがオフになります。 1111が到着すると、セグメントAとBが点火され、データシートからわかるように、セグメントL1とL2にも接続されます。
実際、それがすべてです。
すべてを
プロジェクトは次のとおりです。
ifolder.ru/24865983
FPGAを選択し、ピンを再割り当てする必要があります。 確かに、私はPLLを使用しました...したがって、プロジェクトを別のFPGAに転送するときは、入力周波数を分割する必要があります(そこに50 MHzがあるという事実ではありません)。
ビデオは次のとおりです。
www.youtube.com/watch?v=iUoiOO8wYls
ソース:
1)インジケーターのデータシート:
pdf.eicom.ru/datasheets/lite-on_pdfs/ltc-4727js/ltc-4727js.pdf
2)BINからBCDへの転送:
www.johnloomis.org/ece314/notes/devices/binary_to_BCD/bin_to_bcd.html
www.ece.msstate.edu/courses/ece4743/fall2007/Shift_add_3.pdf
3)セグメントへの出力:
www2.engr.arizona.edu/~rlysecky/courses/ece274-07f/labs/lab4.pdf
we.easyelectronics.ru/Shematech/dinamicheskaya-indikaciya_2.html
www.fpga4fun.com/Opto4.html
4)デコーダー:
www.fpga4fun.com/Opto3.html
ご清聴ありがとうございました。誰かが役に立ちますように!
UPD
みんなにコメントしてくれてありがとう!
このブログでどうなったのかわかりません。 私は見通し、規範の写真を記入し、何かを作り直したかった...しかし、今日はHabrには行きませんでした!
NTPなどを介して外部から時間を取得する方法についてのアイデアがあります。
ホスティングについて-向こうのPMでアドバイスを受けました。
これは私の最初のトピックです。この経験の前に出版物はありませんでした。写真は私が覚えている最初のホスティングにアップロードされました。
私は故郷で、通常のインターネットでちょうど終わった。 明日は希望に応じてカットします!