Skip to content
This repository was archived by the owner on Jul 6, 2023. It is now read-only.

Commit 8e4b730

Browse files
committed
feat: pipeline CPU
1 parent bfbed38 commit 8e4b730

File tree

19 files changed

+579
-62
lines changed

19 files changed

+579
-62
lines changed

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
.DS_Store
22

33
src/core.vvp
4-
src/dump.vcd
5-
src/wave.gtkw
4+
src/dump.vcd

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
系统贯通课程会逐步实现一个 RISC-V 五级流水线 CPU,并实现异常处理、分支预测、Cache 等功能。本 repo 通过分支、tag 等来记录实验进度,保存各阶段成果。
1010

1111
- [x] 系统 Ⅰ lab5-1/lab5-2:单周期 CPU
12-
- [ ] extra:单周期 CPU with 特权指令/异常处理
13-
- [ ] 系统 Ⅱ lab1:流水线 CPU (stall)
12+
- [x] extra:单周期 CPU with 特权指令/异常处理
13+
- [x] 系统 Ⅱ lab1:流水线 CPU (stall)
1414
- [ ] 系统 Ⅱ lab2:流水线 CPU (forwarding)
1515
- [ ] 系统 Ⅱ lab7:流水线 CPU with 特权指令/异常处理
1616
- [ ] 系统 Ⅲ lab1:流水线 CPU with 动态分支预测

