forked from Github_Repos/cvw
		
	Removed unnecessary generate inside hptw
This commit is contained in:
		
							parent
							
								
									8225f85b86
								
							
						
					
					
						commit
						347896064d
					
				@ -121,73 +121,73 @@ module lsu
 | 
			
		||||
  assign IEUAdrExtM = {2'b00, IEUAdrM};
 | 
			
		||||
 | 
			
		||||
  generate
 | 
			
		||||
	if(`MEM_VIRTMEM) begin : MEM_VIRTMEM
 | 
			
		||||
	  logic 					   AnyCPUReqM;
 | 
			
		||||
	  logic [`PA_BITS-1:0] 		   HPTWAdr;
 | 
			
		||||
	  logic 					   HPTWRead;
 | 
			
		||||
	  logic [2:0] 				   HPTWSize;
 | 
			
		||||
	  logic 					   SelReplayCPURequest;
 | 
			
		||||
    if(`MEM_VIRTMEM) begin : MEM_VIRTMEM
 | 
			
		||||
      logic 					   AnyCPUReqM;
 | 
			
		||||
      logic [`PA_BITS-1:0] 		   HPTWAdr;
 | 
			
		||||
      logic 					   HPTWRead;
 | 
			
		||||
      logic [2:0] 				   HPTWSize;
 | 
			
		||||
      logic 					   SelReplayCPURequest;
 | 
			
		||||
 | 
			
		||||
	  assign AnyCPUReqM = (|MemRWM) | (|AtomicM);
 | 
			
		||||
      assign AnyCPUReqM = (|MemRWM) | (|AtomicM);
 | 
			
		||||
 | 
			
		||||
	  interlockfsm interlockfsm (.clk, .reset, .AnyCPUReqM, .ITLBMissF, .ITLBWriteF,
 | 
			
		||||
		 .DTLBMissM, .DTLBWriteM, .ExceptionM, .PendingInterruptM, .DCacheStall,
 | 
			
		||||
		 .InterlockStall, .SelReplayCPURequest, .SelHPTW,
 | 
			
		||||
		 .IgnoreRequest);
 | 
			
		||||
	  
 | 
			
		||||
	  hptw hptw(.clk, .reset, .SATP_REGW, .PCF, .IEUAdrM,
 | 
			
		||||
				.ITLBMissF(ITLBMissF & ~PendingInterruptM),
 | 
			
		||||
				.DTLBMissM(DTLBMissM & ~PendingInterruptM),
 | 
			
		||||
				.MemRWM, .PTE, .PageType, .ITLBWriteF, .DTLBWriteM,
 | 
			
		||||
				.HPTWReadPTE(ReadDataM),
 | 
			
		||||
				.DCacheStall, .HPTWAdr, .HPTWRead, .HPTWSize, .AnyCPUReqM);
 | 
			
		||||
      interlockfsm interlockfsm (.clk, .reset, .AnyCPUReqM, .ITLBMissF, .ITLBWriteF,
 | 
			
		||||
      .DTLBMissM, .DTLBWriteM, .ExceptionM, .PendingInterruptM, .DCacheStall,
 | 
			
		||||
      .InterlockStall, .SelReplayCPURequest, .SelHPTW,
 | 
			
		||||
      .IgnoreRequest);
 | 
			
		||||
      
 | 
			
		||||
      hptw hptw(.clk, .reset, .SATP_REGW, .PCF, .IEUAdrM,
 | 
			
		||||
          .ITLBMissF(ITLBMissF & ~PendingInterruptM),
 | 
			
		||||
          .DTLBMissM(DTLBMissM & ~PendingInterruptM),
 | 
			
		||||
          .MemRWM, .PTE, .PageType, .ITLBWriteF, .DTLBWriteM,
 | 
			
		||||
          .HPTWReadPTE(ReadDataM),
 | 
			
		||||
          .DCacheStall, .HPTWAdr, .HPTWRead, .HPTWSize, .AnyCPUReqM);
 | 
			
		||||
 | 
			
		||||
	  // arbiter between IEU and hptw
 | 
			
		||||
	  
 | 
			
		||||
	  // multiplex the outputs to LSU
 | 
			
		||||
	  mux2 #(2) rwmux(MemRWM, {HPTWRead, 1'b0}, SelHPTW, PreLsuRWM);
 | 
			
		||||
	  mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LsuFunct3M);
 | 
			
		||||
	  mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LsuAtomicM);
 | 
			
		||||
	  mux2 #(12) adremux(IEUAdrE[11:0], HPTWAdr[11:0], SelHPTW, PreLsuAdrE);
 | 
			
		||||
	  mux2 #(`PA_BITS) lsupadrmux(IEUAdrExtM[`PA_BITS-1:0], HPTWAdr, SelHPTW, PreLsuPAdrM);
 | 
			
		||||
      // arbiter between IEU and hptw
 | 
			
		||||
      
 | 
			
		||||
      // multiplex the outputs to LSU
 | 
			
		||||
      mux2 #(2) rwmux(MemRWM, {HPTWRead, 1'b0}, SelHPTW, PreLsuRWM);
 | 
			
		||||
      mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LsuFunct3M);
 | 
			
		||||
      mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LsuAtomicM);
 | 
			
		||||
      mux2 #(12) adremux(IEUAdrE[11:0], HPTWAdr[11:0], SelHPTW, PreLsuAdrE);
 | 
			
		||||
      mux2 #(`PA_BITS) lsupadrmux(IEUAdrExtM[`PA_BITS-1:0], HPTWAdr, SelHPTW, PreLsuPAdrM);
 | 
			
		||||
 | 
			
		||||
	  // always block interrupts when using the hardware page table walker.
 | 
			
		||||
	  assign CPUBusy = StallW & ~SelHPTW;
 | 
			
		||||
	  
 | 
			
		||||
	  // It is not possible to pipeline hptw as the following load will depend on the previous load's
 | 
			
		||||
	  // data. Therefore we don't need a pipeline register
 | 
			
		||||
	  //flop #(`PA_BITS) HPTWAdrMReg(clk, HPTWAdr, HPTWAdrM);   // delay HPTWAdrM by a cycle
 | 
			
		||||
      // always block interrupts when using the hardware page table walker.
 | 
			
		||||
      assign CPUBusy = StallW & ~SelHPTW;
 | 
			
		||||
      
 | 
			
		||||
      // It is not possible to pipeline hptw as the following load will depend on the previous load's
 | 
			
		||||
      // data. Therefore we don't need a pipeline register
 | 
			
		||||
      //flop #(`PA_BITS) HPTWAdrMReg(clk, HPTWAdr, HPTWAdrM);   // delay HPTWAdrM by a cycle
 | 
			
		||||
 | 
			
		||||
	  // Specify which type of page fault is occurring
 | 
			
		||||
	  assign DTLBLoadPageFaultM = DTLBPageFaultM & PreLsuRWM[1];
 | 
			
		||||
	  assign DTLBStorePageFaultM = DTLBPageFaultM & PreLsuRWM[0];
 | 
			
		||||
      // Specify which type of page fault is occurring
 | 
			
		||||
      assign DTLBLoadPageFaultM = DTLBPageFaultM & PreLsuRWM[1];
 | 
			
		||||
      assign DTLBStorePageFaultM = DTLBPageFaultM & PreLsuRWM[0];
 | 
			
		||||
 | 
			
		||||
	  // When replaying CPU memory request after PTW select the IEUAdrM for correct address.
 | 
			
		||||
	  assign LsuAdrE = SelReplayCPURequest ? IEUAdrM[11:0] : PreLsuAdrE;
 | 
			
		||||
      // When replaying CPU memory request after PTW select the IEUAdrM for correct address.
 | 
			
		||||
      assign LsuAdrE = SelReplayCPURequest ? IEUAdrM[11:0] : PreLsuAdrE;
 | 
			
		||||
 | 
			
		||||
	end // if (`MEM_VIRTMEM)
 | 
			
		||||
	else begin
 | 
			
		||||
	  assign InterlockStall = 1'b0;
 | 
			
		||||
	  
 | 
			
		||||
	  assign LsuAdrE = PreLsuAdrE;
 | 
			
		||||
	  assign SelHPTW = 1'b0;
 | 
			
		||||
	  assign IgnoreRequest = 1'b0;
 | 
			
		||||
    end // if (`MEM_VIRTMEM)
 | 
			
		||||
    else begin
 | 
			
		||||
      assign InterlockStall = 1'b0;
 | 
			
		||||
      
 | 
			
		||||
      assign LsuAdrE = PreLsuAdrE;
 | 
			
		||||
      assign SelHPTW = 1'b0;
 | 
			
		||||
      assign IgnoreRequest = 1'b0;
 | 
			
		||||
 | 
			
		||||
	  assign PTE = '0;
 | 
			
		||||
	  assign PageType = '0;
 | 
			
		||||
	  assign DTLBWriteM = 1'b0;
 | 
			
		||||
	  assign ITLBWriteF = 1'b0;	  
 | 
			
		||||
	  
 | 
			
		||||
	  assign PreLsuRWM = MemRWM;
 | 
			
		||||
	  assign LsuFunct3M = Funct3M;
 | 
			
		||||
	  assign LsuAtomicM = AtomicM;
 | 
			
		||||
	  assign PreLsuAdrE = IEUAdrE[11:0];
 | 
			
		||||
	  assign PreLsuPAdrM = IEUAdrExtM;
 | 
			
		||||
	  assign CPUBusy = StallW;
 | 
			
		||||
	  
 | 
			
		||||
	  assign DTLBLoadPageFaultM = 1'b0;
 | 
			
		||||
	  assign DTLBStorePageFaultM = 1'b0;
 | 
			
		||||
	end
 | 
			
		||||
      assign PTE = '0;
 | 
			
		||||
      assign PageType = '0;
 | 
			
		||||
      assign DTLBWriteM = 1'b0;
 | 
			
		||||
      assign ITLBWriteF = 1'b0;	  
 | 
			
		||||
      
 | 
			
		||||
      assign PreLsuRWM = MemRWM;
 | 
			
		||||
      assign LsuFunct3M = Funct3M;
 | 
			
		||||
      assign LsuAtomicM = AtomicM;
 | 
			
		||||
      assign PreLsuAdrE = IEUAdrE[11:0];
 | 
			
		||||
      assign PreLsuPAdrM = IEUAdrExtM;
 | 
			
		||||
      assign CPUBusy = StallW;
 | 
			
		||||
      
 | 
			
		||||
      assign DTLBLoadPageFaultM = 1'b0;
 | 
			
		||||
      assign DTLBStorePageFaultM = 1'b0;
 | 
			
		||||
    end
 | 
			
		||||
  endgenerate
 | 
			
		||||
 | 
			
		||||
  // **** look into this confusing signal.
 | 
			
		||||
