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

Commit

Permalink
feat: Final RV64 CPU with MMU and kernel
Browse files Browse the repository at this point in the history
  • Loading branch information
TonyCrane committed Jul 6, 2023
1 parent b77d285 commit b525b1d
Show file tree
Hide file tree
Showing 85 changed files with 24,762 additions and 706 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
.DS_Store

src/core.vvp
src/dump.vcd
src/dump.vcd

src/dut_changes.txt
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
## 实验进度

系统贯通课程会逐步实现一个 RISC-V 五级流水线 CPU,并实现异常处理、分支预测、Cache 等功能。本 repo 通过分支、tag 等来记录实验进度,保存各阶段成果。
系统贯通课程会逐步实现一个 RISC-V 五级流水线 CPU,并实现异常处理、分支预测、Cache、MMU 等功能,并在其上运行自己编写的简易 kernel。

本 repo 通过分支、tag 等来记录实验进度,保存各阶段成果。

- [x] 系统 Ⅰ lab5-1/lab5-2:单周期 CPU
- [x] extra:单周期 CPU with 特权指令/异常处理
Expand All @@ -18,6 +20,12 @@
- 使用了提供的实验框架而非自己的,就不放在 repo 里了
- [x] 系统 Ⅲ lab2:流水线 CPU with Cache
- 使用了提供的实验框架而非自己的,就不放在 repo 里了
- [x] 系统 Ⅲ lab Xpart:软硬件贯通实验,主要部分是实现 MMU 以及调试 kernel
- RV64IZicsr 全部指令(除去 fence ebreak wfi)
- 包含 Supervisor 和 User 两个特权级
- 实现了 Bare 和 Sv39 两种分页模式
- 支持串口输出
- 展示 slides 在:[slides.tonycrane.cc/sys3-xpart-pre](https://slides.tonycrane.cc/sys3-xpart-pre/)

## 实验环境

Expand Down
396 changes: 158 additions & 238 deletions src/CPU.v

Large diffs are not rendered by default.

51 changes: 32 additions & 19 deletions src/Core.v
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,25 @@ module Core (
input wire step,
input wire debug_mode,
input wire [4:0] debug_reg_addr, // register address
output wire [31:0] chip_debug_out0,
output wire [31:0] chip_debug_out1,
output wire [31:0] chip_debug_out2,
output wire [31:0] chip_debug_out3
output wire [63:0] chip_debug_out0,
output wire [63:0] chip_debug_out1,
output wire [63:0] chip_debug_out2,
output wire [63:0] chip_debug_out3,
output wire [7:0] sim_uart_char_out,
output wire sim_uart_char_valid
);
wire rst, mem_write, mem_clk, cpu_clk;
wire [31:0] inst, core_data_in, addr_out, core_data_out, pc_out;
wire [31:0] inst;
wire [63:0] core_data_in, addr_out, core_data_out, pc_out;
reg [31:0] clk_div;
wire [31:0] debug_reg;
wire [63:0] debug_reg;
wire [63:0] satp;
wire stall, mem_read;
wire [2:0] width;

assign rst = ~aresetn;

CPU cpu(
CPU cpu (
.clk(cpu_clk),
.rst(rst),
.inst(inst),
Expand All @@ -27,8 +33,12 @@ module Core (
.data_out(core_data_out), // data to data memory
.pc_out(pc_out), // connect to instruction memory
.mem_write(mem_write),
.mem_read(mem_read),
.debug_reg_addr(debug_reg_addr),
.debug_reg(debug_reg)
.debug_reg(debug_reg),
.satp(satp),
.data_width(width),
.stall(stall)
);

always @(posedge clk) begin
Expand All @@ -38,21 +48,24 @@ module Core (
assign mem_clk = ~clk_div[0];
assign cpu_clk = debug_mode ? clk_div[0] : step;

ROM rom_unit (
.address(pc_out / 4),
.out(inst)
);

RAM ram_unit (
.clk(mem_clk),
.we(mem_write),
.address(addr_out / 4),
MMU mmu (
.clk(mem_clk), .rst(rst),
.inst_addr(pc_out),
.data_addr(addr_out),
.write_data(core_data_out),
.read_data(core_data_in)
.mem_write(mem_write),
.mem_read(mem_read),
.width(width),
.satp(satp),
.inst_out(inst),
.read_data(core_data_in),
.stall_pipeline(stall),
.sim_uart_char_out(sim_uart_char_out),
.sim_uart_char_valid(sim_uart_char_valid)
);

assign chip_debug_out0 = pc_out;
assign chip_debug_out1 = addr_out;
assign chip_debug_out2 = inst;
assign chip_debug_out2 = {32'b0, inst};
assign chip_debug_out3 = debug_reg;
endmodule
15 changes: 10 additions & 5 deletions src/CoreSim.v
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,28 @@

module CoreSim;
reg clk, rst;
Core core(
Core core (
.clk(clk),
.aresetn(~rst),
.step(1'b0),
.debug_mode(1'b1),
.debug_reg_addr(5'b0)
);

initial begin
$dumpvars(0, CoreSim);
#700000 $finish;
end
// initial begin
// $dumpvars(0, CoreSim);
// // #700000 $finish;
// // #2000 $finish;
// // #1000000000 $finish;
// end

initial begin
clk = 0;
rst = 1;
#2 rst = 0;
end
always #1 clk = ~clk;
// always #5000000 begin
// $display("pc: %h", core.cpu.MEM_WB_pc);
// end
endmodule
35 changes: 35 additions & 0 deletions src/MMUSim.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
`timescale 1ns / 1ps

module MMUSim;
reg clk, rst;
wire [31:0] inst_out;
wire [63:0] read_data;
wire stall_pipeline;

MMU mmu (
.clk(clk), .rst(rst),
.inst_addr(64'hffffffe000200000),
.data_addr(64'hffffffe00020b000),
// .data_addr(64'h800),
.write_data(64'h0000000000000000),
.mem_write(1'b0),
.mem_read(1'b1),
.width(3'b011),
.satp(64'h8000000000080202),
.inst_out(inst_out),
.read_data(read_data),
.stall_pipeline(stall_pipeline)
);

initial begin
$dumpvars(0, MMUSim);
#200 $finish;
end

initial begin
clk = 0;
rst = 1;
#2 rst = 0;
end
always #1 clk = ~clk;
endmodule
16 changes: 15 additions & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,27 @@ all: compile simulate

compile:
iverilog -o core.vvp -y . \
-y components -y memory -y utils \
-y components -y utils \
-I headers \
CoreSim.v

simulate:
vvp -n core.vvp

open:
$(GTKWAVE) dump.vcd wave.gtkw

mmu: compile-mmu simulate-mmu

compile-mmu:
iverilog -o core.vvp -y . \
-y components -y utils \
-I headers \
MMUSim.v

simulate-mmu:
vvp -n core.vvp
$(GTKWAVE) dump.vcd wave_mmu.gtkw

clean:
rm -f core.vvp dump.vcd
56 changes: 44 additions & 12 deletions src/Top.sv
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,44 @@ module Top(
output [ 2:0] rgb1,
output [ 2:0] rgb2,
output [ 7:0] num_csn,
output [ 7:0] num_an
output [ 7:0] num_an,
output UART_TXD
);
logic aresetn;
logic step;

logic [31:0] chip_debug_out0;
logic [31:0] chip_debug_out1;
logic [31:0] chip_debug_out2;
logic [31:0] chip_debug_out3;
logic [63:0] chip_debug_out0;
logic [63:0] chip_debug_out1;
logic [63:0] chip_debug_out2;
logic [63:0] chip_debug_out3;

logic [7:0] uart_data, sim_uart_char;
logic uart_send, uart_ready, sim_uart_char_valid;
logic [31:0] clk_div;
logic clk_cpu;

always @(posedge clk) begin
if (!resetn) clk_div <= 0;
else clk_div <= clk_div + 1;
end
assign clk_cpu = clk_div[3];

Core chip_inst(
.clk(clk),
.clk(clk_cpu),
.aresetn(aresetn),
.step(step),
.debug_mode(switch[15]),
.debug_reg_addr(switch[11:7]),
.chip_debug_out0(chip_debug_out0),
.chip_debug_out1(chip_debug_out1),
.chip_debug_out2(chip_debug_out2),
.chip_debug_out3(chip_debug_out3)
.chip_debug_out3(chip_debug_out3),
.sim_uart_char_out(sim_uart_char),
.sim_uart_char_valid(sim_uart_char_valid),
);

IO_Manager io_manager_inst(
.clk(clk),
.clk(clk_cpu),
.resetn(resetn),

// to chip
Expand All @@ -54,9 +68,27 @@ module Top(
.debug1({16'b0, switch[15:0]}),
.debug2({12'b0, 3'b0, button[4], 3'b0, button[3], 3'b0, button[2], 3'b0, button[1], 3'b0, button[0]}),
.debug3(32'h12345678),
.debug4(chip_debug_out0),
.debug5(chip_debug_out1),
.debug6(chip_debug_out2),
.debug7(chip_debug_out3)
.debug4(chip_debug_out0[31:0]),
.debug5(chip_debug_out1[31:0]),
.debug6(chip_debug_out2[31:0]),
.debug7(chip_debug_out3[31:0])
);

UART_TX_CTRL uart_tx_ctrl (
.SEND(uart_send),
.DATA(uart_data),
.CLK(clk),
.READY(uart_ready),
.UART_TX(UART_TXD)
);

uart_buffer UART_BUFF (
.clk(clk_cpu),
.rst(~aresetn),
.ready(uart_ready),
.sim_uart_char_valid(sim_uart_char_valid),
.sim_uart_char(sim_uart_char),
.send(uart_send),
.datao(uart_data)
);
endmodule
File renamed without changes.
Loading

0 comments on commit b525b1d

Please sign in to comment.