FPGA內部資料大匯集_第1頁
FPGA內部資料大匯集_第2頁
FPGA內部資料大匯集_第3頁
FPGA內部資料大匯集_第4頁
FPGA內部資料大匯集_第5頁
已閱讀5頁,還剩45頁未讀 繼續免費閱讀

付費下載

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、第第1414章章 對驗證的支持對驗證的支持學習內容學習內容1.理解理解Verilog文本輸出文本輸出2.理解不同的讀取仿真時間的系統函數理解不同的讀取仿真時間的系統函數3.理解理解 Verilog文件文件I/O功能功能驗證系統中的任務驗證系統中的任務(task)(task)及函數及函數(function)(function)Verilog讀取當前仿真時間的系統函數讀取當前仿真時間的系統函數 $time $stime $realtimeVerilog支持文本輸出的系統任務:支持文本輸出的系統任務: $display $strobe $write $monitor仿真時間仿真時間訪問仿真時間訪問仿

2、真時間$time,$realtime,和和$stime函數返回當前仿真時間。函數返回當前仿真時間。這些函數的返回值使用調用模塊中這些函數的返回值使用調用模塊中timescale定義的時間單位定義的時間單位$time返回一個返回一個64位整數時間值。位整數時間值。$stime返回一個返回一個32位整數時間值。位整數時間值。$realtime返回一個實數時間值。返回一個實數時間值。 $stime函數返回一個函數返回一個32位整數時間值。對大于位整數時間值。對大于232的時間,返回模的時間,返回模232的值。的值。使用它可以節省顯示及打印空間。使用它可以節省顯示及打印空間。 輸出格式化時間信息輸出格

3、式化時間信息timescale 10ns / 100psmodule top; reg in1; not m1( o1, in1); initial begin $timeformat(-9, 2, ns, 10); in1 = 0; #8 in1 = 1; #10 $display(%t %b %b, $realtime, in1, o1); #10 $finish; endendmodule在這個例子中,顯示在這個例子中,顯示的時間為:的時間為:180.00 nsunit:0(s)到到-15(fs)之間的之間的整數,表示時間度量整數,表示時間度量precision:要顯示的十進:要顯示的十

4、進制小數位數。制小數位數。suffix:在時間值后顯示的:在時間值后顯示的字符串字符串min_width:顯示前三項的:顯示前三項的最小寬度最小寬度 若使用多個若使用多個timescale,以最小的時間精度顯示時間值。,以最小的時間精度顯示時間值。可用系統任務可用系統任務$timeformat結合格式符結合格式符%t全局控制時間顯示方式。全局控制時間顯示方式。$timeformat系統任務的語法為:系統任務的語法為: $timeformat(,);輸出格式化時間信息輸出格式化時間信息timescale 1 ns / 10 psmodule top; reg in1; not #9.53 n1

5、(o1, in1); initial begin $display(time realtime stime t in1 t o1 ); $timeformat(-9, 2, ns, 10); $monitor(%d %t %d t %b t %b, $time, $realtime, $stime, in1, o1); in1 = 0; #10 in1 = 1; #10 $finish; endendmoduletime realtime stime in1 o1 0 0.00ns 0 0 x10 9.53ns 10 0 110 10.00ns 10 1 120 19.53ns 20 1 0輸

6、出格式化時間信息輸出格式化時間信息對#延遲,Verilog將延遲值舍入最近(四舍五入)時間精度值。例如,上面的例子修改為:timescale 1ns/ 100psnot #9.42 n1 (o1, in1);結果為:time realtime stime in1 o1 0 0.00ns 0 0 x 9 9.40ns 9 0 110 10.00ns 10 1 119 19.40ns 19 1 0timescale 1ns/ 100psnot #9.49 n1 (o1, in1);結果為:time realtime stime in1 o1 0 0.00ns 0 0 x 9 9.50ns 9 0

7、110 10.00ns 10 1 119 19.50ns 19 1 0顯示信號值顯示信號值 $displaydisplay$display輸出參數列表中信號的當前值。輸出參數列表中信號的當前值。 語法:語法:$display(“ format_specifiers”, )$display輸出時輸出時自動換行自動換行。 $display ($ time, “%b t %h t %d t %o”, sig1, sig2, sig3, sig4); $display ($ time, “%b t”, sig1, “%h t”, sig2, “% d t”, sig3, “%o”, sig4);$di

