Skip to content

Commit

Permalink
v1.0.1:
Browse files Browse the repository at this point in the history
- Improve support for xRET (sret, mret, ...) instructions.
- Add upper cycle counter registers (rdtimeh).

Testing:
- Boots Linux 5.12 to userspace.
  • Loading branch information
ultraembedded committed Sep 18, 2021
1 parent c17cfba commit 7ae6f80
Show file tree
Hide file tree
Showing 18 changed files with 65 additions and 89 deletions.
2 changes: 1 addition & 1 deletion core/riscv/riscv_alu.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//-----------------------------------------------------------------
// RISC-V Core
// V1.0
// V1.0.1
// Ultra-Embedded.com
// Copyright 2014-2019
//
Expand Down
51 changes: 14 additions & 37 deletions core/riscv/riscv_core.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//-----------------------------------------------------------------
// RISC-V Core
// V1.0
// V1.0.1
// Ultra-Embedded.com
// Copyright 2014-2019
//
Expand Down Expand Up @@ -93,7 +93,6 @@ module riscv_core
wire mmu_lsu_writeback_w;
wire [ 1:0] fetch_in_priv_w;
wire [ 4:0] mul_opcode_rd_idx_w;
wire fetch_dec_instr_csr_w;
wire mmu_flush_w;
wire [ 31:0] lsu_opcode_pc_w;
wire fetch_accept_w;
Expand All @@ -114,7 +113,6 @@ wire mmu_ifetch_valid_w;
wire csr_opcode_invalid_w;
wire [ 5:0] csr_writeback_exception_w;
wire fetch_instr_mul_w;
wire fetch_dec_instr_exec_w;
wire branch_exec_is_ret_w;
wire [ 31:0] csr_writeback_exception_addr_w;
wire [ 3:0] mmu_lsu_wr_w;
Expand All @@ -139,7 +137,6 @@ wire [ 4:0] mul_opcode_ra_idx_w;
wire [ 4:0] csr_opcode_rb_idx_w;
wire lsu_stall_w;
wire branch_exec_is_not_taken_w;
wire fetch_dec_instr_mul_w;
wire [ 31:0] branch_exec_pc_w;
wire [ 31:0] opcode_opcode_w;
wire [ 31:0] mul_opcode_pc_w;
Expand All @@ -148,19 +145,16 @@ wire [ 31:0] mul_opcode_ra_operand_w;
wire branch_exec_is_taken_w;
wire fetch_dec_fault_fetch_w;
wire fetch_dec_valid_w;
wire fetch_dec_instr_lsu_w;
wire fetch_fault_fetch_w;
wire lsu_opcode_invalid_w;
wire [ 31:0] mmu_lsu_addr_w;
wire mul_hold_w;
wire mmu_ifetch_accept_w;
wire mmu_lsu_ack_w;
wire [ 31:0] fetch_pc_w;
wire fetch_dec_instr_div_w;
wire mmu_ifetch_invalidate_w;
wire [ 31:0] mul_opcode_rb_operand_w;
wire [ 1:0] branch_csr_priv_w;
wire fetch_dec_instr_invalid_w;
wire branch_exec_request_w;
wire [ 31:0] lsu_opcode_ra_operand_w;
wire div_opcode_valid_w;
Expand All @@ -169,10 +163,9 @@ wire mmu_lsu_rd_w;
wire [ 31:0] fetch_dec_pc_w;
wire interrupt_inhibit_w;
wire mmu_ifetch_error_w;
wire fetch_dec_instr_branch_w;
wire [ 5:0] writeback_mem_exception_w;
wire fetch_instr_lsu_w;
wire csr_result_e1_write_w;
wire [ 1:0] mmu_priv_d_w;
wire [ 4:0] opcode_ra_idx_w;
wire [ 31:0] csr_opcode_ra_operand_w;
wire [ 31:0] writeback_mem_value_w;
Expand Down Expand Up @@ -207,7 +200,7 @@ wire mmu_lsu_cacheable_w;
wire fetch_instr_csr_w;
wire lsu_opcode_valid_w;
wire [ 31:0] fetch_dec_instr_w;
wire [ 1:0] mmu_priv_d_w;
wire csr_result_e1_write_w;
wire [ 31:0] csr_opcode_opcode_w;
wire fetch_instr_div_w;
wire [ 31:0] fetch_instr_w;
Expand All @@ -220,7 +213,6 @@ wire mmu_lsu_flush_w;
wire [ 4:0] lsu_opcode_rb_idx_w;
wire mmu_lsu_accept_w;
wire [ 31:0] lsu_opcode_rb_operand_w;
wire fetch_dec_instr_rd_valid_w;
wire mmu_sum_w;
wire [ 31:0] writeback_exec_value_w;
wire [ 4:0] lsu_opcode_ra_idx_w;
Expand Down Expand Up @@ -264,8 +256,8 @@ u_exec

