前言 之前一直眼饞Sipeed的Tang系列,正好遇到有工程需要高速控制並行匯流排,就買了NANO 9K和Primer 20K試試水 買回來先拆的貴的20k,結果發現Sipeed設計師有奇怪的腦迴路: 核心板沒有指示燈,沒有集成下載器 tf卡在核心板與底板中間藏著,JTAG絲印在背面 JTAG介面和官 ...
前言
之前一直眼饞Sipeed的Tang系列,正好遇到有工程需要高速控制並行匯流排,就買了NANO 9K和Primer 20K試試水
買回來先拆的貴的20k,結果發現Sipeed設計師有奇怪的腦迴路:
- 核心板沒有指示燈,沒有集成下載器
- tf卡在核心板與底板中間藏著,JTAG絲印在背面
- JTAG介面和官方下載器需要扭麻花形式連接
- 調整供電bank需要手動拆除0R電阻。
- 板載晶振27MHz,很奇怪的頻率
結果就是失去了調試的興趣,隨便寫了個分頻器輸出1pps脈衝了事。
之後拆了NANO 9K,這個就比20K好用多了,板載一串LED,雖然一些板載資源占用了IO,但還是比較方便調試的。
Sipeed還有個問題就是,常式太少,點燈、點屏幕,沒了。好在高雲的手冊比較多,雖然各個功能的手冊是分別發佈的,沒有系統教程,但好在詳細。摸索了一天,算是明白了這個工具要怎麼用,因此先寫一篇博客記錄一下。
軟體準備
- 前往高雲官網下載軟體和各種參考手冊。推薦使用教育版,不用申請license。
- 安裝下載好的雲源軟體,我安裝的1.9.8.09教育版,有的教程說要另外下載programmer,該版本已自帶。軟體安裝問題可以參考SUG501手冊。
- 打開軟體,界面功能問題可以參考SUG100手冊。
- 新建工程,點燈測試,詳見Sipeed點燈常式。
- 綜合、約束、下載之類的基礎操作在常式中已有詳解,這裡列一下可能用到的手冊
- 綜合問題在SUG550
- 約束在SUG935和SUG940
- 下載在SUG502
- 其他高級功能樣例在SUG918,所有功能有獨立說明手冊
所以說高雲手冊雖然不系統,但好在很詳細
IP核調用
IP核怎麼調用,沒有專門教程參考,僅在SUG100中放了個界面。各各IP核手冊中也只是用Verilog或VHDL實例化原語,搞得我這Verilog入門菜鳥一頭霧水。在此隨手記錄一下IP核調用方式。
項目目標
點燈教程中系統時鐘來自於板載時鐘27MHz,這個時鐘我猜測是為了保留3M時鐘基頻,以便精確PLL出如21M、12M、24M等時鐘(那為什麼不用21M時鐘,還包含7M基頻)。
但是我看27MHz不順眼,於是項目目標就是,利用GW1NR-9C自帶的可編程時鐘,產生一個25MHz頻率,再用這個25MHz進PLL產生100MHz時鐘,同時把25MHz用緩衝器輸出到引腳上,以檢測板子的信號完整性。最後固化到內部Flash,完成燒錄與離線運行。
這樣,該項目檢測了邏輯單元、IO、IO速率、PLL、CLK,只剩下DSP、SRAM和一些PHY沒測試了,之後可以寫一個DDS工程,測一下DSP和SRAM。
IP核配置
- 首先是打開IP核界面,選擇時鐘模型,選擇OSC,雙擊
- 可以看到內部可編程時鐘的配置是很簡單的,只需要填一個分頻數就好。該IP核的詳細說明見UG286,具體搭載的時鐘原頻率是多少,不要參考軟體中IP核的說明,要參考IC的Datasheet,如GW1NR-9的DS117的晶振時鐘章節
- 軟體自動生成verilog文件,自己也可以仿照該文件直接在主模型文件中例化原語。
- 在主模型文件中將該OSC模型實例化
- 接著,在IP核管理界面選擇rPLL模塊,一般使用普通模式即可,填入輸入時鐘、輸出時鐘、誤差容忍度,點擊計算即可自動配置。需註意,有些需求時鐘是不能產生的,或者它自動生成參數後綜合軟體認為不在VCO適用頻率內,這時就需要手動湊數計算了。詳細參數計算綜合報錯時會有,UG286也有計算方法。
- 在主文件中將該PLL實例化
- 直接在主文件中將25M時鐘連到OBUF上,輸出帶緩衝的clk_out
- 對點燈例子中的一些計數值稍作修改,即可完成代碼
- 綜合約束,燒錄。燒錄選擇燒錄在內部Flash里,這樣可以離線運行
附
代碼如下:
module led (
input sys_rst_n, // reset input
output reg [5:0] led, // 6 LEDS pin
output wire clk_out
);
reg [31:0] counter;
wire pll_clk;
wire sys_clk;
Gowin_OSC SYSOSC(sys_clk);
Gowin_rPLL APLL(pll_clk,sys_clk);
OBUF uut(
.O(clk_out),
.I(sys_clk)
);
always @(posedge pll_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
counter <= 32'd0;
else if (counter < 32'd49_999_999) // 0.5s delay
counter <= counter + 1'b1;
else
counter <= 32'd0;
end
always @(posedge pll_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
led <= 6'b111110;
else if (counter == 32'd49_999_999) // 0.5s delay
led[5:0] <= {led[4:0],led[5]};
else
led <= led;
end
endmodule
約束: