Vector0
向量用于使用一個名稱對相關信號進行分組,以使其更易于操作。例如,電線[7:0] w; 聲明一個名為w的8位向量,該向量在功能上等同于具有8條獨立的導線。
請注意,向量的聲明將維放置在向量名稱之前,這與C語法相比并不常見。然而,部分選擇了尺寸后,如你所期望的矢量名稱
wire [99:0] my_vector; // Declare a 100-element vector
assign out = my_vector[10]; // Part-select one bit out of the vector
構建一個具有一個3位輸入的電路,然后輸出相同的矢量,并將其分成三個單獨的1位輸出。將輸出連接o0到輸入向量的位置0,o1位置1等。
在圖中,旁邊帶有數(shù)字的刻度線表示向量(或“總線”)的寬度,而不是為向量中的每一位繪制單獨的線。
module top_module (
input wire [2:0] vec,
output wire [2:0] outv,
output wire o2,
output wire o1,
output wire o0 ); // Module body starts after module declaration
assign outv=vec;
assign o2=vec[2];
assign o1=vec[1];
assign o0=vec[0];
endmodule
Vector1
向量用于使用一個名稱對相關信號進行分組,以使其更易于操作。例如,wire [7:0] w;聲明一個名為w的8位向量,該向量等效于具有8條獨立的導線。
聲明向量
向量必須聲明:
輸入 [upper:lower] vector_name;
type指定向量的數(shù)據(jù)類型。通常是wire或reg。如果要聲明輸入或輸出端口,則該類型還可以另外包括端口類型(例如,input或output)。一些例子:
wire [7:0] w; // 8-bit wire
reg [4:1] x; // 4-bit reg
output reg [0:0] y; // 1-bit reg that is also an output port (this is still a vector)
input wire [3:-2] z; // 6-bit wire input (negative ranges are allowed)
output [3:0] a; // 4-bit output wire. Type is 'wire' unless specified otherwise.
wire [0:7] b; // 8-bit wire where b[0] is the most-significant bit.
向量的字節(jié)順序(或非正式地稱為“方向”)是指最低有效位是具有較低的索引(較小的字節(jié)序,例如[3:0])還是具有較高的索引(較大的字節(jié)序,例如[[ 0:3])。在Verilog中,一旦以特定的字節(jié)序聲明了向量,就必須始終以相同的方式使用它。例如,聲明vec[0:3]時寫是非法的。與字節(jié)序一致是一種好習慣,因為如果將不同字節(jié)序的向量一起分配或使用,則會發(fā)生奇怪的錯誤。
隱網(wǎng)隱式網(wǎng)絡通常是難以發(fā)現(xiàn)的錯誤的來源。在Verilog中,可以通過assign語句或通過將未聲明的內(nèi)容附加到模塊端口來隱式創(chuàng)建網(wǎng)絡類型信號。隱式網(wǎng)絡始終是一位電線,如果您打算使用矢量,則會導致錯誤。可以使用`default_nettype none指令來禁止創(chuàng)建隱式網(wǎng)絡。
wire [2:0] a, c; // Two vectors
assign a = 3'b101; // a = 101
assign b = a; // b = 1 implicitly-created wire
assign c = b; // c = 001 <-- bug
my_module i1 (d,e); // d and e are implicitly one-bit wide if not declared.
// This could be a bug if the port was intended to be a vector.
添加`default_nettype none將使第二行代碼出錯,從而使該錯誤更明顯。
未包裝與包裝陣列您可能已經(jīng)注意到,在聲明中,向量索引寫在向量名稱之前。這聲明了數(shù)組的“打包”維,其中位被“打包”到了一個Blob中(這在模擬器中相關,但在硬件中不相關)。將解壓后的尺寸宣布后的名稱。它們通常用于聲明內(nèi)存數(shù)組。
reg [7:0] mem [255:0]; // 256 unpacked elements, each of which is a 8-bit packed vector of reg.
reg mem2 [28:0]; // 29 unpacked elements, each of which is a 1-bit reg.
訪問向量元素:部分選擇
使用向量名稱可以訪問整個向量。例如:
assign w = a;
取整個4位向量a并將其分配給整個8位向量w(從上面獲取聲明)。如果左右邊的長度不匹配,則將其適當?shù)亓銛U展或截斷。部分選擇運算符可用于訪問向量的一部分:
w[3:0] // Only the lower 4 bits of w
x[1] // The lowest bit of x
x[1:1] // ...also the lowest bit of x
z[-1:-2] // Two lowest bits of z
b[3:0] // Illegal. Vector part-select must match the direction of the declaration.
b[0:3] // The *upper* 4 bits of b.
assign w[3:0] = b[0:3]; // Assign upper 4 bits of b to lower 4 bits of w. w[3]=b[0], w[2]=b[1], etc.
A Bit of Practice
建立一個組合電路,將輸入半字(16位,[15:0])分成低[7:0]和高[15:8]個字節(jié)。
Module Declaration
`default_nettype none // Disable implicit nets. Reduces some types of bugs.
module top_module(
input wire [15:0] in,
output wire [7:0] out_hi,
output wire [7:0] out_lo );
Vector2(部分選擇)可以將32位向量視為包含4個字節(jié)(位[31:24],[23:16]等)。建立一個電路,該電路將反轉(zhuǎn)4字節(jié)字的字節(jié)順序。
AaaaaaaaBbbbbbbbCcccccccDddddddd => DdddddddCcccccccBbbbbbbbAaaaaaaa當需要交換數(shù)據(jù)的字節(jié)序時,例如在小字節(jié)序x86系統(tǒng)和許多Internet協(xié)議中使用的大字節(jié)序格式之間交換數(shù)據(jù)時,通常使用此操作。
`default_nettype none
module top_module(
input [31:0] in,
output [31:0] out );//
assign out = {in[7:0], in[15:8], in[23:16], in[31:24]};
endmodule
按位運算符構建一個具有兩個3位輸入的電路,該輸入可計算兩個向量的按位或,兩個向量的邏輯或以及兩個向量的反(NOT)。將的反數(shù)b放在out_not(的[5:3]位)的上半部分,并將其的倒數(shù)a放在下半部分。
按位與邏輯運算符之前,我們提到了各種布爾運算符的按位和邏輯版本(例如norgate)。使用向量時,兩種運算符類型之間的區(qū)別變得很重要。兩個N位向量之間的按位運算會復制該向量的每個位的運算并產(chǎn)生N位輸出,而邏輯運算會將整個向量視為布爾值(真=非零,假=零),并且產(chǎn)生1位輸出。查看仿真波形,了解按位或與邏輯或的不同之處。
module top_module(
input [2:0] a,
input [2:0] b,
output [2:0] out_or_bitwise,
output out_or_logical,
output [5:0] out_not
);
assign out_or_bitwise = a|b;
assign out_or_logical = a||b;
assign out_not = {~(b),~(a)};
endmodule
tips
verilog中,“!”表示邏輯求反,“~”表示按位求反。當對位寬為1的變量進行操作時,這兩個操作符的作用是一樣的,都是求反。當對位寬為2的變量value[1:0]進行操作時,這兩個操作符的作用就不一樣了.
Gates4
構建一個具有四個輸入in [3:0]的組合電路。有3個輸出:out_and:4輸入與門的輸出。out_or:4輸入或門的輸出。out_xor:4輸入XOR門的輸出。要查看AND,OR和XOR運算符,請參見and gate,nor gate和xnor gate。
module top_module(
input [3:0] in,
output out_and,
output out_or,
output out_xor
);
assign out_and = & in;
assign out_or = | in;
assign out_xor= ^ in;
endmodule
Vector3(部分選擇)
使用部分選擇來選擇向量的部分。串聯(lián)運算符{a,b,c}用于通過將向量的較小部分串聯(lián)在一起來創(chuàng)建更大的向量。
{3'b111,3'b000} => 6'b111000
{1'b1,1'b0,3'b101} => 5'b10101
{4'ha,4'd10} => 8'b10101010 // 4'ha和4'd10均為二進制的4'b1010
串聯(lián)需要知道每個分量的寬度(或者您怎么知道結果的長度?)。因此,{1、2、3}是非法的,并導致出現(xiàn)錯誤消息:串聯(lián)中不允許使用不定尺寸的常量。
可以在分配的左側(cè)和右側(cè)使用串聯(lián)運算符。
input [15:0] in;
output [23:0] out;
assign {out[7:0], out[15:8]} = in; // Swap two bytes. Right side and left side are both 16-bit vectors.
assign out[15:0] = {in[7:0], in[15:8]}; // This is the same thing.
assign out = {in[7:0], in[15:8]}; // This is different. The 16-bit vector on the right is extended to
// match the 24-bit vector on the left, so out[23:16] are zero.
// In the first two examples, out[23:16] are not assigned.
A Bit of Practice
給定幾個輸入向量,將它們連接在一起,然后將它們分成幾個輸出向量。有六個5位輸入向量:a,b,c,d,e和f,總共有30位輸入。有四個8位輸出向量:w,x,y和z,用于32位輸出。輸出應該是輸入向量的串聯(lián),后跟兩個1位:
module top_module (
input [4:0] a, b, c, d, e, f,
output [7:0] w, x, y, z );//
assign {w,x,y,z} = { a, b, c, d, e, f,2'b11};
endmodule
矢量反轉(zhuǎn)
給定8位輸入向量[7:0],請反轉(zhuǎn)其位順序。
tips:分配out [7:0] = in [0:7]; 由于Verilog不允許翻轉(zhuǎn)向量位順序,因此無法正常工作。串聯(lián)運算符可以節(jié)省一些編碼,允許使用1個assign語句而不是8個。
module top_module(
input [7:0] in,
output [7:0] out
);
assign out = {in[0],in[1],in[2],in[3],in[4],in[5],in[6],in[7]};
endmodule
復制運算符
所述并置(或者復制)運算符允許矢量串聯(lián)起來以形成更大的載體。但是有時候您想將同一事物連接在一起很多次,而做類似分配a = {b,b,b,b,b,b,b}的事情仍然很乏味;。復制運算符允許重復一個向量并將它們串聯(lián)在一起:
{num {vector}}
這種復制載體由NUM倍。num必須為常數(shù)。兩組嵌套都是必需的。
Examples:
{5{1'b1}} // 5'b11111 (or 5'd31 or 5'h1f)
{2{a,b,c}} // The same as {a,b,c,a,b,c}
{3'd5, {2{3'd6}}} // 9'b101_110_110. It's a concatenation of 101 with
// the second vector, which is two copies of 3'b110.
一個復制運算符的常見用法是將一個較小的數(shù)字符號擴展為一個較大的數(shù)字,同時保留其符號值。這是通過將較小數(shù)字的符號位(最高有效位)復制到左側(cè)來完成的。例如,符號擴展4’B 0 101(5),以8位結果在8’b 0000 0101(5),而符號擴展4’B 1 101在(-3)至8位結果8’b 1111 1101(-3)。
建立一個將8位數(shù)字符號擴展為32位的電路。這需要串聯(lián)24個符號位的副本(即,復制bit [7] 24次),然后是8位數(shù)字本身。
module top_module (
input [7:0] in,
output [31:0] out );//
assign out = { {24{in[7]}} ,in };
endmodule
復制操作
給定五個1位信號(a,b,c,d和e),在25位輸出向量中計算所有25個成對的一位比較。如果要比較的兩位相等,則輸出應為1。
如圖所示,使用復制和串聯(lián)運算符可以更輕松地完成此操作。
頂部向量是每個輸入的5個重復的串聯(lián)誰底部向量是5個重復的輸入
module top_module (
input a, b, c, d, e,
output [24:0] out );//
// The output is XNOR of two vectors created by
// concatenating and replicating the five inputs.
assign out = ~{{5{a}} ,{5} ,{5{c}} ,{5mma8opvakk} ,{5{e}}} ^ { {5{a,b,c,d,e}} };
endmodule