Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: fallen/milkymist-mmu-simulation
base: 9ce4f23
...
head fork: fallen/milkymist-mmu-simulation
compare: 4e83927
Checking mergeability… Don't worry, you can still create the pull request.
  • 4 commits
  • 4 files changed
  • 0 commit comments
  • 1 contributor
Commits on Jun 01, 2012
@fallen Update ISim wave visualization window config file 229d711
@fallen Indent fix 94fc320
@fallen Cleaning code 1805080
@fallen 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
View
4 lm32_cpu.v
@@ -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
View
97 lm32_dcache.v
@@ -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)
View
4 lm32_load_store_unit.v
@@ -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)
View
34 soc.wcfg
@@ -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.