8、splay支持二進制、八進制、十進制和十六進制。缺省基數為十進制。支持二進制、八進制、十進制和十六進制。缺省基數為十進制。 $display (sig1, sig2, sig3, sig4); $displayb (sig1, sig2, sig3, sig4); $displayo (sig1, sig2, sig3, sig4); $displayh (sig1, sig2, sig3, sig4); %h %o %d %b %c %s %v %m %t hex octal decimal binary ASCII string strength module time t n %0d t

9、ab 換行 反斜杠 雙引號 上述的ASCII表示 無前導0的十進制數格式符轉義符顯示信號值顯示信號值$writewrite和和$strobestrobe$write與與$display相同,不同的是不會自動換行。相同,不同的是不會自動換行。 $write($time, “%b t %h t %d t %o t”, sig1, sig2, sig3, sig4); $strobe與與$display相同,不同的是在仿真時間前進之前的信號值。相同,不同的是在仿真時間前進之前的信號值。而而$display和和$write立即顯示信號值。也就是說立即顯示信號值。也就是說$strobe顯示穩定狀態顯示穩

10、定狀態信號值,而信號值,而$display和和$write可以顯示信號的中間狀態值。可以顯示信號的中間狀態值。 $strobe($time, “%b t %h t %d t %o t”, sig1, sig2, sig3, sig4);$write和和$strobe都支持多種數基,缺省為十進制。都支持多種數基,缺省為十進制。$writeb$strobeb $writeo$strobeo $writeh$strobeh顯示信號值顯示信號值$writewrite和和$strobestrobe下面是模塊下面是模塊textio仿真的輸出:仿真的輸出:$writeb輸出:輸出: 0 xxxxxxxx x

11、 注意注意data是是32位數據,由位數據,由8位十六位十六進制數表示。時間以沒有前導零進制數表示。時間以沒有前導零的十進制形式輸出。的十進制形式輸出。 缺省情況下,值以十進制顯示,缺省情況下,值以十進制顯示,忽略前導零,與忽略前導零,與%0d格式符相同。格式符相同。可以在一個格式化符前插入一個可以在一個格式化符前插入一個0使使Verilog忽略開頭的零。忽略開頭的零。 $displayh: 00000000000000f 00000010 1 注意當前時間,一個注意當前時間,一個64位量,需位量,需要要16個十六進制的數。個十六進制的數。$display: 10 20$strobe: 10

12、30module textio; reg flag; reg 31: 0 data; initial begin $writeb(%d, $time, ,%h t, data, , flag, n); #15 flag = 1; data = 16; $displayh($time, ,data, , flag); end initial begin #10 data = 20; $strobe($time, , data); $display($time, , data); data = 30; endendmodule監視信號值監視信號值$monitormonitor$monitor持續監

13、視參數列表中的變量。持續監視參數列表中的變量。在一個時間片中,參數表中任何信號發生變化,在一個時間片中,參數表中任何信號發生變化,$monitor將在仿真時將在仿真時間前進前顯示參數表的信號值。間前進前顯示參數表的信號值。后面的后面的$monitor將覆蓋前面的將覆蓋前面的$monitor。可以用系統任務可以用系統任務$monitoron和和$monitoroff控制持續監視。控制持續監視。$monitor支持多種基數。缺省為十進制。支持多種基數。缺省為十進制。 $monitor ($ time, “%b t %h t %d t %o”, sig1, sig2, sig3, sig4);監示信

14、號值監示信號值$monitormonitor$monitor是唯一的不斷輸出信號值的系統任務。其它系統任務在返回值之后是唯一的不斷輸出信號值的系統任務。其它系統任務在返回值之后就結束。就結束。$monitor和和$strobe一樣,顯示參數列表中信號的穩定狀態值,也就是在仿真一樣,顯示參數列表中信號的穩定狀態值,也就是在仿真時間前進之前顯示信號。在一個時間步中,參數列表中信號值的任何變化將時間前進之前顯示信號。在一個時間步中,參數列表中信號值的任何變化將觸發觸發$monitor 。但。但$time,$stime,$realtime不能觸發。不能觸發。任何后續的任何后續的$monitor覆蓋前面

