Caravel template へのユーザ回路追加

本ドキュメントでは,サンプル回路の16-bitカウンタに AES の 8-bit S-Box のテーブル参照を追加し,ユーザ回路の追加からチップ作製データの作成やシミュレーションを行います.

注釈

なお,本ドキュメントでは,efabless 社 chipignite シャトルサービスを利用しました際のチップ作製データの生成を行っています.チップ作製の詳細については,efabless 社へお問い合わせ下さい.

Caravel template 環境のディレクトリ構成

Caravel template 環境は下記のディレクトリ上に構築されているとします.

以下の項では,setenv.sh により環境設定がなされており,また,操作などは全て Caravel_mpw-9k/caravel_mpw-9k ディレクトリ上で実行することを想定しています.

$HOME/
|-- Caravel_mpw-9k/
    |-- caravel_mpw-9k/
    |-- dependencies/
    |   |-- openlane_src/
    |   |-- pdks/
    |-- precheck_mpw-9k/
    |setenv.sh

ユーザ回路のソースコードの修正・追加

Caravel template (Caravel_mpw-9k/caravel_mpw-9k) へユーザー回路を追加する際は,次のディレクトリへの操作を行います.

  • verilog/rtl,ユーザ回路のRTLファイルの追加・修正を行います.

  • openlane,ビルド対象のRTLファイルなどの設定を行います.

また,論理シミュレーションでは,別途,次のディレクトリへの操作を行います.

  • verilog/dv,シミュレーションのベクタなどの追加・修正を行います.

  • verilog/includes_folder,シミュレーション対象のRTLファイルを設定します.

注釈

RTLファイルの指定はビルドとシミュレーションで独立しており,シミュレーション結果と作製するチップ間で異なるRTLの組み合わせでない事に注意が必要です.

RTL ファイルの追加と修正

verilog/rtl のユーザ領域コードの修正や S-box テーブルの Verilog HDL ファイルを追加します.

ファイルの追加: AES_SBOX_ENC.v を追加します.

