memory instructions

master
xwashere 2023-12-29 16:59:32 -05:00
parent ee7ff194c4
commit 95b2be3ab7
Signed by: XWasHere
GPG Key ID: 042F8BFA1B0EF93B
6 changed files with 149 additions and 24 deletions

View File

@ -85,6 +85,7 @@ module hart(
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
@ -203,8 +204,57 @@ module hart(
t_e_branch = 1;
end
end
{ `INS_LOAD, `F3_DONT_CARE, `F7_DONT_CARE }: $error("NOT IMPLEMENTED");
{ `INS_STORE, `F3_DONT_CARE, `F7_DONT_CARE }: $error("NOT IMPLEMENTED");
{ `INS_LOAD, `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;
pmmu_rd = 0;
case (t_d_f3[1:0])
0: t_e_result = (pmmu_datar >> (8 * (t_e_address & 3))) & 255;
1: begin
if (t_e_address[0] != 0) $error("UNALIGNED READ %08x", t_e_address);
t_e_result = (pmmu_datar >> (8 * (t_e_address & 2))) & 'hffff;
end
2: begin
if (t_e_address[1:0] != 0) $error("UNALIGNED READ %08x", t_e_address);
t_e_result = pmmu_datar;
end
3: $error("INVALID INSTRUCTION");
endcase
case (t_d_f3)
1,2,3,4:;
4: t_e_result = { {24{t_e_result[7]}}, t_e_result[7:0] };
5: t_e_result = { {16{t_e_result[16]}}, t_e_result[15:0] };
6, 7: $error("INVALID INSTRUCTION");
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_wr = 1;
pmmu_rd = 0;
end
{ `INS_IMMOP, `INS_ALUOP_ADD, `F7_DONT_CARE }: begin
t_e_result = $signed(t_r_a) + $signed(t_d_imm);
end
@ -267,8 +317,8 @@ module hart(
default: $error("INVALID INSTRUCTION");
endcase
// write back
@(posedge clk);
// write back (ignore the delay, its not important)
@(posedge clk); #1;
$display("== WRITE REGISTERS ==");
case (t_d_op)
@ -280,5 +330,11 @@ 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

View File

@ -5,7 +5,10 @@ module pmmu(
addr, datar, dataw,
rom_rd,
rom_addr, rom_datar
rom_addr, rom_datar,
ram_rd, ram_wr,
ram_addr, ram_datar, ram_dataw
);
// INPUT SHIT
input clk;
@ -20,16 +23,39 @@ module pmmu(
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;
always @(posedge clk) begin
rom_rd = 0;
ram_rd = 0;
ram_wr = 0;
if ((addr == 0 || addr > 0) && addr < 'h100) begin
rom_addr = addr >> 2;
rom_rd = rd;
#1; // wait for it to finish
if ((addr == 0 || addr > 0) && addr < 'h1000) begin
rom_addr = addr >> 2;
rom_rd = rd;
#1;
if (rd) datar = rom_datar;
rom_rd = 0;
end else if ((addr == 'h100000 || addr > 'h100000) && addr < 'h101000) begin
ram_addr = addr >> 2;
ram_rd = rd;
ram_wr = wr;
if (wr) ram_dataw = dataw;
#1;
if (rd) datar = ram_datar;
ram_wr = 0;
ram_rd = 0;
end else begin
$error("THIS IS BAD");
$error("INVALID MEMORY ACCESS %08x", addr);
end
end
endmodule

25
board/parts/ram.sv Normal file
View File

@ -0,0 +1,25 @@
module ram(
input clk,
input reg rd,
input reg wr,
input reg[31:0] addr,
output reg[31:0] datar,
input reg[31:0] dataw
);
parameter SIZE = 'h1000;
reg [31:0] data[0 : SIZE - 1];
always @(posedge clk) begin
// $display("RAM: %c%c", wr ? "W" : "-", rd ? "R" : "-");
if (wr) begin
$display("RAM: [%08x] <= %d", addr << 2, dataw);
data[addr] = dataw;
end
if (rd) begin
$display("RAM: [%08x] => %d", addr << 2, data[addr]);
datar = data[addr];
end else datar = 0;
end
endmodule

View File

@ -1,6 +1,7 @@
`include "parts/hart.sv";
`include "parts/pmmu.sv";
`include "parts/rom.sv";
`include "parts/ram.sv";
module system();
reg clock = 0; // its the clock
@ -13,12 +14,17 @@ module system();
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;
hart core(clock, wire_rd, wire_wr, wire_addr, wire_datar, wire_dataw); // cpu thing
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);
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);
// run the clock
always #5 clock = ~clock;

View File

@ -6,7 +6,8 @@ VERILOG_SOURCES = \
board/system.sv \
board/parts/hart.sv \
board/parts/pmmu.sv \
board/parts/rom.sv
board/parts/rom.sv \
board/parts/ram.sv
KERNEL_SOURCES = \
os/kernel/boot.s

View File

@ -1,12 +1,23 @@
_start:
li x1, 0
li x2, 1
li x3, 0
li x4, 0
li x5, 32
fib:
add x3, x1, x2
mv x1, x2
mv x2, x3
add x4, x4, 1
bne x4, x5, fib
li x1, 8 // ITERATION * 4
li x2, 5 * 4 // MAX ITERATIONS * 4
li x6, 0x100000 // MEM OFFSET
li x5, 1
sw x5, 4(x6)
fib:
add x3, x6, x1
lw x4, -4(x3) // get a
lw x5, -8(x3) // get b
add x4, x4, x5 // a = a + b
sw x4, (x3) // store a to c
// increment or stop
add x1, x1, 4
bne x1, x2, fib
li x5, 12345678
sw x5, (x6)
li x5, 0
lw x5, (x6)
mv x6, x5