3
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 1 year has passed since last update.

KV260プラットフォームにRISC-Vを組み込む(AI EDGEコンテスト対応版)

Posted at

RISC-VをKV260に組み込む

RISC-Vは、オープンソースのCPUです。
次世代CPUの有力候補で、カスタマイズできるのが大きな特徴になっています。
第6回AIエッジコンテストでの課題で、RISCVを搭載することになりました。
ただ、CPUをFPGAに搭載するのにはハードルも高いです。
今回は、オープンソースのVexRISCVを使って、FPGAボード、KV260に搭載する方法をご紹介します。

FPGAにおけるRISCVの位置づけ。

RISCVはオープンソースのCPUです。命令セットが定義されていて、それに対してのCPUの実装は自由になっています。実質的にフリーライセンスなので、そのため多くの発表例があります。
ハードウェアの実装はIC化すると言うのも一つの例ですが、FPGAに実装している例も多いです。

今回のはRISCVを使えば、どの実装でもいいのですが、評価の高かったVexRISCVを使用して、実装します。

実装の方法

KV260に向けてRISCVの実装をご紹介します。VexRISCVを使った実装です。

  1. VexRISCVのGithubからデータを取り込みます。
  2. VexRISCVの開発環境を整える。
  3. パラメータを設定、コンパイル
  4. Vitis向けにヘッダー設計
  5. Vitis アクセラレータに組み込む
  6. RISC-Vのソフトウェアコンパイル
  7. Vitisのアプリケーションを組み込む
  8. KV260で実行

今回、ソフトウェアの実機動作を含めて、全部紹介したかったのですが、実装を進める途中のシミュレーションで未解決の問題見つかりまして見つかりまして、一部はご紹介のみになります。
6番までは出来ています。
また、改めて、ブログの方を更新させていただきます。

事前準備

予め必要なものがあります。

KV260用のVitis プラットフォーム。
RISC-Vを組み込むために必要になります。
ブログ記事を参照にして、作成することが出来ます。

KV260 SDカード
実機動作できる、SDカードイメージが必要です。今回はPetalinux2022.1のバージョンを使っています。

# RISC-V の 組み込みの仕方
VexRISCV は次のページに用意されています。VexRISCVはSpinalHDLで作成されています。このまま、KV260の開発環境に持ってくることは出来ません。HDL(Verilog)に変更する必要があります。
基本的には、ここに書いてあるページのとおりに実行すれば、RISCVのVerilogソースが出来上がります。
KV260に組み込むには、インターフェースの都合から、さらに追加のソースコードが必要になります。

VexRiscvをダウンロードする。

1.1 Ubutu のターミナルを開けて、ワークスペースに移動します。今回は AIEDGEにしました。

cd ~/AIEDGE

1.2 Gitコマンドを使って、VexRISCVのソースコードをダウンロードします。

 git clone --recursive https://github.com/SpinalHDL/VexRiscv.git

1.3 ダウンロードしたファイルを確認します。

ll VexRiscv
VexRISCVの開発環境を整える。

JAVA 8を使用しています。他のバージョンのJAVAを使っていても、切り替えが出来ます。またはコンパイラーまでの紹介になります。

2.1 下記をコマンドラインで順番に実行します。JAVAとspinalHDLの開発環境をインストールします。

# JAVA JDK 8
sudo add-apt-repository -y ppa:openjdk-r/ppa
sudo apt-get update
sudo apt install openjdk-8-jdk -y
sudo update-alternatives --config java
sudo update-alternatives --config javac

# Install SBT - https://www.scala-sbt.org/
echo "deb https://repo.scala-sbt.org/scalasbt/debian all main" | sudo tee /etc/apt/sources.list.d/sbt.list
echo "deb https://repo.scala-sbt.org/scalasbt/debian /" | sudo tee /etc/apt/sources.list.d/sbt_old.list
curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | sudo apt-key add
sudo apt update
sudo apt install sbt
パラメータを設定、コンパイル

ソースファイルはSpinalHDLで書かれています。ただし、XILINXのVitisでは、SpinalHDLは使えません。Verilogか、VHDLに変更する必要があります。幸い、コンパイラーがVerilogを出力しますので、それをもとにして、使用します。ただし、パラメータはSpinalHDL側で変更したほうが望ましいです。

3.1 ソースファイルは、VexRiscv/src/main/scala/vexriscv/demo の中にあります。
今回は、GenFull.scala を使って、実行します。

3.2 必要に応じてパラメータの設定を行います。今回はリセットベクタを0番地にしたいので、Geditなどで、で、GenFull.scaleを開き、14行目以降に、ResetVectorを挿入して実行しました。
なお、詳しいパラメータの説明は次のところに、書いてあります。

パラメータの説明。

      new IBusCachedPlugin(
        resetVector = 0x00000000l,
        prediction = DYNAMIC,

3.3 コンパイルをします。今回はGenFullで行います。各種パラメータは出来ますので、好みに合わせて、好きなタイプのコンパイルを行います。VexRiscv.v が出来上がります。

sbt "runMain vexriscv.demo.GenFull"
Vitis向けにヘッダー設計

出来上がった、Verlogファイルがそのまま使用できればいいのですが、KV260に合わせるためには、インターフェースを追加する必要がああります。

4.1 ファイルを作成します。ソースファイルは折りたたんだ先にありますので、開いてからコピーしてください。ファイル名は、riscv_example.svで保存します。

Verilogソースを作成します。
// This is a generated file. Use and modify at your own risk.
//////////////////////////////////////////////////////////////////////////////// 
// default_nettype of none prevents implicit wire declaration.
`default_nettype none
module riscv_example #(
  parameter integer C_M00_AXI_ADDR_WIDTH = 64,
  parameter integer C_M00_AXI_DATA_WIDTH = 32,
  parameter integer C_M01_AXI_ADDR_WIDTH = 64,
  parameter integer C_M01_AXI_DATA_WIDTH = 32
)
(
  // System Signals
  input  wire                              ap_clk         ,
  input  wire                              ap_rst_n       ,
  // AXI4 master interface m00_axi
  output wire                              m00_axi_awvalid,
  input  wire                              m00_axi_awready,
  output wire [C_M00_AXI_ADDR_WIDTH-1:0]   m00_axi_awaddr ,
  output wire [8-1:0]                      m00_axi_awlen  ,
  output wire                              m00_axi_wvalid ,
  input  wire                              m00_axi_wready ,
  output wire [C_M00_AXI_DATA_WIDTH-1:0]   m00_axi_wdata  ,
  output wire [C_M00_AXI_DATA_WIDTH/8-1:0] m00_axi_wstrb  ,
  output wire                              m00_axi_wlast  ,
  input  wire                              m00_axi_bvalid ,
  output wire                              m00_axi_bready ,
  output wire                              m00_axi_arvalid,
  input  wire                              m00_axi_arready,
  output wire [C_M00_AXI_ADDR_WIDTH-1:0]   m00_axi_araddr ,
  output wire [8-1:0]                      m00_axi_arlen  ,
  input  wire                              m00_axi_rvalid ,
  output wire                              m00_axi_rready ,
  input  wire [C_M00_AXI_DATA_WIDTH-1:0]   m00_axi_rdata  ,
  input  wire                              m00_axi_rlast  ,
  // AXI4 master interface m01_axi
  output wire                              m01_axi_awvalid,
  input  wire                              m01_axi_awready,
  output wire [C_M01_AXI_ADDR_WIDTH-1:0]   m01_axi_awaddr ,
  output wire [8-1:0]                      m01_axi_awlen  ,
  output wire                              m01_axi_wvalid ,
  input  wire                              m01_axi_wready ,
  output wire [C_M01_AXI_DATA_WIDTH-1:0]   m01_axi_wdata  ,
  output wire [C_M01_AXI_DATA_WIDTH/8-1:0] m01_axi_wstrb  ,
  output wire                              m01_axi_wlast  ,
  input  wire                              m01_axi_bvalid ,
  output wire                              m01_axi_bready ,
  output wire                              m01_axi_arvalid,
  input  wire                              m01_axi_arready,
  output wire [C_M01_AXI_ADDR_WIDTH-1:0]   m01_axi_araddr ,
  output wire [8-1:0]                      m01_axi_arlen  ,
  input  wire                              m01_axi_rvalid ,
  output wire                              m01_axi_rready ,
  input  wire [C_M01_AXI_DATA_WIDTH-1:0]   m01_axi_rdata  ,
  input  wire                              m01_axi_rlast  ,
  // Control Signals
  input  wire                              ap_start       ,
  output wire                              ap_idle        ,
  output wire                              ap_done        ,
  output wire                              ap_ready       ,
  input  wire [32-1:0]                     reset_riscv    ,
  input  wire [32-1:0]                     interrupt_riscv,
  input  wire [32-1:0]                     ABS_ADDRESS    ,
  input  wire [32-1:0]                     SAMPLE         ,
  input  wire [64-1:0]                     dBus           ,
  input  wire [64-1:0]                     iBus           
);


timeunit 1ps;
timeprecision 1ps;

///////////////////////////////////////////////////////////////////////////////
// Local Parameters
///////////////////////////////////////////////////////////////////////////////
// Large enough for interesting traffic.
localparam integer  LP_DEFAULT_LENGTH_IN_BYTES = 16384;
localparam integer  LP_NUM_EXAMPLES    = 2;

///////////////////////////////////////////////////////////////////////////////
// Wires and Variables
///////////////////////////////////////////////////////////////////////////////
(* KEEP = "yes" *)
logic                                areset                         = 1'b0;
logic                                ap_start_r                     = 1'b0;
logic                                ap_idle_r                      = 1'b1;
logic                                ap_start_pulse                ;
logic [LP_NUM_EXAMPLES-1:0]          ap_done_i                     ;
logic [LP_NUM_EXAMPLES-1:0]          ap_done_r                      = {LP_NUM_EXAMPLES{1'b0}};
logic [32-1:0]                       ctrl_xfer_size_in_bytes        = LP_DEFAULT_LENGTH_IN_BYTES;
logic [32-1:0]                       ctrl_constant                  = 32'd1;

// RISC V address

logic              dBus_cmd_valid;
logic               dBus_cmd_ready;
logic              dBus_cmd_payload_wr;
logic              dBus_cmd_payload_uncached;
logic     [31:0]   dBus_cmd_payload_address;
logic     [31:0]   dBus_cmd_payload_data;
logic     [3:0]    dBus_cmd_payload_mask;
logic     [2:0]    dBus_cmd_payload_size;
logic              dBus_cmd_payload_last;
logic               dBus_rsp_valid;
logic               dBus_rsp_payload_last;
logic      [31:0]   dBus_rsp_payload_data;
logic               dBus_rsp_payload_error;
logic               timerInterrupt;
logic               externalInterrupt;
logic               softwareInterrupt;
logic               debug_bus_cmd_valid;
logic           debug_bus_cmd_ready;
logic               debug_bus_cmd_payload_wr;
logic      [7:0]    debug_bus_cmd_payload_address;
logic      [31:0]   debug_bus_cmd_payload_data;
logic  [31:0]   debug_bus_rsp_data;
logic              debug_resetOut;
logic              iBus_cmd_valid;
logic               iBus_cmd_ready;
logic  [31:0]   iBus_cmd_payload_address;
logic     [2:0]    iBus_cmd_payload_size;
logic               iBus_rsp_valid;
logic      [31:0]   iBus_rsp_payload_data;
logic               iBus_rsp_payload_error;
logic               clk;
//logic               reset;
logic               debugReset;


// ADDRESS


logic dBus_addflg;
logic iBus_addflg;
logic reset_0;
logic reset_1;



///////////////////////////////////////////////////////////////////////////////
// Begin RTL
///////////////////////////////////////////////////////////////////////////////

// Register and invert reset signal.
always @(posedge ap_clk) begin
  areset <= ~ap_rst_n;
end

// create pulse when ap_start transitions to 1
always @(posedge ap_clk) begin
  begin
    ap_start_r <= ap_start;
  end
end

assign ap_start_pulse = ap_start & ~ap_start_r;

assign reset_0 = ~ap_start | reset_riscv[0];
assign reset_1 = ~ap_start | reset_riscv[1];

// ap_idle is asserted when done is asserted, it is de-asserted when ap_start_pulse
// is asserted
always @(posedge ap_clk) begin
  if (areset) begin
    ap_idle_r <= 1'b1;
  end
  else begin
    ap_idle_r <= ap_done ? 1'b1 :
      ap_start_pulse ? 1'b0 : ap_idle;
  end
end

assign ap_idle = ap_idle_r;

// Done logic
always @(posedge ap_clk) begin
  if (areset) begin
    ap_done_r <= '0;
  end
  else begin
    ap_done_r <= (ap_done) ? '0 : ap_done_r | ap_done_i;
  end
end

assign ap_done = &ap_done_r;

// Ready Logic (non-pipelined case)
assign ap_ready = ap_done;


assign m00_axi_awvalid = (dBus_cmd_valid && dBus_cmd_payload_wr && !dBus_addflg) ? 1:0;


always_ff @(posedge ap_clk or negedge ap_rst_n) begin : proc_dbus_addflg
  if(~ap_rst_n) begin
    dBus_addflg <= 0;
  end  else if(m00_axi_awvalid && m00_axi_awready) begin
    dBus_addflg <= 1;
  end  else if(m00_axi_arvalid && m00_axi_arready) begin
    dBus_addflg <= 1;
  end else if (!dBus_cmd_valid) begin
    dBus_addflg <= 0;
  end
end

assign m00_axi_awaddr = ( dBus_cmd_payload_address > ABS_ADDRESS) ? dBus_cmd_payload_address : dBus_cmd_payload_address + dBus[31:0];

assign m00_axi_awlen = (dBus_cmd_payload_size == 3'd2) ? 8'd1 :
                       (dBus_cmd_payload_size == 3'd3) ? 8'd2 :
                       (dBus_cmd_payload_size == 3'd4) ? 8'd3 :
                       (dBus_cmd_payload_size == 3'd5) ? 8'd4 :
                       (dBus_cmd_payload_size == 3'd6) ? 8'd5 :
                       (dBus_cmd_payload_size == 3'd7) ? 8'd6 : 8'd0;

assign m00_axi_wvalid = dBus_cmd_valid;

assign m00_axi_wdata = dBus_cmd_payload_data;

assign m00_axi_wstrb = dBus_cmd_payload_mask;

assign m00_axi_wlast = dBus_cmd_payload_last;

assign m00_axi_bready = 1'b1;

assign m00_axi_arvalid = (dBus_cmd_valid && !dBus_cmd_payload_wr && !dBus_addflg) ? 1:0;

assign m00_axi_araddr = ( dBus_cmd_payload_address > ABS_ADDRESS) ? dBus_cmd_payload_address : dBus_cmd_payload_address + dBus[31:0];


assign m00_axi_arlen = (dBus_cmd_payload_size == 3'd2) ? 8'd1 :
                       (dBus_cmd_payload_size == 3'd3) ? 8'd2 :
                       (dBus_cmd_payload_size == 3'd4) ? 8'd3 :
                       (dBus_cmd_payload_size == 3'd5) ? 8'd4 :
                       (dBus_cmd_payload_size == 3'd6) ? 8'd5 :
                       (dBus_cmd_payload_size == 3'd7) ? 8'd6 : 8'd0;

assign m00_axi_rready = 1'b1;

assign m01_axi_awvalid = 1'b0;

assign m01_axi_awaddr = 32'b0;

assign m01_axi_awaddr = ( iBus_cmd_payload_address > ABS_ADDRESS) ? iBus_cmd_payload_address : iBus_cmd_payload_address + iBus[31:0];

assign m01_axi_wdata = 32'b0;

assign m01_axi_wstrb = 4'b0;

assign m01_axi_wlast = 1'b0;

assign m01_axi_bready = 1'b1;

assign m01_axi_arvalid = (iBus_cmd_valid  && !iBus_addflg) ? 1:0;

always_ff @(posedge ap_clk or negedge ap_rst_n) begin : proc_ibus_addflg
  if(~ap_rst_n) begin
    iBus_addflg <= 0;
  end  else if(m01_axi_arvalid && m01_axi_arready) begin
    iBus_addflg <= 1;
  end else if (!iBus_cmd_valid) begin
    iBus_addflg <= 0;
  end
end

assign m01_axi_araddr = iBus_cmd_payload_address;

assign m01_axi_arlen = (iBus_cmd_payload_size == 3'd2) ? 8'd1 :
                       (iBus_cmd_payload_size == 3'd3) ? 8'd2 :
                       (iBus_cmd_payload_size == 3'd4) ? 8'd3 :
                       (iBus_cmd_payload_size == 3'd5) ? 8'd4 :
                       (iBus_cmd_payload_size == 3'd6) ? 8'd5 :
                       (iBus_cmd_payload_size == 3'd7) ? 8'd6 : 8'd0;

assign m01_axi_rready = 1'b1;



assign dBus_cmd_ready = m00_axi_wready;

assign dBus_rsp_valid = m00_axi_rvalid | m00_axi_bvalid;

assign dBus_rsp_payload_last = m00_axi_rlast;

assign dBus_rsp_payload_data = m00_axi_rdata;

assign dBus_rsp_payload_error = 0;


assign timerInterrupt = interrupt_riscv[0];
assign externalInterrupt = interrupt_riscv[1];
assign softwareInterrupt = interrupt_riscv[2];

assign  debug_bus_cmd_valid = 0;
assign  debug_bus_cmd_payload_wr = 0;
assign  debug_bus_cmd_payload_address = 0;
assign  debug_bus_cmd_payload_data = 0;

assign iBus_cmd_ready = m01_axi_arready;

assign iBus_rsp_valid = m01_axi_rvalid;

assign iBus_rsp_payload_data = m01_axi_rdata;

assign iBus_rsp_payload_error = 0;

assign clk = ap_clk;

assign ap_done_i = (dBus_cmd_valid && dBus_cmd_payload_wr && (dBus_cmd_payload_address == 32'hFFFFFFF0))? 2'b11:0;

VexRiscv riscv(
  .dBus_cmd_valid(dBus_cmd_valid),
  .dBus_cmd_ready(dBus_cmd_ready),
  .dBus_cmd_payload_wr(dBus_cmd_payload_wr),
  .dBus_cmd_payload_uncached(dBus_cmd_payload_uncached),
  .dBus_cmd_payload_address(dBus_cmd_payload_address),
  .dBus_cmd_payload_data(dBus_cmd_payload_data),
  .dBus_cmd_payload_mask(dBus_cmd_payload_mask),
  .dBus_cmd_payload_size(dBus_cmd_payload_size),
  .dBus_cmd_payload_last(dBus_cmd_payload_last),
  .dBus_rsp_valid(dBus_rsp_valid),
  .dBus_rsp_payload_last(dBus_rsp_payload_last),
  .dBus_rsp_payload_data(dBus_rsp_payload_data),
  .dBus_rsp_payload_error(dBus_rsp_payload_error),
  .timerInterrupt(timerInterrupt),
  .externalInterrupt(externalInterrupt),
  .softwareInterrupt(softwareInterrupt),
  .debug_bus_cmd_valid(debug_bus_cmd_valid),
  .debug_bus_cmd_ready(debug_bus_cmd_ready),
  .debug_bus_cmd_payload_wr(debug_bus_cmd_payload_wr),
  .debug_bus_cmd_payload_address(debug_bus_cmd_payload_address),
  .debug_bus_cmd_payload_data(debug_bus_cmd_payload_data),
  .debug_bus_rsp_data(debug_bus_rsp_data),
  .debug_resetOut(debug_resetOut),
  .iBus_cmd_valid(iBus_cmd_valid),
  .iBus_cmd_ready(iBus_cmd_ready),
  .iBus_cmd_payload_address(iBus_cmd_payload_address),
  .iBus_cmd_payload_size(iBus_cmd_payload_size),
  .iBus_rsp_valid(iBus_rsp_valid),
  .iBus_rsp_payload_data(iBus_rsp_payload_data),
  .iBus_rsp_payload_error(iBus_rsp_payload_error),
  .clk(clk),
  .reset(reset_0),
  .debugReset(reset_1)
);

endmodule : riscv_example
`default_nettype wire

Vitis アクセラレータに組み込む

作成したファイルをVitisプラットフォームに組み込みます。ここでは、新しいアプリケーションプロジェクトを作って、VexRiscV.vを組み込む方法をご紹介します。

5.1 アプリケーションプロジェクトを作成します。。Vitisのメニューから File → New → Application Projectを実行します。

image.png

5.2 アプリケーションプロジェクトを作成する画面が出てきます。 そのままNextを押します。

5.3 kv260_pfmを選択します。Nextを押します。

image.png

5.4 プロジェクト名をきめます。今回は riscv にしました。

image.png

5.5 sysrootを設定します。ここは、共通イメージから解凍したものを使います。次の位置をして、入力してください。
/home/*****/AIEDGE/xilinx-zynqmp-common-v2022.1/sysroots/cortexa72-cortexa53-xilinx-linux

image.png

5.6 アプリケーションのタイプを入力します。今回はEmpty Applicationを選びます。
終わったらFinishをクリックします。

image.png

5.7 Vexriscv は、Verilogで提供されています。このソースコードをVitisに合うように変更する必要があります。Vitisには、RTL WizartdというツールででVerilogの雛形を作ってくれます。、Verilog等が接続できるようになっています。メニューから XILINX→Launch RTL Kernel Wizard で、riscv_kernels を選択します。(出てこないときもあります)

image.png

5.8 作成するための画面が出てきます。そのままNextを押します。

5.9 作成するRTLカーネルと名前等を決めます。今回はriscvにしました。Nextをクリックします。

image.png

5.10 レジスタポートの設定を行います。。今回は4ポート作成しました。reset_riscv interrupt_riscv ABS_ADDRESS SAMPLE です。それぞれ名前を入力したください。
ここでの名前は次のソースコードに反映されます。

image.png

5.11 AXIポートの設定を行います。RISCVからメモリーにアクセスするために使用できます。
Widthは32ビットを使うので、4バイトになります。
image.png

5.12 AXISの設定画面が出てきます。今回は使わないので、そのままOKになります。

5.13 確認の画面が出てきます。OKボタンをクリックします。
ある程度時間が立って、Vivadoが立ち上がります。ここで、追加のソースコードを実行します。

5.14 VexRisc.vのソースコードを追加します。 ソースコードの上の+ボタンをおして、Add Sourceを選択します。
image.png

5.15 ソースファイルを選択することが出来ます。
今回は、Add or Create Design Sourcesを選びます

image.png

5.16 ソースファイルを追加しますので、Add Filesを追加します。

image.png

5.17 VexRiscv.vを探して入力します。3.3で作成しました。VrexRiscvのフォルダーの下にあります。/home/****/AIEDGE/VexRiscv です。

image.png

5.18 riscv_example.svを4.1で作ったものと置き換えます。VexRiscv.vとの接続を行うためです。ファイルをダブルクリックして、その部分を全選択して、置き換えます。保存を忘れないようにしてください。

image.png

5.19 全部終わりましたら、RTLカーネルを作成します。Generate RTL Kernelをクリックします。これはVitisで使える用のまとめる役目があります。

image.png

5.20 どのような形で渡すかを書いています。ここではソースコードのみを渡します。Sorce-olny Kernelを選択します。

image.png

5.21 開いているVivadoを閉じるかを聞いてきます。このまま閉じてください。Vitisに戻ります。

image.png

5.22 今のままでは、まだ、VitisでハードウェアIPの認識がありません。IPの認識をさせるために、riscv_kernels の設定を行います。IPの追加を行います。右上のActive build Configration は Hardwareに設定の選択してください。

image.png

5.23 どのファイルをトップファイルにして、IP化するかを聞かれます。今回はriscvを選択します。

image.png

5.24 コンパイルをします。 riscv_system をクリックして、ハンマーアイコンをクリックします。
これで、kv260で動く、ハードウェア構成が出来上がります。

image.png

AIエッジコンテスト参加者は、ここまでIPを作りまして、AIの方と組み合わせれば、ハードウェアの構成は週作成できます。
この使い方は、Vitis AIの作り方の方で、ご紹介させていただきます。

RISC-Vのクロスコンパイラー環境、コンパイル

RISCVはコンパイルは、CPUなので、コンパイラーが必要になります。知名度が高いため、検索すれば、かなり使い方は探し出さます。
今回はGNUのツールチェンを使いました。

詳しくは整理して、追加します。

Vitisのアプリケーションを組み込む

KV260では、何かしらの方法で、RISCVが動くプログラムを用意しないといけません。
今回は、Vitisで作成できる、アプリケーションでRISCVの動作を管理します。
クロスコンパイラーでSRECという形式でファイルが作成できます。それを取り込んでメモリーを介して、RISCVにデータをお渡しします。

ブログ発表までに間に合わせたかったのですが、デバッグがうまくいかず、
後日詳細を掲載させていただきます。

KV260で実行

 作成した、ファイルをKV260で動かします。
 必要なファイルはriscv.xclbin と、Vitisプラットフォーム作りでで作成した、pl.dtbo,shell.json です。ここも整理して、後日詳細を掲載させていただきます。

# お詫び

AIエッジコンテストのため、まだ途中でしたが、ブログ公開をさせていただきました。
一部、動作に不具合点があって、中途半端になってしまいました。
後日、追加しますので、ご了承ください。

 

3
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
3
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?