• HDLBits: 在线学习 SystemVerilog(十二)-Problem 65-71(加法器)


    a7bd97a39d66a17adb0a4679091e624c.jpeg

    HDLBits 是一组小型电路设计习题集,使用 Verilog/SystemVerilog 硬件描述语言 (HDL) 练习数字硬件设计~

    网址如下:

    https://hdlbits.01xz.net/

    关于HDLBits的Verilog实现可以查看下面专栏:

    https://www.zhihu.com/column/c_1131528588117385216

    缩略词索引:

    • SV:SystemVerilog

    从今天开始新的一章-Circuits,包括基本逻辑电路、时序电路、组合电路等。

    今天更新整个算术电路-加法器一小节题目,包括半加器,全加器等各种加法器。

    半加器和全加器的区别

    半加器

    半加器是由一个异或门和一个与门连接而成的组合逻辑电路。半加器电路有两个输入:A 和 B,它们将两个输入数字相加并产生一个进位和一个和。

    ad75f57715ff1475b1893648c2e81fe8.png

    异或门的输出是两个数的和,而与门的输出是进位。进位加法不会转发,因为没有逻辑门来处理它。因此,这被称为半加器电路。

    逻辑表达式:

    1. Sum = A XOR B
    2. Carry = A AND B

    真值表:

    af804c19d3f7fbc6d17ff45e9b385c9c.png

    全加器

    全加器是由两个异或门、两个与门和一个或门组成的电路。全加器是将三个输入相加并产生两个输出的加法器,前两个输入是 A 和 B,第三个输入是进位C-IN 的输入。输出进位指定为 C-OUT,正常输出指定为 S,即 SUM。

    b4892b6778abcd349f6e61338f4779fa.png

    异或门得到的方程是二进制数字的和。而AND门得到的输出是加法得到的进位。

    真值表:

    1446657f73b0da1310accf58b026b383.png

    逻辑表达式:

    1. SUM = (A XOR B) XOR Cin = (A ⊕ B) ⊕ Cin
    2. CARRY-OUT = A AND B OR Cin(A XOR B) = A.B + Cin(A ⊕ B)

    半加器和全加器的区别:

    姓名参数半加器全加器
    1描述半加法器是一个组合逻辑电路,将两个 1 位数字相加。半加器产生两个输入的和。全加器是一种组合逻辑电路,它对三个一位二进制数执行加法运算。全加器产生三个输入和进位值的总和。
    2上一次进位不使用前一个进位。使用前一个进位。
    3输入在半加器中,有两个输入位(A,B)。在全加器中,有三个输入位(A、B、C-in)。
    4输出输出是两位和 和Carry 。输出是 2 位的和和 3 位输入的Carry。
    5用作半加器电路不能以与全加器电路相同的方式使用。可以使用全加器电路代替半加器电路。
    6特征它简单易行全加器的设计并不像半加器那么简单。
    7逻辑表达式半加器的逻辑表达式为: S=a⊕b ; C=a*b。全加器的逻辑表达式为:S=a⊕b⊕Cin;Cout=(ab)+(Cin(a⊕b))。
    8逻辑门由一个异或门和一个与门组成。由两个异或门、两个 AND 门和一个 OR 门组成。
    9应用用于计算器,计算机,数字测量设备等。用于多位加法,数字处理器等。

    下面开始我们的题目,对于加法器有个更深刻的认识~

    Problem 65-Hadd

    题目说明

    创建一个半加法器。半加器将两位相加(没有进位)并产生和和进位(sum and carry-out)。

    模块端口声明

    1. module top_module( 
    2.     input a, b,
    3.     output cout, sum );

    题目解析

    根据半加器的逻辑表达式处理即可。

    1. module top_module( 
    2.     input logic a, b,
    3.     output logic cout, sum 
    4.     );
    5.     assign cout = a & b;
    6.     assign sum = a ^ b;
    7. endmodule
    b46d014b9dff642cf5143619fcbb46e5.png

    点击Submit,等待一会就能看到下图结果:

    032e70a6e9b7421b4fcda2acab88211a.png

    注意图中无参考波形。

    这一题就结束了。

    Problem 66-Fadd

    题目说明

    创建一个全加器。全加器将三位相加(包括进位)并产生和和进位。

    模块端口声明

    1. module top_module( 
    2.     input a, b, cin,
    3.     output cout, sum );

    题目解析

    根据全加器的逻辑表达式处理即可。

    简单解答

    1. module top_module( 
    2.     input logic a, b, cin,
    3.     output logic cout, sum );
    4.     assign sum = a^b^cin ;
    5.     assign cout = a&b | cin&(a^b) ;
    6. endmodule
    f87e1a0fac4f38e344d684561732d776.png

    点击Submit,等待一会就能看到下图结果:

    095294c68687bc686ca6c1d45c6ecac9.png

    注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。

    这一题就结束了。

    Problem 67-Adder3

    题目说明

    现在已经知道如何构建一个全加器,例化 3 个实例来创建一个 3 位二进制波纹进位加法器(ripple-carry adder)。加法器将两个 3 位数字和一个进位相加产生一个 3 位和和进位。为了鼓励例化全加器,还要输出纹波进位加法器中每个全加器的进位。cout[2] 是最后一个全加器的最终进位,也是通常看到的进位。

    模块端口声明

    1. module top_module( 
    2.     input [2:0] a, b,
    3.     input cin,
    4.     output [2:0] cout,
    5.     output [2:0] sum );

    题目解析

    例化正常的全加器,然后处理好进位关系即可,这种波纹进位加法器的特点需要理解,最后注意我们要把上一题写的全加器附在后面。

    1. module top_module( 
    2.     input logic [2:0] a, b,
    3.     input logic cin,
    4.     output logic [2:0] cout,
    5.     output logic [2:0] sum 
    6.     );
    7.     
    8.     full_adder f_adder_u1 (.a(a[0]),
    9.                       .b(b[0]), 
    10.                       .cin(cin),
    11.                       .cout(cout[0]), 
    12.                       .sum(sum[0])
    13.                      ); 
    14.     
    15.     full_adder f_adder_u2 (.a(a[1]),
    16.                           .b(b[1]), 
    17.                           .cin(cout[0]), 
    18.                           .cout(cout[1]), 
    19.                           .sum(sum[1]) 
    20.                          ); 
    21.     
    22.     full_adder f_adder_u3 (.a(a[2]), 
    23.                           .b(b[2]), 
    24.                           .cin(cout[1]), 
    25.                           .cout(cout[2]), 
    26.                           .sum(sum[2]) 
    27.                          ); 
    28.     
    29. endmodule
    30. module full_adder( input logic a, 
    31.                    input logic b, 
    32.                    input logic cin, 
    33.                    output logic cout, 
    34.                    output logic sum
    35.                    ); 
    36.     assign sum = a ^ b ^ cin; 
    37.     assign cout= a & b | cin&(a^b);   
    38. endmodule
    fb3ca1fb4ee96b1c7299ebd1893514bc.png

    点击Submit,等待一会就能看到下图结果:

    6d691f37aa3e4e804f5d448210626192.png

    注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。

    这一题就结束了。

    Problem 68-Exams/m2014 q4j

    题目说明

    实现下面电路:

    b81c19bcf83785b48d74c59a5ed0bbba.png图片来源:hdlbits

    FA代表全加器。

    模块端口声明

    1. module top_module (
    2.     input [3:0] x,
    3.     input [3:0] y, 
    4.     output [4:0] sum);

    题目解析

    这一题和上一题类似,看懂图片即可,将X[0]+Y[0]结果作为SUM[0],进位输入到下一级,以此类推。

    1. module top_module (
    2.     input logic [3:0] x,
    3.     input logic [3:0] y, 
    4.     output logic [4:0] sum
    5.     );
    6.     
    7.     wire logic [3:0]cout ;
    8.     full_adder f_adder_u1 (.a(x[0]),
    9.                           .b(y[0]), 
    10.                           .cin(1'd0),
    11.                           .cout(cout[0]), 
    12.                           .sum(sum[0])
    13.                            ); 
    14.     
    15.     full_adder f_adder_u2 (.a(x[1]),
    16.                           .b(y[1]), 
    17.                           .cin(cout[0]), 
    18.                           .cout(cout[1]), 
    19.                           .sum(sum[1]) 
    20.                           ); 
    21.     
    22.     full_adder f_adder_u3 (.a(x[2]), 
    23.                            .b(y[2]), 
    24.                            .cin(cout[1]), 
    25.                            .cout(cout[2]), 
    26.                            .sum(sum[2]) 
    27.                           ); 
    28.     full_adder f_adder_u4 (.a(x[3]), 
    29.                            .b(y[3]), 
    30.                            .cin(cout[2]), 
    31.                            .cout(cout[3]), 
    32.                            .sum(sum[3]) 
    33.                            );    
    34.     assign sum[4] = cout[3] ;
    35. endmodule
    36. module full_adder( input a, input b, input cin, output cout, output sum); 
    37.     assign sum = a ^ b ^ cin; 
    38.     assign cout= a & b | cin&(a^b);  
    39. endmodule
    1c56c51c2dbac727f571bb7156db13c7.png

    点击Submit,等待一会就能看到下图结果:

    77ff737cf9f8a95c7910f40a2868d5cd.png

    注意图中无波形。

    这一题就结束了。

    Problem 69-Exams/ece241 2014 q1c

    题目说明

    假设有两个 2 进制 8bit 有符号数-a[7:0] 和 b[7:0]。这些数字相加产生 s[7:0]。还要计算是否发生了(有符号的)溢出。

    模块端口声明

    1. module top_module (
    2.     input [7:0] a,
    3.     input [7:0] b,
    4.     output [7:0] s,
    5.     output overflow
    6. );

    题目解析

    当两个正数相加产生负结果或两个负数相加产生正结果时,会发生有符号溢出。有几种检测溢出的方法:可以通过比较输入和输出数的符号来计算,或者从位 n 和 n-1 的进位推导出。简单说就是一是正正相加,产生正溢出;另一种情况是负负相减,产生负溢出。所以在代码中需要分别考虑这两种情况,将这两种情况取或判断溢出。

    1. module top_module (
    2.     input logic [7:0] a,
    3.     input logic [7:0] b,
    4.     output logic [7:0] s,
    5.     output logic overflow
    6.     ); 
    7.  
    8.     assign s = a+b ;
    9.     assign overflow = a[7]&b[7]& ~s[7] | ~a[7] & ~b[7] & s[7] ;
    10. endmodule
    d89de59e7b91e944aca11930af4809eb.png

    点击Submit,等待一会就能看到下图结果:

    8573b1d4d0c8099d1cd5bd428b53b333.png

    注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。

    这一题就结束了。

    Problem 70-Adder100

    题目说明

    题目要求我们创建一个100bit的二进制的加法器,该电路共包含两个100bit的输入和一个cin, 输出产生sum和cout。

    模块端口声明

    1. module top_module( 
    2.     input [99:0] a, b,
    3.     input cin,
    4.     output cout,
    5.     output [99:0] sum );

    题目解析

    没什么难度,就是位数多一点,其他没区别。

    1. module top_module( 
    2.     input logic [99:0] a, b,
    3.     input logic cin,
    4.     output logic cout,
    5.     output logic [99:0] sum 
    6.     );
    7.     assign {cout, sum} = a + b  + cin;
    8. endmodule
    b653ca685dde88b4eed9d72700a39b7b.png

    点击Submit,等待一会就能看到下图结果:

    cd4de4247b299a69604ef015b3486b62.png

    注意图中无波形。

    这一题就结束了。

    Problem 71-Bcdadd4

    题目说明

    题目给我们提供了一个BCD加法器名字为bcd_fadd, 输入为两个4bitBCD码,一个cin,产生输出为sum和cout。

    1. module bcd_fadd {
    2.     input [3:0] a,
    3.     input [3:0] b,
    4.     input     cin,
    5.     output   cout,
    6.     output [3:0] sum );

    且题目也说明需要我们例化4次bcd_fadd来得到一个16-bit的BCD加法器(共16bit), 同样产生sum和cout。

    模块端口声明

    1. module top_module ( 
    2.     input [15:0] a, b,
    3.     input cin,
    4.     output cout,
    5.     output [15:0] sum );

    题目解析

    这个题目难度不大,主要考察例化语法,但是我们需要看下BCD加法器结构。

    1. module top_module( 
    2.     input logic [15:0] a, b,
    3.     input logic cin,
    4.     output logic cout,
    5.     output logic [15:0] sum );
    6.     
    7.     wire logic [2:0] cout_temp;
    8.     
    9.     bcd_fadd u1_bcd_fadd(
    10.         .a      (a[3:0]  ),
    11.         .b      (b[3:0]  ),
    12.         .cin (cin  ),
    13.         .cout (cout_temp[0] ),
    14.         .sum (sum[3:0] )
    15.     );
    16.     bcd_fadd u2_bcd_fadd(
    17.         .a      (a[7:4]  ),
    18.         .b      (b[7:4]  ),
    19.         .cin (cout_temp[0] ),
    20.         .cout (cout_temp[1] ),
    21.         .sum (sum[7:4] )
    22.     );
    23.     bcd_fadd u3_bcd_fadd(
    24.         .a      (a[11:8] ),
    25.         .b      (b[11:8] ),
    26.         .cin (cout_temp[1] ),
    27.         .cout (cout_temp[2] ),
    28.         .sum (sum[11:8] )
    29.     );
    30.     bcd_fadd u4_bcd_fadd(
    31.         .a      (a[15:12] ),
    32.         .b      (b[15:12] ),
    33.         .cin (cout_temp[2] ),
    34.         .cout (cout  ),
    35.         .sum (sum[15:12] )
    36.     );
    37. endmodule
    2332d33995cf6f728a325d9e3c09c182.png

    点击Submit,等待一会就能看到下图结果:

    52a961218179ea4bc617986cd0a8bc49.png

    注意图中的Ref是参考波形,Yours是你的代码生成的波形,网站会对比这两个波形,一旦这两者不匹配,仿真结果会变红。

    这一题就结束了。

    总结

    今天的几道题就结束了,整体比较简单,没有复杂的代码,没有复杂的设计思路,主要在于加法器的设计。

    最后我这边做题的代码也是个人理解使用,有错误欢迎大家批评指正,祝大家学习愉快~

    代码链接:

    https://github.com/suisuisi/SystemVerilog/tree/main/SystemVerilogHDLBits

  • 相关阅读:
    【UVA No. 442】 矩阵链乘 Matrix Chain Multiplication
    计算机毕业设计ssm基于SSM框架的药店管理系统ghao1系统+程序+源码+lw+远程部署
    修改Ehcache缓存中取到的值,缓存中的值也被修改了
    Java面试题(JVM篇)
    【C/C++】C语言runtime调用技术
    【题解】E. Sending a Sequence Over the Network(1741)
    RPC之 Sekiro 案例
    丹麦能源袭击预示着更关键的基础设施成为目标
    每天3分钟,重学ES6-ES12(十二)不常用但却常问的迭代器
    常用的路径规划算法浅析
  • 原文地址:https://blog.csdn.net/Pieces_thinking/article/details/127544173