Merge pull request #678 from Karl-Han/latest

[Resolved Conflict] Remove all #delay from non-testbench
This commit is contained in:
David Harris 2024-03-23 15:18:04 -07:00 committed by GitHub
commit bae52cf13d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
34 changed files with 366 additions and 366 deletions

View File

@ -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
View File

@ -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;

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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;