Skip to content
This repository
Browse code

Make DTLB generate exception uppon TLB miss

  • Loading branch information...
commit 43f6245f780d4b2c19122ba55ca759a358470d51 1 parent 8e87083
Yann Sionneau authored May 30, 2012
21  boards/milkymist-one/rtl/lm32_include.v
@@ -96,6 +96,8 @@
96 96
 `define CFG_WATCHPOINTS 32'h4
97 97
 `define CFG_EXTERNAL_BREAK_ENABLED
98 98
 `define CFG_GDBSTUB_ENABLED
  99
+//`define CFG_RANDOM_WISHBONE_LATENCY
  100
+//`define CFG_VERBOSE_DISPLAY_ENABLED
99 101
 
100 102
 // Enable MMU
101 103
 `define CFG_MMU_ENABLED
@@ -304,16 +306,17 @@
304 306
 `define LM32_WPC_C_READ_WRITE           2'b11
305 307
 
306 308
 // Exception IDs
307  
-`define LM32_EID_WIDTH                  3
  309
+`define LM32_EID_WIDTH                  4
308 310
 `define LM32_EID_RNG                    (`LM32_EID_WIDTH-1):0
309  
-`define LM32_EID_RESET                  3'h0
310  
-`define LM32_EID_BREAKPOINT             3'd1
311  
-`define LM32_EID_INST_BUS_ERROR         3'h2
312  
-`define LM32_EID_WATCHPOINT             3'd3
313  
-`define LM32_EID_DATA_BUS_ERROR         3'h4
314  
-`define LM32_EID_DIVIDE_BY_ZERO         3'h5
315  
-`define LM32_EID_INTERRUPT              3'h6
316  
-`define LM32_EID_SCALL                  3'h7
  311
+`define LM32_EID_RESET                  `LM32_EID_WIDTH'h0
  312
+`define LM32_EID_BREAKPOINT             `LM32_EID_WIDTH'd1
  313
+`define LM32_EID_INST_BUS_ERROR         `LM32_EID_WIDTH'h2
  314
+`define LM32_EID_WATCHPOINT             `LM32_EID_WIDTH'd3
  315
+`define LM32_EID_DATA_BUS_ERROR         `LM32_EID_WIDTH'h4
  316
+`define LM32_EID_DIVIDE_BY_ZERO         `LM32_EID_WIDTH'h5
  317
+`define LM32_EID_INTERRUPT              `LM32_EID_WIDTH'h6
  318
+`define LM32_EID_SCALL                  `LM32_EID_WIDTH'h7
  319
+`define LM32_EID_DTLB_MISS              `LM32_EID_WIDTH'h8
317 320
 
318 321
 // Pipeline result selection mux controls
319 322
 
25  cores/lm32/rtl/lm32_cpu.v
@@ -967,6 +967,8 @@ lm32_decoder decoder (
967 967
     .csr_write_enable       (csr_write_enable_d)
968 968
     ); 
969 969
 
  970
+wire dtlb_miss_exception;
  971
+
970 972
 // Load/store unit       
971 973
 lm32_load_store_unit #(
972 974
     .associativity          (dcache_associativity),
@@ -985,6 +987,7 @@ lm32_load_store_unit #(
985 987
     .kill_x                 (kill_x),
986 988
     .kill_m                 (kill_m),
987 989
     .exception_m            (exception_m),
  990
+    .exception_x            (exception_x),
988 991
     .store_operand_x        (store_operand_x),
989 992
     .load_store_address_x   (adder_result_x),
990 993
     .load_store_address_m   (operand_m),
@@ -1006,6 +1009,7 @@ lm32_load_store_unit #(
1006 1009
     .csr		    (csr_x),
1007 1010
     .csr_write_data         (operand_1_x),
1008 1011
     .csr_write_enable       (csr_write_enable_q_x),
  1012
+    .eret_q_x		    (eret_q_x),
1009 1013
     // From Wishbone
1010 1014
     .d_dat_i                (D_DAT_I),
1011 1015
     .d_ack_i                (D_ACK_I),
@@ -1027,7 +1031,7 @@ lm32_load_store_unit #(
1027 1031
 `endif
1028 1032
     .load_data_w            (load_data_w),
1029 1033
     .stall_wb_load          (stall_wb_load),
1030  
-    .dtlb_miss		    (dtlb_miss),
  1034
+    .dtlb_miss		    (dtlb_miss_exception),
1031 1035
     .csr_read_data          (load_store_csr_read_data_x),
1032 1036
     // To Wishbone
1033 1037
     .d_dat_o                (D_DAT_O),
@@ -1766,6 +1770,9 @@ assign non_debug_exception_x = (system_call_exception == `TRUE)
1766 1770
 `endif
1767 1771
                                )
1768 1772
 `endif
  1773
