Welcome to Jelly's documentation!

Overview

はじめに

Jelly とは、FPGA上にてリアルタイムコンピューティングを行う為のプラットフォームを目指している、各種モジュール群です。

もともとはFPGA向けの MIPS-I ライクな命令セットのコアを有したソフトコアプロセッシングシステムで、Real-time OS を動かすことからスタートしたプロジェクトですが、昨今ではXILINXのZynqシリーズのようにCPU部とロジック部を合わせもあったSoCも 台頭してきたため、より柔軟にRTLロジック資産(Verilog)と、CPU資産(C/C++/Pythonなど)を組み合わせて、エッジでのリアルタイムコンピューティングを目指しつつIoT連携できるプラットフォームとして進化を続けています。

FPGAと言いつつかなり Xilinx 専用になっている点はご容赦ください。RTL自体は汎用なものも多いです。

構成

トップディレクトリ

ディレクトリ 説明
docs 各種ドキュメント
projects 各種プロジェクト
rtl 各種RTLソース
include C/C++用インクルードファイル
python Python関連
testbench 各種テストベンチ
tools 各種ツール類

rtl ディレクトリ

ディレクトリ 説明
library 各種ライブラリ的モジュール
bus バス変換などのモジュール
math 算術計算関連
video ビデオ信号処理各種
image 画像処理各種
gpu Real-time GPU
peripheral マイコン周辺モジュール
primitive デバイスプリミティブなモジュール
misc その他コア
model シミュレーション用モデル
cpu CPUコア(MIPS-I互換) Real-time OS 対応
cache キャッシュメモリ
legacy 過去の遺物(新コアに移行前の旧RTL置き場)

project ディレクトリ

ディレクトリ 説明
ultra96v2_udmabuf_sample Ultra96V2 ボード用 udmabufサンプル
zybo_z7_udmabuf_sample ZYBO-Z7 ボード用 udmabufサンプル
zybo_z7_imx219 ZYBO-Z7 ボード用 IMX219サンプル
zybo_z7_imx219_hdmi ZYBO-Z7 ボード用 IMX219+HDMIサンプル
spartan3e_starter Spartan-3E Starter Kit 用プロジェクト
spartan3_starter Spartan-3 Starter Kit 用プロジェクト

その他未整備のプロジェクト各種

Real-time OS について

拙作の HOS-V4a にて、上記の MPIS互換コア、MicroBlaze、Cortex-R5 などに対応中です。

Real-time Neural Network について

微分可能回路記述に基づくLUT 直接学習による深層学習モデル(LUT-Network)用の学習環境として開発中のBinaryBrainもJellyの画像処理コンポーネントを用いてCNNを構成しており、そのまま当プラットフォームに組み込むことが可能です(NN部の入出力自体は AXI4-Stream なので汎用的です)。

メモリを介さずにリアルタイムに推論結果が出力可能であり、本プラットフォーム上で効果的に利用することが可能です。

Jellyを使ったシステムのデモ動画

DMA

jelly_buffer_manager

DMAなどに自動で割り当てるバッファを管理するコア

jelly_buffer_allocator

jelly_buffer_manager からソフトウェアがバッファ割り当てを受ける場合のインターフェースモジュール

jelly_dma_stream_write

概要

N次元構造の Stream から AXI4 メモリバスへとして書き込みを行う。 書き込み先のバッファ制御と、データの書き込み側とを独立性高く扱いつつ、メモリアクセス効率を保つことを目的に設計を行っている。

内部にFIFOバッファを有しており、バッファに準備できたサイズ分のみ一気に書き込みを行う為、利用側はバス効率を気にせずにゆっくりデータを書き込むことも可能である。

CPUからのレジスタ状態変化や割り込みは、内部FIFOの残量に無関係にAXI4バスへのメモリアクセスが完了した段階で発生するため、データ書き込み側とは独立して、書き込みバッファの確保と解放を効率的に実施可能である。

N次元構造を各次元の first と last で表す。特に last を利用して 不足データをパディングしたり、余分データをカットしたりできる。また DMA 非動作時に Streama の ready をアサートして、データをスキップする機能がある。

レジスタ仕様

アドレスはWISHBONEのワードアドレス。 レジスタ幅や初期値は parameter 指定で変更可能。

register name addr R/W size description
CORE_ID 0x00 RO 32 core ID
CORE_VERSION 0x01 RO 32 core verion
CORE_CONFIG 0x03 RO 32 サポート次元数(Nの値)
CTL_CONTROL 0x04 RW 4 bit[0]:有効化
bit[1]:パラメータ更新予約(自動クリア)
bit[2]:ワンショット転送
bit[3] 自動アドレス取得有効
CTL_STATUS 0x05 RO 1 動作中に1となる
CTL_INDEX 0x07 RO INDEX_WIDTH 新規パラメータ反映毎にインクリメント
IRQ_ENABLE 0x08 RW 1 1でIQR有効
IRQ_STATUS 0x09 RO 1 現在のIQR保留状態
IRQ_CLR 0x0a WO 1 1を書き込むと保留IRQクリア
IRQ_SET 0x0b WO 1 1を書き込むと保留IRQセット
PARAM_AWADDR 0x10 RW AXI4_ADDR_WIDTH 転送アドレス(非自動割り当て時)
PARAM_AWOFFSET 0x18 RW AXI4_ADDR_WIDTH 転送アドレスオフセット
PARAM_AWLEN_MAX 0x1c RW AXI4_LEN_WIDTH AXI4バスでの1回の最大転送サイズから1を引いたもの)
PARAM_AWLEN0 0x20 RW AWLEN0_WIDTH 0次元目の転送量からAWLEN_OFFSETを引いた値
PARAM_AWLEN1 0x24 RW AWLEN1_WIDTH 1次元目の転送長らAWLEN_OFFSETを引いた値
PARAM_AWSTEP1 0x25 RW AWSTEP1_WIDTH 1次元目の転送ステップ(バイト単位)
PARAM_AWLEN2 0x28 RW AWLEN2_WIDTH 2次元目の転送長らAWLEN_OFFSETを引いた値
PARAM_AWSTEP2 0x29 RW AWSTEP2_WIDTH 2次元目の転送ステップ(バイト単位)
PARAM_AWLEN3 0x2c RW AWLEN3_WIDTH 3次元目の転送長らAWLEN_OFFSETを引いた値
PARAM_AWSTEP3 0x2d RW AWSTEP3_WIDTH 3次元目の転送ステップ(バイト単位)
PARAM_AWLEN4 0x30 RW AWLEN4_WIDTH 4次元目の転送長らAWLEN_OFFSETを引いた値
PARAM_AWSTEP4 0x31 RW AWSTEP4_WIDTH 4次元目の転送ステップ(バイト単位)
PARAM_AWLEN5 0x34 RW AWLEN5_WIDTH 5次元目の転送長らAWLEN_OFFSETを引いた値
PARAM_AWSTEP5 0x35 RW AWSTEP5_WIDTH 5次元目の転送ステップ(バイト単位)
PARAM_AWLEN6 0x38 RW AWLEN6_WIDTH 6次元目の転送長らAWLEN_OFFSETを引いた値
PARAM_AWSTEP6 0x39 RW AWSTEP6_WIDTH 6次元目の転送ステップ(バイト単位)
PARAM_AWLEN7 0x3c RW AWLEN7_WIDTH 7次元目の転送長らAWLEN_OFFSETを引いた値
PARAM_AWSTEP7 0x3d RW AWSTEP7_WIDTH 7次元目の転送ステップ(バイト単位)
PARAM_AWLEN8 0x30 RW AWLEN8_WIDTH 8次元目の転送長らAWLEN_OFFSETを引いた値
PARAM_AWSTEP8 0x31 RW AWSTEP8_WIDTH 8次元目の転送ステップ(バイト単位)
PARAM_AWLEN9 0x44 RW AWLEN9_WIDTH 9次元目の転送長らAWLEN_OFFSETを引いた値
PARAM_AWSTEP9 0x45 RW AWSTEP9_WIDTH 9次元目の転送ステップ(バイト単位)
WSKIP_EN 0x70 RW 1 DMA停止時にStreamをスキップする
WDETECT_FIRST 0x72 RW N s_wfirstの検出するbitを1にする
WDETECT_LAST 0x73 RW N s_wlastの検出するbitを1にする
WPADDING_EN 0x74 RW 1 データ不足時にパディングを行う
WPADDING_DATA 0x75 RW WDATA_WIDTH パディング時のデータ
WPADDING_STRB 0x76 RW WSTRB_WIDTH パディング時のストローブ

