背景
下邊的內容,適合初次使用Lattice的、具備FPGA開發經驗的同學。
1、初次使用,還真遇到不少的坑,Lattice的工具也有不少優缺點,通過總結,希望能縮短熟悉的時間。
2、具體問題,歡迎留言交流。
DDR3 IP例化
LEF5UM器件,應用DDR3控制器IP。主要分幾步:IP獲取,安裝,例化。
1、先在impl1目錄下,右鍵,新建sbx文件,即Clarity Designer,通過該文件,進行IP的例化管理。

2、打開sbx,在選項卡“Lattice IP Server”里點擊IP聯網獲取IP列表。

3、選擇“DDR3 SDRAM Controller”,目前(18年12月)最新版本3.1,下載(格式exe)后安裝到指定目錄(如:C:\LatticeCore\ddr3_sdram_common_v3.1),這樣可以在選項卡“Lattice IP”中看到“ddr3 sdram controller 3.1”。


4、打開ip,GUI界面如下,在本項目中,參考時鍾(RefClock)來自單板晶振產生的100M,ddr的工作頻率400M,雙沿也就800M。Memory Type選擇On-board Memroy,總線寬度16,配置x16,時鍾寬度1。Data_rdy to Write Data Delay選擇2,表示data_rdy有效之后必須在第2拍送數據。
注意:這里涉及時序收斂上的編碼技巧。通常,用戶邏輯數據先存入fifo,再送給ddr3控制器,再加上控制器要求2拍給數據,這樣,fifo跟ddr3控制器之間時序就比較難收斂(如果很好收斂,那說明你在設計上已經關注到了這點),我的辦法很簡單,就是對fifo進行預讀操作,在讀使能送出之前,先預讀3拍出來,等ddr發出讀使能時,數據就不是從fifo到DDR3了,而是在這之間插入了幾拍的寄存器,從而緩解了時序壓力。

DDR3仿真
仿真腳本我會單獨介紹,其實IP工程給出了仿真腳本,借用過來修改修改就可以使用。這里只提一個導致仿真只運行60多us就提前終止的小問題。

解決辦法,請仔細閱讀仿真工具的告警,工具明確說了,是Memory overflow,建議增加MEM_BITS參數或者定義MAX_MEM。綠色文字也給出了文件路徑的指示,在ddr3_ddr3_x16.v中,include有參數文件
ddr3_parameters.vh,就是同一目錄下,打開vh文件,搜索MEM_BITS,默認為10,修改為16即可。
小結:遇到問題先不慌張,認真閱讀工具給出的提示信息,通常會有解決思路。有同學說英文不好咋辦,那就復制粘貼到網上的翻譯軟件唄,不然還能涼拌?

bit/mcs燒錄
Lattice工具一個不好用的地方,就是mcs燒錄得講究順序,否則會報錯。燒錄mcs的步驟:
A、JTAG模式下,選擇Erase Only。

B、選擇SPI Flash,操作時可以不用verify,如下。

Reveal邏輯分析儀
FPGA廠家都會提供內嵌邏輯分析儀,Xilinx叫chipscope,Lattice的叫reveal,可以單獨安裝reveal程序,也可以在diamond工程中打開。在“File List”的“Debug Files”里,右鍵,點擊Reveal Project Files,可新建*.rvl文件,相對Xilinx,這個rvl比較好用,復制veriog代碼信號名,只要沒被優化,就可以很快找到。

添加信號時,除了在trace signal setup里選擇時鍾和觀察信號之外,另外還需要在trigger signal里設置,這點比Xilinx稍微麻煩點。

trigger設置也有套路。第一步,在trigger unit中拉入信號,可以在一個條件里,也可以分開,operator可以不用管,到時抓波形時可以修改的。第二步,在trigger exprssion里,直接把unit的name復制下來就好。

以上操作完畢,記得點擊design rule check(下圖靠上的圖標),檢查是否有錯,然后點擊insert debug,讓邏輯分析的時鍾自動添加到后端約束lpf文件里(在約束的首行)。

抓波形的其他技巧
- 若要保留抓波形的相關文件,需要復制*.bit,*.rvl和*.rvs文件,同時,對*.rvs文件內容的第一行進行修改,確保指向確定的文件。
- 出於測試目的,臨時添加的信號,為防止被優化掉,可使用 reg signal_name/* synthesis syn_keep=1 */; 直接讓信號保留,記住,完成綜合之后,要手工點擊design fresh,這樣才能在rvl文件中查找到該添加的測試信號。
后端約束lpf
不正確的約束,或者遺漏的約束,會導致跑的結果不符合預期。約束時,記得下邊幾個方面不要遺漏。
1、位置約束,這個和具體硬件相關,對照硬件PCB文件找到相應管腳即可,並添加IO的電平屬性,也可通過ALLPORTS設置默認的電平。
1 LOCATE COMP "DDR_CLK_I" SITE "AD1" ; 2 IOBUF ALLPORTS IO_TYPE=LVCMOS33 ; 3 IOBUF PORT "CLK_27M_I" IO_TYPE=LVCMOS33 ;
2、時鍾約束,在【tool--netlist view】下邊,點net圖標,點開clock可看到整個項目里的時鍾信號,然后逐一確認時鍾頻率並添加約束。

1 FREQUENCY NET "ddr_arbiter_inst/ddr_core_inst/U1_clocking/clk_in_c" 100.0 MHz PAR_ADJ 5.0 ;
2 FREQUENCY NET "user_clk" 200.0 MHz PAR_ADJ 40.0 ;
3 FREQUENCY NET "*/U1_clocking/clkop" 400.0 MHz PAR_ADJ 80.0 ;
3、DDR約束,直接參考IP例子ddr3_x16_eval.lpf抄過來就好(最多確認下那些信號是否都有效),通常在下邊目錄:xxx\coregen_hwt_bit_v901_nocdr_noddr\ddr3_x16\ddr_p_eval\ddr3_x16\impl\lse
4、不需要時序分析的路徑。Xilinx的約束是TIG,Lattice就是BLOCK,免得后端工具把時間耗費在這些不需要時序分析的路徑上。
1 BLOCK PATH FROM CLKNET "clk_54m_pll" TO CLKNET "clk_148m5" ; 2 BLOCK NET "video_rddr_scaler_inst/fifo_rst" ;
5、接口信號的上下拉設置,通常設置為NONE,對按鍵、IIC則設置為上拉PULLMODE=UP。
后端報告
后端跑完,關注的信息,包括:
- 運行時間,決定了迭代的周期多久,方便評估驗證的效率。雖然報告沒給出時間耗費,但有起始時間(下圖synplify報告最前邊幾行)和最終產生bit的時間(看bit修改日期就知道),首尾做個減法就得到最終結果。

- 時序報告,score不能太高,具體得分需要逐條分析,從而評估bit的質量,或者是否適當提高時序約束頻率,面積約束等策略。通過netlist的查看,檢查時鍾路徑是否都覆蓋,避免每次跑出版本的功能不具備一致性。
- 資源報告,評估后端風險,各個模塊資源等


后記
先暫時列這些,想起了再補充。
=======================
by NicoWei
2019-3-8 23:00:48
=======================
