PSoC UDB 内 PLD/マクロセルによるアップダウン・カウンタ (6)
OPL3 の AM LFO を構成する要素のうち、周期 210 のアップダウン・カウンタ部を PSoC の UDB (Universal Digital Block) の PLD/マクロセル部で実現してみた回路を下に示します。
この回路全体で、UDB ひとつ (PLD 2 組、マクロセル 8 個) におさまっています。
「updown7」という名称になっているのが作成したコンポーネントで、7 ビット・アップダウン・カウンタの機能 (だけ) を持っています。 外部に設けた T-FF でアップ/ダウンの切り替えを行なっています。
動作としては、ダウンカウント (DN = 1, UP = 0) で「カウント 0」に達するとカウント方向をアップカウント (DN = 0, UP = 1) に切り替え、アップカウントで「カウント 105」に達するとカウント方向をダウンカウントに切り替えます。
実際には、カウント 0、カウント 105 を検出したのでは間に合わないので、ひとつ前のカウントである「カウント 1」および「カウント 104」を検出して T-FF を反転させています。 カウント 1 は updown7 モジュールの中で検出しています。
updown7 モジュールの Verilog コードを下に示します。
//`#start header` -- edit after this line, do not edit this line // ======================================== // // Copyright YOUR COMPANY, THE YEAR // All Rights Reserved // UNPUBLISHED, LICENSED SOFTWARE. // // CONFIDENTIAL AND PROPRIETARY INFORMATION // WHICH IS THE PROPERTY OF your company. // // ======================================== `include "cypress.v" //`#end` -- edit above this line, do not edit this line // Generated on 10/21/2016 at 01:06 // Component: updown7 module updown7 ( output CNT1, output [6:0] Q, input CLK, input RES, input U_D ); parameter width = 7; //`#start body` -- edit after this line, do not edit this line // count register reg [width-1:0] s; // detect count 1 (and count 0) at down count assign CNT1 = (&(~s[width-1:1]) & U_D); assign Q = s; always @(posedge CLK or posedge RES) begin if (RES) // asynchronous reset s <= {width{1'b0}}; else // count up/down s <= (s + { {width-1{U_D}}, 1'b1}); end // Your code goes here //`#end` -- edit above this line, do not edit this line endmodule //`#start footer` -- edit after this line, do not edit this line //`#end` -- edit above this line, do not edit this line
cin も cout も使用しないので、Verilog の「+」演算子を使っています。
アップカウントはカウント・レジスタに 7'b000_0001 を加算することで実現し、一方、ダウンカウントはカウント・レジスタに 7'b111_1111 を加算することにより実現しています。
「カウント 1」は、カウント・レジスタの b6 から b1 までが全てゼロかどうかをデコードしています。 したがって、「カウント 1」と「カウント 0」がこの条件に当てはまりますが、ダウンカウント方向では先に「カウント 1」に到達するので問題なく、簡単化のためにデコードの条件から b0 を除外しています。
「カウント 104」は 104 = 7'h68 = 7'b110_1000 ですから、
(b6 & b5 & b3) = 1
をデコードすれは、アップカウント方向では「カウント 104」が最初に条件が成立するカウントになります。
「.rpt」ファイルの中から UDB / PLD / マクロセルの使用量に関するサマリの部分を下に示します。
---------------------------------------------------------- Technology mapping summary ---------------------------------------------------------- Resource Type : Used : Free : Max : % Used ========================================================== . . . . . <中略> . . . . . UDB : : : : Macrocells : 8 : 184 : 192 : 4.17 % Unique P-terms : 15 : 369 : 384 : 3.91 % Total P-terms : 15 : : : . . . . . <中略> . . . . . ---------------------------------------------------------- PLD Packing Summary ---------------------------------------------------------- Resource Type : Used : Free : Max : % Used ==================================================== PLDs : 2 : 46 : 48 : 4.17% PLD Resource Type : Average/LAB ======================================= Inputs : 6.00 Pterms : 7.50 Macrocells : 4.00 . . . . . <中略> . . . . . ----------------------------------------------------------- Final Placement Summary ----------------------------------------------------------- Resource Type : Count : Avg Inputs : Avg Outputs ======================================================== UDB : 1 : 8.00 : 8.00
8 個のマクロセルを使用し、PLD は 2 組使用して、UDB ひとつにおさまっています。
マクロセル部分のリスティングを下に示します。
---------------------------------------------------------- Macrocell listing ---------------------------------------------------------- MacroCell: Name=\updown7_1:MODULE_1:g1:a0:s_0\, Mode=(D-Register, Carry-Chain-Start) Total # of inputs : 1 Total # of product terms : 1 List of special equations: Clock = (clk2) => Global Cpt0 Equation = (Q_0) Cpt1 Equation = (0) Clock Enable: True Main Equation : 1 pterm ( Q_0 ); Cout = \updown7_1:MODULE_1:g1:a0:g0:u0:gof:g_arith(0):ga:cadd_0\ Output = Q_0 (fanout=3) MacroCell: Name=\updown7_1:MODULE_1:g1:a0:s_1\, Mode=(D-Register, Carry-Chain-Continue) Total # of inputs : 2 Total # of product terms : 2 List of special equations: Clock = (clk2) => Global Cpt0 Equation = (DN * Q_1) Cpt1 Equation = (!DN * !Q_1) Clock Enable: True Main Equation : 2 pterms ( !DN * !Q_1 + DN * Q_1 ); Cin = \updown7_1:MODULE_1:g1:a0:g0:u0:gof:g_arith(0):ga:cadd_0\ Cout = \updown7_1:MODULE_1:g1:a0:g0:u0:gof:g_arith(0):ga:cadd_1\ Output = Q_1 (fanout=5) . . . . . <中略> . . . . . MacroCell: Name=\updown7_1:MODULE_1:g1:a0:s_6\, Mode=(D-Register, Carry-Chain-Last) Total # of inputs : 2 Total # of product terms : 2 List of special equations: Clock = (clk2) => Global Cpt0 Equation = (DN * Q_6) Cpt1 Equation = (!DN * !Q_6) Clock Enable: True Main Equation : 2 pterms ( !DN * !Q_6 + DN * Q_6 ); Cin = \updown7_1:MODULE_1:g1:a0:g0:u0:gof:g_arith(0):ga:cadd_5\ Cout = \updown7_1:MODULE_1:g1:a0:s_6_cout\ Output = Q_6 (fanout=5) MacroCell: Name=DN, Mode=(T-Register) Total # of inputs : 7 Total # of product terms : 2 List of special equations: Clock = (clk2) => Global Clock Enable: True Main Equation : 2 pterms ( !DN * Q_6 * Q_5 * Q_3 + DN * !Q_6 * !Q_5 * !Q_4 * !Q_3 * !Q_2 * !Q_1 ); Output = DN (fanout=20)
Q_2 から Q_5 までは省略しましたが、最初の 7 個のマクロセルがアップダウン・カウンタ本体で、最後の 1 個の「Name=DN」となっているマクロセルが T-FF およびランダム・ロジック部分です。 「カウント 1」デコーダと「カウント 104」デコーダが PLD のプロダクト・ターム 2 個の中に収容されています。
前述の回路に下の図のような回路を加えて、LFO 波形を SPDIF 経由でキャプチャしてみました。
アップダウン・カウンタ出力に接続したステータス・レジスタから値を読み出し、ビット・マスク、ビット・シフト、log - リニア変換、および SPDIF_Tx モジュール への出力などはソフトウェアで行いました。
キャプチャ結果を波形編集ソフトで見たものを下に示します。
上のトレースが L ch におさめた DAM = 1 相当の波形、下のトレースが R ch におさめた DAM = 0 相当の波形で、実チップからキャプチャしたものと一致しています。