動作説明

CTL_CONTROL の bit0 が1の時にN次元構造のデータの読出しを行い、各次元の先頭末尾で対応するbit位置のフラグを立てたデータを出力することが可能である。

CTL_CONTROL の bit2 に1を立てない限りは、繰り返し同じ動作を行う。CTL_CONTROL の bit2 に1を立てた場合は次回転送完了で、bit0は自動クリアされて停止する。

CTL_CONTROL の bit1 を立てると 1の時は繰り返しのタイミングでパラメータのみ動的に更新することが可能である。パラメータ更新と同時に CTL_CONTROL の bit1 は自動クリアされる。 内部的にシャドーレジスタを有しており、そちらにコピーされる為、動作中もパラメータレジスタは書き換えてかまわない。

割り込みは、1回の転送が終わる毎に発生する。パラメータの更新予約をしていた場合は、ここで更新が行われるため、さらに新しいバッファの割り当てなどをこのタイミングで行うことが可能である。

parameter 設定

デフォルト値から変更する必要のある可能性のあるものだけ記載する。

parameter name description
N 次元数 (1~10)
BYTE_WIDTH 1バイトのbit数
WB_ASYNC WISHBONEバスとAXIバスが非同期か
WB_ADR_WIDTH WISHBONEバスのアドレス幅(8以上)
WB_DAT_WIDTH WISHBONEバスのデータ幅
WB_SEL_WIDTH WISHBONEバスのバイト選択の幅
HAS_WFIRST s_wfirst信号を備える
HAS_WLAST s_wlast信号を備える
WASYNC WriteDataのストリームバスとAXIバスが非同期か
WDATA_WIDTH 書き込むストリームのデータ幅
WSTRB_WIDTH 書き込むストリームのストローブ幅
AXI4_ID_WIDTH AXI4のID幅
AXI4_ADDR_WIDTH AXI4のADDR幅
AXI4_DATA_SIZE AXI4のデータサイズをlog2で指定(0:8bit, 1:16bit, 2:32bit, ...)
AXI4_LEN_WIDTH AXI4の awlen の幅
AXI4_QOS_WIDTH AXI4の awqos の幅
AXI4_AWID AXI4の awid の値(固定値)
AXI4_AWLOCK AXI4の awlock の値(固定値)
AXI4_AWCACHE AXI4の awcach の値(固定値)
AXI4_AWPROT AXI4の awprot の値(固定値)
AXI4_AWQOS AXI4の awqos の値(固定値)
AXI4_AWREGION AXI4の awregion の値(固定値)
INDEX_WIDTH INDEXレジスタの幅
AWLEN_OFFSET 転送サイズのオフセット(1を指定すると転送サイズから1引いた値を設定)
AWLEN0_WIDTH 0次元目の転送量指定幅
AWLEN1_WIDTH 1次元目の転送量指定幅(N >=2 の時のみ)
AWLEN2_WIDTH 2次元目の転送量指定幅(N >=3 の時のみ)
AWLEN3_WIDTH 3次元目の転送量指定幅(N >=4 の時のみ)
AWLEN4_WIDTH 4次元目の転送量指定幅(N >=5 の時のみ)
AWLEN5_WIDTH 5次元目の転送量指定幅(N >=6 の時のみ)
AWLEN6_WIDTH 6次元目の転送量指定幅(N >=7 の時のみ)
AWLEN7_WIDTH 7次元目の転送量指定幅(N >=8 の時のみ)
AWLEN8_WIDTH 8次元目の転送量指定幅(N >=9 の時のみ)
AWLEN9_WIDTH 9次元目の転送量指定幅(N >=10 の時のみ)
ARSTEP1_WIDTH 1次元目の転送ステップ量指定幅(N >=2 の時のみ)
ARSTEP2_WIDTH 2次元目の転送ステップ量指定幅(N >=3 の時のみ)
ARSTEP3_WIDTH 3次元目の転送ステップ量指定幅(N >=4 の時のみ)
ARSTEP4_WIDTH 4次元目の転送ステップ量指定幅(N >=5 の時のみ)
ARSTEP5_WIDTH 5次元目の転送ステップ量指定幅(N >=6 の時のみ)
ARSTEP6_WIDTH 6次元目の転送ステップ量指定幅(N >=7 の時のみ)
ARSTEP7_WIDTH 7次元目の転送ステップ量指定幅(N >=8 の時のみ)
ARSTEP8_WIDTH 8次元目の転送ステップ量指定幅(N >=9 の時のみ)
ARSTEP9_WIDTH 9次元目の転送ステップ量指定幅(N >=10 の時のみ)
BYPASS_GATE 出力の整形ゲートをバイパス(アライメント無し/フラグ無し)
BYPASS_ALIGN AXI4の4kアライメント処理をバイパス
WDETECTOR_ENABLE wチャネルのフラグ検出を利用する(パディング時必須)
ALLOW_UNALIGNED バスサイズのアライメントに合わないアクセスを許す
CAPACITY_WIDTH 内部でキューイングする転送量のbit幅(一度にDAMに予約する転送サイズがAXI4バス側の転送量に換算して総和が保持できるbit幅)
WFIFO_PTR_WIDTH wチャネルのFIFOバッファのポインタ幅(サイズのlog2となる) FIFOサイズ以上の転送は出来ないので注意
WFIFO_RAM_TYPE wチャネルのFIFOバッファのタイプ。"block" で BRAM, "distributed" で分散RAMを利用する

ポート仕様

本モジュールのポートの各信号は以下の通り。

port name I/O size description
endian I 1 エンディアン(0:little, 1:big)
s_wb_rst_i I 1 WISHBONEバス リセット
s_wb_clk_i I 1 WISHBONEバス クロック
s_wb_adr_i I WB_ADR_WIDTH WISHBONEバス アドレス
s_wb_dat_i I WB_DAT_WIDTH WISHBONEバス 書き込みデータ
s_wb_dat_o O WB_DAT_WIDTH WISHBONEバス 読み出しデータ
s_wb_we_i I 1 WISHBONEバス 読み書き選択
s_wb_sel_i I WB_SEL_WIDTH WISHBONEバス バイトセレクト
s_wb_stb_i I 1 WISHBONEバス ストローブ
s_wb_ack_o O 1 WISHBONEバス アクノリッジ
out_irq O 1 IRQ信号(レベル割り込み)
buffer_request O 1 バッファ割り当て要求
buffer_release O 1 バッファ解放
buffer_addr I AXI4_ADDR_WIDTH バッファアドレス
s_wresetn I Write Stream バス リセット
s_wclk I Write Stream バス クロック
s_wdata I WDATA_WIDTH Write Stream バス データ
s_wstrb I WSTRB_WIDTH Write Stream バス ストローブ
s_wfirst I N Write Stream バス 各次元の先頭フラグ
s_wlast I N Write Stream バス 各次元の末尾フラグ
s_wvalid I Write Stream バス valid信号
s_wready O Write Stream バス ready信号
m_aresetn I AXI4 バス リセット(負論理)
m_aclk I AXI4 バス クロック
m_axi4_awid I AXI4_ID_WIDTH AXI4 バス awid 信号
m_axi4_awaddr I AXI4_ADDR_WIDTH AXI4 バス awaddr 信号
m_axi4_awlen I AXI4_LEN_WIDTH AXI4 バス awlen 信号
m_axi4_awsize I 3 AXI4 バス awsize 信号
m_axi4_awburst I 2 AXI4 バス awburst 信号
m_axi4_awlock I 1 AXI4 バス awlock 信号
m_axi4_awcache I 4 AXI4 バス awcache 信号
m_axi4_awprot I 2 AXI4 バス awprot 信号
m_axi4_awqos I AXI4_QOS_WIDTH AXI4 バス awqos 信号
m_axi4_awregion I 4 AXI4 バス awregion 信号
m_axi4_awvalid I 1 AXI4 バス awvalid 信号
m_axi4_awready O 1 AXI4 バス awready 信号
m_axi4_wdata I AXI4_DATA_WIDTH AXI4 バス wdata 信号
m_axi4_wstrb I AXI4_STRB_WIDTH AXI4 バス wstrb 信号
m_axi4_wlast I 1 AXI4 バス wlast 信号
m_axi4_wvalid I 1 AXI4 バス wvalid 信号
m_axi4_wready O 1 AXI4 バス wready 信号
m_axi4_bid O AXI4_ID_WIDTH AXI4 バス bid 信号
m_axi4_bresp O 2 AXI4 バス bresp 信号
m_axi4_bvalid O 1 AXI4 バス bvalid 信号
m_axi4_bready I 1 AXI4 バス bready 信号

