aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlavian Kaufmann <flavian@flaviankaufmann.ch>2024-05-23 20:51:28 +0200
committerFlavian Kaufmann <flavian@flaviankaufmann.ch>2024-05-23 20:51:28 +0200
commita515876002bef28d11e79ee9f74baa34790d86ce (patch)
tree919a124b96cb08561e9eb9b2623ed5d0e1efed86
parenteb163582941af4b3fac8daf00665e1b704fd7c23 (diff)
downloadriscv_cpu-a515876002bef28d11e79ee9f74baa34790d86ce.tar.gz
riscv_cpu-a515876002bef28d11e79ee9f74baa34790d86ce.zip
support for lb, lh, lbu, lhu, sb, sh
-rw-r--r--prog/src/startup.c6
-rw-r--r--prog/src/test_prog.s9
-rw-r--r--rtl/src/ram.v55
-rw-r--r--rtl/src/rom.v41
4 files changed, 104 insertions, 7 deletions
diff --git a/prog/src/startup.c b/prog/src/startup.c
index 2ed3253..b587a95 100644
--- a/prog/src/startup.c
+++ b/prog/src/startup.c
@@ -5,15 +5,15 @@ extern unsigned int _sbss; // start of .bss section
extern unsigned int _ebss; // end of .bss section
extern unsigned int _estack; // end of .stack section (stack top)
-void main(void); // main function declaration
+//void main(void); // main function declaration
-// extern void test_prog(void);
+extern void test_prog(void);
void _start(void) __attribute__((section(".text.startup"), naked)); // entry point, cpu starts executing from here
void _start(void)
{
- // test_prog();
+ //test_prog();
unsigned int *src, *dst;
diff --git a/prog/src/test_prog.s b/prog/src/test_prog.s
index caa6d8c..675a2b8 100644
--- a/prog/src/test_prog.s
+++ b/prog/src/test_prog.s
@@ -2,6 +2,15 @@
.globl test_prog
test_prog:
+
+ la t0, 0x00100000
+ li t1, 0x00ff0000
+
+ sw t1, 0(t0)
+ la t0, 0x00100002
+ lb t2, 0(t0)
+
+
li t0, 0xFFFFFFFF
li t1, 0x33333333
li t2, 0x88888888
diff --git a/rtl/src/ram.v b/rtl/src/ram.v
index fc1dc21..337b3e7 100644
--- a/rtl/src/ram.v
+++ b/rtl/src/ram.v
@@ -18,10 +18,61 @@ module ram #(
//(* RAM_STYLE="BLOCK" *)
reg [31:0] mem [0:SIZE-1];
+reg [31:0] rd_reg;
+reg [31:0] addr_reg;
+
always @(posedge clk) begin
- if (we) mem[addr >> 2] <= wd;
- rd <= mem[addr >> 2];
+ if (we) begin
+ case(size)
+ FUNCT3_LS_W: mem[addr >> 2] <= wd;
+ FUNCT3_LS_H:
+ case (addr[1])
+ 1'b0: mem[addr >> 2][15:0] <= wd[15:0];
+ 1'b1: mem[addr >> 2][31:16] <= wd[15:0];
+ endcase
+ FUNCT3_LS_B:
+ case (addr[1:0])
+ 2'b00: mem[addr >> 2][7:0] <= wd[7:0];
+ 2'b01: mem[addr >> 2][15:8] <= wd[7:0];
+ 2'b10: mem[addr >> 2][23:16] <= wd[7:0];
+ 2'b11: mem[addr >> 2][31:24] <= wd[7:0];
+ endcase
+ endcase
+ end
+ rd_reg <= { mem[addr >> 2][31:24], mem[addr >> 2][23:16], mem[addr >> 2][15:8], mem[addr >> 2][7:0] };
+ addr_reg <= addr;
+end
+
+always @ (*) begin
+ case(size)
+ FUNCT3_LS_W: rd = rd_reg;
+ FUNCT3_LS_H:
+ case (addr_reg[1])
+ 1'b0: rd = { {16{rd_reg[15]}}, rd_reg[15:0] };
+ 1'b1: rd = { {16{rd_reg[31]}}, rd_reg[31:16] };
+ endcase
+ FUNCT3_LS_B:
+ case (addr_reg[1:0])
+ 2'b00: rd = { {24{rd_reg[7]}}, rd_reg[7:0] };
+ 2'b01: rd = { {24{rd_reg[15]}}, rd_reg[15:8] };
+ 2'b10: rd = { {24{rd_reg[23]}}, rd_reg[23:16] };
+ 2'b11: rd = { {24{rd_reg[31]}}, rd_reg[31:24] };
+ endcase
+ FUNCT3_LS_HU:
+ case (addr_reg[1])
+ 1'b0: rd = { {16{1'b0}}, rd_reg[15:0] };
+ 1'b1: rd = { {16{1'b0}}, rd_reg[31:16] };
+ endcase
+ FUNCT3_LS_BU:
+ case (addr_reg[1:0])
+ 2'b00: rd = { {24{1'b0}}, rd_reg[7:0] };
+ 2'b01: rd = { {24{1'b0}}, rd_reg[15:8] };
+ 2'b10: rd = { {24{1'b0}}, rd_reg[23:16] };
+ 2'b11: rd = { {24{1'b0}}, rd_reg[31:24] };
+ endcase
+ default: rd = rd_reg;
+ endcase
end
endmodule
diff --git a/rtl/src/rom.v b/rtl/src/rom.v
index bca7ba8..9ade9bc 100644
--- a/rtl/src/rom.v
+++ b/rtl/src/rom.v
@@ -18,12 +18,49 @@ module rom #(
//(* RAM_STYLE="BLOCK" *)
reg [31:0] mem [0:SIZE-1];
+reg [7:0] mem0, mem1, mem2, mem3;
+
+reg [31:0] rd_reg;
+reg [31:0] addr_reg;
+
initial begin
- $readmemh(ROM_FILE, mem, 0, SIZE-1);
+ $readmemh(ROM_FILE, mem, 0, SIZE - 1);
end
always @ (posedge clk) begin
- rd <= mem[addr >> 2];
+ rd_reg <= { mem[addr >> 2][31:24], mem[addr >> 2][23:16], mem[addr >> 2][15:8], mem[addr >> 2][7:0] };
+ addr_reg <= addr;
+end
+
+always @ (*) begin
+ case(size)
+ FUNCT3_LS_W: rd = rd_reg;
+ FUNCT3_LS_H:
+ case (addr_reg[1])
+ 1'b0: rd = { {16{rd_reg[15]}}, rd_reg[15:0] };
+ 1'b1: rd = { {16{rd_reg[31]}}, rd_reg[31:16] };
+ endcase
+ FUNCT3_LS_B:
+ case (addr_reg[1:0])
+ 2'b00: rd = { {24{rd_reg[7]}}, rd_reg[7:0] };
+ 2'b01: rd = { {24{rd_reg[15]}}, rd_reg[15:8] };
+ 2'b10: rd = { {24{rd_reg[23]}}, rd_reg[23:16] };
+ 2'b11: rd = { {24{rd_reg[31]}}, rd_reg[31:24] };
+ endcase
+ FUNCT3_LS_HU:
+ case (addr_reg[1])
+ 1'b0: rd = { {16{1'b0}}, rd_reg[15:0] };
+ 1'b1: rd = { {16{1'b0}}, rd_reg[31:16] };
+ endcase
+ FUNCT3_LS_BU:
+ case (addr_reg[1:0])
+ 2'b00: rd = { {24{1'b0}}, rd_reg[7:0] };
+ 2'b01: rd = { {24{1'b0}}, rd_reg[15:8] };
+ 2'b10: rd = { {24{1'b0}}, rd_reg[23:16] };
+ 2'b11: rd = { {24{1'b0}}, rd_reg[31:24] };
+ endcase
+ default: rd = rd_reg;
+ endcase
end
endmodule