0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
电子发烧友
开通电子发烧友VIP会员 尊享10大特权
海量资料免费下载
精品直播免费看
优质内容免费畅学
课程9折专享价
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

FPGA Verilog HDL語法之編譯預(yù)處理

FPGA技術(shù)江湖 ? 來源:FPGA技術(shù)江湖 ? 2025-03-27 13:30 ? 次閱讀

今天給大俠帶來的是一周掌握FPGA Verilog HDL 語法,今天開啟第五天。

上一篇提到了case語句、循環(huán)語句(forever、repeat、while、for)、結(jié)構(gòu)說明語句(initial、always、task、 function)等,此篇我們繼續(xù)來看編譯預(yù)處理,結(jié)合實例理解理論語法,會讓你理解運用的更加透徹。下面咱們廢話就不多說了,一起來看看吧。

編譯預(yù)處理

Verilog HDL語言和C語言一樣也提供了編譯預(yù)處理的功能?!熬幾g預(yù)處理”是Verilog HDL編譯系統(tǒng)的一個組成部分。Verilog HDL語言允許在程序中使用幾種特殊的命令(它們不是一般的語句)。Verilog HDL編譯系統(tǒng)通常先對這些特殊的命令進行“預(yù)處理”,然后將預(yù)處理的結(jié)果和源程序一起在進行通常的編譯處理。

在Verilog HDL語言中,為了和一般的語句相區(qū)別,這些預(yù)處理命令以符號“ `”開頭(注意這個符號是不同于單引號“ '”的)。這些預(yù)處理命令的有效作用范圍為定義命令之后到本文件結(jié)束或到其它命令定義替代該命令之處。Verilog HDL提供了以下預(yù)編譯命令:

`accelerate,`autoexpand_vectornets,`celldefine,`default_nettype,`define,`else,`endcelldefine,`endif,`endprotect,`endprotected,`expand_vectornets,`ifdef,`include,`noaccelerate,`noexpand_vectornets , `noremove_gatenames , `noremove_netnames ,`nounconnected_drive , `protect , `protecte , `remove_gatenames , `remove_netnames ,`reset,`timescale,`unconnected_drive

在這里只對常用的`define、`include、`timescale進行介紹,其余的請自行查閱資料。

宏定義 `define

用一個指定的標(biāo)識符(即名字)來代表一個字符串,它的一般形式為:

`define 標(biāo)識符(宏名) 字符串(宏內(nèi)容)

如:`define signal string

它的作用是指定用標(biāo)識符signal來代替string這個字符串,在編譯預(yù)處理時,把程序中在該命令以后所有的signal都替換成string。這種方法使用戶能以一個簡單的名字代替一個長的字符串,也可以用一個有含義的名字來代替沒有含義的數(shù)字和符號,因此把這個標(biāo)識符(名字)稱為“宏名”,在編譯預(yù)處理時將宏名替換成字符串的過程稱為“宏展開”。`define是宏定義命令。

例1:


`define WORDSIZE 8
module
reg[1:`WORDSIZE] data;//這相當(dāng)于定義 reg[1:8] data;
……

關(guān)于宏定義的八點說明:

1) 宏名可以用大寫字母表示,也可以用小寫字母表示。建議使用大寫字母,以與變量名相區(qū)別。

2) `define命令可以出現(xiàn)在模塊定義里面,也可以出現(xiàn)在模塊定義外面。宏名的有效范圍為定義命令之后到原文件結(jié)束。通常,`define命令寫在模塊定義的外面,作為程序的一部分,在此程序內(nèi)有效。

3) 在引用已定義的宏名時,必須在宏名的前面加上符號“`”,表示該名字是一個經(jīng)過宏定義的名字。

4) 使用宏名代替一個字符串,可以減少程序中重復(fù)書寫某些字符串的工作量。而且記住一個宏名要比記住一個無規(guī)律的字符串容易,這樣在讀程序時能立即知道它的含義,當(dāng)需要改變某一個變量時,可以只改變 `define命令行,一改全改。如例1中,先定義WORDSIZE代表常量8,這時寄存器data是一個8位的寄存器。如果需要改變寄存器的大小,只需把該命令行改為:`define WORDSIZE 16。這樣寄存器data則變?yōu)橐粋€16位的寄存器。由此可見使用宏定義,可以提高程序的可移植性和可讀性。

5) 宏定義是用宏名代替一個字符串,也就是作簡單的置換,不作語法檢查。預(yù)處理時照樣代入,不管含義是否正確。只有在編譯已被宏展開后的源程序時才報錯。

