Skip to content

Commit

Permalink
Add ITLB and PSW CSR register and a little bit of refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
fallen committed Jul 22, 2012
1 parent 2c801a4 commit 70b5f48
Show file tree
Hide file tree
Showing 17 changed files with 1,205 additions and 267 deletions.
18 changes: 18 additions & 0 deletions boards/milkymist-one/rtl/lm32_include.v
Expand Up @@ -98,6 +98,7 @@
`define CFG_GDBSTUB_ENABLED
//`define CFG_RANDOM_WISHBONE_LATENCY
//`define CFG_VERBOSE_DISPLAY_ENABLED
//`define CFG_PIPELINE_TRACES

// Enable MMU
`define CFG_MMU_ENABLED
Expand Down Expand Up @@ -292,12 +293,28 @@
`define LM32_CSR_WP3 `LM32_CSR_WIDTH'h1b
`endif
`ifdef CFG_MMU_ENABLED
`define LM32_CSR_PSW `LM32_CSR_WIDTH'hb
`define LM32_CSR_TLB_CTRL `LM32_CSR_WIDTH'h1c
`define LM32_CSR_TLB_VADDRESS `LM32_CSR_WIDTH'h1d
`define LM32_CSR_TLB_PADDRESS `LM32_CSR_WIDTH'h1e
`define LM32_CSR_TLB_DBG `LM32_CSR_WIDTH'h1f
`endif

`ifdef CFG_MMU_ENABLED
`define LM32_CSR_PSW_IE `LM32_WORD_WIDTH'h0
`define LM32_CSR_PSW_EIE `LM32_WORD_WIDTH'h1
`define LM32_CSR_PSW_BIE `LM32_WORD_WIDTH'h2
`define LM32_CSR_PSW_ITLBE `LM32_WORD_WIDTH'h3
`define LM32_CSR_PSW_EITLBE `LM32_WORD_WIDTH'h4
`define LM32_CSR_PSW_BITLBE `LM32_WORD_WIDTH'h5
`define LM32_CSR_PSW_DTLBE `LM32_WORD_WIDTH'h6
`define LM32_CSR_PSW_EDTLBE `LM32_WORD_WIDTH'h7
`define LM32_CSR_PSW_BDTLBE `LM32_WORD_WIDTH'h8
`define LM32_CSR_PSW_USR `LM32_WORD_WIDTH'h9
`define LM32_CSR_PSW_EUSR `LM32_WORD_WIDTH'ha
`define LM32_CSR_PSW_BUSR `LM32_WORD_WIDTH'hb
`endif

// Values for WPC CSR
`define LM32_WPC_C_RNG 1:0
`define LM32_WPC_C_DISABLED 2'b00
Expand All @@ -317,6 +334,7 @@
`define LM32_EID_INTERRUPT `LM32_EID_WIDTH'h6
`define LM32_EID_SCALL `LM32_EID_WIDTH'h7
`define LM32_EID_DTLB_MISS `LM32_EID_WIDTH'h8
`define LM32_EID_ITLB_MISS `LM32_EID_WIDTH'h9

// Pipeline result selection mux controls

