Minimum Design Tool

🎯 結論:あなたが採用すべきオープンツール構成(picoRV32 版)

種類 推奨
CPU picoRV32(本家完全オープン)
合成 Yosys (synth_gowin)
PnR(配置配線) nextpnr-gowin
ビットストリーム生成 nextpnr-gowin(内蔵 gowin_pack)
FPGA 書き込み openFPGALoader
Cコンパイル xPack riscv-none-elf-gcc(newlib-nano)

これにより、Gowin IDE 一切不要で完全オープンフローが実現できます。


📐 Tango Nano 9K picoRV32 SoC(最小構成)

以下を作ることを想定:

+----------------------------+
| picoRV32 CPU (RV32IMC) |
| +--------------+
| | BRAM (RAM) | → 1632 KB
| +--------------+
| MMIO バス: Wishbone風 |
| +--------------+
| LED レジスタ | 0x0100_0000
| UART Lite (TXのみ) | 0x0200_0000
| +--------------+
+----------------------------+

📘 オープンソースフローのセットアップ

✔ 1. Yosys + nextpnr-gowin + openFPGALoader のインストール

Ubuntu/Debian(簡単版)

sudo apt install yosys nextpnr openfpgaloader

最新安定版(推奨)

YosysHQ の prebuilt package を使う(実習でトラブル少ない)。
https://github.com/YosysHQ/oss-cad-suite-build

インストール後:

export PATH=$HOME/oss-cad-suite/bin:$PATH

✔ 2. picoRV32 の導入

公式(Clifford Wolf)から取得:

git clone https://github.com/YosysHQ/picorv32

利用する HDL:

  • picorv32.v(CPU本体)

  • 必要なら picosoc/ も参考にできる


✔ 3. 最小 SoC(例)を作成

以下は Tango Nano 9K 用 完全オープン picoRV32 SoC テンプレート Verilog
※あなたの目的向けに調整済み

🧩 soc_top.v(ひな形)

module soc_top (
input wire clk,
input wire resetn,
output wire led,
output wire uart_tx
);

// ---------------------------
// Clock / Reset
// ---------------------------

wire reset = ~resetn;

// ---------------------------
// Memory: BRAM 32KB
// ---------------------------

reg [31:0] mem [0:8191]; // 32KB / 4 bytes

wire mem_valid;
wire mem_instr;
wire [3:0] mem_wstrb;
wire [31:0] mem_addr;
wire [31:0] mem_wdata;
reg [31:0] mem_rdata;

always @(posedge clk) begin
if (mem_valid && |mem_wstrb && mem_addr < 32'h00008000) begin
if (mem_wstrb[0]) mem[mem_addr[14:2]][ 7: 0] <= mem_wdata[ 7: 0];
if (mem_wstrb[1]) mem[mem_addr[14:2]][15: 8] <= mem_wdata[15: 8];
if (mem_wstrb[2]) mem[mem_addr[14:2]][23:16] <= mem_wdata[23:16];
if (mem_wstrb[3]) mem[mem_addr[14:2]][31:24] <= mem_wdata[31:24];
end
end

always @(posedge clk) begin
mem_rdata <= mem[mem_addr[14:2]];
end

// ---------------------------
// MMIO - LED (0x0100_0000)
// ---------------------------

reg led_reg = 0;
wire led_sel = mem_valid && mem_addr == 32'h01000000;

always @(posedge clk) begin
if (led_sel && |mem_wstrb)
led_reg <= mem_wdata[0];
end

assign led = led_reg;

// ---------------------------
// MMIO - UART TX (0x0200_0000)
// ---------------------------

reg uart_tx_reg = 1'b1;
wire uart_sel = mem_valid && mem_addr == 32'h02000000;

always @(posedge clk) begin
if (uart_sel && |mem_wstrb)
uart_tx_reg <= mem_wdata[0];
end

assign uart_tx = uart_tx_reg;

// ---------------------------
// CPU Instantiation
// ---------------------------

picorv32 #(
.ENABLE_MUL(1),
.ENABLE_DIV(0),
.ENABLE_IRQ(0),
.STACKADDR(32'h00007FFC)
) cpu (
.clk (clk),
.resetn (resetn),
.mem_valid (mem_valid),
.mem_instr (mem_instr),
.mem_ready (1),
.mem_addr (mem_addr),
.mem_wdata (mem_wdata),
.mem_wstrb (mem_wstrb),
.mem_rdata (mem_rdata)
);

endmodule

これだけで picoRV32 + RAM + LED + UART のミニ SoC になります。


📦 Cプログラム(xPack GCC 用)

main.c

#define LED (*(volatile unsigned int*)0x01000000)
#define UART (*(volatile unsigned int*)0x02000000)

void uart_putc(char c) {
UART = c;
}

int main() {
LED = 1;
uart_putc('A');
while (1) {}
}


📄 リンカスクリプト(.ld)

link.ld

ENTRY(_start)

MEMORY {
RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 32K
}

SECTIONS {
.text : {
*(.text*)
*(.rodata*)
} > RAM

.data : {
*(.data*)
} > RAM

.bss : {
*(.bss*)
*(COMMON)
} > RAM
}


🛠 ビルドコマンド(xPack)

riscv-none-elf-gcc -Os -march=rv32im -mabi=ilp32 \
-ffreestanding -nostdlib -nostartfiles \
-Wl,-Bstatic,-T,link.ld \
-o firmware.elf main.c

BIN出力:

riscv-none-elf-objcopy -O binary firmware.elf firmware.bin

🏗 FPGA ビルド(完全オープンフロー)

1) 合成(Yosys)

