From 5f4feb0ff12dae150ac3c782c7ed1d7304c96920 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Thu, 25 Mar 2021 15:42:17 -0400 Subject: [PATCH] Works for misaligned instructions not on line boundaries --- wally-pipelined/src/ifu/icache.sv | 79 +++++++++++++++---------------- 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv index 09fb84ae..85ec4cd3 100644 --- a/wally-pipelined/src/ifu/icache.sv +++ b/wally-pipelined/src/ifu/icache.sv @@ -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;