endian は 動的に変更することは想定していないので注意。バス幅変換が作用した場合に動作が変わる。

jelly_dma_stream_read

概要

(まだデバッグ中、writeもセットで開発中)

AXI4 メモリバスからN次元読み出して Stream を出力する。 読出し先のバッファ制御と、読出しデータの利用側とを独立性高く扱いつつ、メモリアクセス効率を保つことを目的に設計を行っている。

内部にFIFOバッファを有しており、バッファ溢れしない分量のみを読み出し管理する為、利用側はデータ利用に先立って起動しておけば、後は読み出し制御とは独立してデータを取り出して利用するのみでよい。

CPUからのレジスタ状態変化や割り込みは、内部FIFOの残量に無関係にAXI4バスへのメモリアクセスが完了した段階で発生するため、データ読出し側とは独立して、読み出しバッファの解放と、次の読出しバッファのアロケートを効率的に先行実施可能である。 (データの完了を知りたい場合は、データを利用する側のコアから完了割り込みを受けるべきである)。

レジスタ仕様

アドレスはWISHBONEのワードアドレス。 レジスタ幅や初期値は parameter 指定で変更可能。

register name addr R/W size description
CORE_ID 0x00 RO 32 core ID
CORE_VERSION 0x01 RO 32 core verion
CORE_CONFIG 0x03 RO 32 サポート次元数(Nの値)
CTL_CONTROL 0x04 RW 4 bit[0]:有効化
bit[1]:パラメータ更新予約(自動クリア)
bit[2]:ワンショット転送
bit[3] 自動アドレス取得有効
CTL_STATUS 0x05 RO 1 動作中に1となる
CTL_INDEX 0x07 RO INDEX_WIDTH 新規パラメータ反映毎にインクリメント
IRQ_ENABLE 0x08 RW 1 1でIQR有効
IRQ_STATUS 0x09 RO 1 現在のIQR保留状態
IRQ_CLR 0x0a WO 1 1を書き込むと保留IRQクリア
IRQ_SET 0x0b WO 1 1を書き込むと保留IRQセット
PARAM_ARADDR 0x10 RW AXI4_ADDR_WIDTH 転送アドレス(非自動割り当て時)
PARAM_AROFFSET 0x18 RW AXI4_ADDR_WIDTH 転送アドレスオフセット
PARAM_ARLEN_MAX 0x1c RW AXI4_LEN_WIDTH AXI4バスでの1回の最大転送サイズから1を引いたもの)
PARAM_ARLEN0 0x20 RW ARLEN0_WIDTH 0次元目の転送量からARLEN_OFFSETを引いた値
PARAM_ARLEN1 0x24 RW ARLEN1_WIDTH 1次元目の転送長らARLEN_OFFSETを引いた値
PARAM_ARSTEP1 0x25 RW ARSTEP1_WIDTH 1次元目の転送ステップ(バイト単位)
PARAM_ARLEN2 0x28 RW ARLEN2_WIDTH 2次元目の転送長らARLEN_OFFSETを引いた値
PARAM_ARSTEP2 0x29 RW ARSTEP2_WIDTH 2次元目の転送ステップ(バイト単位)
PARAM_ARLEN3 0x2c RW ARLEN3_WIDTH 3次元目の転送長らARLEN_OFFSETを引いた値
PARAM_ARSTEP3 0x2d RW ARSTEP3_WIDTH 3次元目の転送ステップ(バイト単位)
PARAM_ARLEN4 0x30 RW ARLEN4_WIDTH 4次元目の転送長らARLEN_OFFSETを引いた値
PARAM_ARSTEP4 0x31 RW ARSTEP4_WIDTH 4次元目の転送ステップ(バイト単位)
PARAM_ARLEN5 0x34 RW ARLEN5_WIDTH 5次元目の転送長らARLEN_OFFSETを引いた値
PARAM_ARSTEP5 0x35 RW ARSTEP5_WIDTH 5次元目の転送ステップ(バイト単位)
PARAM_ARLEN6 0x38 RW ARLEN6_WIDTH 6次元目の転送長らARLEN_OFFSETを引いた値
PARAM_ARSTEP6 0x39 RW ARSTEP6_WIDTH 6次元目の転送ステップ(バイト単位)
PARAM_ARLEN7 0x3c RW ARLEN7_WIDTH 7次元目の転送長らARLEN_OFFSETを引いた値
PARAM_ARSTEP7 0x3d RW ARSTEP7_WIDTH 7次元目の転送ステップ(バイト単位)
PARAM_ARLEN8 0x30 RW ARLEN8_WIDTH 8次元目の転送長らARLEN_OFFSETを引いた値
PARAM_ARSTEP8 0x31 RW ARSTEP8_WIDTH 8次元目の転送ステップ(バイト単位)
PARAM_ARLEN9 0x44 RW ARLEN9_WIDTH 9次元目の転送長らARLEN_OFFSETを引いた値
PARAM_ARSTEP9 0x45 RW ARSTEP9_WIDTH 9次元目の転送ステップ(バイト単位)

動作説明

CTL_CONTROL の bit0 が1の時にN次元構造のデータの読出しを行い、各次元の先頭末尾で対応するbit位置のフラグを立てたデータを出力することが可能である。

CTL_CONTROL の bit2 に1を立てない限りは、繰り返し同じ動作を行う。CTL_CONTROL の bit2 に1を立てた場合は次回転送完了で、bit0は自動クリアされて停止する。

CTL_CONTROL の bit1 を立てると 1の時は繰り返しのタイミングでパラメータのみ動的に更新することが可能である。パラメータ更新と同時に CTL_CONTROL の bit1 は自動クリアされる。 内部的にシャドーレジスタを有しており、そちらにコピーされる為、動作中もパラメータレジスタは書き換えてかまわない。

割り込みは、1回の転送が終わる毎に発生する。パラメータの更新予約をしていた場合は、ここで更新が行われるため、さらに新しいバッファの割り当てなどをこのタイミングで行うことが可能である。

parameter 設定

デフォルト値から変更する必要のある可能性のあるものだけ記載する。

parameter name description
N 次元数 (1~10)
WB_ASYNC WISHBONEバスとAXIバスが非同期か
RASYNC ReadDataのストリームバスとAXIバスが非同期か
BYTE_WIDTH 1バイトのbit数
BYPASS_GATE 出力の整形ゲートをバイパス(アライメント無し/フラグ無し)
BYPASS_ALIGN AXI4の4kアライメント処理をバイパス
ALLOW_UNALIGNED バスサイズのアライメントに合わないアクセスを許す
HAS_RFIRST s_rfirst信号を備える
HAS_RLAST s_rlast信号を備える
AXI4_ID_WIDTH AXI4のID幅
AXI4_ADDR_WIDTH AXI4のADDR幅
AXI4_DATA_SIZE AXI4のデータサイズをlog2で指定(0:8bit, 1:16bit, 2:32bit, ...)
AXI4_LEN_WIDTH AXI4の arlen の幅
AXI4_QOS_WIDTH AXI4の arqos の幅
AXI4_ARID AXI4の arid の値(固定値)
AXI4_ARLOCK AXI4の arlock の値(固定値)
AXI4_ARCACHE AXI4の arcach の値(固定値)
AXI4_ARPROT AXI4の arprot の値(固定値)
AXI4_ARQOS AXI4の arqos の値(固定値)
AXI4_ARREGION AXI4の arregion の値(固定値)
S_RDATA_WIDTH 読み出したストリームのデータ幅
CAPACITY_WIDTH 内部でキューイングする転送量のbit幅(一度にDAMに予約する転送サイズがAXI4バス側の転送量に換算して総和が保持できるbit幅)
ARLEN_OFFSET 転送サイズのオフセット(1を指定すると転送サイズから1引いた値を設定)
WB_ADR_WIDTH WISHBONEバスのアドレス幅(8以上)
WB_DAT_WIDTH WISHBONEバスのデータ幅
WB_SEL_WIDTH WISHBONEバスのバイト選択の幅
INDEX_WIDTH INDEXレジスタの幅
ARLEN0_WIDTH 0次元目の転送量指定幅
ARLEN1_WIDTH 1次元目の転送量指定幅(N >=2 の時のみ)
ARLEN2_WIDTH 2次元目の転送量指定幅(N >=3 の時のみ)
ARLEN3_WIDTH 3次元目の転送量指定幅(N >=4 の時のみ)
ARLEN4_WIDTH 4次元目の転送量指定幅(N >=5 の時のみ)
ARLEN5_WIDTH 5次元目の転送量指定幅(N >=6 の時のみ)
ARLEN6_WIDTH 6次元目の転送量指定幅(N >=7 の時のみ)
ARLEN7_WIDTH 7次元目の転送量指定幅(N >=8 の時のみ)
ARLEN8_WIDTH 8次元目の転送量指定幅(N >=9 の時のみ)
ARLEN9_WIDTH 9次元目の転送量指定幅(N >=10 の時のみ)
ARSTEP1_WIDTH 1次元目の転送ステップ量指定幅(N >=2 の時のみ)
ARSTEP2_WIDTH 2次元目の転送ステップ量指定幅(N >=3 の時のみ)
ARSTEP3_WIDTH 3次元目の転送ステップ量指定幅(N >=4 の時のみ)
ARSTEP4_WIDTH 4次元目の転送ステップ量指定幅(N >=5 の時のみ)
ARSTEP5_WIDTH 5次元目の転送ステップ量指定幅(N >=6 の時のみ)
ARSTEP6_WIDTH 6次元目の転送ステップ量指定幅(N >=7 の時のみ)
ARSTEP7_WIDTH 7次元目の転送ステップ量指定幅(N >=8 の時のみ)
ARSTEP8_WIDTH 8次元目の転送ステップ量指定幅(N >=9 の時のみ)
ARSTEP9_WIDTH 9次元目の転送ステップ量指定幅(N >=10 の時のみ)
RFIFO_PTR_WIDTH rチャネルのFIFOバッファのポインタ幅(サイズのlog2となる) FIFOサイズ以上の転送は出来ないので注意
RFIFO_RAM_TYPE rチャネルのFIFOバッファのタイプ。"block" で BRAM, "distributed" で分散RAMを利用する

