[HDLBits] Vectors practise

Vectors

题目
Vectors are used to group related signals using one name to make it more convenient to manipulate. For example, wire [7:0] w; declares an 8-bit vector named w that is functionally equivalent to having 8 separate wires.

Notice that the declaration of a vector places the dimensions before the name of the vector, which is unusual compared to C syntax. However, the part select has the dimensions after the vector name as you would expect.

wire [99:0] my_vector; // Declare a 100-element vector
assign out = my_vector[10]; // Part-select one bit out of the vector

Build a circuit that has one 3-bit input, then outputs the same vector, and also splits it into three separate 1-bit outputs. Connect output o0 to the input vector’s position 0, o1 to position 1, etc.

In a diagram, a tick mark with a number next to it indicates the width of the vector (or “bus”), rather than drawing a separate line for each bit in the vector.
翻译
向量经常用于将相关信号用一个名字来进行分组,使其更加容易来进行控制。例如,

wire [7:0] w;

就描述了一个名为w的8比特向量,其功能相当于拥有8个独立的线。
需要注意的是,向量维度的声明是放在向量名字之前的,相比于C的语法是不同的。但是在向量名字后面选择向量的某些维度就如你所期 [ 作者注:下标的方向要和声明时的下标方向保持一致,例如声明时为wire [7:0] w,那么在调用的时候也应该调用为w[7:0] ]。

wire [99:0] my_vector;      // Declare a 100-element vector
assign out = my_vector[10]; // Part-select one bit out of the vector

创建一个拥有3比特的输入和输出向量的电路,同时也创建3个分离的1比特的输出端口。将o0输出端口和输入端口0相连接,以此类推o1和o2。
在图中,用线标记的并且有一个数字相挨着的线表示这个向量的宽度(或者叫“总线”),而分离的线则表示向量的每一个比特
在这里插入图片描述
解答

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 o0 = vec[0];
    assign o1 = vec[1];
    assign o2 = vec[2];
    assign outv = vec;
endmodule

Vectors in more detail

题目
Vectors are used to group related signals using one name to make it more convenient to manipulate. For example, wire [7:0] w; declares an 8-bit vector named w that is equivalent to having 8 separate wires.
Declaring Vectors:
Vectors must be declared:

type [upper:lower] vector_name;

type specifies the datatype of the vector. This is usually wire or reg. If you are declaring a input or output port, the type can additionally include the port type (e.g., input or output) as well. Some examples:

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.

The endianness (or, informally, “direction”) of a vector is whether the the least significant bit has a lower index (little-endian, e.g., [3:0]) or a higher index (big-endian, e.g., [0:3]). In Verilog, once a vector is declared with a particular endianness, it must always be used the same way. e.g., writing vec[0:3] when vec is declared wire [3:0] vec; is illegal. Being consistent with endianness is good practice, as weird bugs occur if vectors of different endianness are assigned or used together.
Implicit nets:
Implicit nets are often a source of hard-to-detect bugs. In Verilog, net-type signals can be implicitly created by an assign statement or by attaching something undeclared to a module port. Implicit nets are always one-bit wires and causes bugs if you had intended to use a vector. Disabling creation of implicit nets can be done using the `default_nettype none directive.

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.

Adding `default_nettype none would make the third line of code an error, which makes the bug more visible.
Unpacked vs. Packed Arrays:
You may have noticed that in declarations, the vector indices are written before the vector name. This declares the “packed” dimensions of the array, where the bits are “packed” together into a blob (this is relevant in a simulator, but not in hardware). The unpacked dimensions are declared after the name. They are generally used to declare memory arrays. Since ECE253 didn’t cover memory arrays, we have not used packed arrays in this course. See http://www.asic-world.com/systemverilog/data_types10.html for more details.

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.

翻译
向量经常用来对相关联的信号用一个名字来进行分组,使其更方便进行操控。例如:

wire [7:0] w;

声明了一个名为w的8比特大小的向量,等效于8个独立的线。
向量的声明:
向量必须被声明为如下形式:

type [upper:lower] vector_name;

type是向量的指定的数据类型,通常为线网型或者寄存器型。type还可以再添加上端口的类型(例如输入端口或者输出端口)当你声明一个输入或者输出端口时。举一些例子如下:

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.

向量的末端性或者正式的说方向性是用来区分最低有效位是在较低索引处(小端)还是在较高索引处(大端)。[ 作者注:计算机里的小端和大端的区别主要在于,小端表示是指数据高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,大端表示是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,值得注意的是,大小端的保存顺序的区别是以字节为单位的而不是以比特为单位的 ] 在verilog种,一旦一个向量用一种末端性声明了,那么就必须用同样的方式来对这个向量进行使用。例如,用wire [3:0] vec; 来声明的向量,使用的时候如果用成vec[0:3]就是非法的。保持一致的末端性是一种好的做法,奇怪的bugs发生往往就是在末端性上混乱使用导致的。
隐式网
隐式网通常是很难发现的bug。在verilog种,一个网型的信号,会由assign语句隐式的创建或者产生于一个没有附加声明的模块端口上。隐式网总是一比特的线网型并且当你使用向量的时候会产生一些bug。如果想要禁止产生隐式网可以直接使用**`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**将会导致第三行代码报错,会使bug更显而易见。 [ 作者注:该命令用于隐性线网指定默认线网类型。特别是在端口定义中,如果没有显示指定线网类型,那么线网的类型为wire(默认值)或者是由命令指定的线网类型 ]
未打包和打包:
你可能注意到在向量的声明种,向量的索引长度是写在向量的名字之前的。这声明了数组的压缩维度,特点是比特都是压缩到一块的(这里和仿真相关,和真实硬件无关)。解压缩数组的声明是放在向量名字之后的。这种方式通常被用作声明存储数组。详情见http://www.asic-world.com/systemverilog/data_types10.html for more details
解答

module top_module (
	input [15:0] in,
	output [7:0] out_hi,
	output [7:0] out_lo
);
	
	assign out_hi = in[15:8];
	assign out_lo = in[7:0];
	
	// Concatenation operator also works: assign {out_hi, out_lo} = in;
	
endmodule

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章