AES_SBOX_ENC.v
//================================================ AES_SBOX_ENC
module AES_SBOX_ENC 
  (input  wire [7:0] x,
   output wire [7:0] y);

   //------------------------------------------------
   assign y = s(x[7:0]);

   function [7:0] s (input [7:0] x);
      case (x)
        8'h00: s=8'h63;  8'h01: s=8'h7c;  8'h02: s=8'h77;  8'h03: s=8'h7b;
        8'h04: s=8'hf2;  8'h05: s=8'h6b;  8'h06: s=8'h6f;  8'h07: s=8'hc5;
        8'h08: s=8'h30;  8'h09: s=8'h01;  8'h0A: s=8'h67;  8'h0B: s=8'h2b;
        8'h0C: s=8'hfe;  8'h0D: s=8'hd7;  8'h0E: s=8'hab;  8'h0F: s=8'h76;
        
        8'h10: s=8'hca;  8'h11: s=8'h82;  8'h12: s=8'hc9;  8'h13: s=8'h7d;
        8'h14: s=8'hfa;  8'h15: s=8'h59;  8'h16: s=8'h47;  8'h17: s=8'hf0;
        8'h18: s=8'had;  8'h19: s=8'hd4;  8'h1A: s=8'ha2;  8'h1B: s=8'haf;
        8'h1C: s=8'h9c;  8'h1D: s=8'ha4;  8'h1E: s=8'h72;  8'h1F: s=8'hc0;
        
        8'h20: s=8'hb7;  8'h21: s=8'hfd;  8'h22: s=8'h93;  8'h23: s=8'h26;
        8'h24: s=8'h36;  8'h25: s=8'h3f;  8'h26: s=8'hf7;  8'h27: s=8'hcc;
        8'h28: s=8'h34;  8'h29: s=8'ha5;  8'h2A: s=8'he5;  8'h2B: s=8'hf1;
        8'h2C: s=8'h71;  8'h2D: s=8'hd8;  8'h2E: s=8'h31;  8'h2F: s=8'h15;
        
        8'h30: s=8'h04;  8'h31: s=8'hc7;  8'h32: s=8'h23;  8'h33: s=8'hc3;
        8'h34: s=8'h18;  8'h35: s=8'h96;  8'h36: s=8'h05;  8'h37: s=8'h9a;
        8'h38: s=8'h07;  8'h39: s=8'h12;  8'h3A: s=8'h80;  8'h3B: s=8'he2;
        8'h3C: s=8'heb;  8'h3D: s=8'h27;  8'h3E: s=8'hb2;  8'h3F: s=8'h75;
        
        8'h40: s=8'h09;  8'h41: s=8'h83;  8'h42: s=8'h2c;  8'h43: s=8'h1a;
        8'h44: s=8'h1b;  8'h45: s=8'h6e;  8'h46: s=8'h5a;  8'h47: s=8'ha0;
        8'h48: s=8'h52;  8'h49: s=8'h3b;  8'h4A: s=8'hd6;  8'h4B: s=8'hb3;
        8'h4C: s=8'h29;  8'h4D: s=8'he3;  8'h4E: s=8'h2f;  8'h4F: s=8'h84;
        
        8'h50: s=8'h53;  8'h51: s=8'hd1;  8'h52: s=8'h00;  8'h53: s=8'hed;
        8'h54: s=8'h20;  8'h55: s=8'hfc;  8'h56: s=8'hb1;  8'h57: s=8'h5b;
        8'h58: s=8'h6a;  8'h59: s=8'hcb;  8'h5A: s=8'hbe;  8'h5B: s=8'h39;
        8'h5C: s=8'h4a;  8'h5D: s=8'h4c;  8'h5E: s=8'h58;  8'h5F: s=8'hcf;
        
        8'h60: s=8'hd0;  8'h61: s=8'hef;  8'h62: s=8'haa;  8'h63: s=8'hfb;
        8'h64: s=8'h43;  8'h65: s=8'h4d;  8'h66: s=8'h33;  8'h67: s=8'h85;
        8'h68: s=8'h45;  8'h69: s=8'hf9;  8'h6A: s=8'h02;  8'h6B: s=8'h7f;
        8'h6C: s=8'h50;  8'h6D: s=8'h3c;  8'h6E: s=8'h9f;  8'h6F: s=8'ha8;
        
        8'h70: s=8'h51;  8'h71: s=8'ha3;  8'h72: s=8'h40;  8'h73: s=8'h8f;
        8'h74: s=8'h92;  8'h75: s=8'h9d;  8'h76: s=8'h38;  8'h77: s=8'hf5;
        8'h78: s=8'hbc;  8'h79: s=8'hb6;  8'h7A: s=8'hda;  8'h7B: s=8'h21;
        8'h7C: s=8'h10;  8'h7D: s=8'hff;  8'h7E: s=8'hf3;  8'h7F: s=8'hd2;
        
        8'h80: s=8'hcd;  8'h81: s=8'h0c;  8'h82: s=8'h13;  8'h83: s=8'hec;
        8'h84: s=8'h5f;  8'h85: s=8'h97;  8'h86: s=8'h44;  8'h87: s=8'h17;
        8'h88: s=8'hc4;  8'h89: s=8'ha7;  8'h8A: s=8'h7e;  8'h8B: s=8'h3d;
        8'h8C: s=8'h64;  8'h8D: s=8'h5d;  8'h8E: s=8'h19;  8'h8F: s=8'h73;
        
        8'h90: s=8'h60;  8'h91: s=8'h81;  8'h92: s=8'h4f;  8'h93: s=8'hdc;
        8'h94: s=8'h22;  8'h95: s=8'h2a;  8'h96: s=8'h90;  8'h97: s=8'h88;
        8'h98: s=8'h46;  8'h99: s=8'hee;  8'h9A: s=8'hb8;  8'h9B: s=8'h14;
        8'h9C: s=8'hde;  8'h9D: s=8'h5e;  8'h9E: s=8'h0b;  8'h9F: s=8'hdb;
        
        8'hA0: s=8'he0;  8'hA1: s=8'h32;  8'hA2: s=8'h3a;  8'hA3: s=8'h0a;
        8'hA4: s=8'h49;  8'hA5: s=8'h06;  8'hA6: s=8'h24;  8'hA7: s=8'h5c;
        8'hA8: s=8'hc2;  8'hA9: s=8'hd3;  8'hAA: s=8'hac;  8'hAB: s=8'h62;
        8'hAC: s=8'h91;  8'hAD: s=8'h95;  8'hAE: s=8'he4;  8'hAF: s=8'h79;
        
        8'hB0: s=8'he7;  8'hB1: s=8'hc8;  8'hB2: s=8'h37;  8'hB3: s=8'h6d;
        8'hB4: s=8'h8d;  8'hB5: s=8'hd5;  8'hB6: s=8'h4e;  8'hB7: s=8'ha9;
        8'hB8: s=8'h6c;  8'hB9: s=8'h56;  8'hBA: s=8'hf4;  8'hBB: s=8'hea;
        8'hBC: s=8'h65;  8'hBD: s=8'h7a;  8'hBE: s=8'hae;  8'hBF: s=8'h08;
        
        8'hC0: s=8'hba;  8'hC1: s=8'h78;  8'hC2: s=8'h25;  8'hC3: s=8'h2e;
        8'hC4: s=8'h1c;  8'hC5: s=8'ha6;  8'hC6: s=8'hb4;  8'hC7: s=8'hc6;
        8'hC8: s=8'he8;  8'hC9: s=8'hdd;  8'hCA: s=8'h74;  8'hCB: s=8'h1f;
        8'hCC: s=8'h4b;  8'hCD: s=8'hbd;  8'hCE: s=8'h8b;  8'hCF: s=8'h8a;

        8'hD0: s=8'h70;  8'hD1: s=8'h3e;  8'hD2: s=8'hb5;  8'hD3: s=8'h66;
        8'hD4: s=8'h48;  8'hD5: s=8'h03;  8'hD6: s=8'hf6;  8'hD7: s=8'h0e;
        8'hD8: s=8'h61;  8'hD9: s=8'h35;  8'hDA: s=8'h57;  8'hDB: s=8'hb9;
        8'hDC: s=8'h86;  8'hDD: s=8'hc1;  8'hDE: s=8'h1d;  8'hDF: s=8'h9e;
        
        8'hE0: s=8'he1;  8'hE1: s=8'hf8;  8'hE2: s=8'h98;  8'hE3: s=8'h11;
        8'hE4: s=8'h69;  8'hE5: s=8'hd9;  8'hE6: s=8'h8e;  8'hE7: s=8'h94;
        8'hE8: s=8'h9b;  8'hE9: s=8'h1e;  8'hEA: s=8'h87;  8'hEB: s=8'he9;
        8'hEC: s=8'hce;  8'hED: s=8'h55;  8'hEE: s=8'h28;  8'hEF: s=8'hdf;
        
        8'hF0: s=8'h8c;  8'hF1: s=8'ha1;  8'hF2: s=8'h89;  8'hF3: s=8'h0d;
        8'hF4: s=8'hbf;  8'hF5: s=8'he6;  8'hF6: s=8'h42;  8'hF7: s=8'h68;
        8'hF8: s=8'h41;  8'hF9: s=8'h99;  8'hFA: s=8'h2d;  8'hFB: s=8'h0f;
        8'hFC: s=8'hb0;  8'hFD: s=8'h54;  8'hFE: s=8'hbb;  8'hFF: s=8'h16;
      endcase
   endfunction