ポート仕様

本モジュールのポートの各信号は以下の通り。

port name I/O size description
endian I 1 エンディアン(0:little, 1:big)
s_wb_rst_i I 1 WISHBONEバス リセット
s_wb_clk_i I 1 WISHBONEバス クロック
s_wb_adr_i I WB_ADR_WIDTH WISHBONEバス アドレス
s_wb_dat_i I WB_DAT_WIDTH WISHBONEバス 書き込みデータ
s_wb_dat_o O WB_DAT_WIDTH WISHBONEバス 読み出しデータ
s_wb_we_i I 1 WISHBONEバス 読み書き選択
s_wb_sel_i I WB_SEL_WIDTH WISHBONEバス バイトセレクト
s_wb_stb_i I 1 WISHBONEバス ストローブ
s_wb_ack_o O 1 WISHBONEバス アクノリッジ
out_irq O 1 IRQ信号(レベル割り込み)
buffer_request O 1 バッファ割り当て要求
buffer_release O 1 バッファ解放
buffer_addr I AXI4_ADDR_WIDTH バッファアドレス
s_rresetn I Read Stream バス リセット
s_rclk I Read Stream バス クロック
s_rdata O S_RDATA_WIDTH Read Stream バス データ
s_rfirst O N Read Stream バス 各次元の先頭フラグ
s_rlast O N Read Stream バス 各次元の末尾フラグ
s_rvalid O Read Stream バス valid信号
s_rready I Read Stream バス ready信号
m_aresetn I AXI4 バス リセット(負論理)
m_aclk I AXI4 バス クロック
m_axi4_arid O AXI4_ID_WIDTH AXI4 バス arid 信号
m_axi4_araddr O AXI4_ADDR_WIDTH AXI4 バス araddr 信号
m_axi4_arlen O AXI4_LEN_WIDTH AXI4 バス arlen 信号
m_axi4_arsize O 3 AXI4 バス arsize 信号
m_axi4_arburst O 2 AXI4 バス arburst 信号
m_axi4_arlock O 1 AXI4 バス arlock 信号
m_axi4_arcache O 4 AXI4 バス arcache 信号
m_axi4_arprot O 2 AXI4 バス arprot 信号
m_axi4_arqos O AXI4_QOS_WIDTH AXI4 バス arqos 信号
m_axi4_arregion O 4 AXI4 バス arregion 信号
m_axi4_arvalid O 1 AXI4 バス arvalid 信号
m_axi4_arready I 1 AXI4 バス arready 信号
m_axi4_rid I AXI4_ID_WIDTH AXI4 バス rid 信号
m_axi4_rdata I AXI4_DATA_WIDTH AXI4 バス rdata 信号
m_axi4_rresp I 2 AXI4 バス rresp 信号
m_axi4_rlast I AXI4 バス rlast 信号
m_axi4_rvalid I AXI4 バス rvalid 信号
m_axi4_rready O AXI4 バス rready 信号

endian は 動的に変更することは想定していないので注意。バス幅変換が作用した場合に動作が変わる。

jelly_dma_fifo

外部メモリを利用した大サイズのFIFOを構成する

レジスタ仕様

アドレスはWISHBONEのワードアドレス。 レジスタ幅や初期値は parameter 指定で変更可能。

register name addr R/W size description
CORE_ID 0x00 RO 32 core ID
CORE_VERSION 0x01 RO 32 core verion
CTL_CONTROL 0x04 RW 2 bit[0]:有効化
bit[1]:パラメータ更新予約(自動クリア)
CTL_STATUS 0x05 RO 1 動作中に1
CTL_INDEX 0x06 RO INDEX_WIDTH 新規パラメータ反映毎にインクリメント
PARAM_ADDR 0x08 RW PARAM_ADDR_WIDTH 割り当てメモリの先頭アドレス
PARAM_SIZE 0x09 RW PARAM_SIZE_WIDTH 割り当てメモリのサイズ
PARAM_AWLEN 0x10 RW PARAM_AWLEN_WIDTH 書き込み側の最大awlen
PARAM_WSTRB 0x11 RW PARAM_WSTRB_WIDTH 書き込み側のストローブ
PARAM_WTIMEOUT 0x13 RW PARAM_WTIMEOUT_WIDTH 書き込み側のタイムアウト時間
PARAM_ARLEN 0x14 RW PARAM_ARLEN_WIDTH 書き込み側の最大arlen
PARAM_RTIMEOUT 0x17 RW PARAM_RTIMEOUT_WIDTH 読み込み側のタイムアウト時間

基本的にメモリを割り当ててしまえば、ストリームデータに対して巨大なFIFOとしてふるまうモジュールである。 ただし、メモリバス幅がストリームバス幅より大きい場合、バス幅分のデータにならないと反対側のポートに転送されないので注意が必要である。

メモリ読み書きの両端でコア内にも小さなFIFOを持っており、データの揃った分しか書き込みコマンドを出さないし、FIFOの空き分しか読出しコマンドを出さないので、ストリーム側は特にメモリの事を気にせずにBRAMで構成したFIFOと似たように利用可能である。

レジスタにはタイムアウトレジスタを用意しており、データや空きが awlen/wrlen のサイズ揃わなくてもタイムアウトすれば転送を行う。タイムアウトしない範囲でなるべくデータを溜めてからバースト転送を行う事でメモリアクセス効率が向上する。

jelly_dma_video_write

AXI4 Stream Video 書き込み用のDMA jelly_dma_stream_write の N=3 のラッパーとして実装されている

レジスタ仕様

アドレスはWISHBONEのワードアドレス。 レジスタ幅や初期値は parameter 指定で変更可能。

