Moselsim仿真:
EP為Endpoint部分實現代碼,即例程主代碼。其他的是搭建的仿真環境,主要目的是仿照驅動的行為,將PCIE軟核用起來,主要是做PC端的行為仿真,如DMA配置,DMA讀寫操作及主時鍾,復位等。加入testbench后結構如上圖。
board:頂層文件+系統復位
RP:Root complex的部分。其中rport就是PCIE端口部分;rx_usrapp是RX部分,負責發送數據;tx_usrapp是TX部分,負責接收數據;cfg_usrapp是配置部分,配置讀寫使能,錯誤控制等,還有一些常用的任務方便其他模塊調用;com_usrapp是加載RX/TX文件,把RX/TX的數據以dat文件形式保存,需要時加載/覆蓋。pl_usrapp物理層控制和狀態部分。
CLK_GEN_RP/EP:分別是兩個端口的時鍾產生信號。
其實EP和RP的結構很像的,基本都是對應的關系,所以理解起來工作量不是很大。
語法筆記:
因為CLK_GEN_RP/EP很簡單,沒有什么扒的必要,所以分分鍾掠過了。接下來是對RP(testbench)的一些平時沒見過的語法的筆記。
1.module xxx #(
parameter xxxx1 = xx,
parameter xxxx2 = xx,
......
)
(
input xxxxxx,
output xxxx,
.......
);
這個是正常的模塊定義。其中前面一個括號是為參數傳遞准備的定義,后面那個括號就是常見的輸入輸出端口定義。
xxx #(
.xxxx1 ( xx),
.xxxx2 (xx),
......
)
module_usrname(
.xxxxxx(xxxxxxx),
.xxxx(xxxx),
.......
);
這個是調用模塊xxx的語句,其中前面一個括號用於參數傳遞,后面一個括號用於輸入輸出端口的引用。
2.rport中,對RP的BAR0-BAR5有明確的定義需要記錄下:
BAR0 = 32'hffffff00,
BAR1 = 32'hffff0000,
BAR2 = 32'hffff000c,
BAR3 = 32'hffffffff,
BAR4 = 32'h00000000,
BAR5 = 32'h00000000,
3.rx_usrapp中的output分別是trn_rdst_rdy_n和trn_rnp_ok_n,這兩個信號是由ramdom產生的。不過原來的代碼里面trn_rdst_rdy_n是始終為0的,實際加入DMA操作的時候可以用trn_rdst_rdy_toggle_count來控制使其有效。其中的狀態機通過調用usrapp_com中的任務來進行RX中數據的store。
4.調用TASK方法:
eg: board.RP.com_usrapp.TSK_READ_DATA(0, `RX_LOG, trn_rd, trn_rrem_n);——是指調用board-RP-com_usrapp里面的 TSK_READ_DATA任務,其中括號里面的是傳遞變量,按照usrapp里面TSK_READ_DATA定義里面的input順序來傳遞變量。
5.$value$plusargs:將運行命令(run-options)中的參數值傳遞給指定的信號或者字符
用法:
if ($value$plusargs("TESTNAME=%s", testname))
$display("Running test {%0s}......", testname);
則,當使用的運行命令為:<run-options>+TESTNAME=tst_name時,運行結果為:Running test {tst_name}......
6.如果想把DMA功能用起來,自行調用pci_exp_usrapp_tx.v中的函數,往DMA控制寄存器中寫入地址、長度等數據,然后啟動DMA讀或者寫。