15、調用的覆蓋前面調用的$monitor。只有新的。只有新的$monitor的參數列的參數列表中的信號被監視,而前面的表中的信號被監視,而前面的$monitor的參數則不被監視。的參數則不被監視。可以用可以用$monitoron和和$monitoroff系統任務控制持續監視,使用戶可以在仿真系統任務控制持續監視,使用戶可以在仿真時只監視特定時間段的信號。時只監視特定時間段的信號。$monitor參數列表的形式與參數列表的形式與$display相同。相同。$monitor支持多種基數。缺省為十進制。支持多種基數。缺省為十進制。$monitorb$monitoro$monitorh文件輸出文件輸出$f

16、open打開一個文件并返回一個多通道描述符(打開一個文件并返回一個多通道描述符(MCD)。)。 MCD是與文件唯一對應的是與文件唯一對應的32位無符號整數。位無符號整數。 如果文件不能打開并進行寫操作,如果文件不能打開并進行寫操作,MCD將等于將等于0。 如果文件成功打開,如果文件成功打開,MCD中的一位將被置位。中的一位將被置位。以以$f開始的顯示系統任務將輸出寫入與開始的顯示系統任務將輸出寫入與MCD相對應的文件中。相對應的文件中。 . . .integer MCD1; MCD1 = $fopen(); $fdisplay( MCD1, P1, P2, ., Pn); $fwrite( M

17、CD1, P1, P2, ., Pn); $fstrobe( MCD1, P1, P2, ., Pn); $fmonitor( MCD1, P1, P2, ., Pn); $fclose( MCD1);. . .文件輸出文件輸出$fopen打開參數中指定的文件并返回一個打開參數中指定的文件并返回一個32位無符號位無符號 整數整數MCD,MCD是與文件一一對應的多通道描述符。如果文件不能打開并進行是與文件一一對應的多通道描述符。如果文件不能打開并進行寫操作,它返回寫操作,它返回0。$fclose關閉關閉MCD指定的通道。指定的通道。輸出信息到輸出信息到log文件和標準輸出的四個格式化顯示任務文件

18、和標準輸出的四個格式化顯示任務($display, $write, $monitor, $strobe)都有相對應的任務用于向指定文件輸出。)都有相對應的任務用于向指定文件輸出。這些對應的任務(這些對應的任務($fdisplay,$fwrite,$fmonitor,$fstrobe)的參數形式)的參數形式與對應的任務相同,只有一個例外:第一個參數必須是一個指定向何與對應的任務相同,只有一個例外:第一個參數必須是一個指定向何哪個文件輸出的哪個文件輸出的MCD。MCD可以是一個表達式,但其值必須是一個可以是一個表達式,但其值必須是一個32位的無符號整數。這個值決定了該任務向哪個打開的文件寫入位的無

19、符號整數。這個值決定了該任務向哪個打開的文件寫入。MCD可以看作由可以看作由32個標志構成的組,每個標志代表一個單一的輸出個標志構成的組,每個標志代表一個單一的輸出通道。通道。文件輸出文件輸出. . .integer messages, broadcast, cpu_chann, alu_chann;initialbegin cpu_chann = $fopen( cpu.dat); if(! cpu_chann) $finish; alu_chann = $fopen( alu.dat); if(! alu_chann) $finish;/ channel to both cpu. dat

20、and alu. dat messages = cpu_chann | alu_chann;/ channel to both files, standard out, and verilog. log broadcast = 1 | messages;endalways ( posedge clock) / print the following to alu. dat $fdisplay( alu_chann, acc= %h f=%h a=%h b=%h, acc, f, a, b);/* at every reset print a message to alu. dat, cpu.

21、dat, standard outputand the verilog. log file */always ( negedge reset) $fdisplay( broadcast, system reset at time %d, $time);. . .必須聲明為integer通道0(編號為1)為標準輸出及verilog.log文件輸入文件輸入Verilog中有兩個系統任務可以將數據文件讀入寄存器組。一個讀取二進中有兩個系統任務可以將數據文件讀入寄存器組。一個讀取二進制數據,另一個讀取十六進制數據:制數據,另一個讀取十六進制數據:$readmemb $readmemb (file_na

22、me, ); $readmemb (file_name, , ); $readmemb (file_name, , , );$readmemh $readmemh ( file_name, ); $readmemh ( file_name, , ); $readmemh ( file_name, , , );文件輸入文件輸入系統任務系統任務$readmemb和和$readmemh從一個文本文件讀取數據并寫入存儲器。從一個文本文件讀取數據并寫入存儲器。如果數據為二進制,使用如果數據為二進制,使用$readmemb;如果數據為十六進制,使用;如果數據為十六進制,使用$readmemh。filena

