浮世分析者———ALU

介绍

ALU是Arithmetic Logic Unit的缩写,即算术逻辑单元。它是CPU中的一个重要组成部分,用于执行各种算术和逻辑操作。例如加法,减法,或运算,与运算等。这些运算被集成在ALU中,我们通过输入的电信号来选择相应的功能对输入数据进行操作并输出到总线上。

引脚图介绍

img1

~~ 太丑了,懒得改了,凑合看吧~~

  • 指令 输入对应电平表中数据选择相应模式
    从ram中读取的8位指令,如果第7位为1,则启用ALU,否则不启用。前三位为启用时的模式选择.
    前三维指令表如图所示:
    img2
  • 输入1 连接特定寄存器一的始终输出引脚
  • 输入2 连接特定寄存器二的始终输出引脚
  • 输出 连接到总线

功能介绍

从引脚图我们可以得到ALU也是由对应的指令所控制的,他链接着特定的寄存器,并输出到总线上。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

module alu (
input alu_sel, //是否启用alu 使能位
input reg [2:0] alu_order, //alu指令 指令位
input [7:0] reg_1, //链接特定寄存器1 always_out
input [7:0] reg_2, // 链接特定寄存器2 always_out

output [7:0] alu_out //链接总线的输出位
);

//运算操作中对应的指令集
parameter alu_or = 3'b 000;
parameter alu_nand = 3'b 001;
parameter alu_nor = 3'b 010;
parameter alu_and = 3'b 011;
parameter alu_add = 3'b 100;
parameter alu_sub = 3'b 101;

reg [7:0] alu_out_r;
assign alu_out=alu_out_r;

always @(alu_sel or alu_order ) begin
if (alu_sel==1'b0) begin //当ALU使能位为0时输出高阻态
alu_out_r=8'b zzzzzzz;
end
else if (alu_sel==1'b1) begin //当ALU使能位为1时读取对应位进行相应操作
case (alu_order)
alu_or:
alu_out_r=reg_1|reg_2;
alu_nand:
alu_out_r=~(reg_1&reg_2);
alu_nor:
alu_out_r=~(reg_1|reg_2);
alu_and:
alu_out_r=reg_1&reg_2;
alu_add:
alu_out_r=reg_1+reg_2;
alu_sub:
alu_out_r=reg_1-reg_2;
default:
alu_out_r=8'b zzzzzzz;
endcase

end
end
endmodule

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

`timescale 1ns/1ns
module alu_tb;

reg alu_sel_r; //ALU使能位
reg [7:0] reg_1; //链接特定寄存器1
reg [7:0] reg_2; //链接特定寄存器2
reg [2:0] alu_order; //ALU指令位
wire alu_out; //链接总线的输出位

wire [7:0] reg_1_w;
wire [7:0] reg_2_w;
wire alu_sel_w;
wire [2:0] alu_order_w;
assign reg_1_w = reg_1;
assign reg_2_w = reg_2;
assign alu_sel_w = alu_sel_r;
assign alu_order_w = alu_order;

initial begin

alu_sel_r=1'b0;
alu_order=3'b000;
reg_1=8'b11110000;
reg_2=8'b00001111;
#50 alu_sel_r=1'b1;

#50 alu_order=3'b001;

#50 alu_order=3'b010;

#50 alu_order=3'b011;

#50 alu_order=3'b100;

#50 alu_order=3'b101;

#50 alu_order=3'b110;
end

alu alu_my( .alu_sel(alu_sel_w),
.alu_order(alu_order_w),
.reg_1(reg_1_w),
.reg_2(reg_2_w),
.alu_out(alu_out) );



endmodule



结语

在本教程的alu中我们只用了3个指令位 ,我们很容易想到可以拓展指令位达到实现更复杂的功能,如单寄存器的取反指令,移位指令,双寄存器的乘法,除法操作等等。如果我后面更新32位cpu时会完成这些指令的实现。

整点二次元

img3