register name addr R/W size description
CORE_ID 0x00 RO 32 core ID
CORE_VERSION 0x01 RO 32 core verion
CORE_CONFIG 0x03 RO 32 サポート次元数(Nの値)
CTL_CONTROL 0x04 RW 4 bit[0]:有効化
bit[1]:パラメータ更新予約(自動クリア)
bit[2]:ワンショット転送
bit[3] 自動アドレス取得有効
CTL_STATUS 0x05 RO 1 動作中に1となる
CTL_INDEX 0x07 RO INDEX_WIDTH 新規パラメータ反映毎にインクリメント
IRQ_ENABLE 0x08 RW 1 1でIQR有効
IRQ_STATUS 0x09 RO 1 現在のIQR保留状態
IRQ_CLR 0x0a WO 1 1を書き込むと保留IRQクリア
IRQ_SET 0x0b WO 1 1を書き込むと保留IRQセット
PARAM_ADDR 0x10 RW AXI4_ADDR_WIDTH 転送アドレス(非自動割り当て時)
PARAM_OFFSET 0x18 RW AXI4_ADDR_WIDTH 転送アドレスオフセット
PARAM_AWLEN_MAX 0x1c RW AXI4_LEN_WIDTH AXI4バスでの1回の最大転送サイズから1を引いたもの)
PARAM_H_SIZE 0x20 RW H_SIZE_WIDTH 水平サイズからSIZE_OFFSETを引いた値
PARAM_V_SIZE 0x24 RW V_SIZE_WIDTH 垂直サイズからSIZE_OFFSETを引いた値
PARAM_LINE_STEP 0x25 RW AXI4_ADDR_WIDTH ライン単位の転送ステップ(バイト単位)
PARAM_F_SIZE 0x28 RW F_SIZE_WIDTH 複数フレーム記録する倍のフレーム数からSIZE_OFFSETを引いた値
PARAM_FRAME_STEP 0x29 RW AXI4_ADDR_WIDTH フレーム単位の転送ステップ(バイト単位)
SKIP_EN 0x70 RW 1 DMA停止時にStreamをスキップする
DETECT_FIRST 0x72 RW 3 転送開始にtuserの検出する場合はbit[1]を1にする
DETECT_LAST 0x73 RW 3 パディングの為にtlastの検出する場合はbit[0]を1にする
PADDING_EN 0x74 RW 1 データ不足時にパディングを行う
PADDING_DATA 0x75 RW WDATA_WIDTH パディング時のデータ
PADDING_STRB 0x76 RW WSTRB_WIDTH パディング時のストローブ

jelly_dma_video_read

AXI4 Stream Video 読み出し用のDMA

register name addr R/W size description
CORE_ID 0x00 RO 32 core ID
CORE_VERSION 0x01 RO 32 core verion
CORE_CONFIG 0x03 RO 32 サポート次元数(Nの値)
CTL_CONTROL 0x04 RW 4 bit[0]:有効化
bit[1]:パラメータ更新予約(自動クリア)
bit[2]:ワンショット転送
bit[3] 自動アドレス取得有効
CTL_STATUS 0x05 RO 1 動作中に1となる
CTL_INDEX 0x07 RO INDEX_WIDTH 新規パラメータ反映毎にインクリメント
IRQ_ENABLE 0x08 RW 1 1でIQR有効
IRQ_STATUS 0x09 RO 1 現在のIQR保留状態
IRQ_CLR 0x0a WO 1 1を書き込むと保留IRQクリア
IRQ_SET 0x0b WO 1 1を書き込むと保留IRQセット
PARAM_ADDR 0x10 RW AXI4_ADDR_WIDTH 転送アドレス(非自動割り当て時)
PARAM_OFFSET 0x18 RW AXI4_ADDR_WIDTH 転送アドレスオフセット
PARAM_ARLEN_MAX 0x1c RW AXI4_LEN_WIDTH AXI4バスでの1回の最大転送サイズから1を引いたもの)
PARAM_H_SIZE 0x20 RW H_SIZE_WIDTH 水平サイズからSIZE_OFFSETを引いた値
PARAM_V_SIZE 0x24 RW V_SIZE_WIDTH 垂直サイズからSIZE_OFFSETを引いた値
PARAM_LINE_STEP 0x25 RW AXI4_ADDR_WIDTH ライン単位の転送ステップ(バイト単位)
PARAM_F_SIZE 0x28 RW F_SIZE_WIDTH 複数フレーム記録する倍のフレーム数からSIZE_OFFSETを引いた値
PARAM_FRAME_STEP 0x29 RW AXI4_ADDR_WIDTH フレーム単位の転送ステップ(バイト単位)

Video 関連

/rtl/video 以下にあるモジュール

jelly_video_parameter_update

概要

frame start を検出してパラメータ更新信号を出す

レジスタ仕様

アドレスはWISHBONEのワードアドレス。 レジスタ幅や初期値は parameter 指定で変更可能。

register name addr R/W size description
CORE_ID 0x00 RO 32 core ID
CORE_VERSION 0x01 RO 32 core verion
CONTROL 0x04 RW 2 bit[0]:更新予約
bit[1]:更新継続
INDEX 0x05 RO -- パラメータ受付毎にインクリメント
FRAME_COUNT 0x06 RO -- フレーム数カウント

動作説明

各画像処理コアで処理途中にパラメータが変化すると不整合を起こすケースで次フレームを待ってパラメータ更新する機能があるものがあるが、コア内の整合性しか取れない。 本コアは、さらに画像処理コア間で不整合を起こさないために、後続コアに一斉に更新許可を出すのに用いる。

jelly_video_format_regularizer

概要

AXI4-Stream Video を指定フォーマットに正規化する

レジスタ仕様

アドレスはWISHBONEのワードアドレス。 レジスタ幅や初期値は parameter 指定で変更可能。

register name addr R/W size description
CORE_ID 0x00 RO 32 core ID
CORE_VERSION 0x01 RO 32 core verion
CTL_CONTROL 0x04 RW 2 bit[0]:有効化
bit[1]:パラメータ更新予約(自動クリア)
CTL_STATUS 0x05 RO 1 DMA動作中に1になる
CTL_INDEX 0x07 RO -- パラメータ受付毎にインクリメント
CTL_SKIP 0x08 RW 1 停止時に入力を堰き止めずに捨てる
CTL_FRM_TIMER_EN 0x0a RW 1 フレームタイマー有効
CTL_FRM_TIMEOUT 0x0b RW -- タイマ有効時に指定時間フレームが来なければタイムアウトして疑似フレームを生成
PARAM_WIDTH 0x10 RW -- 画像幅
PARAM_HEIGHT 0x11 RW -- 画像高さ
PARAM_FILL 0x12 RW -- パディング時の画素値
PARAM_TIMEOUT 0x13 RW -- フレーム転送中のデータが指定時間途切れるとタイムアウト

動作説明

主に画像入力デバイスの突然の切断やデータ欠け、フォーマット不一致などにより後段のDMAの転送データ数が合わずにデッドロックをおこすなどを防止する目的のものである。

jelly_vin_axi4s

ビデオ入力を AXI4 Stream video に変換

jelly_vout_axi4s

AXI4 Stream video をビデオ出力に変換

jelly_vsync_generator

ビデオ出力用の同期信号生成

jelly_dvi_tx

DVI出力コア

jelly_mipi_csi2_rx

MIPI-CSI2 の受信コア

jelly_hdmi_rx

HDMI 受信コア

jelly_vdma_axi4s_to_axi4

Video write DMA(AXI4-Stream to AXI4)

概要

AXI4-Stream Video を AXI4 メモリバスに書き込み転送を行う

レジスタ仕様

アドレスはWISHBONEのワードアドレス。 レジスタ幅や初期値は parameter 指定で変更可能。

register name addr R/W size description
CORE_ID 0x00 RO 32 core ID
CORE_VERSION 0x01 RO 32 core verion
CTL_CONTROL 0x04 RW 3 bit[0]:有効化
bit[1]:パラメータ更新予約(自動クリア)
bit[2]:ワンショット転送
CTL_STATUS 0x05 RO 1 DMA動作中に1になる
PARAM_ADDR 0x08 RW -- 書き込みアドレス
PARAM_STRIDE 0x09 RW -- 1ラインのストライド(バイト単位)
PARAM_WIDTH 0x0a RW -- 画像幅(ピクセル単位)
PARAM_HEIGHT 0x0b RW -- 画像高さ(ピクセル単位)
PARAM_SIZE 0x0c RW -- 転送ピクセルサイズ(ピクセル単位)
PARAM_AWLEN 0x0f RW 8 1回の最大バースト転送サイズ-1(バス幅単位)

動作説明

CTL_CONTROL の bit0 が1の時に画像データが来ると転送を行う。CTL_CONTROL の bit2 が1の場合は、PARAM_SIZE 分転送すると停止する(bit0は自動クリア)。 そうでない場合は画像が来るたびに繰り返し転送を行う。 CTL_CONTROL の bit1 が1の時は転送開始や繰り返しのタイミングでパラメータが更新される。

PARAM_SIZE は PARAM_WIDTH×PARAM_HEIGHT の倍数である必要があるが、設定次第で複数フレームの一括記録が可能である。

jelly_vdma_axi4_to_axi4s

Video read DMA(AXI4 to AXI4-Stream)

概要

AXI4 メモリバスから読み出して AXI4-Stream Video を出力

レジスタ仕様

アドレスはWISHBONEのワードアドレス。 レジスタ幅や初期値は parameter 指定で変更可能。

