1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PYNQ で遊ぶ : 5. BRAM を使う (3)

Last updated at Posted at 2020-11-03

これは何か

PYNQ-Z1 を使って遊んでみます。

今回は、下記ができるようになる事を目指します。

関連記事:

5-1. プロジェクトの作成

5-2. 自作モジュールの作成

今回は、次の構成をゴールにします。

  • BRAM を ROM として設置
  • 自作モジュールで、
    • GPIO から、要求するアドレスを受け取り、
    • BRAM-ROM から要求アドレスのデータを取り出し、
    • GPIO へ返す

5-2-1. 自作モジュールを編集する

bram_loader.v
module bram_loader
  (
    input wire CLK,
    
    input wire [31:0] req_addr,
    output reg [31:0] data,
    
    output wire bram_clk,
    output reg [31:0] bram_addr,
    input wire [31:0] bram_data
  );
  
  assign bram_clk = CLK;
  
  always @(posedge CLK)
    begin
      bram_addr <= req_addr;      
      // 今回は、アドレス指示値に、末尾の 2'b00 を付けません。
      // 今回は、Block Memory Generator で、Stand Alone を選択し、
      // かつ、Generate address interface with 32 bits のチェックボックスを OFF にしました。
      // この場合、アドレスは連続する整数で指定します。

      data <= bram_data;
      // 実際は、データは 1 CLK 遅れてやってきます。
      // 連続してデータを取り続ける必要がある場合などは、気をつけてください。
    end
endmodule

5-3. IP を配置し配線する

5-3-1. IP を配置する

スクリーンショット 2020-11-03 11.47.29.png

5-3-2. Block Memory Generator を ROM で設定する

  • Block Memory Generator をダブルクリックして設定を開き、
    • Mode を、Stand Alone に
    • Memory Type を、Single Port ROM にします。
スクリーンショット 2020-11-03 11.17.16.png
  • メモリを設定します
    • データ個数 = 8 、
    • Always Enabled : en ピンが不要になります
    • Registor を使用しない : レイテンシが短くなります
    • Reset を使わない : rst ピンが不要になります
スクリーンショット 2020-11-03 11.34.36.png
  • ROM データを設定します
    • ROM データは外部ファイルで管理されます
    • 今回は、読み込めるものがないので、新規作成します
スクリーンショット 2020-11-03 11.28.31.png
  • ファイル名はとりあえず、適当です
スクリーンショット 2020-11-03 11.29.48.png
  • 編集します
    • 記述方式は 10 進数にしました
    • Depth を 8 に、メモリを設定しておいたので、データを 8 個書きます。スペース区切りです。
スクリーンショット 2020-11-03 11.31.44.png
  • BRAM の設定状況を確認しておきましょう
    • レイテンシは 1 CLK
    • アドレス幅は 3 bit です
スクリーンショット 2020-11-03 11.36.01.png
  • ちなみに、生成された ROM データのファイルは以下のような感じです
    • テキストなので、事前に python などで準備しておくと便利でしょう
design_1_blk_mem_gen_0_0.coe
memory_initialization_radix=10;
memory_initialization_vector=0 10 20 30 40 50 60 70;
  • 設定後の BRAM はピンが減っています
スクリーンショット 2020-11-03 11.59.55.png

5-3-3. IP を配線する

  • 次の配線を行います:
    • axi_gpio_0.gpio_io_i -- bram_loader_0.data
    • axi_gpio_0.gpio_io_o -- bram_loader_0.req_addr
    • blk_mem_gen_0.addra -- bram_loader_0.bram_addr
    • blk_mem_gen_0.clka -- bram_loader_0.bram_clk
    • blk_mem_gen_0.douta -- bram_loader_0.bram_data
スクリーンショット 2020-11-03 12.04.24.png
  • Run Connection Automation (チェックボックスを全て選択) と、Run Block Automation を実行します。
スクリーンショット 2020-11-03 12.05.15.png

こんな感じになりました。

5-4. 後仕上げ

5-4-1. HDL Wrapper を生成する

手順 1-5. HDL Wrapper を生成する と同様の手順です

5-4-2. 生成する

手順 1-7. 生成する と同様の手順です

こんな実装になりました。

スクリーンショット 2020-11-03 12.12.05.png

5-5. PYNQ で実行する

5-5-1. ファイルのアップロード

scp ~/vivado/asobu/asobu05/asobu05.runs/impl_1/design_1_wrapper.bit xilinx@192.168.2.99:pynq/overlays/asobu05/asobu05.bit
scp ~/vivado/asobu/asobu05/asobu05.srcs/sources_1/bd/design_1/hw_handoff/design_1.hwh xilinx@192.168.2.99:pynq/overlays/asobu05/asobu05.hwh

5-5-2. jupyter で実行

スクリーンショット 2020-11-03 12.12.12.png
asobu05.ipynb
import pynq
fpga = pynq.Overlay('asobu05.bit')

gpio = pynq.MMIO(fpga.ip_dict['axi_gpio_0']['phys_addr'], length=0x1000)

# 読み込んでみます。
gpio.read()
# >> 0
# 初期値は 0 でした。

# req_addr に 1 を入れてみます。
gpio.write(offset=0, data=1)
gpio.read()
# >> 10
# アドレス 1 番に格納した 10 が取り出せました。

# req_addr に 5 を入れてみます。
gpio.write(offset=0, data=5)
gpio.read()
# >> 50
# アドレス 5 番に格納した 50 が取り出せました。
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?