Verilog_Day1 在CSDN博客上。http://blog.csdn.net/m0_38073085 第三章: 書上基本知識 每個Verilog程式包括4個主要部分:埠定義,I/O說明,內部信號聲明和功能定義。 input/output/inout都預設是wire型而不是reg型變數。 1 ...
Verilog_Day1 在CSDN博客上。http://blog.csdn.net/m0_38073085
第三章:
書上基本知識
- 每個Verilog程式包括4個主要部分:埠定義,I/O說明,內部信號聲明和功能定義。
- input/output/inout都預設是wire型而不是reg型變數。
-
1 module block(a,b,c,d); // 埠定義 2 input a,b; // 輸入口說明 3 output c,d; // 輸出口說明 4 5 reg [2:0] e; // 內部信號說明 [2:0] 表示3位信號 6 7 assign c=a|b; // 功能定義 1.用assign申明語句 8 and #2 u1(e,c,d); // 2.用實例元件 #2表示延時2單位時間 9 always @(c or e) 10 begin 11 12 end // 3.用always語句 13 endmodule
在實例元件使用中,and #2 u1()可以看成是調用了一個名為u1的and內置模塊。
- 採用“assign"語句是描述組合邏輯最常用的方法之一。而"always"塊既可以用於描述組合邏輯,也可描述時序邏輯。
- 在"always"模塊內,邏輯是按照指定的順序執行的。 (?)
- 只有連續賦值語句(即用關鍵詞assign引出的語句)和實例應用語句(即用已定義的模塊名引出的語句),可以獨立於過程塊而存在於模塊的功能定義部分。
問題1:begin - end 語句內是順序執行還是併列執行,alwatys內部語句執行順序是不是一定是順序執行,而不是取決於if-else?
- 在數字電路中,x代表不定值,z代表高阻值。z還有一種表示方法是可以寫作“?”。
-
高阻,數字電路里常見的術語,又叫高阻態,指的是電路的一種輸出狀態,既不是高電平也不是低電平。
高阻態是一個數字電路里常見的術語,指的是電路的一種輸出狀態,既不是高電平也不是低電平,如果高阻態再輸入下一級電路的話,對下級電路無任何影響,和沒接一樣,如果用萬用表測的話有可能是高電平也有可能是低電平,隨它後面接的東西定。
高阻態的實質:
電路分析時高阻態可做開路理解。你可以把它看作輸出(輸入)電阻非常大。他的極限可以認為懸空。也就是說理論上高阻態不是懸空,它是對地或對電源電阻極大的狀態。而實際應用上與引腳的懸空幾乎是一樣的。
高阻態的意義:
當門電路的輸出上拉管導通而下拉管截止時,輸出為高電平;反之就是低電平;如上拉管和下拉管都截止時,輸出端就相當於浮空(沒有電流流動),其電平隨外部電平高低而定,即該門電路放棄對輸出端電路的控制 。
單片機引腳複位後P口的所有引腳都是高阻輸入什麼是“高阻”?
高阻 簡言之就是 輸入輸出電阻都相當大,相當於隔離狀態。處在高阻態的三態門是與匯流排隔離開的,這樣匯流排可以同時被其他電路占用。
高阻:從邏輯器件內部電路結構來說,就是其輸出電阻很大,該狀態即不是高電平,也不是低電平。當三態門處於高阻態時,無論該門的輸入如何變化,都不會對其輸出有貢獻。
- 負數的表示方法: -8‘d5 只能放在最前面。
- 可以在長數字中使用下劃線分隔開數以提高程式的可讀性。
- 在verilog中用parameter來定義常量,即用parameter來定義一個標識符代表一個常量,稱為符號常量。 eg: parameter byte=8,byte_msb=byte-1,delay=(byte+byte_msb)/2;
兩種參數傳遞方法
下麵是一個參數傳遞實例:
module Decode(s,A,F); input s; parameter Width=2,Polarity=2; output A,F; reg A,F; always @(s) if(! s) A=Width%2; else F=Polarity%2; endmodule module Top; reg clock; wire A4,A5,F16,F32; initial begin clock=0; end always #50 clock=~clock; always @(posedge clock) begin end Decode #(3,3) D1(clock,A4,F16); Decode #(3) D2(clock,A5,F32); endmodule
代碼表示如果參數傳遞不成功,最後輸出應該都為0,如果都傳遞成功,最後A4,F16,A5輸出為1;F32輸出為0.
最後結果輸出如下圖:
可以看出參數傳遞成功。
編程過程中的幾個問題:
- 把always @(posedge clock) begin end 註釋掉也沒有問題;
- 本來想在Decode模塊中通過reg [Width] A;將輸出的A4,A5的數據長度也進行改變。但是最後沒有成功。 不報錯,但還是1位。
- 在Decode模塊中要使用功能定義模塊。不然輸出全是不定態。
- 在wave視窗,使用 a 快捷鍵可以顯示多個觀察時間點。
- reg A,F; 不能省。不然會報錯:Illegal reference to net "A". 因為 A 和 F 在always模塊內被賦值。需要使用 reg 型數據。
另一種參數傳遞可以通過defparam命令來實現。
module Decode(s,A,F); input s; parameter Width=2,Polarity=2; output A,F; reg F; reg [Width:0] A; always @(s) if(! s) A=Width%2; else F=Polarity%2; endmodule module Top; reg clock; wire A4,A5,F16,F32; initial begin clock=0; end always #50 clock=~clock; //always @(posedge clock) //begin //end Decode #(3,3) D1(clock,A4,F16); Decode D2(clock,A5,F32); // 這裡直接產生Decode的D2。內部參數不變。 defparam // 用defparam來改變參數。 Top.D2.Width=3; // 是Width, 不是A或者是A5。 endmodule
最後模擬結果不變。
總結:可以通過兩種方法來改變module裡面的參數型常量。 第一種是直接在生成一個實例時進行參數更改;第二種是用defparam在生成實例後再進行更改。
網路數據類型(wire,tri)與reg型的一般區別
- 網路數據類型表示結構實體例如門之間的物理連接。常用的網路數據類型包括wire型和tri型。網路數據類型的變數不能儲存值,而且必須受到驅動器(例如門和連續賦值語句,assign)的驅動。
- wire型變數通常是用來表示單個門驅動或連續賦值語句驅動的網路數據類型,tri 型變數則用來表示多驅動器驅動的網路數據。
- 如果沒有驅動器連接到網路類型(wire,tri)的變數,則該變數就是高阻(z)。 reg 型的變數預設為不定值x
- 在”always"模塊內被賦值的每一個信號都必須是reg型。
- 註意:reg 型只表示被定義的信號將用在”always“模塊內。
reg型數據與memory型數據的相似與區別
- verilog通過對 reg 型變數建立數組來對存儲器建模,可以描述RAM型存儲器,ROM存儲器和reg文件。 在verilog 中沒有多維數組存在。數組的維數不能大於2。
- memory 型數據是通過擴展 reg 型數據的地址範圍來生成的。 eg: reg [7:0] mema[255:0] 定義了一個名為mema的存儲器,包含有256個8位存儲器。 註意:第二個括弧的表達式必須是是常數表達式。
- reg [n-1:0] rega; //一個n為存儲器。 可以使用 rega=0; 進行賦值
- reg mema [n-1,0]; // 一個由n個1位存儲器構成的存儲器組。 不能用 mema=0; 進行賦值。 類似於C中的數組。
- 讀多位的memory型,可以用 reg[7:0] mema[255:0]; mema[56][2]; 。 先找到56號8位存儲器,再讀該8位存儲器的第二位。
- 註意存儲器屬於寄存器數組類型。線網數據類型沒有相應的存儲器類型。
.運算符、表達式
- 進行取模運算時,結果值的符號為採用模運算式里第一個操作數的符號位。 eg: -10%3 = -1 ; 11%-3 = 2;
-
位運算符:
- ~ // 取反
- & // 按位與
- | // 按位或
- ^ // 按位異或
- ^~ // 按位同或