register name addr R/W size description
CORE_ID 0x00 RO 32 core ID
CORE_VERSION 0x01 RO 32 core verion
CTL_CONTROL 0x04 RW 3 bit[0]:有効化
bit[1]:パラメータ更新予約(自動クリア)
bit[2]:ワンショット転送
CTL_STATUS 0x05 RO 1 DMA動作中に1になる
PARAM_ADDR 0x08 RW -- 読み出しアドレス
PARAM_STRIDE 0x09 RW -- 1ラインのストライド(バイト単位)
PARAM_WIDTH 0x0a RW -- 画像幅(ピクセル単位)
PARAM_HEIGHT 0x0b RW -- 画像高さ(ピクセル単位)
PARAM_SIZE 0x0c RW -- 転送ピクセルサイズ(ピクセル単位)
PARAM_AWLEN 0x0f RW 8 1回の最大バースト転送サイズ-1(バス幅単位)

動作説明

CTL_CONTROL の bit0 が1の時に画像データの読出しを行う。CTL_CONTROL の bit2 が1の場合は、PARAM_SIZE分転送すると停止する(bit0は自動クリア)。 そうでない場合は画像が来るたびに繰り返し転送を行う。 CTL_CONTROL の bit1 が1の時は転送開始や繰り返しのタイミングでパラメータが更新される。

PARAM_SIZE は PARAM_WIDTH×PARAM_HEIGHT のサイズである必要がある。

画像処理関連

img バス仕様

画像処理において、AXI4 Stream バスの信号をさらに簡易に扱う為に、Jellyでは imgバスという独自仕様に変換して処理している。

imgバスの主な信号は以下の通りであり、必要に応じて個別画像処理に付随する信号を追加する。

signal name description
reset リセット信号
clk クロック
cke クロックイネーブル。ピクセル入力が無い時は落とす
line_first 先頭ラインを示す
line_last 最終ラインを示す
pixel_first ライン内で先頭ピクセルを示す
pixel_last ライン内で最終ピクセルを示す
de 有効ピクセルを示す
user ユーザーデータ
data 画像データ
valid valid の立たないデータは他のすべての信号は無効とする

img バスは有効ピクセルが無い場合に cke(クロックイネーブル)をネゲートするのが特徴である。

したがって、cke の有効な期間のみを処理すれば、データはすべて連続であり、パイプラインステージにおいてステージ前後のデータが左右のピクセルに必ず対応することが保証できる。

また、画像処理においてしばし重要になるボーダー処理において、画像ボーダーを示す4辺のフラグを用意することでこの処理を簡易化している。

一方で有効ピクセルを示す de 信号も備えている。基本的には無効ピクセルはimgバスに変換する段で cke が下げられるが、3x3などのブロック処理を行う場合は最終ラインの掃き出しが必要であるため、deの下がった無効ラインの入力をオプションとして備えている。 また、画像処理の出力過程においては、不要ピクセルのdeを下げることで画像縮小などの処理が可能となる。

これらにより多くの制御信号を有しているが、これらをすべて必須とするとリセットの接続先が増える課題がある。そこでvalid信号をオプショナルとして備えており、valid の立たないデータは他のすべての信号は無効とすることで、リセット信号の接続を valid にかかわる信号だけにすることも可能としている。

jelly_axi4s_to_img

AXI4 Stream を img バスに変換し、画像処理後に再び AXI4 Stream に戻すコア。

jelly_img_blk_buffer

画像を N×M のブロックに変換して画像処理をアシストするコア。 ラインバッファとピクセルバッファを備え、ブロック処理に必要な単位で出力する。 M-1 ライン分の遅延が発生する。

その際、ボーダー処理として NONE, CONSTANT, REPLICATE, REFLECT, REFLECT_101 などの処理が選択可能であり、OpenCV のそれとほぼ一致する。

jelly_img_demosaic_acpi

ACPI法によるデモザイク

jelly_img_color_matrix

カラーマトリックス処理

jelly_img_gaussian_3x3

3x3 限定のガウシアンフィルタ

jelly_img_sobel_core

Sobel フィルタコア 固定値での演算なのでホストから設定するレジスタはない。

jelly_img_binarizer

2値化コア

jelly_img_selector

画像セレクタ。 主にデバッグ時に中間データを切り替えて出力するなどで利用可能

jelly_img_previous_frame

1つ前のフレームを外部メモリに保存して利用するためのDMAモジュール

jelly_img_dnn_maxpol

DNN用の MaxPooling 層。

縮小を行い de の立たないデータを出力するため、この後にさらに画像処理を行うには一度 AXI4 Stream に戻す必要がある。

Library 関連

概要

/rtl/library 以下に、よく使うライブラリ的なモジュール群を集めている。

なるべく下記の再整理しようとしているが、現状まだ古いものも混在している。

各種ライブラリ

jelly_ram_XXX 系

内蔵メモリ関連のライブラリ群

jelly_fifo_XXX 系

FIFOを構成するライブラリ群

jelly_data_XXX 系

つながりを持たない単発のデータに対して処理を行うライブラリ群

基本的に AXIバス方式の valid/ready 方式でハンドシェークする

jelly_stream_XXX 系

last フラグなどで区切られる一連のストリームデータに対して処理を行うライブラリ群

便宜上ストリーム先頭を表す first を付けられるものもある。 基本的に AXIバス方式の valid/ready 方式でハンドシェークする

jelly_address_XXX 系

各種アドレッシングの為のインデックス生成ロジック

jelly_capacity_XXX 系

各種容量管理カウンタ

jelly_func_XXX 系

組み合わせ回路による各種ファンクション提供

その他

その他いろいろ

CPU (MIPS-I compatible)

概要

Jelly とは、FPGA向けの MIPS-I ライクな命令セットのコアを有したソフトコア プロセッシングシステムです。

CPUコアの概要

Jelly の備える CPU コアは命令セットとしては、 MIPS-I ライクな命令セットを 備えており、gcc などによる開発が可能です。 ただし、lwl, lwr, swl, swr 命令は備えていないので注意が必要です。 割込みなどの命令セット以外の機能は基本的に独自仕様なのであくまで コンパイラが流用できるという以外はMIPSシステムと互換性はありません。

jelly_cpu_top モジュール

