verilog 语言,Vivado2018 计算机组成原理实验-adder(加法器)模块的编写

本实验介绍了一个32位加法器模块的设计与验证流程,包括使用Verilog编写加法器代码、搭建整体工程环境、进行仿真验证并最终生成可下载至FPGA的.bit文件等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实验内容:

1.adder(加法器)模块的编写。
2.建立完整的工程,工程中包括自己编写的 adder 模块,adder_display 模块(已
在群文件中提供),testbench.v(仿真文件)文件(已在群文件中提供),
lcd_module.dcp(显示屏操作模块)(已在群文件提供)。
※其中,adder_display.v 文件和 testbench.v 文件中的 adder 模块实例化已被挖
去,请自行填充。
3.完成仿真,并将仿真波形图像截图。
4.生成可以下载到 FPGA 上的.bit 文件。
5.完成整个工程的结构框图(包括 adder_display 模块和 adder 模块,不包括
testbench 部分和 lcd_module 部分)(选做 加分项)

实验过程:

1)新建工程

本过程按照实验手册一路next,按实验手册进行选择:

这里写图片描述

这里写图片描述

这里写图片描述

2)添加源文件

创建adder.v文件,编写代码;

有 2 个 32 位数的输入和 1 个进位输入,产生 1 个 32 位的加法 和结果和 1 个向高位的进位。本实验提供的参考设计是直接写“+”号实现加法功能 的,这样的写法综合工具会调用内部的模块库的加法器来实现;
源码如下:

这里写图片描述

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2018/05/02 22:42:20
// Design Name: 
// Module Name: adder
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module adder(
    input   [31:0]  operand1,
    input   [31:0]  operand2,
    input           cin,
    output  [31:0]  result,
    output          cout
    );
    assign  {cout,result}   = operand1 + operand2 + cin;
endmodule

3)添加展示外围模块

将实验辅助文件adder_display.v,lcd_module与testbentch.v添加到工程中;并对adder_display.v与testbentch.v的未添加模块添加,及对adder.v文件进行实例化。
这里写图片描述
adder_display.v添加部分:
这里写图片描述
源码:

//*************************************************************************
//   > 文件名: adder_display.v
//   > 描述  :加法器显示模块,调用FPGA板上的IO接口和触摸屏
//   > 作者  : LOONGSON
//   > 日期  : 2016-04-14
//*************************************************************************
module adder_display(
    //时钟与复位信号
     input clk,
    input resetn,    //后缀"n"代表低电平有效

    //拨码开关,用于选择输入数和产生cin
    input input_sel, //0:输入为加数1(add_operand1);1:输入为加数2(add_operand2)
    input sw_cin,

    //led灯,用于显示cout
    output led_cout,

    //触摸屏相关接口,不需要更改
    output lcd_rst,
    output lcd_cs,
    output lcd_rs,
    output lcd_wr,
    output lcd_rd,
    inout[15:0] lcd_data_io,
    output lcd_bl_ctr,
    inout ct_int,
    inout ct_sda,
    output ct_scl,
    output ct_rstn
    );

//-----{调用加法模块}begin
    reg  [31:0] adder_operand1;
    reg  [31:0] adder_operand2;
    wire        adder_cin;
    wire [31:0] adder_result  ;
    wire        adder_cout;
    adder adder_module(
    //需要补充的部分
    .operand1(adder_operand1),
     .operand2(adder_operand2),
     .cin (adder_cin ),
     .result (adder_result ),
     .cout (adder_cout ) 
    );
    assign adder_cin = sw_cin;
    assign led_cout  = adder_cout;
//-----{调用加法模块}end

