“本文主要分享了在Verilog設(shè)計過程中一些經(jīng)驗與知識點,主要包括Verilog仿真時常用的系統(tǒng)任務(wù)、雙向端口的使用(inout)、邊沿檢測”
01
—
仿真時常用的系統(tǒng)任務(wù)($display,$fopen,$fscanf,$fwrite($fdisplay),$fclose,$random,$stop)
在RTL設(shè)計過程中,仿真的時候需要用一些系統(tǒng)函數(shù),這邊筆整理了部分Verilog設(shè)計中常用的系統(tǒng)函數(shù):$display,$fopen,$fscanf,$fwrite($fdisplay),$fclose,$random,$stop。
-
$display
這個函數(shù)系統(tǒng)任務(wù)的作用是用來在控制臺輸出信息。
-
$display("!!! Start Simulation !!!");直接顯示字符串
-
$display("data_display = %h hex %d decimal",100, 100); //顯示data_display 的16進(jìn)制 ,10進(jìn)制
-
$display("data_display = %o otal %b binary",100, 100);//顯示data_display 的8進(jìn)制 2進(jìn)制
-
$display("data_display = %d otal next line %bbinary", 100, 100);//主要展示換行操作
-
$display("simulation time is %t",$time);//顯示系統(tǒng)仿真時間
具體代碼如下:
regflag;//****************************** 系統(tǒng)顯示 $display *******************************reg[31:0]data_display;initialbegindata_display = 32'd100;flag = 0;$display("!!! Start Simulation !!!");//顯示16進(jìn)制 10進(jìn)制$display("data_display = %h hex %d decimal", 100, 100);//顯示8進(jìn)制 2進(jìn)制$display("data_display = %o otal %b binary", 100, 100);//ASCII碼$display("data_display has %c ascii character value",64);//顯示10進(jìn)制 換行 2進(jìn)制$display("data_display = %d otal next line %b binary", 100, 100);//顯示系統(tǒng)仿真時間$display("simulation time is %t",$time);flag = 1;end
仿真結(jié)果如下圖所示:

在第五行展示了換行功能;為了驗證系統(tǒng)仿真時間,筆者這邊用flag參數(shù)拉高來測試時間,時間結(jié)果如下圖顯示,和顯示時間一致;

-
$fopen

-
$fscanf
//****************************** 讀文件 $fscanf *******************************//宏定義,定義數(shù)據(jù)長度`define DATA_LENGTH 8//定義RAM大小reg signed [15:0] Sig0 [`DATA_LENGTH-1:0];reg [15:0]Sig1[`DATA_LENGTH-1:0];//定義句柄integer data_file0;integerdata_file1;integeri;//讀取函數(shù)initialbegin#200;//打開句柄data_file0 = $fopen("file/rd_data0_fpga.txt","r");data_file1 = $fopen("file/rd_data1_fpga.txt","r");for(i = 0;i < `DATA_LENGTH; i = i + 1)begin$fscanf(data_file0,"%d",Sig0[i]); //讀取十進(jìn)制$fscanf(data_file1,"%h",Sig1[i]); //讀取十六進(jìn)制end$fclose(data_file0); ////關(guān)閉這個句柄$fclose(data_file1); ////關(guān)閉這個句柄end
仿真結(jié)果如下圖所示:

-
$fwrite($fdisplay)
代碼如下所示:
仿真結(jié)果如下所示//************************** 寫文件 $fwrite($fdisplay) *************************//****** $fwrite 寫下一個數(shù)不會自動轉(zhuǎn)行,所以要加//將讀取的Sig0,Sig1重新寫進(jìn)兩個新的txt中//定義句柄integer data_wr0;integer data_wr1;integer m;//讀取函數(shù)initialbegin#400;//打開句柄data_wr0 = $fopen("file/wr_data1_fpga.txt","w");data_wr1=$fopen("file/wr_data2_fpga.txt","w");for(m = 0;m < `DATA_LENGTH; m = m + 1)begin@(clk);$fwrite(data_wr0,"%d ",Sig0[m]); //向txt寫十進(jìn)制 寫下一個數(shù)不會自動轉(zhuǎn)行,所以要加$fwrite(data_wr1,"%h ",Sig1[m]); //向txt寫十六進(jìn)制 寫下一個數(shù)不會自動轉(zhuǎn)行,所以要加end//關(guān)閉這個句柄$fclose(data_wr0);$fclose(data_wr1);end

