開発環境をインストールしたので引き続きTang NanoでLチカにトライします。基本的には、論理合成にライセンスファイルの請求が必要な Synplify Pro ではなく、ライセンスファイルの請求なしに動作する GowinSysthesis を使っている以外は Qiita の @cinimal さんの「Sipeed Tang Nanoで遊んでみる (Linux版)」と同じ手順です。(感謝)
プロジェクトの作成
GOWIN FPGA DesignerのStart PageでNew Projectアイコンをクリックしてプロジェクトを作成します。
FPGA Desgin Projectを選んでOKをクリックします。
プロジェクト名をつけて、プロジェクトを保存するディレクトリをセットしてNextをクリックします。
GW1N-1のQFN48ピンの中から遅い方=GW1N-1LV1QN48C6/I5を選択します。
サマリを確認してFinishをクリックします。
ソースファイルの作成
Designペインで右クリックしてNew Fileを選択。
ファイルの種類の選択からVerilogファイルを選択し、作成するファイル名と拡張子を入力、現在のプロジェクトに追加(Add to current project)する。
Tang Primerのときに作成した led.v の内容をコピペする。(Add Filesで良かったかも)
module led
(
input wire CLK_IN,
input wire RST_N,
output wire [2:0]RGB_LED
);
parameter time1 = 10'd1000 - 1'd1;
// parameter time2 = 10'd1000 - 1'd1; // 1秒周期
parameter time2 = 10'd500 - 1'd1; // 0.5秒周期
reg [2:0] rled;
reg [2:0] rledout;
reg [9:0] count1; // PWM DUTY用(1ms周期)
reg [9:0] count2; // PWM レベル用(1s周期)
reg [4:0] ckec;
reg cke; // 1us周期イネーブル
reg [9:0] duty;
initial
begin
count1=10'b0;
count2=10'b0;
rled=3'b110;
cke = 1'b1;
ckec <= 5'b0 ;
end
// 1MHz周期のイネーブル信号生成
always @(posedge CLK_IN)begin
if(RST_N==0)begin
cke = 1'b1;
end
if(ckec == 5'd23)
begin
ckec <= 5'b0 ;
cke <= 1'b1;
end
else begin
ckec <= ckec + 1'b1;
cke <= 1'b0;
end
end
always @(posedge CLK_IN)begin
if(cke == 1'b1 & RST_N==0)begin
count1 <= 10'b0;
count2 <= 10'b0;
rled <= 3'b110;
end
// 1usクロックで0〜999(time1)までカウント
if(cke == 1'b1)
begin
if(count1 == time1)
begin
count1<= 10'd0;
end
else begin
count1 <= count1 + 1'b1;
end
end
// count1の1周期で0〜999(time2)までカウント
if(cke == 1'b1 & count1 == time1)
begin
if(count2 == time2)
begin
count2<= 10'd0;
rled <= {rled[1:0],rled[2]};
end
else
count2 <= count2 + 1'b1;
end
// LEDを駆動するPWM信号生成
if(cke == 1'b1)
begin
if(count2 < time2/2)
duty = count2 * 2;
else
duty = (time2 - count2) * 2;
if(count1 < duty)
rledout = rled;
else
rledout = 3'b111;
end
end
assign RGB_LED = rledout;
endmodule
合成と端子制約の追加
ProcessペインからSynthesizeをダブルクリックして、一旦合成を実行
保存されていなかったので、保存するファイルを確認してOKをクリック。
合成が実行される。
ProcessタブでFloorPlannerをダブルクリックする。
端子制約ファイル(*.cst)がないので作成するか聞いてくるのでOKをクリック。
チップ内のレイアウトが開くので、Package Viewタブをクリック、下のペインでI/O Constraintsをクリックする。
端子を割り当てる画面になります。
上記のTang Nanoの回路図はTang NanoのドキュメントのページのDownload Stationの中のHDKディレクトリの中にあります。これを見ると、
- クロックジェネレータからのクロックはIOR5A/GCLKT_2/RPLL_T_in(35pin)
- LED_GはIOB7A(16pin)
- LED_BはIOB10A/GCLKT_5(17pin)
- LED_RはIOB10B/GCLKC_5(18pin)
- ボタンAはIOB6B(15pin)
- ボタンBはIOB3B(14pin)
につながっているようなので、PortのCLK_INをチップの絵の35ピンへドラッグアンドドロップします。
同様にLEDの3本を16〜18ピンへドロップ、RST_Nを15ピンへドロップします(下記では間違ってRST_Nを13ピンへつないでしまっています)。I/O電圧はすべて3.3Vのレギュレータへつながっているので、IO TypeをLVCMOS33にセット、LEDの3つの端子はアノードコモンで3.3Vに吊られているので気分でOpen Drainにセット、Drive能力は4mAあれば十分なので4にセット、プルアップはすべてNONEにセットしました。
フロッピーのアイコンで保存して、FloorPlannerを閉じます。
タイミング制約の追加
ProcessペインのTiming Constraint Editorをダブルクリックします。
Timing Constraint Editorが開きます。
右画面で右クリックしてCreate Clockを選択します。
Clock nameにCLK_IN、Frequencyに24[MHz]をセットします。
Searchを押して信号を検索、CLK_INを選択して「>」で対象にします。
OKを押します。
OKを押してクロックのリストに追加されていることを確認します。
フロッピーのアイコンをクリックして保存します。
配置配線を実行
ProcessペインでPlace&Routeをダブルクリックして実行します
実行すると、チェックマークが付きます。
ビットストリームの書き込み
一般ユーザーでもプログラマが使えるようにudevの設定がしてあれば、Tang Nanoを接続した後、
$ sudo modprobe -r ftdi_sio
としてから、Tools→Programmerでプログラマを起動します。modprobeでモジュールを外さないとデバイスが見つからないのでこの手順は重要です。
虫眼鏡のマークのScan Deviceでデバイスをサーチします。
GW1N-1を選択します
JTAGチェーンにGW1Nが追加されました。
デバイスをダブルクリックして、設定を行います。
OperationはSRAM Programを選択し、Programming Optionでビットストリームファイルを選択します。プロジェクトディレクトリの impl/pnr ディレクトリの下に拡張子 fs でできているはずです。
確認してSaveしてから、Program/Configureボタンをクリックします。
すると、プログレスバーが出てきて、書き込みが完了します。必要に応じて回路で設定したリセットボタンを押して動作させます。
ここで、Tang Primerでは
assign RGB_LED = rledout;
という記述をしていた assign 文は Tang Nanoではだめでしたので、
assign RGB_LED[0] = rledout[0];
assign RGB_LED[1] = rledout[1];
assign RGB_LED[2] = rledout[2];
と修正したら問題なく動作しました。(でもエラーは出ないので、悩みました)
実際の操作の際は、FloorPlannerやProgrammerは開いたままでソース修正⇒合成⇒書き込みができますので、まあまあ作業性は良さそうです。