Works for misaligned instructions not on line boundaries

This commit is contained in:
Jarred Allen 2021-03-25 15:42:17 -04:00
parent 3b4f0141f4
commit 5f4feb0ff1

View File

@ -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;