6) 宏定義不是Verilog HDL語句,不必在行末加分號。如果加了分號會連分號一起進行置換。如:

例2:

moduletest;


  reg a, b, c, d, e,out;
  `defineexpression a+b+c+d;
  assignout=`expression+e;
  ...
 
endmodule

經(jīng)過宏展開以后,該語句為:

assign out = a+b+c+d;+e;

顯然出現(xiàn)語法錯誤。

7) 在進行宏定義時,可以引用已定義的宏名,可以層層置換。如:

例3:

moduletest;


  reg a, b, c;
  wireout;
  `defineaa a+b
  `definecc c+`aa
  assignout=`cc;
 
endmodule

這樣經(jīng)過宏展開以后,assign語句為:

assign out = c + a + b;

8) 宏名和宏內(nèi)容必須在同一行中進行聲明。如果在宏內(nèi)容中包含有注釋行,注釋行不會作為被置換的內(nèi)容。如:

例4:

module

`define typ_nand nand #5//define a nand with typical delay
`typ_nandg121(q21,n10,n11);
………

endmodule

經(jīng)過宏展開以后,該語句為:

nand #5 g121(q21,n10,n11);

宏內(nèi)容可以是空格,在這種情況下,宏內(nèi)容被定義為空的。當(dāng)引用這個宏名時,不會有內(nèi)容被置換。

注意:組成宏內(nèi)容的字符串不能夠被以下的語句記號分隔開的。

注釋行

數(shù)字

字符串

確認符

關(guān)鍵詞

雙目和三目字符運算符

如下面的宏定義聲明和引用是非法的。`define first_half "start of string$display(`first_half end of string");

注意在使用宏定義時要注意以下情況:

1) 對于某些 EDA軟件,在編寫源程序時,如使用和預(yù)處理命令名相同的宏名會發(fā)生沖突,因此建議不要使用和預(yù)處理命令名相同的宏名。

2) 宏名可以是普通的標(biāo)識符(變量名)。例如signal_name 和 'signal_name的意義是不同的。但是這樣容易引起混淆,建議不要這樣使用。

“文件包含”處理`include

所謂“文件包含”處理是一個源文件可以將另外一個源文件的全部內(nèi)容包含進來,即將另外的文件包含到本文件之中。Verilog HDL語言提供了`include命令用來實現(xiàn)“文件包含”的操作。其一般形式為:如下圖1

ee5031a2-0848-11f0-9310-92fbcf53809c.png

上圖表示“文件包含”的含意。(a)為文件File1.v,它有一個`include "File2.v"命令,然后還有其它的內(nèi)容(以A表示)。(b)為另一個文件File2.v,文件的內(nèi)容以B表示。在編譯預(yù)處理時,要對`include命令進行“文件包含”預(yù)處理:將File2.v的全部內(nèi)容復(fù)制插入到 `include "File2.v"命令出現(xiàn)的地方,即File2.v 被包含到File1.v中,得到(c)所示的結(jié)果。在接著往下進行的編譯中,將“包含”以后的File1.v作為一個源文件單位進行編譯。

“文件包含”命令是很有用的,它可以節(jié)省程序設(shè)計人員的重復(fù)勞動??梢詫⒁恍┏S玫暮甓x命令或任務(wù)(task)組成一個文件,然后用`include命令將這些宏定義包含到自己所寫的源文件中,相當(dāng)于工業(yè)上的標(biāo)準(zhǔn)元件拿來使用。另外在編寫Verilog HDL源文件時,一個源文件可能經(jīng)常要用到另外幾個源文件中的模塊,遇到這種情況即可用`include命令將所需模塊的源文件包含進來。

例1:(1)文件aaa.v

moduleaaa(a,b,out);


  input a, b;
  outputout;
  wireout;
 
  assignout= a^b;
 
endmodule
(2)文件bbb.v
`include"aaa.v"


modulebbb(c,d,e,out);


  input c,d,e;
  outputout;
  wire out_a;
  wireout;
 
 aaaaaa(
       .a(c),
       .b(d),
       .out(out_a)
      );
      
  assignout=e&out_a;


endmodule

在上面的例子中,文件bbb.v用到了文件aaa.v中的模塊aaa的實例器件,通過“文件包含”處理來調(diào)用。模塊aaa實際上是作為模塊bbb的子模塊來被調(diào)用的。在經(jīng)過編譯預(yù)處理后,文件bbb.v實際相當(dāng)于下面的程序文件bbb.v:
moduleaaa(a,b,out);


  input a, b;
  outputout;
  wireout;
 
  assignout= a ^ b;


