HDLBits——Vectors

2024-03-27 08:20
文章标签 vectors hdlbits

本文主要是介绍HDLBits——Vectors,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

HDLBits —— Vectors

Vectors(向量;总线)

要求:

Vector0.png

构造一个电路,拥有 1 个 3 bit 位宽的输入端口,4 个输出端口。其中一个输出端口直接输出输入的向量,剩下 3 个输出端口分别各自输出 3 bit 中的 1 bit。上图中,箭头上的小斜杠旁边的数字代表该向量(总线)的位宽,用于将向量同 wire 信号区别开来。

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

改进:assign {o2, o1, o0} = vec;

PS:如果想要片选多个 bit,那么可以通过如下操作实现。

assign w = vec[1:0]; 
Timing Diagram:

image-20211125123807813

Vector in more detail

要求:

分别输出 16 位输入信号的高 8 位 和低 8 位。

Solution:
`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
Timing Diagram:

image-20211125131135171

Vector part select(向量片选)

要求:

一个 32 位的向量可以看做由 4 个字节组成(bits[31:24],[23:16],[15:8],[7:0])。构建一个电路,将输入向量的字节顺序颠倒,也就是字节序大小端转换。

aaaaaaaabbbbbbbbccccccccdddddddd => ddddddddccccccccbbbbbbbbaaaaaaaa

这项操作常见于不同的大小端体系之间的数据交换,比如 x86 体系使用小端模式存储数据,而因特网协议中均使用大端模式,数据在本地和网络进行数据交换之前,均要进行大小端转换。

Solution:
module top_module( input [31:0] in,output [31:0] out );assign out[31:24] = in[7:0];assign out[7:0] = in[31:24];assign out[23:16] = in[15:8];assign out[15:8] = in[23:16];endmodule

改进:用一句 assign 语句代替,使用 {} 位拼接符。

assign out = {in[7-:8],in[15-:8],in[23-:8],in[31-:8]};
Timing Diagram:

image-20211125132816834

Bitwise operators(按位运算符)

要求:

模块有两个 3bit 宽的输入变量 a,b ,要求输出 a,b 逐位或、逻辑或、按位取反的结果,其中 b 在高位。

Vectorgates.png

Solution:
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[2] | b[2],a[1] | b[1],a[0] | b[0]};assign out_or_logical = a || b;assign out_not = ~{b,a};endmodule

PS:逐位逻辑运算符 VS 逻辑运算符

逐位逻辑运算符:对于 N 比特输入向量之间的逻辑比较,会在 N 比特上逐位进行,并产生一个 N 比特长的运算结果。

逻辑运算符:任何类型的输入都会被视作布尔值零->假,非零->真,将布尔值进行逻辑比较后,输出一个 1 比特的结果。

Timing Diagram:

image-20211125134553818

Four-input gates

要求:

分别构建一个 4 输入与门,或门以及异或门。

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

也可:使用缩减运算符的语法。

    assign out_and = & in;assign out_or  = | in;assign out_xor = ^ in;

Timing Diagram:

image-20211125140821442

Vector concatenation operator(连接操作符)

要求:

方格表示模块 32 位输入向量,按照上下对应关系,输出为下方的 4 个 8 比特向量。

Vector3.png

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

也可: assign {w,x,y,z} = {a,b,c,d,e,f,2’b11}; 变量默认用了所有位,但数字必须说明是多少位。

PS:连接操作符的基本语法使用 { } 将较小的向量括起来,每个 { } 内的向量使用逗号作为间隔。连接运算符中的向量务必需要标注位宽,不然综合器不知道结果需要多宽。

习惯上把位连接符用在赋值语句的右侧,表示将较小的向量连接成较大的向量,赋予左值。但实际上位连接符同样可以用在赋值语句左侧,比如:

assign {cout,sum} = a + b + cin;

在表示全加器时,可以使用一句 assign 语句实现结果和进位的赋值。

Timing Diagram:

image-20211125143049455

Vector reversal 1

要求:

给定一个 8bit 输入向量,将其反向输出。

Solution:
module top_module( input [7:0] in,output [7:0] out
);assign out[7:0] = {in[0],in[1],in[2],in[3],in[4],in[5],in[6],in[7]};endmodule

改进:循环实现(如果位数很高,比如2014位,手动调整就太麻烦了)

循环一:使用 for 循环

module top_module( input [7:0] in,output reg [7:0] out
);integer i;always @(*) beginfor(i=0; i<8; i=i+1)beginout[i] = in[7-i];endendendmodule

PS:for 循环描述了电路的行为,而不是电路的结构,因此,for 循环必须置于比如 always 块这样的过程块(在块中的组合逻辑将会按照一定的顺序运行)中。而实际上电路是不存在循环,for 循环表示的代码将被综合器解析为硬件电路。

注意:

  1. Verilog 的语法需要提前定义 integer 变量,即整形,不能在循环里面定义。
  2. always 语句中所有信号必须是 reg 变量。
  3. 循环只能用 +1,不能用 ++。

循环二:使用 generate 生成块

module top_module( input [7:0] in,output [7:0] out
);generategenvar i;for(i=0; i<8; i=i+1) begin:my_block_nameassign out[i] = in[7-i];endendgenerateendmodule

PS:for 循环和 Verilog 中其他的几种循环语句 while ,forever,repeat 本质上都用于控制语句的执行次数。但生成块主要用于动态生成语句,生成块可以例化 assign 语句模块信号和变量的声明以及 always initial 这样的过程块。循环生成块是生成块中的一种类型,在综合过程中同样被综合器进行编译,这个过程可以看做综合过程中动态生成更多 Verilog 代码的预处理过程。

总的来说,for 循环强调了对电路的行为描述,在综合的过程中循环展开,而生成块则用于综合过程中,动态生成代码,两者有本质上的不同。

注意:

  1. 在生成块中的 for 循环中不能使用 integer 作为循环变量,而必须使用 genvar 变量。
  2. begin 后面还有冒号,name。
Timing Diagram:

image-20211125144236950

Replication operator(重复操作符)

要求:

重复操作符的应用场景之一是在有符号数的扩展,即将符号位填充待扩展的比特。比如要将 4bit 的 4’b0101 有符号数扩展为 8bit ,0 是符号位,那么扩展之后为 8’b0000 0101。

构建一个电路,将一个 8bit 有符号数扩展为 32bit 数。

Solution:
module top_module (input [7:0] in,output [31:0] out );assign out = {{24{in[7]}},in};endmodule

PS:语法为 { 重复次数 { 向量 } },重复次数必须是一个常量,而且重复操作符有两对 { },别漏了外层。

More Replication

要求:

将 5 个 1bit 信号分别组成下图中两个 25 bit 信号,输出向量为这两个 25bit 向量的逐位操作的结果。如果两个待比较信号某比特相同,则结果向量对应的该比特位 1 。

Vector5.png

Solution:
module top_module (input a, b, c, d, e,output [24:0] out );//assign out = ~({{5{a}},{5{b}},{5{c}},{5{d}},{5{e}}}^{5{a,b,c,d,e}});endmodule

部分题目改进思路来源于 LogicJitterGibbs,感谢大神。

果然站在巨人的的肩膀上做起来更快更有效率。

这篇关于HDLBits——Vectors的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/851502

相关文章

Educational Codeforces Round 1C. Nearest vectors(极角排序+long double 精度)

题目链接 题意:给你一堆的向量,问你向量之间的夹角最小的是那一对。 解法:极角排序,然后枚举相邻的一对就可以啦,但是坑爹的是double精度不够,使用long double 读入使用cin。。。 #include<bits/stdc++.h>using namespace std;#define LL long long#define pb push_back#define X f

加载org.Hs.eg.db为什么出现error: $ operator is invalid for atomic vectors报错和解决方法

在Bioconductor上已经有人提了问题,并且有了回答(地址:https://support.bioconductor.org/p/9136329/) 简单的说,就是Rstduio出来背锅,最新的RSQLite(v2.2.6)和Rstudio存在冲突,以后要么是RSQLite迁就RStduio,要么就是Rstudio迁就RQLite。 不过目前也不是不能用,以下是解决方法 方法1 手动设

OK6410A 开发板 (三) 13 u-boot-2021.01 boot 解析 U-boot 镜像运行部分 boot 详细解析2 relocate_vectors

从链接角度分析 u-boot.bin 的构成从运行的角度分析 u-boot.bin 前 64byte 的 relocate relocate_vectors 的实现 #ifdef CONFIG_HAS_VBAR// 虽然走的是这一套,但是找到的协处理器cp15的C12的实现(DDI0301H_arm1176jzfs_r0p7_trm.pdf)和下面的内容对不上// 那就分析 #else

HDLbits 刷题 -- Exams/m2014 q3

Consider the function f shown in the Karnaugh map below. Implement this function. d is don't-care, which means you may choose to output whatever value is convenient. 译:考虑下面卡诺图中显示的函数f。 实现这个函数。D是

[HDLBits] Simple wire

Create a module with one input and one output that behaves like a wire. module top_module( input in, output out );assign out = in; endmodule

[HDLBits] AND gate

Create a module that implements an AND gate. module top_module( input a, input b, output out );assign out=a&&b;endmodule

HDLbits 刷题 --Exams/m2014 q4i

Implement the following circuit: 实现以下电路: module top_module (output out);assign out = 1'b0;endmodule 运行结果:

HDLbits 刷题 --Always casez

学习: Build a priority encoder for 8-bit inputs. Given an 8-bit vector, the output should report the first (least significant) bit in the vector that is 1. Report zero if the input vector has no bits t

HDLbits 刷题 -- Alwaysblock2

学习: For hardware synthesis, there are two types of always blocks that are relevant: Combinational: always @(*)Clocked: always @(posedge clk) Clocked always blocks create a blob of combinational log

Chinese Word Vectors 中文词向量(可获取)

github地址 https://github.com/Embedding/Chinese-Word-Vectors