Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 4 commits
  • 4 files changed
  • 0 comments
  • 1 contributor
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
4  lm32_cpu.v
@@ -1850,7 +1850,7 @@ begin
1850 1850
 	if (dtlb_miss_exception == `TRUE )
1851 1851
 		eid_x = `LM32_EID_DTLB_MISS;
1852 1852
 	else
1853  
-        	eid_x = `LM32_EID_SCALL;
  1853
+		eid_x = `LM32_EID_SCALL;
1854 1854
 end
1855 1855
 
1856 1856
 // Stall generation
@@ -2143,7 +2143,7 @@ begin
2143 2143
     `LM32_CSR_JRX:  csr_read_data_x = jrx_csr_read_data;
2144 2144
 `endif
2145 2145
     `LM32_CSR_CFG2: csr_read_data_x = cfg2;
2146  
-    `LM32_CSR_TLB_DBG: csr_read_data_x = load_store_csr_read_data_x;
  2146
+    `LM32_CSR_TLB_VADDRESS: csr_read_data_x = load_store_csr_read_data_x;
2147 2147
       
2148 2148
     default:        csr_read_data_x = {`LM32_WORD_WIDTH{1'bx}};
2149 2149
     endcase
97  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
@@ -109,6 +110,7 @@ module lm32_dcache (
109 110
     csr_write_enable,
110 111
     exception_x,
111 112
     eret_q_x,
  113
+    exception_m,
112 114
     // ----- Outputs -----
113 115
     stall_request,
114 116
     restart_request,
@@ -117,7 +119,7 @@ module lm32_dcache (
117 119
     refilling,
118 120
     load_data,
119 121
    // To pipeline
120  
-    dtlb_miss_q,
  122
+    dtlb_miss_int,
121 123
     kernel_mode,
122 124
     pa,
123 125
     csr_read_data
@@ -137,7 +139,6 @@ parameter dtlb_sets = 1024;				// Number of lines of DTLB
137 139
 parameter page_size = 4096;				// System page size
138 140
 
139 141
 `define LM32_DTLB_IDX_RNG		addr_dtlb_index_msb:addr_dtlb_index_lsb
140  
-//`define LM32_DTLB_INVALID_TAG		{ {9{1'b1}}, `FALSE}
141 142
 `define LM32_DTLB_ADDRESS_PFN_RNG	addr_pfn_msb:addr_pfn_lsb
142 143
 `define LM32_PAGE_OFFSET_RNG		addr_page_offset_msb:addr_page_offset_lsb
143 144
 `define LM32_DTLB_INVALID_ADDRESS	{ vpfn_width{1'b1} }
@@ -205,6 +206,7 @@ input [`LM32_CSR_RNG] csr;				// CSR read/write index
205 206
 input [`LM32_WORD_RNG] csr_write_data;			// Data to write to specified CSR
206 207
 input csr_write_enable;					// CSR write enable
207 208
 input exception_x;					// An exception occured in the X stage
  209
+input exception_m;
208 210
 input eret_q_x;
209 211
 
210 212
 /////////////////////////////////////////////////////
@@ -230,9 +232,7 @@ wire   [`LM32_WORD_RNG] load_data;
230 232
 output kernel_mode;
231 233
 wire kernel_mode;
232 234
 
233  
-output dtlb_miss_q;
234  
-//output dtlb_miss;
235  
-//output dtlb_miss_int;
  235
+output dtlb_miss_int;
236 236
 
237 237
 /////////////////////////////////////////////////////
238 238
 // Internal nets and registers 
@@ -293,8 +293,8 @@ reg [addr_dtlb_index_width-1:0] dtlb_update_set;
293 293
 reg dtlb_flushing;
294 294
 reg [addr_dtlb_index_width-1:0] dtlb_flush_set;
295 295
 wire dtlb_miss;
296  
-reg dtlb_miss_q = 0;
297  
-reg dtlb_miss_int = 0;
  296
+reg dtlb_miss_q = `FALSE;
  297
+wire dtlb_miss_int;
298 298
 reg [`LM32_WORD_RNG] dtlb_miss_addr;
299 299
 wire dtlb_data_valid;
300 300
 wire [`LM32_DTLB_LOOKUP_RANGE] dtlb_lookup;
@@ -464,8 +464,6 @@ end
464 464
 generate
465 465
     for (i = 0; i < associativity; i = i + 1)
466 466
     begin : match
467  
-// FIXME : We need to put physical address coming out from MMU instead of address_m[]
468  
-//assign way_match[i] = ({way_tag[i], way_valid[i]} == {address_m[`LM32_DC_ADDR_TAG_RNG], `TRUE});
469 467
 
470 468
 assign dtlb_read_tag = dtlb_read_data[`LM32_DTLB_TAG_RANGE];
471 469
 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];
473 471
 
474 472
 assign way_match[i] = (kernel_mode_reg == `LM32_KERNEL_MODE) ?
475 473
 		      ({way_tag[i], way_valid[i]} == {address_m[`LM32_DC_ADDR_TAG_RNG], `TRUE})
476  
-		      : /*dtlb_data_valid && (dtlb_read_tag == address_m[`LM32_DC_ADDR_TAG_RNG]) && 
477  
-		     */ ({way_tag[i], way_valid[i]} == {dtlb_lookup, `TRUE});
478  
-
479  
-/*always @(*)
480  
-begin
481  
-	if (kernel_mode_reg == `LM32_KERNEL_MODE)
482  
-		way_match[i] <= ({way_tag[i], way_valid[i]} == {address_m[`LM32_DC_ADDR_TAG_RNG], `TRUE});
483  
-	else if (dtlb_read_tag == `LM32_DTLB_TAG_INVALID) // DTLB tag is invalid
484  
-		way_match[i] <= `FALSE;
485  
-	else
486  
-		way_match[i] <= ({way_tag[i], way_valid[i]} == {dtlb_read_data, `TRUE});
487  
-end*/
  474
+		      : ({way_tag[i], way_valid[i]} == {dtlb_lookup, `TRUE});
488 475
     end
489 476
 endgenerate
490 477
 
@@ -554,20 +541,10 @@ assign dtlb_data_read_address = address_x[`LM32_DTLB_IDX_RNG];
554 541
 assign dtlb_tag_read_address = address_x[`LM32_DTLB_IDX_RNG];
555 542
 
556 543
 // tlb_update_address will receive data from a CSR register
557  
-assign dtlb_data_write_address = /*(dtlb_flushing == `TRUE) 
558  
-				 ? dtlb_flush_set
559  
-				 : */dtlb_update_vaddr_csr_reg[`LM32_DTLB_IDX_RNG];
560  
-
561  
-assign dtlb_tag_write_address = (dtlb_flushing == `TRUE)
562  
-				? dtlb_flush_set
563  
-				: dtlb_update_vaddr_csr_reg[`LM32_DTLB_IDX_RNG];
  544
+assign dtlb_data_write_address = dtlb_update_vaddr_csr_reg[`LM32_DTLB_IDX_RNG];
564 545
 
565 546
 assign dtlb_data_read_port_enable = (stall_x == `FALSE) || !stall_m;
566  
-assign dtlb_tag_read_port_enable = (stall_x == `FALSE) || !stall_m;
567 547
 assign dtlb_write_port_enable = dtlb_updating || dtlb_flushing;
568  
-assign dtlb_write_tag = (dtlb_flushing == `TRUE)
569  
-			? `LM32_DTLB_TAG_INVALID
570  
-			: {dtlb_update_vaddr_csr_reg[30:22], `TRUE}; // 10-1 top VA bits
571 548
 
572 549
 assign physical_address = (kernel_mode_reg == `LM32_KERNEL_MODE)
573 550
 			    ? address_m
@@ -613,7 +590,7 @@ assign tmem_write_data[`LM32_DC_TAGS_VALID_RNG] = ((last_refill == `TRUE) || (va
613 590
 assign tmem_write_data[`LM32_DC_TAGS_TAG_RNG] = refill_address[`LM32_DC_ADDR_TAG_RNG];
614 591
 
615 592
 // Signals that indicate which state we are in
616  
-assign flushing = state[0]; //|| dtlb_miss;
  593
+assign flushing = state[0];
617 594
 assign check = state[1];
618 595
 assign refill = state[2];
619 596
 
@@ -686,8 +663,6 @@ begin
686 663
             end
687 664
             else if (dflush == `TRUE)
688 665
                 state <= `LM32_DC_STATE_FLUSH;
689  
-//           else if (dtlb_miss == `TRUE)
690  
-//		refill_address <= physical_address;
691 666
         end
692 667
 
693 668
         // Refill a cache line
@@ -721,35 +696,24 @@ begin
721 696
 	end
722 697
 end
723 698
 
724  
-assign csr_read_data = latest_store_tlb_lookup;
  699
+assign csr_read_data = dtlb_miss_addr;
725 700
 
726 701
 assign dtlb_miss = (kernel_mode_reg == `LM32_USER_MODE) && (load_q_m || store_q_m) && ~(dtlb_data_valid);
727 702
 
728 703
 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
729 704
 begin
730 705
 	if (rst_i == `TRUE)
731  
-		dtlb_miss_int <= 0;
  706
+		dtlb_miss_q <= `FALSE;
732 707
 	else
733 708
 	begin
734  
-		if (dtlb_miss)
735  
-			dtlb_miss_int <= 1;
736  
-		else
737  
-			dtlb_miss_int <= 0;
  709
+		if (dtlb_miss && ~dtlb_miss_q)
  710
+			dtlb_miss_q <= `TRUE;
  711
+		else if (dtlb_miss_q && exception_m)
  712
+			dtlb_miss_q <= `FALSE;
738 713
 	end
739 714
 end
740 715
 
741  
-always @(posedge clk_i `CFG_RESET_SENSITIVITY)
742  
-begin
743  
-	if (rst_i == `TRUE)
744  
-		dtlb_miss_q <= 0;
745  
-	else
746  
-	begin
747  
-		if (dtlb_miss_int)
748  
-			dtlb_miss_q <= 1;
749  
-		else
750  
-			dtlb_miss_q <= 0;
751  
-	end
752  
-end
  716
+assign dtlb_miss_int = (dtlb_miss || dtlb_miss_q);
753 717
 
754 718
 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
755 719
 begin
@@ -771,17 +735,15 @@ begin
771 735
 			dtlb_flushing <= 0;
772 736
 			if (dtlb_miss == `TRUE)
773 737
 			begin
774  
-//				dtlb_flushing <= 0;
775  
-//				dtlb_flush_set <= address_m[addr_dtlb_index_width-1:0];
776 738
 				dtlb_miss_addr <= address_m;
777  
-				$display("ERROR : DTLB MISS on addr 0x%08X at time %t", address_m, $time);
  739
+				$display("WARNING : DTLB MISS on addr 0x%08X at time %t", address_m, $time);
778 740
 			end
779 741
 			if (csr_write_enable && csr_write_data[0])
780 742
 			begin
781 743
 				// FIXME : test for kernel mode is removed for testing purposes ONLY
782 744
 				if (csr == `LM32_CSR_TLB_CTRL /*&& (kernel_mode_reg == `LM32_KERNEL_MODE)*/)
783 745
 				begin
784  
-					case (csr_write_data[4:1])
  746
+					case (csr_write_data[5:1])
785 747
 					`LM32_DTLB_CTRL_FLUSH:
786 748
 					begin
787 749
 						dtlb_flushing <= 1;
@@ -794,6 +756,15 @@ begin
794 756
 					begin
795 757
 						dtlb_updating <= 1;
796 758
 					end
  759
+
  760
+					`LM32_TLB_CTRL_INVALIDATE_ENTRY:
  761
+					begin
  762
+						dtlb_flushing <= 1;
  763
+						dtlb_flush_set <= dtlb_update_vaddr_csr_reg[`LM32_DTLB_IDX_RNG];
  764
+						dtlb_updating <= 0;
  765
+						dtlb_state <= `LM32_TLB_STATE_CHECK;
  766
+					end
  767
+
797 768
 					endcase
798 769
 				end
799 770
 			end
@@ -811,8 +782,8 @@ begin
811 782
 	end
812 783
 end
813 784
 
814  
-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});
815  
-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});
  785
+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});
  786
