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等。
在图中,旁边带有数字的刻度线表示向量(或“总线”)的宽度,而不是为向量中的每一位绘制单独的线。
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指定向量的数据类型。通常是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.
向量的字节顺序(或非正式地称为“方向”)是指最低有效位是具有较低的索引(较小的字节序,例如[3:0])还是具有较高的索引(较大的字节序,例如[[ 0:3])。在Verilog中,一旦以特定的字节序声明了向量,就必须始终以相同的方式使用它。例如,声明vec[0:3]时写是非法的。与字节序一致是一种好习惯,因为如果将不同字节序的向量一起分配或使用,则会发生奇怪的错误。
隐网
隐式网络通常是难以发现的错误的来源。在Verilog中,可以通过assign语句或通过将未声明的内容附加到模块端口来隐式创建网络类型信号。隐式网络始终是一位电线,如果您打算使用矢量,则会导致错误。可以使用`default_nettype none指令来禁止创建隐式网络。
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将使第二行代码出错,从而使该错误更明显。
未包装与包装阵列
您可能已经注意到,在声明中,向量索引写在向量名称之前。这声明了数组的“打包”维,其中位被“打包”到了一个Blob中(这在模拟器中相关,但在硬件中不相关)。将解压后的尺寸宣布后的名称。它们通常用于声明内存数组。
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(从上面获取声明)。如果左右边的长度不匹配,则将其适当地零扩展或截断。部分选择运算符可用于访问向量的一部分:
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]个字节。
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 );
`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 ); assign out_hi=in[15:8]; assign out_lo=in[7:0]; endmodule
Vector2(部分选择)
可以将32位向量视为包含4个字节(位[31:24],[23:16]等)。建立一个电路,该电路将反转4字节字的字节顺序。
AaaaaaaaBbbbbbbbCcccccccDddddddd => DdddddddCcccccccBbbbbbbbAaaaaaaa
当需要交换数据的字节序时,例如在小字节序x86系统和许多Internet协议中使用的大字节序格式之间交换数据时,通常使用此操作。
`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)。将的反数b放在out_not(的[5:3]位)的上半部分,并将其的倒数a放在下半部分。
按位与逻辑运算符
之前,我们提到了各种布尔运算符的按位和逻辑版本(例如norgate)。使用向量时,两种运算符类型之间的区别变得很重要。两个N位向量之间的按位运算会复制该向量的每个位的运算并产生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