HDLBits答案(2)_Verilog向量基础

HDLBits_Verilog向量基础知识

HDLBits链接


向量

在Verilog中,对向量维度的声明在向量名之前,这点与C语言有所差异,但使用向量的时候维度信息仍在向量名后。

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

向量的更多知识

声明向量

type [upper:lower] vector_name;

type 指定了向量的数据类型,通常为reg或wire类型。如果声明的是输入、输出向量的话,类型前还可以加上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]),一旦用特定的索引规则定义了向量,就要用相同的方式去使用它

[David说]:向量声明时数字的顺序很重要,它决定了向量是以大端存储或者小端存储。举例说明,若声明wire [3:0] w,则w[0]为w的最低位,w[3]为w的最高位;若声明为wire [0:3] w,则与上述结果相反。所以在向量的定义和使用时一定要保持大小端一致!

未定义的中间变量容易出错

使用wire型变量前请先声明,不要图一时之便直接未定义就拿来做中间变量,这样导致的错误会很难发现。

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.

向量名前为维度,向量名后为数目,不写统统视作1。(可类比C语言中的数组,向量名前为数组元素的数据类型,向量名后为数组长度;或者形象化的表述为:维度即为每个房子的大小,数目为房子的总数目)

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;如果左右两边的长度不匹配,则根据情况对向量进行补零或截断。

向量的部分选择操作可以访问向量的一部分。(向量声明来自上面"声明向量"部分)

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.

[David说]:取用向量中特定维度的数时一定注意要与向量的定义一致,注意大小端匹配的问题。

题目描述

构建一个电路将一个4byte的数中的字节顺序调转,常用于数据的大小端转换。

AaaaaaaaBbbbbbbbCcccccccDddddddd => DdddddddCcccccccBbbbbbbbAaaaaaaa

Solution:

module top_module( 
    input [31:0] in,
    output [31:0] out );

    assign out[31:24] = in[7:0];
    assign out[23:16] = in[15:8];
    assign out[15:8] = in[23:16];
    assign out[7:0] = in[31:24];

endmodule

[David说]:在向量赋值的左右两端都可以选择对部分数据进行操作。


对向量进行门操作

位操作运算符VS逻辑操作运算符

对两个Nbit位宽的向量而言,按位操作输出为Nbit位宽向量;而逻辑操作将整个向量视为布尔值(true =非零,false =零)并产生一个1bit的输出。

**题目描述1:**对向量特定部分的数据进行按位操作和逻辑操作。

Solution1:

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_logical = a || b;
    assign out_or_bitwise = a | b;
    assign out_not[5:3] = ~b;
    assign out_not[2:0] = ~a;
endmodule

题目描述2:

对输入向量进行按位的与、或和异或操作。

Solution2:

module top_module( 
    input [3:0] in,
    output out_and,
    output out_or,
    output out_xor
);
    assign out_and = &in;  // &in = in[3]&in[2]&in[1]&in[0]
    assign out_or = |in;
	assign out_xor = ^in;
endmodule

[David说]:合理利用缩位运算符精简代码,按位进行逻辑运算,结果为1bit数。

  • 与缩位运算符:&
  • 或缩位运算符:|
  • 异或缩位运算符:^
  • 与、或、异或运算符和非运算符组成的复合运算符:&,|, ~,^

向量拼接操作

向量拼接操作需要知道待拼接的各向量的位宽,否则你怎么知道结果的位宽?所以{1,2,3}是无效的,因为你未指定向量位宽。

向量的拼接操作在赋值的左右两端均可使用。

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.

[David说]:1、位宽合并需知道各成分的确切位宽,否则结果位宽不定。2、位宽合并时在assign两端均可实现,最好左右两端位宽相同,否则未被指定的数据会被置零。

题目描述:

给定几个输入向量,将它们拼接在一起,然后将它们分割成几个输出向量。有6个5位输入向量:a, b, c, d, e, f,总共30位输入。对于32位的输出,有4个8位的输出向量:w、x、y和z。输出应该是输入向量与两个“1”位的串联:

Snipaste_2020-08-19_21-51-11.png

Solution:

module top_module (
    input [4:0] a, b, c, d, e, f,
    output [7:0] w, x, y, z );
    wire [31:0] temp;
    assign temp = {a,b,c,d,e,f,2'b11};
    assign {w,x,y,z}=temp;
endmodule

向量翻转

题目描述:

给定一个8位输入向量[7:0],颠倒它的位顺序。

Solution1:

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

Solution2:

module top_module( 
    input [7:0] in,
    output [7:0] out
);
	integer i;
    always@(*)begin
        for(i = 0;i < 8;i = i + 1)begin
            out[i]=in[7-i];
        end
    end
endmodule

[David说]:建议使用Solution2实现,可扩展性强。


向量复制操作

向量复制操作允许重复一个向量并将它们连接在一起:{num{vector}}

例如:

{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.

[David说]:复制向量有捷径,花括外面带数字。主要用于符号位的拓展。如4’b0101带符号拓展为8bit的话为8’b00000101,4’b1101带符号拓展为8bit数为8’b11111101。

**题目描述:**建立一个电路,将8位数字扩展到32位。这需要将符号位的24个副本(即将位[7]复制24次)与8位数字本身连接起来。

Solution:

module top_module (
    input [7:0] in,
    output [31:0] out );

    assign out = { {24{in[7]}} , in };

endmodule

**题目描述2:**给定5个1位信号(a、b、c、d和e),计算25位输出向量中所有25个成对的1位比较。如果两个被比较的位相等,输出应该是1。

out[24] = ~a ^ a;   // a == a, so out[24] is always 1.
out[23] = ~a ^ b;
out[22] = ~a ^ c;
...
out[ 1] = ~e ^ d;
out[ 0] = ~e ^ e;

Snipaste_2020-08-20_09-58-51.png

[David说]:该操作可以定位特定signal所在位置,两向量重复数据有规律可循,可用复制的方式来产生,简化代码。

Solution:

module top_module (
    input a, b, c, d, e,
    output [24:0] out );

    assign out = ~{5{a,b,c,d,e}} ^ {{5{a}},{5{b}},{5{c}},{5{d}},{5{e}}};

endmodule

总结:

学习了向量操作的相关知识,包括声明、选择部分数据、合并、复制等操作。

  • 29
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

日拱一卒_未来可期

若复习顺利望有闲钱的同学支持下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值