+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});
816 787
 
817 788
 
818 789
 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
4  lm32_load_store_unit.v
@@ -429,6 +429,7 @@ lm32_dcache #(
429 429
     .csr_write_enable	    (csr_write_enable),
430 430
     .exception_x	    (exception_x),
431 431
     .eret_q_x		    (eret_q_x),
  432
+    .exception_m	    (exception_m),
432 433
     // ----- Outputs -----
433 434
     .stall_request          (dcache_stall_request),
434 435
     .restart_request        (dcache_restart_request),
@@ -436,8 +437,7 @@ lm32_dcache #(
436 437
     .refill_address         (dcache_refill_address),
437 438
     .refilling              (dcache_refilling),
438 439
     .load_data              (dcache_data_m),
439  
-//    .dtlb_miss		    (dtlb_miss),
440  
-    .dtlb_miss_q	    (dtlb_miss),
  440
+    .dtlb_miss_int	    (dtlb_miss),
441 441
     .kernel_mode	    (kernel_mode),
442 442
     .pa			    (physical_address),
443 443
     .csr_read_data	    (csr_read_data)
34  soc.wcfg
@@ -9,7 +9,7 @@
9 9
          </top_modules>
10 10
       </db_ref>
11 11
    </db_ref_list>
12  
-   <WVObjectSize size="149" />
  12
