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

Commit f4ca771

Browse files
committed
feat: pipeline CPU with priviledged ISA
1 parent 56e108c commit f4ca771

File tree

15 files changed

+1383
-75
lines changed

15 files changed

+1383
-75
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
- [x] extra:单周期 CPU with 特权指令/异常处理
1313
- [x] 系统 Ⅱ lab1:流水线 CPU (stall)
1414
- [x] 系统 Ⅱ lab2:流水线 CPU (forwarding)
15-
- [ ] 系统 Ⅱ lab7:流水线 CPU with 特权指令/异常处理
15+
- [x] 系统 Ⅱ lab7:流水线 CPU with 特权指令/异常处理
1616
- [ ] 系统 Ⅲ lab1:流水线 CPU with 动态分支预测
1717
- [ ] 系统 Ⅲ lab2:流水线 CPU with Cache
1818

src/CPU.v

Lines changed: 129 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,28 @@ module CPU(
1919
reg [31:0] IF_ID_inst;
2020

2121
wire [31:0] read_data1, read_data2, imm;
22+
wire [31:0] csr_read_data, csr_ret_pc;
23+
wire [11:0] csr_read_addr, csr_write_addr;
2224
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+
wire [2:0] mem_to_reg;
26+
wire [1:0] pc_src, trap;
27+
wire alu_src;
28+
wire reg_write, branch, b_type, auipc, mem_write_;
2529
wire mem_read, bubble_stop, jump;
30+
wire csr_write, csr_write_src, rev_imm;
2631
reg [31:0] ID_EX_data1, ID_EX_data2;
2732
reg [31:0] ID_EX_pc, ID_EX_imm;
2833
reg [4:0] ID_EX_rs1, ID_EX_rs2;
2934
reg [4:0] ID_EX_write_addr;
3035
reg [3:0] ID_EX_alu_op;
31-
reg [1:0] ID_EX_pc_src, ID_EX_mem_to_reg;
32-
reg ID_EX_reg_write, ID_EX_alu_src, ID_EX_branch, ID_EX_b_type, ID_EX_auipc, ID_EX_mem_write;
36+
reg [2:0] ID_EX_mem_to_reg;
37+
reg [1:0] ID_EX_pc_src;
38+
reg ID_EX_alu_src;
39+
reg ID_EX_reg_write, ID_EX_branch, ID_EX_b_type, ID_EX_auipc, ID_EX_mem_write;
3340
reg ID_EX_mem_read;
41+
reg [11:0] ID_EX_csr_write_addr;
42+
reg ID_EX_csr_write, ID_EX_csr_write_src, ID_EX_rev_imm;
43+
reg [31:0] ID_EX_csr_write_data, ID_EX_csr_read_data;
3444

3545
wire [31:0] alu_data1, alu_data2, alu_result;
3646
wire alu_zero;
@@ -40,15 +50,22 @@ module CPU(
4050
reg [31:0] EX_MEM_alu_result, EX_MEM_pc, EX_MEM_imm;
4151
reg [31:0] EX_MEM_data2;
4252
reg [4:0] EX_MEM_write_addr;
43-
reg [1:0] EX_MEM_pc_src, EX_MEM_mem_to_reg;
53+
reg [2:0] EX_MEM_mem_to_reg;
54+
reg [1:0] EX_MEM_pc_src;
4455
reg EX_MEM_reg_write, EX_MEM_branch, EX_MEM_b_type, EX_MEM_mem_write;
56+
reg [11:0] EX_MEM_csr_write_addr;
57+
reg EX_MEM_csr_write, EX_MEM_csr_write_src, EX_MEM_rev_imm;
58+
reg [31:0] EX_MEM_csr_write_data, EX_MEM_csr_read_data;
4559

4660
wire [31:0] write_data;
4761
wire [31:0] jal_addr, jalr_addr;
4862
reg [31:0] MEM_WB_data_in, MEM_WB_alu_result, MEM_WB_pc, MEM_WB_imm;
4963
reg [4:0] MEM_WB_write_addr;
50-
reg [1:0] MEM_WB_mem_to_reg;
64+
reg [2:0] MEM_WB_mem_to_reg;
5165
reg MEM_WB_reg_write;
66+
reg [11:0] MEM_WB_csr_write_addr;
67+
reg MEM_WB_csr_write, MEM_WB_csr_write_src, MEM_WB_rev_imm;
68+
reg [31:0] MEM_WB_csr_write_data, MEM_WB_csr_read_data;
5269

5370

5471
assign pc_out = pc;
@@ -65,7 +82,7 @@ module CPU(
6582
ID_EX_write_addr <= 5'b0;
6683
ID_EX_alu_op <= 4'b0;
6784
ID_EX_pc_src <= 2'b0;
68-
ID_EX_mem_to_reg <= 2'b0;
85+
ID_EX_mem_to_reg <= 3'b0;
6986
ID_EX_reg_write <= 1'b0;
7087
ID_EX_alu_src <= 1'b0;
7188
ID_EX_branch <= 1'b0;
@@ -75,38 +92,61 @@ module CPU(
7592
ID_EX_mem_read <= 1'b0;
7693
ID_EX_rs1 <= 5'b0;
7794
ID_EX_rs2 <= 5'b0;
95+
ID_EX_csr_write_addr <= 12'b0;
96+
ID_EX_csr_write <= 1'b0;
97+
ID_EX_csr_write_src <= 1'b0;
98+
ID_EX_rev_imm <= 1'b0;
99+
ID_EX_csr_write_data <= 32'b0;
100+
ID_EX_csr_read_data <= 32'b0;
101+
ID_EX_rev_imm <= 1'b0;
78102
EX_MEM_alu_result <= 32'b0;
79103
EX_MEM_pc <= 32'b0;
80104
EX_MEM_imm <= 32'b0;
81105
EX_MEM_data2 <= 32'b0;
82106
EX_MEM_write_addr <= 5'b0;
83107
EX_MEM_pc_src <= 2'b0;
84-
EX_MEM_mem_to_reg <= 2'b0;
108+
EX_MEM_mem_to_reg <= 3'b0;
85109
EX_MEM_reg_write <= 1'b0;
86110
EX_MEM_branch <= 1'b0;
87111
EX_MEM_b_type <= 1'b0;
88112
EX_MEM_mem_write <= 1'b0;
113+
EX_MEM_csr_write_addr <= 12'b0;
114+
EX_MEM_csr_write <= 1'b0;
115+
EX_MEM_csr_write_src <= 1'b0;
116+
EX_MEM_rev_imm <= 1'b0;
117+
EX_MEM_csr_write_data <= 32'b0;
118+
EX_MEM_csr_read_data <= 32'b0;
89119
MEM_WB_data_in <= 32'b0;
90120
MEM_WB_alu_result <= 32'b0;
91121
MEM_WB_pc <= 32'b0;
92122
MEM_WB_imm <= 32'b0;
93123
MEM_WB_write_addr <= 5'b0;
94-
MEM_WB_mem_to_reg <= 2'b0;
124+
MEM_WB_mem_to_reg <= 3'b0;
95125
MEM_WB_reg_write <= 1'b0;
126+
MEM_WB_csr_write_addr <= 12'b0;
127+
MEM_WB_csr_write <= 1'b0;
128+
MEM_WB_csr_write_src <= 1'b0;
129+
MEM_WB_rev_imm <= 1'b0;
130+
MEM_WB_csr_write_data <= 32'b0;
131+
MEM_WB_csr_read_data <= 32'b0;
96132
end
97133
else begin
98134
if (bubble_stop) begin
99135
ID_EX_alu_op <= 4'b0;
100136
ID_EX_pc_src <= 2'b0;
101-
ID_EX_mem_to_reg <= 2'b0;
137+
ID_EX_mem_to_reg <= 3'b0;
102138
ID_EX_reg_write <= 1'b0;
103139
ID_EX_alu_src <= 1'b0;
104140
ID_EX_branch <= 1'b0;
105141
ID_EX_b_type <= 1'b0;
106142
ID_EX_auipc <= 1'b0;
107143
ID_EX_mem_write <= 1'b0;
108144
ID_EX_mem_read <= 1'b0;
109-
end else if (jump) begin
145+
ID_EX_csr_write_addr <= 12'b0;
146+
ID_EX_csr_write <= 1'b0;
147+
ID_EX_csr_write_src <= 1'b0;
148+
ID_EX_rev_imm <= 1'b0;
149+
end else if (jump || trap != 2'b0) begin
110150
pc <= pc_next;
111151

112152
IF_ID_pc <= pc;
@@ -122,6 +162,10 @@ module CPU(
122162
ID_EX_alu_op <= alu_op;
123163
ID_EX_mem_write <= mem_write_;
124164
ID_EX_mem_read <= mem_read;
165+
ID_EX_csr_write_addr <= csr_write_addr;
166+
ID_EX_csr_write <= csr_write;
167+
ID_EX_csr_write_src <= csr_write_src;
168+
ID_EX_rev_imm <= rev_imm;
125169
end else begin
126170
pc <= pc_next;
127171

@@ -138,6 +182,10 @@ module CPU(
138182
ID_EX_alu_op <= alu_op;
139183
ID_EX_mem_write <= mem_write_;
140184
ID_EX_mem_read <= mem_read;
185+
ID_EX_csr_write_addr <= csr_write_addr;
186+
ID_EX_csr_write <= csr_write;
187+
ID_EX_csr_write_src <= csr_write_src;
188+
ID_EX_rev_imm <= rev_imm;
141189
end
142190

143191
ID_EX_pc <= IF_ID_pc;
@@ -147,6 +195,8 @@ module CPU(
147195
ID_EX_write_addr <= IF_ID_inst[11:7];
148196
ID_EX_rs1 <= IF_ID_inst[19:15];
149197
ID_EX_rs2 <= IF_ID_inst[24:20];
198+
ID_EX_csr_write_data <= read_data1;
199+
ID_EX_csr_read_data <= csr_read_data;
150200

151201
EX_MEM_pc <= ID_EX_pc;
152202
EX_MEM_imm <= ID_EX_imm;
@@ -159,6 +209,12 @@ module CPU(
159209
EX_MEM_branch <= ID_EX_branch;
160210
EX_MEM_b_type <= ID_EX_b_type;
161211
EX_MEM_mem_write <= ID_EX_mem_write;
212+
EX_MEM_csr_write_addr <= ID_EX_csr_write_addr;
213+
EX_MEM_csr_write <= ID_EX_csr_write;
214+
EX_MEM_csr_write_src <= ID_EX_csr_write_src;
215+
EX_MEM_rev_imm <= ID_EX_rev_imm;
216+
EX_MEM_csr_write_data <= alu_data1;
217+
EX_MEM_csr_read_data <= ID_EX_csr_read_data;
162218

163219
MEM_WB_data_in <= data_in;
164220
MEM_WB_alu_result <= EX_MEM_alu_result;
@@ -167,6 +223,12 @@ module CPU(
167223
MEM_WB_write_addr <= EX_MEM_write_addr;
168224
MEM_WB_mem_to_reg <= EX_MEM_mem_to_reg;
169225
MEM_WB_reg_write <= EX_MEM_reg_write;
226+
MEM_WB_csr_write_addr <= EX_MEM_csr_write_addr;
227+
MEM_WB_csr_write <= EX_MEM_csr_write;
228+
MEM_WB_csr_write_src <= EX_MEM_csr_write_src;
229+
MEM_WB_rev_imm <= EX_MEM_rev_imm;
230+
MEM_WB_csr_write_data <= EX_MEM_csr_write_data;
231+
MEM_WB_csr_read_data <= EX_MEM_csr_read_data;
170232

171233
end
172234
end
@@ -185,15 +247,15 @@ module CPU(
185247

186248
assign jal_addr = IF_ID_pc + imm;
187249
wire [31:0] reg1, reg2;
188-
assign reg1 = (jump && EX_MEM_reg_write && (EX_MEM_write_addr != 0) && (EX_MEM_write_addr == IF_ID_inst[19:15])) ? EX_MEM_alu_result : read_data1;
189-
assign reg2 = (jump && EX_MEM_reg_write && (EX_MEM_write_addr != 0) && (EX_MEM_write_addr == IF_ID_inst[24:20])) ? EX_MEM_alu_result : read_data2;
250+
assign reg1 = (jump && EX_MEM_reg_write && (EX_MEM_write_addr != 0) && (EX_MEM_write_addr == IF_ID_inst[19:15])) ? (EX_MEM_mem_to_reg == 2'b11 ? data_in : EX_MEM_alu_result) : read_data1;
251+
assign reg2 = (jump && EX_MEM_reg_write && (EX_MEM_write_addr != 0) && (EX_MEM_write_addr == IF_ID_inst[24:20])) ? (EX_MEM_mem_to_reg == 2'b11 ? data_in : EX_MEM_alu_result) : read_data2;
190252
assign jalr_addr = reg1 + reg2;
191253

192254
MuxPC mux_pc (
193255
.I0(jump ? pc : pc + 4),
194256
.I1(jalr_addr),
195257
.I2(jal_addr),
196-
.I3(jal_addr),
258+
.I3(csr_ret_pc),
197259
.s(pc_src),
198260
.branch(branch),
199261
.b_type(b_type),
@@ -215,21 +277,53 @@ module CPU(
215277
.debug_reg(debug_reg)
216278
);
217279

280+
CSRs csrs (
281+
.clk(clk),
282+
.rst(rst),
283+
.we(MEM_WB_csr_write),
284+
.trap(trap),
285+
.pc(IF_ID_pc),
286+
.csr_read_addr(csr_read_addr),
287+
.csr_write_addr(MEM_WB_csr_write_addr),
288+
.csr_write_data(MEM_WB_csr_write_data),
289+
.csr_read_data(csr_read_data)
290+
);
291+
292+
MretForwarding mretforwarding (
293+
.ID_EX_csr_write(ID_EX_csr_write),
294+
.ID_EX_csr_write_addr(ID_EX_csr_write_addr),
295+
// .ID_EX_csr_write_data(ID_EX_csr_write_data),
296+
// .EX_MEM_csr_write(EX_MEM_csr_write),
297+
// .EX_MEM_csr_write_addr(EX_MEM_csr_write_addr),
298+
// .EX_MEM_csr_write_data(EX_MEM_csr_write_data),
299+
.EX_MEM_alu_result(EX_MEM_alu_result),
300+
.csr_read_data(csr_read_data),
301+
.trap(trap),
302+
.csr_ret_pc(csr_ret_pc)
303+
);
304+
218305
Control control (
219306
.op_code(IF_ID_inst[6:0]),
220307
.funct3(IF_ID_inst[14:12]),
221308
.funct7_5(IF_ID_inst[30]),
222-
.alu_op(alu_op),
309+
.csr(IF_ID_inst[31:20]),
223310
.pc_src(pc_src),
224-
.mem_to_reg(mem_to_reg),
225311
.reg_write(reg_write),
226312
.alu_src_b(alu_src),
313+
.alu_op(alu_op),
314+
.mem_to_reg(mem_to_reg),
315+
.mem_write(mem_write_),
227316
.branch(branch),
228317
.b_type(b_type),
229-
.mem_write(mem_write_),
230318
.auipc(auipc),
231319
.mem_read(mem_read),
232-
.jump(jump)
320+
.jump(jump),
321+
.trap(trap),
322+
.csr_read_addr(csr_read_addr),
323+
.csr_write_addr(csr_write_addr),
324+
.csr_write(csr_write),
325+
.csr_write_src(csr_write_src),
326+
.rev_imm(rev_imm)
233327
);
234328

235329
ImmGen immgen (
@@ -268,11 +362,14 @@ module CPU(
268362
.o(alu_data1)
269363
);
270364

365+
wire [31:0] alu_b_imm;
366+
assign alu_b_imm = (ID_EX_mem_to_reg == 3'b100 ? ID_EX_csr_read_data : ID_EX_imm);
367+
271368
Mux8x32 mux_alu_b (
272369
.I0(ID_EX_data2),
273370
.I1(EX_MEM_alu_result),
274371
.I2(write_data),
275-
.I3(ID_EX_imm),
372+
.I3(alu_b_imm),
276373
.I4(EX_MEM_pc + 4),
277374
.I5(MEM_WB_pc + 4),
278375
.I6(EX_MEM_imm),
@@ -305,11 +402,23 @@ module CPU(
305402

306403
//--------------------WB--------------------//
307404

308-
Mux4x32 mux4x32 (
405+
// Mux4x32 mux4x32 (
406+
// .I0(MEM_WB_alu_result),
407+
// .I1(MEM_WB_imm),
408+
// .I2(MEM_WB_pc + 4),
409+
// .I3(MEM_WB_data_in),
410+
// .s(MEM_WB_mem_to_reg),
411+
// .o(write_data)
412+
// );
413+
Mux8x32 mux8x32 (
309414
.I0(MEM_WB_alu_result),
310415
.I1(MEM_WB_imm),
311416
.I2(MEM_WB_pc + 4),
312417
.I3(MEM_WB_data_in),
418+
.I4(MEM_WB_csr_read_data),
419+
.I5(0),
420+
.I6(0),
421+
.I7(0),
313422
.s(MEM_WB_mem_to_reg),
314423
.o(write_data)
315424
);

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-
#1000 $finish;
15+
#700000 $finish;
1616
end
1717

1818
initial begin

src/components/CSRs.v

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
`timescale 1ns / 1ps
2+
3+
module CSRs (
4+
input clk,
5+
input rst,
6+
input we,
7+
input [1:0] trap, // 00 no trap, 01 ecall, 10 unimp, 11 mret
8+
input [31:0] pc,
9+
input [11:0] csr_read_addr,
10+
input [11:0] csr_write_addr,
11+
input [31:0] csr_write_data,
12+
output [31:0] csr_read_data
13+
);
14+
reg [31:0] mstatus, mepc, mtvec, mcause;
15+
16+
assign csr_read_data = (csr_read_addr == 12'h300) ? mstatus :
17+
(csr_read_addr == 12'h341) ? mepc :
18+
(csr_read_addr == 12'h305) ? mtvec :
19+
(csr_read_addr == 12'h342) ? mcause : 0;
20+
21+
always @(negedge clk or posedge rst) begin
22+
if (rst == 1) begin
23+
mstatus <= 0;
24+
mepc <= 0;
25+
mtvec <= 0;
26+
mcause <= 0;
27+
end
28+
else if (trap != 0) begin
29+
if (trap == 2'b01) begin
30+
mepc <= pc;
31+
mcause <= 11;
32+
end
33+
else if (trap == 2'b10) begin
34+
mepc <= pc;
35+
mcause <= 2;
36+
end
37+
end
38+
else if (we == 1) begin
39+
if (csr_write_addr == 12'h300) mstatus <= csr_write_data;
40+
else if (csr_write_addr == 12'h341) mepc <= csr_write_data;
41+
else if (csr_write_addr == 12'h305) mtvec <= csr_write_data;
42+
else if (csr_write_addr == 12'h342) mcause <= csr_write_data;
43+
end
44+
end
45+
endmodule

0 commit comments

Comments
 (0)