diff --git a/board/parts/hart.sv b/board/parts/hart.sv index ccf1477..862e74d 100644 --- a/board/parts/hart.sv +++ b/board/parts/hart.sv @@ -46,46 +46,47 @@ module hart( clk, - pmmu_rd, pmmu_wr, + pmmu_rd, pmmu_wr, pmmu_size, pmmu_addr, pmmu_datar, pmmu_dataw ); input clk; // the clock. pretty important. - output reg pmmu_rd; - output reg pmmu_wr; - output reg [31:0] pmmu_addr; - input reg [31:0] pmmu_datar; - output reg [31:0] pmmu_dataw; + output reg pmmu_rd; + output reg pmmu_wr; + output reg[1:0] pmmu_size; + output reg[31:0] pmmu_addr; + input reg[31:0] pmmu_datar; + output reg[31:0] pmmu_dataw; - reg [31:0] reg_pc = 0; - reg [31:0] reg_int [31:0]; + reg[31:0] reg_pc = 0; + reg[31:0] reg_int[31:0]; // FETCH DATA - reg [31:0] t_ins = 0; // temp for being processed instruction + 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; + 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; + 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; - reg [31:0] t_e_tmp1; + reg[31:0] t_e_result; + reg t_e_branch; + reg[31:0] t_e_address; + reg[31:0] t_e_tmp1; always begin // instruction fetch @@ -94,6 +95,7 @@ module hart( pmmu_addr = reg_pc; pmmu_rd = 1; + pmmu_size = 2; // instruction decode @(posedge clk); @@ -101,6 +103,7 @@ module hart( t_ins = pmmu_datar; pmmu_addr = 0; pmmu_rd = 0; + pmmu_size = 0; t_d_op = t_ins[6:0]; t_d_rd = t_ins[11:7]; @@ -208,9 +211,11 @@ module hart( t_e_address = t_d_imm + t_r_a; pmmu_addr = t_e_address; pmmu_rd = 1; + pmmu_size = 2; - #1; + #2; pmmu_rd = 0; + case (t_d_f3[1:0]) 0: t_e_result = (pmmu_datar >> (8 * (t_e_address & 3))) & 255; 1: begin @@ -232,28 +237,13 @@ module hart( endcase end { `INS_STORE, `F3_DONT_CARE, `F7_DONT_CARE }: begin - t_e_address = t_d_imm + t_r_a; - pmmu_addr = t_e_address; - pmmu_rd = 1; - - #1; - case (t_d_f3) - 0: begin - pmmu_dataw = pmmu_datar & ~('hff << (8 * t_e_address[1:0])) | (t_r_b & 'hff) << (8 * t_e_address[1:0]); - end - 1: begin - if (t_e_address[0] != 0) $error("UNALIGNED STORE %08x", t_e_address); - pmmu_dataw = pmmu_datar & ~('hffff << (8 * t_e_address[1:0])) | (t_r_b & 'hffff) << (8 * t_e_address[1:0]); - end - 2: begin - if (t_e_address[1:0] != 0) $error("UNALIGNED STORE %08x", t_e_address); - pmmu_dataw = t_r_b; - end - 3, 4, 5, 6, 7: $error("INVALID INSTRUCTION"); - endcase - + pmmu_addr = t_d_imm + t_r_a; + pmmu_dataw = t_r_b; pmmu_wr = 1; - pmmu_rd = 0; + pmmu_size = t_d_f3[1:0]; + + #2; + pmmu_wr = 0; end { `INS_IMMOP, `INS_ALUOP_ADD, `F7_DONT_CARE }: begin t_e_result = $signed(t_r_a) + $signed(t_d_imm); @@ -317,8 +307,8 @@ module hart( default: $error("INVALID INSTRUCTION"); endcase - // write back (ignore the delay, its not important) - @(posedge clk); #1; + // write back + @(posedge clk); $display("== WRITE REGISTERS =="); case (t_d_op) @@ -330,11 +320,5 @@ module hart( // finish up reg_pc = t_e_branch ? t_e_address : reg_pc + 4; - - // shhhh... you dont see this... - pmmu_rd = 0; - pmmu_wr = 0; - pmmu_addr = 0; - pmmu_dataw = 0; end endmodule \ No newline at end of file diff --git a/board/parts/pmmu.sv b/board/parts/pmmu.sv index 3ea5cac..5608b84 100644 --- a/board/parts/pmmu.sv +++ b/board/parts/pmmu.sv @@ -1,34 +1,36 @@ // System physical memory management unit, addresses are dword aligned module pmmu( clk, - rd, wr, + rd, wr, size, addr, datar, dataw, rom_rd, rom_addr, rom_datar, - ram_rd, ram_wr, + ram_rd, ram_wr, ram_size, ram_addr, ram_datar, ram_dataw ); // INPUT SHIT - input clk; - input reg rd; - input reg wr; - input reg [31:0] addr; - input reg [31:0] dataw; - output reg [31:0] datar; + input clk; + input reg rd; + input reg wr; + input reg[1:0] size; + input reg[31:0] addr; + input reg[31:0] dataw; + output reg[31:0] datar; // ROM - output reg rom_rd; - output reg [31:0] rom_addr; - input reg [31:0] rom_datar; + output reg rom_rd; + output reg[31:0] rom_addr; + input reg[31:0] rom_datar; // RAM - output reg ram_rd; - output reg ram_wr; - output reg [31:0] ram_addr; - output reg [31:0] ram_dataw; - input reg [31:0] ram_datar; + output reg ram_rd; + output reg ram_wr; + output reg[1:0] ram_size; + output reg[31:0] ram_addr; + output reg[31:0] ram_dataw; + input reg[31:0] ram_datar; always @(posedge clk) begin rom_rd = 0; @@ -44,9 +46,10 @@ module pmmu( rom_rd = 0; end else if ((addr == 'h100000 || addr > 'h100000) && addr < 'h101000) begin - ram_addr = addr >> 2; + ram_addr = addr; ram_rd = rd; ram_wr = wr; + ram_size = size; if (wr) ram_dataw = dataw; #1; diff --git a/board/parts/ram.sv b/board/parts/ram.sv index aa962bb..06653d6 100644 --- a/board/parts/ram.sv +++ b/board/parts/ram.sv @@ -2,6 +2,7 @@ module ram( input clk, input reg rd, input reg wr, + input reg[1:0] size, input reg[31:0] addr, output reg[31:0] datar, input reg[31:0] dataw @@ -14,12 +15,41 @@ module ram( // $display("RAM: %c%c", wr ? "W" : "-", rd ? "R" : "-"); if (wr) begin - $display("RAM: [%08x] <= %d", addr << 2, dataw); - data[addr] = dataw; + $display("RAM: [%08x](%d) <= %d", addr, size, dataw); + + case (size) + 0: begin + data[addr >> 2] = (data[addr >> 2] & ~('hff << (8 * addr[1:0]))) | ((dataw & 'hff) << (8 * addr[1:0])); + end + 1: begin + if (addr[0] != 0) $error("MISALIGNED STORE OF SIZE %d AT %08x", size, addr); + data[addr >> 2] = (data[addr >> 2] & ~('hffff << (8 * addr[1:0]))) | ((dataw & 'hffff) << (8 * addr[1:0])); + end + 2: begin + if (addr[1:0] != 0) $error("MISALIGNED STORE OF SIZE %d AT %08x", size, addr); + data[addr >> 2] = dataw; + end + default: $error("INVALID STORE SIZE %d", size); + endcase end + if (rd) begin - $display("RAM: [%08x] => %d", addr << 2, data[addr]); - datar = data[addr]; + case (size) + 0: begin + datar = (data[addr >> 2] >> (8 * addr[1:0])) & 'hff; + end + 1: begin + if (addr[0] != 0) $error("MISALIGNED LOAD OF SIZE 1 AT %08x", addr); + datar = (data[addr >> 2] >> (8 * addr[1:0])) & 'hffff; + end + 2: begin + if (addr[1:0] != 0) $error("MISALIGNED LOAD OF SIZE %d AT %08x", size, addr); + datar = data[addr >> 2]; + end + default: $error("INVALID LOAD SIZE %d", size); + endcase + + $display("RAM: [%08x](%d) => %d", addr, size, datar); end else datar = 0; end endmodule \ No newline at end of file diff --git a/board/system.sv b/board/system.sv index ef42d18..6939106 100644 --- a/board/system.sv +++ b/board/system.sv @@ -6,25 +6,27 @@ module system(); reg clock = 0; // its the clock - reg wire_rd; - reg wire_wr; - reg [31:0] wire_addr; - reg [31:0] wire_datar; - reg [31:0] wire_dataw; - reg wire_rom_rd; - reg [31:0] wire_rom_addr; - reg [31:0] wire_rom_datar; - reg wire_ram_rd; - reg wire_ram_wr; - reg [31:0] wire_ram_addr; - reg [31:0] wire_ram_datar; - reg [31:0] wire_ram_dataw; + reg wire_rd; + reg wire_wr; + reg[1:0] wire_size; + reg[31:0] wire_addr; + reg[31:0] wire_datar; + reg[31:0] wire_dataw; + reg wire_rom_rd; + reg[31:0] wire_rom_addr; + reg[31:0] wire_rom_datar; + reg wire_ram_rd; + reg wire_ram_wr; + reg[1:0] wire_ram_size; + reg[31:0] wire_ram_addr; + reg[31:0] wire_ram_datar; + reg[31:0] wire_ram_dataw; - hart core(clock, wire_rd, wire_wr, wire_addr, wire_datar, wire_dataw); // cpu thing + hart core(clock, wire_rd, wire_wr, wire_size, wire_addr, wire_datar, wire_dataw); // cpu thing rom#(.FILE("./build/kernel.mem")) rom(clock, wire_rom_rd, wire_rom_addr, wire_rom_datar); - ram#(.SIZE('h1000)) ram(clock, wire_ram_rd, wire_ram_wr, wire_ram_addr, wire_ram_datar, wire_ram_dataw); - pmmu pmmu(clock, wire_rd, wire_wr, wire_addr, wire_datar, wire_dataw, wire_rom_rd, wire_rom_addr, wire_rom_datar, wire_ram_rd, wire_ram_wr, wire_ram_addr, wire_ram_datar, wire_ram_dataw); + ram#(.SIZE('h1000)) ram(clock, wire_ram_rd, wire_ram_wr, wire_ram_size, wire_ram_addr, wire_ram_datar, wire_ram_dataw); + pmmu pmmu(clock, wire_rd, wire_wr, wire_size, wire_addr, wire_datar, wire_dataw, wire_rom_rd, wire_rom_addr, wire_rom_datar, wire_ram_rd, wire_ram_wr, wire_ram_size, wire_ram_addr, wire_ram_datar, wire_ram_dataw); // run the clock always #5 clock = ~clock; diff --git a/os/kernel/boot.s b/os/kernel/boot.s index 55a96c3..b4fdbe7 100644 --- a/os/kernel/boot.s +++ b/os/kernel/boot.s @@ -1,6 +1,6 @@ _start: li x1, 8 // ITERATION * 4 - li x2, 5 * 4 // MAX ITERATIONS * 4 + li x2, 10 * 4 // MAX ITERATIONS * 4 li x6, 0x100000 // MEM OFFSET li x5, 1 @@ -16,8 +16,19 @@ fib: add x1, x1, 4 bne x1, x2, fib - li x5, 12345678 - sw x5, (x6) li x5, 0 + sw x5, (x6) + + li x5, 1 + sb x5, 1(x6) + lw x5, (x6) + mv x0, x5 + + li x5, 1 + sh x5, (x6) lw x5, (x6) - mv x6, x5 \ No newline at end of file + mv x0, x5 + + sh x0, 2(x6) + lw x5, (x6) + mv x0, x5 \ No newline at end of file