From 4b68fa8a6408280116a11a7f6737288a57e2ad8b Mon Sep 17 00:00:00 2001 From: xwashere Date: Fri, 29 Dec 2023 13:45:02 -0500 Subject: [PATCH] all hart shit except doing things --- README.MD | 2 +- board/parts/hart.sv | 120 ++++++++++++++++++++++++++++++++++++++++++-- board/parts/pmmu.sv | 17 +++---- board/parts/rom.sv | 28 ++++------- board/system.sv | 6 +-- makefile | 15 +++++- os/kernel/boot.s | 37 ++++++++++++++ 7 files changed, 187 insertions(+), 38 deletions(-) create mode 100644 os/kernel/boot.s diff --git a/README.MD b/README.MD index 8f89d41..23b0298 100644 --- a/README.MD +++ b/README.MD @@ -1,3 +1,3 @@ ## Dependencies - verilator -- clang++ \ No newline at end of file +- clang (with risc-v support) \ No newline at end of file diff --git a/board/parts/hart.sv b/board/parts/hart.sv index ee9839e..431a597 100644 --- a/board/parts/hart.sv +++ b/board/parts/hart.sv @@ -1,3 +1,44 @@ +`define INS_LUI 7'b0110111 +`define INS_AUIPC 7'b0010111 +`define INS_JAL 7'b1101111 +`define INS_JALR 7'b1100111 +`define INS_BRANCH 7'b1100011 +`define INS_LOAD 7'b0000011 +`define INS_STORE 7'b0100011 +`define INS_IMMOP 7'b0010011 +`define INS_REGOP 7'b0110011 +`define INS_FENCE 7'b0001111 +`define INS_ENVOP 7'b1110011 + +`define INS_BRANCH_EQ 3'b000 +`define INS_BRANCH_NE 3'b001 +`define INS_BRANCH_LT 3'b100 +`define INS_BRANCH_GE 3'b101 +`define INS_BRANCH_LTU 3'b110 +`define INS_BRANCH_GEU 3'b111 + +`define INS_LOAD_8 3'b000 +`define INS_LOAD_16 3'b001 +`define INS_LOAD_32 3'b010 +`define INS_LOAD_U8 3'b100 +`define INS_LOAD_U16 3'b101 + +`define INS_STORE_8 3'b000 +`define INS_STORE_16 3'b001 +`define INS_STORE_32 3'b010 + +`define INS_ALUOP_ADD 3'b000 +`define INS_ALUOP_SLT 3'b010 +`define INS_ALUOP_SLTU 3'b011 +`define INS_ALUOP_XOR 3'b100 +`define INS_ALUOP_OR 3'b110 +`define INS_ALUOP_AND 3'b111 +`define INS_ALUOP_SLL 3'b001 +`define INS_ALUOP_SRL 3'b101 + +`define INS_ENVOP_CALL 12'b000000000000 +`define INS_ENVOP_BREAK 12'b000000000001 + // RISC-V CPU Hart module hart( clk, @@ -14,8 +55,33 @@ module hart( output reg [31:0] pmmu_dataw; reg [31:0] reg_pc = 0; + reg [31:0] reg_int [31:0]; - reg [31:0] t_ins = 0; // + // FETCH DATA + reg [31:0] t_ins = 0; // temp for being processed instruction + + // DECODE DATA + reg [6:0] t_d_op; + reg [4:0] t_d_rd; + reg [2:0] t_d_f3; + reg [4:0] t_d_r1; + reg [4:0] t_d_r2; + reg [6:0] t_d_f7; + reg [31:0] t_d_immi; + reg [31:0] t_d_imms; + reg [31:0] t_d_immb; + reg [31:0] t_d_immu; + reg [31:0] t_d_immj; + reg [31:0] t_d_imm; + + // GET REGISTERS + reg [31:0] t_r_a; + reg [31:0] t_r_b; + + // EXECUTE INSTRUCTION + reg [31:0] t_e_result; + reg t_e_branch; + reg [31:0] t_e_address; always begin // instruction fetch @@ -30,12 +96,53 @@ module hart( $display("== INSTRUCTION DECODE (0x%08h) ==", pmmu_datar); t_ins = pmmu_datar; pmmu_addr = 0; - pmmu_rd = 1; + pmmu_rd = 0; - // get shit + t_d_op = t_ins[6:0]; + t_d_rd = t_ins[11:7]; + t_d_f3 = t_ins[14:12]; + t_d_r1 = t_ins[19:15]; + t_d_r2 = t_ins[24:20]; + t_d_f7 = t_ins[31:25]; + + t_d_immi = {{21{t_ins[31]}}, t_ins[30:20] }; + t_d_imms = {{21{t_ins[31]}}, t_ins[30:25], t_ins[11:7] }; + t_d_immb = {{20{t_ins[31]}}, t_ins[7], t_ins[30:25], t_ins[11:8], 1'b0 }; + t_d_immu = { t_ins[31:12], 12'b0 }; + t_d_immj = {{12{t_ins[31]}}, t_ins[19:12], t_ins[20], t_ins[30:21], 1'b0 }; + + case (t_d_op) + `INS_JALR, + `INS_LOAD, + `INS_IMMOP: t_d_imm = t_d_immi; + + `INS_JAL: t_d_imm = t_d_immj; + + `INS_STORE: t_d_imm = t_d_imms; + + `INS_BRANCH: t_d_imm = t_d_immb; + + `INS_LUI, + `INS_AUIPC: t_d_imm = t_d_immu; + + `INS_ENVOP, + `INS_FENCE, + `INS_REGOP: t_d_imm = 0; + + default: $error("INVALID INSTRUCTION"); + endcase + + $display("INS: %7b %3b %7b %d %d -> %d", t_d_op, t_d_f3, t_d_f7, t_d_r1, t_d_r2, t_d_rd); + $display("IMM: U[%d] S[%d]", t_d_imm, $signed(t_d_imm)); + + // get registers @(posedge clk); $display("== GET REGISTERS =="); + t_r_a = reg_int[t_d_r1]; + t_r_b = reg_int[t_d_r2]; + $display("REG: %d[%d] %d[%d]", t_d_r1, t_r_a, t_d_r2, t_r_b); + // execute @(posedge clk); $display("== EXECUTE =="); @@ -44,6 +151,13 @@ module hart( @(posedge clk); $display("== WRITE REGISTERS =="); + case (t_d_op) + `INS_BRANCH, `INS_STORE, `INS_FENCE, `INS_ENVOP: begin + if (t_d_rd != 0) reg_int[t_d_rd] = t_e_result; + end + default:; + endcase + // finish up reg_pc += 4; end diff --git a/board/parts/pmmu.sv b/board/parts/pmmu.sv index b0ccba2..14378ca 100644 --- a/board/parts/pmmu.sv +++ b/board/parts/pmmu.sv @@ -1,10 +1,11 @@ +// System physical memory management unit, addresses are dword aligned module pmmu( clk, rd, wr, addr, datar, dataw, - rom_rd, rom_wr, - rom_addr, rom_datar, rom_dataw + rom_rd, + rom_addr, rom_datar ); // INPUT SHIT input clk; @@ -16,22 +17,16 @@ module pmmu( // ROM output reg rom_rd; - output reg rom_wr; output reg [31:0] rom_addr; - output reg [31:0] rom_dataw; input reg [31:0] rom_datar; always @(posedge clk) begin rom_rd = 0; - rom_wr = 0; - if ((addr == 0 || addr > 0) && addr < 'h10000) begin - rom_addr = addr; - rom_wr = wr; + if ((addr == 0 || addr > 0) && addr < 'h100) begin + rom_addr = addr >> 2; rom_rd = rd; - if (wr) rom_dataw = dataw; - - #1; + #1; // wait for it to finish if (rd) datar = rom_datar; end else begin $error("THIS IS BAD"); diff --git a/board/parts/rom.sv b/board/parts/rom.sv index ab847fb..a74c63a 100644 --- a/board/parts/rom.sv +++ b/board/parts/rom.sv @@ -1,30 +1,24 @@ // RISC-V Read only memory -module rom(clk, rd, wr, addr, datar, dataw); +module rom(clk, rd, addr, datar); input clk; input reg rd; - input reg wr; // wait why the fuck did i add a write pin input reg [31:0] addr; output reg [31:0] datar; - input reg [31:0] dataw; + + parameter SIZE = 'h100; + parameter FILE = ""; + + reg [31:0] data [0 : SIZE - 1]; always @(posedge clk) begin if (rd) begin - case (addr >> 2) - 0: datar = 0; - 1: datar = 1; - 2: datar = 2; - 3: datar = 3; - 4: datar = 4; - 5: datar = 5; - 6: datar = 6; - 7: datar = 7; - 8: datar = 8; - 9: datar = 9; - 10: datar = 10; - default: $error("INVALID MEMORY ACCESS"); - endcase + datar = data[addr]; end else begin datar = 0; end end + + initial begin + $readmemh(FILE, data, 0, SIZE - 1); + end endmodule \ No newline at end of file diff --git a/board/system.sv b/board/system.sv index 38f13a0..2bd7d08 100644 --- a/board/system.sv +++ b/board/system.sv @@ -11,16 +11,14 @@ module system(); reg [31:0] wire_datar; reg [31:0] wire_dataw; reg wire_rom_rd; - reg wire_rom_wr; reg [31:0] wire_rom_addr; reg [31:0] wire_rom_datar; - reg [31:0] wire_rom_dataw; hart core(clock, wire_rd, wire_wr, wire_addr, wire_datar, wire_dataw); // cpu thing - rom rom(clock, wire_rom_rd, wire_rom_wr, wire_rom_addr, wire_rom_datar, wire_rom_dataw); - pmmu pmmu(clock, wire_rd, wire_wr, wire_addr, wire_datar, wire_dataw, wire_rom_rd, wire_rom_wr, wire_rom_addr, wire_rom_datar, wire_rom_dataw); + rom#(.FILE("./build/kernel.mem")) rom(clock, wire_rom_rd, wire_rom_addr, wire_rom_datar); + pmmu pmmu(clock, wire_rd, wire_wr, wire_addr, wire_datar, wire_dataw, wire_rom_rd, wire_rom_addr, wire_rom_datar); // run the clock always #5 clock = ~clock; diff --git a/makefile b/makefile index a33b02b..ea7a953 100644 --- a/makefile +++ b/makefile @@ -11,10 +11,21 @@ VERILOG_SOURCES = \ KERNEL_SOURCES = \ os/kernel/boot.s -build/cpu: ${VERILOG_SOURCES} +.PHONY: build + +build: build/cpu build/kernel.mem + +build/cpu: ${VERILOG_SOURCES} mkdir -p build/verilog ${VERILATOR} --build --binary board/system.sv -Mdir build/verilog +incdir+board cp -f build/verilog/Vsystem build/cpu +build/kernel.mem: build/kernel + hexdump build/kernel -e '1/4 "%x "' > build/kernel.mem + build/kernel: ${KERNEL_SOURCES} - clang ${KERNEL_SOURCES} -o build/kernel \ No newline at end of file + clang ${KERNEL_SOURCES} -o build/kernel \ + --target=riscv64 \ + -nostdlib \ + -march=rv64i \ + -Xlinker --oformat=binary \ No newline at end of file diff --git a/os/kernel/boot.s b/os/kernel/boot.s new file mode 100644 index 0000000..a2658b1 --- /dev/null +++ b/os/kernel/boot.s @@ -0,0 +1,37 @@ +_start: + li x5, 120 + li x0, 1 + li x5, 214 + li x18, -121 + li x31, -130 + li x1, 0 + li x2, 0 + li x3, 0 + li x4, 0 + li x5, 0 + li x6, 0 + li x7, 0 + li x8, 0 + li x9, 0 + li x10, 0 + li x11, 0 + li x12, 0 + li x13, 0 + li x14, 0 + li x15, 0 + li x16, 0 + li x17, 0 + li x18, 0 + li x19, 0 + li x20, 0 + li x21, 0 + li x22, 0 + li x23, 0 + li x24, 0 + li x25, 0 + li x26, 0 + li x27, 0 + li x28, 0 + li x29, 0 + li x30, 0 + li x31, 0 \ No newline at end of file