以上為小梅哥為了對特權同學的串口收發(fā)模塊進行測試所展開的部分工作,到這里,仿真測試所需要的準備工作我們就做好了,接下來將實際進行仿真,通過仿真來分析該模塊的性能。 這里極力推薦大家使用modelsim進行仿真,因為quartusII自帶的仿真工具靈活性和功能都趕modelsim相差甚遠。Modelsim作為一款強大的仿真軟件,在業(yè)界被廣泛使用。同時,modelsim針對不同的EDA廠家,也推出了OEM版本,modelsim-altera就是為Altera公司開發(fā)的OEM版本,此版本針對Altera公司的器件預先做了許多的工作,使我們使用的時候能夠更加的快捷方便,這里,小梅哥就使用modelsim-Altera版本來仿真這個設計。 我們可以使用modelsim-Altera,通過完全手動化的方式來建立仿真工程,添加仿真庫、編譯文件,添加波形,運行仿真,當然也可以使用Nativelink的方式,通過quartus II軟件實現(xiàn)一鍵調(diào)用,實現(xiàn)自動化的仿真過程。這里,對于初學者,小梅哥還是推薦采用這種自動化的方式,因為簡單,不需要過多的手動操作,且不容易出錯。這里,小梅哥也使用這種方式來進行仿真。 要使用這種方式仿真,我們需要在QuartusII軟件中進行EDA Tools的設置。在quartus II軟件中,依次點擊“tools – options ”,在打開的選項卡中選擇“EDA tool options”,在modelsim-altera一欄中輸入你的modelsim-Altera的安裝路徑(部分在安裝的時候就已經(jīng)自動設置好了,就不用去管),如下圖所示: 這里設置完成后,點擊OK即可。 當確認這一步?jīng)]有問題后,我們就可以開始進行Nativelink的設置了。Nativelive就是一個鏈接的過程,通過設置Nativelink,讓Quartus II軟件能夠自動的調(diào)用modelsim-altera軟件,并建立仿真工程,添加仿真庫、編譯文件,添加波形,運行仿真。接下來我們就來進行Nativelink的設置 第一步:依次點擊“assignments– settings”, 在彈出的選項卡中,選中“EDA Tool Settings”(紅色標號1處),在子選項中選擇“Simulation”(紅色標號2處),注意紅色標號5處和6處應分別選擇為modelsim-altera和Verilog HDL,如果不是,請通過下拉列表選擇為上述選項。點擊“Compile test bench” (紅色標號3處),然后點擊最右側的“Test Benchs” (紅色標號4處),就會彈出如下所示的界面: 點擊“New” (紅色標號1處),接著會彈出“New Test Bench Settings”界面,如下圖所示: 首先我們點擊紅色標號1處的三個小點,在彈出的文件選擇界面中,選中我們需要加入的testbench文件,如下所示: 這里我們選擇“Uart_tb.v”和“Uart_module.v”,點擊“Open”打開。這里,“Uart_tb.v”為仿真頂層文件,“Uart_module.v”為串口仿真模型。 文件選擇好之后,回到New Test Bench Settings界面,如下圖所示, 在頂端“test bench name”(紅色標號2)處輸入我們的仿真頂層文件名,即Uart_tb,注意,不要加“.v”后綴。于是,”Top level module in test bench”會自動與“Test bench name”保持一致。 至此,我們的Nativelink設置就完成了,一路選擇OK下去,直到回到Quartus II軟件的主界面。此時,我們已經(jīng)完成了仿真需要的所有設置,我們直接點擊Quartus II軟件上的RTL Simulation圖標 即可啟動仿真,也可以通過“Tools– Run Simulation Tool – RTL Simulation”啟動仿真。 接下來,我們需要做的就是大約20秒左右的等待,這個過程中,Quartus II會自動啟動modelsim-altera軟件,建立仿真工程,添加仿真庫、編譯文件,添加波形,運行仿真。最后停留在如下所示的狀態(tài): 這里,右側深色窗口為波形窗口,下方為副本界面,打印了軟件運行過程中的信息,包括添加文件、編譯文件、添加波形、運行等,同時還打印了testbench中需要打印輸出的信息。具體的打印信息如下: 由此打印信息可知,串口仿真模型總共進行了8次數(shù)據(jù)發(fā)送,卻只收到了6次數(shù)據(jù),因此有兩次發(fā)送給串口模塊的數(shù)據(jù)丟失或者串口模塊發(fā)送的數(shù)據(jù)不正確。同時,第一次發(fā)送出去的數(shù)據(jù)接收回來還是正確的,但是第二次發(fā)送的數(shù)據(jù)再接收回來,就錯誤了。這兩次數(shù)據(jù)發(fā)送之間的時間間隔為40ns。考慮可能是發(fā)送間隔太短導致,但是當?shù)?次發(fā)送的數(shù)據(jù)(s4)被正確接收后(r3),緊接著第5次發(fā)送的數(shù)據(jù)在發(fā)回的時候,再次出錯,而s4和s5之間間隔了300ns,因此可知,該串口收發(fā)模塊在連續(xù)兩次發(fā)送間隔很短的情況下,很容易出錯。那么,怎么樣才能保證連續(xù)兩次發(fā)送之間,即使很短的間隔,也不出錯誤呢?小梅哥通過對仿真波形的分析發(fā)現(xiàn):一次接收數(shù)據(jù),總共有12個波特率脈沖,如下圖所示: 這里小梅哥就有點疑惑了,我們一般的應用中,串口一幀的數(shù)據(jù)為十位,包含1位起始位、8位數(shù)據(jù)位、一位停止位,一般不含校驗位。因此,這里明顯多了兩個波特率周期,那么,問題很有可能就出在這里。回到這部分的代碼: 43 always @ ( posedge clk or negedge rst_n ) 44 if(! rst_n ) begin 45 bps_start_r 46 rx_int 47 end 48 else if( neg_rs232_rx ) begin // rs232_rx 49 bps_start_r 50 rx_int 51 end 52 else if( num==4'd12 ) begin // 53 bps_start_r 54 rx_int 55 end 56 57 assign bps_start = bps_start_r ; 58 59//--------------------------------------------------------- 60 reg[ 7 : 0] rx_data_r ; // 61 //--------------------------------------------------------- 62 63 reg[ 7 : 0] rx_temp_data ; // 64 65 always @ ( posedge clk or negedge rst_n ) 66 if(! rst_n ) begin 67 rx_temp_data 68 num 69 rx_data_r 70 end 71 else if( rx_int ) begin // 72 if( clk_bps ) begin // , 8bit 1 2 73 num 74 case ( num) 75 4'd1:rx_temp_data[0] 76 4'd2:rx_temp_data [1] 77 4'd3:rx_temp_data [2] 78 4'd4:rx_temp_data [3] 79 4'd5:rx_temp_data [4] 80 4'd6:rx_temp_data [5] 81 4'd7:rx_temp_data [6] 82 4'd8:rx_temp_data [7] 83 default : ; 84 endcase 85 end 86 else if( num == 4'd12 ) begin//我們的標準接收模式下只有1+8+1(2)=11bit的有效數(shù)據(jù) 87 num 88 rx_data_r 89 end 90 end 那么,特權同學在這里有通過注釋解釋為什么是12個波特率周期:“我們的標準接收模式下只有1+8+1(2)=11bit的有效數(shù)據(jù)”。即使是11位,小梅哥還是無法理解為什么需要12個波特率時鐘。我們在實際使用的時候,一般不去考慮校驗位的問題,因此總共只有10位,也就是說,我寫的10位數(shù)據(jù)位的仿真模型和特權的11位方式不兼容。考慮到大多數(shù)的應用過程中是10位,因此小梅哥在特權大神的代碼上稍作修改,以適應10位模式。這里,將第52行代碼“else if( num==4'd12 ) begin ”改為“else if( num==4'd10 ) begin ”,將第86行代碼“else if( num == 4'd12 ) begin”改為“else if( num == 4'd10 ) begin”。通過這樣更改,就能夠適應1bit的數(shù)據(jù)接收。同時,小梅哥在實際調(diào)試中發(fā)現(xiàn),第45行的“bps_start_r 同樣有11個波特率時鐘,因此,小梅哥將發(fā)送部分的代碼稍作修改,以適應10bit的數(shù)據(jù)發(fā)送。特權同學原始代碼如下: 41 always @ ( posedge clk or negedge rst_n ) begin 42 if(! rst_n ) begin 43 bps_start_r 44 tx_en 45 tx_data 46 end 47 else if( neg_rx_int ) begin // 48 bps_start_r 49 tx_data 50 tx_en 51 end 52 else if( num==4'd11 ) begin // 53 bps_start_r 54 tx_en 55 end 56 end 57 58 assign bps_start = bps_start_r ; 59 60//--------------------------------------------------------- 61 reg rs232_tx_r ; 62 63 always @ ( posedge clk or negedge rst_n ) begin 64 if(! rst_n ) begin 65 num 66 rs232_tx_r 67 end 68 else if( tx_en ) begin 69 if( clk_bps ) begin 70 num 71 case ( num) 72 4'd0 : rs232_tx_r 73 4'd1 : rs232_tx_r 74 4'd2 : rs232_tx_r 75 4'd3 : rs232_tx_r 76 4'd4 : rs232_tx_r 77 4'd5 : rs232_tx_r 78 4'd6 : rs232_tx_r 79 4'd7 : rs232_tx_r 80 4'd8 : rs232_tx_r 81 4'd9 : rs232_tx_r 82 default : rs232_tx_r 83 endcase 84 end 85 else if( num==4'd11 ) num 86 end 87 end 88 這里,我們將第52行代碼“else if( num==4'd11 ) begin”修改為“else if( num==4'd10 ) begin”,將第85行代碼“else if( num==4'd11 ) num 由以上仿真結果可知,通過修改,該串口模塊已經(jīng)能夠?qū)崿F(xiàn)正確的收發(fā)了。接下來,小梅哥將通過板級驗證來對該模塊進行測試。 這里,小梅哥使用至芯科技提供的一塊入門級FPGA開發(fā)板來完成該模塊的板級驗證。以下為該開發(fā)板的照片: 該開發(fā)板上集成了一枚PL2303的USB轉串口芯片,因此,我們不再需要笨拙的9針串口線,只需要一根USB線將開發(fā)板與電腦的USB口相連,再安裝PL2303的驅(qū)動,即可在PC端模擬出一個串口端口,該串口端口的使用和傳統(tǒng)串口端口沒有任何差別。具體的串口驅(qū)動安裝過程如下圖所示: 通過以上步驟,我們就實現(xiàn)了PL2303型USB轉串口芯片驅(qū)動的安裝。接下來,我們需要根據(jù)各自使用的開發(fā)板的電路分配引腳,這里小梅哥先用圖文的形式介紹一下針對ZX2開發(fā)板的引腳分配及最終將配置文件下載到開發(fā)板的流程: 通過以上步驟,電路就已經(jīng)成功的配置到了我們的開發(fā)板上并運行起來了,這個時候,我們就需要通過調(diào)試軟件來進行調(diào)試,以驗證我們修改后的UART收發(fā)模塊能否穩(wěn)定運行。要調(diào)試我們的設計,我們還需要一個串口調(diào)試工具,通過串口調(diào)試工具,對我們編寫的串口模塊持續(xù)發(fā)送數(shù)據(jù),然后接收串口模塊發(fā)送回來的數(shù)據(jù),通過對比發(fā)送與接收的數(shù)據(jù),如果相同,則表明我們的模塊是能夠穩(wěn)定工作的,如果出現(xiàn)丟碼或者亂碼,表明收發(fā)過程中出現(xiàn)了錯誤,則表明我們設計的模塊存在工作不穩(wěn)定的情況,需要進一步修改優(yōu)化。 這里,我們使用程序匠人前輩編寫的強大串口調(diào)試軟件——串口獵人。該軟件的下載和安裝小梅哥就不多說了,當我們啟動串口獵人軟件后,會顯示以下界面,接下來小梅哥就直接以圖片配文字的形式來一步一步演示該軟件的使用: 通過以上測試,我們知道了,經(jīng)過小梅哥的修改,該串口模塊目前能夠以連續(xù)無間隔的發(fā)碼速度進行收發(fā),而且不存在任何誤碼和丟碼。因此,可以說,小梅哥的修改是成功的。 這一篇,主要帶領大家一起進行了串口代碼的分析、仿真模型的設計(testbench)、Quartus II軟件下使用Nativelink調(diào)用Modelsim-altera軟件進行仿真、仿真結果簡單分析、串口代碼的修改、串口模塊的板級驗證。相信通過此文,初學者能夠?qū)W到部分知識。 這是該系列文檔的第一篇,主要對特權大神的UART代碼進行了簡單的修改,以適應小梅哥自己的用途。下一篇,小梅哥將詳細介紹基于此模塊的擴展設計,其實擴展也沒多少內(nèi)容,主要就是加上可變波特率功能,順便介紹一下代碼中一些增加設計靈活性的技巧。第三篇,則是小梅哥開始手把手教大家從原理入手,設計我們自己的UART模塊,設計中會加入收發(fā)FIFO,并使用標準的Avalon ST接口協(xié)議,以形成IP核的形式。 |