本人小白在学习Verilog语法过程中,由于没有系统的学习相关知识,因此浅浅记录一下。
题目1:给定一个 100 位输入向量 [99:0],反转其位顺序。
关键点:1、for和always的关系;2、for里面的变量i需要先定义(区别于C语言);3、verilog里面没有递增运算号++
module top_module(
input [99:0] in,
output [99:0] out
);
integer i; //提前定义for中的变量i
always@(*)begin // for的使用要在always中
for(i = 0;i < 100;i = i + 1 )begin //区别于C的i++
out [i] = in[99-i];
end
end
endmodule
题目2:
系统将为您提供一个名为 bcd_fadd 的 BCD 一位数加法器,该加法器将两个 BCD 数字相加并结转,并生成总和和结转。
module bcd_fadd ( input [3:0] a, input [3:0] b, input cin, output cout, output [3:0] sum );
实例化 100 个 bcd_fadd 副本,以创建一个 100 位 BCD 纹波进位加法器。您的加法器应添加两个 100 位 BCD 数字(打包到 400 位向量中)和一个进位以生成 100 位总和并执行。
关键点:1、需要调用for循环,同时实现 实例化bcd_fadd副本。
2、for循环需要在always块内,但是always块内又不能实现实例化。(原因:always是过程描述,而实例化是结构描述)因此,for循环实现可以在generate和genvar结构下完成。
正确结果:
module top_module(
input [399:0] a, b,
input cin,
output cout,
output [399:0] sum );
reg[99:0] cout_to_cin;
generate
genvar i;
bcd_fadd bcd_fadd_inst(
.a (a[3:0] ),
.b (b[3:0] ),
.cin (cin ),
.sum (sum[3:0] ),
.cout (cout_to_cin[0] )
);
for(i = 0; i <= 99; i = i + 1)begin: 模块名 //没有 :模块名的话,会报错block name
bcd_fadd bcd_fadd_inst1(
.a (a[4 * i + 3: 4 * i] ),
.b (b[4 * i + 3: 4 * i] ),
.cin (cout_to_cin[i - 1] ),
.sum (sum[4 * i + 3: 4 * i] ),
.cout (cout_to_cin[i] )
);
end
assign cout = cout_to_cin[99];
endgenerate //generate -- endgenerate 配合使用
endmodule
总结:1、在generate内部进行for循环时需要定义genvar变量一个 genvar 变量可用于多个 generate 循环。但使用同一个 genvar 变量的 generate 语句不能相互嵌套。
2、 在generate - for 循环结构中,需要对 generate 块命名,即begin:xxx
3、如果想在for循环内实例化,那么就不能采用always块,而是采用generate结构。