Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: fallen/milkymist-mmu-simulation
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 720786ee0aab
Choose a base ref
...
head repository: fallen/milkymist-mmu-simulation
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 062e9999d9e4
Choose a head ref
  • 2 commits
  • 4 files changed
  • 1 contributor

Commits on Jul 19, 2012

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    671a19e View commit details
  2. Add correct implementation of itlb_enabled to allow branching to virt…

    …ual address right after ITLB is enabled
    fallen committed Jul 19, 2012
    Copy the full SHA
    062e999 View commit details
Showing with 80 additions and 8 deletions.
  1. +24 −0 lm32_cpu.v
  2. +20 −3 lm32_icache.v
  3. +1 −0 lm32_include.v
  4. +35 −5 lm32_instruction_unit.v
24 changes: 24 additions & 0 deletions lm32_cpu.v
Original file line number Diff line number Diff line change
@@ -630,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
@@ -866,6 +887,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),
23 changes: 20 additions & 3 deletions lm32_icache.v
Original file line number Diff line number Diff line change
@@ -107,6 +107,9 @@ module lm32_icache (
rst_i,
stall_a,
stall_f,
`ifdef CFG_MMU_ENABLED
stall_x,
`endif
address_a,
address_f,
read_enable_f,
@@ -210,6 +213,7 @@ input rst_i; // Reset

input stall_a; // Stall instruction in A stage
input stall_f; // Stall instruction in F stage
input stall_x; // Stall instruction in X stage

input valid_d; // Valid instruction in D stage
input branch_predict_taken_d; // Instruction in D stage is a branch and is predicted taken
@@ -326,7 +330,7 @@ wire itlb_data_valid;
wire [`LM32_ITLB_LOOKUP_RANGE] itlb_lookup;
reg go_to_user_mode;
reg go_to_user_mode_2;
wire itlb_enabled;
reg itlb_enabled;

`endif

@@ -656,8 +660,6 @@ endgenerate

`ifdef CFG_MMU_ENABLED

assign itlb_enabled = csr_psw[`LM32_CSR_PSW_ITLBE];

// Compute address to use to index into the ITLB data memory
assign itlb_data_read_address = address_a[`LM32_ITLB_IDX_RNG];

@@ -762,6 +764,21 @@ begin
end
end

always @(posedge clk_i `CFG_RESET_SENSITIVITY)
begin
if (rst_i == `TRUE)
begin
itlb_enabled <= `FALSE;
end
else
begin
if (~stall_x)
begin
itlb_enabled <= csr_psw[`LM32_CSR_PSW_ITLBE];
end
end
end

always @(posedge clk_i `CFG_RESET_SENSITIVITY)
begin
if (rst_i == `TRUE)
1 change: 1 addition & 0 deletions lm32_include.v
Original file line number Diff line number Diff line change
@@ -98,6 +98,7 @@
//`define CFG_GDBSTUB_ENABLED
`define CFG_RANDOM_WISHBONE_LATENCY
//`define CFG_VERBOSE_DISPLAY_ENABLED
//`define CFG_PIPELINE_TRACES
`define CFG_UART_ENABLED

// Enable MMU
40 changes: 35 additions & 5 deletions lm32_instruction_unit.v
Original file line number Diff line number Diff line change
@@ -139,6 +139,9 @@ module lm32_instruction_unit (
`endif
// ----- Outputs -------
// To pipeline
`ifdef CFG_PIPELINE_TRACES
pc_a,
`endif
pc_f,
pc_d,
pc_x,
@@ -362,6 +365,9 @@ wire itlb_miss;
/////////////////////////////////////////////////////

reg [`LM32_PC_RNG] pc_a; // A stage PC
`ifdef CFG_PIPELINE_TRACES
output [`LM32_PC_RNG] pc_a;
`endif

`ifdef LM32_CACHE_ENABLED
reg [`LM32_PC_RNG] restart_address; // Address to restart from after a cache miss
@@ -484,6 +490,9 @@ lm32_icache #(
.rst_i (rst_i),
.stall_a (stall_a),
.stall_f (stall_f),
`ifdef CFG_MMU_ENABLED
.stall_x (stall_x),
`endif
.branch_predict_taken_d (branch_predict_taken_d),
.valid_d (valid_d),
.address_a (pc_a),
@@ -543,27 +552,48 @@ begin
// The request from the latest pipeline stage must take priority
`ifdef CFG_DCACHE_ENABLED
if (dcache_restart_request == `TRUE)
begin
`ifdef CFG_PIPELINE_TRACES
$display("[%t] We restart to 0x%08X because of DCACHE", $time, restart_address);
`endif
pc_a = restart_address;
end
else
`endif
if (branch_taken_m == `TRUE)
if ((branch_mispredict_taken_m == `TRUE) && (exception_m == `FALSE))
begin
`ifdef CFG_PIPELINE_TRACES
$display("[%t] Mispredict, goto pc_x == 0x%08X", $time, pc_x);
`endif
pc_a = pc_x;
end
else
pc_a = branch_target_m;
`ifdef CFG_FAST_UNCONDITIONAL_BRANCH
else if (branch_taken_x == `TRUE)
pc_a = branch_target_x;
begin
`ifdef CFG_PIPELINE_TRACES
$display("[%t] Correctly predicted, goto branch_target_m == 0x%08X", $time, branch_target_m);
`endif
pc_a = branch_target_m;
end
else
if ( (valid_d == `TRUE) && (branch_predict_taken_d == `TRUE) )
begin
`ifdef CFG_PIPELINE_TRACES
$display("[%t] We go to branch_predict_address_d == 0x%08X", $time, branch_predict_address_d);
`endif
pc_a = branch_predict_address_d;
end
else
`ifdef CFG_ICACHE_ENABLED
if (icache_restart_request == `TRUE)
begin
`ifdef CFG_PIPELINE_TRACES
$display("[%t] We restart to 0x%08X because of ICACHE", $time, restart_address);
`endif
pc_a = restart_address;
end
else
`endif
`endif
pc_a = pc_f + 1'b1;
end