master
xwashere 2023-12-30 13:04:40 -05:00
parent 95b2be3ab7
commit 666b576d90
Signed by: XWasHere
GPG Key ID: 042F8BFA1B0EF93B
5 changed files with 128 additions and 98 deletions

View File

@ -46,46 +46,47 @@
module hart( module hart(
clk, clk,
pmmu_rd, pmmu_wr, pmmu_rd, pmmu_wr, pmmu_size,
pmmu_addr, pmmu_datar, pmmu_dataw pmmu_addr, pmmu_datar, pmmu_dataw
); );
input clk; // the clock. pretty important. input clk; // the clock. pretty important.
output reg pmmu_rd; output reg pmmu_rd;
output reg pmmu_wr; output reg pmmu_wr;
output reg [31:0] pmmu_addr; output reg[1:0] pmmu_size;
input reg [31:0] pmmu_datar; output reg[31:0] pmmu_addr;
output reg [31:0] pmmu_dataw; input reg[31:0] pmmu_datar;
output reg[31:0] pmmu_dataw;
reg [31:0] reg_pc = 0; reg[31:0] reg_pc = 0;
reg [31:0] reg_int [31:0]; reg[31:0] reg_int[31:0];
// FETCH DATA // 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 // DECODE DATA
reg [6:0] t_d_op; reg[6:0] t_d_op;
reg [4:0] t_d_rd; reg[4:0] t_d_rd;
reg [2:0] t_d_f3; reg[2:0] t_d_f3;
reg [4:0] t_d_r1; reg[4:0] t_d_r1;
reg [4:0] t_d_r2; reg[4:0] t_d_r2;
reg [6:0] t_d_f7; reg[6:0] t_d_f7;
reg [31:0] t_d_immi; reg[31:0] t_d_immi;
reg [31:0] t_d_imms; reg[31:0] t_d_imms;
reg [31:0] t_d_immb; reg[31:0] t_d_immb;
reg [31:0] t_d_immu; reg[31:0] t_d_immu;
reg [31:0] t_d_immj; reg[31:0] t_d_immj;
reg [31:0] t_d_imm; reg[31:0] t_d_imm;
// GET REGISTERS // GET REGISTERS
reg [31:0] t_r_a; reg[31:0] t_r_a;
reg [31:0] t_r_b; reg[31:0] t_r_b;
// EXECUTE INSTRUCTION // EXECUTE INSTRUCTION
reg [31:0] t_e_result; reg[31:0] t_e_result;
reg t_e_branch; reg t_e_branch;
reg [31:0] t_e_address; reg[31:0] t_e_address;
reg [31:0] t_e_tmp1; reg[31:0] t_e_tmp1;
always begin always begin
// instruction fetch // instruction fetch
@ -94,6 +95,7 @@ module hart(
pmmu_addr = reg_pc; pmmu_addr = reg_pc;
pmmu_rd = 1; pmmu_rd = 1;
pmmu_size = 2;
// instruction decode // instruction decode
@(posedge clk); @(posedge clk);
@ -101,6 +103,7 @@ module hart(
t_ins = pmmu_datar; t_ins = pmmu_datar;
pmmu_addr = 0; pmmu_addr = 0;
pmmu_rd = 0; pmmu_rd = 0;
pmmu_size = 0;
t_d_op = t_ins[6:0]; t_d_op = t_ins[6:0];
t_d_rd = t_ins[11:7]; t_d_rd = t_ins[11:7];
@ -208,9 +211,11 @@ module hart(
t_e_address = t_d_imm + t_r_a; t_e_address = t_d_imm + t_r_a;
pmmu_addr = t_e_address; pmmu_addr = t_e_address;
pmmu_rd = 1; pmmu_rd = 1;
pmmu_size = 2;
#1; #2;
pmmu_rd = 0; pmmu_rd = 0;
case (t_d_f3[1:0]) case (t_d_f3[1:0])
0: t_e_result = (pmmu_datar >> (8 * (t_e_address & 3))) & 255; 0: t_e_result = (pmmu_datar >> (8 * (t_e_address & 3))) & 255;
1: begin 1: begin
@ -232,28 +237,13 @@ module hart(
endcase endcase
end end
{ `INS_STORE, `F3_DONT_CARE, `F7_DONT_CARE }: begin { `INS_STORE, `F3_DONT_CARE, `F7_DONT_CARE }: begin
t_e_address = t_d_imm + t_r_a; pmmu_addr = 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; pmmu_dataw = t_r_b;
end
3, 4, 5, 6, 7: $error("INVALID INSTRUCTION");
endcase
pmmu_wr = 1; pmmu_wr = 1;
pmmu_rd = 0; pmmu_size = t_d_f3[1:0];
#2;
pmmu_wr = 0;
end end
{ `INS_IMMOP, `INS_ALUOP_ADD, `F7_DONT_CARE }: begin { `INS_IMMOP, `INS_ALUOP_ADD, `F7_DONT_CARE }: begin
t_e_result = $signed(t_r_a) + $signed(t_d_imm); t_e_result = $signed(t_r_a) + $signed(t_d_imm);
@ -317,8 +307,8 @@ module hart(
default: $error("INVALID INSTRUCTION"); default: $error("INVALID INSTRUCTION");
endcase endcase
// write back (ignore the delay, its not important) // write back
@(posedge clk); #1; @(posedge clk);
$display("== WRITE REGISTERS =="); $display("== WRITE REGISTERS ==");
case (t_d_op) case (t_d_op)
@ -330,11 +320,5 @@ module hart(
// finish up // finish up
reg_pc = t_e_branch ? t_e_address : reg_pc + 4; 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 end
endmodule endmodule

View File

@ -1,34 +1,36 @@
// System physical memory management unit, addresses are dword aligned // System physical memory management unit, addresses are dword aligned
module pmmu( module pmmu(
clk, clk,
rd, wr, rd, wr, size,
addr, datar, dataw, addr, datar, dataw,
rom_rd, rom_rd,
rom_addr, rom_datar, rom_addr, rom_datar,
ram_rd, ram_wr, ram_rd, ram_wr, ram_size,
ram_addr, ram_datar, ram_dataw ram_addr, ram_datar, ram_dataw
); );
// INPUT SHIT // INPUT SHIT
input clk; input clk;
input reg rd; input reg rd;
input reg wr; input reg wr;
input reg [31:0] addr; input reg[1:0] size;
input reg [31:0] dataw; input reg[31:0] addr;
output reg [31:0] datar; input reg[31:0] dataw;
output reg[31:0] datar;
// ROM // ROM
output reg rom_rd; output reg rom_rd;
output reg [31:0] rom_addr; output reg[31:0] rom_addr;
input reg [31:0] rom_datar; input reg[31:0] rom_datar;
// RAM // RAM
output reg ram_rd; output reg ram_rd;
output reg ram_wr; output reg ram_wr;
output reg [31:0] ram_addr; output reg[1:0] ram_size;
output reg [31:0] ram_dataw; output reg[31:0] ram_addr;
input reg [31:0] ram_datar; output reg[31:0] ram_dataw;
input reg[31:0] ram_datar;
always @(posedge clk) begin always @(posedge clk) begin
rom_rd = 0; rom_rd = 0;
@ -44,9 +46,10 @@ module pmmu(
rom_rd = 0; rom_rd = 0;
end else if ((addr == 'h100000 || addr > 'h100000) && addr < 'h101000) begin end else if ((addr == 'h100000 || addr > 'h100000) && addr < 'h101000) begin
ram_addr = addr >> 2; ram_addr = addr;
ram_rd = rd; ram_rd = rd;
ram_wr = wr; ram_wr = wr;
ram_size = size;
if (wr) ram_dataw = dataw; if (wr) ram_dataw = dataw;
#1; #1;

View File

@ -2,6 +2,7 @@ module ram(
input clk, input clk,
input reg rd, input reg rd,
input reg wr, input reg wr,
input reg[1:0] size,
input reg[31:0] addr, input reg[31:0] addr,
output reg[31:0] datar, output reg[31:0] datar,
input reg[31:0] dataw input reg[31:0] dataw
@ -14,12 +15,41 @@ module ram(
// $display("RAM: %c%c", wr ? "W" : "-", rd ? "R" : "-"); // $display("RAM: %c%c", wr ? "W" : "-", rd ? "R" : "-");
if (wr) begin if (wr) begin
$display("RAM: [%08x] <= %d", addr << 2, dataw); $display("RAM: [%08x](%d) <= %d", addr, size, dataw);
data[addr] = dataw;
case (size)
0: begin
data[addr >> 2] = (data[addr >> 2] & ~('hff << (8 * addr[1:0]))) | ((dataw & 'hff) << (8 * addr[1:0]));
end 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 if (rd) begin
$display("RAM: [%08x] => %d", addr << 2, data[addr]); case (size)
datar = data[addr]; 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 else datar = 0;
end end
endmodule endmodule

View File

@ -8,23 +8,25 @@ module system();
reg wire_rd; reg wire_rd;
reg wire_wr; reg wire_wr;
reg [31:0] wire_addr; reg[1:0] wire_size;
reg [31:0] wire_datar; reg[31:0] wire_addr;
reg [31:0] wire_dataw; reg[31:0] wire_datar;
reg[31:0] wire_dataw;
reg wire_rom_rd; reg wire_rom_rd;
reg [31:0] wire_rom_addr; reg[31:0] wire_rom_addr;
reg [31:0] wire_rom_datar; reg[31:0] wire_rom_datar;
reg wire_ram_rd; reg wire_ram_rd;
reg wire_ram_wr; reg wire_ram_wr;
reg [31:0] wire_ram_addr; reg[1:0] wire_ram_size;
reg [31:0] wire_ram_datar; reg[31:0] wire_ram_addr;
reg [31:0] wire_ram_dataw; 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); 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); 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_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); 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 // run the clock
always #5 clock = ~clock; always #5 clock = ~clock;

View File

@ -1,6 +1,6 @@
_start: _start:
li x1, 8 // ITERATION * 4 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 x6, 0x100000 // MEM OFFSET
li x5, 1 li x5, 1
@ -16,8 +16,19 @@ fib:
add x1, x1, 4 add x1, x1, 4
bne x1, x2, fib bne x1, x2, fib
li x5, 12345678
sw x5, (x6)
li x5, 0 li x5, 0
sw x5, (x6)
li x5, 1
sb x5, 1(x6)
lw x5, (x6) lw x5, (x6)
mv x6, x5 mv x0, x5
li x5, 1
sh x5, (x6)
lw x5, (x6)
mv x0, x5
sh x0, 2(x6)
lw x5, (x6)
mv x0, x5