+   <WVObjectSize size="144" />
13 13
    <wvobject fp_name="/soc/memadr" type="array" db_ref_id="1">
14 14
       <obj_property name="ElementShortName">memadr[31:0]</obj_property>
15 15
       <obj_property name="ObjectShortName">memadr[31:0]</obj_property>
@@ -413,13 +413,8 @@
413 413
       <obj_property name="Radix">HEXRADIX</obj_property>
414 414
    </wvobject>
415 415
    <wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/dtlb_read_data" type="array" db_ref_id="1">
416  
-      <obj_property name="ElementShortName">dtlb_read_data[19:0]</obj_property>
417  
-      <obj_property name="ObjectShortName">dtlb_read_data[19:0]</obj_property>
418  
-      <obj_property name="Radix">HEXRADIX</obj_property>
419  
-   </wvobject>
420  
-   <wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/dtlb_read_tag" type="array" db_ref_id="1">
421  
-      <obj_property name="ElementShortName">dtlb_read_tag[9:0]</obj_property>
422  
-      <obj_property name="ObjectShortName">dtlb_read_tag[9:0]</obj_property>
  416
+      <obj_property name="ElementShortName">dtlb_read_data[30:0]</obj_property>
  417
+      <obj_property name="ObjectShortName">dtlb_read_data[30:0]</obj_property>
423 418
       <obj_property name="Radix">HEXRADIX</obj_property>