+`ifdef CFG_MMU_ENABLED
  1774
+			|| (dtlb_miss_exception == `TRUE)
  1775
+`endif
1769 1776
                             ;
1770 1777
 
1771 1778
 assign exception_x = (debug_exception_x == `TRUE) || (non_debug_exception_x == `TRUE);
@@ -1789,6 +1796,9 @@ assign exception_x =           (system_call_exception == `TRUE)
1789 1796
 `endif
1790 1797
                                )
1791 1798
 `endif
  1799
+`ifdef CFG_MMU_ENABLED
  1800
+			|| (dtlb_miss_exception == `TRUE)
  1801
+`endif
1792 1802
                             ;
1793 1803
 `endif
1794 1804
 
@@ -1837,7 +1847,10 @@ begin
1837 1847
         eid_x = `LM32_EID_INTERRUPT;
1838 1848
     else
1839 1849
 `endif
1840  
-        eid_x = `LM32_EID_SCALL;
  1850
+	if (dtlb_miss_exception == `TRUE )
  1851
+		eid_x = `LM32_EID_DTLB_MISS;
  1852
+	else
  1853
+		eid_x = `LM32_EID_SCALL;
1841 1854
 end
1842 1855
 
1843 1856
 // Stall generation
@@ -2557,13 +2570,15 @@ begin
2557 2570
 
2558 2571
 		 || ((debug_exception_x == `TRUE) 
2559 2572
 		     && (non_debug_exception_x == `FALSE)))
