LatticeMico32チュートリアル
LatticeMico32とは
LatticeMico32はLattice Semiconductor社が公開している無償で使える32ビットソフトコアCPUです。
Lattice社のFPGA向けに最適化されていますがLattice社以外のFPGAでも使用することが可能です。
リソース使用量が多くLatticeXP2に組み込むと2400LUTほど消費しますが、
六段パイプライン構造でクロックあたりの命令実行能力(Clock Per Instruction)が高いのが特徴です。
開発環境はEclipseベースのLatticeMico Systemが提供されおりC/C++言語が使えます。
Lattice社のFPGA向けに最適化されていますがLattice社以外のFPGAでも使用することが可能です。
リソース使用量が多くLatticeXP2に組み込むと2400LUTほど消費しますが、
六段パイプライン構造でクロックあたりの命令実行能力(Clock Per Instruction)が高いのが特徴です。
開発環境はEclipseベースのLatticeMico Systemが提供されおりC/C++言語が使えます。
以下にLatticeMico32のブロックダイアグラムを示します

このチュートリアルの目標
シミュレーターで動作確認を行い最終的にCQ-FRK-LXP2のLatticeXP2に組み込み、テストプログラム(Lチカ)を走らせることが目標です。
開発環境
Lattice Diamond1.4がインストールされていることが前提です。なおこのチュートリアルではWindows7 64bitでの解説となります。
プラットフォームの作成
まずスタートメニューの[プログラム]から [Lattice Diamond1.4]→[Accessories]→[LatticeMico System] を選択しLatticeMico Systemを起動します
初回起動時にWorkspaceをどこにするか聞かれますが、ここでは[C:\lscc\lm32]にしておきます。
初回起動時にWorkspaceをどこにするか聞かれますが、ここでは[C:\lscc\lm32]にしておきます。

そして次にメニューから[Files]->[New Platform]を選択します。

次のようなウィンドウが開きますので、プラットフォーム名、ディレクトリ、組み込むFPGA、動作周波数、パッケージを設定します。
動作周波数はここでは16MHzになってますが各自の環境に合わせてください。LatticeMico32は70MHzぐらいまでなら動作するようです。
動作周波数はここでは16MHzになってますが各自の環境に合わせてください。LatticeMico32は70MHzぐらいまでなら動作するようです。
LatticeMico32ハードウェアの生成

プラットフォームが作成できたら左側の[Available Components]から[LatticeMico32]を選んでダブルクリックします

LatticeMico32の生成オプションを設定するウィンドウが出てきます。ここではFPGAのリソース節約のため全てのチェックボックスとOFFにします。
次にプログラムROMの設定をします。
プログラムROMはWISHBONEバスにOn chip memoryを接続するかinline memoryを使用する方法と二通りありますが、
inline memoryを使ったほうがバス効率やアクセス速度の面で有利です。なので、ここではinline memoryを使う方法を解説します。
次にプログラムROMの設定をします。
プログラムROMはWISHBONEバスにOn chip memoryを接続するかinline memoryを使用する方法と二通りありますが、
inline memoryを使ったほうがバス効率やアクセス速度の面で有利です。なので、ここではinline memoryを使う方法を解説します。

次に上のタブからinline memoryの設定画面に移ります。Enabledのチェックボックスを2つともONにし
[Instruction Inline Memory]の[Size of Memory(in bytes)]の項目に[0x00000D00]と入力して[OK]を押します。
[Instruction Inline Memory]の[Size of Memory(in bytes)]の項目に[0x00000D00]と入力して[OK]を押します。
GPIOハードウェアの作成

次にGPIOのハードウェアを作成します。[Available Components]から[GPIO]を選んでダブルクリックします

設定画面が出てきますので”Data Width”を[8]にして[OK]を押します。

次にWishbone Connectionの画面の○をクリックしてGPIOのWISHBONEバスを接続します。

最後に上のメニューのGと書かれたボタンを押してハードウェアを出力します。
ソフトウェアの作成

次にソフトウェアプロジェクトを作成します。メニューから[Files]->[New]->[mico Managed Make C Project]を選択します

プロジェクト名とファイル保存する場所を設定する画面が出てきます。
[Project Contents]は最初はワークスペースの場所が入力してあるのですが
ワークスペースの下にコンテンツフォルダを作成しようとすると上の画像のように怒られます。
[Project Contents]は最初はワークスペースの場所が入力してあるのですが
ワークスペースの下にコンテンツフォルダを作成しようとすると上の画像のように怒られます。

そこでワークスペースの外に新たにフォルダを作ってそこをコンテンツフォルダにします。ここでは”lm32c”というフォルダにして[Finish]を押す。