23、me指定要調入的文件。指定要調入的文件。mem_name指定存儲器名。指定存儲器名。start和和finish決定存儲器將被裝載的地址。決定存儲器將被裝載的地址。Start為開始地址,為開始地址,finish為結束地為結束地址。如果不指定開始和結束地址,址。如果不指定開始和結束地址,$readmem按從低端開始讀入數據,與說按從低端開始讀入數據,與說明順序無關。明順序無關。文件輸入文件輸入$readmemb和和$readmemh的文件格式的文件格式 : $readmemb(mem_file. txt, mema);0000_00000110_0001 0011_0010/ 地址地址3255沒有

24、定義沒有定義100 / hex1111_1100/地址地址2571022沒有定義沒有定義3FF1110_0010文本文件:文本文件:mem_file.txt000000000011000011001100103111111002561110001010230 7聲明的存儲器組聲明的存儲器組reg 0:7 mema0:1023module readmem;reg 0:7 mema 0:1023initial$readmemb(“mem_file.txt”, mema);endmodule文件輸入文件輸入$readmemb和和$readmemh的文件格式的文件格式 : $readmemb(mem_

25、file. txt, mema);可以指定二進制(可以指定二進制(b)或十六進制()或十六進制(h)數)數用下劃線(用下劃線(_)提高可讀性。)提高可讀性。可以包含單行或多行注釋。可以包含單行或多行注釋。可以用空格和換行區分存儲器字。可以用空格和換行區分存儲器字。可以給后面的值設定一個特定的地址,格式為:可以給后面的值設定一個特定的地址,格式為: (hex_address) 十六進制地址的大小寫不敏感。十六進制地址的大小寫不敏感。 在在和數字之間不允許有空格。和數字之間不允許有空格。 復習復習問題:問題:哪個系統任務顯示參數列表中信號的穩定狀態值?哪個系統任務顯示參數列表中信號的穩定狀態值?每

26、次能打開多少個輸出文件?每次能打開多少個輸出文件?解答:解答:系統任務系統任務$monitor和和$strobe顯示參數列表中信號的穩定狀態值。顯示參數列表中信號的穩定狀態值。這些任務在時間前進之前輸出信號值。這些任務在時間前進之前輸出信號值。每次只能打開一個輸出文件,包括已由仿真器打開的任何每次只能打開一個輸出文件,包括已由仿真器打開的任何log文件。文件。第十五章第十五章 Verilog Test Bench Verilog Test Bench使用簡介使用簡介學習內容:學習內容:用一個復雜的用一個復雜的test bench復習設計的組織與仿真復習設計的組織與仿真建立建立test benc

27、h通常使用的編碼風格及方法通常使用的編碼風格及方法設計組織設計組織虛線表示編譯時檢測輸入文件是否存在及可讀并允許生成輸出文件。 test benchtest bench組織組織簡單的簡單的test bench向要驗證的設計提供向量,人工驗證輸出。向要驗證的設計提供向量,人工驗證輸出。復雜的復雜的test bench是自檢測的,其結果自動驗證。是自檢測的,其結果自動驗證。 stimulus要驗證的設計簡單的test bench復雜的test bench激勵驗證結果要驗證的設計并行塊并行塊forkjoin塊在測試文件中很常用。他們的并行特性使用戶可以說明塊在測試文件中很常用。他們的并行特性使用戶可

28、以說明絕對時間,并且可以并行的執行復雜的過程結構,如循環或任務。絕對時間,并且可以并行的執行復雜的過程結構,如循環或任務。module inline_ tb; reg 7: 0 data_ bus; / instance of DUT initial fork data_bus = 8b00; #10 data_bus = 8h45; #20 repeat (10) #10 data_bus = data_bus + 1; #25 repeat (5) #20 data_bus = data_bus 1; #140 data_bus = 8h0f; joinendmodule上面的兩個repe

