2. ソースを書く 数値表現 数値表現形式 : ss'fnn...n ss は, 定数のビット幅を 10 進数で表します f は, 基数を表します b が 2 進,o が 8 進,d が 10 進,h が 16 進 nn...n は, 定数値を表します 各基数で許される値を書くこ Verilog ビット幅 基数 2 進表現 1'b0 1 2 進 0 4'b0100 4 2 進 0100 4'd4 4 10 進 0100 4'd7 4 10 進 0111 8'hf0 8 16 進 11110000 8'd1000_1111 8 2 進 10001111 1 32 10 進 000...0001
モジュール回路動作を記述する Verilog-HDL では 回路動作はキーワード module と endmodule で囲まれたモジュール内に定義します キーワード module に続き モジュール名と FPGA の入出力ポート リストを記述します 2. ソースを書くモジュール構文 : module モジュール名 ( 信号名 {, 信号名 }); { ポート宣言文 } { パラメータ宣言文 } { 内部信号宣言文 } { 順序的構文 } { プリミティブ } { 階層構造 } endmodule モジュール名は PwmCtrl 入出力ポートリストは RST_N,CLK,LED0 3 つの入出力ポートを持つことがわかります
2. ソースを書く ポート宣言文 ポート信号は ポート宣言文によって入力 (input) 出力 (output) 双方向入出力 (inout) のいずれかのモードを指定し ベクタの場合はベクタ幅を指定します reg はデータタイプです counter0 という名前の 28bit 幅のレジスタ変数を用意します counter0 27 2 1 0
データタイプ データタイプは 信号や変数の持ちうる状態を指定したもの 2. ソースを書く レジスタ宣言 reg : データを保持する記憶素子一度代入されてから次に代入されるまで値を保ちます レジスタへの代入文は initial 文か always 文 またはサブプログラム内の手続き的ブロックでのみ可能です ネット宣言 wire: モジュールやゲート同士を接続している物理的な状態常にゲートや継続代入文によってドライブされ ドライブされていない時にはハイインピーダンス状態になります レジスタ宣言 : reg <[MSB:LSB]> レジスタ名 ; ネット宣言 : ネットタイプ <[MSB:LSB]> < 電荷ストレングス > < 遅延 > ネット名 ; ネットタイプ := wire wand wor tri triand trior tri1 tri0 trireg supply0 supply1 電荷ストレングス := small medium large
2. ソースを書く 代入文 代入文には 2 種類の基本的な形式があります 継続的代入文 手続き的代入文 if-else 文 case 文 ループ文 遅延制御文などの動作構文 ネットに値を継続的に代入するネット型変数への代入には assign 文でのみ可能 手続きブロックの中でレジスタに値を代入する レジスタ変数の信号への代入は,always 文 initial 文 task function の中で可能です FPGA では ノイマン型の CPU とは一命令ずつ処理を行いません 電気回路なので同時に動作します そのため HDL 言語も C 言語のように一行ずつ処理を書くプログラムと異なり部分があります 代入文が FPGA の特徴をよく現しています FPGA では物理的な電気結線で FPGA 内に論理回路を構築します そのため 複数の代入文が同時に処理されます
2. ソースを書く 継続的代入文 ベクタまたはスカラ ネットに対して継続的に値をドライブする 継続代入文では 右辺に含まれる信号の値が変化すると 自動的に式が評価され左辺へ代入 ネットタイプの宣言と同時に代入式を定義するか またはすでに宣言されたネットに対して assign 文によって代入式を定義します 遅延値が指定されている場合は 指定された時間だけ代入が先送りされます 継続代入文構文 : wire <[MSB:LSB]> < 遅延 > 代入文 ; assign < 遅延 > 代入文 ;
継続的代入文 ネットに値を継続的 2. ソースを書く : 継続的代入文 組合せ回路 (assign 文 ) assign ネット型変数 = 論理式など ; 簡単な組合せ回路を記述するときには assign 文を用います assgin 文の左辺は, ネット型変数 ( ポート宣言, あるいは wire 宣言された変数 ) でなければなりません < 記述例 > wire a, b, c, d; wire [3:0] s, t, u; assign c = a b; // 2 入力 OR assign u = s & t; // 4ビット2 入力 AND assign c = (d == 1)? a: b; // セレクタ (d が1のとき a を,1 // でないとき b を,c に出力 )
Verilog: module example( a, b, c, y); input a, b, c; output y; 2. ソースを書く : 継続的代入文 module example(input a, b, c, output y); assign y = ~a & ~b & ~c a & ~b & ~c a & ~b & c; endmodule a b c Verilog Module y
Verilog: module example( a, b, c, y); input a, b, c; output y; 2. ソースを書く : 継続的代入文 module example(input a, b, c, output y); assign y = ~a & ~b & ~c a & ~b & ~c a & ~b & c; endmodule a b c Verilog Module y
Verilog: module example( a, b, c, y); input a, b, c; output y; 2. ソースを書く : 継続的代入文 module example(input a, b, c, output y); assign y = ~a & ~b & ~c a & ~b & ~c a & ~b & c; endmodule a b c Verilog Module y
Verilog: module example( a, b, c, y); input a, b, c; output y; 2. ソースを書く : 継続的代入文 module example(input a, b, c, output y); assign y = ~a & ~b & ~c a & ~b & ~c a & ~b & c; endmodule a b c Verilog Module y
Verilog: 2. ソースを書く : 継続的代入文 module example(input a, b, c, output y); assign y = ~a & ~b & ~c a & ~b & ~c a & ~b & c; endmodule b c y un5_y y a un8_y a b c Verilog Module y
3 ステート ハイインピーダンス 2. ソースを書く : 継続的代入文 入力信号により 出力の信号が決まり 1 または 0 の状態となります しかし 一部の論理素子ではこの 1 0 以外に もう 1 つの状態を持つものがあります ハイインピーダンス状態と呼びます 入力 制御 1 制御 2 制御 3 入力 入力 A さんが話しているとき B,C は 0(0V=GND) を出力してはいけない
ハイインピーダンスアウトプット 2. ソースを書く : 継続的代入文 module tristate(input [3:0] a, input en, output [3:0] y); assign y = en? a : 4'bz; endmodule 条件演算子 (Conditional Operator) 式 1? 式 2 : 式 3 式 1 が 0 でない ( 真である ) 場合には, 式 2 を返し,0( 偽 ) のときには式 3 を返します a[3:0] en y[3:0] 入力制御信号 en が 1 のときは y には a の値がそのまま出力される 入力制御信号 en が 0 のときは y はハイインピーダンス状態となる
遅延値が指定されている場合 module example(input a, b, c, output y); wire ab, bb, cb, n1, n2, n3; assign #1 {ab, bb, cb} = ~{a, b, c}; assign #2 n1 = ab & bb & cb; assign #2 n2 = a & bb & cb; assign #2 n3 = a & bb & c; assign #4 y = n1 n2 n3; endmodule # 遅延値 2. ソースを書く : 継続的代入文
2. ソースを書く : 継続的代入文 遅延制御 # 遅延式 遅延値は整数で 記述には時間単位 (ns ps など ) は指定せず 遅延値は時間単位を持たないユニット時間となります 遅延値がどのような時間単位であるかは `timescale 文によって指定します たとえば 遅延値 10 が 10 ns を意味させるためには `timescale 1 ns / 1ns のように指定します 1 ユニットを 100ps にし 丸め精度を 100ps にするには `timescale 100ps/100ps `timescale シミュレーションの単位を設定する ( 書式 ) `timescale 1 ユニットの時間 / 丸めの精度
wire [7:0] A, B; wire [8:0] F; wire CIN, X, Y, Z; wire [1:4] bus ; A 2. ソースを書く : 継続的代入文 assign bus = enable? data : 4'bz; assign #1 F = A + B + CIN; assign Z = ~(X & Y); B F enable data[3:0] bus[3:0] X Y CIN Z A[7:0] bus B[7:0] F[8:0] CIN X Y CIN
手続き的代入文 2. ソースを書く手続き的代入文 手続き代入文は 値をレジスタ ( 変数 ) に代入するもので always initial task function のような手続き文内で使用します
手続き文 always 2. ソースを書く手続き的代入文 module flop(input clk, input [3:0] d, output reg [3:0] q); always @ (posedge clk) q <= d; endmodule D Flip-Flop clk のたち上がりで q の値を更新します ( q には d の値が入る )
手続き文 always と case の組合せ 2. ソースを書く手続き的代入文 module sevenseg(input [3:0] data, output reg [6:0] segments); always @(*) case (data) // abc_defg 0: segments = 7'b111_1110; 1: segments = 7'b011_0000; 2: segments = 7'b110_1101; 3: segments = 7'b111_1001; 4: segments = 7'b011_0011; 5: segments = 7'b101_1011; 6: segments = 7'b101_1111; 7: segments = 7'b111_0000; 8: segments = 7'b111_1111; 9: segments = 7'b111_1011; default: segments = 7'b000_0000; // required endcase endmodule coma comb comc comd
ブロッキング代入文とノンブロッキング代入文 Verilog-HDL では並列性のある命令の流れを記述することができます それを実現するのがノンブロッキング代入文です 通常のプログラム言語のように普通の代入文をブロッキング代入文と呼びます 2. ソースを書く ブロッキング代入文 ノンブロッキング代入文 ブロッキング代入文が 代入処理が終了して次の文を実行する initial begin a = 3; b = 5; #10 a = b + 1; b = a + 1; end initial begin a <= 3; b <= 5; #10 a <= b + 1; b <= a + 1; end #10 は,10 単位時間後 同時刻に行われている ブロッキング代入文 a = 6, b = 7 a = 6, b = 4 ノンブロッキング代入文 ノンブロッキング代入文では 同時刻の代入文は, 右辺を評価してから代入する
2. ソースを書く ブロック文 ブロック文は 2 つ以上の手続き文をまとめて 1 つの文のように定義するものです 順序ブロック : 並行ブロック : begin と end で区切る fork と join で区切る RST_N の立下りと CLK の立上りで実行される 並行ブロック構文 : fork <: ブロック名 > { パラメータ宣言 } { 内部データタイプ宣言 } { 手続き文 } join 順序ブロック構文 : begin <: ブロック名 > { パラメータ宣言 } { 内部データタイプ宣言 } { 手続き文 } end 順序ブロック 例 A=4 b0011 : 4 ビットの 0011 = 10 進数の 3 A =2 b01 : 2 ビットの 01 =10 進数の 1 ブロッキング代入 count0 に 0 を入れる ブロッキング代入 count0+1 したのを count0 に代入
2. ソースを書く 組合せ回路 (assign 文 ) assign ネット型変数 = 論理式など ; 簡単な組合せ回路を記述するときには assign 文を用います assgin 文の左辺は, ネット型変数 ( ポート宣言, あるいは wire 宣言された変数 ) でなければなりません < 記述例 > wire a, b, c, d; wire [3:0] s, t, u; assign c = a b; // 2 入力 OR assign u = s & t; // 4ビット2 入力 AND assign c = (d == 1)? a: b; // セレクタ (d が1のとき a を,1 // でないとき b を,c に出力 )
2. ソースを書く