FPGAデバッグボード-フランケンシュタイン。 クリスマスガーランドコントローラー

FPGAとFrankieのデバッグボードに関する別のシリーズ。 前のシリーズ1、2、3







クリスマスツリーのガーランドコントローラーの作成は簡単ではありませんが、非常に簡単です! FPGA上のHello World-これは点滅するLEDです。 そして、FPGAの「Happy New Year」は、いくつかのLEDで点滅します。 これまでの記事のように、原理は単純です。クロックジェネレーターの周波数を分割するカウンターを作成し、カウンターワードからビットを選択して、目的の速度を取得します。 この単語のいくつかのビットは、特定の表示ステップを提供します(選択されたビット1、2、4、8などのステップ数に応じて)。 ステップ番号に応じて、N個のLEDの値を設定します。







実際のガーランドを制御するには、電磁リレーでシールドを使用します。 8つのリレーでこのようになったことがわかりました。 配線図 回路図









プロジェクトベース



module epm7064_test(clk, leds); input wire clk; //    output wire [7:0] leds; // 8   / reg [31:0] cnt; //         always @(posedge clk) cnt <= cnt + 1'b1; //      assign leds = ... //      endmodule
      
      





定期的な回転



電球の通常の交代では、最初のステップで偶数の電球を点灯し、2番目の電球で奇数を点灯します。 2つのステップがあるため、カウンターワードから1ビットだけが必要です。 各ステップでの電球の数は、単語-定数によって設定されます。







 ... wire [7:0] variant1 = (cnt[24]) ? 8'b01010101 : 8'b10101010; assign leds = variant1; ...
      
      





ランニングライト