src/CPU.v

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
`timescale 1ns / 1ps
2+
3+
module CPU(
4+
input clk,
5+
input rst,
6+
input [31:0] inst,
7+
input [31:0] data_in, // data from data memory
8+
input [4:0] debug_reg_addr,
9+
output [31:0] addr_out, // data memory address
10+
output [31:0] data_out, // data to data memory
11+
output [31:0] pc_out, // connect to instruction memory
12+
output mem_write,
13+
output [31:0] debug_reg
14+
);
15+
reg [31:0] pc;
16+
wire [31:0] pc_next;
17+
18+
reg [31:0] IF_ID_pc;
19+
reg [31:0] IF_ID_inst;
20+
21+
wire [31:0] read_data1, read_data2, imm;
22+
wire [3:0] alu_op;
23+
wire [1:0] pc_src, mem_to_reg;
24+
wire reg_write, alu_src, branch, b_type, auipc, mem_write_;
25+
reg [31:0] ID_EX_data1, ID_EX_data2;
26+
reg [31:0] ID_EX_pc, ID_EX_imm;
27+
reg [4:0] ID_EX_write_addr;
28+
reg [3:0] ID_EX_alu_op;
29+
reg [1:0] ID_EX_pc_src, ID_EX_mem_to_reg;
30+
reg ID_EX_reg_write, ID_EX_alu_src, ID_EX_branch, ID_EX_b_type, ID_EX_auipc, ID_EX_mem_write;
31+
32+
wire [31:0] alu_data1, alu_data2, alu_result;
33+
wire alu_zero;
34+
reg [31:0] EX_MEM_alu_result, EX_MEM_pc, EX_MEM_imm;
35+
reg [31:0] EX_MEM_data2;
36+
reg [4:0] EX_MEM_write_addr;
37+
reg [1:0] EX_MEM_pc_src, EX_MEM_mem_to_reg;
38+
reg EX_MEM_reg_write, EX_MEM_branch, EX_MEM_b_type, EX_MEM_mem_write;
39+
40+
wire [31:0] write_data;
41+
wire [31:0] jal_addr, jalr_addr;
42+
reg [31:0] MEM_WB_data_in, MEM_WB_alu_result, MEM_WB_pc, MEM_WB_imm;
43+
reg [4:0] MEM_WB_write_addr;
44+
reg [1:0] MEM_WB_mem_to_reg;
45+
reg MEM_WB_reg_write;
46+
47+
48+
assign pc_out = pc;
49+
50+
always @(posedge clk or posedge rst) begin
51+
if (rst) begin
52+
pc <= 32'b0;
53+
IF_ID_pc <= 32'b0;
54+
IF_ID_inst <= 32'b0;
55+
ID_EX_pc <= 32'b0;
56+
ID_EX_data1 <= 32'b0;
57+
ID_EX_data2 <= 32'b0;
58+
ID_EX_imm <= 32'b0;
59+
ID_EX_write_addr <= 5'b0;
60+
ID_EX_alu_op <= 4'b0;
61+
ID_EX_pc_src <= 2'b0;
62+
ID_EX_mem_to_reg <= 2'b0;
63+
ID_EX_reg_write <= 1'b0;
64+
ID_EX_alu_src <= 1'b0;
65+
ID_EX_branch <= 1'b0;
66+
ID_EX_b_type <= 1'b0;
67+
ID_EX_auipc <= 1'b0;
68+
ID_EX_mem_write <= 1'b0;
69+
EX_MEM_alu_result <= 32'b0;
70+
EX_MEM_pc <= 32'b0;
71+
EX_MEM_imm <= 32'b0;
72+
EX_MEM_data2 <= 32'b0;
73+
EX_MEM_write_addr <= 5'b0;
74+
EX_MEM_pc_src <= 2'b0;
75+
EX_MEM_mem_to_reg <= 2'b0;
76+
EX_MEM_reg_write <= 1'b0;
77+
EX_MEM_branch <= 1'b0;
78+
EX_MEM_b_type <= 1'b0;
79+
EX_MEM_mem_write <= 1'b0;
80+
MEM_WB_data_in <= 32'b0;
81+
MEM_WB_alu_result <= 32'b0;
82+
MEM_WB_pc <= 32'b0;
83+
MEM_WB_imm <= 32'b0;
84+
MEM_WB_write_addr <= 5'b0;
85+
MEM_WB_mem_to_reg <= 2'b0;
86+
MEM_WB_reg_write <= 1'b0;
87+
end
88+
else begin
89+
pc <= pc_next;
90+
91+
IF_ID_pc <= pc;
92+
IF_ID_inst <= inst;
93+
94+
ID_EX_pc <= IF_ID_pc;
95+
ID_EX_data1 <= read_data1;
96+
ID_EX_data2 <= read_data2;
97+
ID_EX_imm <= imm;
98+
ID_EX_write_addr <= IF_ID_inst[11:7];
99+
ID_EX_pc_src <= pc_src;
100+
ID_EX_mem_to_reg <= mem_to_reg;
101+
ID_EX_reg_write <= reg_write;
102+
ID_EX_alu_src <= alu_src;
103+
ID_EX_branch <= branch;
104+
ID_EX_b_type <= b_type;
105+
ID_EX_auipc <= auipc;
106+
ID_EX_alu_op <= alu_op;
107+
ID_EX_mem_write <= mem_write_;
108+
109+
EX_MEM_pc <= ID_EX_pc;
110+
EX_MEM_imm <= ID_EX_imm;
111+
EX_MEM_data2 <= ID_EX_data2;
112+
EX_MEM_alu_result <= alu_result;
113+
EX_MEM_write_addr <= ID_EX_write_addr;
114+
EX_MEM_pc_src <= ID_EX_pc_src;
115+
EX_MEM_mem_to_reg <= ID_EX_mem_to_reg;
116+
EX_MEM_reg_write <= ID_EX_reg_write;
117+
EX_MEM_branch <= ID_EX_branch;
118+
EX_MEM_b_type <= ID_EX_b_type;
119+
EX_MEM_mem_write <= ID_EX_mem_write;
120+
121+
MEM_WB_data_in <= data_in;
122+
MEM_WB_alu_result <= EX_MEM_alu_result;
123+
MEM_WB_pc <= EX_MEM_pc;
124+
MEM_WB_imm <= EX_MEM_imm;
125+
MEM_WB_write_addr <= EX_MEM_write_addr;
126+
MEM_WB_mem_to_reg <= EX_MEM_mem_to_reg;
127+
MEM_WB_reg_write <= EX_MEM_reg_write;
128+
129+
end
130+
end
131+
132+
//--------------------ID--------------------//
133+
134+
Regs regs (
135+
.clk(clk),
136+
.rst(rst),
137+
.we(MEM_WB_reg_write),
138+
.read_addr_1(IF_ID_inst[19:15]),
139+
.read_addr_2(IF_ID_inst[24:20]),
140+
.write_addr(MEM_WB_write_addr),
141+
.write_data(write_data),
142+
.read_data_1(read_data1),
143+
.read_data_2(read_data2),
144+
.debug_reg_addr(debug_reg_addr),
145+
.debug_reg(debug_reg)
146+
);
147+
148+
Control control (
149+
.op_code(IF_ID_inst[6:0]),
150+
.funct3(IF_ID_inst[14:12]),
151+
.funct7_5(IF_ID_inst[30]),
152+
.alu_op(alu_op),
153+
.pc_src(pc_src),
154+
.mem_to_reg(mem_to_reg),
155+
.reg_write(reg_write),
156+
.alu_src_b(alu_src),
157+
.branch(branch),
158+
.b_type(b_type),
159+
.mem_write(mem_write_),
160+
.auipc(auipc)
161+
);
162+
163+
ImmGen immgen (
164+
.inst(IF_ID_inst),
165+
.imm(imm)
166+
);
167+
168+
//--------------------EX--------------------//
169+
170+
Mux2x32 mux2x32_1 (
171+
.I0(ID_EX_data1),
172+
.I1(ID_EX_pc),
173+
.s(ID_EX_auipc),
174+
.o(alu_data1)
175+
);
176+
177+
Mux2x32 mux2x32_2 (
178+
.I0(ID_EX_data2),
179+
.I1(ID_EX_imm),
180+
.s(ID_EX_alu_src),
181+
.o(alu_data2)
182+
);
183+
184+
ALU alu (
185+
.a(alu_data1),
186+
.b(alu_data2),
187+
.alu_op(ID_EX_alu_op),
188+
.res(alu_result),
189+
.zero(alu_zero)
190+
);
191+
192+
//--------------------MEM--------------------//
193+
assign addr_out = EX_MEM_alu_result;
194+
assign data_out = EX_MEM_data2;
195+
assign mem_write = EX_MEM_mem_write;
196+
197+
assign jal_addr = EX_MEM_pc + EX_MEM_imm;
198+
assign jalr_addr = EX_MEM_alu_result;
199+
200+
MuxPC mux_pc (
201+
.I0(pc + 4),
202+
.I1(jalr_addr),
203+
.I2(jal_addr),
204+
.I3(jal_addr),
205+
.s(EX_MEM_pc_src),
206+
.branch(EX_MEM_branch),
207+
.b_type(EX_MEM_b_type),
208+
.alu_res(EX_MEM_alu_result),
209+
.o(pc_next)
210+
);
211+
212+
// assign pc_next = pc + 4;
213+
214+
//--------------------WB--------------------//
215+
216+
Mux4x32 mux4x32 (
217+
.I0(MEM_WB_alu_result),
218+
.I1(MEM_WB_imm),
219+
.I2(MEM_WB_pc + 4),
220+
.I3(MEM_WB_data_in),
221+
.s(MEM_WB_mem_to_reg),
222+
.o(write_data)
223+
);
224+
225+
226+
endmodule

src/Core.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ module Core (
1818

1919
assign rst = ~aresetn;
2020

21-
SCPU cpu(
21+
CPU cpu(
2222
.clk(cpu_clk),
2323
.rst(rst),
2424
.inst(inst),

src/CoreSim.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ module CoreSim;
1212

1313
initial begin
1414
$dumpvars(0, CoreSim);
15-
#220 $finish;
15+
#320 $finish;
1616
end
1717

1818
initial begin

src/SCPU.v

Lines changed: 0 additions & 54 deletions
This file was deleted.

src/components/Control.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ module Control (
6767
end
6868
7'b1100111: begin // jalr
6969
pc_src = 2'b01; reg_write = 1; mem_to_reg = 2'b10;
70-
alu_src_b = 1; alu_op = ADD;
70+
alu_src_b = 1;
7171
end
7272
endcase
7373
end

src/memory/ROM.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module ROM (
77
reg [31:0] rom [0:2047];
88

99
initial begin
10-
$readmemh("tests/full.hex", rom);
10+
$readmemh("tests/PipelineStall/test.hex", rom);
1111
end
1212

1313
assign out = rom[address];

src/tests/PipelineStall/add.asm

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
part1:
2+
addi x1, x0, 0
3+
addi x2, x0, -1
4+
addi x3, x0, 1
5+
addi x4, x0, -1
6+
addi x5, x0, 1
7+
addi x6, x0, -1
8+
addi x1, x1, 0
9+
addi x2, x2, 1
10+
addi x3, x3, -1
11+
addi x4, x4, 1
12+
addi x5, x5, -1
13+
addi x6, x6, 1
14+
15+
gap:
16+
nop
17+
nop
18+
nop
19+
nop
20+
nop
21+
22+
part2:
23+
addi x1, x0, 1
24+
nop
25+
nop
26+
nop
27+
nop
28+
addi x2, x1, 2
29+
nop
30+
nop
31+
nop
32+
nop
33+
addi x3, x2, 3
34+
nop
35+
nop
36+
nop
37+
nop
38+
addi x4, x3, 4

0 commit comments

Comments
 (0)