Add ecall/ebreak

This commit is contained in:
2025-09-03 17:22:00 +03:00
parent 3087975833
commit ee55a07e0a
11 changed files with 148 additions and 37 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
SRC_ALL=$(wildcard src/**/*.sv) SRC_ALL=$(wildcard src/**/*.sv src/*.sv)
SRC_MODULE=$(filter-out %_top.sv,$(filter-out %_tb.sv,$(SRC_ALL))) SRC_MODULE=$(filter-out %_top.sv,$(filter-out %_tb.sv,$(SRC_ALL)))
DEF_MODULE=$(wildcard src/*.svh) DEF_MODULE=$(wildcard src/*.svh)
+4 -6
View File
@@ -15,12 +15,6 @@ SECTIONS {
. = ALIGN(4); . = ALIGN(4);
} }
. = 0x20000;
.vectors : {
*(.text.vectors)
}
. = 0x20000000; . = 0x20000000;
.data : { .data : {
@@ -32,4 +26,8 @@ SECTIONS {
.bss : { .bss : {
*(.bss*) *(.bss*)
} }
. = 0x20400000;
.end : {}
} }
+15 -2
View File
@@ -4,19 +4,32 @@
.option push .option push
.option norvc .option norvc
__entry: __entry:
__reset: j fw_entry
__exception: j fw_exception_entry
fw_entry:
la sp, stack_top la sp, stack_top
jal {firmware_main} jal {firmware_main}
fw_exception_entry:
mv tp, sp
la sp, exception_stack_top
jal {firmware_exception}
j .
.option pop .option pop
.popsection // .text.entry .popsection // .text.entry
.pushsection .text.vectors .pushsection .text.vectors, "ax"
.global __vector
__vector: __vector:
j . j .
.popsection // .text.vectors .popsection // .text.vectors
.pushsection .bss .pushsection .bss
stack_bottom: stack_bottom:
.skip 2048 .skip 65536
stack_top: stack_top:
exception_stack_bottom:
.skip 65536
exception_stack_top:
.popsection // .bss .popsection // .bss
+12 -2
View File
@@ -35,8 +35,18 @@ unsafe extern "C" fn firmware_main() -> ! {
loop { loop {
// TODO pause/system/fence instruction not implemented // TODO pause/system/fence instruction not implemented
// core::hint::spin_loop(); // core::hint::spin_loop();
core::arch::asm!("nop"); core::arch::asm!("ebreak");
} }
} }
global_asm!(include_str!("entry.S"), firmware_main = sym firmware_main); unsafe extern "C" fn firmware_exception() {
use fmt::Write;
let mut d = D;
writeln!(d, "In exception handler").ok();
}
global_asm!(
include_str!("entry.S"),
firmware_main = sym firmware_main,
firmware_exception = sym firmware_exception
);
+17 -2
View File
@@ -40,6 +40,8 @@ module rvx0_core #(
wire fault_instruction_decode; wire fault_instruction_decode;
wire fault_unsupported_size; wire fault_unsupported_size;
wire fault_address_align; wire fault_address_align;
wire raise_ecall;
wire raise_ebreak;
// Control // Control
@@ -112,6 +114,8 @@ module rvx0_core #(
rvx0_decoder decoder ( rvx0_decoder decoder (
.instruction_i (instruction), .instruction_i (instruction),
.instruction_fault_o (fault_instruction_decode),
.v1src_o (v1src), .v1src_o (v1src),
.v2src_o (v2src), .v2src_o (v2src),
.vdsrc_o (vdsrc), .vdsrc_o (vdsrc),
@@ -123,8 +127,10 @@ module rvx0_core #(
.write_mem_o (need_memory_write), .write_mem_o (need_memory_write),
.write_pc_o (write_pc), .write_pc_o (write_pc),
.funct3_o (funct3), .funct3_o (funct3),
.instruction_fault_o (fault_instruction_decode), .conditional_o (conditional),
.conditional_o (conditional)
.raise_ecall_o (raise_ecall),
.raise_ebreak_o (raise_ebreak)
); );
rvx0_regfile regfile ( rvx0_regfile regfile (
@@ -204,6 +210,8 @@ module rvx0_core #(
fault_instruction || fault_instruction ||
fault_memory_align || fault_memory_align ||
fault_memory_access || fault_memory_access ||
raise_ecall ||
raise_ebreak ||
intr_ext_i; intr_ext_i;
assign fault_instruction = fault_instruction_decode || (fault_unsupported_size && (need_memory_read || need_memory_write)); assign fault_instruction = fault_instruction_decode || (fault_unsupported_size && (need_memory_read || need_memory_write));
@@ -257,6 +265,8 @@ module rvx0_core #(
end else if (fault_instruction) begin end else if (fault_instruction) begin
mcause_write_value = MCAUSE_ILLEGAL_INSTRUCTION; mcause_write_value = MCAUSE_ILLEGAL_INSTRUCTION;
mtval_write_value = instruction; mtval_write_value = instruction;
end else if (raise_ebreak) begin
mcause_write_value = MCAUSE_BREAKPOINT;
end else if (~need_memory_write && fault_memory_align) begin end else if (~need_memory_write && fault_memory_align) begin
mcause_write_value = MCAUSE_LOAD_ADDRESS_MISALIGNED; mcause_write_value = MCAUSE_LOAD_ADDRESS_MISALIGNED;
mtval_write_value = alu_output; mtval_write_value = alu_output;
@@ -271,6 +281,8 @@ module rvx0_core #(
// been incremented // been incremented
mepc_write_value = pc_value - 4; mepc_write_value = pc_value - 4;
mtval_write_value = alu_output; mtval_write_value = alu_output;
end else if (raise_ecall) begin
mcause_write_value = MCAUSE_ECALL_MMODE;
end else if (intr_ext_i) begin end else if (intr_ext_i) begin
mcause_write_value = MCAUSE_INTR_EXT_MMODE | MCAUSE_INTERRUPT; mcause_write_value = MCAUSE_INTR_EXT_MMODE | MCAUSE_INTERRUPT;
end end
@@ -284,8 +296,11 @@ module rvx0_core #(
if (fault) begin if (fault) begin
$display("Take exception mcause=%x, mepc=%x, mtval=%x to %x", mcause_write_value, mepc_write_value, mtval_write_value, csr_mtvec); $display("Take exception mcause=%x, mepc=%x, mtval=%x to %x", mcause_write_value, mepc_write_value, mtval_write_value, csr_mtvec);
$display("Instruction: %x", instruction);
`ifdef RVX0_CRASH_ON_EXCEPTION
regfile.dump_state; regfile.dump_state;
$finish; $finish;
`endif
exec_stall = 1; exec_stall = 1;
end else begin end else begin
`ifdef RVX0_DEBUGGING `ifdef RVX0_DEBUGGING
+1 -1
View File
@@ -33,7 +33,7 @@ module rvx0_csr (
always @(posedge clk_i) begin always @(posedge clk_i) begin
if (rst_i) begin if (rst_i) begin
// TODO set from CPU // TODO set from CPU
mtvec_o = 'h00020000; mtvec_o = 'h00001004;
mepc_o = 0; mepc_o = 0;
mstatus_o = 0; mstatus_o = 0;
mstatush_o = 0; mstatush_o = 0;
+78 -13
View File
@@ -8,7 +8,13 @@ module rvx0_decoder (
output logic write_mem_o, output logic write_mem_o,
output logic conditional_o, output logic conditional_o,
output logic is_system_o,
output logic raise_ecall_o,
output logic raise_ebreak_o,
output logic instruction_fault_o, output logic instruction_fault_o,
output logic [6:0] opcode_o,
output wire [31:0] imm_o, output wire [31:0] imm_o,
output wire v1src_o, output wire v1src_o,
output wire [1:0] v2src_o, output wire [1:0] v2src_o,
@@ -20,15 +26,13 @@ module rvx0_decoder (
output wire [4:0] rs2_o, output wire [4:0] rs2_o,
output wire [4:0] rd_o output wire [4:0] rd_o
); );
wire [6:0] opcode;
wire signed [11:0] imm_i_type; wire signed [11:0] imm_i_type;
wire signed [11:0] imm_s_type; wire signed [11:0] imm_s_type;
wire signed [12:0] imm_b_type; wire signed [12:0] imm_b_type;
wire [19:0] imm_u_type; wire [19:0] imm_u_type;
wire signed [20:0] imm_j_type; wire signed [20:0] imm_j_type;
assign opcode = instruction_i[6:0]; assign opcode_o = instruction_i[6:0];
assign funct3_o = instruction_i[14:12]; assign funct3_o = instruction_i[14:12];
assign funct7_o = instruction_i[31:25]; assign funct7_o = instruction_i[31:25];
@@ -42,10 +46,24 @@ module rvx0_decoder (
assign rs2_o = instruction_i[24:20]; assign rs2_o = instruction_i[24:20];
assign rd_o = instruction_i[11:7]; assign rd_o = instruction_i[11:7];
// Decode select
// Base ISA
wire base_instruction_fault;
wire base_write_pc;
wire base_write_mem;
wire base_v1src;
wire [1:0] base_v2src;
wire [1:0] base_vdsrc;
wire base_conditional;
wire [3:0] base_aluop;
wire [31:0] base_imm;
rvx0_decoder_i decoder_i ( rvx0_decoder_i decoder_i (
.instruction_i (instruction_i), .instruction_i (instruction_i),
.opcode (opcode), .opcode (opcode_o),
.funct3 (funct3_o), .funct3 (funct3_o),
.imm_i_type (imm_i_type), .imm_i_type (imm_i_type),
@@ -54,15 +72,62 @@ module rvx0_decoder (
.imm_u_type (imm_u_type), .imm_u_type (imm_u_type),
.imm_j_type (imm_j_type), .imm_j_type (imm_j_type),
.write_pc_o (write_pc_o), .write_pc_o (base_write_pc),
.write_mem_o (write_mem_o), .write_mem_o (base_write_mem),
.conditional_o (conditional_o), .conditional_o (base_conditional),
.instruction_fault_o (instruction_fault_o), .instruction_fault_o (base_instruction_fault),
.imm_o (imm_o), .imm_o (base_imm),
.v1src_o (v1src_o), .v1src_o (base_v1src),
.v2src_o (v2src_o), .v2src_o (base_v2src),
.vdsrc_o (vdsrc_o), .vdsrc_o (base_vdsrc),
.aluop_o (aluop_o) .aluop_o (base_aluop)
); );
always_comb begin
is_system_o = 0;
case (opcode_o)
'b0001111: is_system_o = 1;
'b1110011: is_system_o = 1;
endcase
raise_ecall_o = 0;
raise_ebreak_o = 0;
write_pc_o = 0;
write_mem_o = 0;
conditional_o = 0;
instruction_fault_o = 0;
imm_o = 0;
v1src_o = V1SRC_ZERO;
v2src_o = V2SRC_ZERO;
vdsrc_o = RDSRC_NONE;
aluop_o = ALUOP_ADD;
if (rs1_o == 0 && funct3_o == 0 && rd_o == 0 && opcode_o == 'b1110011) begin
case (instruction_i[31:20])
0: raise_ecall_o = 1;
1: raise_ebreak_o = 1;
default: instruction_fault_o = 1;
endcase
end else if (rs1_o == 0 && funct3_o == 0 && opcode_o == 'b0001111) begin
// Nice
end else begin
instruction_fault_o = base_instruction_fault;
if (~base_instruction_fault) begin
write_pc_o = base_write_pc;
write_mem_o = base_write_mem;
conditional_o = base_conditional;
imm_o = base_imm;
v1src_o = base_v1src;
v2src_o = base_v2src;
vdsrc_o = base_vdsrc;
aluop_o = base_aluop;
end
end
end
endmodule endmodule
+9 -1
View File
@@ -1,4 +1,4 @@
// Base rv32i instruction set decoder // Base rv32i instruction set decoder minus fence/pause/ecall/ebreak
module rvx0_decoder_i ( module rvx0_decoder_i (
input wire [31:0] instruction_i, input wire [31:0] instruction_i,
@@ -69,6 +69,10 @@ module rvx0_decoder_i (
v2src_o = V2SRC_ZERO; v2src_o = V2SRC_ZERO;
vdsrc_o = RDSRC_MEM; vdsrc_o = RDSRC_MEM;
imm_o = 32'(signed'(imm_i_type)); imm_o = 32'(signed'(imm_i_type));
if (funct3[1:0] == 2'b11) begin
instruction_fault_o = 1;
end
end end
7'b0100011: begin // store 7'b0100011: begin // store
v1src_o = V1SRC_RS1; v1src_o = V1SRC_RS1;
@@ -76,6 +80,10 @@ module rvx0_decoder_i (
vdsrc_o = RDSRC_NONE; vdsrc_o = RDSRC_NONE;
write_mem_o = 1; write_mem_o = 1;
imm_o = 32'(signed'(imm_s_type)); imm_o = 32'(signed'(imm_s_type));
if (funct3[1:0] == 2'b11) begin
instruction_fault_o = 1;
end
end end
7'b0010011: begin // alu imm 7'b0010011: begin // alu imm
v1src_o = V1SRC_RS1; v1src_o = V1SRC_RS1;
+1 -1
View File
@@ -14,7 +14,7 @@ module rvx0_busmux (
// RAM // RAM
const logic [31:0] APB1_BASE = 'h20000000; const logic [31:0] APB1_BASE = 'h20000000;
const logic [31:0] APB1_SIZE = 'h00001000; const logic [31:0] APB1_SIZE = 'h00400000;
// Debug // Debug
const logic [31:0] APB2_BASE = 'h10000000; const logic [31:0] APB2_BASE = 'h10000000;
+4
View File
@@ -2,6 +2,7 @@
`define __RVX0_DEFS_SVH `define __RVX0_DEFS_SVH
`define RVX0_DEBUGGING 1 `define RVX0_DEBUGGING 1
// `define RVX0_CRASH_ON_EXCEPTION 1
const logic [1:0] RDSRC_ALU = 0; const logic [1:0] RDSRC_ALU = 0;
const logic [1:0] RDSRC_MEM = 1; const logic [1:0] RDSRC_MEM = 1;
@@ -58,4 +59,7 @@ const logic [31:0] MCAUSE_STORE_PAGE_FAULT = 15;
const logic [31:0] MCAUSE_INTR_EXT_MMODE = 11; const logic [31:0] MCAUSE_INTR_EXT_MMODE = 11;
const logic [31:0] MCAUSE_INTERRUPT = 1 << 31; const logic [31:0] MCAUSE_INTERRUPT = 1 << 31;
const logic IGROUP_RV32I = 0;
const logic IGROUP_SYSTEM = 1;
`endif // __RVX0_DEFS_SVH `endif // __RVX0_DEFS_SVH
+6 -8
View File
@@ -1,7 +1,7 @@
module rvx0_simple_ram ( module rvx0_simple_ram (
rvx0_apb.slave apb_slave rvx0_apb.slave apb_slave
); );
reg [31:0] words [0:1023]; reg [31:0] words [0:1048576];
integer i; integer i;
@@ -9,11 +9,11 @@ module rvx0_simple_ram (
if (apb_slave.prstn) begin if (apb_slave.prstn) begin
if (apb_slave.penable) begin if (apb_slave.penable) begin
if (apb_slave.pwrite) begin if (apb_slave.pwrite) begin
words[apb_slave.paddr[11:2]] <= apb_slave.pwdata; words[apb_slave.paddr[22:2]] <= apb_slave.pwdata;
$display("RAM write [%x] <= %x", apb_slave.paddr, apb_slave.pwdata); $display("RAM write [%x] <= %x", apb_slave.paddr, apb_slave.pwdata);
end else begin end else begin
apb_slave.prdata <= words[apb_slave.paddr[11:2]]; apb_slave.prdata <= words[apb_slave.paddr[22:2]];
$display("RAM read %x <= [%x]", words[apb_slave.paddr[11:2]], apb_slave.paddr); $display("RAM read %x <= [%x]", words[apb_slave.paddr[22:2]], apb_slave.paddr);
end end
apb_slave.pready <= 1; apb_slave.pready <= 1;
@@ -21,10 +21,8 @@ module rvx0_simple_ram (
apb_slave.pready <= 0; apb_slave.pready <= 0;
end end
end else begin end else begin
// for (i = 0; i < 1024; ++i) for (i = 0; i < 1024; ++i)
// words[i] <= 0; words[i] <= 0;
words[0] <= 'h11223344;
end end
end end
endmodule endmodule