29、at循環從不同時間開始,并行執行。象這樣的特殊的激勵集在單個的beginend塊中將很難實現。 Time | data_ bus 0 | 8b0000_000010 | 8b0100_010130 | 8b0100_011040 | 8b0100_011145 | 8b1000_111050 | 8b1000_111160 | 8b1001_000065 | 8b0010_000070 | 8b0010_000180 | 8b0010_001085 | 8b0100_010090 | 8b0100_0101100 | 8b0100_0110105 | 8b1000_1100110 | 8b10

30、00_1101120 | 8b1000_1110125 | 8b0001_1100140 | 8b0000_1111包含文件包含文件包含文件用于讀入代碼的重復部分或公共數據。包含文件用于讀入代碼的重復部分或公共數據。 module clk_gen (clk);output clk; reg clk;include common.txtinitial begin while ($ time sim_end) begin clk = initial_clock; #(period/2) clk = !initial_clock; #(period/2); end $finish;endendmod

31、ule在上面的例子中,公共參數在一個獨立的文件中定義。此文件在不同在上面的例子中,公共參數在一個獨立的文件中定義。此文件在不同的仿真中可被不同的測試文件調用。的仿真中可被不同的測試文件調用。 / common. txt/ clock and simulator constantsparameter initial_clock = 1;parameter period = 15;parameter max_cyc = 100;parameter sim_end = period * max_cyc施加激勵施加激勵產生激勵并加到設計有很多產生激勵并加到設計有很多 種方法。一些常用的方法有:種方法。

32、一些常用的方法有:從一個從一個initial塊中施加線激勵塊中施加線激勵從一個循環或從一個循環或always塊施加激勵塊施加激勵從一個向量或整數數組施加激勵從一個向量或整數數組施加激勵記錄一個仿真過程,然后在另一個仿真中回放施加激勵記錄一個仿真過程,然后在另一個仿真中回放施加激勵線性激勵線性激勵線性激勵有以下特性:線性激勵有以下特性: 只有變量的值改變時才列出只有變量的值改變時才列出 易于定義復雜的時序關系易于定義復雜的時序關系 對一個復雜的測試,測試基準對一個復雜的測試,測試基準(test bench)可能非常大可能非常大module inline_ tb; reg 7: 0 data_ b

33、us, addr; wire 7: 0 results; DUT u1 (results, data_ bus, addr); initial fork data_bus = 8h00; addr = 8h3f; #10 data_ bus = 8h45; #15 addr = 8hf0; #40 data_ bus = 8h0f; #60 $finish; joinendmodule循環激勵循環激勵從循環產生激勵有以下特性:從循環產生激勵有以下特性: 在每一次循環,修改同一組激勵變量在每一次循環,修改同一組激勵變量 時序關系規則時序關系規則 代碼緊湊代碼緊湊 module loop_tb;

34、reg clk; reg 7:0 stimulus; wire 7:0 results; integer i; DUT u1 (results, stimulus); always begin / clock generation clk = 1; #5 clk = 0; #5 end initial begin for (i = 0; i 1; i = i - 1) / 循環循環 #50 stimulus = stim_arrayi ; #30 $finish; endendmodule矢量采樣矢量采樣在仿真過程中可以對激勵和響應矢量進行采樣,作為其它仿真的激在仿真過程中可以對激勵和響應矢量

35、進行采樣,作為其它仿真的激勵和期望結果。勵和期望結果。module capture_tb; parameter period = 20 reg 7:0 in_vec, out_vec; integer RESULTS, STIMULUS; DUT u1 (out_ vec, in_ vec); initial begin STIMULUS = $fopen(stimulus. txt) ; RESULTS = $fopen(results. txt) ; fork if (STIMULUS != 0 ) forever #( period/2) $fstrobeb (STIMULUS, %b,

36、 in_vec); if (RESULTS != 0 ) #( period/2) forever #( period/2) $fstrobeb (RESULTS, %b, out_vec); join endendmodule矢量回放矢量回放保存在文件中的矢量反過來可以作為激勵保存在文件中的矢量反過來可以作為激勵module read_file_tb; parameter num_vecs = 256; reg 7:0 data_bus; reg 7:0 stim num_vecs-1:0; integer i; DUT u1 (results, data_bus) initial begi

