平成26年9月19日版 集積電子回路設計 Part 3:デジタル回路 千葉大学工学部電気電子工学科 橋本研也 論理回路 A B A B Y Y=AB=A+B A B A L H L H Y L L L H Y Y=A+B=AB Y B L L H H A B Y A B A L H L H Y=A+B=A+B Y B L L H H Y L H H H A B A L H L H Y B L L H H Y L H H L セレクタ A 0 B 0 A 1 1 2 3 sel sel H L L sel A x L H _ 0 H L L _ 1 H L H sel H L L L L A x L H L H B x L L H H _ 0 H L H H H _ 1 H H L H H _ 2 H H H L H _ 3 H H H H L デュプレクサ A Rp Y Y A B B sel sel L L H H A L H x x B x x L H Y L H L H sel 3ステートバッファによる実現 (多くの多重化容易) 入出力回路 +5V マイクロ コンピュータ Rp SW1 RB Y 通常の論理ICはGNDへの 電流流出により“L”を判定 無接続の入力は “H”と判 定 RC A I LED 5 VBE VLED RC VLED: LEDの順方向電圧降下 RB(<VBE /ILED) : ベース電流の制限 シュミットトリガ回路 eout Rb V+ Ra ein eout V- eout V V Ra eout Rb ein Vt Ra Rb Ra eout Rb ein Vt Ra Rb V+:”H”出力、 V-:”L”出力 Vs- Vs+ ein シュミットトリガの入出力特性 Vs+=Vt/(1+Rb/Ra)-V-Rb/Ra Vs-=Vt/(1+Rb/Ra)-V+Rb/Ra マルチバイブレータ Vc+ ec Ra R ec V+ Vt C eout V0 Vc- t マルチバイブレータの波形 青曲線を表す式(T=CR) V V (Vo V ) exp(t / T ) Vo Vt (V V ) 2T log(Vo V ) /(Vt V ) 2T log 3 2.2T eout (Vt=(V++V-)/2の時) ワンショットマルチバイブレータ R ein C ein Ra eout ec V+ Vt VV+ eout 青曲線を表す式(T=CR) V- V V (V V ) exp( t / T ) T log(V V ) /(Vt V ) T log 2 0.69T ecut (Vt=(V++V-)/2の時) t 半加算器 HDL(Hardware Description Language) verilogによる構造記述 W0 W1 A B C S module halfadder(s, c, a, b); input a, b; output s, c; 入出力,ワ W2 イヤの定義 wire w0, w1, w2; A L L H H B L H L H S L H H L C L L L H 論理積 assign w0 = a&b, w1 = ~w0, 否定 論理和 w2 = a|b, s = w1 & w2, 論理積 c = w0; endmodule 相互接続の 定義 全加算器 A B Ci 半加算器I0 半加算器I1 A L L L L H H H H B L L H H L L H H Ci L H L H L H L H W1 W0 W2 S L H H L H L L H Co L L L H L H H H HDL(Hardware Description Language) verilogによる構造記述 module fulladder(s, co, a, b, ci); input a, b, ci; Co output s, co; 入出力,ワ S イヤの定義 wire w0, w1, w2; halfadder I0 (.s(w0), .c(w1), .a(a), .b(b)); halfadder I1 (.s(s), .c(w2), .a(w0), .b(ci)); assign co = w1 | w2; endmodule 下位モ ジュール の相互接 続の定義 4bit加算器 Ci A0 B0 A1 B1 A2 B2 A3 B3 全加算器I0 S0 W0 全加算器I1 S1 W1 全加算器I2 全加算器I3 S2 W2 S3 Co module adder4(s, co, a, b, ci); input [3:0] a, b; 4bitデータ input ci; バスの定義 output [3:0] s; output co; wire w0, w1, w2; ワイヤの定義 fulladder I0 (.co(w0), .s (s[0]), .a(a[0]), .b(b[0]), .ci(ci)); fulladder I1 (.co(w1), .s (s[1]), .a(a[1]), .b(b[1]), .ci(w0)); fulladder I2 (.co(w2), .s (s[2]), .a(a[2]), .b(b[2]), .ci(w1)); fulladder I3 (.co(co), .s (s[3]), .a(a[3]), .b(b[3]), .ci(w2)); endmodule 下位モ ジュール の相互接 続の定義 動作試験のためのモジュール(結果を次々加算) begin a = 4'b0001; b = 4'b0001; 2進数の代入 reg [3:0] a, b; データを収 ci = 1'b0; reg [7:0]count; 納するメモ リに定義 $monitor("%t %b %b %b",$time,s,a,b,co); reg ci; for (count=0; count<=7; count=count+1) wire [3:0] s; begin wire co; #10 b = a; a = s; 時間10お休み initial end $finish; 最初にする仕事 終わり end module testadder4; 結果の 出力 7回反復 は以下の通り adder4 inst0 (s,co,a,b,ci); endmodule 始めはこのモ ジュールから VeriLogger Proによる シミュレーション結果 (桁あふれに注意) 4bit加算器 Ci A0 B0 A1 B1 A2 B2 A3 B3 全加算器I0 HDL(Hardware Description Language) verilogによる動作記述 S0 module adder4(s, co, a, b, ci); input [3,0] a, b; input ci; W0 全加算器I1 S1 W1 全加算器I2 全加算器I3 記述は簡単だが、 最適なhardwareが 組み上がるか不明 S2 W2 output [3,0] s; output s, co; reg [3:0] s; reg co; 動作を保管するレジス タの定義 S3 Co always (a or b or ci) begin [co,s] = a + b + ci; end endmodule a,b,ciが変化 した時は常に SR(Set-Reset) フリップフロップ S _ Q R Q S H H L R H L H L L _ S _ R Q _ Q Q L H L H L _ Q L L H L H HH→LLの遷移の結果 は? 早い者勝ち!=実装や 素子によって不定 SW1 Rp _ S _ Rp Rp R Q Rp SW2 _ R SW _ Q スイッチのばたつき (チャタリング) SW2 Q Q t Q _ S _ R _ S SW1 _ Q スイッチのばたつき (チャタリング) t クロック付きSRフリップフロップ _ Q S S S _ Q Q clk R R _ Q Q Q clk clk R S _ Q Q R clk マスタ・スレーブ型 クロックが“H”から“L”に変化し た時のデータを保持 クロックが“H”から“L”に変化し た時のデータを保持 クロック“H”の時に出力変化 それ以外では出力変化せず JKフリップフロップ _ Q J Q K J _ Q K Q clk clk J(S) K(R) Qn _ H H Qn-1 H L H L H L L L Qn-1 pre _ Qn Qn-1 L H _ Qn-1 Qn-1 :1クロック前の出力 clr preset(set):クロックに関わ らず強制的にQ=H clear(reset):クロックに関わ らず強制的にQ= L ラッチ(Dフリップフロップ) 次のクロック入力まで データ保持=メモリ RC D J K pre Q _ Q RB D pre Q _ Q clr clr clk clk D Q 0 0 11 1 0 1 1 1 0 0 0 1 1 0 0 0 1 0 0 0 0 1 1 t Serial-Parallel変換(シフトレジスタ) Q1 D J K pre clr Q J _ Q K Q2 pre clr Q J _ Q K Q3 pre clr Q _ Q クロック入力から出力 変化までに遅延有り clr clk clk D Q1 0 0 1 1 1 0 1 1 1 0 0 0 1 1 0 0 0 1 0 0 0 0 1 1 Q2 0 0 0 1 1 1 0 1 1 1 0 0 0 1 1 0 0 0 1 0 0 0 0 1 Q3 0 0 0 0 1 1 1 0 1 1 1 0 0 0 1 1 0 0 0 1 0 0 0 0 t Parallel-Serial変換(シフトレジスタ) D1 D2 D3 ld Sin clk pre J Q _ K Q clr pre J Q _ K Q clr pre J Q _ K Q clr Sout 2進数(Binary)カウンタ pre J Q _ K Q clr clk clr pre J Q _ K Q clr Q0 pre J Q _ K Q clr Q2 Q1 clk Q0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 Q1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 Q2 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 t 二進化十進数(Binary-Coded Decimal)カウンタ Q0 clk J Q _ K Q Q1 J Q _ K Q Q2 J Q J Q _ _ K Q K Q Q3 Q'2 clk Q0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 Q1 0 0 1 1 0 0 1 1 0 0 0 0 1 1 0 0 1 1 0 0 0 0 1 1 Q2 0 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 Q' 2 Q3 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 t ストップウォッチの回路構成 •クリアパルスの入力で、カウンタをクリア •セットパルスの入力から、計測開始 ③ •リセットパルスの入力で、計測終了 ① Reset Set 基準クロック ② Q (gate) BCDカウンタ Q1 Q2 Q3 Q4 CLR BCDカウンタ Q1 Q2 Q3 Q4 CLR BCDカウンタ Q1 Q2 Q3 Q4 液晶ディスプレイ CLR クロック用発振回路 eout C1 eout C2 音叉型水晶振動子 ein インバータの入出力特性 反転増幅器と等価! 215 =32,768Hz を215分周すれば1Hz! 高安定プログラマブル発振器 (v=Ms/N) 位相検波器 s N分周器 LPF Amp ed v VCO M分周器 Phase-Locked Loop (PLL) VCO:電圧制御発振器(Voltage Controlled Oscillator) • 高安定発振源sによる制御 ⇒ 高精度、高安定 • 分周器をプログラム可能 ⇒ 可変 S水晶発振器による発生 高精度モータ DCモータ+回転検出センサ ミキサ(排他的論理和)とLPFの役割(位相検出) A B A+ B LPF 通過後 閉ループ利得大で、負帰還がか かっている時、差動入力は零 t PLLロック時AとB は90度の位相差 周波数カウンタを作ってみよう •計測区間内のパルス数をカウント •計測後、結果をラッチに保存 •カウンタをクリア clk S Q4 基準クロック 計測開始 計測終了 計測区間 Q(gate) データラッチ カウンタクリア LD CLR t 周波数カウンタの回路構成 基準クロック CLK reset reset BCDカウンタ BCDカウンタ Q4 reset BCDカウンタ Q4 Q4 reset LD set DQ Q (gate) reset CLK reset BCDカウンタ BCDカウンタ Q1 Q2 Q3 Q4 LD D1 D2 D3 D4 Q1 Q2 Q3 Q4 Q1 Q2 Q3 Q4 LD D1 D2 D3 D4 Q1 Q2 Q3 Q4 reset BCDカウンタ Q1 Q2 Q3 Q4 LD D1 D2 D3 D4 Q1Q2 Q3 Q4 液晶ディスプレイ reset DQ set 設計されたカウンタ回路 シミュレーション結果 HDL(Hardware Description Language)による論理回路設計 module jkflipflop(out,outbar,j,k,clk,res); output out,outbar; 入出力線,内部 input j,k,clk,res; レジスタの定義 reg q; always @(negedge clk or negedge res) begin if(!res) begin q <= 0; end else resが偽(0)の時 q=0の代入(リセット動作) その他の時 JKフリップフロップの Verilog-HDLによる記述 clkの立ち下がりもしくは resの立ち下がりの時 低レベル機能の モジュール化 if(j==1) if(k==1) begin q <= ~q; end else begin q <= 1; end else if(k==1) begin q<= 0; end end assign out=q; assign outbar=~q; endmodule もしj=1ならば もしk=1ならば J=K=1の時、qの反転 J=1でK=0の時、q=1 もしk=1ならば J=0でK=1の時、q=0 always構文の終了 出力信号の定義(常時接続) BCDフリップフロップの Verilog-HDLによる記述 module bcdcounter(out,clk,res); output [3:0] out; input clk,res; wire q3,qbar0,qbar1,qbar2,qbar3,a; assign a=1; 相互接続線の定義 a=1(常時接続) jkflipflop I0 (.out(out[0]),.outbar(qbar0),.j(a),.k(a),.clk(clk),.res(res)); jkflipflop I1 (.out(out[1]),.outbar(qbar1),.j(qbar3),.k(a),.clk(out[0]),.res(res)); jkflipflop I2 (.out(out[2]),.outbar(qbar2),.j(a),.k(a),.clk(out[1]),.res(res)); jkflipflop I3 (.out(q3),.outbar(qbar3),.j(out[2]),.k(qbar2),.clk(out[0]),.res(res)); assign out[3]=qbar2&q3; endmodule モジュー ル間の相 互接続の 定義 qbar2とq3の&をoutと定義(常時接続) 論理積 モジュールを組み合わせ て高機能のモジュール化 module bcdtest; wire [3:0] out; reg set,clk,res; 2進数で表示 initial begin $monitor("%t %b %b %b",$time,clk,res,out); clk <=0; res <=0; #40 時間40休止 res <=1; #350 時間350休止 $finish; これ終わり end 試行用信号源の Verilog-HDLによる記述 出力データとその出力 形式の定義 初期動作の定義 always #10 begin 時間10毎の動作 clk<= ~clk; clkの否定(clkの作成) end bcdcounter inst0 (out,clk,res); endmodule VeriLogger Pro Student Versionによるシミュレーション結果 駄目な場合 Field Programmable Logic Array (FPGA) によるハードウェア化 カスタムLSIによ るハードウェア化 FPGAやカスタム Intellectual Property (IP)としての権利化・ LSIへの実装 販売(例: CPUコア) アナログモデルでの シミュレーション(信号 の遅延、鈍り等考慮) トリガ入力後、クロックに同期した パルスを4個出力するためには? clk 入力クロック trig 入力トリガ この区間だけ出力 Q0 Q1 パルスを4 個数える Q2 Q3 最後のパルス リセット信号 out 出力信号 t トリガ入力後、クロックに同期した パルスを4個出力する回路 R Q0 OUT trig clk J J Q Q Q _ _ _ K Q K Q KCLR Q CLR CLR Q1 Q2 実は後述のverilogHDLで最初に設計し、 後にHardware化 J Q3 動くかどうかはシミュレータで実証! 思いもかけない入力もありえる HDL(Hardware Description Language)による論理回路設計 module rsflipflop(out,outbar,set,res); RSフリップフロップの output out,outbar; 入出力線,内部 input set,res; Verilog-HDLによる記述 レジスタの定義 reg q; always @(posedge set or posedge res) setの立ち上がりもしくはresの begin 立ち上がりの時 if(set=1) begin 動作の定義 q <= 1; end set=1の時q=1 else set=0の時q=0 begin q <= 0; end end assign out=q; 出力信号の定義 assign outbar=~q; endmodule module pulse4out(out,clk,trig,res); 4bitデータ output out; 入出力線,相互 input clk,res,trig; 接続線の定義 wire [3:0] q,qbar; wire clk2,a; assign a=1,clk2=res&~q[3]; resとq[3]の否定の&をclk2と定義 rsflipflop I0 (.out(q[0]),.outbar(qbar[0]),.set(trig),.res(~clk2)); jkflipflop I1 (.out(q[1]),.outbar(qbar[1]),.j(q[0]),.k(a),.clk(clk),.res(clk2)); フリップフ jkflipflop I2 (.out(q[2]),.outbar(qbar[2]),.j(q[0]),.k(a),.clk(q[1]),.res(clk2)); ロップ間の jkflipflop I3 (.out(q[3]),.outbar(qbar[3]),.j(q[0]),.k(a),.clk(q[2]),.res(clk2)); 相互接続 assign out=q[0]&clk; endmodule q[0]とclkの&をoutと定義 低レベル機能を利用した高 次機能モジュールの実現 複雑機能のモジュール化 試行用信号源のVerilog-HDLによる記述 module pulse4; wire out; reg clk,res,trig; initial begin $monitor("%t %b %b %b",$time,clk,trig,out); clk <=0; res <=0; trig <=0; #40 res <=1; #25 trig <=1; #5 trig <=0; VeriLogger Pro Student Versionによるシミュレー ション結果 #100 trig <=1; #5 trig <=0; #100 $finish; end always #10 begin clk<= ~clk; end pulse4out inst0 (out,clk,trig,res); endmodule Trig OrCAD PSPICE A/D SVによるシ ミュレーション結果 Reset:FFの初期値 設定(これが無いと シミュレータが怒る) Clk Trigのタイミングによっ てパルス数が変化! 機械同士でデータを交換する(非同期通信) Strobe ホスト Ready 周辺機器 Nビット分のデー タ(Data Bus構造) data Ready Strobe data •周辺機器が準備できるまで待機 •データ出力(データからだけでは データが出ているか否か判定不能) •ストローブ信号を出力 t CPU CLK enable Read/Write address data (同期通信) •クロックもしくはセレクト信号に 同期したデータ出力 メモリ •読み書き動作 •アドレス設定 clk enable Read/Write address data t バス構造 同一配線を選択されたもの同士が利用 アドレ スバス データ バス コントロー ルバス CPU Memory1 Memory2 Memory3 enable Read/Write 必要に応じてユニットを追加・削減可能 3ステートバッファ A Y C=“L”の時 Y A C C H H L A H L x Y H L high-Z high-Z :無接続と同等 C C=“H”の時 双方向性バッファ オープンコレクタ Rp シュミットトリガ Y A 人間を相手にする以上間違いを考慮した設計(Fail Safe) •配線切断(もしくは無接続)の状態ではどうなるか? •GNDとの短絡ではどうなるか? •配線間の短絡ではどうなるか? 高級言語Cによるプログラム例 #include <stdio.h> おまじない(利用する関数群の定義) int main(int argc, char **argv[]) このプログラム(関数)から { スタート int count, cmax; 変数(整数)と初期値の定義 int sum = 0; 変数cmaxの収納場所 scanf("%d",&cmax); cmaxの読み込み(10進数形式) for (count = 1; count <= cmax ; ++count){ sum = sum+count; (sum += count;と標記可) printf("count = %d, sum = %d¥n", count, sum); } return (0); 終了するとき0を返す } 1からcmaxま で順次加算 countとsumの出 力(10進数形式) 行替え lcc-win32でcompileして実行した結果 入力 高級言語CによるBCDカウンタの動作実現 #include <stdio.h> int bcdcount(int, int, int); int main(int argc, char **argv[]) { int count, countmax; int clock = 1, reset = 1; } おまじない(利用する関数群の定義) 使用する関数(moduleと等価)の定義 ここからスタート 変数と初期値の定義 for (count = 0; count <= 5 ; ++count){ clock = -clock; clkの否定(clkの作成) out = bcdcount(clock,reset,in); in=out; printf("time = %d, clock = %d, out = %d¥n", count, clock, out); } reset = 0; scanf("%d",&countmax); countmaxの読み込み for (count = 0; count <= countmax ; ++count){ clock = -clock; clkの否定(clkの作成) out=bcdcount(clock,reset,in); in=out; printf("time = %d, clk = %d, out = %d¥n", count, clock, out); } return (0); 時間5まで reset=1 countmaxまで reset=0 int bcdcount(int clock, int reset, int in) { int out; if( reset == 1 ) { out = 0 ;} else { if( clock == -1 ) {out = in +1 ;} else { out=in ; } } return out; } int updowncount(int clock, int reset, int a, int b, int in) { int out; if( reset == 1 ) { out = 0 ;} else { if( clock==-1) { if( a == 1 & b==0) {out = in +1 ;} if( b == 1 & a==0) {out = in -1 ;} } else { out =in ; } } return out; } reset付BCDカウンタ reset付updownカウンタ lcc-win32で compileして実 行した結果 updown.c 入力 デジタル(Finite-Impulse-Response; FIR)フィルタ ein a0 : 1clk遅延 a1 a2 a3 a4 + + + + N 1 eout (t ) an ein (t n ) n 0 eout N 1 H ( z ) an z n n 0 デジタルシグナルプロセッサ(DSP)による処理 ei ADC DSP DAC eo 離散系信号処理(その1) ei + eo z-1 a 1クロック遅延 = z-1 eo (nT) ei (nT) aei{(n 1)T} 1 1 Eo (z) Ei (z) az Ei (z) {1 az }Ei (z) 1 H(z) 1 az デジタルフィルタ=数値計算によるフィルタリング Finite Impulse Response (FIR) フィルタ ei z-1 a0 z-1 z-1 z-1 a1 a2 a3 a4 + + + + H ( z) N 1 eo an z n n 0 位相直線性が可能、しかし多くの段数を必要 離散系信号処理(その2) ei + eo z-1 a 無限インパルス応答 (IIR)フィルタの一例 eo (nT) ei (nT) aeo{(n 1)T} 1 Eo (z) Ei (z) az Eo (z) 1 H(z) 1 1 az 1 H() 1 aexp( jT) Infinite Impulse Response (IIR) フィルタ ei + + + + -b4 -b3 -b2 -b1 z-1 H ( z ) 1 z-1 z-1 N b z n n 1 eo z-1 1 n 短い演算で急峻な周波数特性可能 ただし、線形位相実現せず デジタルフィルタの一般形 ei z-1 a0 z-1 z-1 a2 a1 z-1 a3 N a4 H ( z) n a z n n 0 N 1 bn z n 1 + + + + -b4 -b3 -b2 -b1 z-1 z-1 z-1 eo z-1 n 平均値フィルタ 1 N1 eo (mT) ei{(m n)T} N n0 有限インパルス応答 (FIR)フィルタの一例 N 1 z 1 n H(z) z N(z1 1) N n0 N1 sin( NT / 2) H ( ) exp{ j ( N 1)T / 2} N sin(T / 2) 線形位相:遅延が周波数に依存せず Relative amplitude in dB 0 sinNx/Nsinx -5 sinNx/Nx -10 -15 -20 -25 -30 -35 -40 -0.5 -0.4 -0.3 -0.2 -0.1 0 0.1 0.2 0.3 0.4 0.5 Relative frequency スペクトラムの 折り返しの影響 zN 1 z=exp(jT)であるから Z e(t ) 1 は? z 1 exp( jNT ) 1 E ( ) exp( jT ) 1 sin( NT / 2) N exp{ j ( N 1)T / 2} 単一パルスの N sin(T / 2) 離散化版 sin( NT / 2) N exp{ j ( N 1)T / 2} ( NT / 2) パルス中心の ずれ:(N-1)T/2 連続関数と離散化関数で何故違う? 窓関数 ブラックマン関数:w(t)=0.42+0.5cos(2t/T) +0.08cos(4t/T) ブラックマン・ハリス関数:w(t)=0.35875+0.48829cos(2t/T) +0.14128cos(4t/T)+0.01168cos(6t/T) 0 1 rectangular Hamming Blackmann -20 Blackmann-Harris 0.8 -40 0.6 -60 0.4 Hamming -80 Blackmann 0.2 Blackmann-Harris -100 0 -1-0.8-0.6-0.4-0.2 0 0.20.40.60.8 1 -1200 2 4 6 8 Relative position Relative frequency Amplitude in dB Weight hd(t)を有限時間で打ち切るための関数:w(t) ハミング関数w(t)=0.54+0.46cos(2t/T) 帯域外抑圧と帯域幅はトレードオフ 10 0 -10 -20 -30 -40 -50 -60 -70 0 0.05 0.04 0.03 0.02 0.01 0 -0.01 -0.02 -0.03 -0.04 -0.05 2 Transfer function in dB Transfer function in dB レメッツ交換法による設計結果 0.5 1 1.5 Relative frequency 手法提案の論文に設 計プログラムが添付 ⇒ 世界中に普及 許容リップルと最も狭 い遷移帯域幅で必用 なタップ数を推定可能 (Infinite-Impulse-Response; IIR)フィルタ ein a0 + + + + b4 b3 b2 b1 N eout (t ) a0 ein (t ) bn eout (t n ) n 1 eout : 1clk遅延 H ( z) a0 N 1 bn z n n 1 ・少ないタップで良好な遮断特性可能(ただし最少位相推移系) ・係数によっては発振(安定条件:全ての極が|Z|<1) ・FIRと組み合わせて、少ないタップで、位相特性、周波数特性 共に良好なフィルタ実現 平均値フィルタの構成タップの場合 新データ temp=clock/TAP; 切捨て演算 position=clock-temp*TAP+TAP; 余りの算出 data[position]=in; data[position-TAP]=in; for (count = 0 ; count < TAP ; ++count) { sum += data[position-count]; } result = sum/TAP; 総和 次々と下 に移動 新データ タップ数での 割り算 return result; } 下まで行ったら 一番上 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 この範囲を加算 int average(int clock, int in) { int position, count, temp, result; long int sum = 0; 32bit整数 #include <stdio.h> #define TAP 8 #define TMAX 20 定数の定義 int average(int, int); int data[2*TAP]; 共用の変数を定義 int main(int argc, char **argv[]) { int count, period, out; int in=0, clock=0; 4回繰り返し TMAX回繰り返し for (period =1 ; period <=4 ; ++period) { for (count = 1 ; count <= TMAX ; ++count) { 傾斜型 ++clock; clockを1ずつ増加 in += 5; inを5ずつ増加 波形の out=average(clock,in); 関数averageの実行 形成 printf("%d, %d, %d¥n", clock, in, out); } 以下省略 TAP=4の結果 TAP=8の結果 計算結果を gnuplotで表示 TAP=16の結果 TAP=32の結果 マイクロプロセッサの構成例 CPU Register A Register B Register C Register D control lines ALU status register Instruction decoder Stack pointer Program counter Address Register Clock Interrupt unit A Reset Interrupt unit B Interrupt Instruction register CPU: Central Processing Unit ALU: Arithmetric Logical Unit Read Write Data bus Address bus 多少高級な言語(アセンブラ)での記述 1. 2. 3. 4. 5. LD A, 30H (16進数で30をレジスタAに代入) DEC A (Aの内容を1つ減少) JNZ 09H (演算結果が"0"で無い場合アドレス09Hにジャンプ) LD 50H, B (レジスタBの内容をアドレス50Hに代入) JMP 30H (アドレス30Hへジャンプ) 機械語への変換 アドレス データ 00 20 30 機械語での表現 02 51 03 25 09 05 32 50 07 20 30 プログラム実行の流れ resetされた時 の開始場所 結果が 0の時 基本的には逐次実行 00H(20H) 01H(30H) 02H(51H) 03H(25H) Jump 04H(09H) 05H(32H) 06H(50H) 07H(20H) 08H(30H) データ 09H(00H) の収納 0AH(18H) 0BH(2CH) 0CH(33H) 0DH(FCH) 0EH(35H) 30H 31H 32H 33H 34H 35H 36H 50H 51H 52H 53H 54H データも同 じ空間上 に展開 サブルーチン(例:三角関数の計算) スタック構造 00H 30H ① 01H 31H ポインタ 02H 32H の位置 call 30H 03H 33H call 50H ② 34H ④ 04H 34H ③① 04H ② 05H 35H ④ 06H 36H return 50H 07H ③ 51H 08H 52H call 30H 09H 53H 0AH 54H return call 50H 0BH 0CH •call: ポインタ1増+ポインタ位置に戻りアドレス収納 0DH +指定アドレスへジャンプ 0EH •return: ポインタ位置のアドレスに移動+ポインタ1減 割り込み処理(例:キーボードが押された場合) 割り込み 発生 割り込み 発生 00H 01H 02H 03H 04H 05H 06H 07H 08H 09H 0AH 0BH 0CH 0DH 0EH ① ② ③ ④ 複数機器の同時 30H の制御等に有効 31H 32H 33H 34H 35H 36H return 1. 現在の処理終了後→ 割り込み 禁止+ポインタ1増+ポインタ位 置に戻りアドレス収納+指定ア ドレスにジャンプ 2. return: ポインタ位置のアドレスに 移動+ポインタ1減+割り込み 禁止解除
© Copyright 2024