hello_veryl
| Version | 0.1.0 |
|---|
Modules
| ActivityLed | アクティビティ表示 (パルス引き伸ばし) |
|---|---|
| AxiLiteMemModel | AXI4-Lite の小容量メモリモデル (L1 テスト用.合成対象ではない) |
| Blink | LED 点滅 (分周トグル) |
| CdcHandshake | 非同期ハンドシェイク CDC (トグルハンドシェイク + 2FF 同期) |
| Fat32Reader | FAT32 リーダ v2 (docs/tfcard.md「FAT32 リーダ仕様」) |
| FontRom | 8x16 フォント ROM (ASCII 0x00-0x7F,未定義コードは全 0) |
| ImageScanout | PSRAM フレームバッファのスキャンアウト (docs/tfcard.md「画像表示デモ仕様」) |
| PsramAxiArb2 | AXI4-Lite 2 マスタ固定優先度アービタ (docs/tfcard.md「画像表示デモ仕様」) |
| PsramAxiBridge | AXI4-Lite ブリッジ + CDC (docs/psram.md「バス IF」「CDC」) |
| PsramClkGen | PSRAM 用クロック生成 (rPLL 27 MHz → clk_mem 54 MHz) |
| PsramCtrl | PSRAM コントローラ (HyperBus FSM,clk_mem 単一ドメイン.docs/psram.md) |
| PsramMemtest | PSRAM memtest (実機デモ,docs/psram.md パッチ計画 #7) |
| PsramPhy | PSRAM 物理層 (ODDR/IDDR/IOBUF ラッパ,docs/psram.md「物理層」) |
| PsramPhySdr | PsramPhySdrCore の IOBUF ラッパ (Top 統合用) |
| PsramPhySdrCore | PSRAM SDR fallback 物理層 (docs/psram.md「SDR fallback phy」) |
| PsramSpikeBitbang | PSRAM spike 段1: bit-bang レジスタ読み出し (docs/psram.md「spikeの構成」) |
| PsramSubsystem | PSRAM サブシステム一式 (docs/psram.md) |
| RvAlu | RV32I の ALU (docs/riscv.md「マイクロアーキテクチャ」) |
| RvAxiMaster | コアの簡易メモリプロトコルを AXI4-Lite マスタへ変換する |
| RvCore | RV32I 多サイクルコア (docs/riscv.md「マイクロアーキテクチャ」) |
| RvCsr | M モードの CSR ファイルとトラップ制御 (docs/riscv.md「ISA スコープ」) |
| RvDecoder | RV32I 命令デコーダ (docs/riscv.md「ISA スコープ」) |
| RvMem | RvCore 用のワードメモリ (docs/riscv.md「メモリマップ」) |
| RvMmio | RvCore のメモリマップドペリフェラル (docs/riscv.md「メモリマップ」) |
| RvMulDiv | RV32M の乗除算ユニット (docs/riscv.md「ISA スコープ」) |
| RvRegFile | RV32I のレジスタファイル (docs/riscv.md「マイクロアーキテクチャ」) |
| RvRom | ソフトコアのブート ROM (docs/riscv.md「ブートフロー」) |
| RvSoc | RV32I ソフトコアの SoC (docs/riscv.md「メモリマップ」) |
| RvTfIo | TF カードの byte-stream 入出力(RvCore の周辺機器. |
| SpiMaster | SPI マスタ (mode 0,バイト単位転送,MSB first) |
| TextConsole | テキストコンソール |
| TfCtrl | TF カードブロック入出力コントローラ v2 (docs/tfcard.md「プロトコル仕様」) |
| TfImageDemo | TF カード画像表示デモ (docs/tfcard.md「画像表示デモ仕様」,パッチ #8) |
| TfSpikeInit | TF カード初期化 spike (docs/tfcard.md「spike の構成」) |
| TfTextDemo | TF カードテキスト表示デモ (docs/tfcard.md パッチ #6) |
| Top | トップモジュール (Tang Nano 9K) |
| TopRv | RV32I ソフトコアのブリングアップ用トップ (docs/riscv.md パッチ計画 #6) |
| Uart | UART 送受信 (8N1) |
| VideoTiming | RGB LCD (DEモード) タイミングジェネレータ |
Module Prototypes
Interfaces
| stream_if | valid/ready ハンドシェイクの汎用 stream interface |
|---|
Packages
| RvBootRom | |
|---|---|
| RvPkg | RISC-V コアの共有型定義 (docs/riscv.md「ISA スコープ」) |
| RvTestImg | |
| TfCrc | TF カード用 CRC 計算 (docs/tfcard.md「プロトコル仕様」) |
| TfTypes | TF カードサブシステムの共有型定義 (docs/tfcard.md「インタフェース」) |
| psram_pkg | PSRAM サブシステム共通定義 (docs/psram.md) |
Modules
Modules
| ActivityLed | アクティビティ表示 (パルス引き伸ばし) |
|---|---|
| AxiLiteMemModel | AXI4-Lite の小容量メモリモデル (L1 テスト用.合成対象ではない) |
| Blink | LED 点滅 (分周トグル) |
| CdcHandshake | 非同期ハンドシェイク CDC (トグルハンドシェイク + 2FF 同期) |
| Fat32Reader | FAT32 リーダ v2 (docs/tfcard.md「FAT32 リーダ仕様」) |
| FontRom | 8x16 フォント ROM (ASCII 0x00-0x7F,未定義コードは全 0) |
| ImageScanout | PSRAM フレームバッファのスキャンアウト (docs/tfcard.md「画像表示デモ仕様」) |
| PsramAxiArb2 | AXI4-Lite 2 マスタ固定優先度アービタ (docs/tfcard.md「画像表示デモ仕様」) |
| PsramAxiBridge | AXI4-Lite ブリッジ + CDC (docs/psram.md「バス IF」「CDC」) |
| PsramClkGen | PSRAM 用クロック生成 (rPLL 27 MHz → clk_mem 54 MHz) |
| PsramCtrl | PSRAM コントローラ (HyperBus FSM,clk_mem 単一ドメイン.docs/psram.md) |
| PsramMemtest | PSRAM memtest (実機デモ,docs/psram.md パッチ計画 #7) |
| PsramPhy | PSRAM 物理層 (ODDR/IDDR/IOBUF ラッパ,docs/psram.md「物理層」) |
| PsramPhySdr | PsramPhySdrCore の IOBUF ラッパ (Top 統合用) |
| PsramPhySdrCore | PSRAM SDR fallback 物理層 (docs/psram.md「SDR fallback phy」) |
| PsramSpikeBitbang | PSRAM spike 段1: bit-bang レジスタ読み出し (docs/psram.md「spikeの構成」) |
| PsramSubsystem | PSRAM サブシステム一式 (docs/psram.md) |
| RvAlu | RV32I の ALU (docs/riscv.md「マイクロアーキテクチャ」) |
| RvAxiMaster | コアの簡易メモリプロトコルを AXI4-Lite マスタへ変換する |
| RvCore | RV32I 多サイクルコア (docs/riscv.md「マイクロアーキテクチャ」) |
| RvCsr | M モードの CSR ファイルとトラップ制御 (docs/riscv.md「ISA スコープ」) |
| RvDecoder | RV32I 命令デコーダ (docs/riscv.md「ISA スコープ」) |
| RvMem | RvCore 用のワードメモリ (docs/riscv.md「メモリマップ」) |
| RvMmio | RvCore のメモリマップドペリフェラル (docs/riscv.md「メモリマップ」) |
| RvMulDiv | RV32M の乗除算ユニット (docs/riscv.md「ISA スコープ」) |
| RvRegFile | RV32I のレジスタファイル (docs/riscv.md「マイクロアーキテクチャ」) |
| RvRom | ソフトコアのブート ROM (docs/riscv.md「ブートフロー」) |
| RvSoc | RV32I ソフトコアの SoC (docs/riscv.md「メモリマップ」) |
| RvTfIo | TF カードの byte-stream 入出力(RvCore の周辺機器. |
| SpiMaster | SPI マスタ (mode 0,バイト単位転送,MSB first) |
| TextConsole | テキストコンソール |
| TfCtrl | TF カードブロック入出力コントローラ v2 (docs/tfcard.md「プロトコル仕様」) |
| TfImageDemo | TF カード画像表示デモ (docs/tfcard.md「画像表示デモ仕様」,パッチ #8) |
| TfSpikeInit | TF カード初期化 spike (docs/tfcard.md「spike の構成」) |
| TfTextDemo | TF カードテキスト表示デモ (docs/tfcard.md パッチ #6) |
| Top | トップモジュール (Tang Nano 9K) |
| TopRv | RV32I ソフトコアのブリングアップ用トップ (docs/riscv.md パッチ計画 #6) |
| Uart | UART 送受信 (8N1) |
| VideoTiming | RGB LCD (DEモード) タイミングジェネレータ |
ActivityLed
ActivityLed
アクティビティ表示 (パルス引き伸ばし)
i_active のパルスを人間が視認できる幅へ引き伸ばす.
i_active が立つたびに保持カウンタをリロードし,HoldCycles の間
o_on を保持する (保持中の再トリガで延長).
Parameters
| HoldCycles | u32 | 保持サイクル数 (既定 100 ms @ 27 MHz) |
|---|
Ports
| i_clk | input | clock | クロック |
|---|---|---|---|
| i_rst | input | reset | リセット |
| i_active | input | logic | アクティビティ検出 (レベル,1 で活動中) |
| o_on | output | logic | 表示出力 (保持中 1) |
AxiLiteMemModel
AxiLiteMemModel
AXI4-Lite の小容量メモリモデル (L1 テスト用.合成対象ではない)
PsramAxiBridge + PsramCtrl + PSRAM の代わりに置き,ライトの内容と回数, リードの応答を検証するために使う.単一アウトスタンディング, 応答は常に OKAY,WSTRB はバイト単位で反映する.
i_dbg_word / o_dbg_data で内容を読み出し,i_dbg_we / i_dbg_wdata で
初期値を直接書き込める.
Parameters
| Words | u32 | 語数 (32 bit ワード) |
|---|---|---|
| ReadDelay | u32 | リード応答を遅らせるサイクル数 (0 で即応答) |
Ports
| i_clk | input | clock | クロック |
|---|---|---|---|
| i_rst | input | reset | リセット |
| s_axi | modport | $std __axi4_lite_if__$std___axi4_lite_pkg__22__4__1 slave | AXI4-Lite スレーブ |
| i_dbg_word | input | logic<20> | 観測・初期化するワード番号 |
| i_dbg_we | input | logic | 1 で i_dbg_wdata を書く (初期値設定用) |
| i_dbg_wdata | input | logic<32> | 初期化データ |
| o_dbg_data | output | logic<32> | 観測値 |
| o_wr_count | output | logic<16> | 受理したライト数 |
| o_rd_count | output | logic<16> | 受理したリード数 |
Blink
Blink
LED 点滅 (分周トグル)
InClkFreq / (BlinkFreq * 2) サイクルごとに出力を反転し,
BlinkFreq [Hz] の矩形波を生成する.
Parameters
| InClkFreq | u32 | 入力クロック周波数 [Hz] |
|---|---|---|
| BlinkFreq | u32 | 点滅周波数 [Hz] |
Ports
| i_clk | input | clock | クロック |
|---|---|---|---|
| i_rst | input | reset | リセット |
| o_led | output | logic | LED 出力 (トグル) |
CdcHandshake
CdcHandshake
非同期ハンドシェイク CDC (トグルハンドシェイク + 2FF 同期)
単一データのクロックドメイン間転送.src 側で valid/ready 成立時に データをラッチしてトグルを反転,dst 側は同期したトグルの変化で データを取り込み od_valid を立てる.dst の消費で dst 状態が反転し, src へ同期して ready が回復する(単一アウトスタンディング).
データレジスタは転送中不変(トグルハンドシェイクの保証)のため, ’d 側でのラッチは安全(unsafe (cdc) で明示).
注: std::async_handshake と同方式だが,同部品は内部で導出リセットを 用いるため veryl 0.20.2 のネイティブシミュレーションで初期化されず L1 検証不能だった(docs/psram.md「CDC」).本実装はリセットを各 ドメインの FF へ直結し,検証可能性を確保する.
Parameters
| TYPE | type | 転送データ型 |
|---|
Clock Domains
| 'd |
|---|
| 's |
Ports
| is_clk | input | 's | clock | src クロック |
|---|---|---|---|---|
| is_rst | input | 's | reset | src リセット |
| is_valid | input | 's | logic | src データ有効 |
| os_ready | output | 's | logic | src 受理可能 |
| is_data | input | 's | TYPE | src データ |
| id_clk | input | 'd | clock | dst クロック |
| id_rst | input | 'd | reset | dst リセット |
| od_valid | output | 'd | logic | dst データ有効 |
| id_ready | input | 'd | logic | dst 受理可能 |
| od_data | output | 'd | TYPE | dst データ |
Fat32Reader
Fat32Reader
FAT32 リーダ v2 (docs/tfcard.md「FAT32 リーダ仕様」)
TfCtrl (v1) のブロックリードを下位に使い,8.3 名で指定されたファイルを ルートディレクトリから探して内容を stream_if で送出する.リード専用.
- MBR パーティション 1 (タイプ 0Bh/0Ch) と,スーパーフロッピー形式 (セクタ 0 が JMP + BytsPerSec=512 の BPB) の両方に対応
- 8.3 名 11 バイト照合.要求名の
'?'(3Fh) は任意 1 文字に一致 - LFN (属性 0Fh)・削除済み (E5h)・ボリュームラベル・サブディレクトリはスキップ, 先頭バイト 00h で列挙終端
- オフセット起点はクラスタチェーン追跡とセクタ内バイト破棄で実現し, 範囲外セクタの CMD17 は発行しない
- FAT 参照はクラスタ遷移毎に該当 FAT セクタを 1 ブロックリードする (キャッシュなし)
- マウント (MBR/BPB 解釈) は初回要求時に行い,以降の要求で再利用する
注意: 下位 TfCtrl の初期化失敗時は要求が受理されない (ブロック要求が 受け付けられないため停止する).利用側は TfCtrl の o_init_err を確認すること.
Ports
| i_clk | input | clock | クロック |
|---|---|---|---|
| i_rst | input | reset | リセット |
| i_req_valid | input | logic | ファイル読み出し要求 |
| i_req_name | input | logic<88> | 8.3 名 11 バイト ([87:80] が先頭文字,'?'=任意) |
| i_req_offset | input | logic<32> | 開始バイトオフセット |
| i_req_len | input | logic<32> | 読み出しバイト数 (ファイル末尾で打ち切り) |
| o_req_ready | output | logic | 要求受付可能 |
| o_done | output | logic | 完了 (1 サイクルパルス) |
| o_err | output | TfTypes FsError | 完了時のエラー種別 |
| o_file_size | output | logic<32> | 発見したファイルのサイズ (found 以降有効) |
| data | modport | stream_if source | ファイル内容 (要求範囲のみ) |
| o_blk_valid | output | logic | ブロックリード要求 |
| o_blk_lba | output | logic<32> | 要求 LBA |
| i_blk_ready | input | logic | 要求受付可能 |
| i_blk_done | input | logic | ブロック完了 (1 サイクルパルス) |
| i_blk_err | input | TfTypes Error | ブロック完了時のエラー種別 |
| blk | modport | stream_if sink | ブロックデータ (512 バイト/ブロック) |
FontRom
FontRom
8x16 フォント ROM (ASCII 0x00-0x7F,未定義コードは全 0)
各バイト: bit0=左端(col0) [LSB-left]. 実装: グリフ単位の case 式で 128bit パック定数 (row0 が下位) を引き, 行はシフトで選択する (Veryl は通常 module の initial で代入不可, また数百アームの単一 case はコンパイラの stack overflow を誘発するため).
生成物のため直接編集しない (scripts/gen_font_rom.py で再生成).
Ports
| i_clk | input | clock | クロック |
|---|---|---|---|
| i_code | input | logic<7> | ASCIIコード |
| i_row | input | logic<4> | グリフ内の行 (0-15) |
| o_line | output | logic<8> | 1行分のピクセル (1サイクル遅れ) |
ImageScanout
ImageScanout
PSRAM フレームバッファのスキャンアウト (docs/tfcard.md「画像表示デモ仕様」)
PSRAM 上の SrcW x SrcH の RGB565 画像を,ScaleX x ScaleY のブロック複製で LCD の有効領域へ拡大表示する.AXI4-Lite のリードマスタとして動作し, ソース 1 行ぶんをラインバッファ (2 面) へ先読みする.
帯域: ソース 1 行は ScaleY ラインぶん表示されるため,その間に次の 1 行 (SrcW/2 ワード) を読めばよい (docs/tfcard.md「帯域の制約と解像度の決定」).
出力位相: TextConsole と同じく i_pos_x から 2 サイクル遅れで o_rgb を出す (ラインバッファの出力レジスタ 1 段 + 本モジュールの出力段 1 段).
制約: SrcW は偶数 (32 bit ワード = 2 px),ScaleX / ScaleY は 2 冪.
Parameters
| SrcW | u32 | ソース画像の幅 [px] (偶数) |
|---|---|---|
| SrcH | u32 | ソース画像の高さ [px] |
| ScaleX | u32 | 水平複製率 (有効幅 = SrcW * ScaleX,2 冪) |
| ScaleY | u32 | 垂直複製率 (有効高 = SrcH * ScaleY,2 冪) |
| FbWordBase | u32 | フレームバッファ先頭のワード番号 (32 bit 単位) |
Ports
| i_clk | input | clock | クロック (= pclk 27 MHz) |
|---|---|---|---|
| i_rst | input | reset | リセット |
| i_en | input | logic | 1 で表示 (フレームバッファ展開完了後) |
| i_frame | input | logic | V ブランキング先頭の 1 クロックパルス |
| i_de | input | logic | データイネーブル |
| i_pos_x | input | logic<10> | 画素 X 座標 (de==1 で有効) |
| m_axi | modport | $std __axi4_lite_if__$std___axi4_lite_pkg__22__4__1 master | PSRAM からのリード |
| o_rgb | output | logic<16> | RGB565 画素 (i_pos_x から 2 サイクル遅れ) |
PsramAxiArb2
PsramAxiArb2
AXI4-Lite 2 マスタ固定優先度アービタ (docs/tfcard.md「画像表示デモ仕様」)
各マスタが単一アウトスタンディングであることを前提に,グラントを トランザクション完了 (ライトは B 応答,リードは R 応答) まで保持する. m0 が高優先度.3 マスタ以上は本モジュールを段積みして構成する (例: arb(arb(memtest, loader), scanout)).
前提: マスタは awvalid / arvalid を受理されるまで下げない. ライト要求は awvalid と wvalid を同一トランザクションとして扱う (AXI4-Lite の単一転送).
Ports
| i_clk | input | clock | |
|---|---|---|---|
| i_rst | input | reset | |
| m0 | modport | $std __axi4_lite_if__$std___axi4_lite_pkg__22__4__1 slave | 高優先マスタ |
| m1 | modport | $std __axi4_lite_if__$std___axi4_lite_pkg__22__4__1 slave | 低優先マスタ |
| s | modport | $std __axi4_lite_if__$std___axi4_lite_pkg__22__4__1 master | 下流スレーブへ |
PsramAxiBridge
PsramAxiBridge
AXI4-Lite ブリッジ + CDC (docs/psram.md「バス IF」「CDC」)
s_axi (27 MHz ドメイン) の単一アウトスタンディング要求を psram_pkg::req_t へ束ね,CdcHandshake で clk_mem 側の PsramCtrl へ渡す.応答は逆方向の handshake で受け,B/R チャネルへ 返す (常に OKAY.PSRAM はエラー応答を持たない).
- AW と W は到着順非依存で合流し,両方揃ってから同時に受理する
- 初期化未完了時は PsramCtrl 側が要求を取らないため,AXI 側は 応答待ちのまま自然にブロックされる
Clock Domains
| 'axi |
|---|
| 'mem |
Ports
| i_clk_axi | input | 'axi | clock | AXI 側クロック (27 MHz) |
|---|---|---|---|---|
| i_rst_axi | input | 'axi | reset | AXI 側リセット |
| i_clk_mem | input | 'mem | clock | clk_mem (54 MHz) |
| i_rst_mem | input | 'mem | reset | mem 側リセット |
| s_axi | modport | 'axi | $std __axi4_lite_if__$std___axi4_lite_pkg__22__4__1 slave | AXI4-Lite スレーブ |
| o_req_valid | output | 'mem | logic | |
| i_req_ready | input | 'mem | logic | |
| o_req | output | 'mem | psram_pkg req_t | |
| i_rsp_valid | input | 'mem | logic | |
| o_rsp_ready | output | 'mem | logic | |
| i_rsp | input | 'mem | psram_pkg rsp_t |
PsramClkGen
PsramClkGen
PSRAM 用クロック生成 (rPLL 27 MHz → clk_mem 54 MHz)
設定 (docs/psram.md,UG286):
fCLKOUT = 27 * FBDIV(2) / IDIV(1) = 54 MHz,
fVCO = 54 * ODIV(16) = 864 MHz (GW1NR-9 C6/I5 許容 400-1200 MHz 内,DS117).
位相調整出力 CLKOUTP は phy パッチで使用する (PSDA_SEL は初期値 90°=0100). LOCK はロック過程でグリッチしうる (UG286 note) ため表示用途に留める. 実機結果 (2026-07-22): 54 MHz 動作と lock を LED で確認済み.
Clock Domains
| 'mem |
|---|
| 'memp |
| 'osc |
Ports
| i_clk | input | 'osc | clock | 基準クロック (27 MHz オシレータ) |
|---|---|---|---|---|
| o_clk_mem | output | 'mem | clock | clk_mem (54 MHz,位相 0°) |
| o_clk_mem_p | output | 'memp | clock | 位相シフト出力 (+90°,段2では未使用) |
| o_lock | output | 'osc | logic | PLL lock (非同期出力,表示用途のみ) |
PsramCtrl
PsramCtrl
PSRAM コントローラ (HyperBus FSM,clk_mem 単一ドメイン.docs/psram.md)
初期化 (RESET# パルス → tVCS 待機 → CR0 書き込み → IR0 読み出し自己診断) の後,req/rsp インタフェースの 32bit アクセスを 16bit HyperBus トランザクション 2 回に分割して実行する (単一アウトスタンディング).
- レイテンシは固定 2x (CR0[3]=1).データ位相は CA 3 クロック目立上りを 起点に 2*InitialLatency CK 後 (spike 段1 実測 L=0B で確定した起点)
- リードは RWDS 修飾のペア検出で語を取り込む.phy の IDDR 取り込みが CK に対しどちらの半サイクルへ載るか (位相依存の半サイクルずれ) に よらず {RWDS=1 の半サンプル, 続く RWDS=0 の半サンプル} を語として 組むため,位相調整 (L4 残余⑤) で壊れない
- ライトの WSTRB は RWDS マスク (High=マスク) へ写像し, 両バイトマスクの半語はトランザクション自体を省略する
- 初期化未完了の間は req_ready を落として待たせる.応答は常に完了 (エラー応答なし.リードのタイムアウト時は FFFF を返し,初期化中の IR0 照合失敗は o_init_ok=0 として観測する)
Parameters
| ResetPulseCycles | u32 | RESET# パルス幅 [cyc] (tRP 200 ns min → 296 ns @54 MHz) |
|---|---|---|
| TvcsCycles | u32 | RESET# 解除後の待機 [cyc] (tVCS 150 µs min → 200 µs @54 MHz) |
| InitialLatency | u32 | CR0 に設定する Initial Latency (54 MHz ≤ 83 MHz → 3) |
| Cr0Value | logic<16> | CR0 書き込み値 (IL=3, 固定 2x, 他はデフォルト維持) |
| WriteCr0 | bit | CR0 書き込みを行うか (0 で POR デフォルト IL=6 のまま動作.L4 切り分け用) |
| Ir0Expected | logic<16> | IR0 期待値 (Winbond / 32 Mbit.spike 段1 実測値) |
| DetectStartCyc | u32 | リード検出ウィンドウ開始 [txn cyc] (CA 期間の RWDS High を誤検出しない下限) |
| TimeoutCyc | u32 | リード検出打ち切り [txn cyc] |
Ports
| i_clk | input | clock | |
|---|---|---|---|
| i_rst | input | reset | |
| i_en | input | logic | 位相イネーブル.1 のサイクルのみ状態更新する (1 サイクル = 1 CK の関係を 保ったまま SDR fallback phy の 1/4 レートで駆動するため.全速 phy では 1 固定). 注意: req/rsp を全速の相手 (CdcHandshake) と結ぶ場合,o_req_ready と o_rsp_valid は i_en で修飾して渡すこと (非イネーブルサイクルでの 取りこぼし・二重送信防止.Top の配線参照) |
| i_req_valid | input | logic | |
| o_req_ready | output | logic | |
| i_req | input | psram_pkg req_t | |
| o_rsp_valid | output | logic | |
| i_rsp_ready | input | logic | |
| o_rsp | output | psram_pkg rsp_t | |
| o_init_done | output | logic | 初期化シーケンス完了 |
| o_init_ok | output | logic | IR0 照合成功 (init_done 後に有効) |
| o_ck_en | output | logic | |
| o_cs_n | output | logic | |
| o_reset_n | output | logic | |
| o_dq_a | output | logic<8> | |
| o_dq_b | output | logic<8> | |
| o_dq_oe | output | logic | |
| o_rwds_a | output | logic | |
| o_rwds_b | output | logic | |
| o_rwds_oe | output | logic | |
| i_dq_a | input | logic<8> | |
| i_dq_b | input | logic<8> | |
| i_rwds_a | input | logic | |
| i_rwds_b | input | logic |
PsramMemtest
PsramMemtest
PSRAM memtest (実機デモ,docs/psram.md パッチ計画 #7)
AXI4-Lite マスタとして PSRAM へ Words 語を書き込み,読み返して照合する.
パターンはアドレス関数 ({k[15:0]^A5A5, k[15:0]}) とし,アドレスデコード
誤りもデータ不一致として検出する.結果は ASCII 1 行の stream として送出:
PSRAM INIT=1 MEMTEST=PASS ERR=0000 K=00000 RD=00000000
K/RD は最初の不一致の語番号と読み値 (診断用.PASS 時は 0)
初期化状態 (i_init_done/ok) は clk_mem ドメインの準静的フラグを 2FF 同期して参照する.
Parameters
| Words | u32 | テストする 32bit ワード数 |
|---|
Ports
| i_clk | input | clock | |
|---|---|---|---|
| i_rst | input | reset | |
| m_axi | modport | $std __axi4_lite_if__$std___axi4_lite_pkg__22__4__1 master | PSRAM ブリッジへ |
| i_init_done | input | logic | PsramCtrl の初期化完了 (clk_mem 域,内部で同期) |
| i_init_ok | input | logic | PsramCtrl の IR0 照合結果 (同上) |
| msg | modport | stream_if source | 結果メッセージ (リセット毎に 1 行) |
PsramPhy
PsramPhy
PSRAM 物理層 (ODDR/IDDR/IOBUF ラッパ,docs/psram.md「物理層」)
FSM 側の SDR インタフェース (1 サイクル = 1 CK,A=CK 立上り側 / B=立下り側) を DDR パッド信号へ変換する.
- すべての出力パッド (CK/CK#/CS#/RESET#/DQ/RWDS) を ODDR 経由とし, 出力パイプライン段数を構成的に一致させる (段数の絶対値に依存しない)
- CK/CK# は clk_mem_p (+90°) の ODDR によるクロックフォワーディングで生成し, clk_mem 側で出すデータに対する 90° 位相関係を PLL の位相シフト設定のみで 決める (位相調整を単一変数化,L4 残余(5))
- 入力 (DQ/RWDS) は clk_mem の IDDR で取り込む (Q0=立上り / Q1=立下り)
注意: ODDR の INIT は 1’b0 固定のため,コンフィグ直後〜FSM 駆動開始までの 遷移期間は CS#=0/RESET#=0 がパッドへ出る.RESET#=0 が RAM をリセットに 保持するため CS# の値は無害だが,FSM は必ず RESET# パルス→tVCS 待機から 開始すること.
Clock Domains
| 'mem |
|---|
| 'memp |
Ports
| i_clk | input | 'mem | clock | clk_mem (FSM/データ,54 MHz) |
|---|---|---|---|---|
| i_clk_p | input | 'memp | clock | clk_mem_p (+90°,CK 出力用) |
| i_rst | input | 'mem | reset | リセット |
| i_ck_en | input | 'mem | logic | CK 駆動 (1 で 1 CK パルス) |
| i_cs_n | input | 'mem | logic | CS# |
| i_reset_n | input | 'mem | logic | RESET# |
| i_dq_a | input | 'mem | logic<8> | DQ 送出 byte A (CK 立上り側) |
| i_dq_b | input | 'mem | logic<8> | DQ 送出 byte B (CK 立下り側) |
| i_dq_oe | input | 'mem | logic | DQ 出力イネーブル |
| i_rwds_a | input | 'mem | logic | RWDS 送出 A (ライトマスク) |
| i_rwds_b | input | 'mem | logic | RWDS 送出 B |
| i_rwds_oe | input | 'mem | logic | RWDS 出力イネーブル |
| o_dq_a | output | 'mem | logic<8> | DQ 取り込み (立上り) |
| o_dq_b | output | 'mem | logic<8> | DQ 取り込み (立下り) |
| o_rwds_a | output | 'mem | logic | RWDS 取り込み (立上り) |
| o_rwds_b | output | 'mem | logic | RWDS 取り込み (立下り) |
| o_pad_ck | output | 'memp | logic | CK パッド |
| o_pad_ck_n | output | 'memp | logic | CK# パッド (差動) |
| o_pad_cs_n | output | 'mem | logic | CS# パッド |
| o_pad_reset_n | output | 'mem | logic | RESET# パッド |
| io_pad_dq | inout | 'mem | trilogic<8> | DQ パッド |
| io_pad_rwds | inout | 'mem | trilogic | RWDS パッド |
PsramPhySdr
PsramPhySdr
PsramPhySdrCore の IOBUF ラッパ (Top 統合用)
Ports
| i_clk | input | clock | |
|---|---|---|---|
| i_rst | input | reset | |
| o_en | output | logic | FSM 状態更新イネーブル |
| i_ck_en | input | logic | |
| i_cs_n | input | logic | |
| i_reset_n | input | logic | |
| i_dq_a | input | logic<8> | |
| i_dq_b | input | logic<8> | |
| i_dq_oe | input | logic | |
| i_rwds_a | input | logic | |
| i_rwds_b | input | logic | |
| i_rwds_oe | input | logic | |
| o_dq_a | output | logic<8> | |
| o_dq_b | output | logic<8> | |
| o_rwds_a | output | logic | |
| o_rwds_b | output | logic | |
| o_pad_ck | output | logic | |
| o_pad_ck_n | output | logic | |
| o_pad_cs_n | output | logic | |
| o_pad_reset_n | output | logic | |
| io_pad_dq | inout | trilogic<8> | |
| io_pad_rwds | inout | trilogic |
PsramPhySdrCore
PsramPhySdrCore
PSRAM SDR fallback 物理層 (docs/psram.md「SDR fallback phy」)
IOLOGIC (ODDR/IDDR) を一切使わず,ファブリック FF のみで HyperBus を 駆動する低速 phy.L4 切り分け (IOLOGIC bitstream 実挙動の疑い) と 動作実績のあるビットバング方式 (spike 段 1,CK 6.75 MHz) の一般化を 兼ねる.PsramPhy と同一の FSM 側 SDR インタフェースを持ち, PsramCtrl (i_en 付き) をそのまま接続できる.
1 SDR サイクル (= 1 CK) を i_clk の 4 位相で構成する (i_clk 27 MHz → CK 6.75 MHz).FSM は o_en (位相 3) のサイクルのみ状態更新し, FSM 出力は位相 0..3 の間安定している:
- 位相 0→1 エッジ: CS#/RESET#/byte A/OE をパッド FF へロード
- 位相 1→2 エッジ: CK 立上り (i_ck_en=1 のとき).byte A に対し 90° 遅れ
- 位相 2→3 エッジ: byte B をロード + リード byte A 取り込み + FSM への提示
- 位相 3→0 エッジ: CK 立下り.byte B に対し 90° 遅れ
リード取り込みは CK エッジの 1 位相 (37 ns) 後に平 FF でサンプルする (RAM の tCKD 後で安定).FSM へは 1 SDR サイクル遅れで (A, B) ペアを 提示する (PsramCtrl のペア検出は遅延不変).
コア (PsramPhySdrCore, プリミティブなし・L1 テスト可) と IOBUF ラッパ (PsramPhySdr) に分割する.
Ports
| i_clk | input | clock | |
|---|---|---|---|
| i_rst | input | reset | |
| o_en | output | logic | FSM 状態更新イネーブル (位相 3 で 1) |
| i_ck_en | input | logic | CK 駆動 (1 で 1 CK パルス) |
| i_cs_n | input | logic | CS# |
| i_reset_n | input | logic | RESET# |
| i_dq_a | input | logic<8> | DQ 送出 byte A (CK 立上り側) |
| i_dq_b | input | logic<8> | DQ 送出 byte B (CK 立下り側) |
| i_dq_oe | input | logic | DQ 出力イネーブル |
| i_rwds_a | input | logic | RWDS 送出 A (ライトマスク) |
| i_rwds_b | input | logic | RWDS 送出 B |
| i_rwds_oe | input | logic | RWDS 出力イネーブル |
| o_dq_a | output | logic<8> | DQ 取り込み (立上り) |
| o_dq_b | output | logic<8> | DQ 取り込み (立下り) |
| o_rwds_a | output | logic | RWDS 取り込み (立上り) |
| o_rwds_b | output | logic | RWDS 取り込み (立下り) |
| o_ck | output | logic | |
| o_ck_n | output | logic | |
| o_cs_n | output | logic | |
| o_reset_n | output | logic | |
| o_dq | output | logic<8> | |
| o_dq_oe | output | logic | |
| i_dq | input | logic<8> | |
| o_rwds | output | logic | |
| o_rwds_oe | output | logic | |
| i_rwds | input | logic |
PsramSpikeBitbang
PsramSpikeBitbang
PSRAM spike 段1: bit-bang レジスタ読み出し (docs/psram.md「spikeの構成」)
PLL・DDR プリミティブを使わず 27 MHz ロジックのみで CK = 27/4 = 6.75 MHz を
生成し,ch0 の IR0/IR1/CR0 を読み出して結果を ASCII 1 行の stream として
送出する (PSRAM IR0=xxxx IR1=xxxx CR0=xxxx L=xx W=x).
CK 位相 (1 CK = 4 サイクル,phase 0..3).CK エッジがデータ遷移から 1 サイクル遅れ,構成的に 90° 相当の関係になる:
リード側は POR デフォルト (固定 2x レイテンシ) 前提で CR0 を書かず, RWDS のエッジ検出で自己同期してデータ語を取り込む (レイテンシ実測値は L=xx として報告し,L1 モデル/データシート解釈の照合に使う). 実機結果 (2026-07-22): IR0=005F / IR1=000F / CR0=8F1F / L=0B / W=1.
Parameters
| ResetPulseCycles | u32 | リセットパルス幅 [cyc] (tRP = 200 ns min → 27 MHz で 8 cyc = 296 ns) |
|---|---|---|
| TvcsCycles | u32 | RESET# 解除後の待機 [cyc] (tVCS = 150 µs min → 200 µs 相当を既定とする) |
Ports
| i_clk | input | clock | クロック (27 MHz) |
|---|---|---|---|
| i_rst | input | reset | リセット |
| o_ck | output | logic | CK 出力 (6.75 MHz) |
| o_cs_n | output | logic | CS# 出力 |
| o_reset_n | output | logic | RESET# 出力 |
| o_dq | output | logic<8> | DQ 出力 (CA) |
| o_dq_oe | output | logic | DQ 出力イネーブル |
| i_dq | input | logic<8> | DQ 入力 (リードデータ) |
| i_rwds | input | logic | RWDS 入力 (データ検出に使用) |
| msg | modport | stream_if source | 結果メッセージ (リセット毎に 1 行送出) |
PsramSubsystem
PsramSubsystem
PSRAM サブシステム一式 (docs/psram.md)
rPLL・SDR phy・コントローラ FSM・AXI4-Lite ブリッジと,内蔵パッド (マジックポート) の配線をまとめたもの.利用側は AXI4-Lite スレーブ端子だけを 見ればよい.
- phy は PsramPhySdr (ファブリック FF 駆動,IOLOGIC 不使用) を clk_mem (rPLL 54 MHz) で駆動し,CK 13.5 MHz を得る (apicula ODDR の実挙動により DDR phy は保留中.docs/psram.md「apicula ODDR 実挙動の調査」)
- ctrl は phy の位相イネーブル ps_en (1/4 レート) で歩調を合わせ, ブリッジの mem 側へ渡す o_req_ready / o_rsp_valid は ps_en で修飾する (非イネーブルサイクルでの取りこぼし・二重送信防止.ctrl.veryl 参照)
- リセットは全ドメインで共有する (デアサート後は各 FSM が RESET# パルス / tVCS 待機で吸収する)
- ch1 は未使用.CS#/RESET# を非アクティブ固定にし,パッドは入力で終端する
Clock Domains
| 'mem |
|---|
Ports
| i_clk | input | clock | AXI 側クロック (27 MHz) | |
|---|---|---|---|---|
| i_rst | input | reset | リセット | |
| s_axi | modport | $std __axi4_lite_if__$std___axi4_lite_pkg__22__4__1 slave | AXI4-Lite スレーブ | |
| o_clk_mem | output | 'mem | clock | clk_mem (54 MHz,診断回路用) |
| o_init_done | output | logic | 初期化完了 (mem 域の値をそのまま出す) | |
| o_init_ok | output | logic | IR0 照合結果 | |
| o_pll_lock | output | logic | rPLL lock | |
| O_psram_ck | output | logic<2> | PSRAM CK (ch1:ch0) | |
| O_psram_ck_n | output | logic<2> | PSRAM CK# (差動) | |
| O_psram_cs_n | output | logic<2> | PSRAM CS# | |
| O_psram_reset_n | output | logic<2> | PSRAM RESET# | |
| IO_psram_dq | inout | trilogic<16> | PSRAM DQ (ch0=下位8bit) | |
| IO_psram_rwds | inout | trilogic<2> | PSRAM RWDS (ch0=bit0) |
RvAlu
RvAlu
RV32I の ALU (docs/riscv.md「マイクロアーキテクチャ」)
組合せ回路.シフト量は第 2 入力の下位 5 bit を使う (RV32 では SLL/SRL/SRA・SLLI/SRLI/SRAI とも shamt は 5 bit).
符号付き比較 (SLT) は符号ビットが異なる場合に第 1 入力の符号ビットが そのまま答えになる性質を使い,符号が同じ場合のみ符号なし比較へ帰着させる. 算術右シフト (SRA) は符号ビットで 64 bit へ拡張してから論理右シフトし, 下位 32 bit を採る.
Ports
| i_op | input | RvPkg AluOp | 演算種別 |
|---|---|---|---|
| i_a | input | logic<32> | 第 1 入力 |
| i_b | input | logic<32> | 第 2 入力 |
| o_y | output | logic<32> | 結果 |
RvAxiMaster
RvAxiMaster
コアの簡易メモリプロトコルを AXI4-Lite マスタへ変換する (docs/riscv.md「メモリマップ」)
コア側は RvMem / RvMmio と同じ握手(i_valid を上げ,完了サイクルに
o_done が 1).AXI 側は単一アウトスタンディングで,
ライトは AW と W を同時に出して B 応答で完了,リードは AR を出して
R 応答で完了とする.
アドレスは下位 AddrW bit のみを AXI へ渡す(窓内オフセット).
完了後は wait_low で i_valid が下がるのを待つ.コアは o_done を見てから
次サイクルに i_valid を下ろすため,これがないと同じ要求を 2 回発行してしまう
(RvMem は accept = i_valid && !pending で同じ効果を得ている).
Parameters
| AddrW | u32 | AXI 側のアドレス幅(PSRAM ch0 は 22 bit = 4 MB) |
|---|
Ports
| i_clk | input | clock | クロック |
|---|---|---|---|
| i_rst | input | reset | リセット |
| i_valid | input | logic | アクセス要求 |
| i_addr | input | logic<32> | バイトアドレス |
| i_write | input | logic | 1 でストア |
| i_wdata | input | logic<32> | ストアデータ |
| i_wstrb | input | logic<4> | バイトイネーブル |
| o_done | output | logic | 完了(1 サイクル) |
| o_rdata | output | logic<32> | リードデータ |
| m_axi | modport | $std __axi4_lite_if__$std___axi4_lite_pkg__22__4__1 master | AXI4-Lite マスタ |
RvCore
RvCore
RV32I 多サイクルコア (docs/riscv.md「マイクロアーキテクチャ」)
1 命令を fetch → exec(→ mem)で処理する非パイプライン実装. メモリが律速(PSRAM 実効 2.25 MB/s = 約 0.56 MIPS)でパイプライン化の 利得が小さく,面積が最小で,1 命令 = 1 トランザクション境界という性質が L1 検証を単純にする.
stateDiagram-v2
[*] --> fetch
fetch --> rdreg: 命令語受領
rdreg --> exec: レジスタ読み出し確定
exec --> memacc: load / store
exec --> mdwait: 乗除算 (M 拡張)
exec --> fetch: それ以外(分岐・ジャンプ・MRET 含む)
memacc --> fetch: 完了
mdwait --> fetch: 完了
rdreg はレジスタファイルの読み出しレイテンシ(1 サイクル)を吸収する
ための待ち状態.レジスタファイルをメモリマクロへ寄せて LUT を削った
代償だが,多サイクル実行なので状態を 1 つ足すだけで済む
(パイプラインならフォワーディングの再設計が要る.docs/riscv.md).
分岐条件の比較はコア内の専用比較器で行う(ALU は分岐先アドレスの 計算に使うため).JALR の分岐先は仕様どおり最下位ビットを 0 にする.
トラップ(不正命令・ECALL・EBREAK・ロード/ストアの非整列・命令フェッチの
非整列・タイマ割り込み)は,どの状態からでも実行を打ち切って mtvec へ飛ぶ.
mepc / mcause / mtval の退避と mstatus の更新は RvCsr 側で行う.
割り込みは命令境界(フェッチ開始前)でのみ受理する.
o_illegal は不正命令例外を 1 度でも起こしたことを示す診断用の粘着フラグ.
Parameters
| ResetPc | u32 | リセット後の開始アドレス |
|---|
Ports
| i_clk | input | clock | クロック |
|---|---|---|---|
| i_rst | input | reset | リセット |
| o_mem_valid | output | logic | アクセス要求 |
| o_mem_addr | output | logic<32> | バイトアドレス |
| o_mem_write | output | logic | 1 でストア |
| o_mem_wdata | output | logic<32> | ストアデータ(整列済み) |
| o_mem_wstrb | output | logic<4> | バイトイネーブル |
| i_mem_done | input | logic | 完了 |
| i_mem_rdata | input | logic<32> | リードデータ |
| i_timer_irq | input | logic | CLINT からのタイマ割り込み |
| o_pc | output | logic<32> | 現在の PC(観測用) |
| o_trap | output | logic | トラップ受理(1 サイクル.観測用) |
| o_cause | output | logic<32> | 受理したトラップの原因(観測用) |
| o_illegal | output | logic | 不正命令例外を 1 度でも起こした(診断用) |
RvCsr
RvCsr
M モードの CSR ファイルとトラップ制御 (docs/riscv.md「ISA スコープ」)
実装するのは M モードのみ.S/U モード・PMP・デバッグトリガは持たない.
| 番号 | 名前 | 実装範囲 |
|---|---|---|
| 0x300 | mstatus | MIE(3) / MPIE(7) のみ.MPP は 11 固定 |
| 0x301 | misa | 読み出し専用.MXL=1, I, M |
| 0x304 | mie | MTIE(7) のみ |
| 0x305 | mtvec | direct モードのみ (下位 2 bit は 0 固定) |
| 0x340 | mscratch | 全 32 bit |
| 0x341 | mepc | 下位 2 bit は 0 固定 |
| 0x342 | mcause | 全 32 bit |
| 0x343 | mtval | 全 32 bit |
| 0x344 | mip | MTIP(7) は読み出し専用 (タイマから) |
| 0xF11-0xF14 | mvendorid/marchid/mimpid/mhartid | 読み出し 0 |
未実装 CSR へのアクセスと,読み出し専用 CSR への書き込みは
o_illegal を立てる (コア側が不正命令例外にする).
Ports
| i_clk | input | clock | クロック |
|---|---|---|---|
| i_rst | input | reset | リセット |
| i_valid | input | logic | CSR 命令を実行する |
| i_addr | input | logic<12> | CSR 番号 |
| i_op | input | logic<2> | 01=RW / 10=RS / 11=RC |
| i_wdata | input | logic<32> | 書き込み値 (rs1 または uimm) |
| i_wen | input | logic | 書き込みを行う (RW,または rs1/uimm != 0) |
| o_rdata | output | logic<32> | 読み出し値 |
| o_illegal | output | logic | 未実装 CSR / 読み出し専用への書き込み |
| i_trap | input | logic | トラップ発生 |
| i_trap_cause | input | logic<32> | mcause へ書く値 |
| i_trap_pc | input | logic<32> | mepc へ書く値 |
| i_trap_tval | input | logic<32> | mtval へ書く値 |
| i_mret | input | logic | MRET 実行 |
| o_tvec | output | logic<32> | トラップベクタ (mtvec) |
| o_epc | output | logic<32> | 復帰先 (mepc) |
| i_timer_irq | input | logic | CLINT からのタイマ割り込み |
| o_irq_pending | output | logic | 受理可能な割り込みがある |
RvDecoder
RvDecoder
RV32I 命令デコーダ (docs/riscv.md「ISA スコープ」)
命令語を制御信号と符号拡張済み即値へ変換する組合せ回路. 符号は RISC-V Instruction Set Manual の RV32I 基本整数命令セットの表に従う (docs/riscv.md 一次資料表).
即値の形式:
| 形式 | 構成 |
|---|---|
| I | sext(inst[31:20]) |
| S | sext({inst[31:25], inst[11:7]}) |
| B | sext({inst[31], inst[7], inst[30:25], inst[11:8], 1’b0}) |
| U | {inst[31:12], 12’b0} |
| J | sext({inst[31], inst[19:12], inst[20], inst[30:21], 1’b0}) |
OP かつ funct7=0000001 は M 拡張 (乗除算) として muldiv を立て,
種別を md_op (funct3) で渡す.
FENCE (MISC-MEM) は本コアではメモリ順序の並べ替えを行わないため NOP として 受理する.SYSTEM は funct3=000 のとき ECALL / EBREAK / MRET, それ以外 (100 を除く) を Zicsr の CSR 命令として受理する.
Ports
| i_inst | input | logic<32> | 命令語 |
|---|---|---|---|
| o_dec | output | RvPkg Decoded | デコード結果 |
RvMem
RvMem
RvCore 用のワードメモリ (docs/riscv.md「メモリマップ」)
32 bit ワード x Words.バイトイネーブル付きで,SB / SH のために
8 bit 幅の RAM を 4 面並べる($std::ram はバイトイネーブルを持たないため).
レイテンシは 1 サイクル(BUFFER_OUT: true で BSRAM の登録読み出しになる)。
プロトコル:
- コアが
i_validを上げ,アドレス等を保持する - メモリは受理した次のサイクルに
o_doneを 1 サイクル上げ, リードならこのときo_rdataが有効 - コアは
o_doneでi_validを下ろす(同一サイクルに次の要求は出さない)
i_dbg_* はテストベンチからの直接書き込み(プログラムのプリロード)用で,
合成時は 0 固定にする.i_dbg_we の間はコアの要求を受け付けないため,
コアはリセット解除後でも o_done 待ちで停止したままプリロードできる.
Parameters
| Words | u32 | 語数(32 bit ワード) |
|---|
Ports
| i_clk | input | clock | クロック |
|---|---|---|---|
| i_rst | input | reset | リセット |
| i_valid | input | logic | アクセス要求 |
| i_addr | input | logic<32> | バイトアドレス |
| i_write | input | logic | 1 でストア |
| i_wdata | input | logic<32> | ストアデータ(バイトレーンへ整列済み) |
| i_wstrb | input | logic<4> | バイトイネーブル |
| o_done | output | logic | 完了(1 サイクル) |
| o_rdata | output | logic<32> | リードデータ(o_done のサイクルで有効) |
| i_dbg_we | input | logic | テストベンチからの直接書き込み |
| i_dbg_word | input | logic<32> | 書き込むワード番号 |
| i_dbg_wdata | input | logic<32> | 書き込むデータ |
RvMmio
RvMmio
RvCore のメモリマップドペリフェラル (docs/riscv.md「メモリマップ」)
レイテンシと握手は RvMem と同じ(要求の次サイクルに o_done).
| オフセット | 幅 | 動作 |
|---|---|---|
0x00 TOHOST | W | 終了通知.o_tohost_valid を 1 サイクル上げ値を出す(riscv-tests と同じ規約) |
0x10 UART | W | 下位 8 bit を UART TX へ送出する |
0x10 UART | R | bit0 = 送信可(0 なら前のバイトが未送出) |
0x14 UART RX | R | bit8 = 受信あり,bit7-0 = データ.読むと 1 バイト消費する |
0x20 LED | W | 下位 6 bit を LED へ(極性は Top 側で扱う) |
0x30 MTIME_LO | R | 自走カウンタ(クロック毎に +1)の下位 32 bit |
0x34 MTIME_HI | R | 同上位 32 bit |
0x38 MTIMECMP_LO | R/W | 比較値の下位 32 bit |
0x3C MTIMECMP_HI | R/W | 同上位 32 bit |
0x50 TF_CTRL | W | bit0 = 開始,bit1 = 方向(0 = リード,1 = ライト) |
0x50 TF_CTRL | R | 状態語(bit0 busy / bit1 init_done / bit4:2 init_err / bit7:5 err / bit8 rx_valid / bit9 tx_space) |
0x54 TF_LBA | R/W | 入出力する論理ブロックアドレス |
0x58 TF_DATA | R | bit8 = 受信あり,bit7:0 = 受信データ.読むと 1 バイト消費する |
0x58 TF_DATA | W | 下位 8 bit をライトデータとして送出する |
タイマ割り込みは mtime >= mtimecmp で o_timer_irq を上げる(CLINT 相当).
mtimecmp はリセット時に全 1 とし,設定するまで割り込まない.
UART は 1 バイトのバッファのみ持つ.ソフトウェアは送信前に
0x10 を読んで bit0 が 1 であることを確認する.
Ports
| i_clk | input | clock | クロック |
|---|---|---|---|
| i_rst | input | reset | リセット |
| i_valid | input | logic | アクセス要求 |
| i_addr | input | logic<32> | バイトアドレス |
| i_write | input | logic | 1 でストア |
| i_wdata | input | logic<32> | ストアデータ |
| o_done | output | logic | 完了(1 サイクル) |
| o_rdata | output | logic<32> | リードデータ |
| tx | modport | stream_if source | UART TX へ |
| rx | modport | stream_if sink | UART RX から |
| o_leds | output | logic<6> | LED(active-high.Top で反転する) |
| o_tohost_valid | output | logic | 終了通知 |
| o_tohost | output | logic<32> | 終了コード |
| o_timer_irq | output | logic | タイマ割り込み(mtime >= mtimecmp) |
| o_tf_start | output | logic | TF セクタ入出力開始(1 サイクルパルス) |
| o_tf_wr | output | logic | TF の方向(0 = リード,1 = ライト) |
| o_tf_lba | output | logic<32> | TF の読み出し LBA |
| i_tf_status | input | logic<32> | TF の状態語 |
| o_tf_rx_pop | output | logic | TF 受信バイト消費(1 サイクルパルス) |
| i_tf_rx_data | input | logic<8> | TF 受信バイト |
| i_tf_rx_valid | input | logic | TF 受信バイトあり |
| o_tf_tx_push | output | logic | TF 送信バイト追加(1 サイクルパルス) |
| o_tf_tx_data | output | logic<8> | TF 送信バイト |
| i_tf_tx_space | input | logic | TF 送信 buffer に空きがある |
RvMulDiv
RvMulDiv
RV32M の乗除算ユニット (docs/riscv.md「ISA スコープ」)
i_start の 1 サイクルパルスで起動し,完了サイクルに o_done を 1 にする.
多サイクルコアから見ると RvMem と同じ「要求 → 完了」の形になる.
- 乗算は 1 サイクル.符号付き / 符号なしの組み合わせは絶対値を取ってから 符号なし乗算し,結果の符号を戻す(MULHSU があるため被乗数と乗数で 符号の扱いが異なる)
- 除算は復元法で 32 反復.ハードウェア除算器は持たない
ゼロ除算とオーバフローの扱いは RISC-V 仕様に従う.
| 条件 | DIV | DIVU | REM | REMU |
|---|---|---|---|---|
| 除数 0 | -1 | 2^32-1 | 被除数 | 被除数 |
| -2^31 / -1 | -2^31 | — | 0 | — |
Ports
| i_clk | input | clock | クロック |
|---|---|---|---|
| i_rst | input | reset | リセット |
| i_start | input | logic | 起動 (1 サイクルパルス) |
| i_funct3 | input | logic<3> | 命令の funct3 |
| i_a | input | logic<32> | rs1 |
| i_b | input | logic<32> | rs2 |
| o_result | output | logic<32> | 結果 |
| o_done | output | logic | 完了 (1 サイクル) |
RvRegFile
RvRegFile
RV32I のレジスタファイル (docs/riscv.md「マイクロアーキテクチャ」)
32 x 32 bit.読み出し 2 ポート・書き込み 1 ポート.
読み出しは 1 サイクル遅れる(i_rs1 / i_rs2 を与えた次のサイクルに
o_rd1 / o_rd2 が確定する).RvCore はこのために rdreg 状態を持つ.
実装は $std::ram を 2 面(読み出しポートごとに 1 面)で,書き込みは
両面へ同じ内容を行う.フリップフロップ + マルチプレクサで作ると
32:1 x 32 bit のマルチプレクサが 2 組必要になり LUT を大きく食うため
(実測でコア全体の LUT の大半を占めていた.docs/riscv.md「資源」),
メモリマクロへ寄せて論理を削る.
x0 は読み出し 0 固定・書き込み無効(RV32I のレジスタ定義). x0 のエントリは書かれないため RAM 上の値は不定だが,読み出し側で 定数 0 に置き換えるため観測されない.
Ports
| i_clk | input | clock | クロック |
|---|---|---|---|
| i_rst | input | reset | リセット |
| i_rs1 | input | logic<5> | 読み出しレジスタ番号 1 |
| o_rd1 | output | logic<32> | 読み出し値 1(1 サイクル遅れ) |
| i_rs2 | input | logic<5> | 読み出しレジスタ番号 2 |
| o_rd2 | output | logic<32> | 読み出し値 2(1 サイクル遅れ) |
| i_we | input | logic | 書き込みイネーブル |
| i_rd | input | logic<5> | 書き込み先レジスタ番号 |
| i_wdata | input | logic<32> | 書き込みデータ |
RvRom
RvRom
ソフトコアのブート ROM (docs/riscv.md「ブートフロー」)
RvBootRom(scripts/gen_riscv_boot.py が software/hello.S から生成)を
登録読み出しで返す.握手は RvMem と同じで,要求の次サイクルに o_done.
case 式の ROM は yosys が BSRAM へ推論する(FontRom と同じ方式).
Ports
| i_clk | input | clock | クロック |
|---|---|---|---|
| i_rst | input | reset | リセット |
| i_valid | input | logic | アクセス要求 |
| i_addr | input | logic<32> | バイトアドレス |
| o_done | output | logic | 完了(1 サイクル) |
| o_rdata | output | logic<32> | リードデータ |
RvSoc
RvSoc
RV32I ソフトコアの SoC (docs/riscv.md「メモリマップ」)
コア・ブート ROM・データ RAM・MMIO をアドレスデコードで束ねる.
| 範囲 | 内容 |
|---|---|
0x0000_0000–0x0000_1FFF | ブート ROM(8 KB 相当,リードのみ) |
0x0000_2000–0x0000_3FFF | データ RAM(RamWords x 4 byte,最大 8 KB) |
0x1000_0000–0x103F_FFFF | PSRAM ch0(AXI4-Lite マスタとして外へ出す) |
0x2000_0000–0x2000_0FFF | MMIO レジスタ(UART / LED / TOHOST / タイマ / TF) |
デコードは addr[29] で MMIO,addr[28] で PSRAM,
残りを addr[13] で ROM / RAM に分ける.
コアは完了まで o_mem_addr を保持するため,組合せデコードで足りる.
PSRAM サブシステム本体(PLL / phy / ctrl / ブリッジ)はクロックドメインが 異なるため SoC の外に置き,ここでは AXI4-Lite マスタ端子だけを出す.
Parameters
| RamWords | u32 | データ RAM の語数(`addr[13]` で選ぶので最大 2048 語 = 8 KB) |
|---|---|---|
| TfInitDivider | u32 | TF カードの初期化クロック分周比(`TfCtrl` へ渡す.テストで短縮する) |
Ports
| i_clk | input | clock | クロック |
|---|---|---|---|
| i_rst | input | reset | リセット |
| tx | modport | stream_if source | UART TX へ |
| rx | modport | stream_if sink | UART RX から |
| m_psram | modport | $std __axi4_lite_if__$std___axi4_lite_pkg__22__4__1 master | PSRAM へ(AXI4-Lite) |
| o_leds | output | logic<6> | LED(active-high) |
| o_tohost_valid | output | logic | 終了通知 |
| o_tohost | output | logic<32> | 終了コード |
| o_pc | output | logic<32> | 現在の PC(観測用) |
| o_trap | output | logic | トラップ受理(観測用) |
| o_cause | output | logic<32> | トラップ原因(観測用) |
| o_illegal | output | logic | 不正命令例外を起こした(診断用) |
| o_tf_sclk | output | logic | TF SCK |
| o_tf_mosi | output | logic | TF MOSI |
| o_tf_cs_n | output | logic | TF CS# |
| i_tf_miso | input | logic | TF MISO |
RvTfIo
RvTfIo
TF カードの byte-stream 入出力(RvCore の周辺機器. docs/riscv.md「TF カードからのブート」)
TfCtrl と MMIO の間に送受信それぞれ 1 byte のバッファを置く.
ソフトウェアは TF_CTRL の rx_valid / tx_space をポーリングし,
TF_DATA で 512 byte を直接受け渡す.TfCtrl は stream の
handshake 待ちで SCK を停止するため,CPU に実時間制約はない.
セクタ全体の RAM と word/byte 変換を持たないため,
RvTfSector より LUT と BSRAM の使用量が少ない.
Parameters
| InitDivider | u32 | 初期化クロック分周比(`TfCtrl` へそのまま渡す.テストで短縮する) |
|---|
Ports
| i_clk | input | clock | クロック |
|---|---|---|---|
| i_rst | input | reset | リセット |
| i_start | input | logic | 1 サイクルパルス.セクタ入出力を開始する |
| i_wr | input | logic | 0 = リード,1 = ライト(i_start と同時に見る) |
| i_lba | input | logic<32> | 対象の論理ブロックアドレス |
| o_status | output | logic<32> | bit0 busy / bit1 init_done / bit4:2 init_err / bit7:5 err / bit8 rx_valid / bit9 tx_space |
| i_rx_pop | input | logic | 受信バイトを消費する(1 サイクルパルス) |
| o_rx_data | output | logic<8> | 受信バイト |
| o_rx_valid | output | logic | 受信バイトあり |
| i_tx_push | input | logic | 送信バイトを追加する(1 サイクルパルス) |
| i_tx_data | input | logic<8> | 送信バイト |
| o_tx_space | output | logic | 送信バッファに空きがある |
| o_sclk | output | logic | TF SCK |
| o_mosi | output | logic | TF MOSI |
| o_cs_n | output | logic | TF CS# |
| i_miso | input | logic | TF MISO |
SpiMaster
SpiMaster
SPI マスタ (mode 0,バイト単位転送,MSB first)
TF カード用: SCK idle Low,立上りでサンプル,立下りでシフト. バイト転送は valid/ready で受け付け,受信バイトは o_valid の 1 サイクルパルスで確定する.CS# は上位 (シーケンサ) が管理する. 分周比は転送開始時の i_fast で選択する (初期化 337.5 kHz / データ 13.5 MHz, docs/tfcard.md「クロック・SCK」).
Parameters
| InitDivider | u32 | 初期化クロック分周比 (SCK = i_clk / InitDivider).2 以上の偶数 |
|---|---|---|
| FastDivider | u32 | データ転送クロック分周比.2 以上の偶数かつ InitDivider 以下 |
Ports
| i_clk | input | clock | クロック (27 MHz) |
|---|---|---|---|
| i_rst | input | reset | リセット |
| i_fast | input | logic | 1 で FastDivider を選択 (転送開始時に参照) |
| i_valid | input | logic | 送信バイト有効 |
| i_data | input | logic<8> | 送信バイト |
| o_ready | output | logic | 送信バイト受付可能 |
| o_valid | output | logic | 受信バイト確定 (1 サイクルパルス) |
| o_data | output | logic<8> | 受信バイト |
| o_sclk | output | logic | SPI SCK (idle Low) |
| o_mosi | output | logic | SPI MOSI (idle High) |
| i_miso | input | logic | SPI MISO |
TextConsole
TextConsole
テキストコンソール
受信した文字をカーソル位置へ書き込み,VideoTiming の座標に同期して 文字ピクセルを描画する.text RAM (std::ram) + FontRom の 2 段読み出しに 合わせ,de/sync を 2 サイクル遅延して出力する.
flowchart LR
CH["文字入力"] --> WR["書き込みFSM<br>カーソル/スクロール"]
WR --> RAM["text RAM<br>(std::ram)"]
POS["VideoTiming座標"] --> RAM
RAM --> FONT["FontRom 8x16"]
FONT --> PX["ピクセル出力<br>(2段パイプライン)"]
文字セマンティクス:
- 0x20-0x7E: カーソル位置へ表示しカーソル前進 (右端で折り返し)
- LF (0x0A): 改行 (行頭復帰 + 行送り)
- CR (0x0D): 行頭復帰
- FF (0x0C): カーソルを左上へ戻す (スクロール位置も先頭へ戻す.画面は消さない)
- その他: 無視
FF は全画面を毎フレーム上書きするアニメーション用途のためにある. 消去を伴わないのは,消去中 (CellCount サイクル) の文字入力が無視され, UART のバイト間隔より長くなって取りこぼすため.送り手が各行を桁数ぶん 埋める前提で,残像が出ないようにする.
最下行での行送りはリングバッファ的に 1 行スクロールする (base_row 前進 + 新最下行のクリア).クリア中 (Cols サイクル) の文字入力は無視されるが, UART のバイト間隔 (115200bps で約 2300 サイクル) より十分短いため実害はない.
Parameters
| Cols | u32 | 桁数 |
|---|---|---|
| Rows | u32 | 行数 |
Ports
| i_clk | input | clock | クロック |
|---|---|---|---|
| i_rst | input | reset | リセット |
| i_char_valid | input | logic | 文字入力有効 |
| i_char | input | logic<8> | 文字コード (ASCII) |
| i_de | input | logic | データイネーブル入力 |
| i_hsync | input | logic | 水平同期入力 |
| i_vsync | input | logic | 垂直同期入力 |
| i_pos_x | input | logic<10> | 画素 X 座標 |
| i_pos_y | input | logic<9> | 画素 Y 座標 |
| o_de | output | logic | データイネーブル出力 |
| o_hsync | output | logic | 水平同期出力 |
| o_vsync | output | logic | 垂直同期出力 |
| o_pixel | output | logic | 文字前景=1 |
TfCtrl
TfCtrl
TF カードブロック入出力コントローラ v2 (docs/tfcard.md「プロトコル仕様」)
リセット後に自動で初期化シーケンス (CMD0 → CMD8 → CMD55/ACMD41 ポーリング → CMD58) を実行し,完了後は要求 IF (valid/ready + LBA + write) で CMD17 単発リード / CMD24 単発ライトを受け付ける. 512 バイトを stream_if でやりとりし,CRC16 を検査 (リード) または 付与 (ライト) して完了時にエラー種別を報告する.
- 発行コマンドは CMD0/CMD8/CMD55/ACMD41/CMD58/CMD17/CMD24 のみ. erase 系・マルチブロック系は FSM 上存在しない
- ライトは「トークン 0xFE → 512 バイト → CRC16 → データ応答 → ビジー解除待ち」 の順に進む.データ応答は下位 5 bit で判定する (00101 = 受理,01011 = CRC 不一致,01101 = 書き込みエラー)
- バッファレス: データバイトは 1 バイトごとに stream の handshake を待ち, その間 SCK を停止する (SPI はマスタペースのため合法).BSRAM 面バッファは 不要 (docs/tfcard.md「インタフェース」)
- CCS=0 (バイトアドレッシング旧世代) は初期化時に unsupported として拒否する
- CRC 不一致はデータストリーム後の完了報告で通知する (リトライは利用側判断)
初期化失敗時は o_init_done が立たず o_init_err に種別が残る (復帰はリセット).
Parameters
| InitDivider | u32 | 初期化クロック分周比 (337.5 kHz) |
|---|---|---|
| FastDivider | u32 | データ転送クロック分周比 (13.5 MHz) |
| PowerUpBytes | u32 | 電源投入クロック供給のバイト数 (74 クロック以上 → 10 バイト = 80 クロック) |
| NcrMaxBytes | u32 | R1 応答待ちの上限バイト数 (NCR) |
| Acmd41MaxPolls | u32 | ACMD41 ポーリング上限回数 (337.5 kHz で約 1.2 s 相当) |
| TokenMaxBytes | u32 | データトークン待ちの上限バイト数 (13.5 MHz で約 155 ms 相当) |
| WriteBusyMaxBytes | u32 | CMD24 書き込み busy 待ちの上限 (13.5 MHz で約 267 ms 相当) |
Ports
| i_clk | input | clock | クロック (27 MHz) |
|---|---|---|---|
| i_rst | input | reset | リセット |
| i_req_valid | input | logic | ブロック入出力要求 |
| i_req_lba | input | logic<32> | 論理ブロックアドレス |
| i_req_write | input | logic | 1 でブロックライト (CMD24) |
| o_req_ready | output | logic | 要求受付可能 |
| o_init_done | output | logic | 初期化完了 |
| o_init_err | output | TfTypes Error | 初期化エラー (失敗時に latch) |
| o_done | output | logic | ブロック入出力完了 (1 サイクルパルス) |
| o_err | output | TfTypes Error | 完了時のエラー種別 (o_done で有効) |
| data | modport | stream_if source | リードデータ (512 バイト/ブロック) |
| i_wr_valid | input | logic | ライトデータ有効 |
| i_wr_data | input | logic<8> | ライトデータ |
| o_wr_ready | output | logic | ライトデータ受付 (1 サイクル) |
| o_sclk | output | logic | TF SCK |
| o_mosi | output | logic | TF MOSI |
| o_cs_n | output | logic | TF CS# |
| i_miso | input | logic | TF MISO |
TfImageDemo
TfImageDemo
TF カード画像表示デモ (docs/tfcard.md「画像表示デモ仕様」,パッチ #8)
ルート直下の IMAGE.BMP (既定.ReqName で変更可) を Fat32Reader から読み,
無圧縮 24 bpp BMP を解析して RGB565 へ変換し,
PSRAM のフレームバッファへ AXI4-Lite で書く.
結果は 1 行の ASCII で報告する.
報告行:
IMG OK: ロード成功 (以降 o_img_done=1.ImageScanout が表示を開始する)TF ERR <d>: TF カード初期化失敗 (d は TfTypes::Error の値)FS ERR <d>: FAT32 リーダのエラー (d は TfTypes::FsError の値)IMG ERR <d> <hhhh>: BMP が受理条件を満たさない (1=BM シグネチャ不一致 / 2=24 bpp・無圧縮でない / 3=寸法が SrcW x SrcH と 不一致 / 4=画素データが途中で終了).hhhhは診断値で, d=1 ならファイル先頭 2 バイト,d=2 なら biBitCount, d=3 なら実際の幅と高さの下位バイト (幅:高さ)
v1 は寸法を SrcW x SrcH 固定で要求する (部分展開によるフレームバッファの 未定義領域を作らないため).ボトムアップ (biHeight > 0) は書き込み行を 反転して PSRAM 上は常に上から下の順に格納する.
Parameters
| SrcW | u32 | ソース画像の幅 [px] (偶数.32 bit ワード = 2 px のため) |
|---|---|---|
| SrcH | u32 | ソース画像の高さ [px] |
| FbWordBase | u32 | フレームバッファ先頭のワード番号 (32 bit 単位) |
| MaxLen | u32 | ファイル読み出し要求長の上限 [byte] |
| ReqName | logic<88> | 対象ファイルの 8.3 名 11 バイト (既定 "IMAGE BMP"). ワイルドカード `'?'` (3Fh) も使えるが,拡張子だけの照合は 中身が BMP でない同名拡張子のファイルを拾いうるため既定では使わない |
Ports
| i_clk | input | clock | クロック |
|---|---|---|---|
| i_rst | input | reset | リセット |
| i_init_done | input | logic | 初期化完了 |
| i_init_err | input | TfTypes Error | 初期化エラー |
| o_req_valid | output | logic | ファイル読み出し要求 |
| o_req_name | output | logic<88> | 8.3 名 |
| o_req_offset | output | logic<32> | 開始オフセット |
| o_req_len | output | logic<32> | 読み出し長 |
| i_req_ready | input | logic | 要求受付可能 |
| i_done | input | logic | 完了パルス |
| i_err | input | TfTypes FsError | 完了時のエラー種別 |
| fdat | modport | stream_if sink | ファイル内容 (Fat32Reader から) |
| msg | modport | stream_if source | 報告行 (TX アービタへ) |
| m_axi | modport | $std __axi4_lite_if__$std___axi4_lite_pkg__22__4__1 master | PSRAM へのライト |
| o_img_done | output | logic | フレームバッファ展開完了 (表示可) |
TfSpikeInit
TfSpikeInit
TF カード初期化 spike (docs/tfcard.md「spike の構成」)
SpiMaster + 最小シーケンサで初期化シーケンス (CMD0 → CMD8 → CMD55/ACMD41 ポーリング → CMD58) を完走し,データクロックへ切り替えて CMD17 で セクタ 0 (MBR) を読む.結果は ASCII 1 行の stream として送出する:
TF R1=xx,xx,xx,xx OCR=xxxxxxxx S0=<先頭16バイトhex> SIG=K E=-
R1=は CMD0 / CMD8 / ACMD41 (最終) / CMD58 の R1 (未実行は FF)SIG=は MBR 署名 55AAh の検査 (K=一致 / N=不一致)E=はエラー段 (-なし /0CMD0 /8CMD8 非対応 /AACMD41 タイムアウト /CCCS=0 非対応 /RCMD17 応答・トークン異常 /Xデータ CRC16 不一致)
発行コマンドは CMD0/CMD8/CMD55/ACMD41/CMD58/CMD17 のみ (リード専用, write 系は FSM 上存在しない).
Parameters
| InitDivider | u32 | 初期化クロック分周比 (337.5 kHz) |
|---|---|---|
| FastDivider | u32 | データ転送クロック分周比 (13.5 MHz) |
| PowerUpBytes | u32 | 電源投入クロック供給のバイト数 (74 クロック以上 → 10 バイト = 80 クロック) |
| NcrMaxBytes | u32 | R1 応答待ちの上限バイト数 (NCR) |
| Acmd41MaxPolls | u32 | ACMD41 ポーリング上限回数 (337.5 kHz で約 1.2 s 相当) |
| TokenMaxBytes | u32 | データトークン待ちの上限バイト数 (13.5 MHz で約 155 ms 相当) |
Ports
| i_clk | input | clock | クロック (27 MHz) |
|---|---|---|---|
| i_rst | input | reset | リセット |
| o_sclk | output | logic | TF SCK |
| o_mosi | output | logic | TF MOSI |
| o_cs_n | output | logic | TF CS# |
| i_miso | input | logic | TF MISO |
| msg | modport | stream_if source | 結果メッセージ (リセット毎に 1 行送出) |
TfTextDemo
TfTextDemo
TF カードテキスト表示デモ (docs/tfcard.md パッチ #6)
TfCtrl の初期化結果を 1 行で報告した後,ルートディレクトリの最初の
*.TXT ファイル (8.3 名 "????????TXT") を Fat32Reader で開き,
内容を stream として送出する.Top の TX アービタ経由で UART へ流れ,
TextConsole の傍受により LCD にも表示される.
報告行:
TF OK: 初期化成功 (続けてファイル内容)TF ERR <d>: 初期化失敗 (d は TfTypes::Error の値: 2=timeout / 4=unsupported / 5=resp)FS ERR <d>: ファイル読み出し失敗 (d は TfTypes::FsError の値: 1=no_fs / 2=not_found / 3=io)
Parameters
| MaxLen | u32 | 読み出しバイト数の上限 (巨大ファイルのダンプ抑止) |
|---|
Ports
| i_clk | input | clock | クロック |
|---|---|---|---|
| i_rst | input | reset | リセット |
| i_init_done | input | logic | 初期化完了 |
| i_init_err | input | TfTypes Error | 初期化エラー |
| o_req_valid | output | logic | ファイル読み出し要求 |
| o_req_name | output | logic<88> | 8.3 名 |
| o_req_offset | output | logic<32> | 開始オフセット |
| o_req_len | output | logic<32> | 読み出し長 |
| i_req_ready | input | logic | 要求受付可能 |
| i_done | input | logic | 完了パルス |
| i_err | input | TfTypes FsError | 完了時のエラー種別 |
| fdat | modport | stream_if sink | ファイル内容 (Fat32Reader から) |
| msg | modport | stream_if source | 表示ストリーム (TX アービタへ) |
Top
Top
トップモジュール (Tang Nano 9K)
UART エコー + テキストコンソール (LCD) + PSRAM サブシステム
- TF カードテキスト表示デモ + LED 表示の統合.
flowchart LR
PC["PC (COMポート)"] -- uart_rx --> RX["Uart RX"]
RX -- "echo" --> ARB["TX arbiter<br>(memtest > TF > echo)"]
MT["PsramMemtest"] -- "結果1行" --> ARB
DEMO["TfImageDemo"] -- "報告行" --> ARB
FAT["Fat32Reader"] --> DEMO
TFC["TfCtrl"] --> FAT
ARB --> TX["Uart TX"] -- uart_tx --> PC
ARB -. "傍受" .-> CON["TextConsole"] --> LCD["5inch LCD"]
MT -- AXI4-Lite --> ARB2["PsramAxiArb2 x2"] --> PS["PsramSubsystem<br>(rPLL + bridge + ctrl + phy)"]
PS <--> RAM["内蔵 PSRAM ch0"]
DEMO -- "AXI4-Lite W" --> ARB2
SC["ImageScanout"] -- "AXI4-Lite R" --> ARB2
SC -- RGB565 --> LCD
TFC <--> TF["TF カード (SPI)"]
PSRAM サブシステム (phy/ctrl) は clk_mem (rPLL 54 MHz) ドメインで動作し, AXI 側 (memtest) とはブリッジ内 CdcHandshake で交差する. phy は SDR fallback (IOLOGIC 不使用.apicula ODDR の実挙動により DDR phy は 保留中.docs/psram.md「apicula ODDR 実挙動の調査」参照).
TX アービタは memtest > TF デモ > エコーの固定優先度とし,行の混在を避けるため TF デモは memtest の報告が完了してから起動する (下記 psram_msg_done). TF カードのブリングアップ時は TfSpikeInit (Top 非接続の spike) を 本デモ一式と差し替えて使う (docs/tfcard.md「spike の構成」).
LED 割当は docs/rtl.md,PSRAM サブシステムは docs/psram.md, TF カードサブシステムは docs/tfcard.md を参照.
Parameters
| OscFreq | u32 | オシレータ周波数 [Hz] |
|---|---|---|
| NumLeds | u32 | LED 数 |
Ports
| i_clk | input | clock | 27 MHz オシレータ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| i_rst | input | reset | S1 ボタン (active-low) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| leds | output | logic| LED (active-low,割当は rtl.md)
|
uart_tx |
output |
logic |
UART TX
|
uart_rx |
input |
logic |
UART RX
|
lcd_clk |
output |
logic |
LCD ピクセルクロック (反転出力)
|
lcd_de |
output |
logic |
LCD データイネーブル
|
lcd_hsync |
output |
logic |
LCD 水平同期 (負極性)
|
lcd_vsync |
output |
logic |
LCD 垂直同期 (負極性)
|
lcd_r |
output |
logic<5> |
LCD R (RGB565)
|
lcd_g |
output |
logic<6> |
LCD G (RGB565)
|
lcd_b |
output |
logic<5> |
LCD B (RGB565)
|
tf_sclk |
output |
logic |
TF SCK
|
tf_mosi |
output |
logic |
TF MOSI (CMD)
|
tf_cs_n |
output |
logic |
TF CS# (DAT3)
|
tf_miso |
input |
logic |
TF MISO (DAT0)
|
O_psram_ck |
output |
logic<2> |
PSRAM CK (ch1:ch0)
|
O_psram_ck_n |
output |
logic<2> |
PSRAM CK# (差動)
|
O_psram_cs_n |
output |
logic<2> |
PSRAM CS#
|
O_psram_reset_n |
output |
logic<2> |
PSRAM RESET#
|
IO_psram_dq |
inout |
trilogic<16> |
PSRAM DQ (ch0=下位8bit)
|
IO_psram_rwds |
inout |
trilogic<2> |
PSRAM RWDS (ch0=bit0)
|
|
TopRv
TopRv
RV32I ソフトコアのブリングアップ用トップ (docs/riscv.md パッチ計画 #6)
既存の Top(UART エコー + LCD + PSRAM + TF カード)とは別のビットストリームで, ソフトコアだけを動かす最小構成.LUT 予算の都合で両者は同居できないため, ペリフェラルをソフトウェアへ移すまでの間はこのトップで検証する (docs/riscv.md「残課題・リスク」の LUT 予算).
flowchart LR
ROM["RvBootRom<br>(software/hello.S)"] --> SOC
SOC["RvSoc<br>RvCore + ROM + RAM + MMIO"] -- "stream_if" --> TX["Uart TX"] -- uart_tx --> PC["PC (COMポート)"]
SOC -- "AXI4-Lite" --> PS["PsramSubsystem<br>rPLL + SDR phy + ctrl + bridge"] <--> RAM["内蔵 PSRAM ch0"]
TX -. "傍受 (valid && ready)" .-> CON["TextConsole"] --> LCD["5inch LCD"]
SOC --> LEDS["leds (active-low)"]
Parameters
| OscFreq | u32 | オシレータ周波数 [Hz] |
|---|---|---|
| NumLeds | u32 | LED 数 |
Ports
| i_clk | input | clock | 27 MHz オシレータ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| i_rst | input | reset | S1 ボタン (active-low) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| leds | output | logic| LED (active-low)
|
uart_tx |
output |
logic |
UART TX
|
uart_rx |
input |
logic |
UART RX (未使用.読み捨てる)
|
lcd_clk |
output |
logic |
LCD ピクセルクロック (反転出力)
|
lcd_de |
output |
logic |
LCD データイネーブル
|
lcd_hsync |
output |
logic |
LCD 水平同期 (負極性)
|
lcd_vsync |
output |
logic |
LCD 垂直同期 (負極性)
|
lcd_r |
output |
logic<5> |
LCD R (RGB565)
|
lcd_g |
output |
logic<6> |
LCD G (RGB565)
|
lcd_b |
output |
logic<5> |
LCD B (RGB565)
|
O_psram_ck |
output |
logic<2> |
PSRAM CK (ch1:ch0)
|
O_psram_ck_n |
output |
logic<2> |
PSRAM CK# (差動)
|
O_psram_cs_n |
output |
logic<2> |
PSRAM CS#
|
O_psram_reset_n |
output |
logic<2> |
PSRAM RESET#
|
IO_psram_dq |
inout |
trilogic<16> |
PSRAM DQ (ch0=下位8bit)
|
IO_psram_rwds |
inout |
trilogic<2> |
PSRAM RWDS (ch0=bit0)
|
tf_sclk |
output |
logic |
TF SCK
|
tf_mosi |
output |
logic |
TF MOSI
|
tf_cs_n |
output |
logic |
TF CS#
|
tf_miso |
input |
logic |
TF MISO
|
|
Uart
Uart
UART 送受信 (8N1)
- TX:
tx_streamから 1 バイト受け取り LSB first で送出する - RX: 2FF 同期 + start bit 中央から 1 ビット周期ごとの中央サンプリング.
受信完了で即
validを立てて次フレームに備えるノンブロッキング供給 (未消費のまま次バイトが完了した場合は旧バイトを上書き)
Parameters
| InClkFreq | u32 | 入力クロック周波数 [Hz] |
|---|---|---|
| BaudRate | u32 | ボーレート [bps] |
Ports
| i_clk | input | clock | クロック |
|---|---|---|---|
| i_rst | input | reset | リセット |
| uart_tx | output | logic | TX ライン (idle High) |
| uart_rx | input | logic | RX ライン (非同期入力,内部で 2FF 同期) |
| tx_stream | modport | stream_if sink | 送信データ入力 |
| rx_stream | modport | stream_if source | 受信データ出力 (ノンブロッキング) |
VideoTiming
VideoTiming
RGB LCD (DEモード) タイミングジェネレータ
デフォルトタイミングは 5inch 800x480 パネル (050QG32-40) の datasheet “6.4 Timing Characteristics” から導出した pclk=27MHz 用の値:
- HSyncWidth=1 (thpw min),HBackPorch=46 (thb 固定値)
- VSyncWidth=3 (tvpw min),VBackPorch=23 (tvb 固定値)
- FrontPorch はライン長/フレーム長の選択からの逆算 (HTotal=890, VTotal=513)
- 27MHz / (890 * 513) = 59.1Hz refresh
sync 極性は負 (公式 Wiki rgb_screen: “enabled by negative polarity”).
本モジュールはタイミングと座標の生成のみを担う.画素合成 (色のゲートや フォーマット変換) は利用側で行い,パイプライン段数に応じて de/sync を 遅延させて位相を合わせること.
Parameters
| Width | u32 | 有効画素数 (水平) |
|---|---|---|
| Height | u32 | 有効画素数 (垂直) |
| HFrontPorch | u32 | 水平フロントポーチ [pclk] |
| HSyncWidth | u32 | 水平同期幅 [pclk] |
| HBackPorch | u32 | 水平バックポーチ [pclk] |
| VFrontPorch | u32 | 垂直フロントポーチ [line] |
| VSyncWidth | u32 | 垂直同期幅 [line] |
| VBackPorch | u32 | 垂直バックポーチ [line] |
Ports
| i_clk | input | clock | クロック (= pclk) |
|---|---|---|---|
| i_rst | input | reset | リセット |
| de | output | logic | データイネーブル |
| hsync | output | logic | 水平同期 (負極性) |
| vsync | output | logic | 垂直同期 (負極性) |
| frame | output | logic | Vブランキング先頭の1クロックパルス |
| pos_x | output | logic<$clog2(Width)> | 画素 X 座標 (de==1 で有効) |
| pos_y | output | logic<$clog2(Height)> | 画素 Y 座標 (de==1 で有効) |
Module Prototypes
Module Prototypes
Interfaces
Interfaces
| stream_if | valid/ready ハンドシェイクの汎用 stream interface |
|---|
stream_if
stream_if
valid/ready ハンドシェイクの汎用 stream interface
valid && ready のサイクルで data を 1 語転送する.
source が data/valid を,sink が ready を駆動する.
Parameters
| BitWidth | u32 | データ幅 [bit] |
|---|
Packages
Packages
| RvBootRom | |
|---|---|
| RvPkg | RISC-V コアの共有型定義 (docs/riscv.md「ISA スコープ」) |
| RvTestImg | |
| TfCrc | TF カード用 CRC 計算 (docs/tfcard.md「プロトコル仕様」) |
| TfTypes | TF カードサブシステムの共有型定義 (docs/tfcard.md「インタフェース」) |
| psram_pkg | PSRAM サブシステム共通定義 (docs/psram.md) |
RvBootRom
RvBootRom
RvPkg
RvPkg
RISC-V コアの共有型定義 (docs/riscv.md「ISA スコープ」)
命令符号化は RISC-V Instruction Set Manual (release riscv-isa-release-fcd15c1-2026-08-18,docs/riscv.md 一次資料表) の RV32I 基本整数命令セットの表に従う.
RvTestImg
RvTestImg
TfCrc
TfCrc
TF カード用 CRC 計算 (docs/tfcard.md「プロトコル仕様」)
- CRC7 (x^7 + x^3 + 1): コマンドフレーム (cmd + arg の 5 バイト)
- CRC16-CCITT (x^16 + x^12 + x^5 + 1,初期値 0): データブロック 512 バイト
いずれも MSB first のバイト単位更新.コントローラとビヘイビアモデルの 双方から参照する.同一実装の共有は解釈の共通モード誤りになりうるため, 実装と独立の既知検査値 (CMD0=95h 等) による固定を test_crc.veryl で行う.
TfTypes
TfTypes
TF カードサブシステムの共有型定義 (docs/tfcard.md「インタフェース」)
psram_pkg
psram_pkg
PSRAM サブシステム共通定義 (docs/psram.md)