From e7e4105931e5b039fd6ef4baf3e31d2d9e854bb6 Mon Sep 17 00:00:00 2001 From: bbracker Date: Tue, 8 Jun 2021 12:32:46 -0400 Subject: [PATCH] * GPIO comprehensive testing * MEPC more aware if M stage has actually committed * UART interrupt testing progress * UART added read IIR side effect of lowering THRE intr --- wally-pipelined/src/dmem/dmem.sv | 17 ++++++--- wally-pipelined/src/ebu/ahblite.sv | 4 ++- wally-pipelined/src/privileged/privileged.sv | 7 ++-- wally-pipelined/src/privileged/trap.sv | 7 ++-- wally-pipelined/src/uncore/uartPC16550D.sv | 35 ++++++++++--------- .../src/wally/wallypipelinedhart.sv | 3 +- .../testbench/testbench-imperas.sv | 2 +- 7 files changed, 45 insertions(+), 30 deletions(-) diff --git a/wally-pipelined/src/dmem/dmem.sv b/wally-pipelined/src/dmem/dmem.sv index 67569f2e..68afaf7f 100644 --- a/wally-pipelined/src/dmem/dmem.sv +++ b/wally-pipelined/src/dmem/dmem.sv @@ -30,7 +30,7 @@ // *** Ross Thompson amo misalignment check? module dmem ( input logic clk, reset, - input logic StallW, FlushW, + input logic StallM, FlushM, StallW, FlushW, //output logic DataStall, // Memory Stage input logic [1:0] MemRWM, @@ -39,10 +39,12 @@ module dmem ( //input logic [`XLEN-1:0] ReadDataW, input logic [`XLEN-1:0] WriteDataM, input logic [1:0] AtomicM, + input logic CommitM, output logic [`XLEN-1:0] MemPAdrM, output logic MemReadM, MemWriteM, output logic [1:0] AtomicMaskedM, output logic DataMisalignedM, + output logic CommittedM, // Writeback Stage input logic MemAckW, input logic [`XLEN-1:0] ReadDataW, @@ -63,11 +65,11 @@ module dmem ( output logic DTLBMissM, DTLBHitM ); - logic SquashSCM; - logic DTLBPageFaultM; - logic MemAccessM; - + logic SquashSCM; + logic DTLBPageFaultM; + logic MemAccessM; logic [1:0] CurrState, NextState; + logic preCommittedM; localparam STATE_READY = 0; localparam STATE_FETCH = 1; @@ -104,6 +106,11 @@ module dmem ( assign AtomicMaskedM = CurrState != STATE_STALLED ? AtomicM : 2'b00 ; assign MemAccessM = |MemRWM; + // Determine if M stage committed + // Reset whenever unstalled. Set when access successfully occurs + flopr #(1) committedMreg(clk,reset,(CommittedM | CommitM) & StallM,preCommittedM); + assign CommittedM = preCommittedM | CommitM; + // Determine if address is valid assign LoadMisalignedFaultM = DataMisalignedM & MemRWM[1]; assign LoadAccessFaultM = DataAccessFaultM & MemRWM[1]; diff --git a/wally-pipelined/src/ebu/ahblite.sv b/wally-pipelined/src/ebu/ahblite.sv index a31448ea..b625129f 100644 --- a/wally-pipelined/src/ebu/ahblite.sv +++ b/wally-pipelined/src/ebu/ahblite.sv @@ -81,7 +81,7 @@ module ahblite ( output logic HWRITED, // Stalls output logic /*InstrUpdate, */DataStall, - output logic MemAckW + output logic CommitM, MemAckW ); logic GrantData; @@ -190,6 +190,8 @@ module ahblite ( assign InstrRData = HRDATA; assign InstrAckF = (BusState == INSTRREAD) && (NextBusState != INSTRREAD); + assign CommitM = (BusState == MEMREAD) || (BusState == MEMWRITE) || (BusState == ATOMICREAD) || (BusState == ATOMICWRITE); + // *** Bracker 6/5/21: why is this W stage? assign MemAckW = (BusState == MEMREAD) && (NextBusState != MEMREAD) || (BusState == MEMWRITE) && (NextBusState != MEMWRITE) || ((BusState == ATOMICREAD) && (NextBusState != ATOMICREAD)) || ((BusState == ATOMICWRITE) && (NextBusState != ATOMICWRITE)); assign MMUReadPTE = HRDATA; diff --git a/wally-pipelined/src/privileged/privileged.sv b/wally-pipelined/src/privileged/privileged.sv index a29fb56e..8e12bb17 100644 --- a/wally-pipelined/src/privileged/privileged.sv +++ b/wally-pipelined/src/privileged/privileged.sv @@ -28,7 +28,7 @@ module privileged ( input logic clk, reset, - input logic FlushW, + input logic FlushD, FlushE, FlushM, FlushW, StallD, StallW, StallE, StallM, input logic CSRReadM, CSRWriteM, input logic [`XLEN-1:0] SrcAM, input logic [`XLEN-1:0] PCF,PCD,PCE,PCM, @@ -37,7 +37,8 @@ module privileged ( output logic [`XLEN-1:0] PrivilegedNextPCM, output logic RetM, TrapM, NonBusTrapM, output logic ITLBFlushF, DTLBFlushM, - input logic InstrValidM,InstrValidW, FloatRegWriteW, LoadStallD, + input logic InstrValidM,InstrValidW, CommittedM, + input logic FloatRegWriteW, LoadStallD, input logic BPPredDirWrongM, input logic BTBPredPCWrongM, input logic RASPredPCWrongM, @@ -57,8 +58,6 @@ module privileged ( output logic [`XLEN-1:0] SATP_REGW, output logic STATUS_MXR, STATUS_SUM, output logic [2:0] FRM_REGW, - input logic FlushD, FlushE, FlushM, StallD, StallW, StallE, StallM, - // PMA checker signals input logic [31:0] HADDR, input logic [2:0] HSIZE, HBURST, diff --git a/wally-pipelined/src/privileged/trap.sv b/wally-pipelined/src/privileged/trap.sv index ee696d82..7e5218de 100644 --- a/wally-pipelined/src/privileged/trap.sv +++ b/wally-pipelined/src/privileged/trap.sv @@ -41,7 +41,7 @@ module trap ( input logic [`XLEN-1:0] InstrMisalignedAdrM, MemAdrM, input logic [31:0] InstrM, input logic StallW, - input logic InstrValidM, + input logic InstrValidM, CommittedM, output logic NonBusTrapM, TrapM, MTrapM, STrapM, UTrapM, RetM, output logic InterruptM, output logic [`XLEN-1:0] PrivilegedNextPCM, CauseM, NextFaultMtvalM @@ -58,7 +58,10 @@ module trap ( assign MIntGlobalEnM = {12{(PrivilegeModeW != `M_MODE) || STATUS_MIE}}; // if M ints enabled or lower priv 3.1.9 assign SIntGlobalEnM = (PrivilegeModeW == `U_MODE) || STATUS_SIE; // if S ints enabled or lower priv 3.1.9 assign PendingIntsM = (MIP_REGW & MIE_REGW) & ((MIntGlobalEnM & 12'h888) | (SIntGlobalEnM & 12'h222)); - assign InterruptM = (|PendingIntsM) && InstrValidM; // interrupt if any sources are pending // & with a M stage valid bit to avoid interrupts from interrupt a nonexistent flushed instruction (in the M stage) + assign InterruptM = (|PendingIntsM) & InstrValidM & ~CommittedM; + // interrupt if any sources are pending + // & with a M stage valid bit to avoid interrupts from interrupt a nonexistent flushed instruction (in the M stage) + // & with ~CommittedM to make sure MEPC isn't chosen so as to rerun the same instr twice // Trigger Traps and RET // Created groups of trap signals so that bus could take in all traps it doesn't already produce (i.e. using just TrapM to squash access created circular paths) diff --git a/wally-pipelined/src/uncore/uartPC16550D.sv b/wally-pipelined/src/uncore/uartPC16550D.sv index 6e173d59..0f539512 100644 --- a/wally-pipelined/src/uncore/uartPC16550D.sv +++ b/wally-pipelined/src/uncore/uartPC16550D.sv @@ -106,8 +106,8 @@ module uartPC16550D( logic fifoenabled, fifodmamodesel, evenparitysel; // interrupts - logic rxlinestatusintr, rxdataavailintr, txhremptyintr, modemstatusintr, intrpending; - logic [2:0] intrid; + logic rxlinestatusintr, rxdataavailintr, modemstatusintr, intrpending, THRE, suppressTHREbecauseIIR, suppressTHREbecauseIIRtrig; + logic [2:0] intrID; /////////////////////////////////////////// // Input synchronization: 2-stage synchronizer @@ -152,8 +152,8 @@ module uartPC16550D( if (RXBR[9]) LSR[2] <= #1 1; // parity error if (RXBR[8]) LSR[3] <= #1 1; // framing error if (rxbreak) LSR[4] <= #1 1; // break indicator - LSR[5] <= #1 txhremptyintr ; // THRE - LSR[6] <= #1 ~txsrfull & txhremptyintr; // TEMT + LSR[5] <= #1 THRE & ~(suppressTHREbecauseIIR | suppressTHREbecauseIIRtrig); // THRE (suppress trigger included to avoid 2-cycle delay) + LSR[6] <= #1 ~txsrfull & THRE; // TEMT if (rxfifohaserr) LSR[7] <= #1 1; // any bits in FIFO have error // Modem Status Register (8.6.8) @@ -168,7 +168,7 @@ module uartPC16550D( case (A) 3'b000: if (DLAB) Dout = DLL; else Dout = RBR; 3'b001: if (DLAB) Dout = DLM; else Dout = {4'b0, IER[3:0]}; - 3'b010: Dout = {{2{fifoenabled}}, 2'b00, intrid[2:0], ~intrpending}; // Read only Interupt Ident Register + 3'b010: Dout = {{2{fifoenabled}}, 2'b00, intrID[2:0], ~intrpending}; // Read only Interupt Ident Register 3'b011: Dout = LCR; 3'b100: Dout = {3'b000, MCR}; 3'b101: Dout = LSR; @@ -411,7 +411,7 @@ module uartPC16550D( always_comb if (fifoenabled & fifodmamodesel) TXRDYb = ~txfifodmaready; - else TXRDYb = ~txhremptyintr; + else TXRDYb = ~THRE; // Transmitter pin assign SOUTbit = txsr[11]; // transmit most significant bit @@ -420,28 +420,31 @@ module uartPC16550D( /////////////////////////////////////////// // interrupts /////////////////////////////////////////// - assign rxlinestatusintr = |LSR[4:1]; // LS interrupt if any of the flags are true assign rxdataavailintr = fifoenabled ? rxfifotriggered : rxdataready; - assign txhremptyintr = fifoenabled ? txfifoempty : ~txhrfull; + assign THRE = fifoenabled ? txfifoempty : ~txhrfull; assign modemstatusintr = |MSR[3:0]; // set interrupt when modem pins change - // interrupt priority (Table 5) - // set intrid based on highest priority pending interrupt source; otherwise, no interrupt is pending + // IIR: interrupt priority (Table 5) + // set intrID based on highest priority pending interrupt source; otherwise, no interrupt is pending always_comb begin intrpending = 1; - if (rxlinestatusintr & IER[2]) intrid = 3'b011; - else if (rxdataavailintr & IER[0]) intrid = 3'b010; - else if (rxfifotimeout & fifoenabled & IER[0]) intrid = 3'b110; - else if (txhremptyintr & IER[1]) intrid = 3'b001; - else if (modemstatusintr & IER[3]) intrid = 3'b000; + if (rxlinestatusintr & IER[2]) intrID = 3'b011; + else if (rxdataavailintr & IER[0]) intrID = 3'b010; + else if (rxfifotimeout & fifoenabled & IER[0]) intrID = 3'b110; + else if (THRE & IER[1] & ~suppressTHREbecauseIIR) intrID = 3'b001; + else if (modemstatusintr & IER[3]) intrID = 3'b000; else begin - intrid = 3'b000; + intrID = 3'b000; intrpending = 0; end end always @(posedge HCLK) INTR <= #1 intrpending; // prevent glitches on interrupt pin + // Side effect of reading IIR is lowering THRE if most significant intr + assign suppressTHREbecauseIIRtrig = ~MEMRb & (A==3'b010) & (intrID==2'h1); + flopr #(1) suppressTHREreg(HCLK, (~HRESETn | (fifoenabled ? ~txfifoempty : txhrfull)), (suppressTHREbecauseIIRtrig | suppressTHREbecauseIIR), suppressTHREbecauseIIR); + /////////////////////////////////////////// // modem control logic /////////////////////////////////////////// diff --git a/wally-pipelined/src/wally/wallypipelinedhart.sv b/wally-pipelined/src/wally/wallypipelinedhart.sv index aa252e37..9ab3feb8 100644 --- a/wally-pipelined/src/wally/wallypipelinedhart.sv +++ b/wally-pipelined/src/wally/wallypipelinedhart.sv @@ -138,6 +138,7 @@ module wallypipelinedhart ( logic InstrReadF; logic DataStall; logic InstrAckF, MemAckW; + logic CommitM, CommittedM; logic BPPredWrongE; logic BPPredDirWrongM; @@ -185,7 +186,7 @@ module wallypipelinedhart ( privileged priv(.*); - fpu fpu(.*); // floating point unit + fpu fpu(.*); // floating point unit // add FPU here, with SetFflagsM, FRM_REGW // presently stub out SetFlagsM and FloatRegWriteW //assign SetFflagsM = 0; diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index dabc6d12..0f33856b 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -489,7 +489,7 @@ string tests32f[] = '{ }; string tests64periph[] = '{ - "rv64i-periph/WALLY-PLIC", "2000" + "rv64i-periph/WALLY-PERIPH", "2000" }; string tests32periph[] = '{