FPGAプログラミング大全 Xilinx編をベースに勉強中。
ultra96で外部にボタンSWをつけて、Lチカの速度を変更できるようにした。
そもそもultra96には、PL側にSWは付属していないので、外部に回路をもって対応することになる。外部とは。Low Speedのコネクタに接続することになる。
以下、回路図だ。(初めて書いた回路図になる。)
https://www.lucidchart.com/
を使用して書いてみた。
ただ、ボタンSWは持っていないので、こんな感じのオスーオスのケーブルをLow Speedのコネクタに接続すればSWなるかなぁ!?と想像している。
しかし、以下の記事を読むと、ちょっとSWとの間に抵抗を入れて、pull-down抵抗を入れた方がよさそうな気がした。
https://voltechno.com/blog/pullup-pulldown/
いつもどおりチュートリアル1をベースに実装してく。
https://www.element14.com/community/docs/DOC-91053/l/01ultra96vivadointro2018201zip
Create Block Designから、ADD IPからZYNQで検索して、Zynq
UltraScale+ MPSoCを追加する。Run Block Automationをクリックして、ZYNQの設定を行う。
次に、ZYNQをクリックして、Clock Configuration→OutputClock→Low Power Domain Clocks→PL Fabric Clock→PL1をチェックする。
原因不明だが、PL0を使用するとうまくいかなかった。またか。。。入力が常に0に見える。
次にSWの電源用のGPIOを追加する。ADD IPからGPIOを検索して、AXI GPIOを追加する。Run Connection Automationを行う。GPIOは、SWを2個使うので、2本だけあればよい。そのため、GPIOをダブルクリックして、2個だけ使用するように設定する。
次に、Lチカ用のコードを追加する。本に載っていたのは、LEDが4個だったが、2個に変更した。ファイル名は、blinkspeed.vとdebounce.vの2ファイルだ。
最初に、すでに、あるdesign_1を右クリックして、Create HDL Wrapperをしておく。
で、その下にできたdesign_1.vのところで、右クリックAdd Sourceあら、blinkspeed.vとdevounce.vを追加する。
blinkspeed.vの方をドラック&ドロップして、Block Designに追加する。LEDに接続する端子(LED[1:0])と、SWからの入力の端子(BTN0,BTN1)の端子を右クリックして、Make Externalをして外部端子を作成する。そして、入力クロックのBL_CLKは、pl_clk1に接続する。そして、BL_RSTは、pl_resetn0に接続した。
ちなみに、今回は困ったのはこのRSTで、RSTは、LowでReset解除になっている。つまり、0になった時に、内部の変数を初期化するのが正しい。本だと逆になっていた。そもそも本の題材はultra96じゃないけど。。。
(blinkspeed.v参照)
次に制約ファイルを作成して追加する。制約ファイルの名称は、b.xdcとする。
Validate Desiginを実施すると、クロックをpl_clk1を使っているので、RSTをクロックが合わないよと言われるが、今回は気にしない。Generate Bitstreamを行う。
SWだが、以下のようなケーブルを使用して、抜き差しをしてSWにならないかと思ったが、ダメあった、SWからの入力のBTN0を観測したところ、ケーブルが未接続の状態で、常に、1だった。たぶん、pull-downの抵抗を使って、未接続状態の時に0になるようにしないとダメらしい。
で、ソフトウェアだが、チュートリアル2をベースにそのままつくればよい。あとは、bitstreamを流し込んで、hello worldを実行すればOK!
今日は、SWの回路は実装だけ、LEDがチカチカしているのだけ確認した!SWの動作は確認しないでおく。。。いつかやろうー。
———-blinkspeed.v——-
odule blinkspeed(
input BL_CLK,
input BL_RST,
input BTN0,
input BTN1,
output reg[1:0] LED
);
wire UP, DOWN;
debounce d0 (.BE_CLK(BL_CLK), .BE_RST(~BL_RST), .BTNIN(BTN0), .BTNOUT(UP));
debounce d1 (.BE_CLK(BL_CLK), .BE_RST(~BL_RST), .BTNIN(BTN1), .BTNOUT(DOWN));
assign UP = 0;
assign DOWN = 0;
reg [1:0] speed;
always @(posedge BL_CLK) begin
if (~BL_RST)
speed <= 2’h0;
else if (UP)
speed <= speed + 2’h1;
else if (DOWN)
speed <= speed – 2’h1;
end
//always @(posedge BL_CLK) begin
// speed <= 2’h2;
//end
reg [24:0] cnt25;
always @( posedge BL_CLK) begin
if (~BL_RST)
cnt25 <= 25’h0;
else
cnt25 <= cnt25 + 25’h1;
end
reg ledcnten;
always @*begin
case ( speed)
2’h0: ledcnten = (cnt25 == 25’h1ffffff);
2’h1: ledcnten = (cnt25[23:0] == 24’hffffff);
2’h2: ledcnten = (cnt25[22:0] == 23’h7fffff);
2’h3: ledcnten = (cnt25[21:0] == 22’h3fffff);
endcase
end
reg [3:0] cnt3;
always @(posedge BL_CLK) begin
if (~BL_RST)
cnt3 <= 4’d4;
else if (ledcnten)
if (cnt3==4’d6)
cnt3 <=5’h0;
else
cnt3 <= cnt3 + 4’h1;
end
always @* begin
case (cnt3)
4’d0: LED = 2’b00;
4’d1: LED = 2’b10;
4’d2: LED = 2’b01;
4’d3: LED = 2’b10;
4’d4: LED = 2’b11;
4’d5: LED = 2’b10;
4’d6: LED = 2’b01;
endcase
end
endmodule
set_property PACKAGE_PIN A9 [get_ports {LED_0[0]}]
set_property PACKAGE_PIN B9 [get_ports {LED_0[1]}]
set_property PACKAGE_PIN D7 [get_ports BTN0_0]
set_property PACKAGE_PIN F8 [get_ports BTN1_0]
set_property PACKAGE_PIN F7 [get_ports {gpio_rtl_tri_o[0]}]
set_property PACKAGE_PIN G7 [get_ports {gpio_rtl_tri_o[1]}]
set_property IOSTANDARD LVCMOS18 [get_ports -of_objects [get_iobanks 26]]
最初に書いた回路図をpullup抵抗を追加して記載しておく。