endmodule
modulebbb(c, d, e,out);


  input c, d, e;
  outputout;
  wire out_a;
  wireout;
 
 aaaaaa(
      .a(c),
      .b(d),
      .out(out_a)
     );
 
  assignout= e & out_a;
 
endmodule

關(guān)于“文件包含”處理的四點說明:

1) 一個`include命令只能指定一個被包含的文件,如果要包含n個文件,要用n個`include命令。注意下面的寫法是非法的`include"aaa.v""bbb.v"

2) `include命令可以出現(xiàn)在Verilog HDL源程序的任何地方,被包含文件名可以是相對路徑名,也可以是絕對路徑名。例如:'include"parts/count.v"

3) 可以將多個`include命令寫在一行,在`include命令行,只可以出空格和注釋行。例如下面的寫法是合法的。 'include "fileB" 'include "fileC" //including fileB and fileC

4) 如果文件1包含文件2,而文件2要用到文件3的內(nèi)容,則可以在文件1用兩個`include命令分別包含文件2和文件3,而且文件3應(yīng)出現(xiàn)在文件2之前。例如在下面的例子中,即在file1.v中定義:

`include"file3.v"
`include"file2.v"


moduletest(a,b,out);


  input[1:`size2] a, b;
  output[1:`size2]out;
  wire[1:`size2]out;
 
  assignout= a+b;
 
endmodule

file2.v的內(nèi)容為:

`define size2 `size1+1 . . .

file3.v的內(nèi)容為:

`define size1 4 . . .

這樣,file1.v和file2.v都可以用到file3.v的內(nèi)容。在file2.v中不必再用 `include "file3.v"了。

5) 在一個被包含文件中又可以包含另一個被包含文件,即文件包含是可以嵌套的。例如上面的問題也可以這樣處理,見下圖2、圖3。

ee6af19a-0848-11f0-9310-92fbcf53809c.png

它的作用和下圖,圖3的作用是相同的。

ee868982-0848-11f0-9310-92fbcf53809c.png

時間尺度 `timescale

`timescale命令用來說明跟在該命令后的模塊的時間單位和時間精度。使用`timescale命令可以在同一個設(shè)計里包含采用了不同的時間單位的模塊。例如,一個設(shè)計中包含了兩個模塊,其中一個模塊的時間延遲單位為ns,另一個模塊的時間延遲單位為ps。EDA工具仍然可以對這個設(shè)計進行仿真測試。

`timescale 命令的格式如下:

`timescale<時間單位>/<時間精度>

在這條命令中,時間單位參量是用來定義模塊中仿真時間和延遲時間的基準(zhǔn)單位的。時間精度參量是用來聲明該模塊的仿真時間的精確程度的,該參量被用來對延遲時間值進行取整操作(仿真前),因此該參量又可以被稱為取整精度。如果在同一個程序設(shè)計里,存在多個`timescale命令,則用最小的時間精度值來決定仿真的時間單位。另外時間精度至少要和時間單位一樣精確,時間精度值不能大于時間單位值。

在`timescale命令中,用于說明時間單位和時間精度參量值的數(shù)字必須是整數(shù),其有效數(shù)字為1、10、100,單位為秒(s)、毫秒(ms)、微秒(us)、納秒(ns)、皮秒(ps)、毫皮秒(fs)。這幾種單位的意義說明見下表。

eed06b88-0848-11f0-9310-92fbcf53809c.png

下面舉例說明`timescale命令的用法。

[例1]: `timescale 1ns/1ps

在這個命令之后,模塊中所有的時間值都表示是1ns的整數(shù)倍。這是因為在`timescale命令中,定義了時間單位是1ns。模塊中的延遲時間可表達為帶三位小數(shù)的實型數(shù),因為 `timescale命令定義時間精度為1ps.

[例2]:`timescale 10us/100ns

在這個例子中,`timescale命令定義后,模塊中時間值均為10us的整數(shù)倍。因為`timesacle 命令定義的時間單位是10us。延遲時間的最小分辨度為十分之一微秒(100ns),即延遲時間可表達為帶一位小數(shù)的實型數(shù)。

例3:

