mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Works for misaligned instructions not on line boundaries
This commit is contained in:
parent
73d4dd8c15
commit
fa6e6f1724
@ -45,7 +45,7 @@ module icache(
|
|||||||
// High if the icache is requesting a stall
|
// High if the icache is requesting a stall
|
||||||
output logic ICacheStallF,
|
output logic ICacheStallF,
|
||||||
// The raw (not decompressed) instruction that was requested
|
// 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
|
output logic [31:0] InstrRawD
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -125,23 +125,25 @@ module icachecontroller #(parameter LINESIZE = 256) (
|
|||||||
output logic InstrReadF
|
output logic InstrReadF
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Happy path signals
|
||||||
logic [31:0] AlignedInstrRawF, AlignedInstrRawD;
|
logic [31:0] AlignedInstrRawF, AlignedInstrRawD;
|
||||||
logic FlushDLastCycleN;
|
logic FlushDLastCycleN;
|
||||||
logic PCPMisalignedF;
|
logic PCPMisalignedF;
|
||||||
const logic [31:0] NOP = 32'h13;
|
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
|
// Detect if the instruction is compressed
|
||||||
assign CompressedF = AlignedInstrRawF[1:0] != 2'b11;
|
assign CompressedF = AlignedInstrRawF[1:0] != 2'b11;
|
||||||
|
|
||||||
// Handle happy path (data in cache, reads aligned)
|
// Handle happy path (data in cache, reads aligned)
|
||||||
always_comb begin
|
|
||||||
assign ICacheMemReadLowerAdr = LowerPCF;
|
|
||||||
assign ICacheMemReadUpperPAdr = UpperPCPF;
|
|
||||||
end
|
|
||||||
|
|
||||||
generate
|
generate
|
||||||
if (`XLEN == 32) begin
|
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;
|
assign PCPMisalignedF = LowerPCF[1] && ~CompressedF;
|
||||||
end else begin
|
end else begin
|
||||||
assign AlignedInstrRawF = LowerPCF[2]
|
assign AlignedInstrRawF = LowerPCF[2]
|
||||||
@ -160,54 +162,48 @@ module icachecontroller #(parameter LINESIZE = 256) (
|
|||||||
assign ICacheStallF = FaultStall | MisalignedStall;
|
assign ICacheStallF = FaultStall | MisalignedStall;
|
||||||
end
|
end
|
||||||
|
|
||||||
// Handle misaligned, noncompressed reads
|
|
||||||
logic MisalignedState, NextMisalignedState;
|
|
||||||
logic MisalignedStall;
|
|
||||||
logic [15:0] MisalignedHalfInstrF;
|
|
||||||
logic [`XLEN:0] MisalignedInstrRawF;
|
|
||||||
|
|
||||||
always_comb begin
|
// Handle misaligned, noncompressed reads
|
||||||
assign MisalignedInstrRawF = {16'b0, ICacheMemReadData[63:48]};
|
|
||||||
end
|
logic MisalignedState, NextMisalignedState;
|
||||||
|
logic [15:0] MisalignedHalfInstrF;
|
||||||
|
logic [15:0] UpperHalfWord;
|
||||||
|
|
||||||
flopenr #(16) MisalignedHalfInstrFlop(clk, reset, ~FaultStall & (PCPMisalignedF & MisalignedState), AlignedInstrRawF[15:0], MisalignedHalfInstrF);
|
flopenr #(16) MisalignedHalfInstrFlop(clk, reset, ~FaultStall & (PCPMisalignedF & MisalignedState), AlignedInstrRawF[15:0], MisalignedHalfInstrF);
|
||||||
flopenr #(1) MisalignedStateFlop(clk, reset, ~FaultStall, NextMisalignedState, MisalignedState);
|
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
|
always_comb begin
|
||||||
assign MisalignedStall = PCPMisalignedF & MisalignedState;
|
assign MisalignedStall = PCPMisalignedF & MisalignedState;
|
||||||
assign NextMisalignedState = ~PCPMisalignedF | ~MisalignedState;
|
assign NextMisalignedState = ~PCPMisalignedF | ~MisalignedState;
|
||||||
end
|
end
|
||||||
|
|
||||||
// Pick the correct address to read
|
// Pick the correct address to read
|
||||||
always_comb begin
|
generate
|
||||||
if (~PCPMisalignedF) begin
|
if (`XLEN == 32) begin
|
||||||
assign ICacheMemReadUpperPAdr = UpperPCPF;
|
assign ICacheMemReadLowerAdr = {LowerPCF[11:2] + (PCPMisalignedF & ~MisalignedState), 2'b00};
|
||||||
generate
|
|
||||||
if (`XLEN == 32)
|
|
||||||
assign ICacheMemReadLowerAdr = {LowerPCF[31:2], 2'b00};
|
|
||||||
else
|
|
||||||
assign ICacheMemReadLowerAdr = {LowerPCF[31:3], 2'b000};
|
|
||||||
endgenerate
|
|
||||||
end else begin
|
end else begin
|
||||||
if (MisalignedState) begin
|
assign ICacheMemReadLowerAdr = {LowerPCF[11:3] + (PCPMisalignedF & ~MisalignedState), 3'b00};
|
||||||
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
|
|
||||||
end
|
end
|
||||||
end
|
endgenerate
|
||||||
|
assign ICacheMemReadUpperPAdr = UpperPCPF;
|
||||||
|
|
||||||
|
|
||||||
// Handle cache faults
|
// Handle cache faults
|
||||||
|
|
||||||
@ -216,7 +212,6 @@ module icachecontroller #(parameter LINESIZE = 256) (
|
|||||||
localparam integer OFFSETWIDTH = $clog2(LINESIZE/8);
|
localparam integer OFFSETWIDTH = $clog2(LINESIZE/8);
|
||||||
|
|
||||||
logic FetchState, EndFetchState, BeginFetchState;
|
logic FetchState, EndFetchState, BeginFetchState;
|
||||||
logic FaultStall;
|
|
||||||
logic [LOGWPL:0] FetchWordNum, NextFetchWordNum;
|
logic [LOGWPL:0] FetchWordNum, NextFetchWordNum;
|
||||||
logic [`XLEN-1:0] LineAlignedPCPF;
|
logic [`XLEN-1:0] LineAlignedPCPF;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user