只需要将in[0]赋值给out[99]、in[1]赋值给out[98]......也可以直接用for循环,其规范格式如下:
for(循环变量赋初值;循环执行条件;循环变量增值) 循环体语句块;
通过for循环赋值很方便:
module top_module (
input [99:0] in,
output reg [99:0] out
);
always @(*) begin
for (int i=0;i<$bits(out);i++) // $bits() is a system function that returns the width of a signal.
out[i] = in[$bits(out)-i-1]; // $bits(out) is 100 because out is 100 bits wide.
end
endmodule
统计1的个数可以直接将每一bit位加起来,得到的数值即为1的个数。缩减运算符只有与或非,由于加法不是一个简单地逻辑门就可以计算,所以只能一位一位的提取出来相加,因此用for语句
module top_module (
input [254:0] in,
output reg [7:0] out
);
always @(*) begin // Combinational always block
out = 0; // if don't assign initial value zero,simulate errors will emerge
for (int i=0;i<255;i++)
out = out + in[i];
end
endmodule
这个加法器将两个100位的输入信号和一个进位进位加起来产生一个100位的输出信号和进位信号。我们依旧用for循环语句,只是这次循环内容是另一个模块,在这里就要引入一个新的概念generate生成块。
Verilog-2001添加了generate循环,允许产生module和primitive的多个实例化,同时也可以产生多个variable,net,task,function,continous assignment,initial和always。在generate语句中可以引入if-else和case语句,根据条件不同产生不同的实例化。
用法:
1. generate语法有generate for, genreate if和generate case三种
2. generate for语句必须有genvar关键字定义for的变量
3. for 的内容必须加begin和end
4. 必须给for语段起个名字,这个名字会作为generate循环的实例名称。
标准格式:
generate genvar i;//定义变量
for(同上) begin:gfor //生成后的例化名,gfor[1].ui(实例化)、gfor[2].ui(实例化)......
需要循环的实例模块
end
endgenerate
因为第一个实例的输入是cin,其他的都是上一级的cout,因此把第一个单独例化。
module top_module(
input [99:0] a, b,
input cin,
output [99:0] cout,
output [99:0] sum );
fadd u0(.a(a[0]),
.b(b[0]),
.cin(cin),
.cout(cout[0]),
.sum(sum[0])
);
generate
genvar i;
for(i=1;i<100;i++)begin: gfor
fadd ui(.a(a[i]), //this i of ui won't be replaced
.b(b[i]),
.cin(cout[i-1]),
.cout(cout[i]),
.sum(sum[i])
);
end
endgenerate
endmodule
module fadd(
input a, b, cin,
output cout, sum );
assign {cout,sum} = a+b+cin;
endmodule
这个加法器有2个100位BCD数的输入(被打包在400位的输入向量中) 和一个cin进位输入信号,产生一个100位的BCD数和一个cout输出信号,由于输出只有一位cout信号,因此我们声明一个存储器形式的couts[98:0],99个1bit的cout连接到下一级一位BCD加法器的cin信号上,它们只是连接线不会出现实体寄存器。由于第一个输入为cin,最后一个输出为cout,所以单独例化,中间的98个例化使用generate生成块for循环语句。
设计电路时首先应该想到电路而不是代码,因此画一个示意图方便理解:
module top_module(
input [399:0] a, b,
input cin,
output cout,
output [399:0] sum );
// 将每个bcd加法器的输出设成存储器cout[i]
reg couts[98:0];
bcd_fadd u0(
.a(a[3:0]),
.b(b[3:0]),
.cin(cin),
.cout(couts[0]),
.sum(sum[3:0])
);
generate
genvar i;
for(i=1;i<99;i++)begin: gfor
bcd_fadd ui(
.a(a[ i*4 + 3 : i*4 + 0 ]),
.b(b[ i*4 + 3 : i*4 + 0 ]),
.cin(couts[i-1]),
.cout(couts[i]),
.sum(sum[i*4 + 3 : i*4 + 0])
);
end
endgenerate
bcd_fadd u99(
.a(a[399:396]),
.b(b[399:396]),
.cin(couts[98]),
.cout(cout),
.sum(sum[399:396])
);
endmodule