2560  
-	       branch_target_m <= {deba, eid_x, {3{1'b0}}};
  2573
+	       branch_target_m <= {deba[31:9], eid_x, {3{1'b0}}};
2561 2574
 	     else
2562  
-	       branch_target_m <= {eba, eid_x, {3{1'b0}}};
  2575
+	       branch_target_m <= {eba[31:9], eid_x, {3{1'b0}}};
2563 2576
 	   else
2564 2577
 	     branch_target_m <= branch_target_x;
2565 2578
 `else
2566  
-            branch_target_m <= exception_x == `TRUE ? {eba, eid_x, {3{1'b0}}} : branch_target_x;
  2579
+//if (exception_x == `TRUE)
  2580
+//	    $display("branch_target_m <= 0x%08X", branch_target_m);
  2581
+            branch_target_m <= exception_x == `TRUE ? {eba[31:9], eid_x, {3{1'b0}}} : branch_target_x;
2567 2582
 `endif
2568 2583
 `ifdef CFG_TRACE_ENABLED
2569 2584
             eid_m <= eid_x;
216  cores/lm32/rtl/lm32_dcache.v
@@ -76,10 +76,11 @@
76 76
 `define LM32_DC_STATE_CHECK              3'b010
77 77
 `define LM32_DC_STATE_REFILL             3'b100
78 78
 
79  
-`define LM32_DTLB_CTRL_FLUSH		 	4'h1
80  
-`define LM32_DTLB_CTRL_UPDATE		 	4'h2
81  
-`define LM32_TLB_CTRL_SWITCH_TO_KERNEL_MODE	4'h4
82  
-`define LM32_TLB_CTRL_SWITCH_TO_USER_MODE	4'h8
  79
+`define LM32_DTLB_CTRL_FLUSH		 	5'h1
  80
+`define LM32_DTLB_CTRL_UPDATE		 	5'h2
  81
+`define LM32_TLB_CTRL_SWITCH_TO_KERNEL_MODE	5'h4
  82
+`define LM32_TLB_CTRL_SWITCH_TO_USER_MODE	5'h8
  83
+`define LM32_TLB_CTRL_INVALIDATE_ENTRY		5'h10
83 84
 
84 85
 `define LM32_TLB_STATE_CHECK		 2'b01
85 86
 `define LM32_TLB_STATE_FLUSH		 2'b10
@@ -107,6 +108,8 @@ module lm32_dcache (
107 108
     csr,
108 109
     csr_write_data,
109 110
     csr_write_enable,
  111
+    exception_x,
  112
+    eret_q_x,
110 113
     // ----- Outputs -----
111 114
     stall_request,
112 115
     restart_request,
@@ -115,7 +118,7 @@ module lm32_dcache (
115 118
     refilling,
116 119
     load_data,
117 120
    // To pipeline
118  
-    dtlb_miss,
  121
+    dtlb_miss_q,
119 122
     kernel_mode,
120 123
     pa,
121 124
     csr_read_data
@@ -135,7 +138,7 @@ parameter dtlb_sets = 1024;				// Number of lines of DTLB
135 138
 parameter page_size = 4096;				// System page size
136 139
 
137 140
 `define LM32_DTLB_IDX_RNG		addr_dtlb_index_msb:addr_dtlb_index_lsb
138  
-`define LM32_DTLB_INVALID_TAG		{ {9{1'b1}}, `FALSE}
  141
+//`define LM32_DTLB_INVALID_TAG		{ {9{1'b1}}, `FALSE}
139 142
 `define LM32_DTLB_ADDRESS_PFN_RNG	addr_pfn_msb:addr_pfn_lsb
140 143
 `define LM32_PAGE_OFFSET_RNG		addr_page_offset_msb:addr_page_offset_lsb
141 144
 `define LM32_DTLB_INVALID_ADDRESS	{ vpfn_width{1'b1} }
@@ -153,6 +156,17 @@ localparam addr_dtlb_tag_lsb = addr_dtlb_index_msb + 1;
153 156
 localparam addr_dtlb_tag_msb = addr_dtlb_tag_lsb + addr_dtlb_tag_width - 1;
154 157
 
155 158
 `define LM32_DTLB_TAG_INVALID		{ addr_dtlb_tag_width{ 1'b0 } }
  159
+`define LM32_DTLB_LOOKUP_RANGE		vpfn_width-1:0
  160
+
  161
+/* The following define is the range containing the TAG inside the dtlb_read_data wire which contains the DTLB value from BlockRAM
  162
+ * Indeed dtlb_read_data contains { VALID_BIT, TAG_VALUE, LOOKUP_VALUE }
  163
+ * LM32_DTLB_TAG_RANGE is the range to extract the TAG_VALUE */
  164
+`define LM32_DTLB_TAG_RANGE		vpfn_width+addr_dtlb_tag_width-1:vpfn_width
  165
+
  166
+/* The following define is the range containing the TAG inside a memory address like dtlb_update_vaddr_csr_reg for instance. */
  167
+`define LM32_DTLB_ADDR_TAG_RNG		addr_dtlb_tag_msb:addr_dtlb_tag_lsb
  168
+`define LM32_DTLB_VALID_BIT		vpfn_width+addr_dtlb_tag_width
  169
+
156 170
 
157 171
 localparam addr_offset_width = clogb2(bytes_per_line)-1-2;
158 172
 localparam addr_set_width = clogb2(sets)-1;
@@ -191,13 +205,15 @@ input dflush;                                           // Indicates cache shoul
191 205
 input [`LM32_CSR_RNG] csr;				// CSR read/write index
192 206
 input [`LM32_WORD_RNG] csr_write_data;			// Data to write to specified CSR
193 207
 input csr_write_enable;					// CSR write enable
  208
+input exception_x;					// An exception occured in the X stage
  209
+input eret_q_x;
194 210
 
195 211
 /////////////////////////////////////////////////////
196 212
 // Outputs
197 213
 /////////////////////////////////////////////////////
198 214
 
199 215
 output csr_read_data;
200  
-reg [`LM32_WORD_RNG] csr_read_data;
  216
+wire [`LM32_WORD_RNG] csr_read_data;
201 217
 
202 218
 output stall_request;                                   // Request pipeline be stalled because cache is busy
203 219
 wire   stall_request;
@@ -215,7 +231,9 @@ wire   [`LM32_WORD_RNG] load_data;
215 231
 output kernel_mode;
216 232
 wire kernel_mode;
217 233
 
218  
-output dtlb_miss;
  234
+output dtlb_miss_q;
  235
+//output dtlb_miss;
  236
+//output dtlb_miss_int;
219 237
 
220 238
 /////////////////////////////////////////////////////
221 239
 // Internal nets and registers 
@@ -253,14 +271,9 @@ wire [addr_dtlb_index_width-1:0] dtlb_data_read_address;
253 271
 wire [addr_dtlb_index_width-1:0] dtlb_data_write_address;
254 272
 wire dtlb_data_read_port_enable;
255 273
 wire dtlb_write_port_enable;
256  
-wire [vpfn_width-1:0] dtlb_write_data;
257  
-wire [vpfn_width-1:0] dtlb_read_data;
258  
-
259  
-wire [addr_dtlb_index_width-1:0] dtlb_tag_read_address;
260  
-wire dtlb_tag_read_port_enable;
261  
-wire [addr_dtlb_index_width-1:0] dtlb_tag_write_address;
262  
-wire [9:0] dtlb_write_tag;
263  
-wire [9:0] dtlb_read_tag;
  274
+wire [vpfn_width + addr_dtlb_tag_width + 1 - 1:0] dtlb_write_data; // +1 is for valid_bit
  275
+wire [vpfn_width + addr_dtlb_tag_width + 1 - 1:0] dtlb_read_data; // +1 is for valid_bit
  276
+
264 277
 wire [`LM32_WORD_RNG] physical_address;
265 278
 
266 279
 wire [`LM32_WORD_RNG] pa;
@@ -270,6 +283,8 @@ reg [`LM32_WORD_RNG] latest_store_tlb_lookup;
270 283
 assign pa = physical_address;
271 284
 
272 285
 reg kernel_mode_reg = `LM32_KERNEL_MODE;
  286
+wire switch_to_kernel_mode;
  287
+wire switch_to_user_mode;
273 288
 reg [`LM32_WORD_RNG] dtlb_update_vaddr_csr_reg = `LM32_WORD_WIDTH'd0;
274 289
 reg [`LM32_WORD_RNG] dtlb_update_paddr_csr_reg = `LM32_WORD_WIDTH'd0;
275 290
 reg [1:0] dtlb_state = `LM32_TLB_STATE_CHECK;
@@ -278,8 +293,12 @@ reg dtlb_updating;
278 293
 reg [addr_dtlb_index_width-1:0] dtlb_update_set;
279 294
 reg dtlb_flushing;
280 295
 reg [addr_dtlb_index_width-1:0] dtlb_flush_set;
281  
-reg dtlb_miss;
  296
+wire dtlb_miss;
  297
+reg dtlb_miss_q = 0;
  298
+reg dtlb_miss_int = 0;
282 299
 reg [`LM32_WORD_RNG] dtlb_miss_addr;
  300
+wire dtlb_data_valid;
  301
+wire [`LM32_DTLB_LOOKUP_RANGE] dtlb_lookup;
283 302
 
284 303
 genvar i, j;
285 304
 
@@ -300,7 +319,7 @@ assign kernel_mode = kernel_mode_reg;
300 319
 lm32_ram 
301 320
   #(
302 321
     // ----- Parameters -------
303  
-    .data_width (vpfn_width),
  322
+    .data_width (vpfn_width + addr_dtlb_tag_width + 1),
304 323
     .address_width (addr_dtlb_index_width)
305 324
 // Modified for Milkymist: removed non-portable RAM parameters
306 325
     ) dtlb_data_ram 
@@ -319,37 +338,16 @@ lm32_ram
319 338
      .read_data (dtlb_read_data)
320 339
      );
321 340
 
  341
+`ifdef CFG_VERBOSE_DISPLAY_ENABLED
322 342
 always @(posedge clk_i)
323 343
 begin
324 344
 	if (dtlb_write_port_enable)
325 345
 	begin
326 346
 		$display("[DTLB data : %d] Writing 0x%08X to 0x%08X", $time, dtlb_write_data, dtlb_data_write_address);
327  
-		$display("[DTLB tag : %d] Writing 0x%08X to 0x%08X", $time, dtlb_write_tag, dtlb_tag_write_address);
328 347
 	end
329 348
 end
  349
+`endif
330 350
 
331  
-lm32_ram 
332  
-  #(
333  
-    // ----- Parameters -------
334  
-    .data_width (addr_dtlb_tag_width),
335  
-    .address_width (addr_dtlb_index_width)
336  
-// Modified for Milkymist: removed non-portable RAM parameters
337  
-    ) dtlb_tag_ram 
338  
-    (
339  
-     // ----- Inputs -------
340  
-     .read_clk (clk_i),
341  
-     .write_clk (clk_i),
342  
-     .reset (rst_i),
343  
-     .read_address (dtlb_tag_read_address),
344  
-     .enable_read (dtlb_tag_read_port_enable),
345  
-     .write_address (dtlb_tag_write_address),
346  
-     .enable_write (`TRUE),
347  
-     .write_enable (dtlb_write_port_enable),
348  
-     .write_data (dtlb_write_tag),    
349  
-     // ----- Outputs -------
350  
-     .read_data (dtlb_read_tag)
351  
-     );
352  
-    
353 351
    generate
354 352
       for (i = 0; i < associativity; i = i + 1)    
355 353
 	begin : memories
@@ -437,21 +435,32 @@ lm32_ram
437 435
 /////////////////////////////////////////////////////
438 436
 
439 437
 // CSR Write
440  
-always @(posedge clk_i)
  438
+always @(posedge clk_i `CFG_RESET_SENSITIVITY)
441 439
 begin
442  
-	if (csr_write_enable)
  440
+	if (rst_i == `TRUE)
443 441
 	begin
444  
-		case (csr)
445  
-		`LM32_CSR_TLB_CTRL:	if (csr_write_data[0]) dtlb_ctrl_csr_reg[31:1] <= csr_write_data[31:1];
446  
-		`LM32_CSR_TLB_VADDRESS: if (csr_write_data[0]) dtlb_update_vaddr_csr_reg[31:1] <= csr_write_data[31:1];
447  
-		`LM32_CSR_TLB_PADDRESS: if (csr_write_data[0]) dtlb_update_paddr_csr_reg[31:1] <= csr_write_data[31:1];
448  
-		endcase
  442
+		dtlb_ctrl_csr_reg <= `LM32_WORD_WIDTH'd0;
  443
+		dtlb_update_vaddr_csr_reg <= `LM32_WORD_WIDTH'd0;
  444
+		dtlb_update_paddr_csr_reg <= `LM32_WORD_WIDTH'd0;
  445
+	end
  446
+	else
  447
+	begin
  448
+		if (csr_write_enable)
  449
+		begin
  450
+			case (csr)
  451
+			`LM32_CSR_TLB_CTRL:	if (csr_write_data[0]) dtlb_ctrl_csr_reg[31:1] <= csr_write_data[31:1];
  452
+			`LM32_CSR_TLB_VADDRESS: if (csr_write_data[0]) dtlb_update_vaddr_csr_reg[31:1] <= csr_write_data[31:1];
  453
+			`LM32_CSR_TLB_PADDRESS: if (csr_write_data[0]) dtlb_update_paddr_csr_reg[31:1] <= csr_write_data[31:1];
  454
+			endcase
  455
+		end
  456
+		dtlb_ctrl_csr_reg[0] <= 0;
  457
+		dtlb_update_vaddr_csr_reg[0] <= 0;
  458
+		dtlb_update_paddr_csr_reg[0] <= 0;
449 459
 	end
450  
-	dtlb_ctrl_csr_reg[0] <= 0;
451  
-	dtlb_update_vaddr_csr_reg[0] <= 0;
452  
-	dtlb_update_paddr_csr_reg[0] <= 0;
453 460
 end
454 461
 
  462
+
  463
+
455 464
 // Compute which ways in the cache match the address being read
456 465
 generate
457 466
     for (i = 0; i < associativity; i = i + 1)
@@ -459,11 +468,14 @@ generate
459 468
 // FIXME : We need to put physical address coming out from MMU instead of address_m[]
460 469
 //assign way_match[i] = ({way_tag[i], way_valid[i]} == {address_m[`LM32_DC_ADDR_TAG_RNG], `TRUE});
461 470
 
  471
+assign dtlb_read_tag = dtlb_read_data[`LM32_DTLB_TAG_RANGE];
  472
+assign dtlb_data_valid = dtlb_read_data[`LM32_DTLB_VALID_BIT];
  473
+assign dtlb_lookup = dtlb_read_data[`LM32_DTLB_LOOKUP_RANGE];
  474
+
462 475
 assign way_match[i] = (kernel_mode_reg == `LM32_KERNEL_MODE) ?
463 476
 		      ({way_tag[i], way_valid[i]} == {address_m[`LM32_DC_ADDR_TAG_RNG], `TRUE})
464  
-		      : (dtlb_read_tag == `LM32_DTLB_TAG_INVALID) ?
465  
-		      `FALSE
466  
-		      : ({way_tag[i], way_valid[i]} == {dtlb_read_data, `TRUE});
  477
+		      : /*dtlb_data_valid && (dtlb_read_tag == address_m[`LM32_DC_ADDR_TAG_RNG]) && 
  478
+		     */ ({way_tag[i], way_valid[i]} == {dtlb_lookup, `TRUE});
467 479
 
468 480
 /*always @(*)
469 481
 begin
@@ -552,19 +564,15 @@ assign dtlb_tag_write_address = (dtlb_flushing == `TRUE)
552 564
 				: dtlb_update_vaddr_csr_reg[`LM32_DTLB_IDX_RNG];
553 565
 
554 566
 assign dtlb_data_read_port_enable = (stall_x == `FALSE) || !stall_m;
555  
-assign dtlb_tag_read_port_enable = (stall_x == `FALSE) || !stall_m;
556 567
 assign dtlb_write_port_enable = dtlb_updating || dtlb_flushing;
557  
-assign dtlb_write_tag = (dtlb_flushing == `TRUE)
558  
-			? `LM32_DTLB_INVALID_TAG
559  
-			: {dtlb_update_vaddr_csr_reg[30:22], `TRUE}; // 10-1 top VA bits
560 568
 
561 569
 assign physical_address = (kernel_mode_reg == `LM32_KERNEL_MODE)
562 570
 			    ? address_m
563  
-			    : { dtlb_read_data , address_m[`LM32_PAGE_OFFSET_RNG] };
  571
+			    : {dtlb_lookup, address_m[`LM32_PAGE_OFFSET_RNG]};
564 572
 
565 573
 assign dtlb_write_data = (dtlb_flushing == `TRUE)
566  
-			 ? `LM32_DTLB_INVALID_ADDRESS
567  
-			 : dtlb_update_paddr_csr_reg[`LM32_DTLB_ADDRESS_PFN_RNG];
  574
+			 ? {`FALSE, {addr_dtlb_tag_width{1'b0}}, {vpfn_width{1'b0}}}
  575
+			 : {`TRUE, {dtlb_update_vaddr_csr_reg[`LM32_DTLB_ADDR_TAG_RNG]}, dtlb_update_paddr_csr_reg[`LM32_DTLB_ADDRESS_PFN_RNG]};
568 576
 
569 577
 // Compute signal to indicate when we are on the last refill accesses
570 578
 generate 
@@ -602,11 +610,11 @@ assign tmem_write_data[`LM32_DC_TAGS_VALID_RNG] = ((last_refill == `TRUE) || (va
602 610
 assign tmem_write_data[`LM32_DC_TAGS_TAG_RNG] = refill_address[`LM32_DC_ADDR_TAG_RNG];
603 611
 
604 612
 // Signals that indicate which state we are in
605  
-assign flushing = state[0];
  613
+assign flushing = state[0]; //|| dtlb_miss;
606 614
 assign check = state[1];
607 615
 assign refill = state[2];
608 616
 
609  
-assign miss = (~(|way_match)) && (load_q_m == `TRUE) && (stall_m == `FALSE);
  617
+assign miss = (~(|way_match)) && (load_q_m == `TRUE) && (stall_m == `FALSE) && (~dtlb_miss);
610 618
 assign stall_request = (check == `FALSE) || (dtlb_state == `LM32_TLB_STATE_FLUSH && kernel_mode_reg != `LM32_KERNEL_MODE);
611 619
                       
612 620
 /////////////////////////////////////////////////////
@@ -675,6 +683,8 @@ begin
675 683
             end
676 684
             else if (dflush == `TRUE)
677 685
                 state <= `LM32_DC_STATE_FLUSH;
  686
+//           else if (dtlb_miss == `TRUE)
  687
+//		refill_address <= physical_address;
678 688
         end
679 689
 
680 690
         // Refill a cache line
@@ -697,15 +707,45 @@ end
697 707
 
698 708
 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
699 709
 begin
700  
-	if (write_port_enable && (|way_dmem_we))
  710
+	if (rst_i == `TRUE)
  711
+		latest_store_tlb_lookup <= `LM32_WORD_WIDTH'd0;
  712
+	else
701 713
 	begin
702  
-		latest_store_tlb_lookup <= { dtlb_read_data , address_m[`LM32_PAGE_OFFSET_RNG] };
  714
+		if (write_port_enable && (|way_dmem_we))
  715
+		begin
  716
+			latest_store_tlb_lookup <= {dtlb_lookup, address_m[`LM32_PAGE_OFFSET_RNG]};
  717
+		end
703 718
 	end
704 719
 end
705 720
 
706  
-always @(*)
  721
+assign csr_read_data = latest_store_tlb_lookup;
  722
+
  723
+assign dtlb_miss = (kernel_mode_reg == `LM32_USER_MODE) && (load_q_m || store_q_m) && ~(dtlb_data_valid);
  724
+
  725
+always @(posedge clk_i `CFG_RESET_SENSITIVITY)
  726
+begin
  727
+	if (rst_i == `TRUE)
  728
+		dtlb_miss_int <= 0;
  729
+	else
  730
+	begin
  731
+		if (dtlb_miss)
  732
+			dtlb_miss_int <= 1;
  733
+		else
  734
+			dtlb_miss_int <= 0;
  735
+	end
  736
+end
  737
+
  738
+always @(posedge clk_i `CFG_RESET_SENSITIVITY)
707 739
 begin
708  
-	csr_read_data <= latest_store_tlb_lookup;
  740
+	if (rst_i == `TRUE)
  741
+		dtlb_miss_q <= 0;
  742
+	else
  743
+	begin
  744
+		if (dtlb_miss_int)
  745
+			dtlb_miss_q <= 1;
  746
+		else
  747
+			dtlb_miss_q <= 0;
  748
+	end
709 749
 end
710 750
 
711 751
 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
@@ -716,6 +756,7 @@ begin
716 756
 		dtlb_flush_set <= {addr_dtlb_index_width{1'b1}};
717 757
 		dtlb_state <= `LM32_TLB_STATE_FLUSH;
718 758
 		dtlb_updating <= 0;
  759
+		dtlb_miss_addr <= `LM32_WORD_WIDTH'd0;
719 760
 	end
720 761
 	else
721 762
 	begin
@@ -725,19 +766,19 @@ begin
725 766
 		begin
726 767
 			dtlb_updating <= 0;
727 768
 			dtlb_flushing <= 0;
728  
-			if ((dtlb_miss == `TRUE) && (kernel_mode_reg == `LM32_KERNEL_MODE))
  769
+			if (dtlb_miss == `TRUE)
729 770
 			begin
730  
-				// FIXME : We need to generate an exception
  771
+//				dtlb_flushing <= 0;
  772
+//				dtlb_flush_set <= address_m[addr_dtlb_index_width-1:0];
731 773
 				dtlb_miss_addr <= address_m;
732  
-				dtlb_updating <= 0;
733  
-				$display("ERROR : DTLB MISS on addr 0x%08X", address_m);
  774
+				$display("ERROR : DTLB MISS on addr 0x%08X at time %t", address_m, $time);
734 775
 			end
735  
-			else if (csr_write_enable && csr_write_data[0])
  776
+			if (csr_write_enable && csr_write_data[0])
736 777
 			begin
737 778
 				// FIXME : test for kernel mode is removed for testing purposes ONLY
738 779
 				if (csr == `LM32_CSR_TLB_CTRL /*&& (kernel_mode_reg == `LM32_KERNEL_MODE)*/)
739 780
 				begin
740  
-					case (csr_write_data[4:1])
  781
+					case (csr_write_data[5:1])
741 782
 					`LM32_DTLB_CTRL_FLUSH:
742 783
 					begin
743 784
 						dtlb_flushing <= 1;
@@ -750,17 +791,13 @@ begin
750 791
 					begin
751 792
 						dtlb_updating <= 1;
752 793
 					end
753  
-					// FIXME : This is for testing purposes ONLY
754  
-					`LM32_TLB_CTRL_SWITCH_TO_KERNEL_MODE:
755  
-					begin
756  
-						kernel_mode_reg <= `LM32_KERNEL_MODE;
757  
-						dtlb_updating <= 0;
758  
-					end
759 794
 
760  
-					`LM32_TLB_CTRL_SWITCH_TO_USER_MODE:
  795
+					`LM32_TLB_CTRL_INVALIDATE_ENTRY:
761 796
 					begin
762  
-						kernel_mode_reg <= `LM32_USER_MODE;
  797
+						dtlb_flushing <= 1;
  798
+						dtlb_flush_set <= dtlb_update_vaddr_csr_reg[`LM32_DTLB_IDX_RNG];
763 799
 						dtlb_updating <= 0;
  800
+						dtlb_state <= `LM32_TLB_STATE_CHECK;
764 801
 					end
765 802
 
766 803
 					endcase
@@ -780,6 +817,23 @@ begin
780 817
 	end
781 818
 end
782 819
 
  820
+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});
  821
+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});
  822
+
  823
+
  824
+always @(posedge clk_i `CFG_RESET_SENSITIVITY)
  825
+begin
  826
+	if (rst_i == `TRUE)
  827
+		kernel_mode_reg <= `LM32_KERNEL_MODE;
  828
+	else
  829
+	begin
  830
+		if (/*exception_x || */switch_to_kernel_mode)
  831
+			kernel_mode_reg <= `LM32_KERNEL_MODE;
  832
+		else if (/*eret_q_x || */switch_to_user_mode)
  833
+			kernel_mode_reg <= `LM32_USER_MODE;
  834
+	end
  835
+end
  836
+
783 837
 generate
784 838
     if (bytes_per_line > 4)
785 839
     begin
28  cores/lm32/rtl/lm32_load_store_unit.v
@@ -80,6 +80,7 @@ module lm32_load_store_unit (
80 80
     kill_x,
81 81
     kill_m,
82 82
     exception_m,
  83
+    exception_x,
83 84
     store_operand_x,
84 85
     load_store_address_x,
85 86
     load_store_address_m,
@@ -101,6 +102,7 @@ module lm32_load_store_unit (
101 102
     csr,
102 103
     csr_write_data,
103 104
     csr_write_enable,
  105
+    eret_q_x,
104 106
     // From Wishbone
105 107
     d_dat_i,
106 108
     d_ack_i,
@@ -164,6 +166,9 @@ input stall_m;                                          // M stage stall
164 166
 input kill_x;                                           // Kill instruction in X stage
165 167
 input kill_m;                                           // Kill instruction in M stage
166 168
 input exception_m;                                      // An exception occured in the M stage
  169
+input exception_x;                                      // An exception occured in the X stage
  170
+input eret_q_x;
  171
+
167 172
 
168 173
 input [`LM32_CSR_RNG] csr;				// CSR read/write index
169 174
 input [`LM32_WORD_RNG] csr_write_data;			// Data to write to specified CSR
@@ -191,7 +196,8 @@ input dflush;                                           // Flush the data cache
191 196
 input [`LM32_WORD_RNG] irom_data_m;                     // Data from Instruction-ROM
192 197
 `endif
193 198
 
194  
-input dtlb_miss;
  199
+wire dtlb_miss;
  200
+output dtlb_miss;
195 201
 
196 202
 input [`LM32_WORD_RNG] d_dat_i;                         // Data Wishbone interface read data
197 203
 input d_ack_i;                                          // Data Wishbone interface acknowledgement
@@ -273,6 +279,7 @@ reg dcache_select_m;
273 279
 wire [`LM32_WORD_RNG] dcache_data_m;                    // Data read from cache
274 280
 wire [`LM32_WORD_RNG] dcache_refill_address;            // Address to refill data cache from
275 281
 reg dcache_refill_ready;                                // Indicates the next word of refill data is ready
  282
+reg d_adr_o_sampling;
276 283
 wire [`LM32_CTYPE_RNG] first_cycle_type;                // First Wishbone cycle type
277 284
 wire [`LM32_CTYPE_RNG] next_cycle_type;                 // Next Wishbone cycle type
278 285
 wire last_word;                                         // Indicates if this is the last word in the cache line
@@ -420,6 +427,8 @@ lm32_dcache #(
420 427
     .csr		    (csr),
421 428
     .csr_write_data	    (csr_write_data),
422 429
     .csr_write_enable	    (csr_write_enable),
  430
+    .exception_x	    (exception_x),
  431
+    .eret_q_x		    (eret_q_x),
423 432
     // ----- Outputs -----
424 433
     .stall_request          (dcache_stall_request),
425 434
     .restart_request        (dcache_restart_request),
@@ -427,7 +436,8 @@ lm32_dcache #(
427 436
     .refill_address         (dcache_refill_address),
428 437
     .refilling              (dcache_refilling),
429 438
     .load_data              (dcache_data_m),
430  
-    .dtlb_miss		    (dtlb_miss),
  439
+//    .dtlb_miss		    (dtlb_miss),
  440
+    .dtlb_miss_q	    (dtlb_miss),
431 441
     .kernel_mode	    (kernel_mode),
432 442
     .pa			    (physical_address),
433 443
     .csr_read_data	    (csr_read_data)
@@ -654,6 +664,7 @@ always @(posedge clk_i `CFG_RESET_SENSITIVITY)
654 664
 begin
655 665
     if (rst_i == `TRUE)
656 666
     begin
  667
+        d_adr_o_sampling <= `FALSE;
657 668
         d_cyc_o <= `FALSE;
658 669
         d_stb_o <= `FALSE;
659 670
         d_dat_o <= {`LM32_WORD_WIDTH{1'b0}};
@@ -690,6 +701,7 @@ begin
690 701
                 else
691 702
 `endif                
692 703
                 begin
  704
+		    d_adr_o_sampling <= 0;
693 705
                     // Refill/access complete
694 706
                     d_cyc_o <= `FALSE;
695 707
                     d_stb_o <= `FALSE;
@@ -716,6 +728,10 @@ begin
716 728
             if (dcache_refill_request == `TRUE)
717 729
             begin
718 730
                 // Start cache refill
  731
+`ifdef CFG_VERBOSE_DISPLAY_ENABLED
  732
+		$display("Sampling address to refill 0x%08X\n", first_address);
  733
+`endif
  734
+		d_adr_o_sampling <= 1;
719 735
                 d_adr_o <= first_address;
720 736
                 d_cyc_o <= `TRUE;
721 737
                 d_sel_o <= {`LM32_WORD_WIDTH/8{`TRUE}};
@@ -737,6 +753,10 @@ begin
737 753
                     )
738 754
             begin
739 755
                 // Data cache is write through, so all stores go to memory
  756
+`ifdef CFG_VERBOSE_DISPLAY_ENABLED
  757
+		$display("Sampling address to write through 0x%08X\n", store_data_m);
  758
+`endif
  759
+		d_adr_o_sampling <= 1;
740 760
                 d_dat_o <= store_data_m;
741 761
                 d_adr_o <= (kernel_mode == `LM32_KERNEL_MODE) ? load_store_address_m : physical_address;
742 762
                 d_cyc_o <= `TRUE;
@@ -752,6 +772,10 @@ begin
752 772
                     )
753 773
             begin
754 774
                 // Read requested address
  775
+`ifdef CFG_VERBOSE_DISPLAY_ENABLED
  776
+		$display("Sampling address to read 0x%08X\n", (kernel_mode == `LM32_KERNEL_MODE) ? load_store_address_m : physical_address);
  777
+`endif
  778
+		d_adr_o_sampling <= 1;
755 779
                 stall_wb_load <= `FALSE;
756 780
                 d_adr_o <= (kernel_mode == `LM32_KERNEL_MODE) ? load_store_address_m : physical_address;
757 781
                 d_cyc_o <= `TRUE;

0 notes on commit 43f6245

Please sign in to comment.
Something went wrong with that request. Please try again.