#verilogまとめ
モジュール単位で色々まとまってる -> モジュール毎にIOポート的アレがある {}ではなくbegin-end
module TEST(IOPORT);
~
endmodule
alwaysとか使うと並列なアレができる 大体FPGAの中にブロック区画を設けてその内部での処理をそれで記述、クロック同期指定があるのでそれに合わせてその区画が動いてる感じ
module TEST(
input wire iCLK
);
always@(posedge iCLK) begin
end
endmodule
wireの他にregがある
レジスタでは?と思うけど違う、これらはネット型変数かレジスタ型変数かの違いで、C言語的に言うならスコープの違い. ビット幅が指定できて、
wire [MSB:LSB] name;
reg [MSB:LSB] name;
みたいな感じで指定できる。LEかBEかも指定可能というか意識せずにできる
assign文はwire指定されたモノ同士を繋ぐいわばケーブリング関数
module TEST(
input wire iCLK
);
wire [15:0] A;
assign A = iCLK * 16;
endmodule
これはregには適用出来ない。なぜならreg指定された変数はalways内(=特定ブロック内)のみで使用可能な変数として宣言されているから。 ついでに書くとassign出来ない理由はregは値保持が役割でありそれを出力するならいいけどもその値は外部入力に依存するべきでは無く、常にwireでワンクッション置いた上でその値を利用してクロック毎に動くべきだから。
まとめるとこうなる
- wire型
- assignによって接続
- 関数内では参照のみの使用
- reg型
- always内部で使用
- 値の保持が主な役割
- 代入等は普通にできる
- 外では参照のみ
- 性質上更新がクロック毎になるのが自明
代入にも2種類あり、それぞれブロッキング、ノンブロッキングな代入と呼ばれる。 まあ名前の通り。
ブロッキング時は=、ノンブロッキングなら<=を使う
define的なparameterとやらもあるけど正直使わん
そいえばalwaysに書いたposedgeの類は信号の立ち上がりか立ち下がるかのアレになる
module TEST(
input wire iCLK
);
// 立ち上がり
always@(posedge iCLK) begin
end
// 立ち下がり
always@(negedge iCLK) begin
end
// 立ち上がり&立ち下がり(正確にはiCLKの変化毎)
always@(iCLK) begin
end
endmodule