endmodule // AES_SBOX_ENC

環境変数設定

Caravel template のダウンロード

環境変数の設定を行い,Caravel template のディレクトリに移動します.

source setenv.sh
cd caravel_mpw-9k

Caravel template (mpw-9k) ディレクトリを作成し,efabless 社の git サイトから Caravel template (caravel_user_template) レポジトリの mpw-9k タグのテンプレートをクローンします.

mkdir Caravel_mpw-9k
cd Caravel_mpw-9k
git clone -b mpw-9k https://github.com/efabless/caravel_user_project.git caravel_mpw-9k

環境変数の設定ファイルの作成

まず,ツールなどの導入や利用に必要な環境変数の設定を行うファイルをあらかじめ作成します.ファイル名を setenv.sh とします.

export OPENLANE_ROOT=$HOME/Caravel_mpw-9k/dependencies/openlane_src
export PDK_ROOT=$HOME/Caravel_mpw-9k/dependencies/pdks
export PDK=sky130A
export CARAVEL_ROOTT=$HOME/Caravel_mpw-9k/caravel_mpw-9k/caravel
コマンドラインからファイルを生成する方法
touch setenv.sh
echo "export OPENLANE_ROOT=\$HOME/Caravel_mpw-9k/dependencies/openlane_src" | tee -a setenv.sh
echo "export PDK_ROOT=\$HOME/Caravel_mpw-9k/dependencies/pdks" | tee -a setenv.sh
echo "export PDK=sky130A" | tee -a setenv.sh
echo "export CARAVEL_ROOTT=\$HOME/Caravel_mpw-9k/caravel_mpw-9k/caravel" | tee -a setenv.sh

