计算机组成原理——ALU

目录

  • alu.v
  • alu_display
  • tb.v

alu.v

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/10/19 15:26:33
// Design Name: 
// Module Name: alu
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module alu(
    input  clk,
    input  [31 :0] alu_src1,//操作数1
    input  [31 :0] alu_src2,//操作数2
    input  [11:0] alu_control,//操作

    output  reg[31 :0] alu_result//结果
    );
    wire op1_sign;
    wire op2_sign;
    wire [31:0] adder_result;
    wire [31:0] sub_result;
    assign op1_sign=alu_src1[0];
    assign op2_sign=alu_src2[0];
    assign adder_result=alu_src1+alu_src2;
    //补码运算[A-B]补 = [A]补 + [-B]补,[-B]补的求法就是 [B]补的连同符号位在内,每位求反加一
    assign sub_result=alu_src1+(~alu_src2+1);
    
    
    always@(*)
    begin
        //位运算中负数以补码形式参加
        if(alu_control==12'd1)//加 
            alu_result<=adder_result;
        else if(alu_control==12'd2)//减
            alu_result<=sub_result;
        else if(alu_control==12'd4)//有符号比较,输入转化成补码计算
            alu_result<=sub_result[31]?1:0;
        else if(alu_control==12'd8)//无符号比较
            alu_result<=alu_src1<alu_src2?1:0;
        else if(alu_control==12'd16)//按位与
            alu_result<=alu_src1&alu_src2;
        else if(alu_control==12'd32)//按位或非
            alu_result<=~(alu_src1|alu_src2);
        else if(alu_control==12'd64)//按位或
            alu_result<=(alu_src1|alu_src2);
        else if(alu_control==12'd128)//按位异或
            alu_result<=(alu_src1^alu_src2);
        else if(alu_control==12'd256)//逻辑左移
            alu_result<=alu_src1<<alu_src2;
        else if(alu_control==12'd512)//逻辑右移
            alu_result<=alu_src1>>alu_src2;
        else if(alu_control==12'd1024)//算数右移
            alu_result<=alu_src1>>>alu_src2;
    end
    
    
    
endmodule

alu_display

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

    //拨码开关,用于选择输入数
    input [1:0] input_sel, //00:输入为控制信号(alu_control)
                           //10:输入为源操作数1(alu_src1)
                           //11:输入为源操作数2(alu_src2)

    //触摸屏相关接口,不需要更改
    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
    );
//-----{调用ALU模块}begin
    reg   [11:0] alu_control;  // ALU控制信号
    reg   [31:0] alu_src1;     // ALU操作数1
    reg   [31:0] alu_src2;     // ALU操作数2
    wire  [31:0] alu_result;   // ALU结果
    alu alu_module(
        .alu_control(alu_control),
        .alu_src1   (alu_src1   ),
        .alu_src2   (alu_src2   ),
        .alu_result (alu_result )
    );
//-----{调用ALU模块}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为00时,表示输入数控制信号,即alu_control
    always @(posedge clk)
    begin
        if (!resetn)
        begin
            alu_control <= 12'd0;
        end
        else if (input_valid && input_sel==2'b00)
        begin
            alu_control <= input_value[11:0];
        end
    end
    
    //当input_sel为10时,表示输入数为源操作数1,即alu_src1
    always @(posedge clk)
    begin
        if (!resetn)
        begin
            alu_src1 <= 32'd0;
        end
        else if (input_valid && input_sel==2'b10)
        begin
            alu_src1 <= input_value;
        end
    end

    //当input_sel为11时,表示输入数为源操作数2,即alu_src2
    always @(posedge clk)
    begin
        if (!resetn)
        begin
            alu_src2 <= 32'd0;
        end
        else if (input_valid && input_sel==2'b11)
        begin
            alu_src2 <= 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  <= "SRC_1";
                display_value <= alu_src1;
            end
            6'd2 :
            begin
                display_valid <= 1'b1;
                display_name  <= "SRC_2";
                display_value <= alu_src2;
            end
            6'd3 :
            begin
                display_valid <= 1'b1;
                display_name  <= "CONTR";
                display_value <={20'd0, alu_control};
            end
            6'd4 :
            begin
                display_valid <= 1'b1;
                display_name  <= "RESUL";
                display_value <= alu_result;
            end
            default :
            begin
                display_valid <= 1'b0;
                display_name  <= 40'd0;
                display_value <= 32'd0;
            end
        endcase
    end
//-----{输出到触摸屏显示}end
//----------------------{调用触摸屏模块}end---------------------//
endmodule

tb.v

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/10/19 22:29:34
// Design Name: 
// Module Name: tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb;
    reg  clk;
    reg  [31 :0] alu_src1;//操作数1
    reg  [31 :0] alu_src2;//操作数2
    reg  [11:0]  alu_control;//操作
    wire [31 :0] alu_result;//结果
    
    alu alu_model(
        .clk(clk),
        .alu_src1(alu_src1),
        .alu_src2(alu_src2),
        .alu_control(alu_control),
        .alu_result(alu_result)
    );
    initial begin
    clk=0;
    alu_control=12'd1;
    alu_src1=31'd6;
    alu_src2=31'H80000001;
    #100
    alu_control=12'd2;
    #200
    alu_control=12'd4;
    #100
    alu_control=12'd8;
    #100
    alu_control=12'd16;
    #100
    alu_control=12'd32;
    #100
    alu_control=12'd64;
    #100
    alu_control=12'd128;
    #100
    alu_control=12'd256;
    #100
    alu_control=12'd512;
    #100
    alu_control=12'd1024;
    end
    always #5 clk=~clk;
 
endmodule

你可能感兴趣的:(计算机组成原理,javascript,html)