【Verilog学习】-02-向量
向量
verilog的向量和C的向量(数组)不太一样,其的位数是写在名称的前面的,例如
1 | wire [7:0] w; |
在对向量赋值的时候,如果向量的位宽是相同的,就可以不用标明位;如果位宽不相同,则需要指明是那些位在进行assign
1 | input wire [2:0] vec; |
向量定义
1 | type [upper:lower] vector_name; |
注意:大小端的定义和使用要保持一致:
e.g., writing
vec[0:3]
whenvec
is declaredwire [3:0] vec;
is illegal.
隐式线网
线网类型的信号能够被隐式地在assign语句中或者在某个模块的输入中用了没有定义的端口定义。
1 | wire [2:0] a, c; // Two vectors |
未压缩和压缩阵列(Unpacked vs. Packed Arrays)
未压缩维度是定义在名字的后面,这是和前面的区别,很好区分。
1 | module packed_unpacked_data(); |
output:
1 | packed array[0] = 0 |
部分选择(Accessing Vector Elements: Part-Select)
对应于上面定义的信号:
1 | w[3:0] // Only the lower 4 bits of w |
练习,大小端的转换:
在x86系统中时小端模式,而在IP(Internet protocols)协议中,一般定义的是大端模式。设计一个模块进行大小端的转换:
1 | module top_module( |
逻辑运算与按位运算
按位运算是每一位作逻辑运算,然后整体输出,如果说输出的位宽小于输入的位宽,是以最低位输出的:
1 | assign out = a | b; //这里的a、b是三位位宽,out是一位位宽,则输出是最低为位0相或的结果 |
逻辑运算是把整个输入(不管多少位),按逻辑值来处理(0或者非0),输出是一位。
1 | assign out_or_bitwise = a | b; |
上述式子中的out_or_bitwise是三位宽,out_or_logical是一位宽度,a、b同上。
串联运算符(concatenation operator)
串联运算符是指的是将几个位宽较小的数合成为一个位宽较大的一个数:
1 | {3'b111, 3'b000} => 6'b111000 |
串联运算需要知道每一位数的位宽,因此需要对其进行位的标注{1,2,3}是非法的。
串联运算符号在assign的两边都可以使用:
1 | input [15:0] in; |
练习,把输入串联之后,再给输出:
答案:
1 | module top_module ( |
向量反转
题目
将8位输入反转后输出。
解法
这里可以直接像先前的方式对其进行直接的赋值,但是更好的方法是使用for循环。
怎么使用for循环呢?
这里原来的博主讲得太好了Vectorr - HDLBits (01xz.net)
1 | module top_module ( |
这里主要介绍了两种for循环,一种是直接在时序模块中使用for循环,这种方式是相当于编译器帮你生成了相应的电路让它看起来就像是for循环在迭代(其实并没有迭代,而只是生成了相应的电路);第二种方式是通过generate模块,这个模块的作用是相当于帮你循环生成了相应的代码,是在编译的时候,编译器帮你完成了代码的复用。
程序报错
1 | Error (10644): Verilog HDL error at top_module.v(7): this block requires a name File: /home/h/work/hdlbits.3279882/top_module.v Line: 7 |
原因
1 | module top_module( |
串联运算的复制操作
在串联运算中,可以对同一个元素重复,格式为{num{vector}}。
1 | {5{1'b1}} // 5'b11111 (or 5'd31 or 5'h1f) |
最常见的重复操作是在符号位拓展的情况(保留符号位(sign-extending)),4’b0101->4’b00000101、4’b1101->4’b111111101
eg.保留符号位8->32位拓展:
1 | module top_module ( |
eg.对五位的输入进行所有组合情况的比较,输出$C^{2}_{5}$种情况,如下所示:
1 | module top_module ( |
编译有一个warning:
1 | Warning (13024): Output pins are stuck at VCC or GND |
这是因为在输出里面有一个值是永远不随输入变化的,在这里是由于存在像 assign a = a & a;这样的情况存在,在这个要求下是需要这样的,因此可以忽略这个warning。