フラット表示 | 前のトピック | 次のトピック |
投稿者 | スレッド |
---|---|
webadm | 投稿日時: 2008-9-19 8:56 |
Webmaster 登録日: 2004-11-7 居住地: 投稿: 3088 |
RTL: CONTROL 次ぎはちょっと込み入ったCONTROLブロック。最初にスケルトンを入力した際にいくつかデバウンスする必要の無い信号等があったので見直しをかけた。
押しボタン入力のA,Bのみデバウンスを行うことにした。それ以外はチャッタリングが起こっても表示が一瞬乱れる以外には悪影響無し。 FREQUENCY COUNTERとCLOCK TIMER及びDISPLAYで必要な制御信号のみを生成するステートマシンから成る。 FREQUENCY COUNTER制御ステートマシンの状態遷移図。ACの立ち上がりで初期状態S=0に遷移し、RESET信号をアサートする。次ぎのC800HZクロックの立ち上がりでプリセット状態S=1に遷移しRESET信号をデアサートしPRESET信号をアサートすると同時に内部のカウンタに初期値をセットする。次ぎのC800HZクロックでカウンタイネーブル状態S=2に遷移しPRESETをデアサートしCEをアサートする。以降のクロックでカウンタ値が0でなければカウンタをデクリメントする。もしカウンタが0に達していたらロード状態S=3に遷移し、CEをデアサートしLOADをアサートする。次ぎのクロックで初期状態S=0に戻りLOADをデアサートする。 CLOCK TIMER制御ステートマシンの状態遷移図。ACの立ち上がりで初期状態IDLEへ遷移し、TIMMADJ,TIMHADJをデアサートする。以降のC10HZの立ち上がりでAもしくはBのどちらかがアサートされていればADJへ遷移しAとBの現在値をTIMMADJ,TIMHADJにそれぞれ保持する。次ぎのC10HZのクロックでAもしくはBが継続的にアサートされている場合には連続アサート期間を計測するためにカウンタ初期値をセットしてADJCへ遷移する。以降C10HZの立ち上がり毎に継続してAもしくはBがアサートされていてかつカウンタが0に達していない場合にはカウンタをデクリメントする。カウンタが0に達した場合にはADJRへ遷移し継続してアサートされているAもしくはBあるいはその両方に対応するTIMMADJ,TIMHADJの出力をキープする。以降のC10HZの立ち上がりでA及びB共にデアサートされた場合IDLEへ遷移しTIMMADJ,TIMHADJを0リセットする。 もう少し状態数の少ないステートマシンにしてAとBを独立して扱っても良い気がする。その場合リソースが余分にかかるかもしれない。 DISPLAY制御用ステートマシンの状態遷移図。基本的にACの立ち上がりでQ1状態へ遷移し、以降はC800HZの立ち上がり毎にQ1->Q2->Q3->Q4->Q1と循環する。DIMMER入力がアサートされていない場合には4サイクル間常にDUTY及びSTROBEはアサートされる。DIMMER入力がアサートされると1サイクル期間のみDUTY及びSTROBEがアサートされる。必要に応じてDUTYは蛍光表示管のプレート電圧制御に対応しSTROBEはグリッド電圧制御に対応する。従ってどちらもアサートしている間だけ表示が行われる。DUTYとSTROBEは同じ信号でもよさそうに思えるが、片方を少し早めにアサートし遅めにデアサートするような制御が実際には必要かもしれない。特にDUTYはセグメントに対応するプレート電圧を制御するのでグリッドがONになる前に予めプリチャージして、グリッドがOFFになってからプレート電圧をOFFするなど綺麗な点消灯のために微調整が出来るようにしてある。DISPLAYブロック側もこれに同期して4サイクル毎に桁スキャンを行う。 最後はデバウンサーサブモジュールの状態遷移。ACの立ち上がりでIDLE状態にリセットされ、C800HZの立ち上がりで入力信号dをサンプルし、アサートされていれば検出サイクル閾値をカウンタにセットしてDET状態へ遷移。入力がアサートされている限りC800HZの立ち上がり毎にカウンタ残りをチェックし0でなければカウンタをデクリメントする。入力信号がデアサートされることなくカウンタが0に至った場合には安定したとみなしてIN状態へ遷移し出力qをアサートする。次ぎのクロックでまだ入力がアサートされていればOUT状態へ遷移し以降クロック毎に入力がデアサートされるまで出力qをアサートし続ける。入力がデアサートされるとIDLEへ遷移し出力qをデアサートする。実際にどれくらいのサイクル数で安定したとみなすかは要調整。 カウンタをシステムリセット直後不定にならないようにすべてのモジュールでリセットがかかるように見直し、ボタン入力関係は独立のステートマシンを設けるようにしてRTLを記述した結果が以下の通り。 dbsm.v: デバウンサステートマシン // Quartus II Verilog Template // 4-State Mealy state machine // A Mealy machine has outputs that depend on both the state and // the inputs. When the inputs change, the outputs are updated // immediately, without waiting for a clock edge. The outputs // can be written more than once per state or per clock cycle. module dbsm ( input clk, in, reset, output reg out ); // Declare state register reg [1:0]state; reg [1:0]count; // Declare states parameter IDLE = 0, DET = 1, IN = 2, OUT = 3; parameter DETCYCLE = 2'b11; // Determine the next state synchronously, based on the // current state and the input always @ (posedge clk or negedge reset) begin if (!reset) begin state <= IDLE; count <= 0; end else case (state) IDLE: if (in) begin state <= DET; count <= DETCYCLE; end DET: if (in) begin if(count) count <= count - 1'b1; else state <= IN; end else begin state <= IDLE; end IN: if (in) begin state <= OUT; end else begin state <= IDLE; end OUT: if (in) begin state <= OUT; end else begin state <= IDLE; end endcase end // Determine the output based only on the current state // and the input (do not wait for a clock edge). always @ (state) begin case (state) IDLE: begin out = 0; end DET: begin out = 0; end IN: begin out = 1; end OUT: begin out = 1; end endcase end endmodule fcsm.v: FREQUENCY COUNTERステートマシン module fcsm(clk, ac, reset, ce, preset, load); // Input Port(s) input clk, ac; // Output Port(s) output reg reset, ce , preset, load; // Parameter Declaration(s) parameter GATETIME = 6'b1111; parameter S0 = 2'b00, S1 = 2'b01, S2 = 2'b11 , S3 = 2'b10; // Additional Module Item(s) reg [1:0] state; reg [5:0] count; always@(posedge clk or negedge ac) begin if(!ac) begin state <= S0; count <= 0; end else case(state) S0: begin state <= S1; end S1: begin state <= S2; count <= GATETIME; end S2: if(count) begin count <= count - 1'b1; end else begin state <= S3; end S3: begin state <= S0; end endcase end always@(state) begin case(state) S0: begin reset = 1; ce = 0; preset = 0; load = 0; end S1: begin reset = 0; ce = 0; preset = 1; load = 0; end S2: begin reset = 0; ce = 1; preset = 0; load = 0; end S3: begin reset = 0; ce = 0; preset = 0; load = 1; end endcase end endmodule ctsm.v: CLOCK TIMERステートマシン // Quartus II Verilog Template // 4-State Mealy state machine // A Mealy machine has outputs that depend on both the state and // the inputs. When the inputs change, the outputs are updated // immediately, without waiting for a clock edge. The outputs // can be written more than once per state or per clock cycle. module ctsm ( input clk, in, reset, output reg out ); // Declare state register reg [1:0]state; reg [3:0]count; // Declare states parameter IDLE = 0, ADJ = 1, ADJC = 2, ADJR = 3; // Determine the next state synchronously, based on the // current state and the input always @ (negedge clk or negedge reset) begin if (!reset) begin state <= IDLE; count <= 0; end else case (state) IDLE: if (in) begin state <= ADJ; end ADJ: if (in) begin state <= ADJC; count <= 15; end else begin state <= IDLE; end ADJC: if (in) begin if(count) count <= count - 1'b1; else begin state <= ADJR; end end else begin state <= IDLE; end ADJR: if (in) begin state <= ADJR; end else begin state <= IDLE; end endcase end // Determine the output based only on the current state // and the input (do not wait for a clock edge). always @ (state) begin case (state) IDLE: begin out = 0; end ADJ: begin out = 1; end ADJC: begin out = 0; end ADJR: begin out = 1; end endcase end endmodule control.v: CONTROLブロックRTLインプリメンテーション module control(a, b, dimmer, ac, c800hz, c10hz, ce, reset, preset, load, duty, strobe, timmadj, timhadj); // Input Port(s) input a, b, dimmer, ac, c800hz, c10hz; // Output Port(s) output ce, reset, preset, load, duty, strobe, timmadj, timhadj; // Inout Port(s) // Parameter Declaration(s) // Additional Module Item(s) wire db_a, db_b; dbsm dmsm_a(c800hz, a, ac, db_a); dbsm dmsm_b(c800hz, b, ac, db_b); fcsm fcsm(c800hz, ac, reset, ce, preset, load); ctsm ctsm_a(c10hz, db_a, ac, timmadj); ctsm ctsm_b(c10hz, db_b, ac, timhadj); dimsm dimsm(c800hz, dimmer, ac, duty, strobe); endmodule これらを合成した結果をRTL Viewerで見るとちょっと冗長のように見えるけど動けばよしとしよう。 |
フラット表示 | 前のトピック | 次のトピック |
投稿するにはまず登録を | |