Q24 加法器
题目描述 对于给定的16bit加法器电路,其代码如下:
试创建一verilog模块,在该模块中实例化两个16bit的加法器,并进行适当的连接,最终构成一个32bit的加法器,该加法器输入进位位为0,如下图所示:
输入格式 32'b0 32'b0 输出格式 32'b0 示例波形
代码
module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
assign {cout,sum} = a + b + cin;
endmodule
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire cout,coutn;
add16 add16_1 (
.a(a[15:0]),
.b(b[15:0]),
.cin(1'b0),
.sum(sum[15:0]),
.cout(cout) );
add16 add16_2 (
.a(a[31:16]),
.b(b[31:16]),
.cin(cout),
.sum(sum[31:16]),
.cout(coutn) );
endmodule
Q25 多层次例化加法器
题目描述 在此练习中,用户需要创建一个包含两层调用的电路,在顶层模块中,实例化两个16bit位宽的加法器add16,而add16模块又是通过例化16个1bit全加器实现的,如下图所示:
在本设计中,一共涉及到3个模块,分别是:顶层模块、add16模块、add1模块,其中add16模块源代码如下:
现在,你需要完成顶层模块和add1模块的verilog代码。
输入格式 两个32位宽的加数a,b 输出格式 32位宽的和sum 示例波形
无。。
代码
module top_module (
input [31:0] a,
input [31:0] b,
output [31:0] sum);
wire cout;
add16 add16_1 (
.a(a[15:0]),
.b(b[15:0]),
.cin(1'b0),
.sum(sum[15:0]),
.cout(cout) );
add16 add16_2 (
.a(a[31:16]),
.b(b[31:16]),
.cin(cout),
.sum(sum[31:16]));
endmodule
module add1 ( input a, input b, input cin, output sum, output cout );
// Full adder module here
assign {cout,sum}=a+b+cin;
endmodule
Q26 进位选择加法器
题目描述 前例中的加法器成为串行进位加法器,只有等前一级的加法器运算结束产生进位位之后,下一级加法器才能利用进位位进行计算,因此电路延时会随加法器串联级数的增加而线性增加,这使得电路计算速度大大降低。设每一级全加器的延时为t,则32bit加法器的延时则为:32t。
为降低电路整体延时,我们可以按下图进行设计:
我们将电路分为两段,每段实现16bit的加法,为了使高16位与低16位同时进行运算,我们采用两个add16对高位进行计算,区别在于进位位分别为0和1,最终通过低16位加法器的输出进位作为选择控制信号,选择高16位的运算结果。这样,32bit加法器的延时就变为:16t+tmux2 ≈16t,延时降低了接近一倍,这种以空间(增加电路)换时间(提高速度)的做法,在数字电路设计中经常使用。 请创建Verilog模块,实现上图中的电路结构,其中add16不需要用户编写,其声明如下:
输入格式 32bit a, 32bit b 输出格式 32bit sum 为 a 与 b 的和 示例波形
无。
代码
module add16 (
input[15:0] a,
input[15:0] b,
input cin,
output[15:0] sum,
output cout
);
assign {cout,sum} = a + b + cin;
endmodule
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire sel;
wire [15:0] sum2,sum3;
add16 add16_1 (
.a(a[15:0]),
.b(b[15:0]),
.cin(0),
.sum(sum[15:0]),
.cout(sel)
);
add16 add16_2 (
.a(a[31:16]),
.b(b[31:16]),
.cin(0),
.sum(sum2)
);
add16 add16_3 (
.a(a[31:16]),
.b(b[31:16]),
.cin(1),
.sum(sum3)
);
assign sum[31:16] = sel?sum3:sum2;
endmodule
Q27 加法减法器
题目描述 通过对加法器进行改造,可以支持加、减两种运算。我们知道,电路中有符号数通常使用补码表示,如-b其补码为:~b + 1(按位取反然后加1)。因此,对于减法算式a-b,可以理解为a+(-b) = a+(~b+1)= a + (~b) +1,因此对于减法运算,可以将加法器进行如下改造实现:
实现减法运算时,首先通过32bit的异或门,将信号b按位取反,同时将输入进位位置1,实现加法运算时,b保持不变,输入进位位置0。 其中add16模块代码如下,用户可直接调用:
请创建Verilog模块,实现上述电路功能。
输入格式 32位的a,b,以及一个1位信号sub,sub为1时为减法,sub为0时为加法 输出格式 32位信号sum
注:我想你读到这里的时候,一定跟我一样想着直接用sum=(sub==0?a+b:a-b)逃课了,但是请老老实实地按题目要求分高位低位取补码相加哦~~~ 示例波形
代码
module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
assign {cout,sum} = a + b + cin;
endmodule
module top_module(
input [31:0] a,
input [31:0] b,
input sub,
output [31:0] sum
);
wire cout_to_cin;
wire [31:0] nb={32{sub}}^b;
add16 add16_1 (
.a(a[15:0]),
.b(nb[15:0]),
.cin(sub),
.sum(sum[15:0]),
.cout(cout_to_cin)
);
add16 add16_2 (
.a(a[31:16]),
.b(nb[31:16]),
.cin(cout_to_cin),
.sum(sum[31:16])
);
endmodule