yosys -p "read_verilog picorv32.v soc_top.v; synth_gowin -top soc_top -json soc.json"

2) 配置配線(nextpnr-gowin)

nextpnr-gowin --device GW1NR-LV9QN88C6/I5 --json soc.json --write soc.fs

3) FPGA 書き込み(openFPGALoader)

openFPGALoader -b tangnano9k soc.fs

🎉 これで、Gowin IDE を一切使わずに picoRV32 SoC が Tango Nano 9K を動きます!


📩 最後に質問

次はどれを進めたいですか?

  1. uart_tx を“本物の UART(ボーレート生成あり)”に改良

  2. RAM/ROM を FPGA の本物の BRAM(SB_RAM40)に置き換える

  3. Wishbone バス化して周辺 IP を増やすひな形

  4. Makefile を自動生成

  5. ローダ(UART/USBからRAMに書き込む MiniLoader)を作る

どれを作りましょう?

xPack riscv-none-elf-gcc(newlib-nano 付き)

はい、**xPack riscv-none-elf-gcc(newlib-nano 付き)**は、以下の手順で簡単にインストールできます。
Windows / macOS / Linux 共通で使える方法です。


最短手順(推奨)

ステップ 1:xpm をインストール

xPack のパッケージマネージャです(npm を使用)。

npm install --global xpm

npm が無ければ:

  • Ubuntu / Debian:sudo apt install npm

  • Arch:sudo pacman -S npm

  • macOS:Homebrew で brew install node

  • Windows:Node.js セットアップに npm が含まれます


ステップ 2:xPack RISC-V Embedded GCC をインストール

最新安定版(推奨):
riscv-none-elf-gcc 12.3.0-1.1

xpm install --global @xpack-dev-tools/riscv-none-elf-gcc@12.3.0-1.1

ステップ 3:PATH を通す

Linux / macOS:

export PATH="$HOME/.local/xPacks/riscv-none-elf-gcc/12.3.0-1.1/bin:$PATH"

.bashrc に追加して自動化:

echo 'export PATH="$HOME/.local/xPacks/riscv-none-elf-gcc/12.3.0-1.1/bin:$PATH"' >> ~/.bashrc

Windows:

パスは以下:

%USERPROFILE%\.local\xPacks\riscv-none-elf-gcc\12.3.0-1.1\bin

これを「システムの環境変数」に追加します。


newlib-nano が含まれているか確認

次のコマンドで確認できます:

riscv-none-elf-gcc --print-multi-lib

出力に nano.specs が付いていれば OK。

さらに、以下で newlib-nano を使ったビルドができます:

-specs=nano.specs

動作確認

riscv-none-elf-gcc -v
riscv-none-elf-ld -v
riscv-none-elf-gdb --version

問題なく表示されればインストール成功です。


🧪 簡易テスト

// hello.c
int main() {}

ビルド:

riscv-none-elf-gcc -Os -march=rv32im -mabi=ilp32 \
-specs=nano.specs \
-c hello.c

成功すれば OK。


✨ 補足:インストール場所まとめ

OS デフォルトのインストールパス
Linux $HOME/.local/xPacks/riscv-none-elf-gcc/<version>/bin
macOS 同上
Windows %USERPROFILE%\.local\xPacks\riscv-none-elf-gcc\<version>\bin

必要であれば:

✅ Makefile(picoRV32 用)
✅ newlib-nano 用リンカスクリプト(最適化済み)
✅ UART printf のミニ実装
などもすぐ作ります。