パラメータ

    CPU_USE_DBUGGER
      デバッガを有効にするかどうかを指定します。
      0: 無効  1:有効 (デフォルト)

    CPU_USE_EXC_SYSCALL
      syscall 命令を有効にするかどうかを指定します。
      0: 無効  1:有効 (デフォルト)

    CPU_USE_EXC_BREAK
      break 命令を有効にするかどうかを指定します。
      0: 無効  1:有効 (デフォルト)

    CPU_USE_EXC_RI
      予約命令例外(Reserve Instruction)を発生させるかどうかを指定します。
      0: 無効  1:有効 (デフォルト)

    CPU_USE_HW_BP
      ハードウェアブレークを利用するかどうかを指定します。
      0: 無効  1:有効 (デフォルト)

    CPU_GPR_TYPE
      汎用レジスタの実装タイプを指定します。
       0: デュアルポートRAMを倍速クロックで利用 (デフォルト)
       1: デュアルポートRAMを2個利用
       2: フリップフロップ記述(合成依存)

    CPU_MUL_CYCLE
       乗算命令のパイプライン段数を指定します。
       デフォルトは0です。
       数を増やすと実行効率は落ちますが高周波でのタイミング制約が
     満たしやすくなります。
       33以上に指定すると加算器の繰り返しに切り替わり、ハードウェア乗算器
     資源が節約できます。

    CPU_DBBP_NUM
      ハードウェアブレークポイントの個数を1〜4で指定します。
      デフォルトは 4 です。


    TCM_ENABLE           = 0,
      密結合メモリ(TCM:Tightly Coupled Memory)を有効/無効を指定します。
      0: 無効(デフォルト)  1:有効 

    TCM_ADDR_WIDTH
      TCMを有効にする場合、TCMの32bitでのメモリビット幅を指定します。
      デフォルトは8で、32bit で 2^8 = 256 word (1024 byte) です。

    TCM_MEM_SIZE
      TCMを有効にする場合、TCMの32bitでのメモリサイズを指定します。
      デフォルトで (1 << TCM_ADDR_WIDTH) となります。

    TCM_READMEMH
      TCMを有効にする場合、初期値の読み込みを $memreadh 命令で行うか
      どうかを指定します。
      0: 無効(デフォルト)  1:有効 
      Xilinx のISE付属のXSTで合成する場合、$memreadh でメモリの初期化が可能です。

    TCM_READMEM_FIlE
      TCMを有効にする場合、$memreadh 命令読み込むファイルを指定します。
      32bitワードで16進数のファイルをメモリサイズ分準備してください。

	CACHE_ENABLE
      キャッシュメモリを有効にするかどうかを指定します。
      0: 無効(デフォルト)  1:有効 

    CACHE_LINE_SIZE
      キャッシュ1ラインのワード数を2のべき乗で指定します。
      0:1words, 1:2words, 2:4words, ... というように指定します。
      デフォルトは 1 で、2^1 = 2 word です。
      キャッシュミス時、1ライン分のデータが読み込まれます。

    CACHE_ARRAY_SIZE
      キャッシュアレイのサイズを2のべき乗で指定します。
      1:2lines, 2:4lines, 3:8lines, ... というように指定します。
      CACHE_LINE_SIZEとこの値でキャッシュの総サイズが決定されます。


    CACHE_BRIDGE
       キャッシュ対象ポートのI/Fにブリッジ回路を挿入するかどうかを
     指定します。
      0: 無効(デフォルト)  1:有効 
       ブリッジを挟むとアクセスサイクルが1サイクル伸びますが、
      高周波でのタイミング制約が満たしやすくなります。

    THROUGH_BRIDGE
       非キャッシュ対象ポートのI/Fにブリッジ回路を挿入するかどうかを
     指定します。
      0: 無効(デフォルト)  1:有効 
       ブリッジを挟むとアクセスサイクルが1サイクル伸びますが、
      高周波でのタイミング制約が満たしやすくなります。


    WB_CACHE_ADR_WIDTH
      キャッシュ対象ポートのアドレスバスの幅を指定します。
      4Gのメモリ空間をすべてキャッシュ対象とする場合を除き、必要量の
     アドレスバス数に減らすことで、キャッシュのタグRAMを節約できます。

    WB_CACHE_DAT_SIZE
      キャッシュ対象ポートデータバスの幅を2のべき乗で指定します。
      0:8bit, 1:16bit, 3:32bit, ... というように指定します。
      32bit より大きいバスを使うことで、キャッシュラインを一気に
     充填できます。デフォルトでキャッシュラインの幅となります。


    WB_THROUGH_ADR_WIDTH
      非 キャッシュ対象ポートのアドレスビット数を指定します。
      デフォルトは 30 です。

    WB_THROUGH_ADR_WIDTH
      非 キャッシュ対象ポートのバスの幅を2のべき乗で指定します。
      0:8bit, 1:16bit, 3:32bit, ... というように指定します。
      デフォルトは 2 (32bit) です。

    SIMULATION
      シミュレーション実行を指定します。
      0:合成時(デフォルト)  1:シュミレーション
      PCトレースをファイルに落とすなどのシュミレーション時固有機能が有効になります。

ポート信号

    reset  (input)
      リセット信号を指定します。1でリセットが有効です。
        同期リセットですので、リセット有効状態で最低1サイクルのクロックを入れて
      初期化する必要があります。
        リセット解除は clk の立ち上がりに同期して行ってください。

    clk  (input)
      基本クロックです。

    clk_x2  (input)
      倍速クロックです。clkと位相のそろった倍速クロックを入れてください。
      汎用レジスタに倍速クロックを指定した場合にのみ必要です。

    endian  (input)
      エンディアンを指定します。
      0:リトルエンディアン  1: ビッグエンディアン
      動作途中での切り替えは行わないでください。

    vect_reset[31:0]  (input)
      リセットベクタのアドレスを指定します。
      リセット解除後、PCはこの値になります。
      下位2bitは必ず0にしてください。

    vect_interrupt[31:0]  (input)
      割込みベクタのアドレスを指定します。
      割込み受付時、PCはこの値に分岐します。
      下位2bitは必ず0にしてください。

    vect_exception[31:0]  (input)
      例外ベクタのアドレスを指定します。
      例外発生時、PCはこの値に分岐します。
      下位2bitは必ず0にしてください。

    interrupt_req  (input)
      割込み要求信号です。1で割り込みを要求します。

    interrupt_req  (output)
      割込みを受け付けたタイミングで1を出力します。
      必要なければ特に監視する必要はありません。

    pause  (input)
      外部から強制的にCPUをインターロックさせます。
      1で停止し、0で動作を再開します。
      利用しない場合は常時 0 としてください。

    tcm_addr_mask[31:0]  (input)
    tcm_addr_value[31:0]  (input)
      TCMに割り当てるアドレスを指定します。
      バイトアドレスなのでご注意ください。下位2bitは必ず0にしてください。
        (address & tcm_addr_mask) == tcm_addr_value
      となるアドレスが、TCM領域として割り当てられます。
      動作中の変更は行わないでください。

   cache_addr_mask[31:0]  (input)
   cache_addr_value[31:0]  (input)
      キャッシュ対象とするアドレスを指定します。
      バイトアドレスなのでご注意ください。下位2bitは必ず0にしてください。
        (address & cache_addr_mask) == cache_addr_value
      となるアドレスが、キャッシュ対象となります。
      動作中の変更は行わないでください。

   wb_cache_adr_o (output)
   wb_cache_dat_i  (input)
   wb_cache_dat_o (output)
   wb_cache_we_o (output)
   wb_cache_sel_o (output)
   wb_cache_stb_o (output)
   wb_cache_ack_i (input)
      キャッシュ対象ポートのWISHBONEバスです。
      キャッシュ領域への書き込みや、キャッシュミスがこのポートから
    アクセスされます。
      アドレスはバイトアドレスではなく、指定したデータバスのサイズが
    単位となります。

   wb_through_adr_o (output)
   wb_through_dat_i  (input)
   wb_through_dat_o (output)
   wb_through_we_o (output)
   wb_through_sel_o (output)
   wb_through_stb_o (output)
   wb_through_ack_i (input)
      非キャッシュ対象ポートのWISHBONEバスです。
      TCMでもキャッシュでもないアドレスにロード/ストアを行うとこのポートから
    アクセスされます。
      アドレスはバイトアドレスではなく、指定したデータバスのサイズが
    単位となります。

   wb_dbg_adr_i[5:2] (input)
   wb_dbg_dat_i[31:0] (input)
   wb_dbg_dat_o[31:0] (output)
   wb_dbg_we_i (input)
   wb_dbg_sel_i[3:0] (input)
   wb_dbg_stb_i (input)
   wb_dbg_ack_o (output)
     外部からCPU内のデバッグユニットにアクセスするためのポートです。
     WISHBONEバス仕様です。

CPUデバッグポート

デバッグポートから下記のアドレスにアクセスできます。

レジスタ仕様

   DBG_CTL  アドレス: 0x0 (バイトアドレス 0x00)
     デバッグ制御レジスタです。
       bit0 [Read Only]  : ブレーク状態 (ブレークが受け付けられ停止すると1になる)
       bit1 [Read/Write] : ブレーク要求 (1でCPUに停止を要求 )

   DBG_ADDR アドレス: 0x2 (バイトアドレス 0x08)
       bit0〜bit31 [Read/Write]
     デバッグアクセスを行うアドレスを指定します。

   REG_DATA アドレス: 0x4 (バイトアドレス 0x10)
       bit0〜bit31 [Read/Write]
     DBG_ADDRで示されるアドレスにある、CPUの内部レジスタがこの
    アドレス経由で読み書きできます。

   DBUS_DATA アドレス: 0x6 (バイトアドレス 0x18)
       bit0〜bit31 [Read/Write]
     DBG_ADDRで示されるメモリアドレスにこのアドレス経由で
    読み書きできます。
     アクセスはデータバス経由で行われます。

   IBUS_DATA アドレス: 0x7 (バイトアドレス 0x1c) [オプション]
       bit0〜bit31 [Read/Write]
     DBG_ADDRで示されるメモリアドレスにこのアドレス経由で
    読み書きできます。
     アクセスは命令バス経由で行われます。
    将来のハーバードアーキテクチャに対する予備的機能です。

UART経由デバッグ制御

