CPU设计笔记1-ALU

序号

逻辑

功能说明

操作

1

Shift Left Logic:

逻辑左移

Rd = rs1 << rs2

2

Shift right Logic

逻辑右移

扫描二维码关注公众号,回复: 6545944 查看本文章

Rd = rs1 >> rs2

3

Shift right Arithmetci

算术右移

Rd = rs1 >> rs2 (arithmetic)

4

add

加,如果溢出给出overflow信号

Rd = rs1 + rs2

5

Sub

减,如果溢出给出overflow信号

Rd = rs1 - rs2

6

Load upper imm

高位加载立即数

Rd = {20bitImm, 12'd0}

7

Signed set if less than

有符号数rs1和rs2的比较

Rd = (signed rs1 < signed rs2) ? 1 : 0

8

Unsigned set if less than

无符号数rs1和rs2的比较

Rd = unsigned rs1 < unsigned rs2 ? 1 : 0

9

xor

异或操作

Rd = rs1 ^ rs2

10

Or

或操作

Rd = rs1 | rs2

11

and

与操作

Rd = rs1 & rs2

12

Mul

乘操作,忽略溢出

Rd = (rs1 * rs2)[31:0]

 

模块的参考接口如下

信号名

位宽

I/O

描述

op

4

I

ALU的操作码定义

rs1

32

I

第1操作数

rs2

32

I

第2操作数

rd

32

O

ALU运算结果操作数

overflow

1

o

操作溢出标志

代码:

module ALU(
    input [3:0] op,
    input [31:0] rs1,
    input [31:0] rs2,
    input [19:0] imm,
    output [31:0] rd,
    output overflow
    );
    
wire [31:0]out1;
wire [31:0]out2;
wire [31:0]out3;
wire [31:0]out4;
wire [31:0]out5;
wire [31:0]out6;
wire [31:0]out7;
wire [31:0]out8;
wire [31:0]out9;
wire [31:0]out10;
wire [31:0]out11;

wire [32:0]sum;
wire [63:0]mul;

assign sum = rs1 + rs2;
assign mul = rs1 * rs2;

assign overflow = ((op == 4'b0011)) & sum[32] | ((op == 4'b1011) & (mul[63:32] > 0));

//第一层mux
assign out1 = op[0] ? rs1>>rs2 : rs1<<rs2;
assign out2 = op[0] ? sum[31:0] : (( {{31{rs1[31]}}, 1'b0 } << (~rs2[4:0]) ) | (rs1 >> rs2[4:0]));
assign out3 = op[0] ? {imm,12'd0} : rs1-rs2;
assign out4 = op[0] ? rs1<rs2 : ((rs1[31] ^~ rs2[31]) & (rs1 < rs2)) | (rs1[31] & ~rs2[31]);
assign out5 = op[0] ? rs1 | rs2 : rs1^rs2;
assign out6 = op[0] ? mul[31:0] : rs1&rs2;
//第二层mux
assign out7 = op[1] ? out2 : out1;
assign out8 = op[1] ? out4 : out3;
assign out9 = op[1] ? out6 : out5;
//第三层mux
assign out10 = op[2] ? out8 : out7;
assign out11 = op[2] ? {32{1'bZ}} : out9; 
//第四层mux
assign rd = op[3] ? out11 : out10;

endmodule

testbench

module ALU_tb(

    );

reg [3:0] op;
reg [31:0] rs1;
reg [31:0] rs2;
reg [19:0] imm;
wire [31:0] rd;
wire overflow;

ALU alu0(
    .op(op),
    .rs1(rs1),
    .rs2(rs2),
    .imm(imm),
    .rd(rd),
    .overflow(overflow)
);

initial
begin
op = 0;
rs1 = 32'h0fffffff;
rs2 = 32'hfffffffe;
imm = 3;

#20
op = 1;

#20
op = 2;

#20
op = 3;

#20
op = 4;

#20
op = 5;

#20
op = 6;

#20
op = 7;

#20
op = 8;

#20
op = 9;

#20
op = 10;

#20
op = 11;

#20
op = 12;

end


endmodule

猜你喜欢

转载自blog.csdn.net/qq_24815615/article/details/92441064
alu