@ -201,54 +201,54 @@ module lsu
 | 
			
		||||
  assign CommittedM = SelHPTW | DCacheCommittedM | BusCommittedM;
 | 
			
		||||
 | 
			
		||||
  generate
 | 
			
		||||
	if(`ZICSR_SUPPORTED == 1) begin : dmmu
 | 
			
		||||
	  logic 					   DataMisalignedM;
 | 
			
		||||
    if(`ZICSR_SUPPORTED == 1) begin : dmmu
 | 
			
		||||
      logic 					   DataMisalignedM;
 | 
			
		||||
 | 
			
		||||
	  mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0))
 | 
			
		||||
	  dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
 | 
			
		||||
		   .PrivilegeModeW, .DisableTranslation(SelHPTW),
 | 
			
		||||
		   .PAdr(PreLsuPAdrM),
 | 
			
		||||
		   .VAdr(IEUAdrM),
 | 
			
		||||
		   .Size(LsuFunct3M[1:0]),
 | 
			
		||||
		   .PTE,
 | 
			
		||||
		   .PageTypeWriteVal(PageType),
 | 
			
		||||
		   .TLBWrite(DTLBWriteM),
 | 
			
		||||
		   .TLBFlush(DTLBFlushM),
 | 
			
		||||
		   .PhysicalAddress(LsuPAdrM),
 | 
			
		||||
		   .TLBMiss(DTLBMissM),
 | 
			
		||||
		   .Cacheable(CacheableM),
 | 
			
		||||
		   .Idempotent(), .AtomicAllowed(),
 | 
			
		||||
		   .TLBPageFault(DTLBPageFaultM),
 | 
			
		||||
		   .InstrAccessFaultF(), .LoadAccessFaultM, .StoreAccessFaultM,
 | 
			
		||||
		   .AtomicAccessM(1'b0), .ExecuteAccessF(1'b0),  ///  atomicaccessm is probably a bug
 | 
			
		||||
		   .WriteAccessM(PreLsuRWM[0]), .ReadAccessM(PreLsuRWM[1]),
 | 
			
		||||
		   .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW
 | 
			
		||||
		   ); // *** the pma/pmp instruction access faults don't really matter here. is it possible to parameterize which outputs exist?
 | 
			
		||||
      mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0))
 | 
			
		||||
      dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
 | 
			
		||||
        .PrivilegeModeW, .DisableTranslation(SelHPTW),
 | 
			
		||||
        .PAdr(PreLsuPAdrM),
 | 
			
		||||
        .VAdr(IEUAdrM),
 | 
			
		||||
        .Size(LsuFunct3M[1:0]),
 | 
			
		||||
        .PTE,
 | 
			
		||||
        .PageTypeWriteVal(PageType),
 | 
			
		||||
        .TLBWrite(DTLBWriteM),
 | 
			
		||||
        .TLBFlush(DTLBFlushM),
 | 
			
		||||
        .PhysicalAddress(LsuPAdrM),
 | 
			
		||||
        .TLBMiss(DTLBMissM),
 | 
			
		||||
        .Cacheable(CacheableM),
 | 
			
		||||
        .Idempotent(), .AtomicAllowed(),
 | 
			
		||||
        .TLBPageFault(DTLBPageFaultM),
 | 
			
		||||
        .InstrAccessFaultF(), .LoadAccessFaultM, .StoreAccessFaultM,
 | 
			
		||||
        .AtomicAccessM(1'b0), .ExecuteAccessF(1'b0),  ///  atomicaccessm is probably a bug
 | 
			
		||||
        .WriteAccessM(PreLsuRWM[0]), .ReadAccessM(PreLsuRWM[1]),
 | 
			
		||||
        .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW
 | 
			
		||||
        ); // *** the pma/pmp instruction access faults don't really matter here. is it possible to parameterize which outputs exist?
 | 
			
		||||
 | 
			
		||||
	  // Determine if an Unaligned access is taking place
 | 
			
		||||
	  // hptw guarantees alignment, only check inputs from IEU.
 | 
			
		||||
	  always_comb
 | 
			
		||||
		case(Funct3M[1:0]) 
 | 
			
		||||
		  2'b00:  DataMisalignedM = 0;                       // lb, sb, lbu
 | 
			
		||||
		  2'b01:  DataMisalignedM = IEUAdrM[0];              // lh, sh, lhu
 | 
			
		||||
		  2'b10:  DataMisalignedM = IEUAdrM[1] | IEUAdrM[0]; // lw, sw, flw, fsw, lwu
 | 
			
		||||
		  2'b11:  DataMisalignedM = |IEUAdrM[2:0];           // ld, sd, fld, fsd
 | 
			
		||||
		endcase 
 | 
			
		||||
      // Determine if an Unaligned access is taking place
 | 
			
		||||
      // hptw guarantees alignment, only check inputs from IEU.
 | 
			
		||||
      always_comb
 | 
			
		||||
      case(Funct3M[1:0]) 
 | 
			
		||||
        2'b00:  DataMisalignedM = 0;                       // lb, sb, lbu
 | 
			
		||||
        2'b01:  DataMisalignedM = IEUAdrM[0];              // lh, sh, lhu
 | 
			
		||||
        2'b10:  DataMisalignedM = IEUAdrM[1] | IEUAdrM[0]; // lw, sw, flw, fsw, lwu
 | 
			
		||||
        2'b11:  DataMisalignedM = |IEUAdrM[2:0];           // ld, sd, fld, fsd
 | 
			
		||||
      endcase 
 | 
			
		||||
 | 
			
		||||
	  // If the CPU's (not HPTW's) request is a page fault.
 | 
			
		||||
	  assign LoadMisalignedFaultM = DataMisalignedM & MemRWM[1];
 | 
			
		||||
	  assign StoreMisalignedFaultM = DataMisalignedM & MemRWM[0];
 | 
			
		||||
	  
 | 
			
		||||
	end else begin
 | 
			
		||||
	  assign LsuPAdrM = PreLsuPAdrM;
 | 
			
		||||
	  assign DTLBMissM = 0;
 | 
			
		||||
	  assign CacheableM = 1;
 | 
			
		||||
	  assign DTLBPageFaultM = 0;
 | 
			
		||||
	  assign LoadAccessFaultM = 0;
 | 
			
		||||
	  assign StoreAccessFaultM = 0;
 | 
			
		||||
	  assign LoadMisalignedFaultM = 0;
 | 
			
		||||
	  assign StoreMisalignedFaultM = 0;
 | 
			
		||||
	end
 | 
			
		||||
      // If the CPU's (not HPTW's) request is a page fault.
 | 
			
		||||
      assign LoadMisalignedFaultM = DataMisalignedM & MemRWM[1];
 | 
			
		||||
      assign StoreMisalignedFaultM = DataMisalignedM & MemRWM[0];
 | 
			
		||||
      
 | 
			
		||||
    end else begin
 | 
			
		||||
      assign LsuPAdrM = PreLsuPAdrM;
 | 
			
		||||
      assign DTLBMissM = 0;
 | 
			
		||||
      assign CacheableM = 1;
 | 
			
		||||
      assign DTLBPageFaultM = 0;
 | 
			
		||||
      assign LoadAccessFaultM = 0;
 | 
			
		||||
      assign StoreAccessFaultM = 0;
 | 
			
		||||
      assign LoadMisalignedFaultM = 0;
 | 
			
		||||
      assign StoreMisalignedFaultM = 0;
 | 
			
		||||
    end
 | 
			
		||||
  endgenerate
 | 
			
		||||
  assign LSUStall = DCacheStall | InterlockStall | BusStall;
 | 
			
		||||
  
 | 
			
		||||