Cプログラムを追加します。プロジェクト切り替えで[C/C++]を選びます。
プロジェクトが切り替わったら、上の画像のようにアイコンを右クリックしてコンテストメニューからCのソースファイルを追加します。
プロジェクトが切り替わったら、上の画像のようにアイコンを右クリックしてコンテストメニューからCのソースファイルを追加します。
/* test.c */
#define GPIO *(volatile int *)0x80000000
int main(void)
{
for(;;){
GPIO = 0xffffffff;
GPIO = 0x00000000;
}
}
ソースファイルに次のように入力したらCtrl+Bを押してビルドします。
メモリファイルの生成

エラーが出ずにビルドできたら、次にメモリファイルを出力します。メニューから[Tools]->[Software Deployment]を選択します。

左のメニューから[Mico32 Onchip Memory Deployment]を選択してからメモリファイルの元になる.elfファイルを選択、
ファイル名を設定してメモリファイルを作成します。
ファイル名を設定してメモリファイルを作成します。

次にプロジェクトをMSBに切り替えて「LM32」をダブルクリックし設定画面をもう一度出します

InlineMemoryのタブで先程生成したメモリファイルを指定します。
このあともう一度Gボタンを押してハードウェアを生成しておきましょう。
このあともう一度Gボタンを押してハードウェアを生成しておきましょう。
Veritakでシミュレーション
テストベンチファイルを作ります。
/* tb_lm32test.v */
`timescale 10ns/10ps
module t;
reg Clock = 1'b0;
reg Reset = 1'b0;
wire [7:0] gpioPIO_OUT;
lm32test lm32 (
.clk_i(Clock),
.reset_n(~Reset),
.gpioPIO_OUT(gpioPIO_OUT) // [8-1:0]
);
//Global Reset
GSR GSR_INST(.GSR(1'b1));
PUR PUR_INST(.PUR(1'b1));
initial begin
#0.5 Reset = 1'b1;
#0.5 Reset = 1'b0;
fork
forever #0.5 Clock = ~Clock;
do;
join
end
task do; begin
#3000;
$finish;
end endtask
endmodule
次にプロジェクトファイルを作ります。

Diamondがインストールされたフォルダにあるシミュレーション用ライブラリがあるフォルダを読み込んでおきます。

Defineで"SIMULATION"を定義しておきましょう。そうしないと論理合成用のブラックボックスモデルが読み込まれてしまいます。
あとLatticeMico32のHDLソースファイルはけっこういい加減な文法なのでVeritakに読み込ませると文法エラーが多発します。
gpio.v
Veritakでエラーが出ないように修正したHDLソースを容易しましたので上のファイルを /componets/gpio/gpio.v を上書きします
あと/components/lm32_top/rtl/verilog/lm32_load_store_unit.v の200行目
あとLatticeMico32のHDLソースファイルはけっこういい加減な文法なのでVeritakに読み込ませると文法エラーが多発します。
gpio.v
Veritakでエラーが出ないように修正したHDLソースを容易しましたので上のファイルを /componets/gpio/gpio.v を上書きします
あと/components/lm32_top/rtl/verilog/lm32_load_store_unit.v の200行目
output irom_store_data_m;
を
output [`LM32_WORD_RNG] irom_store_data_m;
に修正します。

うまくコンパイルできたら。波形を確認して上のようにGPIOの出力値が交互にFF、00と切り替われば正常に動作しています。
論理合成用プログラムのビルド
次に実際にFPGAに組み込むための論理合成用プログラムのソースコードを示します
/* lm32syn_test.c */
#define GPIO *(volatile int *)0x80000000
int main(void)
{
unsigned int i;
unsigned int data = 0;
for(;;){
data = ~data;
GPIO = data;
for (i = 0; i < 0x20000; i++); //wait
}
}
これをビルドしたら前のようにメモリファイルをデプロイしましょう。
Diamondに組み込む
Diamondを起動して新規プロジェクトを作成します。
MicoSystemBuilderで生成したLatticeMico32のCPUコア本体と
次のトップモジュールのVerilog HDLファイルをプロジェクトに追加します。
MicoSystemBuilderで生成したLatticeMico32のCPUコア本体と
次のトップモジュールのVerilog HDLファイルをプロジェクトに追加します。
/* top.v */
module top(
input Clock,
input Reset,
output [1:0] LED
);
wire [7:0] gpio;
assign LED = gpio[1:0];
lm32test lm32 (
.clk_i(Clock),
.reset_n(~Reset),
.gpioPIO_OUT(gpio) // [8-1:0]
);
endmodule
上のファイルをストラテジ設定でトップモジュールに設定して論理合成します。

消費リソース一覧
LUTを2278、組み込みRAMを4つ消費しました。
LUTを2278、組み込みRAMを4つ消費しました。
