【计算机组成原理】实验2:ALU(Verilog)中海大

【计算机组成原理】实验2

使用Verilog语言实现一个简单ALU,测试平台:Vivado

①代码:

alu.v

`timescale 1ns / 1ps
module alu(
    input  [11:0] alu_control,  // ALU控制信号
    input  [31:0] alu_src1,     // ALU操作数1,为补码
    input  [31:0] alu_src2,     // ALU操作数2,为补码
    output [31:0] alu_result    // ALU结果
    );

    wire alu_add;   //加法操作
    wire alu_sub;   //减法操作
    wire alu_slt;   //有符号比较,小于置位,复用加法器做减法
    wire alu_sltu;  //无符号比较,小于置位,复用加法器做减法
    wire alu_and;   //按位与
    wire alu_nor;   //按位或非
    wire alu_or;    //按位或
    wire alu_xor;   //按位异或
    wire alu_sll;   //逻辑左移
    wire alu_srl;   //逻辑右移
    wire alu_sra;   //算术右移
    wire alu_lui;   //高位加载

    assign alu_add  = alu_control[11];
    assign alu_sub  = alu_control[10];
    assign alu_slt  = alu_control[ 9];
    assign alu_sltu = alu_control[ 8];
    assign alu_and  = alu_control[ 7];
    assign alu_nor  = alu_control[ 6];
    assign alu_or   = alu_control[ 5];
    assign alu_xor  = alu_control[ 4];
    assign alu_sll  = alu_control[ 3];
    assign alu_srl  = alu_control[ 2];
    assign alu_sra  = alu_control[ 1];
    assign alu_lui  = alu_control[ 0];

    wire [31:0] add_sub_result; 
    wire [31:0] slt_result; 
    wire [31:0] sltu_result;
    wire [31:0] and_result; 
    wire [31:0] nor_result; 
    wire [31:0] or_result;  
    wire [31:0] xor_result; 
    wire [31:0] sll_result; 
    wire [31:0] srl_result;
    wire [31:0] sra_result; 
    wire [31:0] lui_result; 
    wire signed [31:0] temp_src1;  
    assign temp_src1 = alu_src1;   

    assign and_result = alu_src1 & alu_src2;     
    assign or_result  = alu_src1 | alu_src2;     
    assign nor_result = ~or_result;             
    assign xor_result = alu_src1 ^ alu_src2;
    assign lui_result = {alu_src2[15:0], 16'd0}; 
    wire [31:0] adder_operand1;
    wire [31:0] adder_operand2;
    wire [31:0] adder_result;
    wire adder_cin;
    wire adder_cout;
    assign adder_operand1 = alu_src1;
    assign adder_operand2 = alu_add ? alu_src2 : ~alu_src2; // 1+ , 0-
    assign adder_cin = ~alu_add;
    
    adder adder_module(
    .operand1(adder_operand1),
    .operand2(adder_operand2),
    .cin(adder_cin),
    .result(adder_result),
    .cout(adder_cout)
    );
    
    assign add_sub_result = adder_result;
    assign slt_result = adder_result[31] ?  1'b1 : 1'b0;
    assign sltu_result = adder_cout ? 1'b0 : 1'b1;

    wire [4:0] shf;
    assign shf = alu_src1[4:0];
    wire [1:0] shf_1_0;
    wire [1:0] shf_3_2;
    assign shf_1_0 = shf[1:0];
    assign shf_3_2 = shf[3:2];
    
    wire [31:0] sll_step1;
    wire [31:0] sll_step2;
    assign sll_step1 = {32{shf_1_0 == 2'b00}} & alu_src2                   
                     | {32{shf_1_0 == 2'b01}} & {alu_src2[30:0], 1'd0}     
                     | {32{shf_1_0 == 2'b10}} & {alu_src2[29:0], 2'd0}     
                     | {32{shf_1_0 == 2'b11}} & {alu_src2[28:0], 3'd0};  
    assign sll_step2 = {32{shf_3_2 == 2'b00}} & sll_step1                  
                     | {32{shf_3_2 == 2'b01}} & {sll_step1[27:0], 4'd0}    
                     | {32{shf_3_2 == 2'b10}} & {sll_step1[23:0], 8'd0}    
                     | {32{shf_3_2 == 2'b11}} & {sll_step1[19:0], 12'd0};  
    assign sll_result = shf[4] ? {sll_step2[15:0], 16'd0} : sll_step2;    
    assign srl_result = alu_src1 >> alu_src2;      
assign sra_result = temp_src1 >>> alu_src2;    
 
    assign alu_result = (alu_add|alu_sub) ? add_sub_result[31:0] : 
                        alu_slt           ? slt_result :
                        alu_sltu          ? sltu_result :
                        alu_and           ? and_result :
                        alu_nor           ? nor_result :
                        alu_or            ? or_result  :
                        alu_xor           ? xor_result :
                        alu_sll           ? sll_result :
                        alu_srl           ? srl_result :
                        alu_sra           ? sra_result :
                        alu_lui           ? lui_result :
                        32'd0;
endmodule

Adder_module

adder.v:

`timescale 1ns / 1ps
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

TestBench.v:

`timescale 1ns / 1ps
module tb;
    reg clk;
    reg [11:0] alu_control;
    reg [31:0] alu_src1;
reg [31:0] alu_src2;

    wire [31:0] alu_result;

    alu al(
    .alu_control(alu_control),
    .alu_src1(alu_src1),
    .alu_src2(alu_src2),
    .alu_result(alu_result)
    );

    initial begin
        clk = 0;
        alu_control = 0;

        #10;
        alu_src1 = 32'H00001111;
		alu_src2 = 32'H00000008;
        alu_control = 12'b0000_0000_0001;
        
        #40;
        alu_src1 = 32'HF0001234;
		alu_src2 = 32'H00000008;
        alu_control = 12'b0000_0000_0010;
        
        #40;
        alu_src1 = 32'HF0001234;
		alu_src2 = 32'H00000008;
        alu_control = 12'b0000_0000_0100;
        
        #40;
        alu_src1 = 32'H00012345;
		alu_src2 = 32'H00000008;
        alu_control = 12'b0000_0000_1000;
        
        #40;
        alu_src1 = 32'H00001111;
		alu_src2 = 32'H00000101;
        alu_control = 12'b0000_0001_0000;
        #40;
        alu_control = 12'b0000_0010_0000;
        #40;
        alu_control = 12'b0000_0100_0000;
        #40;
        alu_control = 12'b0000_1000_0000;
		#40;
        alu_control = 12'b0001_0000_0000;
		#40;
        alu_control = 12'b0010_0000_0000;
		#40;
        alu_control = 12'b0100_0000_0000;
		#40;
        alu_control = 12'b1000_0000_0000;
        
        #40;                //end
        alu_control = 0;
        alu_src1 = 32'H00000000;
		alu_src2 = 32'H00000000;    
        
    end
   always #5 clk = ~clk;
endmodule

②仿真图像及其分析:

alu_control=001时进行alu_src2的高位加载,

002时进行alu_src1的算术右移,

004时进行alu_src1的逻辑右移,

008时进行alu_src1的逻辑左移,

010时进行按位异或,020时进行按位或,040时进行按位或非,080时进行按位与,

100时进行无符号比较,200时进行有符号比较

400时进行减法操作,800时进行加法操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值