mirror of
https://github.com/openhwgroup/cvw
synced 2025-01-23 13:04:28 +00:00
Merge pull request #678 from Karl-Han/latest
[Resolved Conflict] Remove all #delay from non-testbench
This commit is contained in:
commit
bae52cf13d
4
src/cache/cachefsm.sv
vendored
4
src/cache/cachefsm.sv
vendored
@ -110,8 +110,8 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
|
||||
flop #(1) resetDelayReg(.clk, .d(reset), .q(resetDelay));
|
||||
|
||||
always_ff @(posedge clk)
|
||||
if (reset | FlushStage) CurrState <= #1 STATE_ACCESS;
|
||||
else CurrState <= #1 NextState;
|
||||
if (reset | FlushStage) CurrState <= STATE_ACCESS;
|
||||
else CurrState <= NextState;
|
||||
|
||||
always_comb begin
|
||||
NextState = STATE_ACCESS;
|
||||
|
16
src/cache/cacheway.sv
vendored
16
src/cache/cacheway.sv
vendored
@ -156,12 +156,12 @@ module cacheway import cvw::*; #(parameter cvw_t P,
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
always_ff @(posedge clk) begin // Valid bit array,
|
||||
if (reset) ValidBits <= #1 0;
|
||||
if (reset) ValidBits <= 0;
|
||||
if(CacheEn) begin
|
||||
ValidWay <= #1 ValidBits[CacheSetTag];
|
||||
if(InvalidateCache) ValidBits <= #1 0; // exclusion-tag: dcache invalidateway
|
||||
else if (SetValidEN) ValidBits[CacheSetData] <= #1 SetValidWay;
|
||||
else if (ClearValidEN) ValidBits[CacheSetData] <= #1 0; // exclusion-tag: icache ClearValidBits
|
||||
ValidWay <= ValidBits[CacheSetTag];
|
||||
if(InvalidateCache) ValidBits <= 0; // exclusion-tag: dcache invalidateway
|
||||
else if (SetValidEN) ValidBits[CacheSetData] <= SetValidWay;
|
||||
else if (ClearValidEN) ValidBits[CacheSetData] <= 0; // exclusion-tag: icache ClearValidBits
|
||||
end
|
||||
end
|
||||
|
||||
@ -173,10 +173,10 @@ module cacheway import cvw::*; #(parameter cvw_t P,
|
||||
if (!READ_ONLY_CACHE) begin:dirty
|
||||
always_ff @(posedge clk) begin
|
||||
// reset is optional. Consider merging with TAG array in the future.
|
||||
//if (reset) DirtyBits <= #1 {NUMLINES{1'b0}};
|
||||
//if (reset) DirtyBits <= {NUMLINES{1'b0}};
|
||||
if(CacheEn) begin
|
||||
Dirty <= #1 DirtyBits[CacheSetTag];
|
||||
if((SetDirtyWay | ClearDirtyWay) & ~FlushStage) DirtyBits[CacheSetData] <= #1 SetDirtyWay; // exclusion-tag: cache UpdateDirty
|
||||
Dirty <= DirtyBits[CacheSetTag];
|
||||
if((SetDirtyWay | ClearDirtyWay) & ~FlushStage) DirtyBits[CacheSetData] <= SetDirtyWay; // exclusion-tag: cache UpdateDirty
|
||||
end
|
||||
end
|
||||
end else assign Dirty = 1'b0;
|
||||
|
@ -82,8 +82,8 @@ module buscachefsm #(
|
||||
assign BusWrite = (CacheBusRW[0] | BusCMOZero) & ~READ_ONLY_CACHE;
|
||||
|
||||
always_ff @(posedge HCLK)
|
||||
if (~HRESETn | Flush) CurrState <= #1 ADR_PHASE;
|
||||
else CurrState <= #1 NextState;
|
||||
if (~HRESETn | Flush) CurrState <= ADR_PHASE;
|
||||
else CurrState <= NextState;
|
||||
|
||||
always_comb begin
|
||||
case(CurrState)
|
||||
|
@ -55,8 +55,8 @@ module busfsm #(
|
||||
busstatetype CurrState, NextState;
|
||||
|
||||
always_ff @(posedge HCLK)
|
||||
if (~HRESETn | Flush) CurrState <= #1 ADR_PHASE;
|
||||
else CurrState <= #1 NextState;
|
||||
if (~HRESETn | Flush) CurrState <= ADR_PHASE;
|
||||
else CurrState <= NextState;
|
||||
|
||||
always_comb begin
|
||||
case(CurrState)
|
||||
|
@ -250,7 +250,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
||||
/* verilator lint_on CASEINCOMPLETE */
|
||||
|
||||
// unswizzle control bits
|
||||
assign #1 {FRegWriteD, FWriteIntD, FResSelD, PostProcSelD, OpCtrlD, FDivStartD, IllegalFPUInstrD, FCvtIntD, ZfaD} = ControlsD;
|
||||
assign {FRegWriteD, FWriteIntD, FResSelD, PostProcSelD, OpCtrlD, FDivStartD, IllegalFPUInstrD, FCvtIntD, ZfaD} = ControlsD;
|
||||
|
||||
// rounding modes:
|
||||
// 000 - round to nearest, ties to even
|
||||
|
@ -63,17 +63,17 @@ module fdivsqrtfsm import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset | FlushE) begin
|
||||
state <= #1 IDLE;
|
||||
state <= IDLE;
|
||||
end else if (IFDivStartE) begin // IFDivStartE implies stat is IDLE
|
||||
step <= CyclesE;
|
||||
if (SpecialCaseE) state <= #1 DONE;
|
||||
else state <= #1 BUSY;
|
||||
if (SpecialCaseE) state <= DONE;
|
||||
else state <= BUSY;
|
||||
end else if (state == BUSY) begin
|
||||
if (step == 1 | WZeroE) state <= #1 DONE; // finished steps or terminate early on zero residual
|
||||
if (step == 1 | WZeroE) state <= DONE; // finished steps or terminate early on zero residual
|
||||
step <= step - 1;
|
||||
end else if (state == DONE) begin // Can't still be stalled in configs tested, but keep this check for paranoia
|
||||
if (StallM) state <= #1 DONE; // exclusion-tag: fdivsqrtfsm stallm
|
||||
else state <= #1 IDLE;
|
||||
if (StallM) state <= DONE; // exclusion-tag: fdivsqrtfsm stallm
|
||||
else state <= IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -47,8 +47,8 @@ module fregfile #(parameter FLEN) (
|
||||
if (reset) for(i=0; i<32; i++) rf[i] <= 0;
|
||||
else if (we4) rf[a4] <= wd4;
|
||||
|
||||
assign #2 rd1 = rf[a1];
|
||||
assign #2 rd2 = rf[a2];
|
||||
assign #2 rd3 = rf[a3];
|
||||
assign rd1 = rf[a1];
|
||||
assign rd2 = rf[a2];
|
||||
assign rd3 = rf[a3];
|
||||
|
||||
endmodule // regfile
|
||||
|
@ -31,6 +31,6 @@ module flop #(parameter WIDTH = 8) (
|
||||
output logic [WIDTH-1:0] q);
|
||||
|
||||
always_ff @(posedge clk)
|
||||
q <= #1 d;
|
||||
q <= d;
|
||||
endmodule
|
||||
|
||||
|
@ -31,6 +31,6 @@ module flopen #(parameter WIDTH = 8) (
|
||||
output logic [WIDTH-1:0] q);
|
||||
|
||||
always_ff @(posedge clk)
|
||||
if (en) q <= #1 d;
|
||||
if (en) q <= d;
|
||||
endmodule
|
||||
|
||||
|
@ -32,7 +32,7 @@ module flopenl #(parameter WIDTH = 8, parameter type TYPE=logic [WIDTH-1:0]) (
|
||||
output TYPE q);
|
||||
|
||||
always_ff @(posedge clk)
|
||||
if (load) q <= #1 val;
|
||||
else if (en) q <= #1 d;
|
||||
if (load) q <= val;
|
||||
else if (en) q <= d;
|
||||
endmodule
|
||||
|
||||
|
@ -31,7 +31,7 @@ module flopenr #(parameter WIDTH = 8) (
|
||||
output logic [WIDTH-1:0] q);
|
||||
|
||||
always_ff @(posedge clk)
|
||||
if (reset) q <= #1 0;
|
||||
else if (en) q <= #1 d;
|
||||
if (reset) q <= 0;
|
||||
else if (en) q <= d;
|
||||
endmodule
|
||||
|
||||
|
@ -31,9 +31,9 @@ module flopenrc #(parameter WIDTH = 8) (
|
||||
output logic [WIDTH-1:0] q);
|
||||
|
||||
always_ff @(posedge clk)
|
||||
if (reset) q <= #1 0;
|
||||
if (reset) q <= 0;
|
||||
else if (en)
|
||||
if (clear) q <= #1 0;
|
||||
else q <= #1 d;
|
||||
if (clear) q <= 0;
|
||||
else q <= d;
|
||||
endmodule
|
||||
|
||||
|
@ -31,8 +31,8 @@ module flopens #(parameter WIDTH = 8) (
|
||||
output logic [WIDTH-1:0] q);
|
||||
|
||||
always_ff @(posedge clk)
|
||||
if (set) q <= #1 1;
|
||||
else if (en) q <= #1 d;
|
||||
if (set) q <= 1;
|
||||
else if (en) q <= d;
|
||||
endmodule
|
||||
|
||||
|
||||
|
@ -31,7 +31,7 @@ module flopr #(parameter WIDTH = 8) (
|
||||
output logic [WIDTH-1:0] q);
|
||||
|
||||
always_ff @(posedge clk)
|
||||
if (reset) q <= #1 0;
|
||||
else q <= #1 d;
|
||||
if (reset) q <= 0;
|
||||
else q <= d;
|
||||
endmodule
|
||||
|
||||
|
@ -33,8 +33,8 @@ module synchronizer (
|
||||
logic mid;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
mid <= #1 d;
|
||||
q <= #1 mid;
|
||||
mid <= d;
|
||||
q <= mid;
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
@ -97,7 +97,7 @@ module ram1p1rwbe import cvw::*; #(parameter USE_SRAM=0, DEPTH=64, WIDTH=44, PRE
|
||||
|
||||
/* // Alternate read logic reads the old contents of mem[addr]. Increases setup time and adds dout reg, but reduces clk to q
|
||||
always_ff @(posedge clk)
|
||||
if(ce) dout <= #1 mem[addr]; */
|
||||
if(ce) dout <= mem[addr]; */
|
||||
|
||||
// Write divided into part for bytes and part for extra msbs
|
||||
// Questa sim version 2022.3_2 does not allow multiple drivers for RAM when using always_ff.
|
||||
@ -106,12 +106,12 @@ module ram1p1rwbe import cvw::*; #(parameter USE_SRAM=0, DEPTH=64, WIDTH=44, PRE
|
||||
always @(posedge clk)
|
||||
if (ce & we)
|
||||
for(i = 0; i < WIDTH/8; i++)
|
||||
if(bwe[i]) RAM[addr][i*8 +: 8] <= #1 din[i*8 +: 8];
|
||||
if(bwe[i]) RAM[addr][i*8 +: 8] <= din[i*8 +: 8];
|
||||
|
||||
if (WIDTH%8 != 0) // handle msbs if width not a multiple of 8
|
||||
always @(posedge clk)
|
||||
if (ce & we & bwe[WIDTH/8])
|
||||
RAM[addr][WIDTH-1:WIDTH-WIDTH%8] <= #1 din[WIDTH-1:WIDTH-WIDTH%8];
|
||||
RAM[addr][WIDTH-1:WIDTH-WIDTH%8] <= din[WIDTH-1:WIDTH-WIDTH%8];
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
@ -78,7 +78,7 @@ module ram1p1rwe import cvw::* ; #(parameter USE_SRAM=0, DEPTH=64, WIDTH=44) (
|
||||
|
||||
/* // Alternate read logic reads the old contents of mem[addr]. Increases setup time and adds dout reg, but reduces clk to q
|
||||
always_ff @(posedge clk)
|
||||
if(ce) dout <= #1 mem[addr]; */
|
||||
if(ce) dout <= mem[addr]; */
|
||||
|
||||
// Write divided into part for bytes and part for extra msbs
|
||||
// Questa sim version 2022.3_2 does not allow multiple drivers for RAM when using always_ff.
|
||||
@ -90,6 +90,6 @@ module ram1p1rwe import cvw::* ; #(parameter USE_SRAM=0, DEPTH=64, WIDTH=44) (
|
||||
// so we can never get we=1, ce=0 for I$.
|
||||
if (ce & we)
|
||||
// coverage on
|
||||
RAM[addr] <= #1 din;
|
||||
RAM[addr] <= din;
|
||||
end
|
||||
endmodule
|
||||
|
@ -130,13 +130,13 @@ module ram2p1r1wbe import cvw::*; #(parameter USE_SRAM=0, DEPTH=1024, WIDTH=68)
|
||||
always @(posedge clk)
|
||||
if (ce2 & we2)
|
||||
for(i = 0; i < WIDTH/8; i++)
|
||||
if(bwe2[i]) mem[wa2][i*8 +: 8] <= #1 wd2[i*8 +: 8];
|
||||
if(bwe2[i]) mem[wa2][i*8 +: 8] <= wd2[i*8 +: 8];
|
||||
// coverage on
|
||||
|
||||
if (WIDTH%8 != 0) // handle msbs if width not a multiple of 8
|
||||
always @(posedge clk)
|
||||
if (ce2 & we2 & bwe2[WIDTH/8])
|
||||
mem[wa2][WIDTH-1:WIDTH-WIDTH%8] <= #1 wd2[WIDTH-1:WIDTH-WIDTH%8];
|
||||
mem[wa2][WIDTH-1:WIDTH-WIDTH%8] <= wd2[WIDTH-1:WIDTH-WIDTH%8];
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
@ -93,12 +93,12 @@ module hazard import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
// Stall each stage for cause or if the next stage is stalled
|
||||
// coverage off: StallFCause is always 0
|
||||
assign #1 StallF = StallFCause | StallD;
|
||||
assign StallF = StallFCause | StallD;
|
||||
// coverage on
|
||||
assign #1 StallD = StallDCause | StallE;
|
||||
assign #1 StallE = StallECause | StallM;
|
||||
assign #1 StallM = StallMCause | StallW;
|
||||
assign #1 StallW = StallWCause;
|
||||
assign StallD = StallDCause | StallE;
|
||||
assign StallE = StallECause | StallM;
|
||||
assign StallM = StallMCause | StallW;
|
||||
assign StallW = StallWCause;
|
||||
|
||||
// detect the first stage that is not stalled
|
||||
assign LatestUnstalledD = ~StallD & StallF;
|
||||
@ -107,8 +107,8 @@ module hazard import cvw::*; #(parameter cvw_t P) (
|
||||
assign LatestUnstalledW = ~StallW & StallM;
|
||||
|
||||
// Each stage flushes if the previous stage is the last one stalled (for cause) or the system has reason to flush
|
||||
assign #1 FlushD = LatestUnstalledD | FlushDCause;
|
||||
assign #1 FlushE = LatestUnstalledE | FlushECause;
|
||||
assign #1 FlushM = LatestUnstalledM | FlushMCause;
|
||||
assign #1 FlushW = LatestUnstalledW | FlushWCause;
|
||||
assign FlushD = LatestUnstalledD | FlushDCause;
|
||||
assign FlushE = LatestUnstalledE | FlushECause;
|
||||
assign FlushM = LatestUnstalledM | FlushMCause;
|
||||
assign FlushW = LatestUnstalledW | FlushWCause;
|
||||
endmodule
|
||||
|
@ -53,6 +53,6 @@ module regfile #(parameter XLEN, E_SUPPORTED) (
|
||||
if (reset) for(i=1; i<NUMREGS; i++) rf[i] <= 0;
|
||||
else if (we3) rf[a3] <= wd3;
|
||||
|
||||
assign #2 rd1 = (a1 != 0) ? rf[a1] : 0;
|
||||
assign #2 rd2 = (a2 != 0) ? rf[a2] : 0;
|
||||
assign rd1 = (a1 != 0) ? rf[a1] : 0;
|
||||
assign rd2 = (a2 != 0) ? rf[a2] : 0;
|
||||
endmodule
|
||||
|
@ -92,7 +92,7 @@ module RASPredictor import cvw::*; #(parameter cvw_t P)(
|
||||
for(index=0; index<P.RAS_SIZE; index++)
|
||||
memory[index] <= {P.XLEN{1'b0}};
|
||||
end else if(PushE) begin
|
||||
memory[NextPtr] <= #1 PCLinkE;
|
||||
memory[NextPtr] <= PCLinkE;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -113,10 +113,10 @@ module localrepairbp import cvw::*; #(parameter cvw_t P,
|
||||
// **** replace with small CAM
|
||||
logic [2**m-1:0] FlushedBits;
|
||||
always_ff @(posedge clk) begin // Valid bit array,
|
||||
SpeculativeFlushedF <= #1 FlushedBits[IndexLHRNextF];
|
||||
if (reset | FlushD) FlushedBits <= #1 '1;
|
||||
SpeculativeFlushedF <= FlushedBits[IndexLHRNextF];
|
||||
if (reset | FlushD) FlushedBits <= '1;
|
||||
if(BranchD & ~StallE & ~FlushE) begin
|
||||
FlushedBits[IndexLHRD] <= #1 0;
|
||||
FlushedBits[IndexLHRD] <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -89,8 +89,8 @@ module spill import cvw::*; #(parameter cvw_t P) (
|
||||
assign TakeSpillF = SpillF & ~EarlyCompressedF & ~IFUCacheBusStallF & ~(ITLBMissF | (P.SVADU_SUPPORTED & InstrUpdateDAF));
|
||||
|
||||
always_ff @(posedge clk)
|
||||
if (reset | FlushD) CurrState <= #1 STATE_READY;
|
||||
else CurrState <= #1 NextState;
|
||||
if (reset | FlushD) CurrState <= STATE_READY;
|
||||
else CurrState <= NextState;
|
||||
|
||||
always_comb begin
|
||||
case (CurrState)
|
||||
|
@ -117,8 +117,8 @@ module align import cvw::*; #(parameter cvw_t P) (
|
||||
assign ValidSpillM = MisalignedM & PotentialSpillM & ~CacheBusHPWTStall; // Don't take the spill if there is a stall
|
||||
|
||||
always_ff @(posedge clk)
|
||||
if (reset | FlushM) CurrState <= #1 STATE_READY;
|
||||
else CurrState <= #1 NextState;
|
||||
if (reset | FlushM) CurrState <= STATE_READY;
|
||||
else CurrState <= NextState;
|
||||
|
||||
always_comb begin
|
||||
case (CurrState)
|
||||
|
@ -130,8 +130,8 @@ module csrc import cvw::*; #(parameter cvw_t P) (
|
||||
assign WriteHPMCOUNTERM[i] = CSRMWriteM & (CSRAdrM == MHPMCOUNTERBASE + i);
|
||||
assign NextHPMCOUNTERM[i][P.XLEN-1:0] = WriteHPMCOUNTERM[i] ? CSRWriteValM : HPMCOUNTERPlusM[i][P.XLEN-1:0];
|
||||
always_ff @(posedge clk) //, posedge reset) // ModelSim doesn't like syntax of passing array element to flop
|
||||
if (reset) HPMCOUNTER_REGW[i][P.XLEN-1:0] <= #1 0;
|
||||
else HPMCOUNTER_REGW[i][P.XLEN-1:0] <= #1 NextHPMCOUNTERM[i];
|
||||
if (reset) HPMCOUNTER_REGW[i][P.XLEN-1:0] <= 0;
|
||||
else HPMCOUNTER_REGW[i][P.XLEN-1:0] <= NextHPMCOUNTERM[i];
|
||||
|
||||
if (P.XLEN==32) begin // write high and low separately
|
||||
logic [P.COUNTERS-1:0] WriteHPMCOUNTERHM;
|
||||
@ -140,8 +140,8 @@ module csrc import cvw::*; #(parameter cvw_t P) (
|
||||
assign WriteHPMCOUNTERHM[i] = CSRMWriteM & (CSRAdrM == MHPMCOUNTERHBASE + i);
|
||||
assign NextHPMCOUNTERHM[i] = WriteHPMCOUNTERHM[i] ? CSRWriteValM : HPMCOUNTERPlusM[i][63:32];
|
||||
always_ff @(posedge clk) //, posedge reset) // ModelSim doesn't like syntax of passing array element to flop
|
||||
if (reset) HPMCOUNTERH_REGW[i][P.XLEN-1:0] <= #1 0;
|
||||
else HPMCOUNTERH_REGW[i][P.XLEN-1:0] <= #1 NextHPMCOUNTERHM[i];
|
||||
if (reset) HPMCOUNTERH_REGW[i][P.XLEN-1:0] <= 0;
|
||||
else HPMCOUNTERH_REGW[i][P.XLEN-1:0] <= NextHPMCOUNTERHM[i];
|
||||
end else begin // XLEN=64; write entire register
|
||||
assign HPMCOUNTERPlusM[i] = HPMCOUNTER_REGW[i] + {63'b0, CounterEvent[i] & ~MCOUNTINHIBIT_REGW[i]};
|
||||
end
|
||||
|
@ -140,22 +140,22 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
|
||||
// complex register with reset, write enable, and the ability to update other bits in certain cases
|
||||
always_ff @(posedge clk) //, posedge reset)
|
||||
if (reset) begin
|
||||
STATUS_TSR_INT <= #1 0;
|
||||
STATUS_TW_INT <= #1 0;
|
||||
STATUS_TVM_INT <= #1 0;
|
||||
STATUS_MXR_INT <= #1 0;
|
||||
STATUS_SUM_INT <= #1 0;
|
||||
STATUS_MPRV_INT <= #1 0; // Per Priv 3.3
|
||||
STATUS_FS_INT <= #1 P.F_SUPPORTED ? 2'b00 : 2'b00; // leave floating-point off until activated, even if F_SUPPORTED
|
||||
STATUS_MPP <= #1 0;
|
||||
STATUS_SPP <= #1 0;
|
||||
STATUS_MPIE <= #1 0;
|
||||
STATUS_SPIE <= #1 0;
|
||||
STATUS_MIE <= #1 0;
|
||||
STATUS_SIE <= #1 0;
|
||||
STATUS_MBE <= #1 0;
|
||||
STATUS_SBE <= #1 0;
|
||||
STATUS_UBE <= #1 0;
|
||||
STATUS_TSR_INT <= 0;
|
||||
STATUS_TW_INT <= 0;
|
||||
STATUS_TVM_INT <= 0;
|
||||
STATUS_MXR_INT <= 0;
|
||||
STATUS_SUM_INT <= 0;
|
||||
STATUS_MPRV_INT <= 0; // Per Priv 3.3
|
||||
STATUS_FS_INT <= P.F_SUPPORTED ? 2'b00 : 2'b00; // leave floating-point off until activated, even if F_SUPPORTED
|
||||
STATUS_MPP <= 0;
|
||||
STATUS_SPP <= 0;
|
||||
STATUS_MPIE <= 0;
|
||||
STATUS_SPIE <= 0;
|
||||
STATUS_MIE <= 0;
|
||||
STATUS_SIE <= 0;
|
||||
STATUS_MBE <= 0;
|
||||
STATUS_SBE <= 0;
|
||||
STATUS_UBE <= 0;
|
||||
end else if (~StallW) begin
|
||||
if (TrapM) begin
|
||||
// Update interrupt enables per Privileged Spec p. 21
|
||||
@ -163,55 +163,55 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
|
||||
// x = NextPrivilegeModeM
|
||||
// Modes: 11 = Machine, 01 = Supervisor, 00 = User
|
||||
if (NextPrivilegeModeM == P.M_MODE) begin
|
||||
STATUS_MPIE <= #1 STATUS_MIE;
|
||||
STATUS_MIE <= #1 0;
|
||||
STATUS_MPP <= #1 PrivilegeModeW;
|
||||
STATUS_MPIE <= STATUS_MIE;
|
||||
STATUS_MIE <= 0;
|
||||
STATUS_MPP <= PrivilegeModeW;
|
||||
end else begin // supervisor mode
|
||||
STATUS_SPIE <= #1 STATUS_SIE;
|
||||
STATUS_SIE <= #1 0;
|
||||
STATUS_SPP <= #1 PrivilegeModeW[0];
|
||||
STATUS_SPIE <= STATUS_SIE;
|
||||
STATUS_SIE <= 0;
|
||||
STATUS_SPP <= PrivilegeModeW[0];
|
||||
end
|
||||
end else if (mretM) begin // Privileged 3.1.6.1
|
||||
STATUS_MIE <= #1 STATUS_MPIE; // restore global interrupt enable
|
||||
STATUS_MPIE <= #1 1; //
|
||||
STATUS_MPP <= #1 P.U_SUPPORTED ? P.U_MODE : P.M_MODE; // set MPP to lowest supported privilege level
|
||||
STATUS_MPRV_INT <= #1 STATUS_MPRV_INT & (STATUS_MPP == P.M_MODE); // page 21 of privileged spec.
|
||||
STATUS_MIE <= STATUS_MPIE; // restore global interrupt enable
|
||||
STATUS_MPIE <= 1; //
|
||||
STATUS_MPP <= P.U_SUPPORTED ? P.U_MODE : P.M_MODE; // set MPP to lowest supported privilege level
|
||||
STATUS_MPRV_INT <= STATUS_MPRV_INT & (STATUS_MPP == P.M_MODE); // page 21 of privileged spec.
|
||||
end else if (sretM) begin
|
||||
STATUS_SIE <= #1 STATUS_SPIE; // restore global interrupt enable
|
||||
STATUS_SPIE <= #1 P.S_SUPPORTED;
|
||||
STATUS_SPP <= #1 0; // set SPP to lowest supported privilege level to catch bugs
|
||||
STATUS_MPRV_INT <= #1 0; // always clear MPRV
|
||||
STATUS_SIE <= STATUS_SPIE; // restore global interrupt enable
|
||||
STATUS_SPIE <= P.S_SUPPORTED;
|
||||
STATUS_SPP <= 0; // set SPP to lowest supported privilege level to catch bugs
|
||||
STATUS_MPRV_INT <= 0; // always clear MPRV
|
||||
end else if (WriteMSTATUSM) begin
|
||||
STATUS_TSR_INT <= #1 CSRWriteValM[22];
|
||||
STATUS_TW_INT <= #1 CSRWriteValM[21];
|
||||
STATUS_TVM_INT <= #1 CSRWriteValM[20];
|
||||
STATUS_MXR_INT <= #1 CSRWriteValM[19];
|
||||
STATUS_SUM_INT <= #1 CSRWriteValM[18];
|
||||
STATUS_MPRV_INT <= #1 CSRWriteValM[17];
|
||||
STATUS_FS_INT <= #1 CSRWriteValM[14:13];
|
||||
STATUS_MPP <= #1 STATUS_MPP_NEXT;
|
||||
STATUS_SPP <= #1 P.S_SUPPORTED & CSRWriteValM[8];
|
||||
STATUS_MPIE <= #1 CSRWriteValM[7];
|
||||
STATUS_SPIE <= #1 P.S_SUPPORTED & CSRWriteValM[5];
|
||||
STATUS_MIE <= #1 CSRWriteValM[3];
|
||||
STATUS_SIE <= #1 P.S_SUPPORTED & CSRWriteValM[1];
|
||||
STATUS_UBE <= #1 CSRWriteValM[6] & P.U_SUPPORTED & P.BIGENDIAN_SUPPORTED;
|
||||
STATUS_MBE <= #1 nextMBE;
|
||||
STATUS_SBE <= #1 nextSBE;
|
||||
STATUS_TSR_INT <= CSRWriteValM[22];
|
||||
STATUS_TW_INT <= CSRWriteValM[21];
|
||||
STATUS_TVM_INT <= CSRWriteValM[20];
|
||||
STATUS_MXR_INT <= CSRWriteValM[19];
|
||||
STATUS_SUM_INT <= CSRWriteValM[18];
|
||||
STATUS_MPRV_INT <= CSRWriteValM[17];
|
||||
STATUS_FS_INT <= CSRWriteValM[14:13];
|
||||
STATUS_MPP <= STATUS_MPP_NEXT;
|
||||
STATUS_SPP <= P.S_SUPPORTED & CSRWriteValM[8];
|
||||
STATUS_MPIE <= CSRWriteValM[7];
|
||||
STATUS_SPIE <= P.S_SUPPORTED & CSRWriteValM[5];
|
||||
STATUS_MIE <= CSRWriteValM[3];
|
||||
STATUS_SIE <= P.S_SUPPORTED & CSRWriteValM[1];
|
||||
STATUS_UBE <= CSRWriteValM[6] & P.U_SUPPORTED & P.BIGENDIAN_SUPPORTED;
|
||||
STATUS_MBE <= nextMBE;
|
||||
STATUS_SBE <= nextSBE;
|
||||
// coverage off
|
||||
// MSTATUSH only exists in 32-bit configurations, will not be hit on rv64gc
|
||||
end else if (WriteMSTATUSHM) begin
|
||||
STATUS_MBE <= #1 CSRWriteValM[5] & P.BIGENDIAN_SUPPORTED;
|
||||
STATUS_SBE <= #1 CSRWriteValM[4] & P.S_SUPPORTED & P.BIGENDIAN_SUPPORTED;
|
||||
STATUS_MBE <= CSRWriteValM[5] & P.BIGENDIAN_SUPPORTED;
|
||||
STATUS_SBE <= CSRWriteValM[4] & P.S_SUPPORTED & P.BIGENDIAN_SUPPORTED;
|
||||
// coverage on
|
||||
end else if (WriteSSTATUSM) begin // write a subset of the STATUS bits
|
||||
STATUS_MXR_INT <= #1 CSRWriteValM[19];
|
||||
STATUS_SUM_INT <= #1 CSRWriteValM[18];
|
||||
STATUS_FS_INT <= #1 CSRWriteValM[14:13];
|
||||
STATUS_SPP <= #1 P.S_SUPPORTED & CSRWriteValM[8];
|
||||
STATUS_SPIE <= #1 P.S_SUPPORTED & CSRWriteValM[5];
|
||||
STATUS_SIE <= #1 P.S_SUPPORTED & CSRWriteValM[1];
|
||||
STATUS_UBE <= #1 CSRWriteValM[6] & P.U_SUPPORTED & P.BIGENDIAN_SUPPORTED;
|
||||
end else if (FRegWriteM | WriteFRMM | WriteFFLAGSM) STATUS_FS_INT <= #1 2'b11;
|
||||
STATUS_MXR_INT <= CSRWriteValM[19];
|
||||
STATUS_SUM_INT <= CSRWriteValM[18];
|
||||
STATUS_FS_INT <= CSRWriteValM[14:13];
|
||||
STATUS_SPP <= P.S_SUPPORTED & CSRWriteValM[8];
|
||||
STATUS_SPIE <= P.S_SUPPORTED & CSRWriteValM[5];
|
||||
STATUS_SIE <= P.S_SUPPORTED & CSRWriteValM[1];
|
||||
STATUS_UBE <= CSRWriteValM[6] & P.U_SUPPORTED & P.BIGENDIAN_SUPPORTED;
|
||||
end else if (FRegWriteM | WriteFRMM | WriteFFLAGSM) STATUS_FS_INT <= 2'b11;
|
||||
end
|
||||
endmodule
|
||||
|
@ -52,8 +52,8 @@ module clint_apb import cvw::*; #(parameter cvw_t P) (
|
||||
assign PREADY = 1'b1; // CLINT never takes >1 cycle to respond
|
||||
|
||||
// word aligned reads
|
||||
if (P.XLEN==64) assign #2 entry = {PADDR[15:3], 3'b000};
|
||||
else assign #2 entry = {PADDR[15:2], 2'b00};
|
||||
if (P.XLEN==64) assign entry = {PADDR[15:3], 3'b000};
|
||||
else assign entry = {PADDR[15:2], 2'b00};
|
||||
|
||||
// DH 2/20/21: Eventually allow MTIME to run off a separate clock
|
||||
// This will require synchronizing MTIME to the system clock
|
||||
|
@ -70,33 +70,33 @@ module gpio_apb import cvw::*; #(parameter cvw_t P) (
|
||||
input_en <= 0;
|
||||
output_en <= 0;
|
||||
// *** synch reset not yet implemented [DH: can we delete this comment? Check if a sync reset is required]
|
||||
output_val <= #1 0;
|
||||
rise_ie <= #1 0;
|
||||
rise_ip <= #1 0;
|
||||
fall_ie <= #1 0;
|
||||
fall_ip <= #1 0;
|
||||
high_ie <= #1 0;
|
||||
high_ip <= #1 0;
|
||||
low_ie <= #1 0;
|
||||
low_ip <= #1 0;
|
||||
iof_en <= #1 0;
|
||||
iof_sel <= #1 0;
|
||||
out_xor <= #1 0;
|
||||
output_val <= 0;
|
||||
rise_ie <= 0;
|
||||
rise_ip <= 0;
|
||||
fall_ie <= 0;
|
||||
fall_ip <= 0;
|
||||
high_ie <= 0;
|
||||
high_ip <= 0;
|
||||
low_ie <= 0;
|
||||
low_ip <= 0;
|
||||
iof_en <= 0;
|
||||
iof_sel <= 0;
|
||||
out_xor <= 0;
|
||||
end else begin // writes
|
||||
// According to FE310 spec: Once the interrupt is pending, it will remain set until a 1 is written to the *_ip register at that bit.
|
||||
/* verilator lint_off CASEINCOMPLETE */
|
||||
if (memwrite)
|
||||
case(entry)
|
||||
8'h04: input_en <= #1 Din;
|
||||
8'h08: output_en <= #1 Din;
|
||||
8'h0C: output_val <= #1 Din;
|
||||
8'h18: rise_ie <= #1 Din;
|
||||
8'h20: fall_ie <= #1 Din;
|
||||
8'h28: high_ie <= #1 Din;
|
||||
8'h30: low_ie <= #1 Din;
|
||||
8'h38: iof_en <= #1 Din;
|
||||
8'h3C: iof_sel <= #1 Din;
|
||||
8'h40: out_xor <= #1 Din;
|
||||
8'h04: input_en <= Din;
|
||||
8'h08: output_en <= Din;
|
||||
8'h0C: output_val <= Din;
|
||||
8'h18: rise_ie <= Din;
|
||||
8'h20: fall_ie <= Din;
|
||||
8'h28: high_ie <= Din;
|
||||
8'h30: low_ie <= Din;
|
||||
8'h38: iof_en <= Din;
|
||||
8'h3C: iof_sel <= Din;
|
||||
8'h40: out_xor <= Din;
|
||||
endcase
|
||||
/* verilator lint_on CASEINCOMPLETE */
|
||||
|
||||
@ -111,22 +111,22 @@ module gpio_apb import cvw::*; #(parameter cvw_t P) (
|
||||
else low_ip <= low_ip | ~input3d;
|
||||
|
||||
case(entry) // flop to sample inputs
|
||||
8'h00: Dout <= #1 input_val;
|
||||
8'h04: Dout <= #1 input_en;
|
||||
8'h08: Dout <= #1 output_en;
|
||||
8'h0C: Dout <= #1 output_val;
|
||||
8'h18: Dout <= #1 rise_ie;
|
||||
8'h1C: Dout <= #1 rise_ip;
|
||||
8'h20: Dout <= #1 fall_ie;
|
||||
8'h24: Dout <= #1 fall_ip;
|
||||
8'h28: Dout <= #1 high_ie;
|
||||
8'h2C: Dout <= #1 high_ip;
|
||||
8'h30: Dout <= #1 low_ie;
|
||||
8'h34: Dout <= #1 low_ip;
|
||||
8'h38: Dout <= #1 iof_en;
|
||||
8'h3C: Dout <= #1 iof_sel;
|
||||
8'h40: Dout <= #1 out_xor;
|
||||
default: Dout <= #1 0;
|
||||
8'h00: Dout <= input_val;
|
||||
8'h04: Dout <= input_en;
|
||||
8'h08: Dout <= output_en;
|
||||
8'h0C: Dout <= output_val;
|
||||
8'h18: Dout <= rise_ie;
|
||||
8'h1C: Dout <= rise_ip;
|
||||
8'h20: Dout <= fall_ie;
|
||||
8'h24: Dout <= fall_ip;
|
||||
8'h28: Dout <= high_ie;
|
||||
8'h2C: Dout <= high_ip;
|
||||
8'h30: Dout <= low_ie;
|
||||
8'h34: Dout <= low_ip;
|
||||
8'h38: Dout <= iof_en;
|
||||
8'h3C: Dout <= iof_sel;
|
||||
8'h40: Dout <= out_xor;
|
||||
default: Dout <= 0;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
@ -107,48 +107,48 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
|
||||
always_ff @(posedge PCLK) begin
|
||||
// resetting
|
||||
if (~PRESETn) begin
|
||||
intPriority <= #1 0;
|
||||
intEn <= #1 0;
|
||||
intThreshold <= #1 0;
|
||||
intInProgress <= #1 0;
|
||||
intPriority <= 0;
|
||||
intEn <= 0;
|
||||
intThreshold <= 0;
|
||||
intInProgress <= 0;
|
||||
// writing
|
||||
end else begin
|
||||
if (memwrite)
|
||||
casez(entry)
|
||||
24'h0000??: intPriority[entry[7:2]] <= #1 Din[2:0];
|
||||
24'h002000: intEn[0][PLIC_NUM_SRC_MIN_32:1] <= #1 Din[PLIC_NUM_SRC_MIN_32:1];
|
||||
24'h002080: intEn[1][PLIC_NUM_SRC_MIN_32:1] <= #1 Din[PLIC_NUM_SRC_MIN_32:1];
|
||||
24'h002004: if (P.PLIC_NUM_SRC >= 32) intEn[0][PLIC_SRC_TOP:PLIC_SRC_BOT] <= #1 Din[PLIC_SRC_DINTOP:0];
|
||||
24'h002084: if (P.PLIC_NUM_SRC >= 32) intEn[1][PLIC_SRC_TOP:PLIC_SRC_BOT] <= #1 Din[PLIC_SRC_DINTOP:0];
|
||||
24'h200000: intThreshold[0] <= #1 Din[2:0];
|
||||
24'h200004: intInProgress <= #1 intInProgress & ~(One << (Din[5:0]-1)); // lower "InProgress" to signify completion
|
||||
24'h201000: intThreshold[1] <= #1 Din[2:0];
|
||||
24'h201004: intInProgress <= #1 intInProgress & ~(One << (Din[5:0]-1)); // lower "InProgress" to signify completion
|
||||
24'h0000??: intPriority[entry[7:2]] <= Din[2:0];
|
||||
24'h002000: intEn[0][PLIC_NUM_SRC_MIN_32:1] <= Din[PLIC_NUM_SRC_MIN_32:1];
|
||||
24'h002080: intEn[1][PLIC_NUM_SRC_MIN_32:1] <= Din[PLIC_NUM_SRC_MIN_32:1];
|
||||
24'h002004: if (P.PLIC_NUM_SRC >= 32) intEn[0][PLIC_SRC_TOP:PLIC_SRC_BOT] <= Din[PLIC_SRC_DINTOP:0];
|
||||
24'h002084: if (P.PLIC_NUM_SRC >= 32) intEn[1][PLIC_SRC_TOP:PLIC_SRC_BOT] <= Din[PLIC_SRC_DINTOP:0];
|
||||
24'h200000: intThreshold[0] <= Din[2:0];
|
||||
24'h200004: intInProgress <= intInProgress & ~(One << (Din[5:0]-1)); // lower "InProgress" to signify completion
|
||||
24'h201000: intThreshold[1] <= Din[2:0];
|
||||
24'h201004: intInProgress <= intInProgress & ~(One << (Din[5:0]-1)); // lower "InProgress" to signify completion
|
||||
endcase
|
||||
// Read synchronously because a read can have side effect of changing intInProgress
|
||||
if (memread) begin
|
||||
casez(entry)
|
||||
24'h000000: Dout <= #1 32'b0; // there is no intPriority[0]
|
||||
24'h0000??: Dout <= #1 {29'b0,intPriority[entry[7:2]]};
|
||||
24'h001000: Dout <= #1 {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intPending[PLIC_NUM_SRC_MIN_32:1],1'b0};
|
||||
24'h002000: Dout <= #1 {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intEn[0][PLIC_NUM_SRC_MIN_32:1],1'b0};
|
||||
24'h001004: if (P.PLIC_NUM_SRC >= 32) Dout <= #1 {{(PLIC_SRC_EXT){1'b0}},intPending[PLIC_SRC_TOP:PLIC_SRC_BOT]};
|
||||
24'h002004: if (P.PLIC_NUM_SRC >= 32) Dout <= #1 {{(PLIC_SRC_EXT){1'b0}},intEn[0][PLIC_SRC_TOP:PLIC_SRC_BOT]};
|
||||
24'h002080: Dout <= #1 {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intEn[1][PLIC_NUM_SRC_MIN_32:1],1'b0};
|
||||
24'h002084: if (P.PLIC_NUM_SRC >= 32) Dout <= #1 {{(PLIC_SRC_EXT){1'b0}},intEn[1][PLIC_SRC_TOP:PLIC_SRC_BOT]};
|
||||
24'h200000: Dout <= #1 {29'b0,intThreshold[0]};
|
||||
24'h000000: Dout <= 32'b0; // there is no intPriority[0]
|
||||
24'h0000??: Dout <= {29'b0,intPriority[entry[7:2]]};
|
||||
24'h001000: Dout <= {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intPending[PLIC_NUM_SRC_MIN_32:1],1'b0};
|
||||
24'h002000: Dout <= {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intEn[0][PLIC_NUM_SRC_MIN_32:1],1'b0};
|
||||
24'h001004: if (P.PLIC_NUM_SRC >= 32) Dout <= {{(PLIC_SRC_EXT){1'b0}},intPending[PLIC_SRC_TOP:PLIC_SRC_BOT]};
|
||||
24'h002004: if (P.PLIC_NUM_SRC >= 32) Dout <= {{(PLIC_SRC_EXT){1'b0}},intEn[0][PLIC_SRC_TOP:PLIC_SRC_BOT]};
|
||||
24'h002080: Dout <= {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intEn[1][PLIC_NUM_SRC_MIN_32:1],1'b0};
|
||||
24'h002084: if (P.PLIC_NUM_SRC >= 32) Dout <= {{(PLIC_SRC_EXT){1'b0}},intEn[1][PLIC_SRC_TOP:PLIC_SRC_BOT]};
|
||||
24'h200000: Dout <= {29'b0,intThreshold[0]};
|
||||
24'h200004: begin
|
||||
Dout <= #1 {26'b0,intClaim[0]};
|
||||
intInProgress <= #1 intInProgress | (One << (intClaim[0]-1)); // claimed requests are currently in progress of being serviced until they are completed
|
||||
Dout <= {26'b0,intClaim[0]};
|
||||
intInProgress <= intInProgress | (One << (intClaim[0]-1)); // claimed requests are currently in progress of being serviced until they are completed
|
||||
end
|
||||
24'h201000: Dout <= #1 {29'b0,intThreshold[1]};
|
||||
24'h201000: Dout <= {29'b0,intThreshold[1]};
|
||||
24'h201004: begin
|
||||
Dout <= #1 {26'b0,intClaim[1]};
|
||||
intInProgress <= #1 intInProgress | (One << (intClaim[1]-1)); // claimed requests are currently in progress of being serviced until they are completed
|
||||
Dout <= {26'b0,intClaim[1]};
|
||||
intInProgress <= intInProgress | (One << (intClaim[1]-1)); // claimed requests are currently in progress of being serviced until they are completed
|
||||
end
|
||||
default: Dout <= #1 32'h0; // invalid access
|
||||
default: Dout <= 32'h0; // invalid access
|
||||
endcase
|
||||
end else Dout <= #1 32'h0;
|
||||
end else Dout <= 32'h0;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -86,8 +86,8 @@ module ram_ahb import cvw::*; #(parameter cvw_t P,
|
||||
statetype CurrState, NextState;
|
||||
|
||||
always_ff @(posedge HCLK)
|
||||
if (~HRESETn) CurrState <= #1 READY;
|
||||
else CurrState <= #1 NextState;
|
||||
if (~HRESETn) CurrState <= READY;
|
||||
else CurrState <= NextState;
|
||||
|
||||
always_comb begin
|
||||
case(CurrState)
|
||||
|
@ -136,19 +136,19 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
|
||||
// Register access
|
||||
always_ff@(posedge PCLK, negedge PRESETn)
|
||||
if (~PRESETn) begin
|
||||
SckDiv <= #1 12'd3;
|
||||
SckMode <= #1 2'b0;
|
||||
ChipSelectID <= #1 2'b0;
|
||||
ChipSelectDef <= #1 4'b1111;
|
||||
ChipSelectMode <= #1 0;
|
||||
Delay0 <= #1 {8'b1,8'b1};
|
||||
Delay1 <= #1 {8'b0,8'b1};
|
||||
Format <= #1 {5'b10000};
|
||||
TransmitData <= #1 9'b0;
|
||||
TransmitWatermark <= #1 3'b0;
|
||||
ReceiveWatermark <= #1 3'b0;
|
||||
InterruptEnable <= #1 2'b0;
|
||||
InterruptPending <= #1 2'b0;
|
||||
SckDiv <= 12'd3;
|
||||
SckMode <= 2'b0;
|
||||
ChipSelectID <= 2'b0;
|
||||
ChipSelectDef <= 4'b1111;
|
||||
ChipSelectMode <= 0;
|
||||
Delay0 <= {8'b1,8'b1};
|
||||
Delay1 <= {8'b0,8'b1};
|
||||
Format <= {5'b10000};
|
||||
TransmitData <= 9'b0;
|
||||
TransmitWatermark <= 3'b0;
|
||||
ReceiveWatermark <= 3'b0;
|
||||
InterruptEnable <= 2'b0;
|
||||
InterruptPending <= 2'b0;
|
||||
end else begin // writes
|
||||
|
||||
|
||||
@ -176,21 +176,21 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
|
||||
InterruptPending[1] <= RecieveWriteMark;
|
||||
|
||||
case(Entry) // Flop to sample inputs
|
||||
8'h00: Dout <= #1 {20'b0, SckDiv};
|
||||
8'h04: Dout <= #1 {30'b0, SckMode};
|
||||
8'h10: Dout <= #1 {30'b0, ChipSelectID};
|
||||
8'h14: Dout <= #1 {28'b0, ChipSelectDef};
|
||||
8'h18: Dout <= #1 {30'b0, ChipSelectMode};
|
||||
8'h28: Dout <= #1 {8'b0, Delay0[15:8], 8'b0, Delay0[7:0]};
|
||||
8'h2C: Dout <= #1 {8'b0, Delay1[15:8], 8'b0, Delay1[7:0]};
|
||||
8'h40: Dout <= #1 {12'b0, Format[4:1], 13'b0, Format[0], 2'b0};
|
||||
8'h48: Dout <= #1 {23'b0, TransmitFIFOWriteFull, 8'b0};
|
||||
8'h4C: Dout <= #1 {23'b0, ReceiveFIFOReadEmpty, ReceiveData[7:0]};
|
||||
8'h50: Dout <= #1 {29'b0, TransmitWatermark};
|
||||
8'h54: Dout <= #1 {29'b0, ReceiveWatermark};
|
||||
8'h70: Dout <= #1 {30'b0, InterruptEnable};
|
||||
8'h74: Dout <= #1 {30'b0, InterruptPending};
|
||||
default: Dout <= #1 32'b0;
|
||||
8'h00: Dout <= {20'b0, SckDiv};
|
||||
8'h04: Dout <= {30'b0, SckMode};
|
||||
8'h10: Dout <= {30'b0, ChipSelectID};
|
||||
8'h14: Dout <= {28'b0, ChipSelectDef};
|
||||
8'h18: Dout <= {30'b0, ChipSelectMode};
|
||||
8'h28: Dout <= {8'b0, Delay0[15:8], 8'b0, Delay0[7:0]};
|
||||
8'h2C: Dout <= {8'b0, Delay1[15:8], 8'b0, Delay1[7:0]};
|
||||
8'h40: Dout <= {12'b0, Format[4:1], 13'b0, Format[0], 2'b0};
|
||||
8'h48: Dout <= {23'b0, TransmitFIFOWriteFull, 8'b0};
|
||||
8'h4C: Dout <= {23'b0, ReceiveFIFOReadEmpty, ReceiveData[7:0]};
|
||||
8'h50: Dout <= {29'b0, TransmitWatermark};
|
||||
8'h54: Dout <= {29'b0, ReceiveWatermark};
|
||||
8'h70: Dout <= {30'b0, InterruptEnable};
|
||||
8'h74: Dout <= {30'b0, InterruptPending};
|
||||
default: Dout <= 32'b0;
|
||||
endcase
|
||||
end
|
||||
|
||||
@ -200,7 +200,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
|
||||
assign SCLKenable = (DivCounter == SckDiv);
|
||||
assign SCLKenableEarly = ((DivCounter + 12'b1) == SckDiv);
|
||||
always_ff @(posedge PCLK, negedge PRESETn)
|
||||
if (~PRESETn) DivCounter <= #1 0;
|
||||
if (~PRESETn) DivCounter <= 0;
|
||||
else if (SCLKenable) DivCounter <= 0;
|
||||
else DivCounter <= DivCounter + 12'b1;
|
||||
|
||||
|
@ -125,10 +125,10 @@ module uartPC16550D #(parameter UART_PRESCALE) (
|
||||
///////////////////////////////////////////
|
||||
|
||||
always_ff @(posedge PCLK) begin
|
||||
{SINd, DSRbd, DCDbd, CTSbd, RIbd} <= #1 {SIN, DSRb, DCDb, CTSb, RIb};
|
||||
{SINsync, DSRbsync, DCDbsync, CTSbsync, RIbsync} <= #1 loop ? {SOUTbit, ~MCR[0], ~MCR[3], ~MCR[1], ~MCR[2]} :
|
||||
{SINd, DSRbd, DCDbd, CTSbd, RIbd} <= {SIN, DSRb, DCDb, CTSb, RIb};
|
||||
{SINsync, DSRbsync, DCDbsync, CTSbsync, RIbsync} <= loop ? {SOUTbit, ~MCR[0], ~MCR[3], ~MCR[1], ~MCR[2]} :
|
||||
{SINd, DSRbd, DCDbd, CTSbd, RIbd}; // syncrhonized signals, handle loopback testing
|
||||
{DSRb2, DCDb2, CTSb2, RIb2} <= #1 {DSRbsync, DCDbsync, CTSbsync, RIbsync}; // for detecting state changes
|
||||
{DSRb2, DCDb2, CTSb2, RIb2} <= {DSRbsync, DCDbsync, CTSbsync, RIbsync}; // for detecting state changes
|
||||
end
|
||||
|
||||
///////////////////////////////////////////
|
||||
@ -137,25 +137,25 @@ module uartPC16550D #(parameter UART_PRESCALE) (
|
||||
|
||||
always_ff @(posedge PCLK, negedge PRESETn)
|
||||
if (~PRESETn) begin // Table 3 Reset Configuration
|
||||
IER <= #1 4'b0;
|
||||
FCR <= #1 8'b0;
|
||||
LCR <= #1 8'b11; // **** fpga used to require reset to 3, double check this is no longer needed.
|
||||
MCR <= #1 5'b0;
|
||||
LSR <= #1 8'b01100000;
|
||||
MSR <= #1 4'b0;
|
||||
DLL <= #1 8'd1; // this cannot be zero with DLM also zer0.
|
||||
DLM <= #1 8'b0;
|
||||
SCR <= #1 8'b0; // not strictly necessary to reset
|
||||
IER <= 4'b0;
|
||||
FCR <= 8'b0;
|
||||
LCR <= 8'b11; // **** fpga used to require reset to 3, double check this is no longer needed.
|
||||
MCR <= 5'b0;
|
||||
LSR <= 8'b01100000;
|
||||
MSR <= 4'b0;
|
||||
DLL <= 8'd1; // this cannot be zero with DLM also zer0.
|
||||
DLM <= 8'b0;
|
||||
SCR <= 8'b0; // not strictly necessary to reset
|
||||
end else begin
|
||||
if (~MEMWb) begin
|
||||
/* verilator lint_off CASEINCOMPLETE */
|
||||
case (A)
|
||||
3'b000: if (DLAB) DLL <= #1 Din; // else TXHR <= #1 Din; // TX handled in TX register/FIFO section
|
||||
3'b001: if (DLAB) DLM <= #1 Din; else IER <= #1 Din[3:0];
|
||||
3'b010: FCR <= #1 {Din[7:6], 2'b0, Din[3], 2'b0, Din[0]}; // Write only FIFO Control Register; 4:5 reserved and 2:1 self-clearing
|
||||
3'b011: LCR <= #1 Din;
|
||||
3'b100: MCR <= #1 Din[4:0];
|
||||
3'b111: SCR <= #1 Din;
|
||||
3'b000: if (DLAB) DLL <= Din; // else TXHR <= Din; // TX handled in TX register/FIFO section
|
||||
3'b001: if (DLAB) DLM <= Din; else IER <= Din[3:0];
|
||||
3'b010: FCR <= {Din[7:6], 2'b0, Din[3], 2'b0, Din[0]}; // Write only FIFO Control Register; 4:5 reserved and 2:1 self-clearing
|
||||
3'b011: LCR <= Din;
|
||||
3'b100: MCR <= Din[4:0];
|
||||
3'b111: SCR <= Din;
|
||||
endcase
|
||||
/* verilator lint_on CASEINCOMPLETE */
|
||||
end
|
||||
@ -163,28 +163,28 @@ module uartPC16550D #(parameter UART_PRESCALE) (
|
||||
// Line Status Register (8.6.3)
|
||||
// Ben 6/9/21 I don't like how this is a register. A lot of the individual bits have clocked components, so this just adds unecessary delay.
|
||||
if (~MEMWb & (A == 3'b101))
|
||||
LSR[6:1] <= #1 Din[6:1]; // recommended only for test, see 8.6.3
|
||||
LSR[6:1] <= Din[6:1]; // recommended only for test, see 8.6.3
|
||||
else begin
|
||||
LSR[0] <= #1 rxdataready; // Data ready
|
||||
LSR[1] <= #1 (LSR[1] | RXBR[10]) & ~squashRXerrIP;; // overrun error
|
||||
LSR[2] <= #1 (LSR[2] | RXBR[9]) & ~squashRXerrIP; // parity error
|
||||
LSR[3] <= #1 (LSR[3] | RXBR[8]) & ~squashRXerrIP; // framing error
|
||||
LSR[4] <= #1 (LSR[4] | rxbreak) & ~squashRXerrIP; // break indicator
|
||||
LSR[5] <= #1 THRE; // THRE
|
||||
LSR[6] <= #1 ~txsrfull & THRE; // TEMT
|
||||
if (rxfifohaserr) LSR[7] <= #1 1; // any bits in FIFO have error
|
||||
LSR[0] <= rxdataready; // Data ready
|
||||
LSR[1] <= (LSR[1] | RXBR[10]) & ~squashRXerrIP;; // overrun error
|
||||
LSR[2] <= (LSR[2] | RXBR[9]) & ~squashRXerrIP; // parity error
|
||||
LSR[3] <= (LSR[3] | RXBR[8]) & ~squashRXerrIP; // framing error
|
||||
LSR[4] <= (LSR[4] | rxbreak) & ~squashRXerrIP; // break indicator
|
||||
LSR[5] <= THRE; // THRE
|
||||
LSR[6] <= ~txsrfull & THRE; // TEMT
|
||||
if (rxfifohaserr) LSR[7] <= 1; // any bits in FIFO have error
|
||||
end
|
||||
|
||||
// Modem Status Register (8.6.8)
|
||||
if (~MEMWb & (A == 3'b110))
|
||||
MSR <= #1 Din[3:0];
|
||||
MSR <= Din[3:0];
|
||||
else if (~MEMRb & (A == 3'b110))
|
||||
MSR <= #1 4'b0; // Reading MSR clears the flags in MSR bits 3:0
|
||||
MSR <= 4'b0; // Reading MSR clears the flags in MSR bits 3:0
|
||||
else begin
|
||||
MSR[0] <= #1 MSR[0] | CTSb2 ^ CTSbsync; // Delta Clear to Send
|
||||
MSR[1] <= #1 MSR[1] | DSRb2 ^ DSRbsync; // Delta Data Set Ready
|
||||
MSR[2] <= #1 MSR[2] | (~RIb2 & RIbsync); // Trailing Edge of Ring Indicator
|
||||
MSR[3] <= #1 MSR[3] | DCDb2 ^ DCDbsync; // Delta Data Carrier Detect
|
||||
MSR[0] <= MSR[0] | CTSb2 ^ CTSbsync; // Delta Clear to Send
|
||||
MSR[1] <= MSR[1] | DSRb2 ^ DSRbsync; // Delta Data Set Ready
|
||||
MSR[2] <= MSR[2] | (~RIb2 & RIbsync); // Trailing Edge of Ring Indicator
|
||||
MSR[3] <= MSR[3] | DCDb2 ^ DCDbsync; // Delta Data Carrier Detect
|
||||
end
|
||||
end
|
||||
always_comb
|
||||
@ -214,18 +214,18 @@ module uartPC16550D #(parameter UART_PRESCALE) (
|
||||
///////////////////////////////////////////
|
||||
always_ff @(posedge PCLK, negedge PRESETn)
|
||||
if (~PRESETn) begin
|
||||
baudcount <= #1 1;
|
||||
baudpulse <= #1 0;
|
||||
baudcount <= 1;
|
||||
baudpulse <= 0;
|
||||
end else if (~MEMWb & DLAB & (A == 3'b0 | A == 3'b1)) begin
|
||||
baudcount <= #1 1;
|
||||
baudcount <= 1;
|
||||
end else begin
|
||||
// the baudpulse is too long by 2 clock cycles.
|
||||
// This is cause baudpulse is registered adding 1 cycle and
|
||||
// baudcount is reset when baudcount equals the threshold {DLM, DLL, UART_PRESCALE}
|
||||
// rather than 1 less than that value. Alternatively the reset value could be 1 rather
|
||||
// than 0.
|
||||
baudpulse <= #1 baudpulseComb;
|
||||
baudcount <= #1 baudpulseComb ? 1 : baudcount +1;
|
||||
baudpulse <= baudpulseComb;
|
||||
baudcount <= baudpulseComb ? 1 : baudcount +1;
|
||||
end
|
||||
|
||||
assign baudpulseComb = (baudcount == {DLM, DLL, {(UART_PRESCALE){1'b0}}});
|
||||
@ -240,27 +240,27 @@ module uartPC16550D #(parameter UART_PRESCALE) (
|
||||
|
||||
always_ff @(posedge PCLK, negedge PRESETn)
|
||||
if (~PRESETn) begin
|
||||
rxoversampledcnt <= #1 0;
|
||||
rxstate <= #1 UART_IDLE;
|
||||
rxbitsreceived <= #1 0;
|
||||
rxtimeoutcnt <= #1 0;
|
||||
rxoversampledcnt <= 0;
|
||||
rxstate <= UART_IDLE;
|
||||
rxbitsreceived <= 0;
|
||||
rxtimeoutcnt <= 0;
|
||||
end else begin
|
||||
if (rxstate == UART_IDLE & ~SINsync) begin // got start bit
|
||||
rxstate <= #1 UART_ACTIVE;
|
||||
rxoversampledcnt <= #1 0;
|
||||
rxbitsreceived <= #1 0;
|
||||
if (~rxfifotimeout) rxtimeoutcnt <= #1 0; // reset timeout when new character is arriving. Jacob Pease: Only if the timeout was not already reached. p.16 PC16550D.pdf
|
||||
rxstate <= UART_ACTIVE;
|
||||
rxoversampledcnt <= 0;
|
||||
rxbitsreceived <= 0;
|
||||
if (~rxfifotimeout) rxtimeoutcnt <= 0; // reset timeout when new character is arriving. Jacob Pease: Only if the timeout was not already reached. p.16 PC16550D.pdf
|
||||
end else if (rxbaudpulse & (rxstate == UART_ACTIVE)) begin
|
||||
rxoversampledcnt <= #1 rxoversampledcnt + 1; // 16x oversampled counter
|
||||
if (rxcentered) rxbitsreceived <= #1 rxbitsreceived + 1;
|
||||
if (rxbitsreceived == rxbitsexpected) rxstate <= #1 UART_DONE; // pulse rxdone for a cycle
|
||||
rxoversampledcnt <= rxoversampledcnt + 1; // 16x oversampled counter
|
||||
if (rxcentered) rxbitsreceived <= rxbitsreceived + 1;
|
||||
if (rxbitsreceived == rxbitsexpected) rxstate <= UART_DONE; // pulse rxdone for a cycle
|
||||
end else if (rxstate == UART_DONE | rxstate == UART_BREAK) begin
|
||||
if (rxbreak & ~SINsync) rxstate <= #1 UART_BREAK;
|
||||
else rxstate <= #1 UART_IDLE;
|
||||
if (rxbreak & ~SINsync) rxstate <= UART_BREAK;
|
||||
else rxstate <= UART_IDLE;
|
||||
end
|
||||
// timeout counting
|
||||
if (~MEMRb & A == 3'b000 & ~DLAB) rxtimeoutcnt <= #1 0; // reset timeout on read
|
||||
else if (fifoenabled & ~rxfifoempty & rxbaudpulse & ~rxfifotimeout) rxtimeoutcnt <= #1 rxtimeoutcnt+1; // may not be right
|
||||
if (~MEMRb & A == 3'b000 & ~DLAB) rxtimeoutcnt <= 0; // reset timeout on read
|
||||
else if (fifoenabled & ~rxfifoempty & rxbaudpulse & ~rxfifotimeout) rxtimeoutcnt <= rxtimeoutcnt+1; // may not be right
|
||||
end
|
||||
|
||||
assign rxcentered = rxbaudpulse & (rxoversampledcnt == 4'b1000); // implies rxstate = UART_ACTIVE
|
||||
@ -272,8 +272,8 @@ module uartPC16550D #(parameter UART_PRESCALE) (
|
||||
///////////////////////////////////////////
|
||||
|
||||
always_ff @(posedge PCLK, negedge PRESETn)
|
||||
if (~PRESETn) rxshiftreg <= #1 10'b0000000001; // initialize so that there is a valid stop bit
|
||||
else if (rxcentered) rxshiftreg <= #1 {rxshiftreg[8:0], SINsync}; // capture bit
|
||||
if (~PRESETn) rxshiftreg <= 10'b0000000001; // initialize so that there is a valid stop bit
|
||||
else if (rxcentered) rxshiftreg <= {rxshiftreg[8:0], SINsync}; // capture bit
|
||||
assign rxparitybit = rxshiftreg[1]; // parity, if it exists, in bit 1 when all done
|
||||
assign rxstopbit = rxshiftreg[0];
|
||||
always_comb
|
||||
@ -295,32 +295,32 @@ module uartPC16550D #(parameter UART_PRESCALE) (
|
||||
// receive FIFO and register
|
||||
always_ff @(posedge PCLK)
|
||||
if (~PRESETn) begin
|
||||
rxfifohead <= #1 0; rxfifotail <= #1 0; rxdataready <= #1 0; RXBR <= #1 0;
|
||||
rxfifohead <= 0; rxfifotail <= 0; rxdataready <= 0; RXBR <= 0;
|
||||
end else begin
|
||||
if (~MEMWb & (A == 3'b010) & Din[1]) begin
|
||||
rxfifohead <= #1 0; rxfifotail <= #1 0; rxdataready <= #1 0;
|
||||
rxfifohead <= 0; rxfifotail <= 0; rxdataready <= 0;
|
||||
end else if (rxstate == UART_DONE) begin
|
||||
RXBR <= #1 {rxoverrunerr, rxparityerr, rxframingerr, rxdata}; // load recevive buffer register
|
||||
RXBR <= {rxoverrunerr, rxparityerr, rxframingerr, rxdata}; // load recevive buffer register
|
||||
if (rxoverrunerr) $warning("UART RX Overrun Err\n");
|
||||
if (rxparityerr) $warning("UART RX Parity Err\n");
|
||||
if (rxframingerr) $warning("UART RX Framing Err\n");
|
||||
if (fifoenabled) begin
|
||||
rxfifo[rxfifohead] <= #1 {rxoverrunerr, rxparityerr, rxframingerr, rxdata};
|
||||
rxfifohead <= #1 rxfifohead + 1;
|
||||
rxfifo[rxfifohead] <= {rxoverrunerr, rxparityerr, rxframingerr, rxdata};
|
||||
rxfifohead <= rxfifohead + 1;
|
||||
end
|
||||
rxdataready <= #1 1;
|
||||
rxdataready <= 1;
|
||||
end else if (~MEMRb & A == 3'b000 & ~DLAB) begin // reading RBR updates ready / pops fifo
|
||||
if (fifoenabled) begin
|
||||
if (~rxfifoempty) rxfifotail <= #1 rxfifotail + 1;
|
||||
// if (rxfifoempty) rxdataready <= #1 0;
|
||||
if (rxfifoentries == 1) rxdataready <= #1 0; // When reading the last entry, data ready becomes zero
|
||||
if (~rxfifoempty) rxfifotail <= rxfifotail + 1;
|
||||
// if (rxfifoempty) rxdataready <= 0;
|
||||
if (rxfifoentries == 1) rxdataready <= 0; // When reading the last entry, data ready becomes zero
|
||||
end else begin
|
||||
rxdataready <= #1 0;
|
||||
RXBR <= #1 {1'b0, RXBR[9:0]}; // Ben 31 March 2022: I added this so that rxoverrunerr permanently goes away upon reading RBR (when not in FIFO mode)
|
||||
rxdataready <= 0;
|
||||
RXBR <= {1'b0, RXBR[9:0]}; // Ben 31 March 2022: I added this so that rxoverrunerr permanently goes away upon reading RBR (when not in FIFO mode)
|
||||
end
|
||||
end else if (~MEMWb & A == 3'b010) // writes to FIFO Control Register
|
||||
if (Din[1] | ~Din[0]) begin // rx FIFO reset or FIFO disable clears FIFO contents
|
||||
rxfifohead <= #1 0; rxfifotail <= #1 0;
|
||||
rxfifohead <= 0; rxfifotail <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
@ -354,9 +354,9 @@ module uartPC16550D #(parameter UART_PRESCALE) (
|
||||
|
||||
// receive buffer register and ready bit
|
||||
always_ff @(posedge PCLK, negedge PRESETn) // track rxrdy for DMA mode (FCR3 = FCR0 = 1)
|
||||
if (~PRESETn) rxfifodmaready <= #1 0;
|
||||
else if (rxfifotriggered | rxfifotimeout) rxfifodmaready <= #1 1;
|
||||
else if (rxfifoempty) rxfifodmaready <= #1 0;
|
||||
if (~PRESETn) rxfifodmaready <= 0;
|
||||
else if (rxfifotriggered | rxfifotimeout) rxfifodmaready <= 1;
|
||||
else if (rxfifoempty) rxfifodmaready <= 0;
|
||||
|
||||
always_comb
|
||||
if (fifoenabled) begin
|
||||
@ -375,21 +375,21 @@ module uartPC16550D #(parameter UART_PRESCALE) (
|
||||
|
||||
always_ff @(posedge PCLK, negedge PRESETn)
|
||||
if (~PRESETn) begin
|
||||
txoversampledcnt <= #1 0;
|
||||
txstate <= #1 UART_IDLE;
|
||||
txbitssent <= #1 0;
|
||||
txoversampledcnt <= 0;
|
||||
txstate <= UART_IDLE;
|
||||
txbitssent <= 0;
|
||||
end else if ((txstate == UART_IDLE) & txsrfull) begin // start transmitting
|
||||
txstate <= #1 UART_ACTIVE;
|
||||
txoversampledcnt <= #1 1;
|
||||
txbitssent <= #1 0;
|
||||
txstate <= UART_ACTIVE;
|
||||
txoversampledcnt <= 1;
|
||||
txbitssent <= 0;
|
||||
end else if (txbaudpulse & (txstate == UART_ACTIVE)) begin
|
||||
txoversampledcnt <= #1 txoversampledcnt + 1;
|
||||
txoversampledcnt <= txoversampledcnt + 1;
|
||||
if (txnextbit) begin // transmit at end of phase
|
||||
txbitssent <= #1 txbitssent+1;
|
||||
if (txbitssent == txbitsexpected) txstate <= #1 UART_DONE;
|
||||
txbitssent <= txbitssent+1;
|
||||
if (txbitssent == txbitsexpected) txstate <= UART_DONE;
|
||||
end
|
||||
end else if (txstate == UART_DONE) begin
|
||||
txstate <= #1 UART_IDLE;
|
||||
txstate <= UART_IDLE;
|
||||
end
|
||||
|
||||
assign txbitsexpected = 4'd1 + (4'd5 + {2'b00, LCR[1:0]}) + {3'b000, LCR[3]} + 4'd1 + {3'b000, LCR[2]} - 4'd1; // start bit + data bits + (parity bit) + stop bit(s) - 1
|
||||
@ -423,37 +423,37 @@ module uartPC16550D #(parameter UART_PRESCALE) (
|
||||
// registers & FIFO
|
||||
always_ff @(posedge PCLK, negedge PRESETn)
|
||||
if (~PRESETn) begin
|
||||
txfifohead <= #1 0; txfifotail <= #1 0; txhrfull <= #1 0; txsrfull <= #1 0; TXHR <= #1 0; txsr <= #1 12'hfff;
|
||||
txfifohead <= 0; txfifotail <= 0; txhrfull <= 0; txsrfull <= 0; TXHR <= 0; txsr <= 12'hfff;
|
||||
end else if (~MEMWb & (A == 3'b010) & Din[2]) begin
|
||||
txfifohead <= #1 0; txfifotail <= #1 0;
|
||||
txfifohead <= 0; txfifotail <= 0;
|
||||
end else begin
|
||||
if (~MEMWb & A == 3'b000 & ~DLAB) begin // writing transmit holding register or fifo
|
||||
if (fifoenabled) begin
|
||||
txfifo[txfifohead] <= #1 Din;
|
||||
txfifohead <= #1 txfifohead + 1;
|
||||
txfifo[txfifohead] <= Din;
|
||||
txfifohead <= txfifohead + 1;
|
||||
end else begin
|
||||
TXHR <= #1 Din;
|
||||
txhrfull <= #1 1;
|
||||
TXHR <= Din;
|
||||
txhrfull <= 1;
|
||||
end
|
||||
$write("%c",Din); // for testbench
|
||||
end
|
||||
if (txstate == UART_IDLE) begin // move data into tx shift register if available
|
||||
if (fifoenabled) begin
|
||||
if (~txfifoempty & ~txsrfull) begin
|
||||
txsr <= #1 txdata;
|
||||
txfifotail <= #1 txfifotail+1;
|
||||
txsrfull <= #1 1;
|
||||
txsr <= txdata;
|
||||
txfifotail <= txfifotail+1;
|
||||
txsrfull <= 1;
|
||||
end
|
||||
end else if (txhrfull) begin
|
||||
txsr <= #1 txdata;
|
||||
txhrfull <= #1 0;
|
||||
txsrfull <= #1 1;
|
||||
txsr <= txdata;
|
||||
txhrfull <= 0;
|
||||
txsrfull <= 1;
|
||||
end
|
||||
end else if (txstate == UART_DONE) txsrfull <= #1 0; // done transmitting shift register
|
||||
else if (txstate == UART_ACTIVE & txnextbit) txsr <= #1 {txsr[10:0], 1'b1}; // shift txhr
|
||||
end else if (txstate == UART_DONE) txsrfull <= 0; // done transmitting shift register
|
||||
else if (txstate == UART_ACTIVE & txnextbit) txsr <= {txsr[10:0], 1'b1}; // shift txhr
|
||||
if (!MEMWb & A == 3'b010) // writes to FIFO control register
|
||||
if (Din[2] | ~Din[0]) begin // tx FIFO reste or FIFO disable clears FIFO contents
|
||||
txfifohead <= #1 0; txfifotail <= #1 0;
|
||||
txfifohead <= 0; txfifotail <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
@ -483,9 +483,9 @@ module uartPC16550D #(parameter UART_PRESCALE) (
|
||||
|
||||
// transmit buffer ready bit
|
||||
always_ff @(posedge PCLK, negedge PRESETn) // track txrdy for DMA mode (FCR3 = FCR0 = 1)
|
||||
if (~PRESETn) txfifodmaready <= #1 0;
|
||||
else if (txfifoempty) txfifodmaready <= #1 1;
|
||||
else if (txfifofull) txfifodmaready <= #1 0;
|
||||
if (~PRESETn) txfifodmaready <= 0;
|
||||
else if (txfifoempty) txfifodmaready <= 1;
|
||||
else if (txfifofull) txfifodmaready <= 0;
|
||||
|
||||
always_comb
|
||||
if (fifoenabled & fifodmamodesel) TXRDYb = ~txfifodmaready;
|
||||
@ -520,7 +520,7 @@ module uartPC16550D #(parameter UART_PRESCALE) (
|
||||
intrpending = 0;
|
||||
end
|
||||
end
|
||||
always_ff @(posedge PCLK) INTR <= #1 intrpending; // prevent glitches on interrupt pin
|
||||
always_ff @(posedge PCLK) INTR <= intrpending; // prevent glitches on interrupt pin
|
||||
|
||||
// Side effect of reading LSR is lowering overrun, parity, framing, break intr's
|
||||
assign setSquashRXerrIP = ~MEMRb & (A==3'b101);
|
||||
|
@ -284,7 +284,7 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
|
||||
|
||||
assign valid = InstrValidW & ~StallW;
|
||||
assign rvvi.clk = clk;
|
||||
assign #1 rvvi.valid[0][0] = valid;
|
||||
assign rvvi.valid[0][0] = valid;
|
||||
assign rvvi.order[0][0] = CSRArray[12'hB02]; // TODO: IMPERAS Should be event order
|
||||
assign rvvi.insn[0][0] = InstrRawW;
|
||||
assign rvvi.pc_rdata[0][0] = PCW;
|
||||
@ -361,44 +361,44 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
|
||||
end
|
||||
|
||||
// check for csr value change.
|
||||
assign #2 CSR_W[12'h300] = (CSRArrayOld[12'h300] != CSRArray[12'h300]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h310] = (CSRArrayOld[12'h310] != CSRArray[12'h310]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h305] = (CSRArrayOld[12'h305] != CSRArray[12'h305]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h341] = (CSRArrayOld[12'h341] != CSRArray[12'h341]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h306] = (CSRArrayOld[12'h306] != CSRArray[12'h306]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h30A] = (CSRArrayOld[12'h30A] != CSRArray[12'h30A]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h320] = (CSRArrayOld[12'h320] != CSRArray[12'h320]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h302] = (CSRArrayOld[12'h302] != CSRArray[12'h302]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h303] = (CSRArrayOld[12'h303] != CSRArray[12'h303]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h344] = (CSRArrayOld[12'h344] != CSRArray[12'h344]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h304] = (CSRArrayOld[12'h304] != CSRArray[12'h304]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h301] = (CSRArrayOld[12'h301] != CSRArray[12'h301]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'hF14] = (CSRArrayOld[12'hF14] != CSRArray[12'hF14]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h340] = (CSRArrayOld[12'h340] != CSRArray[12'h340]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h342] = (CSRArrayOld[12'h342] != CSRArray[12'h342]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h343] = (CSRArrayOld[12'h343] != CSRArray[12'h343]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'hF11] = (CSRArrayOld[12'hF11] != CSRArray[12'hF11]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'hF12] = (CSRArrayOld[12'hF12] != CSRArray[12'hF12]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'hF13] = (CSRArrayOld[12'hF13] != CSRArray[12'hF13]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'hF15] = (CSRArrayOld[12'hF15] != CSRArray[12'hF15]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h34A] = (CSRArrayOld[12'h34A] != CSRArray[12'h34A]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'hB00] = (CSRArrayOld[12'hB00] != CSRArray[12'hB00]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'hB02] = (CSRArrayOld[12'hB02] != CSRArray[12'hB02]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h100] = (CSRArrayOld[12'h100] != CSRArray[12'h100]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h104] = (CSRArrayOld[12'h104] != CSRArray[12'h104]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h105] = (CSRArrayOld[12'h105] != CSRArray[12'h105]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h141] = (CSRArrayOld[12'h141] != CSRArray[12'h141]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h106] = (CSRArrayOld[12'h106] != CSRArray[12'h106]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h10A] = (CSRArrayOld[12'h10A] != CSRArray[12'h10A]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h180] = (CSRArrayOld[12'h180] != CSRArray[12'h180]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h140] = (CSRArrayOld[12'h140] != CSRArray[12'h140]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h143] = (CSRArrayOld[12'h143] != CSRArray[12'h143]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h142] = (CSRArrayOld[12'h142] != CSRArray[12'h142]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h144] = (CSRArrayOld[12'h144] != CSRArray[12'h144]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h14D] = (CSRArrayOld[12'h14D] != CSRArray[12'h14D]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h001] = (CSRArrayOld[12'h001] != CSRArray[12'h001]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h002] = (CSRArrayOld[12'h002] != CSRArray[12'h002]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h003] = (CSRArrayOld[12'h003] != CSRArray[12'h003]) ? 1 : 0;
|
||||
assign CSR_W[12'h300] = (CSRArrayOld[12'h300] != CSRArray[12'h300]) ? 1 : 0;
|
||||
assign CSR_W[12'h310] = (CSRArrayOld[12'h310] != CSRArray[12'h310]) ? 1 : 0;
|
||||
assign CSR_W[12'h305] = (CSRArrayOld[12'h305] != CSRArray[12'h305]) ? 1 : 0;
|
||||
assign CSR_W[12'h341] = (CSRArrayOld[12'h341] != CSRArray[12'h341]) ? 1 : 0;
|
||||
assign CSR_W[12'h306] = (CSRArrayOld[12'h306] != CSRArray[12'h306]) ? 1 : 0;
|
||||
assign CSR_W[12'h30A] = (CSRArrayOld[12'h30A] != CSRArray[12'h30A]) ? 1 : 0;
|
||||
assign CSR_W[12'h320] = (CSRArrayOld[12'h320] != CSRArray[12'h320]) ? 1 : 0;
|
||||
assign CSR_W[12'h302] = (CSRArrayOld[12'h302] != CSRArray[12'h302]) ? 1 : 0;
|
||||
assign CSR_W[12'h303] = (CSRArrayOld[12'h303] != CSRArray[12'h303]) ? 1 : 0;
|
||||
assign CSR_W[12'h344] = (CSRArrayOld[12'h344] != CSRArray[12'h344]) ? 1 : 0;
|
||||
assign CSR_W[12'h304] = (CSRArrayOld[12'h304] != CSRArray[12'h304]) ? 1 : 0;
|
||||
assign CSR_W[12'h301] = (CSRArrayOld[12'h301] != CSRArray[12'h301]) ? 1 : 0;
|
||||
assign CSR_W[12'hF14] = (CSRArrayOld[12'hF14] != CSRArray[12'hF14]) ? 1 : 0;
|
||||
assign CSR_W[12'h340] = (CSRArrayOld[12'h340] != CSRArray[12'h340]) ? 1 : 0;
|
||||
assign CSR_W[12'h342] = (CSRArrayOld[12'h342] != CSRArray[12'h342]) ? 1 : 0;
|
||||
assign CSR_W[12'h343] = (CSRArrayOld[12'h343] != CSRArray[12'h343]) ? 1 : 0;
|
||||
assign CSR_W[12'hF11] = (CSRArrayOld[12'hF11] != CSRArray[12'hF11]) ? 1 : 0;
|
||||
assign CSR_W[12'hF12] = (CSRArrayOld[12'hF12] != CSRArray[12'hF12]) ? 1 : 0;
|
||||
assign CSR_W[12'hF13] = (CSRArrayOld[12'hF13] != CSRArray[12'hF13]) ? 1 : 0;
|
||||
assign CSR_W[12'hF15] = (CSRArrayOld[12'hF15] != CSRArray[12'hF15]) ? 1 : 0;
|
||||
assign CSR_W[12'h34A] = (CSRArrayOld[12'h34A] != CSRArray[12'h34A]) ? 1 : 0;
|
||||
assign CSR_W[12'hB00] = (CSRArrayOld[12'hB00] != CSRArray[12'hB00]) ? 1 : 0;
|
||||
assign CSR_W[12'hB02] = (CSRArrayOld[12'hB02] != CSRArray[12'hB02]) ? 1 : 0;
|
||||
assign CSR_W[12'h100] = (CSRArrayOld[12'h100] != CSRArray[12'h100]) ? 1 : 0;
|
||||
assign CSR_W[12'h104] = (CSRArrayOld[12'h104] != CSRArray[12'h104]) ? 1 : 0;
|
||||
assign CSR_W[12'h105] = (CSRArrayOld[12'h105] != CSRArray[12'h105]) ? 1 : 0;
|
||||
assign CSR_W[12'h141] = (CSRArrayOld[12'h141] != CSRArray[12'h141]) ? 1 : 0;
|
||||
assign CSR_W[12'h106] = (CSRArrayOld[12'h106] != CSRArray[12'h106]) ? 1 : 0;
|
||||
assign CSR_W[12'h10A] = (CSRArrayOld[12'h10A] != CSRArray[12'h10A]) ? 1 : 0;
|
||||
assign CSR_W[12'h180] = (CSRArrayOld[12'h180] != CSRArray[12'h180]) ? 1 : 0;
|
||||
assign CSR_W[12'h140] = (CSRArrayOld[12'h140] != CSRArray[12'h140]) ? 1 : 0;
|
||||
assign CSR_W[12'h143] = (CSRArrayOld[12'h143] != CSRArray[12'h143]) ? 1 : 0;
|
||||
assign CSR_W[12'h142] = (CSRArrayOld[12'h142] != CSRArray[12'h142]) ? 1 : 0;
|
||||
assign CSR_W[12'h144] = (CSRArrayOld[12'h144] != CSRArray[12'h144]) ? 1 : 0;
|
||||
assign CSR_W[12'h14D] = (CSRArrayOld[12'h14D] != CSRArray[12'h14D]) ? 1 : 0;
|
||||
assign CSR_W[12'h001] = (CSRArrayOld[12'h001] != CSRArray[12'h001]) ? 1 : 0;
|
||||
assign CSR_W[12'h002] = (CSRArrayOld[12'h002] != CSRArray[12'h002]) ? 1 : 0;
|
||||
assign CSR_W[12'h003] = (CSRArrayOld[12'h003] != CSRArray[12'h003]) ? 1 : 0;
|
||||
|
||||
assign rvvi.csr_wb[0][0][12'h300] = CSR_W[12'h300];
|
||||
assign rvvi.csr_wb[0][0][12'h310] = CSR_W[12'h310];
|
||||
@ -480,14 +480,14 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
|
||||
|
||||
// PMP CFG 3A0 to 3AF
|
||||
for(index='h3A0; index<='h3AF; index++) begin
|
||||
assign #2 CSR_W[index] = (CSRArrayOld[index] != CSRArray[index]) ? 1 : 0;
|
||||
assign CSR_W[index] = (CSRArrayOld[index] != CSRArray[index]) ? 1 : 0;
|
||||
assign rvvi.csr_wb[0][0][index] = CSR_W[index];
|
||||
assign rvvi.csr[0][0][index] = CSRArray[index];
|
||||
end
|
||||
|
||||
// PMP ADDR 3B0 to 3EF
|
||||
for(index='h3B0; index<='h3EF; index++) begin
|
||||
assign #2 CSR_W[index] = (CSRArrayOld[index] != CSRArray[index]) ? 1 : 0;
|
||||
assign CSR_W[index] = (CSRArrayOld[index] != CSRArray[index]) ? 1 : 0;
|
||||
assign rvvi.csr_wb[0][0][index] = CSR_W[index];
|
||||
assign rvvi.csr[0][0][index] = CSRArray[index];
|
||||
end
|
||||
|
@ -498,7 +498,7 @@ module sdModel
|
||||
crcRst<=0;
|
||||
crcIn <= #`tIH qCmd; // tIH 0
|
||||
inCmd[47-cmdRead] <= #`tIH qCmd; // tIH 0
|
||||
cmdRead <= #1 cmdRead+1;
|
||||
cmdRead <= cmdRead+1;
|
||||
if (cmdRead >= 40)
|
||||
crcEn<=0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user