HDLBits 系列入门题目详解之 Vector
发布于 2024-09-23 21:37:00(微信公众号导出记录)。
本文来自公众号后台的“导出文章内容”功能。博客正文由导出长图进行本地 OCR 转写,并保留原始排版图用于逐段核对。
原文链接:查看原文
OCR 转写有效文字约 5480 字;代码、流程图和版式以文末原始排版图为准。
正文(本地 OCR 转写)
Vectoro Question 向量是用来将相关的信号组合成一个名移,以便更方便地对它们进行操作。例如,wire[7:3] w:这行代码声明了一个名为W的8位向量,它的功能等同于有8条独立的线路。 需要注意的是,在声明向量时,尺寸(dimensions)是放在向量名称的前面的,这与C语言的 语法有所不同。但是,在部分选择(part-select)时,尺寸会放在向量名称的后面,这是符合 预期的语法。 例如,wire[99:B]ny_vector:声明了一个 108 元素的向量。然后可以用my_vector[1
0)选择向量中的第11个元素(下标从0开始)。
解决这个具体的题目: 位输出。要求将输出oH连接到输入向量的第0位,01连接到第1位,依此类推。 在电路图中,每一个向量(或“总线”)旁边的短竖线和数字表示该向量的宽度,而不是为每一位 都面一根线。这样的表示方式更加简洁明了。 outv output [2:0] outv input[2:e]vec 02 01 output 02, o1,00 00 top_module Solution nodule top_nodule ( output wire [2:0] outv, ‘o a 1nd1na output wire 00 //将输入向量直接激值给输出向量 assign outv = vec; //将向量的各个位分别值始单独的输出 assign ol = vec[1]; endnodule Vectorl NOTE
1.向量的声明向量用于将相关的信号组含成一个名称,以使更方便地操作它们声明一个向量
的语法如下: type [upper:lower] vector_name; type指定向量的数据类型,通常是vire或reg。如果是声明输人或输出端口,type还 可以包含端口炎型(如input或uutput)。例如: vire [7:8] w; //8位wire 向量 reg [4:1] ×; output reg [9:0] y; // 1 但 reg 输出向量 input wire[3:-2]z;//6位wire 输入向量(负数范围也是允许的) 向量的大小端序[endanness)指的是最低有效位是否有更低的索引l(小端,如[3:e])或更 高的索引(大端,如[0:3])。在Verilog中,一旦一个向量被声明为某种大小端序,就必须
一直保持一致。
2.隐式网络隐式网络是一个常见的bug来源。在Verilog中,信号类型的网络可能会
被assign语句或末声明的模决端口式创建。式网络永远是1位宽的wire,如果你本 来打算使用一个向量,这可能会导致bug。可以使用defauLt_nettype none指令禁用隐式 网络的创建。
3.非紧凑数组VS,紧凑数组在向量声明中,尺寸索引是放在向量名称的前面的。这声明了致
组的”紧凑“维度,即位被”紧凑”在一起成为一个整体(这在模拟器中很重要,但在硬件中不太相 关)。“非紧凑“维度则是在名移之后声明的,通常用于声明存储卷数组。由于ECE253课程没有 涉及存储器数组,我们也没有在这里使用过餐淡数组。
4.向量元素访间:部分选择可以使用向量名移访问整个向量:
assign w = a; 这会将4位向量a完整地值给8位向量《假设之前有相应的声明)。如果左右两边的 长度不匹配,会进行适当的零扩展或藏断。 还可以使用“部分选择“运算符访问向量的某些位: //只访问w的低4位 [3:8] /...也是x的最低位 ×[1:1] 4 z[ -1: -2] //访间z的两个最低位 //非法,向量部分选择必须与惠明方向一致 b[3:0] b[0:3] //访问b的高4 位(大避序) assign w[3:8]=b[0:3]:// 将b的高 4 位赋值给 w的低 4 位 Solution nodule top_nodule( input wire [15:θ] in, output vire [7:] out_hi, outp 4 assign out_hi = in[15:8]: //将输人的低8位聚值给oul_10 assign out_lo = in[7:0]; endnodule
ct_24X(9 X[的5 X12 XXs3X aX±c5 aX
Vector2 NOTE
一个32位的向量可以被视为包含4个字节(比特位[31:24]、[23:16]等)。请构建一个
电路,可以反转这个4字节词的字节顺序。 AaaaaaaaBbbbbbbbCcccccccDddddddd => DdddddddCcccccccBbbbbbbbAaaaaaaa 这种字节顺序反转的操作在需要交换数据的大小端模式时经常用到,比如在小端模式的x86系 统和许多互联网协议使用的大端格式之间进行转换。 梗块byte_reverse_32bit( 输入 wire [31:0] 1n, 输出 wire [31:e] out 聚值 out = {in[7:a]。 in[15:B], in[23:16], in[31:24]}; endnodule 这个Ver1log 模块名为byte_reverse_32bit,它有一个32位的输人向量in,通过一 个签单的Verilog连接操作将其字节颠序反转,并输出到32位的out向量中。 具体来说,[1n[7:0],1n[15:8].1n[23:16],1n[31:24]}这行代码将 1n向量中的 4 个字节按照从低到高的期序重新组合起来,形成了新的32位向量oul。 这种字节顺序反转的电路在需要进行大小端转换的场景中非常有用,比如在小端x86系统和大 端互联网协议之间进行数据交换时。 Solution nodule top_module( input [31:e] in, output [31:0] out );// ass1gn out[31:24] - 1n[7:0]; a5sign out[15:8] = in[23:16]; endnodule n12153524c065e81B484d509b10583760 46dd28465 893752123301 24351512815e09c09d6404636051d7b600319d466584c22125237891e3300
Vectorgates NOTE 这个电路需要有两个3位的输入,然后计算以下三个结果: L.两个向量的按位”或“(bitwise-OR)
2.两个向量的逻辑”或“(logical-OR)
3.两个向量的取反(NOT)
其中,将b向量的取反放在outnat的高3位(即[5:3]).将a向量的取反放在低 3 位(即 [2:0])。 对于两个N位的向量进行“按位“运算,会把运算应用到每一位上,产生一个N位的输出。 而“逻错“运算则是把整个向量作为一个布尔值(非零为真,零为假),产生一个1位的输出。 我们可以通过仿真波形图来观察一下“按位或“和“逻辑或”之间的差异。 >output [2:8] out_or_bitwise out_or_bitw1se input [2:θ] a, b out_or_logjcal tetbotJo"4no 4ndano out_not top_module Solution nodule top_nodute( ‘g[g:z] ndu1 input [2:e] b, output [2:e] out_or_bitwise, putput aut_or_logical, 1ouμno [e=s] 4ndno ) : //按位或 q 1e = osatqJono usse //逻辑或 assign out_or_logical = |a 1l Ib; //反转 assign out_not[5:3] = ~b; endnodule
Gates4 NOTE
四输入的组合电路。
这个电路有以下三个输出: L.out_and:4个输人的“与"(AND)门输出
2.out_or:4个输入的“或“(0R)门输出
3.out_xor:4个输人的"异或”(XOR)门输出
Solution nodule top_module( 1nput [3:0] 1n, output out_and, output out_xor ); assign out_and = E // 等价于 in[3] & in[2] & in[1]& in[] []u[π]u[z]u [ε]u ±θ鲁 // u1= oxμno ufss endnodule
pueno out_or out_xor out_or out_xor
Vector3 NOTE 关于向量拼接和分割的题目。 向量拼接运算使用{a,b,c)这种语法,将多个较小的向量拼接起来创建一个更大的向量。比 如: {3b111, 3'bege) => 6'b111999 L0101q.5 <= {t0tq.e *eq.1 '1q.T) {4°ha, 4′d18} => 8′b101e1919 // 4'ha 和 4'd1e 在二进刚下郁是 4b1e18 在进行拼接运算时,需要明确指定每个分量的宽度,因为这样才能确定最终结果的长度。所 以[1,2,3]这种用法是非法的,会报错。 拼接运算符可以出现在慰值语句的左右两边: uT [e:st] nduT no [e:ez] 1ndno //交换两个字节。左右两边部是16 assign {out[7:8], out[15:8]} = in; //这是等价的。 assign out = {in[7:0], 1n[15:8]}; //这种情况不同。右边的16位向量会很 //匹配左边24位向量的长度,所以out //前两个例子中,out[23:16]没有被 解决这个练习题: 有6个5位的输入向量a、b、C、d、e和f,总共39位输入。需要将它们拼接起来,然 后分割成4个8位的输出向量V、X、y和z,总共32位输出。最终输出应该是输人向量 的拼接,后面跟两个1位。 al blcldlelfhi →→ y Solution nodule top_module ( input [4:e] a, b, c, d, e, f, output [7:0] v, x, y, z //连接所有输入向量和两个1位,然后分配给输出 assign {w, x, y. z} = {a, b, c, d, e, f, 2b11}; endnodule
0 0 X1X0 0 0X1X2X4X8X10X 0 0 0 X124:0X 37b1323383X 0 X1X24810 37132333 Mismatch: Vectorr NOTE 设计这个电路,用于反转8位输人向量的位顺序。 Solution nodule top_nmodule( input [7:e] in, output [7:8]out ) ; assign out = {1n[0], in[1]。 in[2], in[3]。 in[4], 1n[5]. in[6], in[7 endnodule nd
Vector4 NOTE 重复运算符(ReplicationOperator)的使用: num次,并将它们拼接在一 重复运算符 {num{vector}}可以用来重复一个向量 vector num必须是一个常量。大括号是必须的,不能省略。 起。这里
一些例子:
//5′b11111(或5'd31、5'h1f)
{5{1'b1}}
{2{a,b,c}}
//等同于{a,b,c,a,b,c}
//9'b101_110_110。前面是101,后面是两个3'b110拼接
{3'd5,{2{3'd6}}}
这种重复运算在一些场景中很有用,比如符号扩展:
当需要将一个小的有符号数扩展到一个更大的位宽时,我们可以通过重复符号位(最高位)来保留
原有的有符号值。
例如,将4'b0101(5)扩展到8位,结果是8'b00000101(5)。将4'b1101(-3)扩展
到8位,结果是8'b11111101(-3)。
需要设计一个电路,将一个8位的数字符号扩展到32位。这需要先重复24次符号位(也就
是重复bit[7]24次),然后再拼接上原来的8位数字。
Solution
module top_module (
input [7:0] in,
output[31:0] out
);
assign out ={{24{in[7]}}, in};
endmodule
Vector5
NOTE
给定5个1位的输入信号a、b、c、d和e,请在25位的输出向量out中计
算所有25种可能的成对比较结果。如果被比较的两个位相等,则输出1,否则输出0。
具体而言:
out[24] =aa;
//a与自己比较,out[24]永远是1
//a与b比较
qe~=[εz]no
out[22]=ac;
//a与c比较
//e与d比较
out[1]=~e^d;
aaaaabbbbbcccccdddddeeeee XNORabcdeabcdeabcdeabcdeabcde 本 25 comparisons Solution module top_module ( input a, b,c, d,e, output[24:0] out ); wire[4:0] input_vector ={a,b,C,d,e}; assign out = ~({5{input_vector}} ^ {a,a,a,a,a,b,b,b,b,b,c,c,c,c,c endmodule
#FPGA #Verlog FPGA·目录三 <上一篇 下一篇> HDLBits系列入门题目详解之Modules: 高云FPGALinux下调制PWM Hierarchy(模块的层次结构)
原始排版图