$fwrite和$fdisplay的區(qū)別,$fwrite寫下一個數(shù)不會自動轉(zhuǎn)行,可以加 來轉(zhuǎn)行,$fdisplay則會自動轉(zhuǎn)行。
-
$fdisplay
仿真結(jié)果如下圖所示://****** $fdisplay//將讀取的Sig0,Sig1重新寫進(jìn)兩個新的txt中//定義句柄integer data_wr2;integer data_wr3;integer j;//讀取函數(shù)initialbegin#600;//打開句柄data_wr2 = $fopen("file/wr_data3_fpga.txt","w");data_wr3=$fopen("file/wr_data4_fpga.txt","w");for(j = 0;j < `DATA_LENGTH; j = j + 1)begin@(clk);$fdisplay(data_wr2,"%d",Sig0[j]); //向txt寫十進(jìn)制 寫下一個數(shù)會自動轉(zhuǎn)行,所以不需要加$fdisplay(data_wr3,"%h",Sig1[j]); //向txt寫十六進(jìn)制 寫下一個數(shù)會自動轉(zhuǎn)行,所以不需要加end//關(guān)閉這個句柄$fclose(data_wr2);$fclose(data_wr3);end

-
$fclose
-
$stop
02
—
雙向端口的使用(inout)
根據(jù)Verilog的語法定義,IO的端口可以定義為三種類型input、output和inout,其中inout為雙向端口。雙向端口通過控制三態(tài)門來實現(xiàn),其結(jié)構(gòu)框圖如下所示。

-
當(dāng)T為1的時候,I端忽略(高阻),O端電平 = IO端電平;
-
當(dāng)T為0的時候,IO端電平=I端電平=O端電平;

同樣,Xilinx也有三態(tài)門的源語assign io = ( !t ) ? i : 1'bz ;assign o = io;
參考:Xilinx 7 Series FPGA Libraries Guide for HDL Design
仿真結(jié)果如下:IOBUF.DRIVE ( 12 ), // Specify the output drive strength.IBUF_LOW_PWR ( "TRUE" ), // Low Power - "TRUE", High Performance = "FALSE".IOSTANDARD ( "DEFAULT" ), // Specify the I/O standard.SLEW ( "SLOW" ) // Specify the output slew rate) IOBUF_inst (.O(o1 ),//Bufferoutput.IO(io),//Bufferinoutport(connectdirectlytotop-levelport).I(i1),//Bufferinput.T ( t ) // 3-state enable input, high=input, low=output);

可以看出:
-
當(dāng)T=1的時候,O端電平=IO端電平;
-
當(dāng)T=0的時候,O端電平=IO端電平=I端電平。
03
—
邊沿檢測
在程序設(shè)計過程中,經(jīng)常需要檢測一個脈沖信號的上升沿或者下降沿,下面給大家介紹如何使用Verilog實現(xiàn)對脈沖信號的邊沿進(jìn)行檢測。時鐘信號與脈沖信號如下圖所示。

Verilog代碼如下:
上述程序經(jīng)過綜合后,其RTL結(jié)構(gòu)如下圖所示,由兩個D觸發(fā)器和兩個與門組成。module edge_detection(input wire clk,input wire rst,input wire sin_pulse,output wire sout_r, //上升沿檢測output wire sout_f //下降沿檢測);//--------------------------------------------------------------------------------reg sin_reg0,sin_reg1;//--------------------------------------------------------------------------------clk or posedge rst)beginif(rst)beginsin_reg0 <= 0;sin_reg1 <= 0;endelsebeginsin_reg0 <= sin_pulse;sin_reg1 <= sin_reg0;endend//--------------------------------------------------------------------------------assign sout_r = sin_reg0 & (~sin_reg1); //上升沿檢測=(~sin_reg0)&sin_reg1;//下降沿檢測//--------------------------------------------------------------------------------

仿真后的結(jié)果如下圖所示,可以看出sout_r為上升沿檢測結(jié)果,sout_f為下降沿檢測結(jié)果。

審核編輯:郭婷
-
Verilog
+關(guān)注
關(guān)注
30文章
1374瀏覽量
114524 -
代碼
+關(guān)注
關(guān)注
30文章
4968瀏覽量
73960
原文標(biāo)題:Verilog基礎(chǔ)知識學(xué)習(xí)筆記(一)
文章出處:【微信號:zhuyandz,微信公眾號:FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
fpga應(yīng)用篇(二):邊沿檢測
關(guān)于FPGA進(jìn)行外部邊沿檢測,檢測不準(zhǔn)確問題?
邊沿檢測的目的及電路原理分析
Verilog HDL語言中任務(wù)與函數(shù)的比較
剖析verilog2005的騷操作之對數(shù)函數(shù)
FPGA學(xué)習(xí)-邊沿檢測技術(shù)
Verilog實現(xiàn)邊沿檢測的原理
Verilog系統(tǒng)函數(shù)和邊沿檢測
評論