Jelly では、上記のCPUデバッグポートを UART 経由で制御する モジュールを用意しています。 UARTプロトコルは以下のとおり。

  接続確認(nop)
    要求パケット  0x00
    応答パケット  0x80
   単純に応答のみ行います

  状態確認(statu)
    要求パケット  0x01
    応答パケット  0x81 status

    0x81 に続いて、status 1バイトが返されます。
    status の 0bit目に、エンディアンが返されます。
    他のビットは現在予約bitです

  デバッガライト(dbg_write)
    CPUデバッグポートの指定アドレスにシングルライトを行う
      要求パケット  0x02 sel+adr dat0 dat1 dat2 dat3
      応答パケット  0x82
    (注:アドレス4bitと、レーンセレクト4bit で1バイト)

  デバッガリード(dbg_read)
      要求パケット  0x03 sel+adr
      応答パケット  0x83 dat0 dat1 dat2 dat3
    (注:アドレス4bitと、レーンセレクト4bit で1バイト)

  メモリライト(mem_write)
      要求パケット 0x04 size adr0 adr1 adr2 adr3 dat0 dat1 dat2 dat3 ....
      応答パケット 0x84

    サイズ、アドレスの後にデータを送ります。
    1パケットで最大で256バイトまで送ることが出来ます。
    すべての送信が終わると応答パケットが返ります

  メモリリード(mem_read)
      要求パケット 0x05 size adr0 adr1 adr2 adr3
      応答パケット 0x85 dat0 dat1 dat2 dat3 ....

    サイズ、アドレスを送ると応答パケットが来ます。
    1パケットで最大で256バイトまで送ることが出来ます。

WISHBONEバス

Jellyでは OpenCores(http://www.opencores.org/) の定めるWISBONEバスを 利用しています。 WISHBONEバス規格は多岐にわたっていますが、Jellyではシングルアクセスに 必要な最小限の信号のみ利用しています。 以下に利用している信号のみ簡単に説明します。

   adr_o
     アクセスするアドレスを指定します。
     バイト単位ではなくデータバスの単位となります。
     したがって、32bitデータバスの場合、アドレスバス幅は30bit幅で4Gbyteのメモリ空間を
    カバーします。

   dat_o
   dat_i
     データの入出力を行う信号です。ライト/リードの信号が流れます。

   we_o
     リード/ライトの指定を行う信号です。
     0:read 1:write となります。

   sel_o
     リード/ライト時のデータバスの有効なレーンを示します。
     Jellyの場合、レーンサイズは8bit固定です。
     32bitバスの場合、4bit幅の信号となります。

   stb_o
     マスター側がアクセスを要求していることを示します。
     アクセスが完了するまで 1 をキープします。

   ack_i
     スレーブ側がアクセスを完了させたことを示します。
     組合せ回路に stb_o を含むことができ、アクセス要求と同じサイクルで
    アクノリッジを返すことが可能です。

Jelly bus

WISHBONEバスはサイクル内でトランザクションが完結するため多くの場合 便利ですが、FPGAの内蔵SRAMの様にREAD結果の取得が次サイクルとなり、 メモリにCPUコアを直結する場合に相性が悪いです。 そこで下記のような独自バスを jbus として定義しています。

   en [master]
     バスのイネーブル
     組合わせ回路に ready を含んでもよい
   
   addr [master]
     アドレス値
     クロックの立ち上がりで en & valid & ready が 1 のとき受け付けられる
     master は en または ready が 0 のサイクルで値を変化させてはならない
   
   we [master]
     1で書き込みを示す
     クロックの立ち上がりで en & valid & ready が 1 のとき受け付けられる
     master は en または ready が 0 のサイクルで値を変化させてはならない
   
   sel [master]
     バイトセレクト。1で有効バイト
     クロックの立ち上がりで en & valid & ready が 1 のとき受け付けられる
     master は en または ready が 0 のサイクルで値を変化させてはならない
   
   wdata [master]
     書き込みデータ
     クロックの立ち上がりで en & valid & ready が 1 のとき受け付けられる
     master は en または ready が 0 のサイクルで値を変化させてはならない
   
   rdata [slave]
     読み出しデータ
     クロックの立ち上がりで en & valid & ready が 1 のとき受け付けられる
     読み出し要求が受け付けられた後、en & ready の時データが出力される
     slave は en が 0 のサイクルで値を変化させてはならない
   
   valid [master]
     アクセス要求
     master は en または ready が 0 のサイクルで値を変化させてはならない
     組合わせ回路に ready を含んではならない
   
   ready [slave]
     アクセス許可
     組合わせ回路に valid を含んでもよいが、en を含んではならない

命令セット等

こちらに置いておきます。

files/jelly_cpu.ods

MIPS-I 互換ソフトコア環境

はじめに

MicroBlazeが無償で利用でき、ZynqにARMコアが搭載され、今となっては過去の遺物となってしまっていますが、私が Jelly システムを作り始めたきっかけは「CPUを書いてみたい」が発端だったのと、今でも rtl/cpu フォルダの下に当時RTLを覚えたばかりの頃に書いたCPUのRTLコードが居座っていますので、当時 HTML で書いた説明文を今風に Markdown に書き直してみたいと思います。

spartan3e_starter mmc cq_frk_s3e2

Jelly-CPUの特徴

  • MIPS-Iライクな命令セットで、gcc でC言語開発が行える

  • キャッシュ機能

  • 密結合メモリ(TCM)機能

  • Verilog 2001 で記述

  • DDR-SDRAM対応

  • μITRON4.0仕様 HOS-V4a 対応中

  • ICE拡張用のデバッグポートを備えている

  • キュメントが日本語(作者が英語わかんない)

システムの説明

CPUコアのブロック図

cpu_core_block

典型的な教科書どおり5段パイプラインのアーキテクチャで、コア部はハーバードアーキテクチャ(命令バスとデータバスが別)にしています。

また、内蔵でデバッグユニットも用意しており、外部からCPUコアを直接操作可能です。

フォワーディングも入っており、殆どの実行ユニットをEXステージに固めていますし、MIPS-Iではロード命令の次命令ではロードしたレジスタは利用禁止ですので、特にストルール要因はありません(なのでバスビジーなどでインターロックが必要なケースではプロセッサ全体をとめてしまい、機構をシンプル化しています)。

その他、FPGA的な工夫点としては、フォワーディングのマルチプレクサがFPGA的に苦手なので、特に32bit乗算でクリティカルパスとして現れます。そこで乗算命令の時でなく、結果の読み出し命令(mfhi, mflo)で乗算するようにして、見かけ上、乗算は1サイクルで実現できました(除算はさすがに32サイクルのインターロックがかかりますが)。

デバッグユニットのようなボトルネックを挟んで Spartan-3 のスピードグレード-4で50MHzで動いていますのでまあまあといったところではないでしょうか?

CPUトップの説明図

cpu_top_block

CPUコアの外に、密結合メモリ(TCM)とキャッシュを搭載しています。TCMとキャッシュはオプションで切り離しも可能です。

FPGAの内蔵デュアルポートRAMを行かして、2つのポートを命令/データに割り当てているのでロス無くユニファイドキャッシュが実装できており、命令/データでのキャッシュコヒーレンシの問題も出ません。

密結合メモリ(TCM)もFPGAの内蔵デュアルポートRAMのおかげで、命令/データバスの両方からアクセスできます。

各種バスにはOPENCORES.ORGWISHBONEバス と互換性があるように作ったつもりです(単純なシングルアクセスしか使ってませんが)。

Spartan3e statrer kit でのシステムの説明図

spartan3e_block

今回のボードにはRS-232Cが2ポートあるのをいいことに、デバッグポートはUART経由で制御するようにしています。パソコン側はUSBシリアルなどを買ってきて、増設すればどうにでもなります。ひとまず、プログラムダウンロードやレジスタ制御、ハードウェアブレークなど、将来デバッガ機能を一通り作れる機能を準備しています。

また、非常にシンプルなものですがDDR-SDRAMの制御RTLも書いてみました。IOの遅延調整がボード個体差があると思われますので、流用したい方でうまく動かない方はucfファイルの遅延値を調整してみてください。今のところシングルアクセスのみです。CPUの50MHzに対し、DDR-SDRAMは100MHz駆動なのでクロック乗せかえ用のブリッジが入っています。

ペリフェラルバスには各種周辺回路をつないでいます。IRC(割り込みコントローラ)はITRON屋らしく、多重割り込みや優先度設定が豊富にできるように工夫しています。本当はITRONのAPIをそのまま被せたかったのですが、回路的に無謀なのでそれなりにソフトウェア任せなところもあります。

開発環境について

ハードウェア環境

開発ボードには Xilinx の Spartan-3e Starter Kitを使っていました。 今だと入手は難しいと思いますので、あくまで参考です。

ソフトウェア環境

Xilinx の ISE WebPack を使っています。

C言語コンパイラは当時 gcc のクロスコンパイラを cygwin 上で構築して使っていました。今だと Windows 派の人でも WSL や VirtualBox がありますので Linux 上でクロスコンパイラが使えると思います。

swl,swr,lwl,lwr 等が使えないのでそこだけお気をつけください。

Indices and tables