参考链接:HDLBits导学
Problem 36: Conditional ternary operator(Conditional)
概述:Verilog跟C语言一样有一个三元运算符( ? : )
condition ? if_true : if_false
问题:给出四个无符号数,请找到其中的最小值。无符号数可以使用比较运算符进行比较(a<b)。使用条件运算符描述一个两路的最小值电路,然后组合它来创建一个4路最小电路。 可能需要一些wire变量用于表述中间结果
思路:构建一个两路比较的电路,再例化出两个模块来进行比较。简单点就三个assign就好了,具体看上面链接
解决:
module top_module (
input [7:0] a, b, c, d,
output [7:0] min);//
wire [7:0] compare_r1,compare_r2;
// assign intermediate_result1 = compare? true: false;
compare compare_inst1(
.a(a),
.b(b),
.min(compare_r1)
);
compare compare_inst2(
.a(c),
.b(d),
.min(compare_r2)
);
assign min = compare_r1 < compare_r2 ? compare_r1 : compare_r2;
endmodule
module compare(
input [7:0] a,b,
output [7:0] min
);
assign min = a < b ? a : b;
endmodule
Problem 37: Reduction operators(Reduction)
概述:归约运算符(Reduction Operators)可以对向量的每一位位进行AND,OR和XOR,产生一位输出:
&a [3:0] // AND:a[3]&a[2]&a[1]&a [0]相当于(a[3:0]== 4'hf)
|b [3:0] // OR: b[3]|b[2]|b[1]|b [0]相当于(b[3:0]!= 4'h0)
^c [2:0] // XOR:c[2]^c[1]^c[0]
这些是只有一个操作数的一元运算符(类似于NOT运算符!和~)。也可以将这些本节课的运算符的输出反相以创建NAND,NOR和XNOR门,例如(~&d[7:0])。
问题:构建一个电路,计算8位字节输入的校验位(将向该字节添加第9位)。 我们将使用偶校验,其中奇偶校验位只是所有8个数据位的XOR
解决:
module top_module (
input [7:0] in,
output parity);
assign parity = ^ in;
endmodule
Problem 38: Reduction: Even wider gates(Gates100)
问题:构建具有100个输入的组合电路。
电路一共有3个输出:
解决:
module top_module(
input [99:0] in,
output out_and,
output out_or,
output out_xor
);
assign out_and = ∈
assign out_or = |in;
assign out_xor = ^in;
endmodule
Problem 39: Combinational for-loop: Vector reversal2(Vector100r)
问题:给一个100位宽的向量,翻转向量
思路:使用for循环
解决:
module top_module(
input [99:0] in,
output [99:0] out
);
integer i;
always @(*) begin
for(i=0;i<100;i=i+1) begin
out[i]=in[99-i];
end
end
endmodule
Problem 40 Combinational for-loop: 255-bit population count
问题:设计电路来计算输入矢量中 ’1‘ 的个数,题目要求建立一个255bit输入的矢量来判断输入中 ’1‘ 的个数
思路:使用for循环
解决:
module top_module(
input [254:0] in,
output [7:0] out );
integer i;
always @(*) begin
out = 8'd0;//记得初始化为0
for(i=0;i<255;i++) begin
out = in[i] ? out+1 : out;
end
end
endmodule
Problem 41 Generate for-loop: 100-bit binary adder 2
问题:通过实例化100个全加器来实现一个100bit的二进制加法器。该加法器有两个100bit的输入和cin,输出为sum与cout。为了鼓励大家使用实例化来完成电路设计,我们同时需要输出每个全加器的cout。 故cout[99]标志着全加器的最终进位
思路:普通的for循环貌似不能例化模块(个人猜测),所以学习了一下使用generate代码块来例化多个模块
解决:
module top_module(
input [99:0] a, b,
input cin,
output [99:0] cout,
output [99:0] sum );
genvar gv_i;
full_add full_add_inst(
.a(a[0]),
.b(b[0]),
.cin(cin),
.sum(sum[0]),
.cout(cout[0])
);
generate
for(gv_i=1;gv_i<100;gv_i=gv_i+1) begin : label
full_add full_add_inst(
.a(a[gv_i]),
.b(b[gv_i]),
.cin(cout[gv_i-1]),
.sum(sum[gv_i]),
.cout(cout[gv_i])
);
end
endgenerate
endmodule
module full_add(
input a,
input b,
input cin,
output sum,
output cout
);
assign sum = a^b^cin;
assign cout = (a&b)|(a&cin)|(b&cin);
endmodule
Problem 42 Generate for-loop: 100-digit BCD adder
概述:本题已经提供了一个名为bcd_fadd的BCD一位全加器,他会添加两个BCD码和一个cin,并产生一个cout和sum
module bcd_fadd {
input [3:0] a,
input [3:0] b,
input cin,
output cout,
output [3:0] sum );
问题:我们需要实例化100个bcd_fadd来实现100位的BCD进位加法器。该加法器应包含两个100bit的BCD码(包含在400bit的矢量中)和一个cin, 输出产生sum 和 cout
解决:
module top_module(
input [399:0] a, b,
input cin,
output cout,
output [399:0] sum );
wire [99:0] cout_t;
genvar i;
assign cout = cout_t[99];
bcd_fadd bcd_fadd_inst(
.a(a[3:0]),
.b(b[3:0]),
.cin(cin),
.sum(sum[3:0]),
.cout(cout_t[0])
);
generate
for(i=1;i<100;i=i+1) begin : label
bcd_fadd bcd_fadd_inst(
.a(a[4*(i+1)-1:i*4]),
.b(b[4*(i+1)-1:i*4]),
.cin(cout_t[i-1]),
.sum(sum[4*(i+1)-1:i*4]),
.cout(cout_t[i])
);
end
endgenerate
endmodule
注意:for 循环begin后面一定要加一个标签名