424 419
    </wvobject>
425 420
    <wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/dtlb_sets" type="array" db_ref_id="1">
@@ -431,38 +426,19 @@
431 426
       <obj_property name="ElementShortName">dtlb_state[1:0]</obj_property>
432 427
       <obj_property name="ObjectShortName">dtlb_state[1:0]</obj_property>
433 428
    </wvobject>
434  
-   <wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/dtlb_tag_read_address" type="array" db_ref_id="1">
435  
-      <obj_property name="ElementShortName">dtlb_tag_read_address[9:0]</obj_property>
436  
-      <obj_property name="ObjectShortName">dtlb_tag_read_address[9:0]</obj_property>
437  
-      <obj_property name="Radix">HEXRADIX</obj_property>
438  
-   </wvobject>
439  
-   <wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/dtlb_tag_read_port_enable" type="logic" db_ref_id="1">
440  
-      <obj_property name="ElementShortName">dtlb_tag_read_port_enable</obj_property>
441  
-      <obj_property name="ObjectShortName">dtlb_tag_read_port_enable</obj_property>
442  
-   </wvobject>
443  
-   <wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/dtlb_tag_write_address" type="array" db_ref_id="1">
444  
-      <obj_property name="ElementShortName">dtlb_tag_write_address[9:0]</obj_property>
445  
-      <obj_property name="ObjectShortName">dtlb_tag_write_address[9:0]</obj_property>
446  
-      <obj_property name="Radix">HEXRADIX</obj_property>
447  
-   </wvobject>
448 429
    <wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/dtlb_updating" type="logic" db_ref_id="1">
449 430
       <obj_property name="ElementShortName">dtlb_updating</obj_property>
450 431
       <obj_property name="ObjectShortName">dtlb_updating</obj_property>
451 432
    </wvobject>
452 433
    <wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/dtlb_write_data" type="array" db_ref_id="1">
453  
-      <obj_property name="ElementShortName">dtlb_write_data[19:0]</obj_property>
454  
-      <obj_property name="ObjectShortName">dtlb_write_data[19:0]</obj_property>
  434
+      <obj_property name="ElementShortName">dtlb_write_data[30:0]</obj_property>
  435
+      <obj_property name="ObjectShortName">dtlb_write_data[30:0]</obj_property>
455 436
       <obj_property name="Radix">HEXRADIX</obj_property>
456 437
    </wvobject>
457 438
    <wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/dtlb_write_port_enable" type="logic" db_ref_id="1">
458 439
       <obj_property name="ElementShortName">dtlb_write_port_enable</obj_property>
459 440
       <obj_property name="ObjectShortName">dtlb_write_port_enable</obj_property>
460 441
    </wvobject>
461  
-   <wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/dtlb_write_tag" type="array" db_ref_id="1">
462  
-      <obj_property name="ElementShortName">dtlb_write_tag[9:0]</obj_property>
463  
-      <obj_property name="ObjectShortName">dtlb_write_tag[9:0]</obj_property>
464  
-      <obj_property name="Radix">HEXRADIX</obj_property>
465  
-   </wvobject>
466 442
    <wvobject fp_name="/soc/lm32/cpu/load_store_unit/dcache/flush_set" type="array" db_ref_id="1">
467 443
       <obj_property name="ElementShortName">flush_set[7:0]</obj_property>
468 444
       <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.