Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: fallen/milkymist-mmu-simulation
base: 9ce4f23
...
head fork: fallen/milkymist-mmu-simulation
compare: 4e83927
  • 4 commits
  • 4 files changed
  • 0 commit comments
  • 1 contributor
Commits on Jun 01, 2012
Yann Sionneau Update ISim wave visualization window config file 229d711
Yann Sionneau Indent fix 94fc320
Yann Sionneau Cleaning code 1805080
Yann Sionneau Improve DTLB exceptions, add CSR to retrieve virtual addr causing a p…
…age fault

- Add a wcsr TLBCTRL bit to ask the TLB to invalidate a TLB entry
- Add a rcsr DTLBMA (DTLB Miss Address) using the same CSR id as DTLBVADDR
  allowing to retrieve the virtual address which caused a DTLB miss
- Improve DTLB exceptions to generate exceptions more reliably.
  exception_x is now asserted until exception_m is asserted as well
  preventing pipeline stalls to cancel exception propagation from
  stage X to stage M.
4e83927
Showing with 43 additions and 96 deletions.
  1. +2 −2 lm32_cpu.v
  2. +34 −63 lm32_dcache.v
  3. +2 −2 lm32_load_store_unit.v
  4. +5 −29 soc.wcfg
4 lm32_cpu.v
View
@@ -1850,7 +1850,7 @@ begin
if (dtlb_miss_exception == `TRUE )
eid_x = `LM32_EID_DTLB_MISS;
else
- eid_x = `LM32_EID_SCALL;
+ eid_x = `LM32_EID_SCALL;
end
// Stall generation
@@ -2143,7 +2143,7 @@ begin
`LM32_CSR_JRX: csr_read_data_x = jrx_csr_read_data;
`endif
`LM32_CSR_CFG2: csr_read_data_x = cfg2;
- `LM32_CSR_TLB_DBG: csr_read_data_x = load_store_csr_read_data_x;
+ `LM32_CSR_TLB_VADDRESS: csr_read_data_x = load_store_csr_read_data_x;
default: csr_read_data_x = {`LM32_WORD_WIDTH{1'bx}};
endcase
97 lm32_dcache.v
View
@@ -76,10 +76,11 @@
`define LM32_DC_STATE_CHECK 3'b010
`define LM32_DC_STATE_REFILL 3'b100
-`define LM32_DTLB_CTRL_FLUSH 4'h1
-`define LM32_DTLB_CTRL_UPDATE 4'h2
-`define LM32_TLB_CTRL_SWITCH_TO_KERNEL_MODE 4'h4
-`define LM32_TLB_CTRL_SWITCH_TO_USER_MODE 4'h8
+`define LM32_DTLB_CTRL_FLUSH 5'h1
+`define LM32_DTLB_CTRL_UPDATE 5'h2
+`define LM32_TLB_CTRL_SWITCH_TO_KERNEL_MODE 5'h4
+`define LM32_TLB_CTRL_SWITCH_TO_USER_MODE 5'h8
+`define LM32_TLB_CTRL_INVALIDATE_ENTRY 5'h10
`define LM32_TLB_STATE_CHECK 2'b01
`define LM32_TLB_STATE_FLUSH 2'b10
@@ -109,6 +110,7 @@ module lm32_dcache (
csr_write_enable,
exception_x,
eret_q_x,
+ exception_m,
// ----- Outputs -----
stall_request,
restart_request,
@@ -117,7 +119,7 @@ module lm32_dcache (
refilling,
load_data,
// To pipeline
- dtlb_miss_q,
+ dtlb_miss_int,
kernel_mode,
pa,
csr_read_data
@@ -137,7 +139,6 @@ parameter dtlb_sets = 1024; // Number of lines of DTLB
parameter page_size = 4096; // System page size
`define LM32_DTLB_IDX_RNG addr_dtlb_index_msb:addr_dtlb_index_lsb
-//`define LM32_DTLB_INVALID_TAG { {9{1'b1}}, `FALSE}
`define LM32_DTLB_ADDRESS_PFN_RNG addr_pfn_msb:addr_pfn_lsb
`define LM32_PAGE_OFFSET_RNG addr_page_offset_msb:addr_page_offset_lsb
`define LM32_DTLB_INVALID_ADDRESS { vpfn_width{1'b1} }
@@ -205,6 +206,7 @@ input [`LM32_CSR_RNG] csr; // CSR read/write index
input [`LM32_WORD_RNG] csr_write_data; // Data to write to specified CSR
input csr_write_enable; // CSR write enable
input exception_x; // An exception occured in the X stage
+input exception_m;
input eret_q_x;
/////////////////////////////////////////////////////
@@ -230,9 +232,7 @@ wire [`LM32_WORD_RNG] load_data;
output kernel_mode;
wire kernel_mode;
-output dtlb_miss_q;
-//output dtlb_miss;
-//output dtlb_miss_int;
+output dtlb_miss_int;
/////////////////////////////////////////////////////
// Internal nets and registers
@@ -293,8 +293,8 @@ reg [addr_dtlb_index_width-1:0] dtlb_update_set;
reg dtlb_flushing;
reg [addr_dtlb_index_width-1:0] dtlb_flush_set;
wire dtlb_miss;
-reg dtlb_miss_q = 0;
-reg dtlb_miss_int = 0;
+reg dtlb_miss_q = `FALSE;
+wire dtlb_miss_int;
reg [`LM32_WORD_RNG] dtlb_miss_addr;
wire dtlb_data_valid;
wire [`LM32_DTLB_LOOKUP_RANGE] dtlb_lookup;
@@ -464,8 +464,6 @@ end
generate
for (i = 0; i < associativity; i = i + 1)
begin : match
-// FIXME : We need to put physical address coming out from MMU instead of address_m[]
-//assign way_match[i] = ({way_tag[i], way_valid[i]} == {address_m[`LM32_DC_ADDR_TAG_RNG], `TRUE});
assign dtlb_read_tag = dtlb_read_data[`LM32_DTLB_TAG_RANGE];
assign dtlb_data_valid = dtlb_read_data[`LM32_DTLB_VALID_BIT];
@@ -473,18 +471,7 @@ assign dtlb_lookup = dtlb_read_data[`LM32_DTLB_LOOKUP_RANGE];
assign way_match[i] = (kernel_mode_reg == `LM32_KERNEL_MODE) ?
({way_tag[i], way_valid[i]} == {address_m[`LM32_DC_ADDR_TAG_RNG], `TRUE})
- : /*dtlb_data_valid && (dtlb_read_tag == address_m[`LM32_DC_ADDR_TAG_RNG]) &&
- */ ({way_tag[i], way_valid[i]} == {dtlb_lookup, `TRUE});
-
-/*always @(*)
-begin
- if (kernel_mode_reg == `LM32_KERNEL_MODE)
- way_match[i] <= ({way_tag[i], way_valid[i]} == {address_m[`LM32_DC_ADDR_TAG_RNG], `TRUE});
- else if (dtlb_read_tag == `LM32_DTLB_TAG_INVALID) // DTLB tag is invalid
- way_match[i] <= `FALSE;
- else
- way_match[i] <= ({way_tag[i], way_valid[i]} == {dtlb_read_data, `TRUE});
-end*/
+ : ({way_tag[i], way_valid[i]} == {dtlb_lookup, `TRUE});
end
endgenerate
@@ -554,20 +541,10 @@ assign dtlb_data_read_address = address_x[`LM32_DTLB_IDX_RNG];
assign dtlb_tag_read_address = address_x[`LM32_DTLB_IDX_RNG];
// tlb_update_address will receive data from a CSR register
-assign dtlb_data_write_address = /*(dtlb_flushing == `TRUE)
- ? dtlb_flush_set
- : */dtlb_update_vaddr_csr_reg[`LM32_DTLB_IDX_RNG];
-
-assign dtlb_tag_write_address = (dtlb_flushing == `TRUE)
- ? dtlb_flush_set
- : dtlb_update_vaddr_csr_reg[`LM32_DTLB_IDX_RNG];
+assign dtlb_data_write_address = dtlb_update_vaddr_csr_reg[`LM32_DTLB_IDX_RNG];
assign dtlb_data_read_port_enable = (stall_x == `FALSE) || !stall_m;
-assign dtlb_tag_read_port_enable = (stall_x == `FALSE) || !stall_m;
assign dtlb_write_port_enable = dtlb_updating || dtlb_flushing;
-assign dtlb_write_tag = (dtlb_flushing == `TRUE)
- ? `LM32_DTLB_TAG_INVALID
- : {dtlb_update_vaddr_csr_reg[30:22], `TRUE}; // 10-1 top VA bits
assign physical_address = (kernel_mode_reg == `LM32_KERNEL_MODE)
? address_m
@@ -613,7 +590,7 @@ assign tmem_write_data[`LM32_DC_TAGS_VALID_RNG] = ((last_refill == `TRUE) || (va
assign tmem_write_data[`LM32_DC_TAGS_TAG_RNG] = refill_address[`LM32_DC_ADDR_TAG_RNG];
// Signals that indicate which state we are in
-assign flushing = state[0]; //|| dtlb_miss;
+assign flushing = state[0];
assign check = state[1];
assign refill = state[2];
@@ -686,8 +663,6 @@ begin
end
else if (dflush == `TRUE)
state <= `LM32_DC_STATE_FLUSH;
-// else if (dtlb_miss == `TRUE)
-// refill_address <= physical_address;
end
// Refill a cache line
@@ -721,35 +696,24 @@ begin
end
end
-assign csr_read_data = latest_store_tlb_lookup;
+assign csr_read_data = dtlb_miss_addr;
assign dtlb_miss = (kernel_mode_reg == `LM32_USER_MODE) && (load_q_m || store_q_m) && ~(dtlb_data_valid);
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
begin
if (rst_i == `TRUE)
- dtlb_miss_int <= 0;
+ dtlb_miss_q <= `FALSE;
else
begin
- if (dtlb_miss)
- dtlb_miss_int <= 1;
- else
- dtlb_miss_int <= 0;
+ if (dtlb_miss && ~dtlb_miss_q)
+ dtlb_miss_q <= `TRUE;
+ else if (dtlb_miss_q && exception_m)
+ dtlb_miss_q <= `FALSE;
end
end
-always @(posedge clk_i `CFG_RESET_SENSITIVITY)
-begin
- if (rst_i == `TRUE)
- dtlb_miss_q <= 0;
- else
- begin
- if (dtlb_miss_int)
- dtlb_miss_q <= 1;
- else
- dtlb_miss_q <= 0;
- end
-end
+assign dtlb_miss_int = (dtlb_miss || dtlb_miss_q);
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
begin
@@ -771,17 +735,15 @@ begin
dtlb_flushing <= 0;
if (dtlb_miss == `TRUE)
begin
-// dtlb_flushing <= 0;
-// dtlb_flush_set <= address_m[addr_dtlb_index_width-1:0];
dtlb_miss_addr <= address_m;
- $display("ERROR : DTLB MISS on addr 0x%08X at time %t", address_m, $time);
+ $display("WARNING : DTLB MISS on addr 0x%08X at time %t", address_m, $time);
end
if (csr_write_enable && csr_write_data[0])
begin
// FIXME : test for kernel mode is removed for testing purposes ONLY
if (csr == `LM32_CSR_TLB_CTRL /*&& (kernel_mode_reg == `LM32_KERNEL_MODE)*/)
begin
- case (csr_write_data[4:1])
+ case (csr_write_data[5:1])
`LM32_DTLB_CTRL_FLUSH:
begin
dtlb_flushing <= 1;
@@ -794,6 +756,15 @@ begin
begin
dtlb_updating <= 1;
end
+
+ `LM32_TLB_CTRL_INVALIDATE_ENTRY:
+ begin
+ dtlb_flushing <= 1;
+ dtlb_flush_set <= dtlb_update_vaddr_csr_reg[`LM32_DTLB_IDX_RNG];
+ dtlb_updating <= 0;
+ dtlb_state <= `LM32_TLB_STATE_CHECK;
+ end
+
endcase
end
end
@@ -811,8 +782,8 @@ begin
end
end
-assign switch_to_kernel_mode = (csr_write_enable && (csr == `LM32_CSR_TLB_CTRL) && csr_write_data[4:0] == {`LM32_TLB_CTRL_SWITCH_TO_KERNEL_MODE, 1'b1});
-assign switch_to_user_mode = (csr_write_enable && (csr == `LM32_CSR_TLB_CTRL) && csr_write_data[4:0] == {`LM32_TLB_CTRL_SWITCH_TO_USER_MODE, 1'b1});
+assign switch_to_kernel_mode = (/*(kernel_mode_reg == `LM32_KERNEL_MODE) && */csr_write_enable && (csr == `LM32_CSR_TLB_CTRL) && csr_write_data[5:0] == {`LM32_TLB_CTRL_SWITCH_TO_KERNEL_MODE, 1'b1});
+assign switch_to_user_mode = (/*(kernel_mode_reg == `LM32_KERNEL_MODE) && */csr_write_enable && (csr == `LM32_CSR_TLB_CTRL) && csr_write_data[5:0] == {`LM32_TLB_CTRL_SWITCH_TO_USER_MODE, 1'b1});
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
4 lm32_load_store_unit.v
View
@@ -429,6 +429,7 @@ lm32_dcache #(
.csr_write_enable (csr_write_enable),
.exception_x (exception_x),
.eret_q_x (eret_q_x),
+ .exception_m (exception_m),
// ----- Outputs -----
.stall_request (dcache_stall_request),
.restart_request (dcache_restart_request),
@@ -436,8 +437,7 @@ lm32_dcache #(
.refill_address (dcache_refill_address),
.refilling (dcache_refilling),
.load_data (dcache_data_m),
-// .dtlb_miss (dtlb_miss),
- .dtlb_miss_q (dtlb_miss),
+ .dtlb_miss_int (dtlb_miss),
.kernel_mode (kernel_mode),
.pa (physical_address),
.csr_read_data (csr_read_data)
34 soc.wcfg
View
@@ -9,7 +9,7 @@
</top_modules>
</db_ref>
</db_ref_list>
- <WVObjectSize size="149" />
+ <WVObjectSize size="144" />
<wvobject fp_name="/soc/memadr" type="array" db_ref_id="1">
<obj_property name="ElementShortName">memadr[31:0]</obj_property>
<obj_property name="ObjectShortName">memadr[31:0]</obj_property>
@@ -413,13 +413,8 @@
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/dtlb_read_data" type="array" db_ref_id="1">
- <obj_property name="ElementShortName">dtlb_read_data[19:0]</obj_property>
- <obj_property name="ObjectShortName">dtlb_read_data[19:0]</obj_property>
- <obj_property name="Radix">HEXRADIX</obj_property>
- </wvobject>
- <wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/dtlb_read_tag" type="array" db_ref_id="1">
- <obj_property name="ElementShortName">dtlb_read_tag[9:0]</obj_property>
- <obj_property name="ObjectShortName">dtlb_read_tag[9:0]</obj_property>
+ <obj_property name="ElementShortName">dtlb_read_data[30:0]</obj_property>
+ <obj_property name="ObjectShortName">dtlb_read_data[30:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/dtlb_sets" type="array" db_ref_id="1">
@@ -431,38 +426,19 @@
<obj_property name="ElementShortName">dtlb_state[1:0]</obj_property>
<obj_property name="ObjectShortName">dtlb_state[1:0]</obj_property>
</wvobject>
- <wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/dtlb_tag_read_address" type="array" db_ref_id="1">
- <obj_property name="ElementShortName">dtlb_tag_read_address[9:0]</obj_property>
- <obj_property name="ObjectShortName">dtlb_tag_read_address[9:0]</obj_property>
- <obj_property name="Radix">HEXRADIX</obj_property>
- </wvobject>
- <wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/dtlb_tag_read_port_enable" type="logic" db_ref_id="1">
- <obj_property name="ElementShortName">dtlb_tag_read_port_enable</obj_property>
- <obj_property name="ObjectShortName">dtlb_tag_read_port_enable</obj_property>
- </wvobject>
- <wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/dtlb_tag_write_address" type="array" db_ref_id="1">
- <obj_property name="ElementShortName">dtlb_tag_write_address[9:0]</obj_property>
- <obj_property name="ObjectShortName">dtlb_tag_write_address[9:0]</obj_property>
- <obj_property name="Radix">HEXRADIX</obj_property>
- </wvobject>
<wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/dtlb_updating" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">dtlb_updating</obj_property>
<obj_property name="ObjectShortName">dtlb_updating</obj_property>
</wvobject>
<wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/dtlb_write_data" type="array" db_ref_id="1">
- <obj_property name="ElementShortName">dtlb_write_data[19:0]</obj_property>
- <obj_property name="ObjectShortName">dtlb_write_data[19:0]</obj_property>
+ <obj_property name="ElementShortName">dtlb_write_data[30:0]</obj_property>
+ <obj_property name="ObjectShortName">dtlb_write_data[30:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/dtlb_write_port_enable" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">dtlb_write_port_enable</obj_property>
<obj_property name="ObjectShortName">dtlb_write_port_enable</obj_property>
</wvobject>
- <wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/dtlb_write_tag" type="array" db_ref_id="1">
- <obj_property name="ElementShortName">dtlb_write_tag[9:0]</obj_property>
- <obj_property name="ObjectShortName">dtlb_write_tag[9:0]</obj_property>
- <obj_property name="Radix">HEXRADIX</obj_property>
- </wvobject>
<wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/flush_set" type="array" db_ref_id="1">
<obj_property name="ElementShortName">flush_set[7:0]</obj_property>
<obj_property name="ObjectShortName">flush_set[7:0]</obj_property>

No commit comments for this range

Something went wrong with that request. Please try again.