世界的构建者–BUS

介绍

这个章节会是这个主题中最重要的章节,在这个章节里,我们将会对整个cpu架构有个清楚的认知,之后我们只需要慢慢实现对应的功能模块就好了。

功能介绍

cpu中的的存储与处理相关数据依赖着寄存器阵列,寄存器阵列与外部设备之间的数据交换依赖着总线。这些数据交换的通路就是BUS。

我们先假设我们现在的cpu只实现寄存器阵列之间的数据转移,从外部读取数据以及向外输出数据的功能。

有了上面的功能 我们就需要设计我们这方面功能的指令集:

img1
从图片中我们可以看到
指令集的第0位到第2位作为使能寄存器保存位,他决定着要开启对应寄存器的data_in引脚。
我们的寄存器个数为6,从000开始编号 直到101 ,110为cpu的外部输入引脚 所以我们需要例化一个3线转8线模块

指令集的第3位到第5位作为使能寄存器输出位,他决定着要开启对应寄存器的data_out引脚
    我们的寄存器个数为6,从000开始编号 直到101 ,110为cpu的外部输出引脚 所以我们需要例化一个3线转8线模块
指令集6为与7位为功能选择位,其中10为copy功能

代码实现

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161


module bus(
input reg [7:0] code_in, //指令集输入
input reg [7:0] data_in, //cpu外部输入



output [7:0] data_out, //cpu外部输出

);

// 使能寄存器保存与输出3转8模块的线阵列
wire [7:0] data_save_en;
wire [7:0] data_load_en;
//数据交换总线
wire [7:0] bus_line_w;
//功能选择线阵列
wire [3:0] function_sel_w;

//寄存器一直输出的线阵列 (本章可省略)
wire [7:0] reg_0_always_out_w;
wire [7:0] reg_1_always_out_w;
wire [7:0] reg_2_always_out_w;
wire [7:0] reg_3_always_out_w;


reg en =1'b1;

//线转寄存器
reg [7:0] bus_line = 8'b00000000;
reg [7:0] data_load_en_r=8'b00000000;
reg [7:0] data_save_en_r=8'b00000000;
reg [3:0] function_sel=2'b00;

reg reg_3_en=1'b0;
reg reg_0_en=1'b0;

//寄存器一直输出的线阵列 (本章可省略)
reg [7:0] reg_0_always_out;
reg [7:0] reg_3_always_out;




//最高两位为具体功能 第六位位数据位或地址位
always @(data_save_en or data_load_en or bus_line_w) begin
data_save_en_r<=data_save_en;
data_load_en_r<=data_load_en;
function_sel<=function_sel_w;
bus_line<=bus_line_w;
end





//功能解码位
decoder_2to4 decoder_2to4_sel(
.in (code_in[7:6]) ,
.en (en),
.out (function_sel_w)
);







//寄存器解码 保存
decoder_3to8 decoder_3to8_save(
.in (code_in[2:0]) ,
.en (function_sel_w[2]) , //当功能为copy时激活
.out (data_save_en)
);


//寄存器解码 输出
decoder_3to8 decoder_3to8_load(
.in (code_in[5:3]) ,
.en (function_sel_w[2]) ,//当功能为copy时激活

.out (data_load_en)
);


//寄存器挂载

register_pluse register_pluser_0(
.save_en (reg_0_en),
.load_en (data_load_en_r[0]),
.data_in (bus_line) ,

.data_out (bus_line_w) ,
.data_out_always (reg_0_always_out_w)
);

register_pluse register_pluser_1(
.save_en (data_save_en_r[1]),
.load_en (data_load_en_r[1]),
.data_in (bus_line) ,

.data_out (bus_line_w) ,
.data_out_always (reg_1_always_out_w)
);

register_pluse register_pluser_2(
.save_en (data_save_en_r[2]),
.load_en (data_load_en_r[2]),
.data_in (bus_line) ,
.data_out (bus_line_w) ,
.data_out_always (reg_2_always_out_w)
);

register_pluse register_pluser_3(
.save_en (reg_3_en),
.load_en (data_load_en_r[3]),
.data_in (bus_line) ,
.data_out (bus_line_w) ,
.data_out_always (reg_3_always_out_w)
);

register_pluse register_pluser_4(
.save_en (data_save_en_r[4]),
.load_en (data_load_en_r[4]),
.data_in (bus_line) ,
.data_out (bus_line_w) ,
.data_out_always ()
);

register_pluse register_pluser_5(
.save_en (data_save_en_r[5]),
.load_en (data_load_en_r[5]),
.data_in (bus_line) ,
.data_out (bus_line_w) ,
.data_out_always ()
);




//输入口
register_pluse register_pluser_in(
.save_en (en),
.load_en (data_load_en_r[6]),
.data_in (data_in) ,
.data_out (bus_line_w) ,
.data_out_always ()
);

//输出口
register_pluse register_pluser_out(
.save_en (data_save_en_r[6]),
.load_en (en),
.data_in (bus_line) ,

.data_out (data_out) ,
.data_out_always ()
);
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

`timescale 1ns/1ns

module bus_tb;


reg [7:0] code_in=8'b zzzzzzzz;
reg [7:0] data_in=8'b zzzzzzzz;

wire [7:0] data_out;
wire [7:0] code_addr_out;



initial begin
#50 data_in=8'b 11110000;
#50 code_in=8'b 00_110_000; //从外界输入赋予寄存器0

#50 data_in=8'b 00001111;
#50 code_in=8'b 00_110_001; //从外界输入赋予寄存器1

#50 code_in=8'b 00_000_010; //从寄存器0复制到寄存器2

#50 code_in=8'b 00_001_011; //从寄存器0复制到寄存器3

#50 code_in=8'b 00_011_100; //从寄存器3复制到寄存器4

end

bus bus_my(
.code_in (code_in),
.data_in (data_in),
.data_out (data_out),
.code_addr_out (code_addr_out)
);

endmodule

结语

在本章中,我们构建了cpu的基本框架实现了总线的设计与copy的功能,在后面的章节中我们将一个个介绍cpu的哥哥功能模块并在最后的章节中拼接起来组成一个完整的cpu。

整点二次元

img2