题目说明
给出了一个可以做16bit加法的模块add16,实例化两个add16以达到32bit加法的。
这个题目的核心就是上面的图片,将两个16bit加法合成32bit加法即可。
模块端口声明
moduletop_module( input[31:0]a, input[31:0]b, output[31:0]sum );
题目解析
这个题目重点是进位的处理,一个add16模块计算结果的低16位,另一个add16模块在接收到第一个的进位后计算结果的高16位。此32bit加法器不需要处理输入进位(假设为0)和输出进位(无需进位),但为了内部模块为了结果的正确仍要处理进位信号。(换句话说,add16模块执行16bit的a+b+cin,而顶层模块执行32bit的a+b)
moduletop_module( inputlogic[31:0]a, inputlogic[31:0]b, outputlogic[31:0]sum ); wirelogic[15:0]sum_temp0,sum_temp1; varlogiccout1; add16d1( .a(a[15:0]), .b(b[15:0]), .cin(1'd0), .sum(sum_temp0), .cout(cout1) ); add16d2( .a(a[31:16]), .b(b[31:16]), .cin(cout1), .sum(sum_temp1), .cout() ); assignsum={sum_temp1,sum_temp0}; endmodule
点击Submit,等待一会就能看到下图结果:
注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。
这一题就结束了。
Problem 25-Module fadd
题目说明
在本练习中,将创建具有两个层次结构的电路。top_module将实例化add16(提供)的两个副本,每个副本将实例化add1(必须自己编写)的 16 个副本。因此,必须编写两个模块:top_module和add1。与Problem 24: Adder 1(Module add)一样,提供给您一个执行16bit的加法的模块。您需要实例化两个16bit加法模块来实现32bit加法器。一个add16计算加法结果的低16位,另一个计算结果的高16位。您的32位加法器同样不需要处理进位输入(假设为0)和进位输出(无需进位)信号。
如下图所示,将add16模块连接在一起,给出的add16模块如下:
moduleadd16(input[15:0]a,input[15:0]b,inputcin,output[15:0]sum,outputcout);
在每个add16中,16 个全加器(模块add1,未提供)被实例化以实际执行加法。必须编写具有以下声明的完整加法器模块:
moduleadd1(inputa,inputb,inputcin,outputsum,outputcout);
回想一下,全加器计算 a+b+cin 的和和进位。
综上所述,本设计共有三个模块:
top_module— 顶级模块包含两个add16
add16 — 一个 16 位加法器模块,由 16 个add1组成
add1 — 1 位全加器模块。
如果提交缺少add1模块,将收到一条错误消息,内容为:
Error(12006):Nodeinstance"user_fadd[0].a1"instantiatesundefinedentity"add1".
模块端口声明
moduletop_module( input[31:0]a, input[31:0]b, output[31:0]sum );
题目解析
只比上一题复杂些,核心内容没变。
moduletop_module( inputlogic[31:0]a, inputlogic[31:0]b, outputlogic[31:0]sum );// wirelogiccout; add16u1_add16( .a(a[15:0]), .b(b[15:0]), .cin(1'd0), .sum(sum[15:0]), .cout(cout) ); add16u2_add16( .a(a[31:16]), .b(b[31:16]), .cin(cout), .sum(sum[31:16]), .cout() ); endmodule moduleadd1(inputlogica, inputlogicb, inputlogiccin, outputlogicsum, outputlogiccout ); //Fulladdermodulehere assign{cout,sum}=a+b+cin; endmodule
点击Submit,等待一会就能看到下图结果:
注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。
这一题就结束了。
Problem 26-Module_cseladd
题目说明
上一个练习中(Problem 25: Adder 2(Module fadd))实现的加法器应该叫做行波进位加法器(RCA: Ripple-Carry Adder)。这种加法器的缺点是计算进位输出的延迟是相当慢的(最坏的情况下,来自于进位输入)。并且如果前一级加法器计算完成之前,后一级加法器不能开始计算。这又使得加法器的计算延迟变大。
一种改进是进位选择加法器,如下所示。第一级加法器与之前相同,但我们复制第二级加法器,一个假设进位=0,一个假设进位=1,然后使用快速2对1多路复用器选择哪个结果碰巧是正确的。
在本练习中,将获得与上一个练习相同的模块add16,该模块将两个 16 位数字与进位相加,并产生一个进位和 16 位和。必须实例化其中的三add16来构建进位选择加法器,同时实现16bit的2选1选择器来选择结果。
如下图所示将模块连接在一起。提供的模块add16具有以下声明:
moduleadd16(input[15:0]a,input[15:0]b,inputcin,output[15:0]sum,outputcout);
模块端口声明
moduletop_module( input[31:0]a, input[31:0]b, output[31:0]sum );
题目解析
这题是上一题的改进版本的加法器,其实这也是我们数电上学到的CSA(Carry-Select Adder,选择进位加法器),其相对于行波进位加法器延迟小一半左右,但是其是利用资源换取的,所以相应消耗的资源增加约一倍。
moduletop_module( inputlogic[31:0]a, inputlogic[31:0]b, outputlogic[31:0]sum ); wirelogiccout_sel; wirelogic[15:0]upperbit_sum0,upperbit_sum1; add16u0_add16( .a(a[15:0]), .b(b[15:0]), .cin(1'd0), .sum(sum[15:0]), .cout(cout_sel) ); add16u1_add16( .a(a[31:16]), .b(b[31:16]), .cin(1'd0), .sum(upperbit_sum0), .cout() ); add16u2_add16( .a(a[31:16]), .b(b[31:16]), .cin(1'd1), .sum(upperbit_sum1), .cout() ); always_comb begin uniquecase(cout_sel) 1'd0:sum[31:16]=upperbit_sum0; 1'd1:sum[31:16]=upperbit_sum1; default:sum[31:16]=upperbit_sum0; endcase end endmodule
点击Submit,等待一会就能看到下图结果:
注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。
这一题就结束了。
Problem 27-Module addsub
题目说明
减法器可以通过选择性地取反一个输入而从加法器构建,这相当于将输入反相然后加 1。最终结果是一个可以执行两种操作的电路:(a + b + 0) 和 ( a + ~b + 1)。
题目要求构建下面的加减法器。
提供了一个 16 位加法器模块,需要对其进行两次实例化:
moduleadd16(input[15:0]a,input[15:0]b,inputcin,output[15:0]sum,outputcout);
每当sub为 1 时,使用 32 位宽的 XOR 门来反转b输入。(这也可以被视为b[31:0]与sub复制32次相异或)。同时sub信号连接到加法器的进位。
图片来自 HDLBits
模块端口声明
moduletop_module( input[31:0]a, input[31:0]b, inputsub, output[31:0]sum );
题目解析
这个题目考察的是减法器,这里就用到数电小常识:减去一个数等于加上这个数的补码(就是题中的按位取反再加1)。
moduletop_module( inputlogic[31:0]a, inputlogic[31:0]b, inputlogicsub, outputlogic[31:0]sum ); wirelogiccout_0; wirelogic[31:0]b_reverse; assignb_reverse=b^{32{sub}}; add16u1_add16( .a(a[15:0]), .b(b_reverse[15:0]), .cin(sub), .sum(sum[15:0]), .cout(cout_0) ); add16u2_add16( .a(a[31:16]), .b(b_reverse[31:16]), .cin(cout_0), .sum(sum[31:16]), .cout() ); endmodule
点击Submit,等待一会就能看到下图结果:
注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。
这一题就结束了。
审核编辑:刘清
-
Verilog
+关注
关注
28文章
1351浏览量
110105 -
HDL
+关注
关注
8文章
327浏览量
47390 -
加法器
+关注
关注
6文章
183浏览量
30128
原文标题:HDLBits: 在线学习 SystemVerilog(六)-Problem 24-27
文章出处:【微信号:Open_FPGA,微信公众号:OpenFPGA】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论