Expand Down
129 changes: 120 additions & 9 deletions cores/lm32/rtl/lm32_cpu.v
Expand Up @@ -616,7 +616,8 @@ wire mc_stall_request_x; // Multi-cycle arithmetic unit s
wire [`LM32_WORD_RNG] mc_result_x;
`endif

wire [`LM32_WORD_RNG] load_store_csr_read_data_x;// Data read from load store CSRs
wire [`LM32_WORD_RNG] load_store_csr_read_data_x;// Data read from load store unit CSRs
wire [`LM32_WORD_RNG] instruction_csr_read_data_x;// Data read from instruction unit CSRs
// From CSRs
`ifdef CFG_INTERRUPTS_ENABLED
wire [`LM32_WORD_RNG] interrupt_csr_read_data_x;// Data read from interrupt CSRs
Expand All @@ -629,11 +630,32 @@ reg [`LM32_WORD_RNG] cc; // Cycle counter CSR
reg [`LM32_WORD_RNG] csr_read_data_x; // Data read from CSRs

// To/from instruction unit
`ifdef CFG_PIPELINE_TRACES
wire [`LM32_PC_RNG] pc_a;
`endif
wire [`LM32_PC_RNG] pc_f; // PC of instruction in F stage
wire [`LM32_PC_RNG] pc_d; // PC of instruction in D stage
wire [`LM32_PC_RNG] pc_x; // PC of instruction in X stage
wire [`LM32_PC_RNG] pc_m; // PC of instruction in M stage
wire [`LM32_PC_RNG] pc_w; // PC of instruction in W stage

`ifdef CFG_PIPELINE_TRACES
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
begin
if (~rst_i)
begin
if (~stall_a)
$display("[%t] Addressing inst @ 0x%08X", $time, pc_a);
if (~stall_f)
$display("[%t] Fetching inst @ 0x%08X", $time, pc_f);
if (~stall_d)
$display("[%t] Decoding inst @ 0x%08X", $time, pc_d);
if (~stall_x)
$display("[%t] Executing inst @ 0x%08X", $time, pc_x);
end
end
`endif

`ifdef CFG_TRACE_ENABLED
reg [`LM32_PC_RNG] pc_c; // PC of last commited instruction
`endif
Expand Down Expand Up @@ -777,6 +799,12 @@ reg data_bus_error_seen; // Indicates if a data bus error
reg ext_break_r;
`endif

`ifdef CFG_MMU_ENABLED
wire dtlb_miss_exception;
wire itlb_miss_exception;
reg [`LM32_WORD_RNG] lm32_csr_psw_reg;
`endif

/////////////////////////////////////////////////////
// Functions
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -819,6 +847,9 @@ lm32_instruction_unit #(
.branch_target_x (branch_target_x),
`endif
.exception_m (exception_m),
`ifdef CFG_MMU_ENABLED
.exception_x (exception_x),
`endif
.branch_taken_m (branch_taken_m),
.branch_mispredict_taken_m (branch_mispredict_taken_m),
.branch_target_m (branch_target_m),
Expand All @@ -834,7 +865,15 @@ lm32_instruction_unit #(
.dcache_restart_request (dcache_restart_request),
.dcache_refill_request (dcache_refill_request),
.dcache_refilling (dcache_refilling),
`endif
`endif
`ifdef CFG_MMU_ENABLED
.csr (csr_x),
.csr_write_data (operand_1_x),
.csr_write_enable (csr_write_enable_q_x),
.eret_q_x (eret_q_x),
.csr_psw (lm32_csr_psw_reg),
.q_x (q_x),
`endif
`ifdef CFG_IWB_ENABLED
// From Wishbone
.i_dat_i (I_DAT_I),
Expand All @@ -849,6 +888,9 @@ lm32_instruction_unit #(
`endif
// ----- Outputs -------
// To pipeline
`ifdef CFG_PIPELINE_TRACES
.pc_a (pc_a),
`endif
.pc_f (pc_f),
.pc_d (pc_d),
.pc_x (pc_x),
Expand All @@ -863,6 +905,10 @@ lm32_instruction_unit #(
`ifdef CFG_IROM_ENABLED
.irom_data_m (irom_data_m),
`endif
`ifdef CFG_MMU_ENABLED
.itlb_miss (itlb_miss_exception),
.csr_read_data (instruction_csr_read_data_x),
`endif
`ifdef CFG_IWB_ENABLED
// To Wishbone
.i_dat_o (I_DAT_O),
Expand Down Expand Up @@ -967,8 +1013,6 @@ lm32_decoder decoder (
.csr_write_enable (csr_write_enable_d)
);

wire dtlb_miss_exception;

// Load/store unit
lm32_load_store_unit #(
.associativity (dcache_associativity),
Expand Down Expand Up @@ -1006,10 +1050,13 @@ lm32_load_store_unit #(
`ifdef CFG_IROM_ENABLED
.irom_data_m (irom_data_m),
`endif
`ifdef CFG_MMU_ENABLED
.csr (csr_x),
.csr_write_data (operand_1_x),
.csr_write_enable (csr_write_enable_q_x),
.eret_q_x (eret_q_x),
.csr_psw (lm32_csr_psw_reg),
`endif
// From Wishbone
.d_dat_i (D_DAT_I),
.d_ack_i (D_ACK_I),
Expand All @@ -1031,8 +1078,10 @@ lm32_load_store_unit #(
`endif
.load_data_w (load_data_w),
.stall_wb_load (stall_wb_load),
`ifdef CFG_MMU_ENABLED
.dtlb_miss (dtlb_miss_exception),
.csr_read_data (load_store_csr_read_data_x),
`endif
// To Wishbone
.d_dat_o (D_DAT_O),
.d_adr_o (D_ADR_O),
Expand Down Expand Up @@ -1771,7 +1820,7 @@ assign non_debug_exception_x = (system_call_exception == `TRUE)
)
`endif
`ifdef CFG_MMU_ENABLED
|| (dtlb_miss_exception == `TRUE)
|| (dtlb_miss_exception == `TRUE || itlb_miss_exception == `TRUE)
`endif
;

Expand All @@ -1797,7 +1846,7 @@ assign exception_x = (system_call_exception == `TRUE)
)
`endif
`ifdef CFG_MMU_ENABLED
|| (dtlb_miss_exception == `TRUE)
|| (dtlb_miss_exception == `TRUE || itlb_miss_exception == `TRUE)
`endif
;
`endif
Expand Down Expand Up @@ -1847,9 +1896,13 @@ begin
eid_x = `LM32_EID_INTERRUPT;
else
`endif
if (dtlb_miss_exception == `TRUE )
`ifdef CFG_MMU_ENABLED
if (dtlb_miss_exception == `TRUE)
eid_x = `LM32_EID_DTLB_MISS;
else if (itlb_miss_exception == `TRUE)
eid_x = `LM32_EID_ITLB_MISS;
else
`endif
eid_x = `LM32_EID_SCALL;
end

Expand Down Expand Up @@ -2144,11 +2197,69 @@ begin
`endif
`LM32_CSR_CFG2: csr_read_data_x = cfg2;
`LM32_CSR_TLB_VADDRESS: csr_read_data_x = load_store_csr_read_data_x;

`LM32_CSR_TLB_PADDRESS: csr_read_data_x = instruction_csr_read_data_x;
`LM32_CSR_PSW: csr_read_data_x = lm32_csr_psw_reg;
default: csr_read_data_x = {`LM32_WORD_WIDTH{1'bx}};
endcase
end

`ifdef CFG_MMU_ENABLED

always @(posedge clk_i `CFG_RESET_SENSITIVITY)
begin
if (rst_i)
begin
lm32_csr_psw_reg <= `LM32_WORD_WIDTH'h0;
end
else
begin
`ifdef CFG_DEBUG_ENABLED
if (non_debug_exception_q_w == `TRUE)
begin
// Save and then clear ITLB enable
lm32_csr_psw_reg[`LM32_CSR_PSW_EITLBE] <= lm32_csr_psw_reg[`LM32_CSR_PSW_ITLBE];
lm32_csr_psw_reg[`LM32_CSR_PSW_ITLBE] <= `FALSE;
end
else if (debug_exception_q_w == `TRUE)
begin
// Save and then clear TLB enable
lm32_csr_psw_reg[`LM32_CSR_PSW_BITLBE] <= lm32_csr_psw_reg[`LM32_CSR_PSW_ITLBE];
lm32_csr_psw_reg[`LM32_CSR_PSW_ITLBE] <= `FALSE;
end
`else
if (exception_q_w == `TRUE)
begin
// Save and then clear ITLB enable
lm32_csr_psw_reg[`LM32_CSR_PSW_EITLBE] <= lm32_csr_psw_reg[`LM32_CSR_PSW_ITLBE];
lm32_csr_psw_reg[`LM32_CSR_PSW_ITLBE] <= `FALSE;
end
`endif
else if (stall_x == `FALSE)
begin
if (eret_q_x == `TRUE)
// Restore ITLB enable
lm32_csr_psw_reg[`LM32_CSR_PSW_ITLBE] <= lm32_csr_psw_reg[`LM32_CSR_PSW_EITLBE];
`ifdef CFG_DEBUG_ENABLED
else if (bret_q_x == `TRUE)
// Restore ITLB enable
lm32_csr_psw_reg[`LM32_CSR_PSW_ITLBE] <= lm32_csr_psw_reg[`LM32_CSR_PSW_BITLBE];
`endif
else if (csr_write_enable_q_x == `TRUE)
begin
// Handle wcsr write
case (csr_x)
// operand_1_x is csr_write_data
`LM32_CSR_PSW:
lm32_csr_psw_reg <= operand_1_x;
`LM32_CSR_IE:
lm32_csr_psw_reg[2:0] <= operand_1_x[2:0];
endcase
end
end
end
end
`endif

/////////////////////////////////////////////////////
// Sequential Logic
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -2231,7 +2342,7 @@ begin
end
`endif

// Valid bits to indicate whether an instruction in a partcular pipeline stage is valid or not
// Valid bits to indicate whether an instruction in a particular pipeline stage is valid or not

`ifdef CFG_ICACHE_ENABLED
`ifdef CFG_DCACHE_ENABLED
Expand Down

0 comments on commit 70b5f48

Please sign in to comment.