FPGA:HDLとXDCの勉強
無事にLチカできたが、サンプルをDLしてきて、ボードに書き込んで動作させてみたというだけ・・・
XDCや回路記述言語について理解をすすめる必要がある。たくさんexampleを見ながら書いて動かしてとしか方法はないのですが・・・
制約ファイル(XDCファイル)
FPGAの端子の割り当て
信号レベルの設定
クロックの周波数と波形の設定
を行うファイルの事
XDC は Xilinx Design Constraint (ザイリンクス・デザイン・コンストレイント)
自由にできるものを特定のピンに束縛することから、”制約”
いちからすべて記載する訳ではなくDIGILENT社の制約ファイルを編集する形で使っていく。DIGILENT社オリジナルの制約ファイルを見てみる。
https://github.com/Digilent/digilent-xdc/
に各ボードに対応するMaster XDC Filesがおいてある。
## Clock signal | |
#set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { CLK100MHZ }]; #IO_L12P_T1_MRCC_35 Sch=gclk[100] | |
#create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports { CLK100MHZ }]; | |
## Switches | |
#set_property -dict { PACKAGE_PIN A8 IOSTANDARD LVCMOS33 } [get_ports { sw[0] }]; #IO_L12N_T1_MRCC_16 Sch=sw[0] | |
#set_property -dict { PACKAGE_PIN C11 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }]; #IO_L13P_T2_MRCC_16 Sch=sw[1] | |
#set_property -dict { PACKAGE_PIN C10 IOSTANDARD LVCMOS33 } [get_ports { sw[2] }]; #IO_L13N_T2_MRCC_16 Sch=sw[2] | |
#set_property -dict { PACKAGE_PIN A10 IOSTANDARD LVCMOS33 } [get_ports { sw[3] }]; #IO_L14P_T2_SRCC_16 Sch=sw[3] | |
## RGB LEDs | |
#set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { led0_b }]; #IO_L18N_T2_35 Sch=led0_b | |
#set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { led0_g }]; #IO_L19N_T3_VREF_35 Sch=led0_g | |
#set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { led0_r }]; #IO_L19P_T3_35 Sch=led0_r |
によると、Arty A7は100MHzの水晶振動子がピンE3に接続されているのでPACKAGE_PIN E3という記述だろうという事はわかる。
IOSTANDARD の部分は3.3Vの振幅でと指定しているところ
ネットに落ちているのXDCファイルの例も眺めると、
set_property PACKAGE_PIN E3 [get_ports { CLK }];
set_property IOSTANDARD LVCMOS33 [get_ports { CLK }];
と2行に分けて記載しているものもあるので、-dict { }の所が調べきれていないがまとめて指定する方法の模様。
# LEDs
set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { RGB0_Blue }]; #IO_L18N_T2_35 Sch=led0_b
set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { RGB0_Green }]; #IO_L19N_T3_VREF_35 Sch=led0_g
set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { RGB0_Red }]; #IO_L19P_T3_35 Sch=led0_r
の9ベーシックIOと対比すると、Lチカに用いたLED0の3色のピンはそれぞれG6,F6,E1がそれぞれRGBに対応しているFPGAのピンに接続されているので、それぞれ指定していて、振幅も指定している
set_property
https://www.acri.c.titech.ac.jp/wordpress/archives/3449#toc9
https://www.paltek.co.jp/techblog/techinfo/211018_01
create_clock
https://www.xilinx.com/support/documentation/sw_manuals_j/xilinx2012_3/ug903-vivado-using-constraints.pdf
のP35に周期とデューティー比の記載について説明がある。
のP35に周期とデューティー比の記載について説明がある。
blink.xdcの中身は以下
# Clock Signal
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { CLK }];
create_clock -add -name CLK -period 10.00 -waveform {0 5} [get_ports { CLK }];
#create_clock -add -name SYSCLK -period 10.00 -waveform {0 5} [get_nets { design_1_i/clk_wiz_1/clk_out1 }];
#Reset
set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports { RST }]; # BTN[3]
# RGB LEDs
set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { LED_RGB[0] }]; # Blue
set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { LED_RGB[1] }]; # Green
set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { LED_RGB[2] }]; # Red
ハードウェア記述言語
ハードウェア記述言語にはいろいろあるらしい・・・特徴はまだよくわからないが
VHDL
拡張子は.vhd
https://digilent.com/reference/programmable-logic/arty-a7/start
のデモはこちら側で記述されている。
Velilog
verilogの拡張子は.v。これの進化版でSystem Verilogの拡張子.svってのもあるらしく、これから学ぶのであれば後者とも記載があった。
FPGAプログラミング大全の書籍はこちら側での記述になっている。
module blink (
input CLK,
input RST,
output reg [2:0] LED_RGB
);
CLK、RST、LED_RGBは対になっているXDC内で定義
/* divide the system clock */
reg [25:0] cnt26;
always @( posedge CLK ) begin
if ( RST )
cnt26 <= 26'h0;
else
cnt26 <= cnt26 + 1'h1;
end
reg [25:0] cnt26;の所で26ビット分のレジスタを用意している。
@( posedge CLK ) の所がクロックがあがるたびにendまでの処理をするということ。
posedgeなのでポジティブ(0から1になる時のエッジ)を検出する。
if (RST)で、初期状態を入れていて、初期伊賀では、cnt26のカウンターを一つ一つあげていく動作になる(と解釈した・・・不勉強なので間違っているかもしれないがだいたい間違ってはない)
1'h1は1ビットの16進数で1という意味
wire ledcnten = (cnt26==26'h3ffffff);
カウンタがffffffとイコールになったら、ledcntenが1になる。
/* quintic counter for LED */
reg [2:0] cnt3;
ここでcnt3という名の3ビットのレジスタを用意
always @( posedge CLK ) begin
if ( RST )
cnt3 <= 3'h0;
else if ( ledcnten )
if ( cnt3==3'd4)
cnt3 <=3'h0;
else
cnt3 <= cnt3 + 3'h1;
end
初期は、3'h1なので000として、ledcnten が1になったらcnt3 のカウントに001を足していく。3'd4だから11の時は3'h0にしてもとに戻す。
/*LED Decoder */
always @* begin
case ( cnt3 )
3'd0: LED_RGB = 3'b100;
3'd1: LED_RGB = 3'b010;
3'd2: LED_RGB = 3'b001;
3'd3: LED_RGB = 3'b111;
3'd4: LED_RGB = 3'b000;
default:LED_RGB = 3'b000;
endcase
end
LED_RGBはLED_RGB[0], LED_RGB[1], LED_RGB[2]の3つで
cnt3の値によって、どれを点灯させるかを決めている。
endmodule
モジュールの最後には必ず置く。
解釈は間違ってはいないと思うが・・・
Velilog HDLの書き方を勉強してここに記載している内容を理解しろって事・・・
コメント
コメントを投稿