`timescale10ns/1ns


moduletest;
  regset;
 parameterd=1.55;
 
 initial
   begin
    #dset=0;
    #dset=1;
   end
   
endmodule

在這個例子中,`timescale命令定義了模塊test的時間單位為10ns、時間精度為1ns。因此在模塊test中,所有的時間值應(yīng)為10ns的整數(shù)倍,且以1ns為時間精度。這樣經(jīng)過取整操作,存在參數(shù)d中的延遲時間實際是16ns(即1.6×10ns),這意味著在仿真時刻為16ns時寄存器set被賦值0,在仿真時刻為32ns時寄存器set被賦值1。仿真時刻值是按照以下的步驟來計算的。

1) 根據(jù)時間精度,參數(shù)d值被從1.55取整為1.6。

2) 因為時間單位是10ns,時間精度是1ns,所以延遲時間#d作為 時間單位的整數(shù)倍為16ns。

3) EDA工具預(yù)定在仿真時刻為16ns的時候給寄存器set賦值0 (即語句 #d set=0;執(zhí)行時刻),在仿真時刻為32ns的時候給 寄存器set賦值1(即語句 #d set=1;執(zhí)行時刻),

注意:如果在同一個設(shè)計里,多個模塊中用到的時間單位不同,需要用到以下的時間結(jié)構(gòu)。

1) 用`timescale命令來聲明本模塊中所用到的時間單位和時間精度。

2) 用系統(tǒng)任務(wù)$printtimescale來輸出顯示一個模塊的時間單位和時間精度。

3) 用系統(tǒng)函數(shù)$time和$realtime及%t格式聲明來輸出顯示EDA工具記錄的時間信息。

條件編譯命令`ifdef、`else、`endif

一般情況下,Verilog HDL源程序中所有的行都將參加編譯。但是有時希望對其中的一部分內(nèi)容只有在滿足條件才進行編譯,也就是對一部分內(nèi)容指定編譯的條件,這就是“條件編譯”。有時,希望當(dāng)滿足條件時對一組語句進行編譯,而當(dāng)條件不滿足時則編譯另一部分。

條件編譯命令有以下幾種形式:

1)

`ifdef 宏名 (標(biāo)識符) 程序段1

`else

程序段2

`endif

它的作用是當(dāng)宏名已經(jīng)被定義過(用`define命令定義),則對程序段1進行編譯,程序段2將被忽略;否則編譯程序段2,程序段1被忽略。其中`else部分可以沒有,即: 2)

`ifdef 宏名 (標(biāo)識符)

程序段1

`endif

這里的 “宏名” 是一個Verilog HDL的標(biāo)識符,“程序段”可以是Verilog HDL語句組,也可以是命令行。這些命令可以出現(xiàn)在源程序的任何地方。

注意:被忽略掉不進行編譯的程序段部分也要符合Verilog HDL程序的語法規(guī)則。

通常在Verilog HDL程序中用到`ifdef、`else、`endif編譯命令的情況有以下幾種:

? 選擇一個模塊的不同代表部分。

? 選擇不同的時序或結(jié)構(gòu)信息。

? 對不同的EDA工具,選擇不同的激勵。

總結(jié)

Verilog HDL的語法與C語言的語法有許多類似的地方,但也有許多不同的地方。我們學(xué)習(xí)Verilog HDL語法要善于找到不同點,著重理解如:阻塞〔Blocking〕和非阻塞〔Non-Blocking〕賦值的不同;順序塊和并行塊的不同;塊與塊之間的并行執(zhí)行的概念;task和function的概念。Verilog HDL還有許多系統(tǒng)函數(shù)和任務(wù)也是C語言中沒有的如:$monitor、$readmemb、$stop等等,而這些系統(tǒng)任務(wù)在調(diào)試模塊的設(shè)計中是非常有用的,我們只有通過閱讀大量的Verilog調(diào)試模塊實例,經(jīng)過長期的實踐,經(jīng)常查閱理論知識才能逐步掌握。

Day 5 就到這里,到這里,經(jīng)過五天的Verilog HDL基礎(chǔ)語法的學(xué)習(xí),基本語法差不多都在這里了,從Day 6 繼續(xù)開始,最后兩天將推出思考題(附參考答案),大俠可以自行思考,檢測一下自己這一周的語法學(xué)習(xí)效果,大俠保重,告辭。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • FPGA
    +關(guān)注

    關(guān)注

    1638

    文章

    21859

    瀏覽量

    609797
  • Verilog
    +關(guān)注

    關(guān)注

    28

    文章

    1360

    瀏覽量

    111100
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7622

    瀏覽量

    139068
  • HDL語言
    +關(guān)注

    關(guān)注

    0

    文章

    48

    瀏覽量

    9022

