HDLBits(3)8.24

1|02 Verilog语言

1|12.2 向量

1|02.2.4 逐位操作符(x)与逻辑操作符(xx)

逐位:对一个n bit输入向量进行逻辑运算,在n bit上逐位进行,并产生一个n bit长的结果

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

eg:分别输出a,b逐位或;a,b逻辑或;a,b按位取反

assign out_or_bitwise = a | b; assign out_or_logical = a || b; assign out_not[2:0] = ~a; assign out_not[5:3] = ~b;

1|0 2.2.5 四输入门

多输入的逻辑门可以使用位展开的写法和缩减运算符的写法,如下:

/* 缩减运算符 */ assign out_and = & in; assign out_or = | in; assign out_xor = ^ in; /* 位展开运算符 */ assign out_and = in[3] & in[2] & in[1] & in[0]; assign out_or = in[3] | in[2] | in[1] | in[0]; assign out_xor = in[3] ^ in[2] ^ in[1] ^ in[0];

1|02.2.6 向量串联运算符(连续操作符)

将较小的向量连接在一起,创建更大的向量 

基本语法:assign { a , b } = c;

一定要标注位宽,否则综合器不知道结果需要多少位宽

连接符既可用于赋值语句的右侧创造更大的向量,也可用于左侧奇偶啊换字节顺序,eg:

input [15:0] in; output [23:0] out; assign {out[7:0], out[15:8]} = in; // 连接符用于赋值语句左侧,交换了字节的顺序 assign out[15:0] = {in[7:0], in[15:8]}; // 连接符用于赋值语句右侧,交换了字节的顺序 assign out = {in[7:0], in[15:8]}; // 此语句作用上与上两句相同交换了字节顺序,但不同的是赋值语句右侧为16位 //赋予左值后,右值扩展为24位,高8位赋零,前两句中,高8位为未赋值状态

题目:

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

 

1|02.2.7 矢量反转

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

可以使用连接符来实现,但这种方法比较笨,不适用于较大位宽的向量,由于是多个重复操作,想到使用for循环来实现:

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

 首先创建循环变量i,注意,HDLBits 上的 solution 中,i 定义于 for 循环的括号中,这在 Verilog 的语法中是不被允许的,是 SystemVerilog 的语法,Verilog 的语法需要提前定义 integer 变量,即整形变量

再创建组合逻辑always块,

always块是Verilog中用来描述组合逻辑以及时序逻辑的语法,组合逻辑语法为:

always @ (level event) begin [multiple statements] end

可以用 * 代替敏感信号,编译器会很具内部内容自动识别,达到简化的目的

值得注意的是,for 循环中的“循环”指的是代码层面的循环,而电路是不存在循环的,无论是信号而是门电路,都不存在循环。实际上,for 循环表示的代码将被综合器解析,for 循环将被分别解析为硬件电路。

除此之外,还可以使用generate 生成块(HDLBits提供的solution)

generate genvar i; for (i=0; i<8; i = i+1) begin: my_block_name assign out[i] = in[8-i-1]; end

 生成块与for循环的概念并不相同(一下全是复制粘贴,有待进一步理解)

for 循环和 Verilog 中其他的几种循环语句 while ,forever,repeat 本质上都用于控制语句的执行次数

生成块主要用于动态生成语句,例化 something(不只是例化模块),生成块与上述的过程块循环语句不同,并不是描述电路的一种行为。

生成块可以例化 assign 语句,模块,信号和变量的声明以及 always initial 这样的过程块。循环生成块是生成块中的一种类型,在综合过程中同样被综合器进行编译,这个过程可以看做综合过程中动态生成更多 Verilog 代码的预处理过程。在上面的例子中,generate 块在综合的过程中,综合了 8 句 assign 赋值语句

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

而且再生成块中的 for 循环中不能像前例一样使用 integer 作为循环变量,而是必须使用 genvar 变量


__EOF__

本文作者LhTian
本文链接https://www.cnblogs.com/LhTian/p/16618714.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   LhTian21  阅读(61)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示