64位加法——计算机组成原理实验1

实验原理图

在这里插入图片描述

实验步骤

因为一次最多输入32位数,而要实现64位的加法器,我们采用32位加法器拼接的方式
在输入的时候需要把两个64位数分成高32位和低32位分别输入。
在运算的过程中,先对两个64位数的低32位进行运算,生成低32位的结果(result_low)和一个临时进位(cout_low_to_high)
再对两个64位数的高32位相加,并加上上一步产生的临时进位,生成高32位的结果(result_high)和最终进位(cout)

修改后的最终代码如下:

//adder.v
module adder(
    input  [31:0] operand1_high,
    input  [31:0] operand1_low,
    input  [31:0] operand2_high,
    input  [31:0] operand2_low,
    input         cin,
    output [31:0] result_high,
    output [31:0] result_low,
    output        cout,
    wire cout_low_to_high 
    );
    assign{cout_low_to_high ,result_low}=operand1_low+ operand2_low+cin;
    assign {cout,result_high} =cout_low_to_high + operand1_high +operand2_high;

endmodule

下面对adder_display.v进行更改
//adder_display.v

64位加法需要两个开关分别输入高32位和低32位

input input_sel_num, //0:输入为加数1(add_operand1);1:输入为加数2(add_operand2)
input input_sel_high_or_low, //0:输入为低32位;1:输入为高32位

下面修改对adder的调用
首先创建寄存器,用于存储输入的数
代码如下:

reg  [31:0] adder_operand1_low; 
reg  [31:0] adder_operand1_high; 
reg  [31:0] adder_operand2_low;
reg  [31:0] adder_operand2_high;
wire        adder_cin;
wire [31:0] adder_result_low;
wire [31:0] adder_result_high;
wire        adder_cout;

接着实例化adder
代码如下:

adder adder_module(
    .operand1_high(adder_operand1_high), 
    .operand1_low(adder_operand1_low),    
    .operand2_high(adder_operand2_high), 
    .operand2_low(adder_operand2_low),   
    .cin     (adder_cin),   
    .result_low(adder_result_low),  
    .result_high(adder_result_high),    
    .cout    (adder_cout) 
);
assign adder_cin = sw_cin;
assign led_cout  = adder_cout;

接着根据两个开关和使能端R的选择为64位数分别赋值
代码如下:

//当 input_sel_num 为0时,表示输入数为加数1,即 operand1 ;
//当 input_sel_num 为1时,表示 输入数为加数2,即 operand
//当input_Sel_high_or_low为0:输入为低32位;1:输入为高32位

always @(posedge clk)
begin
    if (!resetn)
    begin
        adder_operand1_low <= 32'd0;
        adder_operand1_high <= 32'd0;
    end
    else if (input_valid && !input_sel_num && !input_sel_high_or_low)
    begin
        adder_operand1_low <= input_value;
    end
     else if (input_valid && !input_sel_num && input_sel_high_or_low)
    begin
        adder_operand1_high <= input_value;
    end
    
end

//当input_sel_num为1时,表示输入数为加数2,即operand2
always @(posedge clk)
begin
    if (!resetn)
    begin
        adder_operand2_low <= 32'd0;
        adder_operand2_high <= 32'd0;
    end
    else if (input_valid && input_sel_num && !input_sel_high_or_low)
    begin
        adder_operand2_low <= input_value;
    end
    else if (input_valid && input_sel_num && input_sel_high_or_low)
    begin
        adder_operand2_high <= 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  <= "1_HIGH";
                display_value <= adder_operand1_high;
            end
            6'd2 :
            begin
                display_valid <= 1'b1;
                display_name  <= "1_LOW";
                display_value <= adder_operand1_low;
            end
            6'd3 :
            begin
                display_valid <= 1'b1;
                display_name  <= "2_HIGH";
                display_value <= adder_operand2_high;
            end
            6'd4 :
            begin
                display_valid <= 1'b1;
                display_name  <= "2_LOW";
                display_value <= adder_operand2_low;
            end
            6'd5 :
            begin
                display_valid <= 1'b1;
                display_name  <= "R_HIGH";
                display_value <= adder_result_high;
            end
            6'd6 :
            begin
                display_valid <= 1'b1;
                display_name  <= "R_LOW";
                display_value <= adder_result_low;
            end
            default :
            begin
                display_valid <= 1'b0;
                display_name  <= 40'd0;
                display_value <= 32'd0;
            end
        endcase
    end
//-----{输出到触摸屏显示}end
//----------------------{调用触摸屏模块}end---------------------//
endmodule

然后在.xdc文件中修改新加的两个拨码开关和 FPGA 上具体的接口的连接。
查图可以得到 SW2 和 SW3 对应的 Package Pin 分别是 AC22 和 AC23 。
我们把 input_sel_num 连接到 SW2 ,把 input_sel_high_or_low 连接到 SW3 ,并为其设立合理电压。
代码如下:

set_property PACKAGE_PIN AC22 [get_ports input_sel_num] 
set_property IOSTANDARD LVCMOS33 [get_ports input_sel_num] 
set_property PACKAGE_PIN AC23 [get_ports input_sel_high_or_low]
set_property IOSTANDARD LVCMOS33 [get_ports input_sel_high_or_low] 

最后对仿真文件testbench.v进行修改
代码如下:

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

    // Inputs
    reg [31:0] operand1_low;
    reg [31:0] operand1_high;   
    reg [31:0] operand2_low;   
    reg [31:0] operand2_high; 
    reg cin;

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

实验结果分析:
在这里插入图片描述

用计算器验证,结果正确

烧入 FPGA 得到如下结果:

在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值