//---------------------{调用触摸屏模块}begin--------------------//
//-----{实例化触摸屏}begin
//此小节不需要更改
    reg         display_valid;
    reg  [39:0] display_name;
    reg  [31:0] display_value;
    wire [5 :0] display_number;
    wire        input_valid;
    wire [31:0] input_value;

    lcd_module lcd_module(
        .clk            (clk           ),   //10Mhz
        .resetn         (resetn        ),

        //调用触摸屏的接口
        .display_valid  (display_valid ),
        .display_name   (display_name  ),
        .display_value  (display_value ),
        .display_number (display_number),
        .input_valid    (input_valid   ),
        .input_value    (input_value   ),

        //lcd触摸屏相关接口,不需要更改
        .lcd_rst        (lcd_rst       ),
        .lcd_cs         (lcd_cs        ),
        .lcd_rs         (lcd_rs        ),
        .lcd_wr         (lcd_wr        ),
        .lcd_rd         (lcd_rd        ),
        .lcd_data_io    (lcd_data_io   ),
        .lcd_bl_ctr     (lcd_bl_ctr    ),
        .ct_int         (ct_int        ),
        .ct_sda         (ct_sda        ),
        .ct_scl         (ct_scl        ),
        .ct_rstn        (ct_rstn       )
    ); 
//-----{实例化触摸屏}end

//-----{从触摸屏获取输入}begin
//根据实际需要输入的数修改此小节,
//建议对每一个数的输入,编写单独一个always块
    //当input_sel为0时,表示输入数为加数1,即operand1
    always @(posedge clk)
    begin
        if (!resetn)
        begin
            adder_operand1 <= 32'd0;
        end
        else if (input_valid && !input_sel)
        begin
            adder_operand1 <= input_value;
        end
    end

    //当input_sel为1时,表示输入数为加数2,即operand2
    always @(posedge clk)
    begin
        if (!resetn)
        begin
            adder_operand2 <= 32'd0;
        end
        else if (input_valid && input_sel)
        begin
            adder_operand2 <= input_value;
        end
    end
//-----{从触摸屏获取输入}end

//-----{输出到触摸屏显示}begin
//根据需要显示的数修改此小节,
//触摸屏上共有44块显示区域,可显示44组32位数据
//44块显示区域从1开始编号,编号为1~44,
    always @(posedge clk)
    begin
        case(display_number)
            6'd1 :
            begin
                display_valid <= 1'b1;
                display_name  <= "ADD_1";
                display_value <= adder_operand1;
            end
            6'd2 :
            begin
                display_valid <= 1'b1;
                display_name  <= "ADD_2";
                display_value <= adder_operand2;
            end
            6'd3 :
            begin
                display_valid <= 1'b1;
                display_name  <= "RESUL";
                display_value <= adder_result;
            end
            default :
            begin
                display_valid <= 1'b0;
                display_name  <= 40'd0;
                display_value <= 32'd0;
            end
        endcase
    end
//-----{输出到触摸屏显示}end
//----------------------{调用触摸屏模块}end---------------------//
endmodule

testbentch.v添加部分:

这里写图片描述

源码:

`timescale 1ns / 1ps   //仿真单位时间为1ns,精度为1ps
module testbench;

    // Inputs
    reg [31:0] operand1;
    reg [31:0] operand2;
    reg cin;

    // Outputs
    wire [31:0] result;
    wire cout;
    // Instantiate the Unit Under Test (UUT)
    adder uut (
    //需要补充的部分
    .operand1(operand1),
    .operand2(operand2),
    .cin(cin),
    .result(result),
    .cout(cout)
    );
    initial begin
        // Initialize Inputs
        operand1 = 0;
        operand2 = 0;
        cin = 0;
        // Wait 100 ns for global reset to finish
        #100;
        // Add stimulus here
    end
    always #10 operand1 = $random;  //$random为系统任务,产生一个随机的32位数
    always #10 operand2 = $random;  //#10 表示等待10个单位时间(10ns),即每过10ns,赋值一个随机的32位数
    always #10 cin = {$random} % 2; //加了拼接符,{$random}产生一个非负数,除2取余得到0或1
endmodule

4)仿真图像

这里写图片描述

这里写图片描述

5)加入约束文件,烧成bit文件,上板验证

将adder.xdc文件添加到工程中;

生成可烧写的bit文件
点击“Generate Bitsteam”

上板验证:烧写bit文件,在FPGA板上操作

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

<think>好的,我现在要处理用户关于加法器的问题,涉及电路设计、数字逻辑和实现方式。首先,我需要回忆加法器的基本知识,确保正确性。加法器分为半加器和全加器,记得半加器处理两个一位二进制数,不考虑进位输入,而全加器则要考虑进位输入。用户提供的引用中有提到这些,可以引用[2]来支持。 接下来,用户可能想知道加法器的类型,比如串行和并行,以及它们的区别。串行加法器延迟高,但结构简单;并行加法器如超前进位,速度更快但设计复杂。这里需要结合引用[1]提到的FPGA设计和Quartus II工具,说明实现方式的不同。 然后,关于实现方式,用户提供的引用[3]中有Verilog代码示例,这是一个8位并行加法器,使用连续赋值语句。需要解释这段代码的结构,比如输入输出端口,如何通过组合逻辑实现加法。同时,可以提到其他实现方式,如门级结构或行为级描述,以及它们的优缺点。 用户还可能关心应用场景,比如在ALU、DSP处理器中的使用,或者加密算法中的模加运算。这部分需要结合数字逻辑的整体应用,引用相关例子。 最后,生成相关问题时要覆盖基本概念、类型对比、设计挑战、Verilog实现细节以及应用场景。确保问题有层次,从基础到进阶,帮助用户深入理解。 需要注意使用正确的LaTeX格式,所有数学表达式如$S = A \oplus B \oplus C_{in}$用$包围,独立公式如全加器表达式用$$。同时检查引用标记是否正确添加,例如引用[1]、[2]、[3]的位置是否合适,确保回答结构清晰,符合用户的要求。</think>### 加法器的电路设计与实现方式 #### 1. **基本概念** 加法器是数字逻辑电路中用于执行二进制加法的核心组件。根据功能可分为: - **半加器(Half Adder)**:计算两个一位二进制数的和($S$)与进位($C_{out}$),但不考虑低位进位输入。逻辑表达式为: $$S = A \oplus B$$ $$C_{out} = A \cdot B$$ 常用于最低位的加法[^2]。 - **全加器(Full Adder)**:计算两个一位二进制数的和,并考虑低位进位输入($C_{in}$)。逻辑表达式为: $$S = A \oplus B \oplus C_{in}$$ $$C_{out} = (A \cdot B) + (C_{in} \cdot (A \oplus B))$$ 用于多位数加法的高位计算[^2]。 --- #### 2. **实现方式** ##### (1) **串行进位加法器(Ripple Carry Adder)** - **原理**:将多个全加器串联,低位进位输出($C_{out}$)连接到高位进位输入($C_{in}$)。 - **特点**:结构简单,但延迟随位数增加线性增长,适用于低速场景。 ##### (2) **并行进位加法器(Look-Ahead Carry Adder)** - **原理**:通过提前计算进位信号来减少延迟。逻辑表达式为: $$C_{i} = G_i + P_i \cdot C_{i-1}$$ 其中$G_i = A_i \cdot B_i$(生成信号),$P_i = A_i + B_i$(传播信号)。 - **特点**:速度快但电路复杂度高,常用于高性能计算[^1]。 ##### (3) **硬件描述语言(HDL)实现** - **Verilog示例**(基于引用[3]的8位并行加法器): ```verilog module parallel_adder ( input [7:0] din_a, // 输入A input [7:0] din_b, // 输入B input cin, // 进位输入 output [7:0] sum, // 和 output cout // 进位输出 ); assign {cout, sum} = din_a + din_b + cin; // 直接使用运算符实现 endmodule ``` 此代码通过组合逻辑直接实现加法,综合后生成并行进位电路[^3]。 --- #### 3. **设计挑战与优化** - **延迟优化**:采用超前进位或分组进位(如4位一组)。 - **面积优化**:复用逻辑单元或使用进位选择加法器- **功耗管理**:动态调整电路结构以降低开关活动因子。 --- #### 4. **应用场景** - **算术逻辑单元(ALU)**:CPU中执行加减运算的核心部件。 - **数字信号处理器(DSP)**:用于滤波、FFT等算法中的累加操作。 - **加密算法**:模加运算(如RSA、ECC)的底层实现。 ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值