ツール・PDK のセットアップ

環境変数の設定を行い,Caravel template ディレクトリに移動します.

source setenv.sh
cd caravel_mpw-9k

セットアップ前に Makefile を編集します.

回路合成結果をチェックする precheck のインストールフォルダを下記の通り修正します.

- PRECHECK_ROOT?=${HOME}/mpw_precheck
+ PRECHECK_ROOT?=${HOME}/Caravel_mpw-9k/precheck_mpw-9k

Caravel template の環境を Rootless mode の Docker により利用するための修正を行います.

- ROOTLESS ?= 0
+ ROOTLESS ?= 1

上記の ROOTLESS 設定で Rootless mode に切り替わらないため,261, 273, 289 行あたりの「-u」オプション行を削除します.

-		-u $(shell id -u $(USER)):$(shell id -g $(USER)) \

Makefile ファイルの修正後,セットアップ実行します.10分程度要します.

make setup

テンプレートを利用した最小構成の回路の合成

テンプレートの初期サンプル回路を合成し,Caravel template 環境を用いたビルドの手順を確認します.なお,回路合成にはおよそ1~2時間程度を要します.

サンプル回路は 16-bit のカウンタ回路であり,カウンタの値がユーザ用 IO に接続されています.また,Caravel 制御回路の RISC-V プロセッサと Wishbone バス,内部ロジックアナライザにも接続されており,Caravel 制御回路からユーザ回路を操作する機構を試用することもできます.

クロックやリセットも Caravel 制御回路により生成されます.

サンプル回路の修正

サンプル回路の IO (GPIO) の電源投入時の設定を記述するファイル verilog/rtl/user_define.v の修正を行う必要があります.

verilog/rtl/user_define.v 中の USER_CONFIG_GPIO_*_INIT が GPIO_MODE_INVALID と無効に設定されており,これを GPIO_MODE_USER_STD_OUTPUT に修正します.(下記の例)

`define USER_CONFIG_GPIO_5_INIT  `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_6_INIT  `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_7_INIT  `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_8_INIT  `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_9_INIT  `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_10_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_11_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_12_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_13_INIT `GPIO_MODE_USER_STD_OUTPUT 

// Configurations of GPIO 14 to 24 are used on caravel but not caravan.
`define USER_CONFIG_GPIO_14_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_15_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_16_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_17_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_18_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_19_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_20_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_21_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_22_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_23_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_24_INIT `GPIO_MODE_USER_STD_OUTPUT 

`define USER_CONFIG_GPIO_25_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_26_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_27_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_28_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_29_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_30_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_31_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_32_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_33_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_34_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_35_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_36_INIT `GPIO_MODE_USER_STD_OUTPUT 
`define USER_CONFIG_GPIO_37_INIT `GPIO_MODE_USER_STD_OUTPUT 

回路合成の実行

user_define.v の修正後,ユーザ回路本体(user_proj_example)と Caravel と接続するラッパー(user_project_wrapper)の合成を実行します.

make user_proj_example
make user_project_wrapper

エラーなど表示されず回路合成が成功すると「Flow complete」と表示され,gdsフォルダ下に user_progect_wrapper.gds ファイルが生成されます.

チップ作製データのチェック

回路合成により得られるチップ作製データの整合性などのチェックを行います. チェックではチップ製造の工程との整合性チェックのほか,説明ファイル README.md の内容についてもチェックされます.

チェック用スクリプトの修正

Caravel_mpw-9k/precheck_mpw-9k/docker-mount.sh ファイル 19 行あたりの「-u」オプション行を削除します.(Docker の Rootless mode に対応する修正です)

-  -u $(id -u "$USER"):$(id -g "$USER") \

README の修正

README.md を下記の例のように書き換えます.

This project is minimally modified to mpw-9i caravel template.
The function is 32-bit counter. 16-bit IOs are set to OUTPUT.

なお,README.md に原文が残っている場合や README.bak などオリジナルの複製など残している場合もチェックにてエラーが報告されます.

チェックの実行

下記コマンドによりチェックを実行します. チェック中に不具合が見つかった場合でも全ての項目が確認され,1時間程度要します.

make run-precheck

全て項目のチェックに合格すると All Checks Passed !!! と表示されます.