woah
parent
95b2be3ab7
commit
666b576d90
|
@ -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_dataw = t_r_b;
|
||||||
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_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
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
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
|
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
|
|
@ -6,25 +6,27 @@
|
||||||
module system();
|
module system();
|
||||||
reg clock = 0; // its the clock
|
reg clock = 0; // its the clock
|
||||||
|
|
||||||
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 wire_rom_rd;
|
reg[31:0] wire_dataw;
|
||||||
reg [31:0] wire_rom_addr;
|
reg wire_rom_rd;
|
||||||
reg [31:0] wire_rom_datar;
|
reg[31:0] wire_rom_addr;
|
||||||
reg wire_ram_rd;
|
reg[31:0] wire_rom_datar;
|
||||||
reg wire_ram_wr;
|
reg wire_ram_rd;
|
||||||
reg [31:0] wire_ram_addr;
|
reg wire_ram_wr;
|
||||||
reg [31:0] wire_ram_datar;
|
reg[1:0] wire_ram_size;
|
||||||
reg [31:0] wire_ram_dataw;
|
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);
|
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;
|
||||||
|
|
|
@ -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)
|
||||||
|
mv x0, x5
|
||||||
|
|
||||||
|
li x5, 1
|
||||||
|
sh x5, (x6)
|
||||||
lw x5, (x6)
|
lw x5, (x6)
|
||||||
mv x6, x5
|
mv x0, x5
|
||||||
|
|
||||||
|
sh x0, 2(x6)
|
||||||
|
lw x5, (x6)
|
||||||
|
mv x0, x5
|
Loading…
Reference in New Issue