From 73d4dd8c15d2b05b59af78445190df7b28e9f158 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Thu, 25 Mar 2021 14:43:10 -0400 Subject: [PATCH] Begin work on compressed instructions --- .../regression/wave-dos/ahb-waves.do | 1 - .../regression/wave-dos/cache-waves.do | 1 - wally-pipelined/src/ebu/ahblite.sv | 4 - wally-pipelined/src/ifu/icache.sv | 77 ++++++++++++++++--- .../testbench/testbench-imperas.sv | 2 +- 5 files changed, 69 insertions(+), 16 deletions(-) diff --git a/wally-pipelined/regression/wave-dos/ahb-waves.do b/wally-pipelined/regression/wave-dos/ahb-waves.do index c542f5841..263693d74 100644 --- a/wally-pipelined/regression/wave-dos/ahb-waves.do +++ b/wally-pipelined/regression/wave-dos/ahb-waves.do @@ -51,7 +51,6 @@ add wave -hex /testbench/dut/hart/ebu/HRDATA add wave -hex /testbench/dut/hart/ebu/HWRITE add wave -hex /testbench/dut/hart/ebu/HWDATA add wave -hex /testbench/dut/hart/ebu/CaptureDataM -add wave -hex /testbench/dut/hart/ebu/InstrStall add wave -divider add wave -hex /testbench/dut/uncore/dtim/* diff --git a/wally-pipelined/regression/wave-dos/cache-waves.do b/wally-pipelined/regression/wave-dos/cache-waves.do index bdd88a13f..20c7061b3 100644 --- a/wally-pipelined/regression/wave-dos/cache-waves.do +++ b/wally-pipelined/regression/wave-dos/cache-waves.do @@ -61,7 +61,6 @@ add wave -hex /testbench/dut/hart/ebu/HRDATA add wave -hex /testbench/dut/hart/ebu/HWRITE add wave -hex /testbench/dut/hart/ebu/HWDATA add wave -hex /testbench/dut/hart/ebu/CaptureDataM -add wave -hex /testbench/dut/hart/ebu/InstrStall add wave -divider add wave -hex /testbench/dut/uncore/dtim/* diff --git a/wally-pipelined/src/ebu/ahblite.sv b/wally-pipelined/src/ebu/ahblite.sv index c0aa27dba..73df76a38 100644 --- a/wally-pipelined/src/ebu/ahblite.sv +++ b/wally-pipelined/src/ebu/ahblite.sv @@ -136,10 +136,6 @@ module ahblite ( // stall signals assign #2 DataStall = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) || (NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE); - // *** Could get finer grained stalling if we distinguish between MMU - // instruction address translation and data address translation - assign #1 InstrStall = (NextBusState == INSTRREAD) || (NextBusState == INSTRREADC) || - (NextBusState == MMUTRANSLATE) || (NextBusState == MMUIDLE); // bus outputs assign #1 GrantData = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) || diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv index 631a9bd6d..09fb84ae6 100644 --- a/wally-pipelined/src/ifu/icache.sv +++ b/wally-pipelined/src/ifu/icache.sv @@ -127,11 +127,11 @@ module icachecontroller #(parameter LINESIZE = 256) ( logic [31:0] AlignedInstrRawF, AlignedInstrRawD; logic FlushDLastCycleN; + logic PCPMisalignedF; const logic [31:0] NOP = 32'h13; - // TODO allow compressed instructions - // (start with noncompressed only to get something working) - assign CompressedF = 1'b0; + // Detect if the instruction is compressed + assign CompressedF = AlignedInstrRawF[1:0] != 2'b11; // Handle happy path (data in cache, reads aligned) always_comb begin @@ -141,9 +141,13 @@ module icachecontroller #(parameter LINESIZE = 256) ( generate if (`XLEN == 32) begin - assign AlignedInstrRawF = ICacheMemReadData; + assign AlignedInstrRawF = LowerPCF[1] ? {16'b0, ICacheMemReadData[31:16]} : ICacheMemReadData; + assign PCPMisalignedF = LowerPCF[1] && ~CompressedF; end else begin - assign AlignedInstrRawF = LowerPCF[2] ? ICacheMemReadData[63:32] : ICacheMemReadData[31:0]; + assign AlignedInstrRawF = LowerPCF[2] + ? (LowerPCF[1] ? MisalignedInstrRawF : ICacheMemReadData[63:32]) + : (LowerPCF[1] ? ICacheMemReadData[47:16] : ICacheMemReadData[31:0]); + assign PCPMisalignedF = LowerPCF[2] && LowerPCF[1] && ~CompressedF; end endgenerate @@ -151,15 +155,70 @@ module icachecontroller #(parameter LINESIZE = 256) ( flopr #(1) FlushDLastCycleFlop(clk, reset, ~FlushD & (FlushDLastCycleN | ~StallF), FlushDLastCycleN); mux2 #(32) InstrRawDMux(AlignedInstrRawD, NOP, ~FlushDLastCycleN, InstrRawD); + // Stall for faults or misaligned reads + always_comb begin + 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 + + flopenr #(16) MisalignedHalfInstrFlop(clk, reset, ~FaultStall & (PCPMisalignedF & MisalignedState), AlignedInstrRawF[15:0], MisalignedHalfInstrF); + flopenr #(1) MisalignedStateFlop(clk, reset, ~FaultStall, NextMisalignedState, MisalignedState); + + 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 + 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 + end + end + // Handle cache faults localparam integer WORDSPERLINE = LINESIZE/`XLEN; localparam integer LOGWPL = $clog2(WORDSPERLINE); localparam integer OFFSETWIDTH = $clog2(LINESIZE/8); - logic FetchState, EndFetchState, BeginFetchState; - logic [LOGWPL:0] FetchWordNum, NextFetchWordNum; - logic [`XLEN-1:0] LineAlignedPCPF; + logic FetchState, EndFetchState, BeginFetchState; + logic FaultStall; + logic [LOGWPL:0] FetchWordNum, NextFetchWordNum; + logic [`XLEN-1:0] LineAlignedPCPF; flopr #(1) FetchStateFlop(clk, reset, BeginFetchState | (FetchState & ~EndFetchState), FetchState); flopr #(LOGWPL+1) FetchWordNumFlop(clk, reset, NextFetchWordNum, FetchWordNum); @@ -193,7 +252,7 @@ module icachecontroller #(parameter LINESIZE = 256) ( // Stall the pipeline while loading a new line from memory always_comb begin - assign ICacheStallF = FetchState | ~ICacheMemReadValid; + assign FaultStall = FetchState | ~ICacheMemReadValid; end endmodule diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 37d9883ee..b94c1b62c 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -340,7 +340,7 @@ string tests32i[] = { tests = testsBP64; end else begin tests = {tests64i}; - if (`C_SUPPORTED) tests = {tests, tests64ic}; + if (`C_SUPPORTED) tests = {tests64ic, tests}; else tests = {tests, tests64iNOc}; if (`M_SUPPORTED) tests = {tests, tests64m}; if (`A_SUPPORTED) tests = {tests, tests64a};