forked from Github_Repos/cvw
		
	Works for misaligned instructions not on line boundaries
This commit is contained in:
		
							parent
							
								
									3b4f0141f4
								
							
						
					
					
						commit
						5f4feb0ff1
					
				@ -45,7 +45,7 @@ module icache(
 | 
			
		||||
  // High if the icache is requesting a stall
 | 
			
		||||
  output logic              ICacheStallF,
 | 
			
		||||
  // The raw (not decompressed) instruction that was requested
 | 
			
		||||
  // If the next instruction is compressed, the upper 16 bits may be anything
 | 
			
		||||
  // If this instruction is compressed, upper 16 bits may be the next 16 bits or may be zeros
 | 
			
		||||
  output logic [31:0]       InstrRawD
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
@ -125,23 +125,25 @@ module icachecontroller #(parameter LINESIZE = 256) (
 | 
			
		||||
    output logic             InstrReadF
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
    // Happy path signals
 | 
			
		||||
    logic [31:0]    AlignedInstrRawF, AlignedInstrRawD;
 | 
			
		||||
    logic           FlushDLastCycleN;
 | 
			
		||||
    logic           PCPMisalignedF;
 | 
			
		||||
    const logic [31:0] NOP = 32'h13;
 | 
			
		||||
    // Misaligned signals
 | 
			
		||||
    logic [`XLEN:0] MisalignedInstrRawF;
 | 
			
		||||
    logic           MisalignedStall;
 | 
			
		||||
    // Cache fault signals
 | 
			
		||||
    logic           FaultStall;
 | 
			
		||||
 | 
			
		||||
    // Detect if the instruction is compressed
 | 
			
		||||
    assign CompressedF = AlignedInstrRawF[1:0] != 2'b11;
 | 
			
		||||
 | 
			
		||||
    // Handle happy path (data in cache, reads aligned)
 | 
			
		||||
    always_comb begin
 | 
			
		||||
        assign ICacheMemReadLowerAdr = LowerPCF;
 | 
			
		||||
        assign ICacheMemReadUpperPAdr = UpperPCPF;
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    generate
 | 
			
		||||
        if (`XLEN == 32) begin
 | 
			
		||||
            assign AlignedInstrRawF = LowerPCF[1] ? {16'b0, ICacheMemReadData[31:16]} : ICacheMemReadData;
 | 
			
		||||
            assign AlignedInstrRawF = LowerPCF[1] ? MisalignedInstrRawF : ICacheMemReadData;
 | 
			
		||||
            assign PCPMisalignedF = LowerPCF[1] && ~CompressedF;
 | 
			
		||||
        end else begin
 | 
			
		||||
            assign AlignedInstrRawF = LowerPCF[2]
 | 
			
		||||
@ -160,54 +162,48 @@ module icachecontroller #(parameter LINESIZE = 256) (
 | 
			
		||||
        assign ICacheStallF = FaultStall | MisalignedStall;
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    // Handle misaligned, noncompressed reads
 | 
			
		||||
    logic           MisalignedState, NextMisalignedState;
 | 
			
		||||
    logic           MisalignedStall;
 | 
			
		||||
    logic [15:0]    MisalignedHalfInstrF;
 | 
			
		||||
    logic [`XLEN:0] MisalignedInstrRawF;
 | 
			
		||||
 | 
			
		||||
    always_comb begin
 | 
			
		||||
        assign MisalignedInstrRawF = {16'b0, ICacheMemReadData[63:48]};
 | 
			
		||||
    end
 | 
			
		||||
    // Handle misaligned, noncompressed reads
 | 
			
		||||
 | 
			
		||||
    logic           MisalignedState, NextMisalignedState;
 | 
			
		||||
    logic [15:0]    MisalignedHalfInstrF;
 | 
			
		||||
    logic [15:0]    UpperHalfWord;
 | 
			
		||||
 | 
			
		||||
    flopenr #(16) MisalignedHalfInstrFlop(clk, reset, ~FaultStall & (PCPMisalignedF & MisalignedState), AlignedInstrRawF[15:0], MisalignedHalfInstrF);
 | 
			
		||||
    flopenr #(1)  MisalignedStateFlop(clk, reset, ~FaultStall, NextMisalignedState, MisalignedState);
 | 
			
		||||
 | 
			
		||||
    // When doing a misaligned read, swizzle the bits correctly
 | 
			
		||||
    generate
 | 
			
		||||
        if (`XLEN == 32) begin
 | 
			
		||||
            assign UpperHalfWord = ICacheMemReadData[31:16];
 | 
			
		||||
        end else begin
 | 
			
		||||
            assign UpperHalfWord = ICacheMemReadData[63:48];
 | 
			
		||||
        end
 | 
			
		||||
    endgenerate
 | 
			
		||||
    always_comb begin
 | 
			
		||||
        if (MisalignedState) begin
 | 
			
		||||
            assign MisalignedInstrRawF = {16'b0, UpperHalfWord};
 | 
			
		||||
        end else begin
 | 
			
		||||
            assign MisalignedInstrRawF = {ICacheMemReadData[15:0], MisalignedHalfInstrF};
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    // Manage internal state and stall when necessary
 | 
			
		||||
    always_comb begin
 | 
			
		||||
        assign MisalignedStall = PCPMisalignedF & MisalignedState;
 | 
			
		||||
        assign NextMisalignedState = ~PCPMisalignedF | ~MisalignedState;
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    // Pick the correct address to read
 | 
			
		||||
    always_comb begin
 | 
			
		||||
        if (~PCPMisalignedF) begin
 | 
			
		||||
            assign ICacheMemReadUpperPAdr = UpperPCPF;
 | 
			
		||||
            generate
 | 
			
		||||
                if (`XLEN == 32)
 | 
			
		||||
                    assign ICacheMemReadLowerAdr = {LowerPCF[31:2], 2'b00};
 | 
			
		||||
                else
 | 
			
		||||
                    assign ICacheMemReadLowerAdr = {LowerPCF[31:3], 2'b000};
 | 
			
		||||
            endgenerate
 | 
			
		||||
    generate
 | 
			
		||||
        if (`XLEN == 32) begin
 | 
			
		||||
            assign ICacheMemReadLowerAdr = {LowerPCF[11:2] + (PCPMisalignedF & ~MisalignedState), 2'b00};
 | 
			
		||||
        end else begin
 | 
			
		||||
            if (MisalignedState) begin
 | 
			
		||||
                assign ICacheMemReadUpperPAdr = UpperPCPF;
 | 
			
		||||
                generate
 | 
			
		||||
                    if (`XLEN == 32)
 | 
			
		||||
                        assign ICacheMemReadLowerAdr = {LowerPCF[31:2]+1, 2'b00};
 | 
			
		||||
                    else
 | 
			
		||||
                        assign ICacheMemReadLowerAdr = {LowerPCF[31:3]+1, 2'b000};
 | 
			
		||||
                endgenerate
 | 
			
		||||
            end else begin
 | 
			
		||||
                assign ICacheMemReadUpperPAdr = UpperPCPF;
 | 
			
		||||
                generate
 | 
			
		||||
                    if (`XLEN == 32)
 | 
			
		||||
                        assign ICacheMemReadLowerAdr = {LowerPCF[31:2], 2'b00};
 | 
			
		||||
                    else
 | 
			
		||||
                        assign ICacheMemReadLowerAdr = {LowerPCF[31:3], 2'b000};
 | 
			
		||||
                endgenerate
 | 
			
		||||
            end
 | 
			
		||||
            assign ICacheMemReadLowerAdr = {LowerPCF[11:3] + (PCPMisalignedF & ~MisalignedState), 3'b00};
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    endgenerate
 | 
			
		||||
    assign ICacheMemReadUpperPAdr = UpperPCPF;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Handle cache faults
 | 
			
		||||
 | 
			
		||||
@ -216,7 +212,6 @@ module icachecontroller #(parameter LINESIZE = 256) (
 | 
			
		||||
    localparam integer OFFSETWIDTH = $clog2(LINESIZE/8);
 | 
			
		||||
 | 
			
		||||
    logic               FetchState, EndFetchState, BeginFetchState;
 | 
			
		||||
    logic               FaultStall;
 | 
			
		||||
    logic [LOGWPL:0]    FetchWordNum, NextFetchWordNum;
 | 
			
		||||
    logic [`XLEN-1:0]   LineAlignedPCPF;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user