8本の電球を通過するには、8つのステップが必要です。 これを行うには、カウンターワードから3ビットを選択します(2 ^ 3 = 8)。 リレーをオンにするために0を指定する必要があるため、出力が反転することに注意してください。







 ... wire [7:0] variant2 = (cnt[24:22] == 3'd0) ? 8'b11111110 : (cnt[24:22] == 3'd1) ? 8'b11111101 : (cnt[24:22] == 3'd2) ? 8'b11111011 : (cnt[24:22] == 3'd3) ? 8'b11110111 : (cnt[24:22] == 3'd4) ? 8'b11101111 : (cnt[24:22] == 3'd5) ? 8'b11011111 : (cnt[24:22] == 3'd6) ? 8'b10111111 : (cnt[24:22] == 3'd7) ? 8'b01111111 : 8'b11111111; assign leds = variant2; ...
      
      





通常回転v2



第1の実施形態と同じように、バルブをペアで組み合わせるだけである。







 ... wire [7:0] variant3 = (cnt[24]) ? 8'b00110011 : 8'b11001100; assign leds = variant3; ...
      
      





ダブルランニングライト



これは単一のランニングライトのバリエーションですが、ステップ数が半分になります







 ... wire [7:0] variant4 = (cnt[24:23] == 2'd0) ? 8'b11001100 : (cnt[24:23] == 2'd1) ? 8'b01100110 : (cnt[24:23] == 2'd2) ? 8'b00110011 : (cnt[24:23] == 2'd3) ? 8'b10011001 : 8'b11111111; assign leds = variant4; ...
      
      





ランダムライト



これが最も興味深い部分です。 疑似ランダムランダムネスを生成するために、 LFSRを使用しました。 このリンクでコード例を直接取得できます。 少しだけ取りました。 アルゴリズムは既にテ​​ストされていますが、何らかの理由で動作したくありませんでした! その理由は、レジスタにゼロ値があってはならず、FPGAがオンになると、各ビットでゼロになるからです。 しかし、最初のセクションを適用しました!!! 一般的に、愛をこめてドキュメントを読まなかったため、実験を通して真実が明らかになりました。 EPM7000シリーズFPGAには初期セクションがありません。 ちなみに、同じ問題はラティス4064にもありました。これはすべて、Cycloneクラスのより大きなFPGAで、初期ブロックが追加のハードウェア部分で生成されると信じる理由になります。 また、EPMで初期化を行うために、別のカウンターを追加してリセット信号を生成しました。 この信号を受信すると、擬似ランダムシーケンスジェネレータのレジスタに初期値が割り当てられます。 その後、「ジェネレータ」が機能しました。







リソースを節約するため、すべてのビットに対してジェネレーターを作成しませんでした。 ほとんどの場合、十分なリソースがありません。 実際には、発電機は各サイクルで次の値を提供でき、サイクルごとに電球を更新する必要がないため、1つの発電機を使用してすべてのランプの値を入力します。







 ... reg [2:0] res_gen_reg; //    wire reset = ~(res_gen_reg==3'b111); // ,    1,      8 always @(posedge clk) begin //    ,    ,     //  .  ,        //         .   //     res_gen_reg <= (res_gen_reg==3'b111) ? res_gen_reg : res_gen_reg + 1'b1; end reg [7:0] variant5; //        ,    reg [7:0] d; //      always @(posedge clk) begin if (reset) begin d <= 1; //    end else begin if (cnt[20:0]==21'd0) begin //      d <= { d[5:0], d[6] ^ d[5] }; //     //          variant5[cnt[23:21]] <= d[5]; //    8    end end end assign leds = variant5; ...
      
      





すべてをまとめる



FPGAリソースはまだあるため、カウンターの最上位ビットを取得し、それらを使用してランニングライトのタイプを切り替えることができます。 2、4、8種類のほうが簡単ですが、5種類あります。 したがって、それらの4つをソートし、それらの間隔に5番目のオプション(または、最初のオプション)を挿入します。 一般に、実験用のフィールドがあります。 64個のセルのうち58個が消費されているため、まだ無料のリソースがあります。







 assign leds = (cnt[29:27] == 3'd1) ? variant2 : (cnt[29:27] == 3'd3) ? variant3 : (cnt[29:27] == 3'd5) ? variant4 : (cnt[29:27] == 3'd7) ? variant5 : variant1;
      
      





完全に
 module epm7064_test(clk, leds); input wire clk; output wire [7:0] leds; reg [31:0] cnt; initial cnt <= 32'd0; always @(posedge clk) cnt <= cnt + 1'b1; wire [7:0] variant1 = (cnt[24]) ? 8'b01010101 : 8'b10101010; wire [7:0] variant2 = (cnt[24:22] == 3'd0) ? 8'b11111110 : (cnt[24:22] == 3'd1) ? 8'b11111101 : (cnt[24:22] == 3'd2) ? 8'b11111011 : (cnt[24:22] == 3'd3) ? 8'b11110111 : (cnt[24:22] == 3'd4) ? 8'b11101111 : (cnt[24:22] == 3'd5) ? 8'b11011111 : (cnt[24:22] == 3'd6) ? 8'b10111111 : (cnt[24:22] == 3'd7) ? 8'b01111111 : 8'b11111111; wire [7:0] variant3 = (cnt[24]) ? 8'b00110011 : 8'b11001100; wire [7:0] variant4 = (cnt[24:23] == 2'd0) ? 8'b11001100 : (cnt[24:23] == 2'd1) ? 8'b01100110 : (cnt[24:23] == 2'd2) ? 8'b00110011 : (cnt[24:23] == 2'd3) ? 8'b10011001 : 8'b11111111; reg [2:0] res_gen_reg; wire reset = ~(res_gen_reg==3'b111); always @(posedge clk) begin res_gen_reg <= (res_gen_reg==3'b111) ? res_gen_reg : res_gen_reg + 1'b1; end reg [7:0] variant5; reg [7:0] d; always @(posedge clk) begin if (reset) begin d <= 1; end else begin if (cnt[20:0]==21'd0) begin d <= { d[5:0], d[6] ^ d[5] }; variant5[cnt[23:21]] <= d[5]; end end end assign leds = (cnt[29:27] == 3'd1) ? variant2 : (cnt[29:27] == 3'd3) ? variant3 : (cnt[29:27] == 3'd5) ? variant4 : (cnt[29:27] == 3'd7) ? variant5 : variant1; endmodule
      
      







結論



無意味なプロジェクトのように思えますが、このシリーズの最初の動作不能などのニュアンスについて学ぶことができました。 これは通常、製造元(ラティス、ザイリンクス、またはアルテラ)の機能だと思っていました。 また、コメントから、このFPGAをフラッシュする回数は約100回であることが判明しました。 新しい知識がやってくると、これはすべて無駄ではありません!








All Articles