37、n / Vectors are loaded $readmemb (vec. txt, stim); for (i =0; i num_vecs ; i = i + 1) #50 data_bus = stimi; endendmodule/ 激勵文件激勵文件vec.txt001110000011100100111010001111000011000000101000000110000111100010111000.使用矢量文件輸入使用矢量文件輸入/輸出的優點:輸出的優點: 激勵修改簡單激勵修改簡單 設計反復驗證時直接使用工具比較矢量文件。設計反復驗證時直接使用工具比較矢量文件。錯誤及警告報告

38、錯誤及警告報告使用文本或文件輸出類的系統任務報告錯誤及警告使用文本或文件輸出類的系統任務報告錯誤及警告always ( posedge par_err) $display ( error-bus parity errors detected);always ( posedge cor_err) $display(warning-correctable error detected);一個更為復雜的一個更為復雜的test bench可以:可以: 不但能報告錯誤,而能進行一些動作,如取消一個激勵塊并跳轉不但能報告錯誤,而能進行一些動作,如取消一個激勵塊并跳轉到下一個激勵。到下一個激勵。 在內部保持

39、錯誤跟蹤,并在每次測試結束時產生一個錯誤報告。在內部保持錯誤跟蹤,并在每次測試結束時產生一個錯誤報告。強制激勵強制激勵在過程塊中,可以用兩種持續賦值語句驅動一個值或表達式到一個信號。在過程塊中,可以用兩種持續賦值語句驅動一個值或表達式到一個信號。 過程持續賦值通常不可綜合,所以它們通常用于測試基準描述。過程持續賦值通常不可綜合,所以它們通常用于測試基準描述。 對每一種持續賦值,都有對應的命令停止信號賦值。對每一種持續賦值,都有對應的命令停止信號賦值。 不允許在賦值語句內部出現時序控制。不允許在賦值語句內部出現時序控制。對一個寄存器使用對一個寄存器使用assign和和deassign,將覆蓋所有

40、其他在該信號上的賦值。,將覆蓋所有其他在該信號上的賦值。這個寄存器可以是這個寄存器可以是RTL設計中的一個節點或測試基準中在多個地方賦值的設計中的一個節點或測試基準中在多個地方賦值的信號等。信號等。 initial begin #10 assign top.dut.fsm1.state_reg = init_state ; #20 deassign top.dut.fsm1.state_reg ; end在在register和和net上(例如一個門級掃描寄存器的輸出)使用上(例如一個門級掃描寄存器的輸出)使用force和和release,將覆蓋該信號上的所有其他驅動。將覆蓋該信號上的所有其他驅

41、動。 initial begin #10 force top. dut. counter. scan_ reg. q = 0 ; #20 release top. dut. counter. scan_ reg. q ; end強制激勵強制激勵可以強制可以強制(force)并釋放一個信號的指定位、部分位或連接,但位的指定不能并釋放一個信號的指定位、部分位或連接,但位的指定不能是一個變量(例如是一個變量(例如out_veci)不能對不能對register的一位或部分位使用的一位或部分位使用assign和和deassign對同一個信號,對同一個信號,force覆蓋覆蓋assign。后面的后面的as

42、sign或或force語句覆蓋以前相同類型的語句。語句覆蓋以前相同類型的語句。如果對一個信號先如果對一個信號先assign然后然后force,它將保持,它將保持force值。在對其進行值。在對其進行release后,后,信號為信號為assign值。值。如果在一個信號上如果在一個信號上force多個值,然后多個值,然后release該信號,則不出現任何該信號,則不出現任何force值。值。 在上面兩個例子中,在在上面兩個例子中,在 net或或register上所賦的常數值,覆蓋所有在時刻上所賦的常數值,覆蓋所有在時刻10和時刻和時刻20之間可能發生在該信號上的其他任何賦值或驅動。如果所賦值是一個

43、表達式,之間可能發生在該信號上的其他任何賦值或驅動。如果所賦值是一個表達式,則該表達式將被持續計算。則該表達式將被持續計算。建立時鐘建立時鐘例例1:雖然有時候在設計中給出時鐘,但通常時鐘是測試基準中建立。:雖然有時候在設計中給出時鐘,但通常時鐘是測試基準中建立。下面介紹如何產生不同的時鐘波形。同時給出用門級和行為級描述方法下面介紹如何產生不同的時鐘波形。同時給出用門級和行為級描述方法下面是一個簡單對稱時鐘的例子:下面是一個簡單對稱時鐘的例子: reg ck;always begin #( period/2) ck = 0; #( period/2) ck = 1;endreg go; wire

