forked from Github_Repos/cvw
		
	Fixed combo loop in between the page table walker and i/dtlb.
This commit is contained in:
		
							parent
							
								
									aeeaf6d919
								
							
						
					
					
						commit
						c02141697d
					
				@ -36,7 +36,7 @@
 | 
			
		||||
 | 
			
		||||
module pagetablewalker (
 | 
			
		||||
  // Control signals
 | 
			
		||||
  input  logic             HCLK, HRESETn,
 | 
			
		||||
  input  logic             clk, reset,
 | 
			
		||||
  input  logic [`XLEN-1:0] SATP_REGW,
 | 
			
		||||
 | 
			
		||||
  // Signals from TLBs (addresses to translate)
 | 
			
		||||
@ -73,6 +73,10 @@ module pagetablewalker (
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
  // Internal signals
 | 
			
		||||
  // register TLBs translation miss requests
 | 
			
		||||
  logic [`XLEN-1:0] 	   TranslationVAdrQ;
 | 
			
		||||
  logic 		   ITLBMissFQ, DTLBMissMQ;
 | 
			
		||||
  
 | 
			
		||||
  logic [`PPN_BITS-1:0] BasePageTablePPN;
 | 
			
		||||
  logic [`XLEN-1:0]     TranslationVAdr;
 | 
			
		||||
  logic [`XLEN-1:0]     SavedPTE, CurrentPTE;
 | 
			
		||||
@ -98,8 +102,28 @@ module pagetablewalker (
 | 
			
		||||
  assign MemStore = MemRWM[0];
 | 
			
		||||
 | 
			
		||||
  // Prefer data address translations over instruction address translations
 | 
			
		||||
  assign TranslationVAdr = (DTLBMissM) ? MemAdrM : PCF;
 | 
			
		||||
  assign MMUTranslate = DTLBMissM || ITLBMissF;
 | 
			
		||||
  assign TranslationVAdr = (DTLBMissM) ? MemAdrM : PCF; // *** need to register TranslationVAdr
 | 
			
		||||
  flopenr #(`XLEN) 
 | 
			
		||||
  TranslationVAdrReg(.clk(clk),
 | 
			
		||||
		     .reset(reset),
 | 
			
		||||
		     .en(1'b1), // *** use enable later to save power
 | 
			
		||||
		     .d(TranslationVAdr),
 | 
			
		||||
		     .q(TranslationVAdrQ));
 | 
			
		||||
 | 
			
		||||
  flopr #(1)
 | 
			
		||||
  DTLBMissMReg(.clk(clk),
 | 
			
		||||
	       .reset(reset),
 | 
			
		||||
	       .d(DTLBMissM),
 | 
			
		||||
	       .q(DTLBMissMQ));
 | 
			
		||||
  
 | 
			
		||||
  flopr #(1)
 | 
			
		||||
  ITLBMissMReg(.clk(clk),
 | 
			
		||||
	       .reset(reset),
 | 
			
		||||
	       .d(ITLBMissF),
 | 
			
		||||
	       .q(ITLBMissFQ));
 | 
			
		||||
  		     
 | 
			
		||||
    
 | 
			
		||||
  assign MMUTranslate = DTLBMissMQ | ITLBMissFQ;
 | 
			
		||||
 | 
			
		||||
  // unswizzle PTE bits
 | 
			
		||||
  assign {Dirty, Accessed, Global, User,
 | 
			
		||||
@ -108,7 +132,7 @@ module pagetablewalker (
 | 
			
		||||
  // Assign PTE descriptors common across all XLEN values
 | 
			
		||||
  assign LeafPTE = Executable | Writable | Readable;
 | 
			
		||||
  assign ValidPTE = Valid && ~(Writable && ~Readable);
 | 
			
		||||
  assign AccessAlert = ~Accessed || (MemStore && ~Dirty);
 | 
			
		||||
  assign AccessAlert = ~Accessed | (MemStore & ~Dirty);
 | 
			
		||||
 | 
			
		||||
  // Assign specific outputs to general outputs
 | 
			
		||||
  assign PageTableEntryF = PageTableEntry;
 | 
			
		||||
@ -129,7 +153,7 @@ localparam LEVEL0 = 3'h0;
 | 
			
		||||
    if (`XLEN == 32) begin
 | 
			
		||||
      logic [9:0] VPN1, VPN0;
 | 
			
		||||
 | 
			
		||||
      flopenl #(3) mmureg(HCLK, ~HRESETn, 1'b1, NextWalkerState, IDLE, WalkerState);
 | 
			
		||||
      flopenl #(3) mmureg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState);
 | 
			
		||||
 | 
			
		||||
      // State transition logic
 | 
			
		||||
      always_comb begin
 | 
			
		||||
@ -162,8 +186,8 @@ localparam LEVEL0 = 3'h0;
 | 
			
		||||
      assign MegapageMisaligned = |(CurrentPPN[9:0]);
 | 
			
		||||
      assign BadMegapage = MegapageMisaligned || AccessAlert;  // *** Implement better access/dirty scheme
 | 
			
		||||
 | 
			
		||||
      assign VPN1 = TranslationVAdr[31:22];
 | 
			
		||||
      assign VPN0 = TranslationVAdr[21:12];
 | 
			
		||||
      assign VPN1 = TranslationVAdrQ[31:22];
 | 
			
		||||
      assign VPN0 = TranslationVAdrQ[21:12];
 | 
			
		||||
 | 
			
		||||
      // Assign combinational outputs
 | 
			
		||||
      always_comb begin
 | 
			
		||||
@ -193,14 +217,14 @@ localparam LEVEL0 = 3'h0;
 | 
			
		||||
            TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
 | 
			
		||||
            PageTableEntry = CurrentPTE;
 | 
			
		||||
            PageType = (WalkerState == LEVEL1) ? 2'b01 : 2'b00;
 | 
			
		||||
            DTLBWriteM = DTLBMissM;
 | 
			
		||||
            ITLBWriteF = ~DTLBMissM;  // Prefer data over instructions
 | 
			
		||||
            DTLBWriteM = DTLBMissMQ;
 | 
			
		||||
            ITLBWriteF = ~DTLBMissMQ;  // Prefer data over instructions
 | 
			
		||||
          end
 | 
			
		||||
          FAULT: begin
 | 
			
		||||
            TranslationPAdr = {CurrentPPN, VPN0, 2'b00};
 | 
			
		||||
            WalkerInstrPageFaultF = ~DTLBMissM;
 | 
			
		||||
            WalkerLoadPageFaultM = DTLBMissM && ~MemStore;
 | 
			
		||||
            WalkerStorePageFaultM = DTLBMissM && MemStore;
 | 
			
		||||
            WalkerInstrPageFaultF = ~DTLBMissMQ;
 | 
			
		||||
            WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore;
 | 
			
		||||
            WalkerStorePageFaultM = DTLBMissMQ && MemStore;
 | 
			
		||||
            MMUStall = '0;  // Drop the stall early to enter trap handling code
 | 
			
		||||
          end
 | 
			
		||||
          default: begin
 | 
			
		||||
@ -210,7 +234,7 @@ localparam LEVEL0 = 3'h0;
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      // Capture page table entry from ahblite
 | 
			
		||||
      flopenr #(32) ptereg(HCLK, ~HRESETn, MMUReady, MMUReadPTE, SavedPTE);
 | 
			
		||||
      flopenr #(32) ptereg(clk, reset, MMUReady, MMUReadPTE, SavedPTE);
 | 
			
		||||
      mux2 #(32) ptemux(SavedPTE, MMUReadPTE, MMUReady, CurrentPTE);
 | 
			
		||||
      assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10];
 | 
			
		||||
 | 
			
		||||
@ -227,7 +251,7 @@ localparam LEVEL0 = 3'h0;
 | 
			
		||||
 | 
			
		||||
      logic TerapageMisaligned, GigapageMisaligned, BadTerapage, BadGigapage;
 | 
			
		||||
 | 
			
		||||
      flopenl #(3) mmureg(HCLK, ~HRESETn, 1'b1, NextWalkerState, IDLE, WalkerState);
 | 
			
		||||
      flopenl #(3) mmureg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState);
 | 
			
		||||
 | 
			
		||||
      always_comb begin
 | 
			
		||||
        case (WalkerState)
 | 
			
		||||
@ -294,10 +318,10 @@ localparam LEVEL0 = 3'h0;
 | 
			
		||||
      assign BadGigapage = GigapageMisaligned || AccessAlert;  // *** Implement better access/dirty scheme
 | 
			
		||||
      assign BadMegapage = MegapageMisaligned || AccessAlert;  // *** Implement better access/dirty scheme
 | 
			
		||||
 | 
			
		||||
      assign VPN3 = TranslationVAdr[47:39];
 | 
			
		||||
      assign VPN2 = TranslationVAdr[38:30];
 | 
			
		||||
      assign VPN1 = TranslationVAdr[29:21];
 | 
			
		||||
      assign VPN0 = TranslationVAdr[20:12];
 | 
			
		||||
      assign VPN3 = TranslationVAdrQ[47:39];
 | 
			
		||||
      assign VPN2 = TranslationVAdrQ[38:30];
 | 
			
		||||
      assign VPN1 = TranslationVAdrQ[29:21];
 | 
			
		||||
      assign VPN0 = TranslationVAdrQ[20:12];
 | 
			
		||||
 | 
			
		||||
      always_comb begin
 | 
			
		||||
        // default values
 | 
			
		||||
@ -338,15 +362,15 @@ localparam LEVEL0 = 3'h0;
 | 
			
		||||
            PageType = (WalkerState == LEVEL3) ? 2'b11 :
 | 
			
		||||
                                ((WalkerState == LEVEL2) ? 2'b10 : 
 | 
			
		||||
                                ((WalkerState == LEVEL1) ? 2'b01 : 2'b00));
 | 
			
		||||
            DTLBWriteM = DTLBMissM;
 | 
			
		||||
            ITLBWriteF = ~DTLBMissM;  // Prefer data over instructions
 | 
			
		||||
            DTLBWriteM = DTLBMissMQ;
 | 
			
		||||
            ITLBWriteF = ~DTLBMissMQ;  // Prefer data over instructions
 | 
			
		||||
          end
 | 
			
		||||
          FAULT: begin
 | 
			
		||||
            // Keep physical address alive to prevent HADDR dropping to 0
 | 
			
		||||
            TranslationPAdr = {CurrentPPN, VPN0, 3'b000};
 | 
			
		||||
            WalkerInstrPageFaultF = ~DTLBMissM;
 | 
			
		||||
            WalkerLoadPageFaultM = DTLBMissM && ~MemStore;
 | 
			
		||||
            WalkerStorePageFaultM = DTLBMissM && MemStore;
 | 
			
		||||
            WalkerInstrPageFaultF = ~DTLBMissMQ;
 | 
			
		||||
            WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore;
 | 
			
		||||
            WalkerStorePageFaultM = DTLBMissMQ && MemStore;
 | 
			
		||||
            MMUStall = '0;  // Drop the stall early to enter trap handling code
 | 
			
		||||
          end
 | 
			
		||||
          default: begin
 | 
			
		||||
@ -356,7 +380,7 @@ localparam LEVEL0 = 3'h0;
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      // Capture page table entry from ahblite
 | 
			
		||||
      flopenr #(`XLEN) ptereg(HCLK, ~HRESETn, MMUReady, MMUReadPTE, SavedPTE);
 | 
			
		||||
      flopenr #(`XLEN) ptereg(clk, reset, MMUReady, MMUReadPTE, SavedPTE);
 | 
			
		||||
      mux2 #(`XLEN) ptemux(SavedPTE, MMUReadPTE, MMUReady, CurrentPTE);
 | 
			
		||||
      assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user