riscv_decode
#(
.SUPPORT_MULDIV(SUPPORT_MULDIV)
,.EXTRA_DECODE_STAGE(EXTRA_DECODE_STAGE)
.EXTRA_DECODE_STAGE(EXTRA_DECODE_STAGE)
,.SUPPORT_MULDIV(SUPPORT_MULDIV)
)
u_decode
(
Expand All @@ -277,14 +269,6 @@ u_decode
,.fetch_in_pc_i(fetch_dec_pc_w)
,.fetch_in_fault_fetch_i(fetch_dec_fault_fetch_w)
,.fetch_in_fault_page_i(fetch_dec_fault_page_w)
,.fetch_in_instr_exec_i(fetch_dec_instr_exec_w)
,.fetch_in_instr_lsu_i(fetch_dec_instr_lsu_w)
,.fetch_in_instr_branch_i(fetch_dec_instr_branch_w)
,.fetch_in_instr_mul_i(fetch_dec_instr_mul_w)
,.fetch_in_instr_div_i(fetch_dec_instr_div_w)
,.fetch_in_instr_csr_i(fetch_dec_instr_csr_w)
,.fetch_in_instr_rd_valid_i(fetch_dec_instr_rd_valid_w)
,.fetch_in_instr_invalid_i(fetch_dec_instr_invalid_w)
,.fetch_out_accept_i(fetch_accept_w)
,.squash_decode_i(squash_decode_w)

Expand All @@ -308,9 +292,9 @@ u_decode

riscv_mmu
#(
.SUPPORT_MMU(SUPPORT_MMU)
.MEM_CACHE_ADDR_MAX(MEM_CACHE_ADDR_MAX)
,.SUPPORT_MMU(SUPPORT_MMU)
,.MEM_CACHE_ADDR_MIN(MEM_CACHE_ADDR_MIN)
,.MEM_CACHE_ADDR_MAX(MEM_CACHE_ADDR_MAX)
)
u_mmu
(
Expand Down Expand Up @@ -377,8 +361,8 @@ u_mmu

riscv_lsu
#(
.MEM_CACHE_ADDR_MIN(MEM_CACHE_ADDR_MIN)
,.MEM_CACHE_ADDR_MAX(MEM_CACHE_ADDR_MAX)
.MEM_CACHE_ADDR_MAX(MEM_CACHE_ADDR_MAX)
,.MEM_CACHE_ADDR_MIN(MEM_CACHE_ADDR_MIN)
)
u_lsu
(
Expand Down Expand Up @@ -421,8 +405,8 @@ u_lsu

riscv_csr
#(
.SUPPORT_MULDIV(SUPPORT_MULDIV)
,.SUPPORT_SUPER(SUPPORT_SUPER)
.SUPPORT_SUPER(SUPPORT_SUPER)
,.SUPPORT_MULDIV(SUPPORT_MULDIV)
)
u_csr
(
Expand Down Expand Up @@ -513,10 +497,11 @@ u_div

riscv_issue
#(
.SUPPORT_MULDIV(SUPPORT_MULDIV)
.SUPPORT_REGFILE_XILINX(SUPPORT_REGFILE_XILINX)
,.SUPPORT_LOAD_BYPASS(SUPPORT_LOAD_BYPASS)
,.SUPPORT_MULDIV(SUPPORT_MULDIV)
,.SUPPORT_MUL_BYPASS(SUPPORT_MUL_BYPASS)
,.SUPPORT_REGFILE_XILINX(SUPPORT_REGFILE_XILINX)
,.SUPPORT_DUAL_ISSUE(1)
)
u_issue
(
Expand Down Expand Up @@ -644,14 +629,6 @@ u_fetch
,.fetch_pc_o(fetch_dec_pc_w)
,.fetch_fault_fetch_o(fetch_dec_fault_fetch_w)
,.fetch_fault_page_o(fetch_dec_fault_page_w)
,.fetch_instr_exec_o(fetch_dec_instr_exec_w)
,.fetch_instr_lsu_o(fetch_dec_instr_lsu_w)
,.fetch_instr_branch_o(fetch_dec_instr_branch_w)
,.fetch_instr_mul_o(fetch_dec_instr_mul_w)
,.fetch_instr_div_o(fetch_dec_instr_div_w)
,.fetch_instr_csr_o(fetch_dec_instr_csr_w)
,.fetch_instr_rd_valid_o(fetch_dec_instr_rd_valid_w)
,.fetch_instr_invalid_o(fetch_dec_instr_invalid_w)
,.icache_rd_o(mmu_ifetch_rd_w)
,.icache_flush_o(mmu_ifetch_flush_w)
,.icache_invalidate_o(mmu_ifetch_invalidate_w)
Expand Down
17 changes: 12 additions & 5 deletions core/riscv/riscv_csr.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//-----------------------------------------------------------------
// RISC-V Core
// V1.0
// V1.0.1
// Ultra-Embedded.com
// Copyright 2014-2019
//
Expand Down Expand Up @@ -103,7 +103,8 @@ module riscv_csr
//-----------------------------------------------------------------
wire ecall_w = opcode_valid_i && ((opcode_opcode_i & `INST_ECALL_MASK) == `INST_ECALL);
wire ebreak_w = opcode_valid_i && ((opcode_opcode_i & `INST_EBREAK_MASK) == `INST_EBREAK);
wire eret_w = opcode_valid_i && ((opcode_opcode_i & `INST_MRET_MASK) == `INST_MRET);
wire eret_w = opcode_valid_i && ((opcode_opcode_i & `INST_ERET_MASK) == `INST_ERET);
wire [1:0] eret_priv_w = opcode_opcode_i[29:28];
wire csrrw_w = opcode_valid_i && ((opcode_opcode_i & `INST_CSRRW_MASK) == `INST_CSRRW);
wire csrrs_w = opcode_valid_i && ((opcode_opcode_i & `INST_CSRRS_MASK) == `INST_CSRRS);
wire csrrc_w = opcode_valid_i && ((opcode_opcode_i & `INST_CSRRC_MASK) == `INST_CSRRC);
Expand Down Expand Up @@ -212,6 +213,9 @@ reg [ 31:0] rd_result_e1_q;
reg [ 31:0] csr_wdata_e1_q;
reg [`EXCEPTION_W-1:0] exception_e1_q;

// Inappropriate xRET for the current exec priv level
wire eret_fault_w = eret_w && (current_priv_w < eret_priv_w);

always @ (posedge clk_i or posedge rst_i)
if (rst_i)
begin
Expand All @@ -226,16 +230,19 @@ begin

// Invalid instruction / CSR access fault?
// Record opcode for writing to csr_xtval later.
if (opcode_invalid_i || csr_fault_r)
if (opcode_invalid_i || csr_fault_r || eret_fault_w)
rd_result_e1_q <= opcode_opcode_i;
else
rd_result_e1_q <= csr_rdata_w;

// E1 CSR exceptions
if ((opcode_opcode_i & `INST_ECALL_MASK) == `INST_ECALL)
exception_e1_q <= `EXCEPTION_ECALL + {4'b0, current_priv_w};
else if ((opcode_opcode_i & `INST_MRET_MASK) == `INST_MRET)
exception_e1_q <= `EXCEPTION_ERET; // TODO: MPRIV
// xRET for priv level above this one - fault
else if (eret_fault_w)
exception_e1_q <= `EXCEPTION_ILLEGAL_INSTRUCTION;
else if ((opcode_opcode_i & `INST_ERET_MASK) == `INST_ERET)
exception_e1_q <= `EXCEPTION_ERET_U + {4'b0, eret_priv_w};
else if ((opcode_opcode_i & `INST_EBREAK_MASK) == `INST_EBREAK)
exception_e1_q <= `EXCEPTION_BREAKPOINT;
else if (opcode_invalid_i || csr_fault_r)
Expand Down
19 changes: 12 additions & 7 deletions core/riscv/riscv_csr_regfile.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//-----------------------------------------------------------------
// RISC-V Core
// V1.0
// V1.0.1
// Ultra-Embedded.com
// Copyright 2014-2019
//
Expand Down Expand Up @@ -101,6 +101,7 @@ reg [31:0] csr_mip_q;
reg [31:0] csr_mie_q;
reg [1:0] csr_mpriv_q;
reg [31:0] csr_mcycle_q;
reg [31:0] csr_mcycle_h_q;
reg [31:0] csr_mscratch_q;
reg [31:0] csr_mtval_q;
reg [31:0] csr_mtimecmp_q;
Expand Down Expand Up @@ -190,6 +191,7 @@ begin
`CSR_MIE: rdata_r = csr_mie_q & `CSR_MIE_MASK;
`CSR_MCYCLE,
`CSR_MTIME: rdata_r = csr_mcycle_q;
`CSR_MTIMEH: rdata_r = csr_mcycle_h_q;
`CSR_MHARTID: rdata_r = cpu_id_i;
`CSR_MISA: rdata_r = misa_i;
`CSR_MEDELEG: rdata_r = SUPPORT_SUPER ? (csr_medeleg_q & `CSR_MEDELEG_MASK) : 32'b0;
Expand Down Expand Up @@ -330,11 +332,10 @@ begin
end
end
// Exception return
else if (exception_i == `EXCEPTION_ERET)
else if (exception_i >= `EXCEPTION_ERET_U && exception_i <= `EXCEPTION_ERET_M)
begin
// TODO: Not quite correct - should check which ERET insn
// MRET (return from machine)
if (csr_mpriv_q == `PRIV_MACHINE)
if (exception_i[1:0] == `PRIV_MACHINE)
begin
// Set privilege level to previous MPP
csr_mpriv_r = csr_sr_r[`SR_MPP_R];
Expand Down Expand Up @@ -506,6 +507,7 @@ begin
csr_mie_q <= 32'b0;
csr_mpriv_q <= `PRIV_MACHINE;
csr_mcycle_q <= 32'b0;
csr_mcycle_h_q <= 32'b0;
csr_mscratch_q <= 32'b0;
csr_mtimecmp_q <= 32'b0;
csr_mtime_ie_q <= 1'b0;
Expand Down Expand Up @@ -550,6 +552,10 @@ begin

csr_mip_next_q <= buffer_mip_w ? csr_mip_next_r : 32'b0;

// Increment upper cycle counter on lower 32-bit overflow
if (csr_mcycle_q == 32'hFFFFFFFF)
csr_mcycle_h_q <= csr_mcycle_h_q + 32'd1;

`ifdef HAS_SIM_CTRL
// CSR SIM_CTRL (or DSCRATCH)
if ((csr_waddr_i == `CSR_DSCRATCH || csr_waddr_i == `CSR_SIM_CTRL) && ~(|exception_i))
Expand Down Expand Up @@ -588,11 +594,10 @@ begin
branch_target_r = (irq_priv_q == `PRIV_MACHINE) ? csr_mtvec_q : csr_stvec_q;
end
// Exception return
else if (exception_i == `EXCEPTION_ERET)
else if (exception_i >= `EXCEPTION_ERET_U && exception_i <= `EXCEPTION_ERET_M)
begin
// TODO: Not quite correct - should check which ERET insn
// MRET (return from machine)
if (csr_mpriv_q == `PRIV_MACHINE)
if (exception_i[1:0] == `PRIV_MACHINE)
begin
branch_r = 1'b1;
branch_target_r = csr_mepc_q;
Expand Down
10 changes: 1 addition & 9 deletions core/riscv/riscv_decode.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//-----------------------------------------------------------------
// RISC-V Core
// V1.0
// V1.0.1
// Ultra-Embedded.com
// Copyright 2014-2019
//
Expand Down Expand Up @@ -59,14 +59,6 @@ module riscv_decode
,input [ 31:0] fetch_in_pc_i
,input fetch_in_fault_fetch_i
,input fetch_in_fault_page_i
,input fetch_in_instr_exec_i
,input fetch_in_instr_lsu_i
,input fetch_in_instr_branch_i
,input fetch_in_instr_mul_i
,input fetch_in_instr_div_i
,input fetch_in_instr_csr_i
,input fetch_in_instr_rd_valid_i
,input fetch_in_instr_invalid_i
,input fetch_out_accept_i
,input squash_decode_i

Expand Down
6 changes: 3 additions & 3 deletions core/riscv/riscv_decoder.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//-----------------------------------------------------------------
// RISC-V Core
// V1.0
// V1.0.1
// Ultra-Embedded.com
// Copyright 2014-2019
//
Expand Down Expand Up @@ -99,7 +99,7 @@ wire invalid_w = valid_i &&
((opcode_i & `INST_SW_MASK) == `INST_SW) ||
((opcode_i & `INST_ECALL_MASK) == `INST_ECALL) ||
((opcode_i & `INST_EBREAK_MASK) == `INST_EBREAK) ||
((opcode_i & `INST_MRET_MASK) == `INST_MRET) ||
((opcode_i & `INST_ERET_MASK) == `INST_ERET) ||
((opcode_i & `INST_CSRRW_MASK) == `INST_CSRRW) ||
((opcode_i & `INST_CSRRS_MASK) == `INST_CSRRS) ||
((opcode_i & `INST_CSRRC_MASK) == `INST_CSRRC) ||
Expand Down Expand Up @@ -220,7 +220,7 @@ assign div_o = enable_muldiv_i &&

assign csr_o = ((opcode_i & `INST_ECALL_MASK) == `INST_ECALL) ||
((opcode_i & `INST_EBREAK_MASK) == `INST_EBREAK) ||
((opcode_i & `INST_MRET_MASK) == `INST_MRET) ||
((opcode_i & `INST_ERET_MASK) == `INST_ERET) ||
((opcode_i & `INST_CSRRW_MASK) == `INST_CSRRW) ||
((opcode_i & `INST_CSRRS_MASK) == `INST_CSRRS) ||
((opcode_i & `INST_CSRRC_MASK) == `INST_CSRRC) ||
Expand Down
16 changes: 9 additions & 7 deletions core/riscv/riscv_defs.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//-----------------------------------------------------------------
// RISC-V Core
// V1.0
// V1.0.1
// Ultra-Embedded.com
// Copyright 2014-2019
//
Expand Down Expand Up @@ -216,10 +216,9 @@
`define INST_EBREAK 32'h100073
`define INST_EBREAK_MASK 32'hffffffff

// mret / sret
`define INST_MRET 32'h10200073
`define INST_MRET_MASK 32'hdfffffff
`define INST_MRET_R 29
// eret
`define INST_ERET 32'h200073
`define INST_ERET_MASK 32'hcfffffff

// csrrw
`define INST_CSRRW 32'h1073
Expand Down Expand Up @@ -501,8 +500,11 @@
`define EXCEPTION_PAGE_FAULT_STORE 6'h1f
`define EXCEPTION_EXCEPTION 6'h10
`define EXCEPTION_INTERRUPT 6'h20
`define EXCEPTION_ERET 6'h30
`define EXCEPTION_FENCE 6'h31
`define EXCEPTION_ERET_U 6'h30
`define EXCEPTION_ERET_S 6'h31
`define EXCEPTION_ERET_H 6'h32
`define EXCEPTION_ERET_M 6'h33
`define EXCEPTION_FENCE 6'h34
`define EXCEPTION_TYPE_MASK 6'h30
`define EXCEPTION_SUBTYPE_R 3:0

Expand Down
2 changes: 1 addition & 1 deletion core/riscv/riscv_divider.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//-----------------------------------------------------------------
// RISC-V Core
// V1.0
// V1.0.1
// Ultra-Embedded.com
// Copyright 2014-2019
//
Expand Down
Loading

0 comments on commit 7ae6f80

Please sign in to comment.