44、 ck;nand #( period/2) u1 (ck, ck, go);initial begin go = 0; #( period/2) go = 1;end注意:注意:在一些仿真器中,時鐘與設計使用相同的抽象級描述時,仿真性能會好一些。 產生的波形(假定產生的波形(假定period為為20)建立時鐘建立時鐘例例2:有啟動延時的對稱時鐘的例子:有啟動延時的對稱時鐘的例子:reg ck;initial begin ck = 0; #( period) forever #( period/2) ck = !ck;endreg go; wire ck;nand #( period/2) u1

45、 (ck, ck, go);initialbegin go = 0; #(period) go = 1;end注意:注意:在行為描述中,在時間0將CK初始化為0;而在結構描述中,直到period/2才影響CK值。當go信號在時間0初始化時,CK值到period/2才變化。可以使用特殊命令force和release立即影響CK值。產生的波形(假定產生的波形(假定period為為20)建立時鐘建立時鐘例例3:有不規則啟動延時的不對稱時鐘的例子:有不規則啟動延時的不對稱時鐘的例子:注意:注意:在行為描述中,CK值立刻被影響;而在結構描述中,在傳播延時后才輸出正確波形。產生的波形(假定產生的波形(假定

46、period為為20)reg ck;initial begin #(period + 1) ck = 1; #(period/2 1) forever begin #(period/4) ck = 0; #(3*period/4) ck = 1; endendreg go; wire ck;nand #(3*period/4, period/4) u1(ck, ck, go);initial begin #(period/4 + 1) go = 0; #(5*period/4 1) go = 1;end使用使用tasktask在在test bench中使用中使用task可以壓縮重復操作,提高代

47、碼效率。可以壓縮重復操作,提高代碼效率。module bus_ctrl_tb; reg 7: 0 data; reg data_valid, data_rd; cpu u1 (data_valid, data,data_rd); initial begin cpu_driver (8b0000_0000); cpu_driver (8b1010_1010); cpu_driver (8b0101_0101); end task cpu_driver; input 7:0 data_in; begin #30 data_valid = 1; wait (data_rd = 1); #20 dat

48、a = data_ in; wait (data_rd = 0); #20 data = 8hzz; #30 data_valid = 0; end endtaskendmodule 使用使用tasktask產生的波形產生的波形復習復習問題:問題:什么操作可以容易的在什么操作可以容易的在forkjoin塊做到,而不容易在塊做到,而不容易在beginend塊做到?塊做到?通常怎樣產生規則激勵和不規則激勵?通常怎樣產生規則激勵和不規則激勵?從一個文件中讀取激勵時使用什么數據類型?從一個文件中讀取激勵時使用什么數據類型?在行為級時鐘模型中能做哪些在門級時鐘模型中很難或不能作到的事?在行為級時鐘模型中

49、能做哪些在門級時鐘模型中很難或不能作到的事? 解答:解答:forkjoin塊中不但能夠賦值,還可以并行執行循環、條件語句、任務或函塊中不但能夠賦值,還可以并行執行循環、條件語句、任務或函數調用。數調用。循環或循環或always塊能有效地產生規則激勵,不規則激勵適合用在塊能有效地產生規則激勵,不規則激勵適合用在initial塊產生。塊產生。用寄存器組(存儲器)并用用寄存器組(存儲器)并用$readmem系統任務從一個文件以讀取向量。系統任務從一個文件以讀取向量。行為級代碼可以很容易地產生一個啟動時間不規則的時鐘波形,并且可以行為級代碼可以很容易地產生一個啟動時間不規則的時鐘波形,并且可以在時刻零

50、初始化時鐘。在時刻零初始化時鐘。 第第1616章章 存儲器建模存儲器建模學習內容學習內容: 如何描述存儲器如何描述存儲器 如何描述雙向端口如何描述雙向端口存儲器件建模存儲器件建模描述存儲器必須做兩件事:描述存儲器必須做兩件事: 說明一個適當容量的存儲器。說明一個適當容量的存儲器。 提供內容訪問的級別,例如:提供內容訪問的級別,例如: 只讀只讀 讀和寫讀和寫 寫同時讀寫同時讀 多個讀操作,同時進行單個寫操作多個讀操作,同時進行單個寫操作 同時有多個讀和多個寫操作,有保證一致性的方法同時有多個讀和多個寫操作,有保證一致性的方法簡單簡單ROMROM描述描述 下面的下面的ROM描述中使用二維寄存器組定