@ -257,18 +257,17 @@ module lsu
 | 
			
		||||
  // Move generate from lrsc to outside this module.
 | 
			
		||||
  // use PreLsu as prefix for lrsc 
 | 
			
		||||
  generate
 | 
			
		||||
	if (`A_SUPPORTED) begin:lrsc
 | 
			
		||||
	  assign MemReadM = PreLsuRWM[1] & ~(IgnoreRequest) & ~DTLBMissM;
 | 
			
		||||
	  lrsc lrsc(.clk, .reset, .FlushW, .CPUBusy, .MemReadM, .PreLsuRWM, .LsuAtomicM, .LsuPAdrM,
 | 
			
		||||
				.SquashSCW, .LsuRWM);
 | 
			
		||||
	end else begin:lrsc
 | 
			
		||||
      assign SquashSCW = 0;
 | 
			
		||||
      assign LsuRWM = PreLsuRWM;
 | 
			
		||||
	end
 | 
			
		||||
    if (`A_SUPPORTED) begin:lrsc
 | 
			
		||||
      assign MemReadM = PreLsuRWM[1] & ~(IgnoreRequest) & ~DTLBMissM;
 | 
			
		||||
      lrsc lrsc(.clk, .reset, .FlushW, .CPUBusy, .MemReadM, .PreLsuRWM, .LsuAtomicM, .LsuPAdrM,
 | 
			
		||||
          .SquashSCW, .LsuRWM);
 | 
			
		||||
    end else begin:lrsc
 | 
			
		||||
        assign SquashSCW = 0;
 | 
			
		||||
        assign LsuRWM = PreLsuRWM;
 | 
			
		||||
    end
 | 
			
		||||
  endgenerate
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // conditional
 | 
			
		||||
  // 1. ram // controlled by `MEM_DTIM
 | 
			
		||||
  // 2. cache `MEM_DCACHE
 | 
			
		||||
