中科大OJ Verilog 在线评测题解24-27


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值