51、義了一個存儲器描述中使用二維寄存器組定義了一個存儲器mem。ROM的數的數據單獨保存在文件據單獨保存在文件my_rom_data中,如右邊所示。通常用這種方法使中,如右邊所示。通常用這種方法使ROM數據獨立于數據獨立于ROM描述。描述。timescale 1ns/10psmodule myrom (read_data, addr, read_en_); input read_en_; input 3:0 addr; output 3:0 read_data; reg 3:0 read_data; reg 3:0 mem 0:15; initial $readmemb (my_rom_data,

52、 mem); always ( addr or read_en_) if (! read_en_) read_data = memaddr;endmodulemy_rom_data0000010111000011110100100011111110001001100000011101101000011101簡單的簡單的RAMRAM描述描述 RAM描述比描述比ROM略微復雜,因為必須既有讀功能又有寫功能,而讀寫通常略微復雜,因為必須既有讀功能又有寫功能,而讀寫通常使用同一數據總線。這要求使用新的處理雙向數據線的建模技術。在下面使用同一數據總線。這要求使用新的處理雙向數據線的建模技術。在下面的例子

53、中,若讀端口未使能,則模型不驅動數據總線;此時若數據總線沒的例子中,若讀端口未使能,則模型不驅動數據總線;此時若數據總線沒有寫數據驅動,則總線為高阻態有寫數據驅動,則總線為高阻態Z。這避免了。這避免了RAM寫入時的沖突。寫入時的沖突。timescale 1ns /1nsmodule mymem (data, addr, read, write); inout 3:0 data; input 3:0 addr; input read, write; reg 3:0 memory 0:15; / 16*4/ 讀讀 assign data = read ? memoryaddr : 4bz;/ 寫寫

54、 always ( posedge write) memoryaddr = data;endmodule 這個描述可綜合,但許這個描述可綜合,但許多工具僅僅產生一個寄多工具僅僅產生一個寄存器堆,因此與一個真存器堆,因此與一個真正的存儲器相比耗費更正的存儲器相比耗費更多的面積。多的面積。參數化存儲器描述參數化存儲器描述 在下面的例子中,給出如何定義一個字長和地址均參數化的只讀存儲器件。在下面的例子中,給出如何定義一個字長和地址均參數化的只讀存儲器件。module scalable_ROM (mem_word, address); parameter addr_bits = 8; / 地址總線寬度

55、地址總線寬度 parameter wordsize = 8; / 字寬字寬 parameter words = (1 addr_bits); / mem容量容量 output wordsize:1 mem_word; / 存儲器存儲器字字 input addr_bits:1 address; / 地址總線地址總線 reg wordsize:1 mem 0 : words-1; / mem聲明聲明/ 輸出存儲器的一個字輸出存儲器的一個字 wire wordsize:1 mem_word = memaddress;endmodule 例中存儲器字范圍從例中存儲器字范圍從0而不是而不是1開始,因為存

56、儲器直接用地址線確定地址。也開始,因為存儲器直接用地址線確定地址。也可以用下面的方式聲明存儲器并尋址。可以用下面的方式聲明存儲器并尋址。 reg wordsize:1 mem 1:words; / 從地址1開始的存儲器/ 存儲器尋址時地址必須加1 wire wordsize:1 mem_word = mem address + 1; 存儲器數據裝入存儲器數據裝入可以使用循環或系統任務給存儲器裝入初始化數據可以使用循環或系統任務給存儲器裝入初始化數據用循環給存儲器的每個字賦值用循環給存儲器的每個字賦值 for (i= 0; i memsize; i = i+ 1) / initialize memory mema i = wordsize 1b1; 調用系統任務調用系統任務$readmem $readmemb(mem_file. txt, mema); 可以用可以用 系統任務系統任務$readmem給一個給一個ROM或或RAM加載數據。對于加載數據。對于ROM,開始時寫入的數據就是其實際內容。對于開始時寫入的數據就是其實際內容。對于RAM,可以通過初始化,而不,可以通過初始化,而不是用不同

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論