@ -306,25 +305,25 @@ module lsu
 | 
			
		||||
  logic 			   SelUncachedAdr;
 | 
			
		||||
 | 
			
		||||
  generate
 | 
			
		||||
	if(`MEM_DCACHE) begin : dcache
 | 
			
		||||
	  dcache dcache(.clk, .reset, .CPUBusy,
 | 
			
		||||
					.LsuRWM, .FlushDCacheM, .LsuAtomicM, .LsuAdrE, .LsuPAdrM,
 | 
			
		||||
					.FinalWriteDataM, .ReadDataWordM, .DCacheStall,
 | 
			
		||||
					.DCacheMiss, .DCacheAccess, 
 | 
			
		||||
					.IgnoreRequest, .CacheableM, .DCacheCommittedM,
 | 
			
		||||
					.DCacheBusAdr, .ReadDataBlockSetsM, .DCacheMemWriteData,
 | 
			
		||||
					.DCacheFetchLine, .DCacheWriteLine,.DCacheBusAck);
 | 
			
		||||
	end else begin : passthrough
 | 
			
		||||
	  assign ReadDataWordM = 0;
 | 
			
		||||
	  assign DCacheStall = 0;
 | 
			
		||||
	  assign DCacheMiss = 1;
 | 
			
		||||
	  assign DCacheAccess = CacheableM;
 | 
			
		||||
	  assign DCacheCommittedM = 0;
 | 
			
		||||
	  assign DCacheWriteLine = 0;
 | 
			
		||||
	  assign DCacheFetchLine = 0;
 | 
			
		||||
	  assign DCacheBusAdr = 0;
 | 
			
		||||
	  assign ReadDataBlockSetsM[0] = 0;
 | 
			
		||||
	end
 | 
			
		||||
    if(`MEM_DCACHE) begin : dcache
 | 
			
		||||
      dcache dcache(.clk, .reset, .CPUBusy,
 | 
			
		||||
            .LsuRWM, .FlushDCacheM, .LsuAtomicM, .LsuAdrE, .LsuPAdrM,
 | 
			
		||||
            .FinalWriteDataM, .ReadDataWordM, .DCacheStall,
 | 
			
		||||
            .DCacheMiss, .DCacheAccess, 
 | 
			
		||||
            .IgnoreRequest, .CacheableM, .DCacheCommittedM,
 | 
			
		||||
            .DCacheBusAdr, .ReadDataBlockSetsM, .DCacheMemWriteData,
 | 
			
		||||
            .DCacheFetchLine, .DCacheWriteLine,.DCacheBusAck);
 | 
			
		||||
    end else begin : passthrough
 | 
			
		||||
      assign ReadDataWordM = 0;
 | 
			
		||||
      assign DCacheStall = 0;
 | 
			
		||||
      assign DCacheMiss = 1;
 | 
			
		||||
      assign DCacheAccess = CacheableM;
 | 
			
		||||
      assign DCacheCommittedM = 0;
 | 
			
		||||
      assign DCacheWriteLine = 0;
 | 
			
		||||
      assign DCacheFetchLine = 0;
 | 
			
		||||
      assign DCacheBusAdr = 0;
 | 
			
		||||
      assign ReadDataBlockSetsM[0] = 0;
 | 
			
		||||
    end
 | 
			
		||||
  endgenerate
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -48,162 +48,154 @@ module hptw
 | 
			
		||||
   output logic [2:0] 		   HPTWSize // 32 or 64 bit access.
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
      typedef enum  {L0_ADR, L0_RD, 
 | 
			
		||||
				     L1_ADR, L1_RD, 
 | 
			
		||||
				     L2_ADR, L2_RD, 
 | 
			
		||||
				     L3_ADR, L3_RD, 
 | 
			
		||||
				     LEAF, IDLE} statetype; // *** placed outside generate statement to remove synthesis errors
 | 
			
		||||
	typedef enum  {L0_ADR, L0_RD, 
 | 
			
		||||
					L1_ADR, L1_RD, 
 | 
			
		||||
					L2_ADR, L2_RD, 
 | 
			
		||||
					L3_ADR, L3_RD, 
 | 
			
		||||
					LEAF, IDLE} statetype; // *** placed outside generate statement to remove synthesis errors
 | 
			
		||||
 | 
			
		||||
  generate
 | 
			
		||||
    if (`MEM_VIRTMEM) begin:virtmem
 | 
			
		||||
      logic			    DTLBWalk; // register TLBs translation miss requests
 | 
			
		||||
      logic [`PPN_BITS-1:0]	    BasePageTablePPN;
 | 
			
		||||
      logic [`PPN_BITS-1:0]	    CurrentPPN;
 | 
			
		||||
      logic			    MemWrite;
 | 
			
		||||
      logic			    Executable, Writable, Readable, Valid;
 | 
			
		||||
	  logic 			Misaligned, MegapageMisaligned;
 | 
			
		||||
      logic			    ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE;
 | 
			
		||||
      logic			    StartWalk;
 | 
			
		||||
 	  logic     		TLBMiss;
 | 
			
		||||
      logic			    PRegEn;
 | 
			
		||||
	  logic [1:0]       NextPageType;
 | 
			
		||||
      logic [`SVMODE_BITS-1:0]	    SvMode;
 | 
			
		||||
      logic [`XLEN-1:0] 	    TranslationVAdr;
 | 
			
		||||
      
 | 
			
		||||
	  (* mark_debug = "true" *)      statetype WalkerState, NextWalkerState, InitialWalkerState;
 | 
			
		||||
	logic			    DTLBWalk; // register TLBs translation miss requests
 | 
			
		||||
	logic [`PPN_BITS-1:0]	    BasePageTablePPN;
 | 
			
		||||
	logic [`PPN_BITS-1:0]	    CurrentPPN;
 | 
			
		||||
	logic			    MemWrite;
 | 
			
		||||
	logic			    Executable, Writable, Readable, Valid;
 | 
			
		||||
	logic 			Misaligned, MegapageMisaligned;
 | 
			
		||||
	logic			    ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE;
 | 
			
		||||
	logic			    StartWalk;
 | 
			
		||||
	logic     		TLBMiss;
 | 
			
		||||
	logic			    PRegEn;
 | 
			
		||||
	logic [1:0]       NextPageType;
 | 
			
		||||
	logic [`SVMODE_BITS-1:0]	    SvMode;
 | 
			
		||||
	logic [`XLEN-1:0] 	    TranslationVAdr;
 | 
			
		||||
 | 
			
		||||
	  // Extract bits from CSRs and inputs
 | 
			
		||||
      assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS];
 | 
			
		||||
      assign BasePageTablePPN = SATP_REGW[`PPN_BITS-1:0];
 | 
			
		||||
      assign MemWrite = MemRWM[0];
 | 
			
		||||
	  assign TLBMiss = (DTLBMissM | ITLBMissF);
 | 
			
		||||
	(* mark_debug = "true" *)      statetype WalkerState, NextWalkerState, InitialWalkerState;
 | 
			
		||||
 | 
			
		||||
      // Determine which address to translate
 | 
			
		||||
 	  assign TranslationVAdr = DTLBWalk ? IEUAdrM : PCF;
 | 
			
		||||
      assign CurrentPPN = PTE[`PPN_BITS+9:10];
 | 
			
		||||
	// Extract bits from CSRs and inputs
 | 
			
		||||
	assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS];
 | 
			
		||||
	assign BasePageTablePPN = SATP_REGW[`PPN_BITS-1:0];
 | 
			
		||||
	assign MemWrite = MemRWM[0];
 | 
			
		||||
	assign TLBMiss = (DTLBMissM | ITLBMissF);
 | 
			
		||||
 | 
			
		||||
	  // State flops
 | 
			
		||||
 	  flopenr #(1) TLBMissMReg(clk, reset, StartWalk, DTLBMissM, DTLBWalk); // when walk begins, record whether it was for DTLB (or record 0 for ITLB)
 | 
			
		||||
	  assign PRegEn = HPTWRead & ~DCacheStall;
 | 
			
		||||
  	  flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, HPTWReadPTE, PTE); // Capture page table entry from data cache
 | 
			
		||||
	
 | 
			
		||||
      // Assign PTE descriptors common across all XLEN values
 | 
			
		||||
	  // For non-leaf PTEs, D, A, U bits are reserved and ignored.  They do not cause faults while walking the page table
 | 
			
		||||
      assign {Executable, Writable, Readable, Valid} = PTE[3:0]; 
 | 
			
		||||
      assign LeafPTE = Executable | Writable | Readable; 
 | 
			
		||||
      assign ValidPTE = Valid && ~(Writable && ~Readable);
 | 
			
		||||
	  assign ValidLeafPTE = ValidPTE & LeafPTE;
 | 
			
		||||
	  assign ValidNonLeafPTE = ValidPTE & ~LeafPTE;
 | 
			
		||||
	  
 | 
			
		||||
	  // Enable and select signals based on states
 | 
			
		||||
      assign StartWalk = (WalkerState == IDLE) & TLBMiss;
 | 
			
		||||
	  assign HPTWRead = (WalkerState == L3_RD) | (WalkerState == L2_RD) | (WalkerState == L1_RD) | (WalkerState == L0_RD);
 | 
			
		||||
	  assign DTLBWriteM = (WalkerState == LEAF) & DTLBWalk;
 | 
			
		||||
	  assign ITLBWriteF = (WalkerState == LEAF) & ~DTLBWalk;
 | 
			
		||||
	// Determine which address to translate
 | 
			
		||||
	assign TranslationVAdr = DTLBWalk ? IEUAdrM : PCF;
 | 
			
		||||
	assign CurrentPPN = PTE[`PPN_BITS+9:10];
 | 
			
		||||
 | 
			
		||||
	  // FSM to track PageType based on the levels of the page table traversed
 | 
			
		||||
	  flopr #(2) PageTypeReg(clk, reset, NextPageType, PageType);
 | 
			
		||||
	  always_comb 
 | 
			
		||||
		case (WalkerState)
 | 
			
		||||
			L3_RD:  NextPageType = 2'b11; // terapage
 | 
			
		||||
			L2_RD:  NextPageType = 2'b10; // gigapage
 | 
			
		||||
			L1_RD:  NextPageType = 2'b01; // megapage
 | 
			
		||||
			L0_RD:  NextPageType = 2'b00; // kilopage
 | 
			
		||||
			default: NextPageType = PageType;
 | 
			
		||||
	// State flops
 | 
			
		||||
	flopenr #(1) TLBMissMReg(clk, reset, StartWalk, DTLBMissM, DTLBWalk); // when walk begins, record whether it was for DTLB (or record 0 for ITLB)
 | 
			
		||||
	assign PRegEn = HPTWRead & ~DCacheStall;
 | 
			
		||||
	flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, HPTWReadPTE, PTE); // Capture page table entry from data cache
 | 
			
		||||
 | 
			
		||||
	// Assign PTE descriptors common across all XLEN values
 | 
			
		||||
	// For non-leaf PTEs, D, A, U bits are reserved and ignored.  They do not cause faults while walking the page table
 | 
			
		||||
	assign {Executable, Writable, Readable, Valid} = PTE[3:0]; 
 | 
			
		||||
	assign LeafPTE = Executable | Writable | Readable; 
 | 
			
		||||
	assign ValidPTE = Valid && ~(Writable && ~Readable);
 | 
			
		||||
	assign ValidLeafPTE = ValidPTE & LeafPTE;
 | 
			
		||||
	assign ValidNonLeafPTE = ValidPTE & ~LeafPTE;
 | 
			
		||||
 | 
			
		||||
	// Enable and select signals based on states
 | 
			
		||||
	assign StartWalk = (WalkerState == IDLE) & TLBMiss;
 | 
			
		||||
	assign HPTWRead = (WalkerState == L3_RD) | (WalkerState == L2_RD) | (WalkerState == L1_RD) | (WalkerState == L0_RD);
 | 
			
		||||
	assign DTLBWriteM = (WalkerState == LEAF) & DTLBWalk;
 | 
			
		||||
	assign ITLBWriteF = (WalkerState == LEAF) & ~DTLBWalk;
 | 
			
		||||
 | 
			
		||||
	// FSM to track PageType based on the levels of the page table traversed
 | 
			
		||||
	flopr #(2) PageTypeReg(clk, reset, NextPageType, PageType);
 | 
			
		||||
	always_comb 
 | 
			
		||||
	case (WalkerState)
 | 
			
		||||
		L3_RD:  NextPageType = 2'b11; // terapage
 | 
			
		||||
		L2_RD:  NextPageType = 2'b10; // gigapage
 | 
			
		||||
		L1_RD:  NextPageType = 2'b01; // megapage
 | 
			
		||||
		L0_RD:  NextPageType = 2'b00; // kilopage
 | 
			
		||||
		default: NextPageType = PageType;
 | 
			
		||||
	endcase
 | 
			
		||||
 | 
			
		||||
	// HPTWAdr muxing
 | 
			
		||||
	if (`XLEN==32) begin // RV32
 | 
			
		||||
	logic [9:0] VPN;
 | 
			
		||||
	logic [`PPN_BITS-1:0] PPN;
 | 
			
		||||
	assign VPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? TranslationVAdr[31:22] : TranslationVAdr[21:12]; // select VPN field based on HPTW state
 | 
			
		||||
	assign PPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? BasePageTablePPN : CurrentPPN; 
 | 
			
		||||
	assign HPTWAdr = {PPN, VPN, 2'b00};
 | 
			
		||||
	assign HPTWSize = 3'b010;
 | 
			
		||||
	end else begin // RV64
 | 
			
		||||
	logic [8:0] VPN;
 | 
			
		||||
	logic [`PPN_BITS-1:0] PPN;
 | 
			
		||||
	always_comb
 | 
			
		||||
		case (WalkerState) // select VPN field based on HPTW state
 | 
			
		||||
			L3_ADR, L3_RD:  			VPN = TranslationVAdr[47:39];
 | 
			
		||||
			L2_ADR, L2_RD:    VPN = TranslationVAdr[38:30];
 | 
			
		||||
			L1_ADR, L1_RD: 	VPN = TranslationVAdr[29:21];
 | 
			
		||||
			default:		 						VPN = TranslationVAdr[20:12];
 | 
			
		||||
		endcase
 | 
			
		||||
	assign PPN = ((WalkerState == L3_ADR) | (WalkerState == L3_RD) | 
 | 
			
		||||
					(SvMode != `SV48 & ((WalkerState == L2_ADR) | (WalkerState == L2_RD)))) ? BasePageTablePPN : CurrentPPN;
 | 
			
		||||
	assign HPTWAdr = {PPN, VPN, 3'b000};
 | 
			
		||||
	assign HPTWSize = 3'b011;
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	  // HPTWAdr muxing
 | 
			
		||||
	  if (`XLEN==32) begin // RV32
 | 
			
		||||
		logic [9:0] VPN;
 | 
			
		||||
		logic [`PPN_BITS-1:0] PPN;
 | 
			
		||||
		assign VPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? TranslationVAdr[31:22] : TranslationVAdr[21:12]; // select VPN field based on HPTW state
 | 
			
		||||
		assign PPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? BasePageTablePPN : CurrentPPN; 
 | 
			
		||||
		assign HPTWAdr = {PPN, VPN, 2'b00};
 | 
			
		||||
		assign HPTWSize = 3'b010;
 | 
			
		||||
	  end else begin // RV64
 | 
			
		||||
		logic [8:0] VPN;
 | 
			
		||||
		logic [`PPN_BITS-1:0] PPN;
 | 
			
		||||
		always_comb
 | 
			
		||||
			case (WalkerState) // select VPN field based on HPTW state
 | 
			
		||||
				L3_ADR, L3_RD:  			VPN = TranslationVAdr[47:39];
 | 
			
		||||
				L2_ADR, L2_RD:    VPN = TranslationVAdr[38:30];
 | 
			
		||||
				L1_ADR, L1_RD: 	VPN = TranslationVAdr[29:21];
 | 
			
		||||
				default:		 						VPN = TranslationVAdr[20:12];
 | 
			
		||||
			endcase
 | 
			
		||||
		assign PPN = ((WalkerState == L3_ADR) | (WalkerState == L3_RD) | 
 | 
			
		||||
		              (SvMode != `SV48 & ((WalkerState == L2_ADR) | (WalkerState == L2_RD)))) ? BasePageTablePPN : CurrentPPN;
 | 
			
		||||
		assign HPTWAdr = {PPN, VPN, 3'b000};
 | 
			
		||||
		assign HPTWSize = 3'b011;
 | 
			
		||||
	  end
 | 
			
		||||
	// Initial state and misalignment for RV32/64
 | 
			
		||||
	if (`XLEN == 32) begin
 | 
			
		||||
	assign InitialWalkerState = L1_ADR;
 | 
			
		||||
	assign MegapageMisaligned = |(CurrentPPN[9:0]); // must have zero PPN0
 | 
			
		||||
		// *** Possible bug - should be L1_ADR?
 | 
			
		||||
	assign Misaligned = ((WalkerState == L0_ADR) & MegapageMisaligned);
 | 
			
		||||
	end else begin
 | 
			
		||||
	logic  GigapageMisaligned, TerapageMisaligned;
 | 
			
		||||
	assign InitialWalkerState = (SvMode == `SV48) ? L3_ADR : L2_ADR;
 | 
			
		||||
	assign TerapageMisaligned = |(CurrentPPN[26:0]); // must have zero PPN2, PPN1, PPN0
 | 
			
		||||
	assign GigapageMisaligned = |(CurrentPPN[17:0]); // must have zero PPN1 and PPN0
 | 
			
		||||
	assign MegapageMisaligned = |(CurrentPPN[8:0]); // must have zero PPN0		  
 | 
			
		||||
	assign Misaligned = ((WalkerState == L2_ADR) & TerapageMisaligned) | ((WalkerState == L1_ADR) & GigapageMisaligned) | ((WalkerState == L0_ADR) & MegapageMisaligned);
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	  // Initial state and misalignment for RV32/64
 | 
			
		||||
	  if (`XLEN == 32) begin
 | 
			
		||||
		assign InitialWalkerState = L1_ADR;
 | 
			
		||||
		assign MegapageMisaligned = |(CurrentPPN[9:0]); // must have zero PPN0
 | 
			
		||||
	     // *** Possible bug - should be L1_ADR?
 | 
			
		||||
		assign Misaligned = ((WalkerState == L0_ADR) & MegapageMisaligned);
 | 
			
		||||
	  end else begin
 | 
			
		||||
		logic  GigapageMisaligned, TerapageMisaligned;
 | 
			
		||||
		assign InitialWalkerState = (SvMode == `SV48) ? L3_ADR : L2_ADR;
 | 
			
		||||
		assign TerapageMisaligned = |(CurrentPPN[26:0]); // must have zero PPN2, PPN1, PPN0
 | 
			
		||||
		assign GigapageMisaligned = |(CurrentPPN[17:0]); // must have zero PPN1 and PPN0
 | 
			
		||||
		assign MegapageMisaligned = |(CurrentPPN[8:0]); // must have zero PPN0		  
 | 
			
		||||
		assign Misaligned = ((WalkerState == L2_ADR) & TerapageMisaligned) | ((WalkerState == L1_ADR) & GigapageMisaligned) | ((WalkerState == L0_ADR) & MegapageMisaligned);
 | 
			
		||||
 	  end
 | 
			
		||||
 | 
			
		||||
    // Page Table Walker FSM
 | 
			
		||||
	// Page Table Walker FSM
 | 
			
		||||
	// If the setup time on the D$ RAM is short, it should be possible to merge the LEVELx_READ and LEVELx states
 | 
			
		||||
	// to decrease the latency of the HPTW.  However, if the D$ is a cycle limiter, it's better to leave the
 | 
			
		||||
	// HPTW as shown below to keep the D$ setup time out of the critical path.
 | 
			
		||||
	// *** Is this really true.  Talk with Ross.  Seems like it's the next state logic on critical path instead.
 | 
			
		||||
	flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState); 
 | 
			
		||||
	always_comb 
 | 
			
		||||
	  case (WalkerState)
 | 
			
		||||
	    IDLE: if (TLBMiss)	 		NextWalkerState = InitialWalkerState;
 | 
			
		||||
		      else 					NextWalkerState = IDLE;
 | 
			
		||||
	    L3_ADR: 			NextWalkerState = L3_RD; // first access in SV48
 | 
			
		||||
	    L3_RD: if (DCacheStall) NextWalkerState = L3_RD;
 | 
			
		||||
	                else 			NextWalkerState = L2_ADR;
 | 
			
		||||
//	    LEVEL3: if (ValidLeafPTE && ~Misaligned) NextWalkerState = LEAF;
 | 
			
		||||
//		  		else if (ValidNonLeafPTE) NextWalkerState = L2_ADR;
 | 
			
		||||
//		 		else 				NextWalkerState = FAULT;
 | 
			
		||||
	    L2_ADR: if (InitialWalkerState == L2_ADR) NextWalkerState = L2_RD; // first access in SV39
 | 
			
		||||
				else if (ValidLeafPTE && ~Misaligned) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
 | 
			
		||||
		  		else if (ValidNonLeafPTE) NextWalkerState = L2_RD;
 | 
			
		||||
        		else 				NextWalkerState = LEAF;
 | 
			
		||||
	    L2_RD: if (DCacheStall) NextWalkerState = L2_RD;
 | 
			
		||||
	      			else 			NextWalkerState = L1_ADR;
 | 
			
		||||
//	    LEVEL2: if (ValidLeafPTE && ~Misaligned) NextWalkerState = LEAF;
 | 
			
		||||
//				else if (ValidNonLeafPTE) NextWalkerState = L1_ADR;
 | 
			
		||||
//				else 				NextWalkerState = FAULT;
 | 
			
		||||
	    L1_ADR: if (InitialWalkerState == L1_ADR) NextWalkerState = L1_RD; // first access in SV32
 | 
			
		||||
				else if (ValidLeafPTE && ~Misaligned) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
 | 
			
		||||
		  		else if (ValidNonLeafPTE) NextWalkerState = L1_RD;
 | 
			
		||||
		 		else 				NextWalkerState = LEAF;	
 | 
			
		||||
	    L1_RD: if (DCacheStall) NextWalkerState = L1_RD;
 | 
			
		||||
	      			else 			NextWalkerState = L0_ADR;
 | 
			
		||||
//	    LEVEL1: if (ValidLeafPTE && ~Misaligned) NextWalkerState = LEAF;
 | 
			
		||||
//	      		else if (ValidNonLeafPTE) NextWalkerState = L0_ADR;
 | 
			
		||||
//				else 				NextWalkerState = FAULT;
 | 
			
		||||
	    L0_ADR: if (ValidLeafPTE && ~Misaligned) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
 | 
			
		||||
		  		else if (ValidNonLeafPTE) NextWalkerState = L0_RD;
 | 
			
		||||
		 		else 				NextWalkerState = LEAF;
 | 
			
		||||
	    L0_RD: if (DCacheStall) NextWalkerState = L0_RD;
 | 
			
		||||
	      			else 			NextWalkerState = LEAF;
 | 
			
		||||
//	    LEVEL0: if (ValidLeafPTE) 	NextWalkerState = LEAF;
 | 
			
		||||
//				else 				NextWalkerState = FAULT;
 | 
			
		||||
	    LEAF:                       NextWalkerState = IDLE; // updates TLB
 | 
			
		||||
	    default: begin
 | 
			
		||||
	      // synthesis translate_off
 | 
			
		||||
	      $error("Default state in HPTW should be unreachable");
 | 
			
		||||
	      // synthesis translate_on
 | 
			
		||||
	      NextWalkerState = IDLE; // should never be reached
 | 
			
		||||
	    end
 | 
			
		||||
	  endcase
 | 
			
		||||
    end else begin // No Virtual memory supported; tie HPTW outputs to 0
 | 
			
		||||
      assign HPTWRead = 0;
 | 
			
		||||
      assign HPTWAdr = 0;
 | 
			
		||||
	  assign HPTWSize = 3'b000;
 | 
			
		||||
    end
 | 
			
		||||
  endgenerate
 | 
			
		||||
	case (WalkerState)
 | 
			
		||||
	IDLE: if (TLBMiss)	 		NextWalkerState = InitialWalkerState;
 | 
			
		||||
			else 					NextWalkerState = IDLE;
 | 
			
		||||
	L3_ADR: 			NextWalkerState = L3_RD; // first access in SV48
 | 
			
		||||
	L3_RD: if (DCacheStall) NextWalkerState = L3_RD;
 | 
			
		||||
				else 			NextWalkerState = L2_ADR;
 | 
			
		||||
	//	    LEVEL3: if (ValidLeafPTE && ~Misaligned) NextWalkerState = LEAF;
 | 
			
		||||
	//		  		else if (ValidNonLeafPTE) NextWalkerState = L2_ADR;
 | 
			
		||||
	//		 		else 				NextWalkerState = FAULT;
 | 
			
		||||
	L2_ADR: if (InitialWalkerState == L2_ADR) NextWalkerState = L2_RD; // first access in SV39
 | 
			
		||||
			else if (ValidLeafPTE && ~Misaligned) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
 | 
			
		||||
			else if (ValidNonLeafPTE) NextWalkerState = L2_RD;
 | 
			
		||||
			else 				NextWalkerState = LEAF;
 | 
			
		||||
	L2_RD: if (DCacheStall) NextWalkerState = L2_RD;
 | 
			
		||||
				else 			NextWalkerState = L1_ADR;
 | 
			
		||||
	//	    LEVEL2: if (ValidLeafPTE && ~Misaligned) NextWalkerState = LEAF;
 | 
			
		||||
	//				else if (ValidNonLeafPTE) NextWalkerState = L1_ADR;
 | 
			
		||||
	//				else 				NextWalkerState = FAULT;
 | 
			
		||||
	L1_ADR: if (InitialWalkerState == L1_ADR) NextWalkerState = L1_RD; // first access in SV32
 | 
			
		||||
			else if (ValidLeafPTE && ~Misaligned) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
 | 
			
		||||
			else if (ValidNonLeafPTE) NextWalkerState = L1_RD;
 | 
			
		||||
			else 				NextWalkerState = LEAF;	
 | 
			
		||||
	L1_RD: if (DCacheStall) NextWalkerState = L1_RD;
 | 
			
		||||
				else 			NextWalkerState = L0_ADR;
 | 
			
		||||
	//	    LEVEL1: if (ValidLeafPTE && ~Misaligned) NextWalkerState = LEAF;
 | 
			
		||||
	//	      		else if (ValidNonLeafPTE) NextWalkerState = L0_ADR;
 | 
			
		||||
	//				else 				NextWalkerState = FAULT;
 | 
			
		||||
	L0_ADR: if (ValidLeafPTE && ~Misaligned) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
 | 
			
		||||
			else if (ValidNonLeafPTE) NextWalkerState = L0_RD;
 | 
			
		||||
			else 				NextWalkerState = LEAF;
 | 
			
		||||
	L0_RD: if (DCacheStall) NextWalkerState = L0_RD;
 | 
			
		||||
				else 			NextWalkerState = LEAF;
 | 
			
		||||
	//	    LEVEL0: if (ValidLeafPTE) 	NextWalkerState = LEAF;
 | 
			
		||||
	//				else 				NextWalkerState = FAULT;
 | 
			
		||||
	LEAF:                       NextWalkerState = IDLE; // updates TLB
 | 
			
		||||
	default: begin
 | 
			
		||||
		// synthesis translate_off
 | 
			
		||||
		$error("Default state in HPTW should be unreachable");
 | 
			
		||||
		// synthesis translate_on
 | 
			
		||||
		NextWalkerState = IDLE; // should never be reached
 | 
			
		||||
	end
 | 
			
		||||
	endcase
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user