FPGA MAX10(3)-Verilog HDL(1)

このエントリーをはてなブックマークに追加

前回、LEDチカチカ回路を作成する為に、下記のようなVerilog HDLでコードを構築しました。


`define CYCLE_1SEC 48000000

//---------------------------
// Top of the FPGA
//---------------------------
module FPGA
(
	input wire clk,			//48MHz Clock
	input wire res_n,			//Reset Switch
	output wire [2:0] led	//LED Output
);

//-----------------------------
// Counter to make 1sec Period
//-----------------------------
reg [31:0] counter_1sec;
wire period_1sec;

always @(posedge clk, negedge res_n)
begin
	if (~res_n)
		counter_1sec <= 32'h00000000;
	else if (period_1sec)
		counter_1sec <= 32'h00000000;
	else
		counter_1sec <= counter_1sec + 32'h00000001;
end

assign period_1sec = (counter_1sec == (`CYCLE_1SEC - 1));

//------------------------------
// Counter to make LED signal
//------------------------------
reg [2:0] counter_led;

always @(posedge clk, negedge res_n)
begin
	if (~res_n)
		counter_led <= 3'b000;
	else if (period_1sec)
		counter_led <= counter_led + 3'b001;
end

assign led = ~counter_led;	//LED on by low level

endmodule

このコードを分析していこうと思います。

module FPGA();~endmodule

これが大枠になるようです。

括弧の中身は実際にFPGAとやり取りする引数になると思います。

それでは、括弧の中身を見ていきます。

input、output,inout

これはポート宣言で、実際にMAX10に信号を送ったり、MAX10から信号をもらったりする部分になります。

input 信号名

と宣言します。

バス(デバイス間通信)の宣言もできます。

input [MSB(上位ビット):LSB(下位ビット)] 信号名

と宣言します。

上記コードではLEDデバイスと通信する為にバスの宣言を使用しています。

wire, reg

これはそれぞれネット宣言,レジスタ宣言とです。

ネット変数は、宣言ではモジュール内で使用する変数で、常にゲートや継続代入文によって値を送受信しており、送受信していない時にはハイインピーダンス状態になります。

ハイインピーダンスとはようは抵抗が大きい状態なので、電流が流れない。

よって、値を送受信されない状態です。

レジスタ変数は、データを保持します。

ネット型変数の信号への代入は、assign 文でのみ可能で、レジスタ変数の信号への代入は,always 文,initial 文などで可能です。

always @(ステートメント)

ステートメントには、信号名が入ります。

信号名だけの時は、信号が立ち上がる時と,立ち下がる時にbegineからendの処理がされます。

posedge 信号名の時は、信号が立ち上がる時、begineからendの処理がされます。

negedge 信号名の時は、信号が立ち下時、begineからendの処理がされます。

beginからendの中には、よく見るif文が記載されています。

if文は、resetスイッチ(SW1)が押された時(Lowの時)、period_1secが1の時に、counter_1secを0に初期化されます。

その他はcounter_1secをインクリメントします。

32'h00000000は32bitの16進数で10進数の0を表します。

32'h00000001は32bitの16進数で10進数の1を表します。

assign

組合せ回路を記述する時にassign 文を使用します。

assgin 文の左辺はネット型変数になります。

右辺には、論理式がよく使用されますが、定数なども設定可能です。

上記コードでは、counter_1secと`CYCLE_1SEC - 1の値がイコールの時に、period_1secに1が代入されます。

ここまでが、カウンタの処理になります。

LEDも使用している文法はほぼ同じです。

LEDはresetスイッチ(SW1)が押された時(Lowの時)、LEDを消すために、counter_ledに0を入力、period_1secが1の時に、色を変更する為に、counter_ledをインクリメントします。

assignを使用して、ledにcounter_ledの否定値を入力します。

LEDはLow信号の時に光るので、led[2:0]が111の時にLEDは消えます。