原文標(biāo)題:一周掌握FPGA Verilog HDL語法 day 5

文章出處:【微信號:HXSLH1010101010,微信公眾號:FPGA技術(shù)江湖】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 0人收藏

    評論

    相關(guān)推薦

    深入理解FPGA Verilog HDL語法(一)

    今天給大俠帶來的是一周掌握FPGA Verilog HDL 語法,今天開啟第一天,下面咱們廢話就不多說了,一起來看看吧。
    發(fā)表于 07-18 09:47 ?3604次閱讀

    深入理解FPGA Verilog HDL語法(二)

    今天給大俠帶來的是一周掌握FPGA Verilog HDL 語法,今天開啟第二天。上一篇提到了整數(shù)型以及參數(shù)型,此篇我們繼續(xù)來看變量以及后續(xù)其他內(nèi)容,結(jié)合實例理解理論
    發(fā)表于 07-18 09:52 ?1931次閱讀

    [下載]cpld\fpga\verilog hdl視頻教程

      cpld\fpga\verilog hdl視頻教程入門篇:第1講、FPGA設(shè)計基礎(chǔ)(PDF、視頻)第2講、FPGA設(shè)計入門(視
    發(fā)表于 03-26 16:37

    FPGA-Verilog HDL語法參考

    FPGA-Verilog HDL語法參考語法規(guī)范下列規(guī)范應(yīng)用于語法描述,規(guī)則采用巴科斯—諾爾范式(B N F)書寫:1)
    發(fā)表于 08-11 10:33

    Verilog HDL的基本語法

    Verilog HDL的基本語法 .pdf
    發(fā)表于 08-15 15:06

    Verilog HDL語法

    Verilog HDL語法,要的拿
    發(fā)表于 01-24 22:53

    verilog HDL語法總結(jié)

    verilog HDL語法總結(jié)
    發(fā)表于 03-16 14:26

    FPGA雙沿發(fā)送Verilog HDL實現(xiàn) 精選資料推薦

    1.1 FPGA雙沿發(fā)送Verilog HDL實現(xiàn)1.1.1 本節(jié)目錄1)本節(jié)目錄;2)本節(jié)引言;3)FPGA簡介;4)
    發(fā)表于 07-26 06:20

    FPGA雙沿采樣Verilog HDL實現(xiàn) 精選資料分享

    1.1 FPGA雙沿采樣Verilog HDL實現(xiàn)1.1.1 本節(jié)目錄1)本節(jié)目錄;2)本節(jié)引言;3)FPGA簡介;4)
    發(fā)表于 07-26 07:44

    Verilog_HDL的基本語法詳解(夏宇聞版)

    Verilog_HDL的基本語法詳解(夏宇聞版):Verilog HDL是一種用于數(shù)字邏輯電路設(shè)計的語言。用Verilog
    發(fā)表于 10-08 14:48 ?0次下載
    <b class='flag-5'>Verilog_HDL</b>的基本<b class='flag-5'>語法</b>詳解(夏宇聞版)

    Verilog HDL實驗練習(xí)與語法手冊

    Verilog HDL實驗練習(xí)與語法手冊-高教
    發(fā)表于 05-11 11:30 ?0次下載

    _Verilog_HDL的基本語法

    Verilog_HDL語言的學(xué)習(xí),為FPGA編程打下堅實的基礎(chǔ)
    發(fā)表于 05-19 16:40 ?12次下載

    淺析VerilogHDL編譯系統(tǒng)的預(yù)處理

    。在Verilog HDL語言編譯時,特定的編譯指令在整個編譯過程中有效(編譯過程可跨越多個文件
    發(fā)表于 03-26 16:10 ?826次閱讀

    Verilog HDL入門教程-Verilog HDL的基本語法

    Verilog HDL入門教程-Verilog HDL的基本語法
    發(fā)表于 01-07 09:23 ?180次下載

    FPGA技術(shù)Verilog語法基本概念

    Verilog HDL是一種用于數(shù)字系統(tǒng)設(shè)計的語言。用Verilog HDL描述的電路設(shè)計就是該電路的Verilog
    發(fā)表于 12-08 14:00 ?3047次閱讀

    電子發(fā)燒友

    中國電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會員交流學(xué)習(xí)
    • 獲取您個性化的科技前沿技術(shù)信息
    • 參加活動獲取豐厚的禮品