改异步复位,增加flush接口,删除其他工程代码以编译通过
This commit is contained in:
@@ -114,8 +114,6 @@ lazy val blocks = (project in file("./rocket-chip-blocks"))
|
|||||||
|
|
||||||
|
|
||||||
lazy val root = (project in file("."))
|
lazy val root = (project in file("."))
|
||||||
.dependsOn(rocketchip)
|
|
||||||
.dependsOn(blocks)
|
|
||||||
.settings(
|
.settings(
|
||||||
name := "%NAME%",
|
name := "%NAME%",
|
||||||
libraryDependencies ++= Seq(
|
libraryDependencies ++= Seq(
|
||||||
|
|||||||
@@ -1,175 +0,0 @@
|
|||||||
package Switch
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
|
|
||||||
|
|
||||||
import org.chipsalliance.cde.config._
|
|
||||||
import freechips.rocketchip.tilelink._
|
|
||||||
|
|
||||||
|
|
||||||
abstract class DMAMstBase(val edgeOut: TLEdgeOut)(implicit p: Parameters) extends SwitchNode{
|
|
||||||
class MacTileLinkMasterIO extends Bundle{
|
|
||||||
val A = Decoupled(new TLBundleA(edgeOut.bundle))
|
|
||||||
val D = Flipped(Decoupled(new TLBundleD(edgeOut.bundle)))
|
|
||||||
}
|
|
||||||
|
|
||||||
class SwitchMuxIO(implicit p: Parameters) extends SwitchBundle{
|
|
||||||
val dmaMst = new MacTileLinkMasterIO
|
|
||||||
|
|
||||||
val cfg = Vec( chn, Flipped(new DMA_Register_Bundle) )
|
|
||||||
|
|
||||||
val selIn = Input(UInt( (log2Ceil(chn)).W))
|
|
||||||
val selOut = Output(UInt((log2Ceil(chn)).W))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
val io: SwitchMuxIO = IO(new SwitchMuxIO)
|
|
||||||
val (_, _, isLastD, transDCnt) = edgeOut.count(io.dmaMst.D)
|
|
||||||
|
|
||||||
val rxBuff = Module(new RxBuff(8))
|
|
||||||
val txBuff = Module(new TxBuff(0))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def stateIdle = 0.U
|
|
||||||
def stateRx = 1.U
|
|
||||||
def stateTx = 2.U
|
|
||||||
|
|
||||||
val stateNxt = Wire(UInt(2.W))
|
|
||||||
val stateCur = RegNext(stateNxt, stateIdle)
|
|
||||||
val stateDMA = RegInit(0.U(2.W))
|
|
||||||
|
|
||||||
val dmaAValid = RegInit(false.B)
|
|
||||||
val dmaABits = Reg(new TLBundleA(edgeOut.bundle))
|
|
||||||
val dmaAddress = Reg( UInt(32.W) )
|
|
||||||
|
|
||||||
val trigRxNum = Reg(UInt((log2Ceil(chn)).W))
|
|
||||||
val trigTxNum = Reg(UInt((log2Ceil(chn)).W))
|
|
||||||
|
|
||||||
val rxLength = RegInit(0.U)
|
|
||||||
}
|
|
||||||
|
|
||||||
trait DMAMstFSM{ this: DMAMstBase =>
|
|
||||||
|
|
||||||
stateNxt :=
|
|
||||||
Mux1H(Seq(
|
|
||||||
( stateCur === stateIdle ) -> Mux( (0 until chn).map{i => (io.cfg(i).triTx & io.cfg(i).r_TxLen > 32.U)}.foldLeft(false.B)(_|_) , stateTx, Mux( txBuff.io.deq.valid, stateRx, stateIdle ) ),
|
|
||||||
( stateCur === stateRx ) -> Mux( stateDMA === 0.U, stateIdle, stateRx ),
|
|
||||||
( stateCur === stateTx ) -> Mux( stateDMA === 0.U, stateIdle, stateTx ),
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
when( stateNxt =/= stateIdle && stateCur === stateIdle ){
|
|
||||||
stateDMA := 1.U
|
|
||||||
} .elsewhen( io.dmaMst.A.fire ){
|
|
||||||
stateDMA := 2.U
|
|
||||||
} .elsewhen( io.dmaMst.D.fire & isLastD ){
|
|
||||||
when( stateCur === stateTx & dmaAddress === (io.cfg(trigTxNum).r_TxPtr + io.cfg(trigTxNum).r_TxLen) ){
|
|
||||||
stateDMA := 0.U
|
|
||||||
} .elsewhen( stateCur === stateRx & ~txBuff.io.deq.valid ){
|
|
||||||
stateDMA := 0.U
|
|
||||||
} .otherwise{
|
|
||||||
stateDMA := 1.U
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
trait DMAMstTileLink{ this: DMAMstBase =>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val mInfoValid = stateCur === stateTx
|
|
||||||
|
|
||||||
when( txBuff.io.deq.valid & stateCur === stateIdle & stateNxt === stateRx ){
|
|
||||||
|
|
||||||
trigRxNum := io.selIn
|
|
||||||
|
|
||||||
dmaAddress := io.cfg(io.selIn).r_RxPtr
|
|
||||||
}
|
|
||||||
|
|
||||||
for( i <- 0 until chn ){
|
|
||||||
io.cfg(i).triRx := txBuff.io.deq.fire & txBuff.io.deq.bits.isLast & trigRxNum === i.U
|
|
||||||
io.cfg(i).r_RxLen := RegEnable( rxLength + 1.U, io.cfg(i).triRx )
|
|
||||||
}
|
|
||||||
|
|
||||||
for( i <- 0 until chn ){
|
|
||||||
when( io.cfg(i).triTx & io.cfg(i).r_TxLen > 32.U & stateCur === stateIdle ){
|
|
||||||
trigTxNum := i.U
|
|
||||||
dmaAddress := io.cfg(i).r_TxPtr
|
|
||||||
assert( stateNxt === stateTx )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
when( io.dmaMst.A.fire ){
|
|
||||||
dmaAddress := dmaAddress + 1.U
|
|
||||||
}
|
|
||||||
|
|
||||||
txBuff.io.deq.ready := io.dmaMst.A.fire & (stateCur === stateRx)
|
|
||||||
assert( ~(txBuff.io.deq.ready & ~txBuff.io.deq.valid) )
|
|
||||||
|
|
||||||
when( io.dmaMst.A.fire ){
|
|
||||||
dmaAValid := false.B
|
|
||||||
}.elsewhen( stateDMA === 1.U & ~io.dmaMst.A.valid & stateCur === stateTx ){
|
|
||||||
dmaAValid := true.B
|
|
||||||
dmaABits :=
|
|
||||||
edgeOut.Get(
|
|
||||||
fromSource = 0.U,
|
|
||||||
toAddress = dmaAddress,
|
|
||||||
lgSize = log2Ceil(8/8).U,
|
|
||||||
)._2
|
|
||||||
} .elsewhen( stateDMA === 1.U & ~io.dmaMst.A.valid & stateCur === stateRx ) {
|
|
||||||
dmaAValid := true.B
|
|
||||||
dmaABits :=
|
|
||||||
edgeOut.Put(
|
|
||||||
fromSource = 0.U,
|
|
||||||
toAddress = dmaAddress,
|
|
||||||
lgSize = log2Ceil(8/8).U,
|
|
||||||
data = txBuff.io.deq.bits.data,
|
|
||||||
mask = "b1".U,
|
|
||||||
)._2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
io.dmaMst.A.valid := dmaAValid
|
|
||||||
io.dmaMst.A.bits := dmaABits
|
|
||||||
|
|
||||||
|
|
||||||
io.dmaMst.D.ready :=
|
|
||||||
Mux1H(Seq(
|
|
||||||
( stateCur === stateRx ) -> true.B,
|
|
||||||
( stateCur === stateTx ) -> rxBuff.io.enq.ready,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
trait DMAMstBuff{ this: DMAMstBase =>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
when( txBuff.io.deq.fire ){
|
|
||||||
when( txBuff.io.deq.bits.isStart ){
|
|
||||||
rxLength := 0.U
|
|
||||||
} .otherwise{
|
|
||||||
rxLength := rxLength + 1.U
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rxBuff.io.enq.valid := io.dmaMst.D.valid & stateCur === stateTx
|
|
||||||
rxBuff.io.enq.bits.data := io.dmaMst.D.bits.data
|
|
||||||
rxBuff.io.enq.bits.isStart := RegEnable( dmaAddress === io.cfg(trigTxNum).r_TxPtr, io.dmaMst.A.fire)
|
|
||||||
rxBuff.io.enq.bits.isLast := dmaAddress === (io.cfg(trigTxNum).r_TxPtr + io.cfg(trigTxNum).r_TxLen)
|
|
||||||
|
|
||||||
io.selOut := trigTxNum
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
abstract class DMAMst(edgeOut: TLEdgeOut)(implicit p: Parameters) extends DMAMstBase(edgeOut)
|
|
||||||
with DMAMstFSM
|
|
||||||
with DMAMstTileLink
|
|
||||||
with DMAMstBuff
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
package Switch
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
|
|
||||||
import freechips.rocketchip.regmapper._
|
|
||||||
import freechips.rocketchip.tilelink._
|
|
||||||
import org.chipsalliance.cde.config._
|
|
||||||
import freechips.rocketchip.diplomacy._
|
|
||||||
import freechips.rocketchip.interrupts._
|
|
||||||
|
|
||||||
|
|
||||||
class DMA_Register_Bundle extends Bundle{
|
|
||||||
val r_TxPtr = Output(UInt(32.W))
|
|
||||||
val r_RxPtr = Output(UInt(32.W))
|
|
||||||
val r_TxLen = Output(UInt(16.W))
|
|
||||||
val r_RxLen = Input (UInt(16.W))
|
|
||||||
val triTx = Output( Bool())
|
|
||||||
val triRx = Input ( Bool())
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class DmaRegIO(implicit p: Parameters) extends SwitchBundle{
|
|
||||||
|
|
||||||
val MacAddr = Output(UInt(48.W))
|
|
||||||
|
|
||||||
val cfg = Vec( chn, new DMA_Register_Bundle )
|
|
||||||
}
|
|
||||||
|
|
||||||
class DmaReg(implicit p: Parameters) extends LazyModule with HasSwitchParameters{
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// DTS
|
|
||||||
val dtsdevice = new SimpleDevice("dma",Seq("dma_0"))
|
|
||||||
|
|
||||||
|
|
||||||
val configNode = TLRegisterNode(
|
|
||||||
address = Seq(AddressSet(0x30001000L, 0x00000fffL)),
|
|
||||||
device = dtsdevice,
|
|
||||||
concurrency = 1,
|
|
||||||
beatBytes = 32/8,
|
|
||||||
executable = true
|
|
||||||
)
|
|
||||||
lazy val module = new DmaRegImp(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
class DmaRegImp(outer: DmaReg)(implicit p: Parameters) extends LazyModuleImp(outer) with HasSwitchParameters{
|
|
||||||
|
|
||||||
val io: DmaRegIO = IO(new DmaRegIO)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val txPtr = for( i <- 0 until chn ) yield { RegInit( "h80002000".U(32.W)) }
|
|
||||||
val rxPtr = for( i <- 0 until chn ) yield { RegInit( "h80002000".U(32.W)) }
|
|
||||||
val txLen = for( i <- 0 until chn ) yield { RegInit( 65535.U(16.W)) }
|
|
||||||
// val rxLen = RegInit( 65535.U(16.W))
|
|
||||||
val triRx = for( i <- 0 until chn ) yield { RegInit(false.B) }
|
|
||||||
|
|
||||||
for( i <- 0 until chn ) {
|
|
||||||
io.cfg(i).r_TxPtr := txPtr(i)
|
|
||||||
io.cfg(i).r_RxPtr := rxPtr(i)
|
|
||||||
io.cfg(i).r_TxLen := txLen(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
for( i <- 0 until chn ) { when( io.cfg(i).triRx ) { triRx(i) := true.B } }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val comMap = Seq(
|
|
||||||
( 0 << 2 ) ->
|
|
||||||
RegFieldGroup("MAC_ADDR0", Some("MAC Address Register 0"), Seq(
|
|
||||||
RegField(32)
|
|
||||||
)),
|
|
||||||
|
|
||||||
( 1 << 2 ) ->
|
|
||||||
RegFieldGroup("MAC_ADDR1", Some("MAC Address Register 1"), Seq(
|
|
||||||
RegField(32)
|
|
||||||
))
|
|
||||||
)
|
|
||||||
|
|
||||||
val trigMap =
|
|
||||||
((0 until chn).map{ i =>
|
|
||||||
( (10*i + 10) << 2 ) ->
|
|
||||||
RegFieldGroup("DMATrigger", Some("Tx Control DMA"), Seq(
|
|
||||||
RegField.w(1, RegWriteFn((valid, data) => { io.cfg(i).triTx := (valid & (data === 1.U)) ; true.B} ), RegFieldDesc("bd", s"bd$i", reset=Some(0x0))),
|
|
||||||
RegField(1, triRx(i), RegFieldDesc("bd", s"bd$i", reset=Some(0x0)))
|
|
||||||
))
|
|
||||||
})
|
|
||||||
|
|
||||||
val lenMap =
|
|
||||||
(0 until chn).map{ i =>
|
|
||||||
( (10*i + 11) << 2 ) ->
|
|
||||||
RegFieldGroup("TxRxDMALength", Some("Tx RxControl DMA"), Seq(
|
|
||||||
RegField(16, txLen(i), RegFieldDesc("txLen", "length of tx", reset=Some(65535))),
|
|
||||||
RegField.r(16, io.cfg(i).r_RxLen, RegFieldDesc("rxLen", "length of rx")),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
val txAddrMap =
|
|
||||||
(0 until chn).map{ i =>
|
|
||||||
( (10*i + 12) << 2 ) ->
|
|
||||||
RegFieldGroup("TxDMAAddress", Some("Tx Control DMA"), Seq(
|
|
||||||
RegField(32, txPtr(i), RegFieldDesc("txPtr", "pointer of tx", reset=Some(0x80002000))),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
val rxAddrMap =
|
|
||||||
(0 until chn).map{ i =>
|
|
||||||
( (10*i + 13) << 2 ) ->
|
|
||||||
RegFieldGroup("RxDMAAddress", Some("Rx Control DMA"), Seq(
|
|
||||||
RegField(32, rxPtr(i), RegFieldDesc("rxPtr", "pointer of rx", reset=Some(0x80002000))),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
val regMap = comMap ++ trigMap ++ lenMap ++ txAddrMap ++ rxAddrMap
|
|
||||||
outer.configNode.regmap(regMap: _*)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,468 +0,0 @@
|
|||||||
package Switch
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
|
|
||||||
import org.chipsalliance.cde.config._
|
|
||||||
|
|
||||||
import MAC._
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MII extends Bundle with MDIO{
|
|
||||||
// Tx
|
|
||||||
val mtx_clk_pad_i = Input(Bool())
|
|
||||||
val mtxd_pad_o = Output(UInt(4.W))
|
|
||||||
val mtxen_pad_o = Output(Bool())
|
|
||||||
|
|
||||||
// Rx
|
|
||||||
val mrx_clk_pad_i = Input(Bool())
|
|
||||||
val mrxd_pad_i = Input(UInt(4.W))
|
|
||||||
val mrxdv_pad_i = Input(Bool())
|
|
||||||
|
|
||||||
// Common Tx and Rx
|
|
||||||
val mcoll_pad_i = Input(Bool())
|
|
||||||
val mcrs_pad_i = Input(Bool())
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MacIO extends Bundle{
|
|
||||||
val mii = new MII
|
|
||||||
val cfg = Flipped(new Mac_Config_Bundle)
|
|
||||||
|
|
||||||
// val int_o = Output(Bool())
|
|
||||||
|
|
||||||
val isLoopBack = Output(Bool())
|
|
||||||
val asyncReset = Input(AsyncReset())
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
abstract class Mac(implicit p: Parameters) extends SwitchNode{
|
|
||||||
|
|
||||||
val io = IO(new MacIO)
|
|
||||||
|
|
||||||
|
|
||||||
val r_ClkDiv = Wire(UInt(8.W))
|
|
||||||
val r_MiiNoPre = Wire(Bool())
|
|
||||||
val r_CtrlData = Wire(UInt(16.W))
|
|
||||||
val r_FIAD = Wire(UInt(5.W))
|
|
||||||
val r_RGAD = Wire(UInt(5.W))
|
|
||||||
val r_WCtrlData = Wire(Bool())
|
|
||||||
val r_RStat = Wire(Bool())
|
|
||||||
val r_ScanStat = Wire(Bool())
|
|
||||||
val NValid_stat = Wire(Bool())
|
|
||||||
val Busy_stat = Wire(Bool())
|
|
||||||
val LinkFail = Wire(Bool())
|
|
||||||
val Prsd = Wire(UInt(16.W))
|
|
||||||
val WCtrlDataStart = Wire(Bool())
|
|
||||||
val RStatStart = Wire(Bool())
|
|
||||||
val UpdateMIIRX_DATAReg = Wire(Bool())
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val TxStartFrm = Wire(Bool())
|
|
||||||
val TxEndFrm = Wire(Bool())
|
|
||||||
val TxUsedData = Wire(Bool())
|
|
||||||
val TxData = Wire(UInt(8.W))
|
|
||||||
val TxAbort = Wire(Bool())
|
|
||||||
val TxDone = Wire(Bool())
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Connecting Miim module
|
|
||||||
val miim = Module(new MIIM)
|
|
||||||
|
|
||||||
miim.io.Divider := r_ClkDiv
|
|
||||||
miim.io.NoPre := r_MiiNoPre
|
|
||||||
miim.io.WCtrlData := r_WCtrlData
|
|
||||||
miim.io.CtrlData := r_CtrlData
|
|
||||||
miim.io.Fiad := r_FIAD
|
|
||||||
miim.io.Rgad := r_RGAD
|
|
||||||
miim.io.RStat := r_RStat
|
|
||||||
miim.io.ScanStat := r_ScanStat
|
|
||||||
|
|
||||||
miim.io.mdi := io.mii.mdi
|
|
||||||
|
|
||||||
Busy_stat := miim.io.Busy
|
|
||||||
LinkFail := miim.io.LinkFail
|
|
||||||
NValid_stat := miim.io.Nvalid
|
|
||||||
Prsd := miim.io.Prsd
|
|
||||||
WCtrlDataStart := miim.io.WCtrlDataStart
|
|
||||||
RStatStart := miim.io.RStatStart
|
|
||||||
UpdateMIIRX_DATAReg := miim.io.UpdateMIIRX_DATAReg
|
|
||||||
|
|
||||||
io.mii.mdc := miim.io.mdc
|
|
||||||
io.mii.mdo := miim.io.mdo
|
|
||||||
io.mii.mdoEn := miim.io.mdoEn
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val r_LoopBck = Wire(Bool())
|
|
||||||
val r_TxEn = Wire(Bool())
|
|
||||||
val r_RxEn = Wire(Bool())
|
|
||||||
val MRxDV_Lb = Wire(Bool())
|
|
||||||
val MRxD_Lb = Wire(UInt(4.W))
|
|
||||||
val Transmitting = Wire(Bool())
|
|
||||||
val DribbleNibble = Wire(Bool())
|
|
||||||
val LoadRxStatus = Wire(Bool())
|
|
||||||
val r_HASH0 = Wire(UInt(32.W))
|
|
||||||
val r_HASH1 = Wire(UInt(32.W))
|
|
||||||
val r_IPGT = Wire(UInt(7.W))
|
|
||||||
val r_IPGR1 = Wire(UInt(7.W))
|
|
||||||
val r_IPGR2 = Wire(UInt(7.W))
|
|
||||||
val r_CollValid = Wire(UInt(6.W))
|
|
||||||
val r_ExDfrEn = Wire(Bool())
|
|
||||||
val r_IFG = Wire(Bool())
|
|
||||||
val TxB_IRQ = Wire(Bool())
|
|
||||||
val TxE_IRQ = Wire(Bool())
|
|
||||||
val RxB_IRQ = Wire(Bool())
|
|
||||||
val RxE_IRQ = Wire(Bool())
|
|
||||||
val Busy_IRQ = Wire(Bool())
|
|
||||||
val r_FullD = Wire(Bool())
|
|
||||||
val r_NoPre = Wire(Bool())
|
|
||||||
val StartTxDone = Wire(Bool())
|
|
||||||
val PerPacketCrcEn = Wire(Bool())
|
|
||||||
val LateCollision = Wire(Bool())
|
|
||||||
val DeferIndication = Wire(Bool())
|
|
||||||
val LateCollLatched = Wire(Bool())
|
|
||||||
val DeferLatched = Wire(Bool())
|
|
||||||
val RstDeferLatched = Wire(Bool())
|
|
||||||
val CarrierSenseLost = Wire(Bool())
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
io.cfg.WCtrlDataStart := WCtrlDataStart
|
|
||||||
io.cfg.RStatStart := RStatStart
|
|
||||||
io.cfg.UpdateMIIRX_DATAReg := UpdateMIIRX_DATAReg
|
|
||||||
io.cfg.Prsd := Prsd
|
|
||||||
io.cfg.NValid_stat := NValid_stat
|
|
||||||
io.cfg.Busy_stat := Busy_stat
|
|
||||||
io.cfg.LinkFail := LinkFail
|
|
||||||
io.cfg.TxB_IRQ := TxB_IRQ
|
|
||||||
io.cfg.TxE_IRQ := TxE_IRQ
|
|
||||||
io.cfg.RxB_IRQ := RxB_IRQ
|
|
||||||
io.cfg.RxE_IRQ := RxE_IRQ
|
|
||||||
io.cfg.Busy_IRQ := Busy_IRQ
|
|
||||||
io.cfg.StartTxDone := StartTxDone
|
|
||||||
io.cfg.TxClk := io.mii.mtx_clk_pad_i
|
|
||||||
io.cfg.RxClk := io.mii.mrx_clk_pad_i
|
|
||||||
|
|
||||||
r_FullD := io.cfg.r_FullD
|
|
||||||
r_ExDfrEn := io.cfg.r_ExDfrEn
|
|
||||||
r_LoopBck := io.cfg.r_LoopBck
|
|
||||||
r_IFG := io.cfg.r_IFG
|
|
||||||
r_NoPre := io.cfg.r_NoPre
|
|
||||||
r_TxEn := io.cfg.r_TxEn
|
|
||||||
r_RxEn := io.cfg.r_RxEn
|
|
||||||
r_HASH0 := io.cfg.r_HASH0
|
|
||||||
r_HASH1 := io.cfg.r_HASH1
|
|
||||||
r_IPGT := io.cfg.r_IPGT
|
|
||||||
r_IPGR1 := io.cfg.r_IPGR1
|
|
||||||
r_IPGR2 := io.cfg.r_IPGR2
|
|
||||||
r_CollValid := io.cfg.r_CollValid
|
|
||||||
r_MiiNoPre := io.cfg.r_MiiNoPre
|
|
||||||
r_ClkDiv := io.cfg.r_ClkDiv
|
|
||||||
r_WCtrlData := io.cfg.r_WCtrlData
|
|
||||||
r_RStat := io.cfg.r_RStat
|
|
||||||
r_ScanStat := io.cfg.r_ScanStat
|
|
||||||
r_RGAD := io.cfg.r_RGAD
|
|
||||||
r_FIAD := io.cfg.r_FIAD
|
|
||||||
r_CtrlData := io.cfg.r_CtrlData
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val RxData = Wire(UInt(8.W))
|
|
||||||
val RxValid = Wire(Bool())
|
|
||||||
val RxStartFrm = Wire(Bool())
|
|
||||||
val RxEndFrm = Wire(Bool())
|
|
||||||
val WillTransmit = Wire(Bool())
|
|
||||||
val ResetCollision = Wire(Bool())
|
|
||||||
val LatchedCrcError = Wire(Bool())
|
|
||||||
val RxLateCollision = Wire(Bool())
|
|
||||||
val StartTxAbort = Wire(Bool())
|
|
||||||
val MaxCollisionOccured = Wire(Bool())
|
|
||||||
val RetryLimit = Wire(Bool())
|
|
||||||
val StatePreamble = Wire(Bool())
|
|
||||||
val StateData = Wire(UInt(2.W))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val TxCarrierSense = Wire(Bool())
|
|
||||||
val Collision = Wire(Bool())
|
|
||||||
val CarrierSense_Tx2 = Wire(Bool())
|
|
||||||
val RxEnSync = Wire(Bool())
|
|
||||||
|
|
||||||
|
|
||||||
io.isLoopBack := r_LoopBck
|
|
||||||
|
|
||||||
// Muxed MII receive data valid
|
|
||||||
MRxDV_Lb := Mux(r_LoopBck, io.mii.mtxen_pad_o, io.mii.mrxdv_pad_i & RxEnSync)
|
|
||||||
|
|
||||||
// Muxed MII Receive Data
|
|
||||||
MRxD_Lb := Mux(r_LoopBck, io.mii.mtxd_pad_o, io.mii.mrxd_pad_i)
|
|
||||||
|
|
||||||
|
|
||||||
val txethmac = withClockAndReset(io.mii.mtx_clk_pad_i.asClock, io.asyncReset)( Module(new MacTx))
|
|
||||||
|
|
||||||
txethmac.io.TxStartFrm := TxStartFrm
|
|
||||||
txethmac.io.TxEndFrm := TxEndFrm
|
|
||||||
txethmac.io.TxData := TxData
|
|
||||||
txethmac.io.CarrierSense := TxCarrierSense
|
|
||||||
txethmac.io.Collision := Collision
|
|
||||||
txethmac.io.CrcEn := PerPacketCrcEn
|
|
||||||
txethmac.io.FullD := r_FullD
|
|
||||||
txethmac.io.IPGT := r_IPGT
|
|
||||||
txethmac.io.IPGR1 := r_IPGR1
|
|
||||||
txethmac.io.IPGR2 := r_IPGR2
|
|
||||||
txethmac.io.CollValid := r_CollValid
|
|
||||||
txethmac.io.ExDfrEn := r_ExDfrEn
|
|
||||||
|
|
||||||
io.mii.mtxd_pad_o := txethmac.io.MTxD
|
|
||||||
io.mii.mtxen_pad_o := txethmac.io.MTxEn
|
|
||||||
TxDone := txethmac.io.TxDone
|
|
||||||
TxAbort := txethmac.io.TxAbort
|
|
||||||
TxUsedData := txethmac.io.TxUsedData
|
|
||||||
WillTransmit := txethmac.io.WillTransmit
|
|
||||||
ResetCollision := txethmac.io.ResetCollision
|
|
||||||
StartTxDone := txethmac.io.StartTxDone
|
|
||||||
StartTxAbort := txethmac.io.StartTxAbort
|
|
||||||
MaxCollisionOccured := txethmac.io.MaxCollisionOccured
|
|
||||||
LateCollision := txethmac.io.LateCollision
|
|
||||||
DeferIndication := txethmac.io.DeferIndication
|
|
||||||
StatePreamble := txethmac.io.StatePreamble
|
|
||||||
StateData := txethmac.io.StateData
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val RxByteCnt = Wire(UInt(16.W))
|
|
||||||
val RxByteCntEq0 = Wire(Bool())
|
|
||||||
val RxByteCntGreat2 = Wire(Bool())
|
|
||||||
val RxCrcError = Wire(Bool())
|
|
||||||
val RxStateIdle = Wire(Bool())
|
|
||||||
val RxStatePreamble = Wire(Bool())
|
|
||||||
val RxStateSFD = Wire(Bool())
|
|
||||||
val RxStateData = Wire(UInt(2.W))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val rxethmac = withClockAndReset(io.mii.mrx_clk_pad_i.asClock, io.asyncReset)( Module(new MacRx))
|
|
||||||
|
|
||||||
rxethmac.io.MRxDV := MRxDV_Lb
|
|
||||||
rxethmac.io.MRxD := MRxD_Lb
|
|
||||||
rxethmac.io.Transmitting := Transmitting
|
|
||||||
rxethmac.io.r_IFG := r_IFG
|
|
||||||
rxethmac.io.r_HASH0 := r_HASH0
|
|
||||||
rxethmac.io.r_HASH1 := r_HASH1
|
|
||||||
|
|
||||||
RxData := rxethmac.io.RxData
|
|
||||||
RxValid := rxethmac.io.RxValid
|
|
||||||
RxStartFrm := rxethmac.io.RxStartFrm
|
|
||||||
RxEndFrm := rxethmac.io.RxEndFrm
|
|
||||||
RxByteCnt := rxethmac.io.ByteCnt
|
|
||||||
RxByteCntEq0 := rxethmac.io.ByteCntEq0
|
|
||||||
RxByteCntGreat2 := rxethmac.io.ByteCntGreat2
|
|
||||||
RxCrcError := rxethmac.io.CrcError
|
|
||||||
RxStateIdle := rxethmac.io.StateIdle
|
|
||||||
RxStatePreamble := rxethmac.io.StatePreamble
|
|
||||||
RxStateSFD := rxethmac.io.StateSFD
|
|
||||||
RxStateData := rxethmac.io.StateData
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
withClockAndReset( io.mii.mtx_clk_pad_i.asClock, reset.asAsyncReset ) {
|
|
||||||
// MII Carrier Sense Synchronization
|
|
||||||
CarrierSense_Tx2 := ShiftRegister(io.mii.mcrs_pad_i, 2, false.B, true.B)
|
|
||||||
|
|
||||||
TxCarrierSense := ~r_FullD & CarrierSense_Tx2
|
|
||||||
|
|
||||||
val Collision_Tx1 = RegNext(io.mii.mcoll_pad_i, false.B)
|
|
||||||
val Collision_Tx2 = RegInit(false.B)
|
|
||||||
|
|
||||||
when(ResetCollision){
|
|
||||||
Collision_Tx2 := false.B
|
|
||||||
} .elsewhen(Collision_Tx1){
|
|
||||||
Collision_Tx2 := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Synchronized Collision
|
|
||||||
Collision := ~r_FullD & Collision_Tx2
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
withClockAndReset( io.mii.mrx_clk_pad_i.asClock, reset.asAsyncReset ) {
|
|
||||||
val WillTransmit_q = ShiftRegister(WillTransmit, 2, false.B, true.B)
|
|
||||||
|
|
||||||
Transmitting := ~r_FullD & WillTransmit_q
|
|
||||||
RxEnSync := RegEnable( ShiftRegister(r_RxEn, 2), false.B, ~io.mii.mrxdv_pad_i)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val macstatus = Module(new MacStatus)
|
|
||||||
|
|
||||||
macstatus.io.asyncReset := io.asyncReset
|
|
||||||
macstatus.io.MRxClk := io.mii.mrx_clk_pad_i
|
|
||||||
macstatus.io.RxCrcError := RxCrcError
|
|
||||||
macstatus.io.MRxDV := MRxDV_Lb
|
|
||||||
macstatus.io.RxStateSFD := RxStateSFD
|
|
||||||
macstatus.io.RxStateData := RxStateData
|
|
||||||
macstatus.io.RxStatePreamble := RxStatePreamble
|
|
||||||
macstatus.io.RxStateIdle := RxStateIdle
|
|
||||||
macstatus.io.Transmitting := Transmitting
|
|
||||||
macstatus.io.RxByteCnt := RxByteCnt
|
|
||||||
macstatus.io.RxByteCntEq0 := RxByteCntEq0
|
|
||||||
macstatus.io.RxByteCntGreat2 := RxByteCntGreat2
|
|
||||||
macstatus.io.MRxD := MRxD_Lb
|
|
||||||
macstatus.io.Collision := io.mii.mcoll_pad_i
|
|
||||||
macstatus.io.CollValid := r_CollValid
|
|
||||||
macstatus.io.StartTxDone := StartTxDone
|
|
||||||
macstatus.io.StartTxAbort := StartTxAbort
|
|
||||||
macstatus.io.MTxClk := io.mii.mtx_clk_pad_i
|
|
||||||
macstatus.io.MaxCollisionOccured := MaxCollisionOccured
|
|
||||||
macstatus.io.LateCollision := LateCollision
|
|
||||||
macstatus.io.DeferIndication := DeferIndication
|
|
||||||
macstatus.io.TxStartFrm := TxStartFrm
|
|
||||||
macstatus.io.StatePreamble := StatePreamble
|
|
||||||
macstatus.io.StateData := StateData
|
|
||||||
macstatus.io.CarrierSense := CarrierSense_Tx2
|
|
||||||
macstatus.io.Loopback := r_LoopBck
|
|
||||||
macstatus.io.r_FullD := r_FullD
|
|
||||||
macstatus.io.RstDeferLatched := RstDeferLatched
|
|
||||||
|
|
||||||
LatchedCrcError := macstatus.io.LatchedCrcError
|
|
||||||
RxLateCollision := macstatus.io.RxLateCollision
|
|
||||||
DribbleNibble := macstatus.io.DribbleNibble
|
|
||||||
LoadRxStatus := macstatus.io.LoadRxStatus
|
|
||||||
RetryLimit := macstatus.io.RetryLimit
|
|
||||||
LateCollLatched := macstatus.io.LateCollLatched
|
|
||||||
DeferLatched := macstatus.io.DeferLatched
|
|
||||||
CarrierSenseLost := macstatus.io.CarrierSenseLost
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val macTileLinkTx = Module(new MacTileLinkTx)
|
|
||||||
|
|
||||||
RstDeferLatched := macTileLinkTx.io.RstDeferLatched
|
|
||||||
TxStartFrm := macTileLinkTx.io.TxStartFrm
|
|
||||||
TxEndFrm := macTileLinkTx.io.TxEndFrm
|
|
||||||
TxData := macTileLinkTx.io.TxData
|
|
||||||
macTileLinkTx.io.TxUsedData := TxUsedData
|
|
||||||
macTileLinkTx.io.TxAbort := TxAbort
|
|
||||||
macTileLinkTx.io.TxDone := TxDone
|
|
||||||
|
|
||||||
macTileLinkTx.io.RetryLimit := RetryLimit
|
|
||||||
macTileLinkTx.io.LateCollLatched := LateCollLatched
|
|
||||||
macTileLinkTx.io.DeferLatched := DeferLatched
|
|
||||||
macTileLinkTx.io.CarrierSenseLost := CarrierSenseLost
|
|
||||||
PerPacketCrcEn := macTileLinkTx.io.PerPacketCrcEn
|
|
||||||
|
|
||||||
macTileLinkTx.io.r_TxEn := r_TxEn
|
|
||||||
|
|
||||||
macTileLinkTx.io.isTxIdle := txethmac.io.isTxIdle
|
|
||||||
|
|
||||||
macTileLinkTx.io.MTxClk := io.mii.mtx_clk_pad_i
|
|
||||||
macTileLinkTx.io.asyncReset := io.asyncReset
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val macTileLinkRx = Module(new MacTileLinkRx)
|
|
||||||
macTileLinkRx.io.DribbleNibble := DribbleNibble
|
|
||||||
macTileLinkRx.io.LatchedCrcError := LatchedCrcError
|
|
||||||
macTileLinkRx.io.RxLateCollision := RxLateCollision
|
|
||||||
macTileLinkRx.io.LoadRxStatus := LoadRxStatus
|
|
||||||
|
|
||||||
macTileLinkRx.io.RxData := RxData
|
|
||||||
macTileLinkRx.io.RxValid := RxValid
|
|
||||||
macTileLinkRx.io.RxStartFrm := RxStartFrm
|
|
||||||
macTileLinkRx.io.RxEndFrm := RxEndFrm
|
|
||||||
|
|
||||||
Busy_IRQ := macTileLinkRx.io.Busy_IRQ
|
|
||||||
|
|
||||||
macTileLinkRx.io.r_RxEn := r_RxEn
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
macTileLinkRx.io.MRxClk := io.mii.mrx_clk_pad_i
|
|
||||||
macTileLinkRx.io.asyncReset := io.asyncReset
|
|
||||||
|
|
||||||
TxB_IRQ := false.B
|
|
||||||
TxE_IRQ := false.B
|
|
||||||
RxB_IRQ := false.B
|
|
||||||
RxE_IRQ := false.B
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,349 +0,0 @@
|
|||||||
package Switch
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
|
|
||||||
import freechips.rocketchip.regmapper._
|
|
||||||
import freechips.rocketchip.tilelink._
|
|
||||||
import org.chipsalliance.cde.config._
|
|
||||||
import freechips.rocketchip.diplomacy._
|
|
||||||
import freechips.rocketchip.interrupts._
|
|
||||||
|
|
||||||
class Mac_Config_Bundle extends Bundle{
|
|
||||||
val WCtrlDataStart = Input(Bool())
|
|
||||||
val RStatStart = Input(Bool())
|
|
||||||
val UpdateMIIRX_DATAReg = Input(Bool())
|
|
||||||
val Prsd = Input(UInt(16.W))
|
|
||||||
val NValid_stat = Input(Bool())
|
|
||||||
val Busy_stat = Input(Bool())
|
|
||||||
val LinkFail = Input(Bool())
|
|
||||||
val TxB_IRQ = Input(Bool())
|
|
||||||
val TxE_IRQ = Input(Bool())
|
|
||||||
val RxB_IRQ = Input(Bool())
|
|
||||||
val RxE_IRQ = Input(Bool())
|
|
||||||
val Busy_IRQ = Input(Bool())
|
|
||||||
val StartTxDone = Input(Bool())
|
|
||||||
val TxClk = Input(Bool())
|
|
||||||
val RxClk = Input(Bool())
|
|
||||||
|
|
||||||
val r_FullD = Output(Bool())
|
|
||||||
val r_ExDfrEn = Output(Bool())
|
|
||||||
val r_LoopBck = Output(Bool())
|
|
||||||
val r_IFG = Output(Bool())
|
|
||||||
val r_NoPre = Output(Bool())
|
|
||||||
val r_TxEn = Output(Bool())
|
|
||||||
val r_RxEn = Output(Bool())
|
|
||||||
val r_HASH0 = Output(UInt(32.W))
|
|
||||||
val r_HASH1 = Output(UInt(32.W))
|
|
||||||
val r_IPGT = Output(UInt(7.W))
|
|
||||||
val r_IPGR1 = Output(UInt(7.W))
|
|
||||||
val r_IPGR2 = Output(UInt(7.W))
|
|
||||||
val r_CollValid = Output(UInt(6.W))
|
|
||||||
val r_MiiNoPre = Output(Bool())
|
|
||||||
val r_ClkDiv = Output(UInt(8.W))
|
|
||||||
val r_WCtrlData = Output(Bool())
|
|
||||||
val r_RStat = Output(Bool())
|
|
||||||
val r_ScanStat = Output(Bool())
|
|
||||||
val r_RGAD = Output(UInt(5.W))
|
|
||||||
val r_FIAD = Output(UInt(5.W))
|
|
||||||
val r_CtrlData = Output(UInt(16.W))
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class MacRegIO extends Mac_Config_Bundle{
|
|
||||||
val asyncReset = Input(AsyncReset())
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MacReg(chn: Int)(implicit p: Parameters) extends LazyModule{
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// DTS
|
|
||||||
val dtsdevice = new SimpleDevice(s"mac$chn",Seq(s"mac_$chn"))
|
|
||||||
val int_node = IntSourceNode(IntSourcePortSimple(num = 1, resources = dtsdevice.int))
|
|
||||||
|
|
||||||
|
|
||||||
val configNode = TLRegisterNode(
|
|
||||||
address = Seq(AddressSet(0x30000000L + 0x100*chn, 0x000000ffL)),
|
|
||||||
device = dtsdevice,
|
|
||||||
concurrency = 1,
|
|
||||||
beatBytes = 32/8,
|
|
||||||
executable = true
|
|
||||||
)
|
|
||||||
lazy val module = new MacRegImp(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
class MacRegImp(outer: MacReg)(implicit p: Parameters) extends LazyModuleImp(outer) with HasSwitchParameters{
|
|
||||||
|
|
||||||
val io: MacRegIO = IO(new MacRegIO)
|
|
||||||
val (int, _) = outer.int_node.out(0)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val FullD = RegInit(false.B)
|
|
||||||
val ExDfrEn = RegInit(false.B)
|
|
||||||
val LoopBck = RegInit(false.B)
|
|
||||||
val IFG = RegInit(false.B)
|
|
||||||
val NoPre = RegInit(false.B)
|
|
||||||
val TxEn = RegInit(false.B)
|
|
||||||
val RxEn = RegInit(false.B)
|
|
||||||
|
|
||||||
// Interrupt generation
|
|
||||||
val irq_txb = RegInit(false.B)
|
|
||||||
val irq_txe = RegInit(false.B)
|
|
||||||
val irq_rxb = RegInit(false.B)
|
|
||||||
val irq_rxe = RegInit(false.B)
|
|
||||||
val irq_busy = RegInit(false.B)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val INT_MASK = RegInit(0.U(7.W)) // INT_MASK Register
|
|
||||||
val IPGT = RegInit("h12".U(7.W)) // IPGT Register
|
|
||||||
val IPGR1 = RegInit("h0C".U(7.W)) // IPGR1 Register
|
|
||||||
val IPGR2 = RegInit("h12".U(7.W))
|
|
||||||
|
|
||||||
val collValid = RegInit("h3f".U(6.W))
|
|
||||||
|
|
||||||
val clkDiv = RegInit("h64".U(8.W))
|
|
||||||
val miiNoPre = RegInit(false.B)
|
|
||||||
|
|
||||||
|
|
||||||
val scanStat = RegInit(false.B)
|
|
||||||
val readStat = RegInit(false.B)
|
|
||||||
val wCtrlData = RegInit(false.B)
|
|
||||||
|
|
||||||
when(io.RStatStart){ readStat := false.B }
|
|
||||||
when(io.WCtrlDataStart){ wCtrlData := false.B }
|
|
||||||
|
|
||||||
val FIAD = RegInit(0.U(5.W))
|
|
||||||
val RGAD = RegInit(0.U(5.W))
|
|
||||||
|
|
||||||
val MIITX_DATA = RegInit(0.U(16.W)) // MIITX_DATA Register
|
|
||||||
|
|
||||||
val MIIRX_DATA = RegEnable(io.Prsd, 0.U(16.W), io.UpdateMIIRX_DATAReg) // MIIRX_DATA Register
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val HASH0 = RegInit(0.U(32.W))
|
|
||||||
val HASH1 = RegInit(0.U(32.W))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
outer.configNode.regmap(
|
|
||||||
( 0 << 2 ) ->
|
|
||||||
RegFieldGroup("MODER", Some("Mode Register"), Seq(
|
|
||||||
RegField(1, RxEn , RegFieldDesc( "RxEn", "RxEn", reset = Some(0))) ,
|
|
||||||
RegField(1, TxEn , RegFieldDesc( "TxEn", "TxEn", reset = Some(0) ) ),
|
|
||||||
RegField(1, NoPre , RegFieldDesc( "NoPre", "NoPre", reset = Some(0) ) ),
|
|
||||||
RegField.r(1, 0.U , RegFieldDesc( "Bro", "Bro", reset = Some(0) ) ),
|
|
||||||
RegField.r(1, 0.U , RegFieldDesc( "Iam", "Iam Unused", reset = Some(0) ) ),
|
|
||||||
RegField.r(1, 0.U , RegFieldDesc( "Pro", "Pro", reset = Some(0) ) ),
|
|
||||||
RegField(1, IFG , RegFieldDesc( "IFG", "IFG", reset = Some(0) ) ),
|
|
||||||
RegField(1, LoopBck, RegFieldDesc( "LoopBck", "LoopBck", reset = Some(0) ) ),
|
|
||||||
RegField.r(1, 0.U, RegFieldDesc( "NoBckof", "NoBckof", reset = Some(0) ) ),
|
|
||||||
RegField(1, ExDfrEn, RegFieldDesc( "ExDfrEn", "ExDfrEn", reset = Some(0) ) ),
|
|
||||||
RegField(1, FullD , RegFieldDesc( "FullD", "FullD", reset = Some(0) ) ),
|
|
||||||
RegField.r(1, 0.U),
|
|
||||||
RegField.r(1, 0.U, RegFieldDesc( "DlyCrcEn", "DlyCrcEn", reset=Some(0)) ),
|
|
||||||
RegField.r(1, 0.U, RegFieldDesc( "CrcEn", "CrcEn", reset=Some(1)) ),
|
|
||||||
RegField.r(1, 1.U , RegFieldDesc( "HugEn", "HugEn", reset=Some(0)) ),
|
|
||||||
RegField.r(1, 1.U , RegFieldDesc( "Pad", "Pad", reset=Some(1)) ),
|
|
||||||
RegField.r(1, 1.U, RegFieldDesc( "RecSmall", "RecSmall", reset=Some(0)) )
|
|
||||||
)),
|
|
||||||
|
|
||||||
( 1 << 2 ) ->
|
|
||||||
RegFieldGroup("INT_SOURCE", Some("Interrupt Source Register"), Seq(
|
|
||||||
RegField(1, irq_txb, RegWriteFn((valid, data) => { when ((valid & data) === 1.U) { irq_txb := 0.U }; true.B }), RegFieldDesc("txb", "txb", reset=Some(0))),
|
|
||||||
RegField(1, irq_txe, RegWriteFn((valid, data) => { when ((valid & data) === 1.U) { irq_txe := 0.U }; true.B }), RegFieldDesc("txe", "txe", reset=Some(0))),
|
|
||||||
RegField(1, irq_rxb, RegWriteFn((valid, data) => { when ((valid & data) === 1.U) { irq_rxb := 0.U }; true.B }), RegFieldDesc("rxb", "rxb", reset=Some(0))),
|
|
||||||
RegField(1, irq_rxe, RegWriteFn((valid, data) => { when ((valid & data) === 1.U) { irq_rxe := 0.U }; true.B }), RegFieldDesc("rxe", "rxe", reset=Some(0))),
|
|
||||||
RegField(1, irq_busy, RegWriteFn((valid, data) => { when ((valid & data) === 1.U) { irq_busy := 0.U }; true.B }), RegFieldDesc("busy", "busy", reset=Some(0))),
|
|
||||||
RegField.r(1, 0.U, RegFieldDesc("txc", "txc", reset=Some(0))),
|
|
||||||
RegField.r(1, 0.U, RegFieldDesc("rxc", "rxc", reset=Some(0))),
|
|
||||||
)),
|
|
||||||
|
|
||||||
( 2 << 2 ) ->
|
|
||||||
RegFieldGroup("INT_MASK", Some("Interrupt Mask Register"), Seq(
|
|
||||||
RegField(7, INT_MASK)
|
|
||||||
)),
|
|
||||||
|
|
||||||
( 3 << 2 ) ->
|
|
||||||
RegFieldGroup("IPGT", Some("Back to Back Inter Packet Gap Register"), Seq(
|
|
||||||
RegField(7, IPGT, RegFieldDesc("IPGT", "IPGT", reset=Some(0x12)))
|
|
||||||
)),
|
|
||||||
|
|
||||||
( 4 << 2 ) ->
|
|
||||||
RegFieldGroup("IPGR1", Some("Non Back to Back Inter Packet Gap Register 1"), Seq(
|
|
||||||
RegField(7, IPGR1, RegFieldDesc("IPGR1", "IPGR1", reset=Some(0xc)))
|
|
||||||
)),
|
|
||||||
|
|
||||||
( 5 << 2 ) ->
|
|
||||||
RegFieldGroup("IPGR2", Some("Non Back to Back Inter Packet Gap Register 2"), Seq(
|
|
||||||
RegField(7, IPGR2, RegFieldDesc("IPGR2", "IPGR2", reset=Some(0x12)))
|
|
||||||
)),
|
|
||||||
|
|
||||||
( 7 << 2 ) ->
|
|
||||||
RegFieldGroup("COLLCONF", Some("Collision and Retry Configuration Register"), Seq(
|
|
||||||
RegField(6, collValid, RegFieldDesc("collValid", "Collision Valid", reset=Some(0x3f))),
|
|
||||||
RegField.r(10,0.U),
|
|
||||||
RegField.r(4, 0.U, RegFieldDesc("maxRet", "Maximum Retry", reset=Some(0xf))),
|
|
||||||
)),
|
|
||||||
|
|
||||||
|
|
||||||
( 10 << 2 ) ->
|
|
||||||
RegFieldGroup("MIIMODER", Some("MII Mode Register"), Seq(
|
|
||||||
RegField(8, clkDiv, RegFieldDesc("clkDiv", "Clock Divider", reset=Some(0x64))),
|
|
||||||
RegField(1, miiNoPre, RegFieldDesc("MIINoPre", "NO Preamble", reset=Some(0x0))),
|
|
||||||
)),
|
|
||||||
|
|
||||||
( 11 << 2 ) ->
|
|
||||||
RegFieldGroup("MIICOMMAND", Some("MII Command Register"), Seq(
|
|
||||||
RegField(1, scanStat, RegFieldDesc("scanStat", "Scan Status", reset=Some(0x0))),
|
|
||||||
RegField(1, readStat, RegFieldDesc("readStat", "Read Status", reset=Some(0x0))),
|
|
||||||
RegField(1, wCtrlData, RegFieldDesc("wCtrlData", "Write Control Data", reset=Some(0x0))),
|
|
||||||
)),
|
|
||||||
|
|
||||||
( 12 << 2 ) ->
|
|
||||||
RegFieldGroup("MIIADDRESS", Some("MII Address Register"), Seq(
|
|
||||||
RegField(5, FIAD, RegFieldDesc("FIAD", "PHY Address", reset=Some(0x0))),
|
|
||||||
RegField.r(3 ,0.U),
|
|
||||||
RegField(5, RGAD, RegFieldDesc("RGAD", "Register Address", reset=Some(0x0))),
|
|
||||||
)),
|
|
||||||
|
|
||||||
( 13 << 2 ) ->
|
|
||||||
RegFieldGroup("MIITX_DATA", Some("MII Transmit Data"),
|
|
||||||
RegField.bytes(MIITX_DATA)
|
|
||||||
),
|
|
||||||
|
|
||||||
( 14 << 2 ) ->
|
|
||||||
RegFieldGroup("MIIRX_DATA", Some("MII Receive Data"), Seq(
|
|
||||||
RegField.r(16, MIIRX_DATA)
|
|
||||||
)),
|
|
||||||
|
|
||||||
( 15 << 2 ) ->
|
|
||||||
RegFieldGroup("MIISTATUS", Some("MII Status Register"), Seq(
|
|
||||||
RegField.r(1, io.LinkFail),
|
|
||||||
RegField.r(1, io.Busy_stat),
|
|
||||||
RegField.r(1, io.NValid_stat),
|
|
||||||
)),
|
|
||||||
|
|
||||||
( 16 << 2 ) ->
|
|
||||||
RegFieldGroup("MAC_ADDR0", Some("MAC Address Register 0"), Seq(
|
|
||||||
RegField(32)
|
|
||||||
)),
|
|
||||||
|
|
||||||
( 17 << 2 ) ->
|
|
||||||
RegFieldGroup("MAC_ADDR1", Some("MAC Address Register 1"), Seq(
|
|
||||||
RegField(32)
|
|
||||||
)),
|
|
||||||
|
|
||||||
( 18 << 2 ) ->
|
|
||||||
RegFieldGroup("HASH0", Some("HASH Register 0"),
|
|
||||||
RegField.bytes(HASH0)
|
|
||||||
),
|
|
||||||
|
|
||||||
( 19 << 2 ) ->
|
|
||||||
RegFieldGroup("HASH1", Some("HASH Register 1"),
|
|
||||||
RegField.bytes(HASH1)
|
|
||||||
),
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
io.r_FullD := FullD
|
|
||||||
io.r_ExDfrEn := ExDfrEn
|
|
||||||
io.r_LoopBck := LoopBck
|
|
||||||
io.r_IFG := IFG
|
|
||||||
io.r_NoPre := NoPre
|
|
||||||
io.r_TxEn := TxEn
|
|
||||||
io.r_RxEn := RxEn
|
|
||||||
|
|
||||||
io.r_IPGT := IPGT
|
|
||||||
io.r_IPGR1 := IPGR1
|
|
||||||
io.r_IPGR2 := IPGR2
|
|
||||||
io.r_CollValid := collValid
|
|
||||||
io.r_MiiNoPre := miiNoPre
|
|
||||||
io.r_ClkDiv := clkDiv
|
|
||||||
io.r_WCtrlData := wCtrlData
|
|
||||||
io.r_RStat := readStat
|
|
||||||
io.r_ScanStat := scanStat
|
|
||||||
io.r_RGAD := RGAD
|
|
||||||
io.r_FIAD := FIAD
|
|
||||||
io.r_CtrlData := MIITX_DATA
|
|
||||||
|
|
||||||
io.r_HASH1 := HASH1
|
|
||||||
io.r_HASH0 := HASH0
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
when(io.TxB_IRQ){ irq_txb := true.B }
|
|
||||||
when(io.TxE_IRQ){ irq_txe := true.B }
|
|
||||||
when(io.RxB_IRQ){ irq_rxb := true.B }
|
|
||||||
when(io.RxE_IRQ){ irq_rxe := true.B }
|
|
||||||
when(io.Busy_IRQ){ irq_busy := true.B }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Generating interrupt signal
|
|
||||||
// io.int_o :=
|
|
||||||
int(0) :=
|
|
||||||
(irq_txb & INT_MASK.extract(0) ) |
|
|
||||||
(irq_txe & INT_MASK.extract(1) ) |
|
|
||||||
(irq_rxb & INT_MASK.extract(2) ) |
|
|
||||||
(irq_rxe & INT_MASK.extract(3) ) |
|
|
||||||
(irq_busy & INT_MASK.extract(4) )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
package Switch
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.stage._
|
|
||||||
import freechips.rocketchip.diplomacy._
|
|
||||||
|
|
||||||
import org.chipsalliance.cde.config._
|
|
||||||
|
|
||||||
abstract class SwitchModule(implicit val p: Parameters) extends Module with HasSwitchParameters { def io: Record }
|
|
||||||
abstract class SwitchBundle(implicit val p: Parameters) extends Bundle with HasSwitchParameters
|
|
||||||
|
|
||||||
|
|
||||||
case object SwitchParamsKey extends Field[SwitchSetting]
|
|
||||||
|
|
||||||
|
|
||||||
case class SwitchSetting(
|
|
||||||
// isTileLink: Boolean = true
|
|
||||||
chn: Int = 3
|
|
||||||
){
|
|
||||||
require( chn > 0 , "Error, at least one mac chn!\n" )
|
|
||||||
require( chn <= 16, "Error, register address between only 0x000~0x1000, 0x100 for each!\n" )
|
|
||||||
}
|
|
||||||
|
|
||||||
trait HasSwitchParameters {
|
|
||||||
implicit val p: Parameters
|
|
||||||
|
|
||||||
val switchSetting = p(SwitchParamsKey)
|
|
||||||
|
|
||||||
def chn = switchSetting.chn
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class SwitchCfg extends Config((_, _, _) => {
|
|
||||||
case SwitchParamsKey => SwitchSetting()
|
|
||||||
})
|
|
||||||
|
|
||||||
class EfConfig extends Config((site, here, up) => {
|
|
||||||
case SwitchParamsKey => SwitchSetting(
|
|
||||||
chn = 2,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
@@ -1,175 +0,0 @@
|
|||||||
package Switch
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
|
|
||||||
import MAC._
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PiPoBuffBase[T<:Data]( dp: Int, val threshold: Int = 32) extends Module{
|
|
||||||
|
|
||||||
class PiPoBuffIO extends Bundle{
|
|
||||||
val enq = Flipped(Decoupled(new Mac_Stream_Bundle))
|
|
||||||
val deq = Decoupled(new Mac_Stream_Bundle)
|
|
||||||
}
|
|
||||||
|
|
||||||
val io: PiPoBuffIO = IO(new PiPoBuffIO)
|
|
||||||
|
|
||||||
val isEnqPi = RegInit(true.B)
|
|
||||||
val isEnqPo = ~isEnqPi
|
|
||||||
|
|
||||||
val isDeqPi = RegInit(true.B)
|
|
||||||
val isDeqPo = ~isDeqPi
|
|
||||||
|
|
||||||
|
|
||||||
val buff = for( i <- 0 until 2 ) yield { Module(new Queue( new Mac_Stream_Bundle, dp )) }
|
|
||||||
val isReach = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
|
||||||
val cnt = RegInit(0.U((log2Ceil(dp)).W))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
buff(0).io.enq.valid := isEnqPi & io.enq.valid
|
|
||||||
buff(0).io.enq.bits := io.enq.bits
|
|
||||||
|
|
||||||
buff(1).io.enq.valid := isEnqPo & io.enq.valid
|
|
||||||
buff(1).io.enq.bits := io.enq.bits
|
|
||||||
|
|
||||||
io.enq.ready :=
|
|
||||||
Mux1H(Seq(
|
|
||||||
isEnqPi -> buff(0).io.enq.ready,
|
|
||||||
isEnqPo -> buff(1).io.enq.ready
|
|
||||||
))
|
|
||||||
|
|
||||||
when( io.enq.fire & io.enq.bits.isLast ){
|
|
||||||
isEnqPi := ~isEnqPi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
when( io.enq.fire ){
|
|
||||||
when( io.enq.bits.isLast ){
|
|
||||||
cnt := 0.U
|
|
||||||
} .elsewhen( io.enq.bits.isStart ){
|
|
||||||
cnt := 1.U
|
|
||||||
} .otherwise{
|
|
||||||
cnt := cnt + 1.U
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
when( io.enq.fire ){
|
|
||||||
when( io.enq.bits.isStart ){
|
|
||||||
when( isEnqPi ){ isReach(0) := false.B }
|
|
||||||
when( isEnqPo ){ isReach(1) := false.B }
|
|
||||||
} .elsewhen(
|
|
||||||
io.enq.bits.isLast ||
|
|
||||||
(if( threshold != 0 ) { cnt === threshold.U } else {false.B})
|
|
||||||
){
|
|
||||||
when( isEnqPi ){ isReach(0) := true.B }
|
|
||||||
when( isEnqPo ){ isReach(1) := true.B }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
when( io.deq.fire & io.deq.bits.isLast ){
|
|
||||||
isDeqPi := ~isDeqPi
|
|
||||||
}
|
|
||||||
|
|
||||||
io.deq.valid :=
|
|
||||||
Mux1H(Seq(
|
|
||||||
isDeqPi -> ( buff(0).io.deq.valid & isReach(0) ),
|
|
||||||
isDeqPo -> ( buff(1).io.deq.valid & isReach(1) ),
|
|
||||||
))
|
|
||||||
|
|
||||||
io.deq.bits :=
|
|
||||||
Mux1H(Seq(
|
|
||||||
isDeqPi -> buff(0).io.deq.bits,
|
|
||||||
isDeqPo -> buff(1).io.deq.bits,
|
|
||||||
))
|
|
||||||
|
|
||||||
buff(0).io.deq.ready := io.deq.ready & isReach(0) & isDeqPi
|
|
||||||
buff(1).io.deq.ready := io.deq.ready & isReach(1) & isDeqPo
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TxBuff(threshold: Int = 8) extends PiPoBuffBase(2048, threshold)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Rx_MuxInfo_Bundle extends Bundle{
|
|
||||||
val dest = Valid(UInt((48+1).W))
|
|
||||||
val source = Valid(UInt((48+1).W))
|
|
||||||
|
|
||||||
def isBroadcast = dest.bits.extract(40)
|
|
||||||
}
|
|
||||||
|
|
||||||
class RxBuff(threshold: Int = 8) extends PiPoBuffBase(2048, threshold){
|
|
||||||
val mInfo = IO(new Rx_MuxInfo_Bundle)
|
|
||||||
|
|
||||||
val destReg = for( i <- 0 until 2 ) yield { Reg(Vec(6, UInt(8.W))) }
|
|
||||||
val destValid = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
|
||||||
|
|
||||||
val sourceReg = for( i <- 0 until 2 ) yield { Reg(Vec(6, UInt(8.W))) }
|
|
||||||
val sourceValid = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
|
||||||
|
|
||||||
when( io.enq.fire ){
|
|
||||||
when( cnt < 6.U ){
|
|
||||||
when( isEnqPi ){ destReg(0)(cnt) := io.enq.bits.data }
|
|
||||||
when( isEnqPo ){ destReg(1)(cnt) := io.enq.bits.data }
|
|
||||||
} .elsewhen( cnt < 12.U ){
|
|
||||||
when( isEnqPi ){ sourceReg(0)(cnt-6.U) := io.enq.bits.data }
|
|
||||||
when( isEnqPo ){ sourceReg(1)(cnt-6.U) := io.enq.bits.data }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
when( io.deq.fire & io.deq.bits.isLast ){
|
|
||||||
when( isDeqPi ) { destValid(0) := false.B; sourceValid(0) := false.B }
|
|
||||||
when( isDeqPo ) { destValid(1) := false.B; sourceValid(1) := false.B }
|
|
||||||
} .elsewhen( io.enq.fire & cnt === 5.U ){
|
|
||||||
when( isEnqPi ) { destValid(0) := true.B }
|
|
||||||
when( isEnqPo ) { destValid(1) := true.B }
|
|
||||||
} .elsewhen( io.enq.fire & cnt === 11.U ){
|
|
||||||
when( isEnqPi ) { sourceValid(0) := true.B }
|
|
||||||
when( isEnqPo ) { sourceValid(1) := true.B }
|
|
||||||
}
|
|
||||||
|
|
||||||
mInfo.dest.valid :=
|
|
||||||
Mux1H(Seq(
|
|
||||||
isDeqPi -> destValid(0),
|
|
||||||
isDeqPo -> destValid(1),
|
|
||||||
))
|
|
||||||
|
|
||||||
mInfo.dest.bits :=
|
|
||||||
Mux1H(Seq(
|
|
||||||
isDeqPi -> Cat(destReg(0)),
|
|
||||||
isDeqPo -> Cat(destReg(1)),
|
|
||||||
))
|
|
||||||
|
|
||||||
mInfo.source.valid :=
|
|
||||||
Mux1H(Seq(
|
|
||||||
isDeqPi -> sourceValid(0),
|
|
||||||
isDeqPo -> sourceValid(1),
|
|
||||||
))
|
|
||||||
|
|
||||||
mInfo.source.bits :=
|
|
||||||
Mux1H(Seq(
|
|
||||||
isDeqPi -> Cat(sourceReg(0)),
|
|
||||||
isDeqPo -> Cat(sourceReg(1)),
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
|
|
||||||
package Switch
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
import chisel3.util.random._
|
|
||||||
|
|
||||||
|
|
||||||
import org.chipsalliance.cde.config._
|
|
||||||
import freechips.rocketchip.diplomacy._
|
|
||||||
import freechips.rocketchip.tilelink._
|
|
||||||
|
|
||||||
import MAC._
|
|
||||||
|
|
||||||
class Robin_Bundle(implicit p: Parameters) extends SwitchBundle{
|
|
||||||
val rx = Decoupled(new Mac_Stream_Bundle)
|
|
||||||
val mInfo = new Rx_MuxInfo_Bundle
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class Robin(implicit p: Parameters) extends SwitchModule{
|
|
||||||
class RobinIO extends Bundle{
|
|
||||||
val enq = Vec( chn+1, Flipped(new Robin_Bundle) )
|
|
||||||
val deq = new Robin_Bundle
|
|
||||||
val sel = Output(UInt( (log2Ceil(chn+1)).W ))
|
|
||||||
}
|
|
||||||
|
|
||||||
val io: RobinIO = IO(new RobinIO)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val isLock = RegInit(false.B)
|
|
||||||
val lockChn = Reg(UInt((log2Ceil(chn+1)).W))
|
|
||||||
io.sel := lockChn
|
|
||||||
|
|
||||||
val lfsr = ~LFSR( (log2Ceil(chn+1)+1), ~isLock)
|
|
||||||
|
|
||||||
for( i <- 0 until chn+1 ) {
|
|
||||||
when( i.U === lfsr ){
|
|
||||||
when( io.enq(i).mInfo.dest.valid ){
|
|
||||||
assert( ~isLock )
|
|
||||||
isLock := true.B
|
|
||||||
lockChn := lfsr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
when( io.deq.rx.fire & io.deq.rx.bits.isLast ){
|
|
||||||
assert( isLock )
|
|
||||||
isLock := false.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for( i <- 0 until chn+1 ) {
|
|
||||||
io.enq(i).rx.ready := false.B
|
|
||||||
}
|
|
||||||
when( ~isLock ){
|
|
||||||
io.deq.rx.valid := false.B
|
|
||||||
io.deq.rx.bits := 0.U.asTypeOf(new Mac_Stream_Bundle)
|
|
||||||
io.deq.mInfo.dest.valid := false.B
|
|
||||||
io.deq.mInfo.dest.bits := 0.U
|
|
||||||
io.deq.mInfo.source.valid := false.B
|
|
||||||
io.deq.mInfo.source.bits := 0.U
|
|
||||||
} .otherwise{
|
|
||||||
io.deq <> io.enq(lockChn)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,174 +0,0 @@
|
|||||||
package Switch
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
|
|
||||||
import MAC._
|
|
||||||
|
|
||||||
import org.chipsalliance.cde.config._
|
|
||||||
import freechips.rocketchip.diplomacy._
|
|
||||||
import freechips.rocketchip.tilelink._
|
|
||||||
import freechips.rocketchip.interrupts._
|
|
||||||
|
|
||||||
import chisel3.experimental.dataview._
|
|
||||||
|
|
||||||
|
|
||||||
class SwitchIO(implicit p: Parameters) extends SwitchBundle{
|
|
||||||
val mii = Vec( chn, new MII )
|
|
||||||
|
|
||||||
val isLoopBack = Output(Vec( chn, Bool()))
|
|
||||||
val asyncReset = Input(AsyncReset())
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Switch(implicit p: Parameters) extends LazyModule with HasSwitchParameters{
|
|
||||||
|
|
||||||
val tlClientNode = TLClientNode(Seq(TLMasterPortParameters.v1(
|
|
||||||
Seq(TLMasterParameters.v1(
|
|
||||||
name = "DMA",
|
|
||||||
sourceId = IdRange(0, chn),
|
|
||||||
))
|
|
||||||
)))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val macReg = for( i <- 0 until chn ) yield { LazyModule(new MacReg(i)) }
|
|
||||||
val dmaReg = LazyModule(new DmaReg)
|
|
||||||
|
|
||||||
lazy val module = new SwitchImp(this)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class SwitchImp(outer: Switch)(implicit p: Parameters) extends LazyModuleImp(outer) with HasSwitchParameters{
|
|
||||||
val io = IO(new SwitchIO)
|
|
||||||
val ( dma_bus, dma_edge ) = outer.tlClientNode.out.head
|
|
||||||
|
|
||||||
val mac = ( 0 until chn ).map{ i =>
|
|
||||||
Module(new MacNode)
|
|
||||||
}
|
|
||||||
|
|
||||||
( 0 until chn ).map{ i =>
|
|
||||||
mac(i).io.mii <> io.mii(i)
|
|
||||||
mac(i).io.asyncReset := io.asyncReset
|
|
||||||
io.isLoopBack(i) := mac(i).io.isLoopBack
|
|
||||||
|
|
||||||
outer.macReg(i).module.io.asyncReset := io.asyncReset
|
|
||||||
outer.macReg(i).module.io.viewAsSupertype(new Mac_Config_Bundle) <> mac(i).io.cfg
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
val dmaMst = Module(new DmaNode(dma_edge))
|
|
||||||
|
|
||||||
dmaMst.io.cfg <> outer.dmaReg.module.io.cfg
|
|
||||||
|
|
||||||
|
|
||||||
dmaMst.io.dmaMst.D.bits := dma_bus.d.bits
|
|
||||||
dmaMst.io.dmaMst.D.valid := dma_bus.d.valid
|
|
||||||
dma_bus.d.ready := dmaMst.io.dmaMst.D.ready
|
|
||||||
dma_bus.a.valid := dmaMst.io.dmaMst.A.valid
|
|
||||||
dma_bus.a.bits := dmaMst.io.dmaMst.A.bits
|
|
||||||
dmaMst.io.dmaMst.A.ready := dma_bus.a.ready
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val robin = Module(new Robin)
|
|
||||||
|
|
||||||
// dmaMst.ex.tx <>
|
|
||||||
// <> mac(0).ex.tx
|
|
||||||
|
|
||||||
for( i <- 0 until chn ){
|
|
||||||
mac(i).ex.rx <> robin.io.enq(i).rx
|
|
||||||
mac(i).ex.mInfo <> robin.io.enq(i).mInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
dmaMst.ex.rx <> robin.io.enq(chn+1-1).rx
|
|
||||||
dmaMst.ex.mInfo <> robin.io.enq(chn+1-1).mInfo
|
|
||||||
|
|
||||||
|
|
||||||
val destTable = Wire( Vec( chn+1, Vec( 4, UInt(48.W) ) ) )
|
|
||||||
for( i <- 0 until chn+1 ){
|
|
||||||
destTable(i)(0) := "h102030405A00".U + i.U
|
|
||||||
destTable(i)(1) := "h102030405B00".U + i.U
|
|
||||||
destTable(i)(2) := "h102030405C00".U + i.U
|
|
||||||
destTable(i)(3) := "h102030405D00".U + i.U
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val isHit = Reg(Bool())
|
|
||||||
val destChn = Reg(UInt((log2Ceil(chn+1)).W))
|
|
||||||
val isMuxBusy = RegInit(false.B)
|
|
||||||
val dmaSelIn = Reg(UInt((log2Ceil(chn)).W)); dmaMst.io.selIn := dmaSelIn
|
|
||||||
|
|
||||||
|
|
||||||
when( robin.io.deq.rx.fire & robin.io.deq.rx.bits.isLast ){
|
|
||||||
assert( isMuxBusy )
|
|
||||||
isMuxBusy := false.B
|
|
||||||
} .elsewhen( robin.io.deq.mInfo.dest.valid & ~isMuxBusy ){
|
|
||||||
|
|
||||||
isMuxBusy := true.B
|
|
||||||
isHit := false.B
|
|
||||||
dmaSelIn := robin.io.sel
|
|
||||||
|
|
||||||
when( robin.io.sel === (chn+1-1).U ){ //DMA
|
|
||||||
isHit := true.B
|
|
||||||
destChn := dmaMst.io.selOut
|
|
||||||
} .otherwise{
|
|
||||||
for( i <- 0 until chn+1 ){
|
|
||||||
when(
|
|
||||||
robin.io.deq.mInfo.dest.bits === destTable(i)(0) ||
|
|
||||||
robin.io.deq.mInfo.dest.bits === destTable(i)(1) ||
|
|
||||||
robin.io.deq.mInfo.dest.bits === destTable(i)(2) ||
|
|
||||||
robin.io.deq.mInfo.dest.bits === destTable(i)(3)
|
|
||||||
){
|
|
||||||
isHit := true.B
|
|
||||||
destChn := i.U
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
val tempTxPort = Wire( Vec( chn+1, Decoupled(new Mac_Stream_Bundle) ) )
|
|
||||||
for( i <- 0 until chn ){
|
|
||||||
mac(i).ex.tx.valid := tempTxPort(i).valid
|
|
||||||
mac(i).ex.tx.bits := tempTxPort(i).bits
|
|
||||||
tempTxPort(i).ready := mac(i).ex.tx.ready
|
|
||||||
}
|
|
||||||
dmaMst.ex.tx.valid := tempTxPort(chn+1-1).valid
|
|
||||||
dmaMst.ex.tx.bits := tempTxPort(chn+1-1).bits
|
|
||||||
tempTxPort(chn+1-1).ready := dmaMst.ex.tx.ready
|
|
||||||
|
|
||||||
|
|
||||||
val allTxReady = tempTxPort.map{ x => x.ready }.foldLeft(true.B)(_&_)
|
|
||||||
|
|
||||||
|
|
||||||
for( i <- 0 until chn+1 ){
|
|
||||||
tempTxPort(i).valid := false.B
|
|
||||||
tempTxPort(i).bits := 0.U.asTypeOf(new Mac_Stream_Bundle)
|
|
||||||
}
|
|
||||||
robin.io.deq.rx.ready := false.B
|
|
||||||
|
|
||||||
when( isMuxBusy ){
|
|
||||||
when( isHit ){
|
|
||||||
tempTxPort(destChn).valid := robin.io.deq.rx.valid
|
|
||||||
tempTxPort(destChn).bits := robin.io.deq.rx.bits
|
|
||||||
robin.io.deq.rx.ready := tempTxPort(destChn).ready
|
|
||||||
} .otherwise{
|
|
||||||
for( i <- 0 until chn+1 ){
|
|
||||||
when( i.U =/= robin.io.sel ){
|
|
||||||
tempTxPort(i).valid := robin.io.deq.rx.valid & allTxReady
|
|
||||||
tempTxPort(i).bits := robin.io.deq.rx.bits
|
|
||||||
}
|
|
||||||
}
|
|
||||||
robin.io.deq.rx.ready := allTxReady
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,159 +0,0 @@
|
|||||||
package Switch
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
|
|
||||||
|
|
||||||
import org.chipsalliance.cde.config._
|
|
||||||
import freechips.rocketchip.diplomacy._
|
|
||||||
import freechips.rocketchip.tilelink._
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
abstract class SwitchMuxBase(edgeOut: TLEdgeOut)(implicit p: Parameters) extends SwitchModule{
|
|
||||||
|
|
||||||
class MacTileLinkMasterIO extends Bundle{
|
|
||||||
val A = Decoupled(new TLBundleA(edgeOut.bundle))
|
|
||||||
val D = Flipped(Decoupled(new TLBundleD(edgeOut.bundle)))
|
|
||||||
}
|
|
||||||
|
|
||||||
class SwitchMuxIO(implicit p: Parameters) extends SwitchBundle{
|
|
||||||
val dmaMst = new MacTileLinkMasterIO
|
|
||||||
|
|
||||||
val triTx = Input(Bool())
|
|
||||||
val triRx = Output(Bool())
|
|
||||||
val r_TxPtr = Input(UInt(32.W))
|
|
||||||
val r_RxPtr = Input(UInt(32.W))
|
|
||||||
val r_TxLen = Input(UInt(16.W))
|
|
||||||
val r_RxLen = Output(UInt(16.W))
|
|
||||||
|
|
||||||
val rxEnq = Vec(chn, Flipped(new Receive_Enq_Bundle))
|
|
||||||
val txDeq = Vec(chn, new Transmit_Bundle)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
val io: SwitchMuxIO = IO(new SwitchMuxIO)
|
|
||||||
val (_, _, isLastD, transDCnt) = edgeOut.count(io.dmaMst.D)
|
|
||||||
|
|
||||||
val rxBuff = Module(new RxBuff)
|
|
||||||
rxBuff.io.enq <> io.rxEnq(0)
|
|
||||||
|
|
||||||
|
|
||||||
val txBuff = Module(new TxBuff)
|
|
||||||
txBuff.io.deq <> io.txDeq(0)
|
|
||||||
|
|
||||||
def stateIdle = 0.U
|
|
||||||
def stateRx = 1.U
|
|
||||||
def stateTx = 2.U
|
|
||||||
|
|
||||||
val stateNxt = Wire(UInt(2.W))
|
|
||||||
val stateCur = RegNext(stateNxt, stateIdle)
|
|
||||||
val stateDMA = RegInit(0.U(2.W))
|
|
||||||
|
|
||||||
when( stateNxt =/= stateIdle && stateCur === stateIdle ){
|
|
||||||
stateDMA := 1.U
|
|
||||||
} .elsewhen( io.dmaMst.A.fire ){
|
|
||||||
stateDMA := 2.U
|
|
||||||
} .elsewhen( io.dmaMst.D.fire & isLastD ){
|
|
||||||
when( stateCur === stateTx & dmaAddress < (io.r_TxPtr + io.r_TxLen) ){
|
|
||||||
stateDMA := 0.U
|
|
||||||
} .elsewhen( stateCur === stateRx & rxBuff.io.deq.data.valid ){
|
|
||||||
stateDMA := 0.U
|
|
||||||
} .otherwise{
|
|
||||||
stateDMA := 1.U
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
stateNxt :=
|
|
||||||
Mux1H(Seq(
|
|
||||||
( stateCur === stateIdle ) -> Mux( (io.triTx & io.r_TxLen > 32.U), stateTx, Mux( rxBuff.io.deq.header.fire, stateRx, stateIdle ) ),
|
|
||||||
( stateCur === stateRx ) -> Mux( rxBuff.io.deq.ctrl.fire, stateIdle, stateRx ),
|
|
||||||
( stateCur === stateTx ) -> Mux( txBuff.io.enq.resp.fire, stateIdle, stateTx ),
|
|
||||||
))
|
|
||||||
|
|
||||||
io.triRx := rxBuff.io.deq.ctrl.fire
|
|
||||||
io.r_RxLen := RegEnable( rxBuff.io.deq.ctrl.bits.LatchedRxLength, rxBuff.io.deq.ctrl.fire )
|
|
||||||
rxBuff.io.deq.ctrl.ready := stateCur === stateRx & io.dmaMst.D.fire & isLastD
|
|
||||||
|
|
||||||
|
|
||||||
txBuff.io.enq.resp.ready := true.B
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val dmaAValid = RegInit(false.B)
|
|
||||||
val dmaABits = Reg(new TLBundleA(edgeOut.bundle))
|
|
||||||
|
|
||||||
|
|
||||||
val dmaAddress = Reg( UInt(32.W) )
|
|
||||||
|
|
||||||
when( stateCur === stateIdle & stateNxt === stateTx ){
|
|
||||||
dmaAddress := io.r_TxPtr
|
|
||||||
} .elsewhen( stateCur === stateIdle & stateNxt === stateRx ){
|
|
||||||
dmaAddress := io.r_RxPtr
|
|
||||||
} .elsewhen( io.dmaMst.A.fire ){
|
|
||||||
dmaAddress := dmaAddress + 1.U
|
|
||||||
}
|
|
||||||
|
|
||||||
rxBuff.io.deq.data.ready := io.dmaMst.A.fire & (stateCur === stateRx)
|
|
||||||
assert( ~(rxBuff.io.deq.data.ready & ~rxBuff.io.deq.data.valid) )
|
|
||||||
|
|
||||||
rxBuff.io.deq.header.ready := ~(io.triTx & io.r_TxLen > 32.U) & stateCur === stateIdle
|
|
||||||
|
|
||||||
when( io.dmaMst.A.fire ){
|
|
||||||
dmaAValid := false.B
|
|
||||||
}.elsewhen( stateDMA === 1.U & ~io.dmaMst.A.valid & stateCur === stateTx ){
|
|
||||||
dmaAValid := true.B
|
|
||||||
dmaABits :=
|
|
||||||
edgeOut.Get(
|
|
||||||
fromSource = 0.U,
|
|
||||||
toAddress = dmaAddress,
|
|
||||||
lgSize = log2Ceil(8/8).U,
|
|
||||||
)._2
|
|
||||||
} .elsewhen( stateDMA === 1.U & ~io.dmaMst.A.valid & stateCur === stateRx ) {
|
|
||||||
dmaAValid := true.B
|
|
||||||
dmaABits :=
|
|
||||||
edgeOut.Put(
|
|
||||||
fromSource = 0.U,
|
|
||||||
toAddress = dmaAddress,
|
|
||||||
lgSize = log2Ceil(8/8).U,
|
|
||||||
data = rxBuff.io.deq.data.bits,
|
|
||||||
mask = "b1".U,
|
|
||||||
)._2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
io.dmaMst.A.valid := dmaAValid
|
|
||||||
io.dmaMst.A.bits := dmaABits
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
txBuff.io.enq.req.valid := io.dmaMst.D.valid & stateCur === stateTx
|
|
||||||
txBuff.io.enq.req.bits.data := io.dmaMst.D.bits.data
|
|
||||||
txBuff.io.enq.req.bits.isStart := dmaAddress === io.r_TxPtr
|
|
||||||
txBuff.io.enq.req.bits.isLast := dmaAddress === (io.r_TxPtr + io.r_TxLen)
|
|
||||||
|
|
||||||
|
|
||||||
io.dmaMst.D.ready :=
|
|
||||||
Mux1H(Seq(
|
|
||||||
( stateCur === stateRx ) -> true.B,
|
|
||||||
( stateCur === stateTx ) -> txBuff.io.enq.req.ready,
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
trait SwitchMuxDMATx{ this: SwitchMuxBase =>
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class SwitchMux(edgeOut: TLEdgeOut)(implicit p: Parameters) extends SwitchMuxBase(TLEdgeOut)
|
|
||||||
with SwitchMuxDMATx
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
package Switch
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
|
|
||||||
|
|
||||||
import org.chipsalliance.cde.config._
|
|
||||||
import freechips.rocketchip.diplomacy._
|
|
||||||
import freechips.rocketchip.tilelink._
|
|
||||||
|
|
||||||
import MAC._
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SwitchNodeIO extends Bundle{
|
|
||||||
val rx = Decoupled(new Mac_Stream_Bundle)
|
|
||||||
val mInfo = new Rx_MuxInfo_Bundle
|
|
||||||
|
|
||||||
val tx = Flipped(Decoupled(new Mac_Stream_Bundle))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
abstract class SwitchNode(implicit p: Parameters) extends SwitchModule{
|
|
||||||
val ex: SwitchNodeIO = IO(new SwitchNodeIO)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MacNode(implicit p: Parameters) extends Mac{
|
|
||||||
val rxBuff = Module(new RxBuff)
|
|
||||||
val txBuff = Module(new TxBuff)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
macTileLinkRx.io.rxEnq <> rxBuff.io.enq
|
|
||||||
txBuff.io.deq <> macTileLinkTx.io.txDeq
|
|
||||||
|
|
||||||
rxBuff.io.deq <> ex.rx
|
|
||||||
ex.tx <> txBuff.io.enq
|
|
||||||
|
|
||||||
|
|
||||||
ex.mInfo <> rxBuff.mInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class DmaNode(edgeOut: TLEdgeOut)(implicit p: Parameters) extends DMAMst(edgeOut){
|
|
||||||
// def DmaMac = "habcdef".U(48.W)
|
|
||||||
|
|
||||||
ex.tx <> txBuff.io.enq
|
|
||||||
rxBuff.io.deq <> ex.rx
|
|
||||||
|
|
||||||
ex.mInfo.dest.valid := rxBuff.mInfo.dest.valid
|
|
||||||
ex.mInfo.dest.bits := 0.U
|
|
||||||
ex.mInfo.source.valid := rxBuff.mInfo.source.valid
|
|
||||||
ex.mInfo.source.bits := 0.U
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
package Switch
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
|
|
||||||
import freechips.rocketchip.subsystem.BaseSubsystem
|
|
||||||
import freechips.rocketchip.diplomacy._
|
|
||||||
import freechips.rocketchip.tilelink._
|
|
||||||
import org.chipsalliance.cde.config._
|
|
||||||
|
|
||||||
|
|
||||||
trait WithSwitchMix { this: BaseSubsystem =>
|
|
||||||
|
|
||||||
val switch = LazyModule(new Switch)
|
|
||||||
|
|
||||||
sbus.coupleFrom("switch_mst") { _ := TLBuffer() := TLWidthWidget(8 / 8) := switch.tlClientNode }
|
|
||||||
// pbus.coupleTo("switch_cfg") { switch0.tlMasterNode := TLFragmenter(pbus) := _ }
|
|
||||||
|
|
||||||
for( i <- 0 until 3 ){
|
|
||||||
pbus.coupleTo(s"mac_cfg$i") { switch.macReg(i).configNode := TLFragmenter(pbus) := _ }
|
|
||||||
ibus.fromSync := switch.macReg(i).int_node
|
|
||||||
}
|
|
||||||
|
|
||||||
pbus.coupleTo("dma_cfg") { switch.dmaReg.configNode := TLFragmenter(pbus) := _ }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
trait WithSwitchMixModuleImp extends LazyModuleImp {
|
|
||||||
val outer: WithSwitchMix
|
|
||||||
|
|
||||||
val switchIO = IO(new SwitchIO)
|
|
||||||
|
|
||||||
switchIO <> outer.switch.module.io
|
|
||||||
|
|
||||||
// println("Warning, did you delete the rocket-chip.jar on top to reflash?")
|
|
||||||
// println("Warning, did you delete the rocket-chip.jar on top to reflash?")
|
|
||||||
// println("Warning, did you delete the rocket-chip.jar on top to reflash?")
|
|
||||||
// println("Warning, did you delete the rocket-chip.jar on top to reflash?")
|
|
||||||
// println("Warning, did you delete the rocket-chip.jar on top to reflash?")
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class SwitchConfig() extends Config((site, here, up) => {
|
|
||||||
case SwitchParamsKey => SwitchSetting()
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,239 +0,0 @@
|
|||||||
package MAC
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MIIMIO extends Bundle with MDIO{
|
|
||||||
val Divider = Input( UInt(8.W) ) // Divider for the host clock // Divider (input clock will be divided by the Divider[7:0])
|
|
||||||
val NoPre = Input(Bool()) // No Preamble (no 32-bit preamble)
|
|
||||||
|
|
||||||
val WCtrlData = Input(Bool()) // Write Control Data operation
|
|
||||||
val CtrlData = Input( UInt(16.W) ) // Control Data (to be written to the PHY reg.)
|
|
||||||
|
|
||||||
val Fiad = Input( UInt(5.W) ) // PHY Address
|
|
||||||
val Rgad = Input(UInt(5.W)) // Register Address (within the PHY)
|
|
||||||
|
|
||||||
val RStat = Input( Bool() ) // Read Status operation
|
|
||||||
|
|
||||||
val ScanStat = Input( Bool() ) // Scan Status operation
|
|
||||||
|
|
||||||
val Busy = Output(Bool()) // Busy Signal
|
|
||||||
val LinkFail = Output(Bool()) // Link Integrity Signal
|
|
||||||
val Nvalid = Output(Bool()) // Invalid Status (qualifier for the valid scan result)
|
|
||||||
val Prsd = Output(UInt(16.W)) // Read Status Data (data read from the PHY)
|
|
||||||
|
|
||||||
val WCtrlDataStart = Output(Bool()) // This signals resets the WCTRLDATA bit in the MIIM Command register
|
|
||||||
val RStatStart = Output(Bool()) // This signal resets the RSTAT BIT in the MIIM Command register
|
|
||||||
val UpdateMIIRX_DATAReg = Output(Bool()) // Updates MII RX_DATA register with read data
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class MIIMBase extends Module{
|
|
||||||
val io: MIIMIO = IO(new MIIMIO)
|
|
||||||
|
|
||||||
|
|
||||||
val ByteSelect = Wire( Vec( 4, Bool() ) ) // Byte Select defines which byte (preamble, data, operation, etc.) is loaded and shifted through the shift register.
|
|
||||||
|
|
||||||
|
|
||||||
// Counter counts half period
|
|
||||||
val Counter = RegInit( 1.U(8.W) )
|
|
||||||
val mdc = RegInit(false.B) // Output clock
|
|
||||||
val mdcEn = (Counter === 0.U) & ~mdc // Enable signal is asserted for one Clk period before mdc rises.
|
|
||||||
val mdcEn_n = (Counter === 0.U) & mdc // Enable signal is asserted for one Clk period before mdc falls.
|
|
||||||
|
|
||||||
val ShiftReg = RegInit(0.U(8.W)) // Shift register for shifting the data in and out
|
|
||||||
val Prsd = RegInit(0.U(16.W))
|
|
||||||
val LinkFail = RegInit(false.B)
|
|
||||||
|
|
||||||
|
|
||||||
val BitCounter = RegInit( 0.U(7.W) ) // Bit Counter counts from 0 to 63 (from 32 to 63 when NoPre is asserted)
|
|
||||||
val EndOp = BitCounter === 63.U // Operation ends when the Bit Counter reaches 63
|
|
||||||
|
|
||||||
|
|
||||||
val InProgress = RegInit(false.B) // Operation in progress
|
|
||||||
val InProgress_q = ShiftRegisters(InProgress, 3, false.B, mdcEn) // Operation in progress delayed 3 mdc cycles
|
|
||||||
val EndBusy = ShiftRegister(~InProgress_q(1) & InProgress_q(2), 2, false.B, true.B) // Generation of the EndBusy signal. It is used for ending the MII Management operation.
|
|
||||||
|
|
||||||
val WriteOp = RegInit(false.B) // Write Operation Latch (When asserted, write operation is in progress)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
io.mdc := mdc
|
|
||||||
io.LinkFail := LinkFail
|
|
||||||
io.Prsd := Prsd
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Connecting the Clock Generator Module */
|
|
||||||
trait MIIMClockGen{ this: MIIMBase =>
|
|
||||||
|
|
||||||
val TempDivider = Mux( io.Divider < 2.U, 2.U, io.Divider ) // If smaller than 2
|
|
||||||
val CounterPreset = ( TempDivider >> 1 ) - 1.U // We are counting half of period
|
|
||||||
|
|
||||||
when( Counter === 0.U ) {
|
|
||||||
mdc := ~mdc // mdc is asserted every other half period
|
|
||||||
Counter := CounterPreset
|
|
||||||
} .otherwise{
|
|
||||||
Counter := Counter - 1.U
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
trait MIIMShiftReg{ this: MIIMBase =>
|
|
||||||
|
|
||||||
val LatchByte0 = ShiftRegister(InProgress & ~WriteOp & BitCounter === "h3F".U, 2, false.B, mdcEn) // Latch Byte selects which part of Read Status Data is updated from the shift register
|
|
||||||
val LatchByte1 = ShiftRegister(InProgress & ~WriteOp & BitCounter === "h37".U, 2, false.B, mdcEn) // Latch Byte selects which part of Read Status Data is updated from the shift register
|
|
||||||
|
|
||||||
ByteSelect(0) := InProgress & ((io.NoPre & (BitCounter === 0.U)) | (~io.NoPre & (BitCounter === "h20".U)));
|
|
||||||
ByteSelect(1) := InProgress & (BitCounter === "h28".U);
|
|
||||||
ByteSelect(2) := InProgress & WriteOp & (BitCounter === "h30".U);
|
|
||||||
ByteSelect(3) := InProgress & WriteOp & (BitCounter === "h38".U);
|
|
||||||
|
|
||||||
when(mdcEn_n){
|
|
||||||
when(ByteSelect.reduce(_|_)) {
|
|
||||||
ShiftReg := Mux1H(Seq(
|
|
||||||
ByteSelect(0) -> Cat("b01".U(2.W), ~WriteOp, WriteOp, io.Fiad(4,1)),
|
|
||||||
ByteSelect(1) -> Cat(io.Fiad.extract(0), io.Rgad(4,0), "b10".U(2.W)),
|
|
||||||
ByteSelect(2) -> io.CtrlData(15,8),
|
|
||||||
ByteSelect(3) -> io.CtrlData( 7,0),
|
|
||||||
))
|
|
||||||
} .otherwise{
|
|
||||||
ShiftReg := Cat(ShiftReg(6,0), io.mdi)
|
|
||||||
when(LatchByte0){
|
|
||||||
Prsd := Cat(Prsd(15,8), ShiftReg(6,0), io.mdi)
|
|
||||||
when(io.Rgad === 1.U){
|
|
||||||
LinkFail := ~ShiftReg.extract(1) // this is bit [2], because it is not shifted yet
|
|
||||||
}
|
|
||||||
} .elsewhen(LatchByte1){
|
|
||||||
Prsd := Cat(ShiftReg(6,0), io.mdi, Prsd(7,0))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
trait MIIMOutputCtl{ this: MIIMBase =>
|
|
||||||
|
|
||||||
// Generation of the Serial Enable signal (enables the serialization of the data)
|
|
||||||
val SerialEn = ( WriteOp & InProgress & ( BitCounter > 31.U | ( ( BitCounter === 0.U ) & io.NoPre ) )) |
|
|
||||||
(~WriteOp & InProgress & (( BitCounter > 31.U & BitCounter < 46.U ) | ( ( BitCounter === 0.U ) & io.NoPre )))
|
|
||||||
|
|
||||||
val mdoEn = ShiftRegister( SerialEn | (InProgress & BitCounter<32.U), 3, false.B, mdcEn_n)
|
|
||||||
val mdo_2d = RegEnable( ~SerialEn & BitCounter<32.U, false.B, mdcEn_n)
|
|
||||||
val mdo_d = RegEnable( ShiftReg.extract(7) | mdo_2d, false.B, mdcEn_n)
|
|
||||||
val mdo = RegEnable( mdo_d, false.B, mdcEn_n)
|
|
||||||
io.mdo := mdo
|
|
||||||
io.mdoEn := mdoEn
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class MIIM extends MIIMBase with MIIMClockGen with MIIMShiftReg with MIIMOutputCtl{
|
|
||||||
|
|
||||||
val WCtrlData_q = ShiftRegisters(io.WCtrlData, 3, false.B, true.B)
|
|
||||||
val WCtrlDataStart = RegInit(false.B) // Start Write Control Data Command (positive edge detected)
|
|
||||||
val WCtrlDataStart_q = ShiftRegisters(WCtrlDataStart, 2, false.B, mdcEn) // Start Write Control Data Command delayed 2 mdc cycle
|
|
||||||
val WriteDataOp = WCtrlDataStart_q(0) & ~WCtrlDataStart_q(1) // Write Data Operation (positive edge detected)
|
|
||||||
io.WCtrlDataStart := WCtrlDataStart
|
|
||||||
|
|
||||||
// Generation of the Operation signals
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val StartOp = Wire(Bool()) // Start Operation (start of any of the preceding operations)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
when( EndBusy ){
|
|
||||||
WCtrlDataStart := false.B
|
|
||||||
} .elsewhen( WCtrlData_q(1) & ~WCtrlData_q(2) ){
|
|
||||||
WCtrlDataStart := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update MII RX_DATA register
|
|
||||||
val WCtrlDataStart_q0 = RegEnable(WCtrlDataStart, false.B, ~EndBusy)
|
|
||||||
val UpdateMIIRX_DATAReg = RegNext(EndBusy & ~WCtrlDataStart_q0, false.B) // Updates MII RX_DATA register with read data
|
|
||||||
io.UpdateMIIRX_DATAReg := UpdateMIIRX_DATAReg
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val RStat_q = ShiftRegisters(io.RStat, 3, false.B, true.B)
|
|
||||||
val RStatStart = RegInit(false.B) // Start Read Status Command (positive edge detected)
|
|
||||||
val RStatStart_q = ShiftRegisters(RStatStart, 2, false.B, mdcEn) // Start Read Status Command delayed 2 mdc cycles
|
|
||||||
val ReadStatusOp = RStatStart_q(0) & ~RStatStart_q(1) // Read Status Operation (positive edge detected)
|
|
||||||
io.RStatStart := RStatStart
|
|
||||||
|
|
||||||
when( EndBusy ){
|
|
||||||
RStatStart := false.B
|
|
||||||
} .elsewhen(RStat_q(1) & ~RStat_q(2)){
|
|
||||||
RStatStart := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
when(mdcEn){
|
|
||||||
when(StartOp) {
|
|
||||||
InProgress := true.B
|
|
||||||
} .elsewhen(EndOp) {
|
|
||||||
InProgress := false.B
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val ScanStat_q = ShiftRegisters(io.ScanStat, 2, false.B, true.B)
|
|
||||||
val SyncStatmdcEn = RegEnable(ScanStat_q(1), false.B, mdcEn) // Scan Status operation delayed at least cycles and synchronized to mdcEn
|
|
||||||
val ScanStatusOp = SyncStatmdcEn & ~InProgress & ~InProgress_q(0) & ~InProgress_q(1) // Scan Status Operation (positive edge detected)
|
|
||||||
|
|
||||||
|
|
||||||
val Nvalid = RegInit(false.B) // Generation of the Nvalid signal (indicates when the status is invalid)
|
|
||||||
io.Nvalid := Nvalid
|
|
||||||
|
|
||||||
when( ~InProgress_q(1) & InProgress_q(2) ) {
|
|
||||||
Nvalid := false.B
|
|
||||||
} .elsewhen(ScanStat_q(1) & ~SyncStatmdcEn) {
|
|
||||||
Nvalid := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
when(mdcEn){
|
|
||||||
when(StartOp) {
|
|
||||||
when( ~InProgress ){
|
|
||||||
WriteOp := Mux( WriteDataOp, true.B, false.B )
|
|
||||||
}
|
|
||||||
} .elsewhen(EndOp) {
|
|
||||||
WriteOp := false.B
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
when( mdcEn ){
|
|
||||||
when( InProgress ) {
|
|
||||||
when( io.NoPre & BitCounter === 0.U ) {
|
|
||||||
BitCounter := "h21".U
|
|
||||||
} .otherwise {
|
|
||||||
BitCounter := BitCounter + 1.U
|
|
||||||
}
|
|
||||||
} .otherwise {
|
|
||||||
BitCounter := 0.U
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
StartOp := WriteDataOp | ReadStatusOp | ScanStatusOp
|
|
||||||
io.Busy := io.WCtrlData | WCtrlDataStart | io.RStat | RStatStart | SyncStatmdcEn | EndBusy | InProgress | InProgress_q(2) | Nvalid
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
package MAC
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TxBuffDesc extends Bundle{
|
|
||||||
val len = UInt(16.W) //[31.16]
|
|
||||||
val rd = Bool() //[15]
|
|
||||||
val irq = Bool() //14
|
|
||||||
val wr = Bool() //13
|
|
||||||
val pad = Bool() //12
|
|
||||||
val crc = Bool() //11
|
|
||||||
val reserved1 = UInt(2.W) //10,9
|
|
||||||
val ur = Bool() //8
|
|
||||||
val rtry = UInt(4.W) //7 6 5 4
|
|
||||||
val rl = Bool() //3
|
|
||||||
val lc = Bool() //2
|
|
||||||
val df = Bool() //1
|
|
||||||
val cs = Bool() //0
|
|
||||||
}
|
|
||||||
|
|
||||||
class RxBuffDesc extends Bundle{
|
|
||||||
val len = UInt(16.W) //[31.16]
|
|
||||||
val e = Bool() //15
|
|
||||||
val irq = Bool() //14
|
|
||||||
val wrap = Bool() //13
|
|
||||||
val reserved1 = UInt(4.W) //12 11 10 9
|
|
||||||
val cf = Bool() //8
|
|
||||||
val m = Bool() //7
|
|
||||||
val or = Bool() //6
|
|
||||||
val is = Bool() //5
|
|
||||||
val dn = Bool() //4
|
|
||||||
val tl = Bool() //3
|
|
||||||
val sf = Bool() //2
|
|
||||||
val crc = Bool() //1
|
|
||||||
val lc = Bool() //0
|
|
||||||
}
|
|
||||||
|
|
||||||
class MacWishboneMasterIO extends Bundle{
|
|
||||||
val m_wb_adr_o = Output(UInt(32.W))
|
|
||||||
val m_wb_sel_o = Output(UInt(4.W))
|
|
||||||
val m_wb_we_o = Output(Bool())
|
|
||||||
val m_wb_dat_i = Input(UInt(32.W))
|
|
||||||
val m_wb_dat_o = Output(UInt(32.W))
|
|
||||||
val m_wb_cyc_o = Output(Bool())
|
|
||||||
val m_wb_stb_o = Output(Bool())
|
|
||||||
val m_wb_ack_i = Input(Bool())
|
|
||||||
val m_wb_err_i = Input(Bool())
|
|
||||||
val m_wb_cti_o = Output(UInt(3.W))
|
|
||||||
val m_wb_bte_o = Output(UInt(2.W))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class MacWishboneSlaveIO extends Bundle{
|
|
||||||
val WB_DAT_I = Input(UInt(32.W)) // WISHBONE data input
|
|
||||||
val WB_DAT_O = Output(UInt(32.W)) // WISHBONE data output
|
|
||||||
|
|
||||||
val WB_ADR_I = Input(UInt(12.W)) // WISHBONE address input
|
|
||||||
val WB_WE_I = Input(Bool()) // WISHBONE write enable input
|
|
||||||
|
|
||||||
val WB_SEL_I = Input(UInt(4.W)) // WISHBONE byte select input
|
|
||||||
val WB_CYC_I = Input(Bool()) // WISHBONE cycle input
|
|
||||||
val WB_STB_I = Input(Bool()) // WISHBONE strobe input
|
|
||||||
|
|
||||||
val WB_ACK_O = Output(Bool()) // WISHBONE acknowledge output
|
|
||||||
val WB_ERR_O = Output(Bool()) // WISHBONE error output
|
|
||||||
}
|
|
||||||
|
|
||||||
trait MDIO { this: Bundle =>
|
|
||||||
val mdi = Input( Bool()) // MII Management Data In
|
|
||||||
val mdc = Output(Bool()) // MII Management Data Clock
|
|
||||||
val mdo = Output(Bool()) // MII Management Data Output
|
|
||||||
val mdoEn = Output(Bool()) // MII Management Data Output Enable
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
package MAC
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
|
|
||||||
class MacFifoIO(dw: Int, cntw: Int) extends Bundle{
|
|
||||||
val write = Input(Bool())
|
|
||||||
val read = Input(Bool())
|
|
||||||
val clear = Input(Bool())
|
|
||||||
val data_in = Input(UInt(dw.W))
|
|
||||||
|
|
||||||
val data_out = Output(UInt(dw.W))
|
|
||||||
val almost_full = Output(Bool())
|
|
||||||
val full = Output(Bool())
|
|
||||||
val almost_empty = Output(Bool())
|
|
||||||
val empty = Output(Bool())
|
|
||||||
val cnt = Output(UInt(cntw.W))
|
|
||||||
}
|
|
||||||
|
|
||||||
class MacFifo(dw: Int, dp: Int) extends Module{
|
|
||||||
def cntw = log2Ceil(dp)+1
|
|
||||||
val io: MacFifoIO = IO(new MacFifoIO(dw, cntw ))
|
|
||||||
|
|
||||||
val fifo = Mem( dp, UInt(dw.W) )
|
|
||||||
val data_out = Reg(UInt(dw.W)); io.data_out := data_out
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val cnt = RegInit( 0.U(cntw.W)); io.cnt := cnt
|
|
||||||
val read_pointer = RegInit(0.U(log2Ceil(dp).W))
|
|
||||||
val write_pointer = RegInit(0.U(log2Ceil(dp).W))
|
|
||||||
|
|
||||||
when(io.clear){
|
|
||||||
cnt := io.read ^ io.write
|
|
||||||
} .elsewhen(io.read ^ io.write){
|
|
||||||
when(io.read){
|
|
||||||
cnt := cnt - 1.U
|
|
||||||
} .otherwise{
|
|
||||||
cnt := cnt + 1.U
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
when(io.clear){
|
|
||||||
read_pointer := io.read
|
|
||||||
} .elsewhen(io.read & ~io.empty){
|
|
||||||
read_pointer := read_pointer + 1.U
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
when(io.clear){
|
|
||||||
write_pointer := io.write
|
|
||||||
} .elsewhen(io.write & ~io.full){
|
|
||||||
write_pointer := write_pointer + 1.U
|
|
||||||
}
|
|
||||||
|
|
||||||
io.empty := ~(cnt.orR)
|
|
||||||
io.almost_empty := cnt === 1.U
|
|
||||||
io.full := cnt === dp.U;
|
|
||||||
io.almost_full := cnt(cntw-2,0).andR
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
when(io.write & io.clear){
|
|
||||||
fifo.write(0.U, io.data_in)
|
|
||||||
} .elsewhen(io.write & ~io.full){
|
|
||||||
fifo.write(write_pointer, io.data_in)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
when(io.clear){
|
|
||||||
data_out := fifo.read(0.U)
|
|
||||||
} .otherwise{
|
|
||||||
data_out := fifo.read(read_pointer)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,298 +0,0 @@
|
|||||||
package MAC
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MacRxIO extends Bundle{
|
|
||||||
|
|
||||||
val MRxDV = Input(Bool())
|
|
||||||
val MRxD = Input(UInt(4.W))
|
|
||||||
val Transmitting = Input(Bool())
|
|
||||||
val r_IFG = Input(Bool())
|
|
||||||
val r_HASH0 = Input(UInt(32.W)) // lower 4 bytes Hash Table
|
|
||||||
val r_HASH1 = Input(UInt(32.W)) // upper 4 bytes Hash Table
|
|
||||||
|
|
||||||
val RxData = Output(UInt(8.W))
|
|
||||||
val RxValid = Output(Bool())
|
|
||||||
val RxStartFrm = Output(Bool())
|
|
||||||
val RxEndFrm = Output(Bool())
|
|
||||||
val ByteCnt = Output(UInt(16.W))
|
|
||||||
val ByteCntEq0 = Output(Bool())
|
|
||||||
val ByteCntGreat2 = Output(Bool())
|
|
||||||
val CrcError = Output(Bool())
|
|
||||||
val StateIdle = Output(Bool())
|
|
||||||
val StatePreamble = Output(Bool())
|
|
||||||
val StateSFD = Output(Bool())
|
|
||||||
val StateData = Output(UInt(2.W))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
abstract class MacRxBase extends Module with RequireAsyncReset{
|
|
||||||
val io: MacRxIO = IO(new MacRxIO)
|
|
||||||
|
|
||||||
val MRxDEqD = io.MRxD === "hd".U
|
|
||||||
val MRxDEq5 = io.MRxD === "h5".U
|
|
||||||
|
|
||||||
val IFGCounterEq24 = Wire(Bool())
|
|
||||||
|
|
||||||
val ByteCntEq0 = Wire(Bool())
|
|
||||||
io.ByteCntEq0 := ByteCntEq0
|
|
||||||
|
|
||||||
val ByteCntEq1 = Wire(Bool())
|
|
||||||
val ByteCntEq2 = Wire(Bool())
|
|
||||||
val ByteCntEq3 = Wire(Bool())
|
|
||||||
val ByteCntEq4 = Wire(Bool())
|
|
||||||
val ByteCntEq5 = Wire(Bool())
|
|
||||||
val ByteCntEq6 = Wire(Bool())
|
|
||||||
val ByteCntEq7 = Wire(Bool())
|
|
||||||
|
|
||||||
val ByteCntSmall7 = Wire(Bool())
|
|
||||||
|
|
||||||
|
|
||||||
val StateData0 = RegInit(false.B)
|
|
||||||
val StateData1 = RegInit(false.B)
|
|
||||||
val StateIdle = RegInit(false.B); io.StateIdle := StateIdle
|
|
||||||
val StateDrop = RegInit(true.B)
|
|
||||||
val StatePreamble = RegInit(false.B); io.StatePreamble := StatePreamble
|
|
||||||
val StateSFD = RegInit(false.B); io.StateSFD := StateSFD
|
|
||||||
|
|
||||||
val RxData_d = RegInit(0.U(8.W))
|
|
||||||
val RxData = RegNext(RxData_d, 0.U); io.RxData := RxData
|
|
||||||
|
|
||||||
val Crc = RegInit("hFFFFFFFF".U(32.W))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
trait MacRxFSM { this: MacRxBase =>
|
|
||||||
|
|
||||||
val StateData = Cat( StateData1, StateData0 )
|
|
||||||
io.StateData := StateData
|
|
||||||
|
|
||||||
// Defining the next state
|
|
||||||
val StartIdle = ~io.MRxDV & (StateDrop | StatePreamble | StateSFD | StateData0 | StateData1 )
|
|
||||||
val StartPreamble = io.MRxDV & ~MRxDEq5 & (StateIdle & ~io.Transmitting)
|
|
||||||
val StartSFD = io.MRxDV & MRxDEq5 & (StateIdle & ~io.Transmitting | StatePreamble)
|
|
||||||
val StartData0 = io.MRxDV & (StateSFD & MRxDEqD & IFGCounterEq24 | StateData1)
|
|
||||||
val StartData1 = io.MRxDV & StateData0
|
|
||||||
val StartDrop = io.MRxDV & (
|
|
||||||
(StateIdle & io.Transmitting) | (StateSFD & ~IFGCounterEq24 & MRxDEqD )
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
when(StartPreamble | StartSFD | StartDrop){
|
|
||||||
StateIdle := false.B
|
|
||||||
} .elsewhen( StartIdle ){
|
|
||||||
StateIdle := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
when( StartIdle ){
|
|
||||||
StateDrop := false.B
|
|
||||||
} .elsewhen(StartDrop){
|
|
||||||
StateDrop := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
when(StartSFD | StartIdle | StartDrop ){
|
|
||||||
StatePreamble := false.B
|
|
||||||
} .elsewhen(StartPreamble){
|
|
||||||
StatePreamble := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
when(StartPreamble | StartIdle | StartData0 | StartDrop){
|
|
||||||
StateSFD := false.B
|
|
||||||
} .elsewhen (StartSFD){
|
|
||||||
StateSFD := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
when(StartIdle | StartData1 | StartDrop){
|
|
||||||
StateData0 := false.B
|
|
||||||
} .elsewhen(StartData0){
|
|
||||||
StateData0 := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
when(StartIdle | StartData0 | StartDrop){
|
|
||||||
StateData1 := false.B
|
|
||||||
} .elsewhen(StartData1){
|
|
||||||
StateData1 := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
trait MacRxCounter { this: MacRxBase =>
|
|
||||||
|
|
||||||
val ByteCnt = RegInit(0.U(16.W))
|
|
||||||
val IFGCounter = RegInit(0.U(5.W))
|
|
||||||
|
|
||||||
val ByteCntMax = ByteCnt === "hffff".U
|
|
||||||
|
|
||||||
val ResetByteCounter = io.MRxDV & (io.StateSFD & MRxDEqD)
|
|
||||||
|
|
||||||
val IncrementByteCounter =
|
|
||||||
~ResetByteCounter & io.MRxDV & (
|
|
||||||
io.StatePreamble | io.StateSFD | io.StateIdle & ~io.Transmitting |
|
|
||||||
(io.StateData.extract(1) & ~ByteCntMax)
|
|
||||||
)
|
|
||||||
|
|
||||||
val ByteCntDelayed = ByteCnt + 4.U
|
|
||||||
io.ByteCnt := ByteCnt
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
when( ResetByteCounter ){
|
|
||||||
ByteCnt := 0.U
|
|
||||||
} .elsewhen(IncrementByteCounter){
|
|
||||||
ByteCnt := ByteCnt + 1.U
|
|
||||||
}
|
|
||||||
|
|
||||||
ByteCntEq0 := ByteCnt === 0.U
|
|
||||||
ByteCntEq1 := ByteCnt === 1.U
|
|
||||||
ByteCntEq2 := ByteCnt === 2.U
|
|
||||||
ByteCntEq3 := ByteCnt === 3.U
|
|
||||||
ByteCntEq4 := ByteCnt === 4.U
|
|
||||||
ByteCntEq5 := ByteCnt === 5.U
|
|
||||||
ByteCntEq6 := ByteCnt === 6.U
|
|
||||||
ByteCntEq7 := ByteCnt === 7.U
|
|
||||||
|
|
||||||
io.ByteCntGreat2 := ByteCnt > 2.U
|
|
||||||
ByteCntSmall7 := ByteCnt < 7.U
|
|
||||||
|
|
||||||
val ResetIFGCounter = io.StateSFD & io.MRxDV & MRxDEqD | StateDrop;
|
|
||||||
val IncrementIFGCounter = ~ResetIFGCounter & (StateDrop | io.StateIdle | io.StatePreamble | io.StateSFD) & ~IFGCounterEq24;
|
|
||||||
|
|
||||||
when( ResetIFGCounter ){
|
|
||||||
IFGCounter := 0.U
|
|
||||||
} .elsewhen(IncrementIFGCounter){
|
|
||||||
IFGCounter := IFGCounter + 1.U
|
|
||||||
}
|
|
||||||
|
|
||||||
IFGCounterEq24 := (IFGCounter === "h18".U) | io.r_IFG; // 24*400 = 9600 ns or r_IFG is set to 1
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
trait MacRxFAddrCheck { this: MacRxBase =>
|
|
||||||
|
|
||||||
val HashBit = Wire(UInt(1.W))
|
|
||||||
|
|
||||||
val RxCheckEn = io.StateData.orR
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val CrcHash = RegInit(0.U(6.W))
|
|
||||||
val CrcHashGood = RegNext(StateData0 & ByteCntEq6) // Latching CRC for use in the hash table
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val IntHash = Mux(CrcHash.extract(5), io.r_HASH1, io.r_HASH0)
|
|
||||||
val ByteHash =
|
|
||||||
Mux1H(Seq(
|
|
||||||
(CrcHash(4,3) === "b00".U) -> IntHash(7 ,0),
|
|
||||||
(CrcHash(4,3) === "b01".U) -> IntHash(15,8),
|
|
||||||
(CrcHash(4,3) === "b10".U) -> IntHash(23,16),
|
|
||||||
(CrcHash(4,3) === "b11".U) -> IntHash(31,24),
|
|
||||||
))
|
|
||||||
|
|
||||||
HashBit := ByteHash >> CrcHash(2,0)
|
|
||||||
|
|
||||||
when(StateIdle){
|
|
||||||
CrcHash := 0.U
|
|
||||||
} .elsewhen(StateData0 & ByteCntEq6){
|
|
||||||
CrcHash := Crc(31,26)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
trait MacRxCRC { this: MacRxBase =>
|
|
||||||
|
|
||||||
val Data_Crc = Cat(io.MRxD.extract(0),io.MRxD.extract(1),io.MRxD.extract(2),io.MRxD.extract(3))
|
|
||||||
val Enable_Crc = io.MRxDV & (io.StateData.orR)
|
|
||||||
val Initialize_Crc = io.StateSFD
|
|
||||||
|
|
||||||
when( Initialize_Crc ){
|
|
||||||
Crc := "hFFFFFFFF".U
|
|
||||||
} .otherwise{
|
|
||||||
Crc := Cat(
|
|
||||||
Crc.extract(27),
|
|
||||||
Crc.extract(26),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Crc.extract(31))) ^ Crc.extract(25),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(2) ^ Crc.extract(30))) ^ Crc.extract(24),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(1) ^ Crc.extract(29))) ^ Crc.extract(23),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(0) ^ Crc.extract(31) ^ Crc.extract(28))) ^ Crc.extract(22),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(2) ^ Crc.extract(31) ^ Crc.extract(30))) ^ Crc.extract(21),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(2) ^ Data_Crc.extract(1) ^ Crc.extract(30) ^ Crc.extract(29))) ^ Crc.extract(20),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(1) ^ Data_Crc.extract(0) ^ Crc.extract(29) ^ Crc.extract(28))) ^ Crc.extract(19),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(0) ^ Crc.extract(28))) ^ Crc.extract(18),
|
|
||||||
Crc.extract(17),
|
|
||||||
Crc.extract(16),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Crc.extract(31))) ^ Crc.extract(15),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(2) ^ Crc.extract(30))) ^ Crc.extract(14),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(1) ^ Crc.extract(29))) ^ Crc.extract(13),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(0) ^ Crc.extract(28))) ^ Crc.extract(12),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Crc.extract(31))) ^ Crc.extract(11),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(2) ^ Crc.extract(30) ^ Crc.extract(31))) ^ Crc.extract(10),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(2) ^ Data_Crc.extract(1) ^ Crc.extract(29) ^ Crc.extract(30) ^ Crc.extract(31))) ^ Crc.extract(9),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(2) ^ Data_Crc.extract(1) ^ Data_Crc.extract(0) ^ Crc.extract(28) ^ Crc.extract(29) ^ Crc.extract(30))) ^ Crc.extract(8),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(1) ^ Data_Crc.extract(0) ^ Crc.extract(28) ^ Crc.extract(29) ^ Crc.extract(31))) ^ Crc.extract(7),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(2) ^ Data_Crc.extract(0) ^ Crc.extract(28) ^ Crc.extract(30) ^ Crc.extract(31))) ^ Crc.extract(6),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(2) ^ Data_Crc.extract(1) ^ Crc.extract(29) ^ Crc.extract(30))) ^ Crc.extract(5),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(1) ^ Data_Crc.extract(0) ^ Crc.extract(28) ^ Crc.extract(29) ^ Crc.extract(31))) ^ Crc.extract(4),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(2) ^ Data_Crc.extract(0) ^ Crc.extract(28) ^ Crc.extract(30) ^ Crc.extract(31))) ^ Crc.extract(3),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(2) ^ Data_Crc.extract(1) ^ Crc.extract(29) ^ Crc.extract(30))) ^ Crc.extract( 2),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(1) ^ Data_Crc.extract(0) ^ Crc.extract(28) ^ Crc.extract(29) ^ Crc.extract(31))) ^ Crc.extract(1),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(2) ^ Data_Crc.extract(0) ^ Crc.extract(28) ^ Crc.extract(30) ^ Crc.extract(31))) ^ Crc.extract(0),
|
|
||||||
Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(2) ^ Data_Crc.extract(1) ^ Crc.extract(29) ^ Crc.extract(30) ^ Crc.extract(31)),
|
|
||||||
Enable_Crc & (Data_Crc.extract(2) ^ Data_Crc.extract(1) ^ Data_Crc.extract(0) ^ Crc.extract(28) ^ Crc.extract(29) ^ Crc.extract(30)),
|
|
||||||
Enable_Crc & (Data_Crc.extract(1) ^ Data_Crc.extract(0) ^ Crc.extract(28) ^ Crc.extract(29)),
|
|
||||||
Enable_Crc & (Data_Crc.extract(0) ^ Crc.extract(28))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
io.CrcError := Crc =/= "hc704dd7b".U // CRC not equal to magic number
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class MacRx extends MacRxBase with MacRxFSM with MacRxCounter with MacRxFAddrCheck with MacRxCRC{
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val GenerateRxValid = StateData0 & ~ByteCntEq0;
|
|
||||||
val DelayData = RegNext(StateData0, false.B)
|
|
||||||
val LatchedByte = RegInit(0.U(8.W))
|
|
||||||
when(true.B) {
|
|
||||||
LatchedByte := Cat(io.MRxD, LatchedByte(7,4))// Latched byte
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Output byte stream
|
|
||||||
when( GenerateRxValid ){
|
|
||||||
RxData_d := LatchedByte & Fill(8, StateData0 | StateData1) // Data goes through only in data state
|
|
||||||
} .elsewhen(~DelayData){
|
|
||||||
RxData_d := 0.U // Delaying data to be valid for two cycles. // Zero when not active.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
io.RxValid := ShiftRegister(GenerateRxValid, 2, false.B, true.B)
|
|
||||||
|
|
||||||
|
|
||||||
val GenerateRxStartFrm = StateData0 & ByteCntEq1
|
|
||||||
|
|
||||||
io.RxStartFrm := ShiftRegister(GenerateRxStartFrm, 2, false.B, true.B)
|
|
||||||
|
|
||||||
|
|
||||||
val GenerateRxEndFrm = StateData0 & (~io.MRxDV & io.ByteCntGreat2)
|
|
||||||
val DribbleRxEndFrm = StateData1 & ~io.MRxDV & io.ByteCntGreat2
|
|
||||||
|
|
||||||
val RxEndFrm_d = RegNext(GenerateRxEndFrm, false.B)
|
|
||||||
io.RxEndFrm := RegNext(RxEndFrm_d | DribbleRxEndFrm, false.B)
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
package MAC
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
|
|
||||||
|
|
||||||
class MacSRAMIO extends Bundle{
|
|
||||||
val we = Input(Vec(4, Bool())) // Write enable input, active high
|
|
||||||
val oe = Input(Bool()) // Output enable input, active high
|
|
||||||
val addr = Input(UInt(8.W)) // address bus inputs
|
|
||||||
val di = Input(UInt(32.W)) // input data bus
|
|
||||||
val dato = Output(UInt(32.W)) // output data bus
|
|
||||||
}
|
|
||||||
|
|
||||||
class MacSRAM extends Module{
|
|
||||||
val io: MacSRAMIO = IO(new MacSRAMIO)
|
|
||||||
|
|
||||||
|
|
||||||
// Generic RAM's registers and wires
|
|
||||||
|
|
||||||
val mem0 = Mem( 256, UInt(8.W) )
|
|
||||||
val mem1 = Mem( 256, UInt(8.W) )
|
|
||||||
val mem2 = Mem( 256, UInt(8.W) )
|
|
||||||
val mem3 = Mem( 256, UInt(8.W) )
|
|
||||||
val q = Wire(UInt(32.W))
|
|
||||||
val raddr = Reg( UInt(8.W) )
|
|
||||||
|
|
||||||
|
|
||||||
// Data output drivers
|
|
||||||
io.dato := Mux((io.oe), q, DontCare)
|
|
||||||
|
|
||||||
// read operation
|
|
||||||
when( true.B ){
|
|
||||||
raddr := io.addr // read address needs to be registered to read clock
|
|
||||||
}
|
|
||||||
|
|
||||||
q := Mux(reset.asBool, 0.U, Cat(mem3.read(raddr), mem2.read(raddr), mem1.read(raddr), mem0.read(raddr)))
|
|
||||||
|
|
||||||
// write operation
|
|
||||||
when(io.we(3)){
|
|
||||||
mem3.write(io.addr, io.di(31,24))
|
|
||||||
}
|
|
||||||
|
|
||||||
when(io.we(2)){
|
|
||||||
mem2.write(io.addr, io.di(23,16))
|
|
||||||
}
|
|
||||||
|
|
||||||
when(io.we(1)){
|
|
||||||
mem1.write(io.addr, io.di(15, 8))
|
|
||||||
}
|
|
||||||
|
|
||||||
when(io.we(0)){
|
|
||||||
mem0.write(io.addr, io.di( 7, 0))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
package MAC
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
|
|
||||||
class MacStatusIO extends Bundle{
|
|
||||||
val asyncReset = Input(AsyncReset())
|
|
||||||
|
|
||||||
val MRxClk = Input(Bool())
|
|
||||||
val RxCrcError = Input(Bool())
|
|
||||||
val MRxDV = Input(Bool())
|
|
||||||
val RxStateSFD = Input(Bool())
|
|
||||||
val RxStateData = Input(UInt(2.W))
|
|
||||||
val RxStatePreamble = Input(Bool())
|
|
||||||
val RxStateIdle = Input(Bool())
|
|
||||||
val Transmitting = Input(Bool())
|
|
||||||
val RxByteCnt = Input(UInt(16.W))
|
|
||||||
val RxByteCntEq0 = Input(Bool())
|
|
||||||
val RxByteCntGreat2 = Input(Bool())
|
|
||||||
val MRxD = Input(UInt(4.W))
|
|
||||||
val Collision = Input(Bool())
|
|
||||||
val CollValid = Input(UInt(6.W))
|
|
||||||
val StartTxDone = Input(Bool())
|
|
||||||
val StartTxAbort = Input(Bool())
|
|
||||||
val MTxClk = Input(Bool())
|
|
||||||
val MaxCollisionOccured = Input(Bool())
|
|
||||||
val LateCollision = Input(Bool())
|
|
||||||
val DeferIndication = Input(Bool())
|
|
||||||
val TxStartFrm = Input(Bool())
|
|
||||||
val StatePreamble = Input(Bool())
|
|
||||||
val StateData = Input(UInt(2.W))
|
|
||||||
val CarrierSense = Input(Bool())
|
|
||||||
val Loopback = Input(Bool())
|
|
||||||
val r_FullD = Input(Bool())
|
|
||||||
val RstDeferLatched = Input(Bool())
|
|
||||||
|
|
||||||
val LatchedCrcError = Output(Bool())
|
|
||||||
val RxLateCollision = Output(Bool())
|
|
||||||
val DribbleNibble = Output(Bool())
|
|
||||||
val LoadRxStatus = Output(Bool())
|
|
||||||
val RetryLimit = Output(Bool())
|
|
||||||
val LateCollLatched = Output(Bool())
|
|
||||||
val DeferLatched = Output(Bool())
|
|
||||||
val CarrierSenseLost = Output(Bool())
|
|
||||||
}
|
|
||||||
|
|
||||||
class MacStatus extends RawModule{
|
|
||||||
val io: MacStatusIO = IO(new MacStatusIO)
|
|
||||||
|
|
||||||
withClockAndReset( io.MRxClk.asClock, io.asyncReset ) {
|
|
||||||
|
|
||||||
val LatchedCrcError = RegInit(false.B); io.LatchedCrcError := LatchedCrcError // Crc error
|
|
||||||
|
|
||||||
when(io.RxStateSFD){
|
|
||||||
LatchedCrcError := false.B
|
|
||||||
} .elsewhen(io.RxStateData.extract(0)){
|
|
||||||
LatchedCrcError := io.RxCrcError & ~io.RxByteCntEq0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Time to take a sample
|
|
||||||
val TakeSample =
|
|
||||||
(io.RxStateData.orR & ~io.MRxDV)
|
|
||||||
|
|
||||||
val LoadRxStatus = RegNext(TakeSample, false.B); io.LoadRxStatus := LoadRxStatus // LoadRxStatus
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val RxLateCollision = RegInit(false.B); io.RxLateCollision := RxLateCollision // Late Collision
|
|
||||||
val RxColWindow = RegInit(true.B)// Collision Window
|
|
||||||
|
|
||||||
when(LoadRxStatus){
|
|
||||||
RxLateCollision := false.B
|
|
||||||
} .elsewhen(io.Collision & (~io.r_FullD) ){
|
|
||||||
RxLateCollision := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
when(~io.Collision & io.RxByteCnt(5,0) === io.CollValid & io.RxStateData.extract(1)){
|
|
||||||
RxColWindow := false.B
|
|
||||||
} .elsewhen(io.RxStateIdle){
|
|
||||||
RxColWindow := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// DribbleNibble
|
|
||||||
val DribbleNibble = RegInit(false.B); io.DribbleNibble := DribbleNibble
|
|
||||||
|
|
||||||
when(io.RxStateSFD){
|
|
||||||
DribbleNibble := false.B
|
|
||||||
} .elsewhen(~io.MRxDV & io.RxStateData.extract(1)){
|
|
||||||
DribbleNibble := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
withClockAndReset( io.MTxClk.asClock, io.asyncReset ) {
|
|
||||||
val RetryLimit = RegEnable( io.MaxCollisionOccured, false.B, io.StartTxDone | io.StartTxAbort ); io.RetryLimit := RetryLimit // Latched Retransmission limit
|
|
||||||
val LateCollLatched = RegEnable( io.LateCollision, false.B, io.StartTxDone | io.StartTxAbort); io.LateCollLatched := LateCollLatched // Latched Late Collision
|
|
||||||
|
|
||||||
|
|
||||||
val DeferLatched = RegInit(false.B); io.DeferLatched := DeferLatched // Latched Defer state
|
|
||||||
|
|
||||||
when(io.DeferIndication){
|
|
||||||
DeferLatched := true.B
|
|
||||||
} .elsewhen(io.RstDeferLatched){
|
|
||||||
DeferLatched := false.B
|
|
||||||
}
|
|
||||||
|
|
||||||
val CarrierSenseLost = RegInit(false.B); io.CarrierSenseLost := CarrierSenseLost // CarrierSenseLost
|
|
||||||
|
|
||||||
when((io.StatePreamble | io.StateData.orR) & ~io.CarrierSense & ~io.Loopback & ~io.Collision & ~io.r_FullD){
|
|
||||||
CarrierSenseLost := true.B
|
|
||||||
} .elsewhen(io.TxStartFrm){
|
|
||||||
CarrierSenseLost := false.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,232 +0,0 @@
|
|||||||
package MAC
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
|
|
||||||
import freechips.rocketchip.util._
|
|
||||||
|
|
||||||
|
|
||||||
class Mac_Stream_Bundle extends Bundle{
|
|
||||||
val data = UInt(8.W)
|
|
||||||
val isStart = Bool()
|
|
||||||
val isLast = Bool()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MacTileLinkRxIO extends Bundle{
|
|
||||||
|
|
||||||
val LoadRxStatus = Input(Bool())
|
|
||||||
|
|
||||||
val RxData = Input(UInt(8.W)) // Received data byte (from PHY)
|
|
||||||
val RxValid = Input(Bool())
|
|
||||||
val RxStartFrm = Input(Bool())
|
|
||||||
val RxEndFrm = Input(Bool())
|
|
||||||
|
|
||||||
val DribbleNibble = Input(Bool())
|
|
||||||
val LatchedCrcError = Input(Bool())
|
|
||||||
val RxLateCollision = Input(Bool())
|
|
||||||
|
|
||||||
val asyncReset = Input(AsyncReset())
|
|
||||||
val MRxClk = Input(Bool())
|
|
||||||
|
|
||||||
val Busy_IRQ = Output(Bool())
|
|
||||||
|
|
||||||
|
|
||||||
val r_RxEn = Input(Bool()) // Receive enable
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val rxEnq = Decoupled(new Mac_Stream_Bundle)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class MacTileLinkRx extends Module{
|
|
||||||
val io = IO(new MacTileLinkRxIO)
|
|
||||||
|
|
||||||
val syncReqBundle = Wire(Decoupled(new Mac_Stream_Bundle))
|
|
||||||
val asyncReqBundle = Wire(Decoupled(new Mac_Stream_Bundle))
|
|
||||||
val req_ToAsync = Wire(new AsyncBundle(new Mac_Stream_Bundle))
|
|
||||||
|
|
||||||
val rxReady = RegInit(false.B)
|
|
||||||
val rxReadyAsync = Wire(Bool())
|
|
||||||
withClockAndReset( io.MRxClk.asClock, io.asyncReset ) {
|
|
||||||
rxReadyAsync := ShiftRegister( rxReady, 2, false.B, true.B )
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
withClockAndReset(io.MRxClk.asClock, io.asyncReset){
|
|
||||||
|
|
||||||
when( io.LoadRxStatus ) {
|
|
||||||
when( io.DribbleNibble ) { printf("Warning! DribbleNibble!\n"); }
|
|
||||||
when( io.LatchedCrcError ) { printf("Warning! LatchedCrcError!\n"); }
|
|
||||||
when( io.RxLateCollision ) { printf("Warning! RxLateCollision!\n"); }
|
|
||||||
}
|
|
||||||
|
|
||||||
val RxEnableWindow = RegInit(false.B)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Indicating start of the reception process
|
|
||||||
val SetWriteRxDataToFifo =
|
|
||||||
io.RxValid & rxReadyAsync & (io.RxStartFrm | RxEnableWindow )
|
|
||||||
|
|
||||||
|
|
||||||
// Generation of the end-of-frame signal
|
|
||||||
when(io.RxStartFrm){
|
|
||||||
RxEnableWindow := true.B
|
|
||||||
} .elsewhen(io.RxEndFrm ){
|
|
||||||
RxEnableWindow := false.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val rxFifo = Module(new Queue(new Mac_Stream_Bundle, 4))
|
|
||||||
rxFifo.io.enq.valid := SetWriteRxDataToFifo
|
|
||||||
rxFifo.io.enq.bits.data := io.RxData
|
|
||||||
rxFifo.io.enq.bits.isStart := io.RxStartFrm
|
|
||||||
rxFifo.io.enq.bits.isLast := io.RxEndFrm
|
|
||||||
assert( ~(rxFifo.io.enq.valid & ~rxFifo.io.enq.ready) )
|
|
||||||
|
|
||||||
asyncReqBundle <> rxFifo.io.deq
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
syncReqBundle <> FromAsyncBundle( req_ToAsync )
|
|
||||||
|
|
||||||
withClockAndReset(io.MRxClk.asClock, io.asyncReset) {
|
|
||||||
req_ToAsync <> ToAsyncBundle( asyncReqBundle )
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Busy Interrupt
|
|
||||||
val Busy_IRQ_rck = withClockAndReset(io.MRxClk.asClock, io.asyncReset) {RegInit(false.B)}
|
|
||||||
val Busy_IRQ_sync = ShiftRegister(Busy_IRQ_rck, 2, false.B, true.B)
|
|
||||||
|
|
||||||
|
|
||||||
io.Busy_IRQ := Busy_IRQ_sync & ~RegNext(Busy_IRQ_sync, false.B)
|
|
||||||
|
|
||||||
|
|
||||||
withClockAndReset( io.MRxClk.asClock, io.asyncReset ) {
|
|
||||||
val Busy_IRQ_syncb = ShiftRegister( Busy_IRQ_sync, 2, false.B, true.B )
|
|
||||||
|
|
||||||
when(io.RxValid & io.RxStartFrm & ~rxReadyAsync){
|
|
||||||
Busy_IRQ_rck := true.B
|
|
||||||
} .elsewhen(Busy_IRQ_syncb){
|
|
||||||
Busy_IRQ_rck := false.B
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
when(syncReqBundle.bits.isLast & syncReqBundle.fire ){
|
|
||||||
rxReady := false.B
|
|
||||||
} .elsewhen( io.r_RxEn & (io.rxEnq.ready) ){
|
|
||||||
rxReady := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
io.rxEnq.bits := syncReqBundle.bits
|
|
||||||
io.rxEnq.valid := syncReqBundle.valid
|
|
||||||
syncReqBundle.ready := io.rxEnq.ready
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
assert( ~(io.rxEnq.valid & ~io.rxEnq.ready), "Assert Failed, rx overrun!" )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,238 +0,0 @@
|
|||||||
package MAC
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
|
|
||||||
|
|
||||||
import freechips.rocketchip.util._
|
|
||||||
|
|
||||||
|
|
||||||
class MacTileLinkTxIO extends Bundle{
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val RstDeferLatched = Output(Bool())
|
|
||||||
|
|
||||||
val TxStartFrm = Output(Bool()) // Transmit packet start frame
|
|
||||||
val TxEndFrm = Output(Bool()) // Transmit packet end frame
|
|
||||||
val TxData = Output(UInt(8.W)) // Transmit packet data byte
|
|
||||||
|
|
||||||
val TxUsedData = Input(Bool()) // Transmit packet used data
|
|
||||||
val TxAbort = Input(Bool()) // Transmit packet abort
|
|
||||||
val TxDone = Input(Bool()) // Transmission ended
|
|
||||||
|
|
||||||
val MTxClk = Input(Bool())
|
|
||||||
val asyncReset = Input(AsyncReset())
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Tx Status signals
|
|
||||||
val RetryLimit = Input(Bool()) // Retry limit reached (Retry Max value +1 attempts were made)
|
|
||||||
val LateCollLatched = Input(Bool()) // Late collision occured
|
|
||||||
val DeferLatched = Input(Bool()) // Defer indication (Frame was defered before sucessfully sent)
|
|
||||||
val CarrierSenseLost = Input(Bool()) // Carrier Sense was lost during the frame transmission
|
|
||||||
val PerPacketCrcEn = Output(Bool()) // Per packet crc enable
|
|
||||||
|
|
||||||
//Register
|
|
||||||
val r_TxEn = Input(Bool()) // Transmit enable
|
|
||||||
|
|
||||||
val txDeq = Flipped(Decoupled(new Mac_Stream_Bundle))
|
|
||||||
|
|
||||||
val isTxIdle = Input(Bool())
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MacTileLinkTx extends Module{
|
|
||||||
val io = IO(new MacTileLinkTxIO)
|
|
||||||
|
|
||||||
val syncReqBundle = Wire(Decoupled(new Mac_Stream_Bundle))
|
|
||||||
val asyncReqBundle = Wire(Decoupled(new Mac_Stream_Bundle))
|
|
||||||
val txReq_ToAsync = Wire(new AsyncBundle(new Mac_Stream_Bundle))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
withClockAndReset( io.MTxClk.asClock, io.asyncReset ){
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val TxStartFrm = RegInit(false.B); io.TxStartFrm := TxStartFrm
|
|
||||||
val TxEndFrm = RegInit(false.B); io.TxEndFrm := TxEndFrm
|
|
||||||
val TxData = RegInit(0.U(8.W)); io.TxData := TxData
|
|
||||||
|
|
||||||
// Generating delayed signals
|
|
||||||
val TxAbort_q = RegNext( io.TxAbort, false.B)
|
|
||||||
val TxUsedData_q = RegNext( io.TxUsedData, false.B)
|
|
||||||
|
|
||||||
// Changes for tx occur every second clock. Flop is used for this manner.
|
|
||||||
val Flop = RegInit(false.B)
|
|
||||||
when( io.TxDone | io.TxAbort){
|
|
||||||
Flop := false.B
|
|
||||||
} .elsewhen ( io.TxUsedData ){
|
|
||||||
Flop := ~Flop
|
|
||||||
}
|
|
||||||
|
|
||||||
when( asyncReqBundle.valid & asyncReqBundle.bits.isStart & ~TxStartFrm & io.isTxIdle ){
|
|
||||||
TxStartFrm := true.B
|
|
||||||
} .elsewhen(TxUsedData_q | io.TxAbort & (~TxAbort_q) ){
|
|
||||||
TxStartFrm := false.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Tx end frame generation
|
|
||||||
when(Flop & TxEndFrm | io.TxAbort){
|
|
||||||
TxEndFrm := false.B
|
|
||||||
} .elsewhen( asyncReqBundle.fire & asyncReqBundle.bits.isLast ){
|
|
||||||
TxEndFrm := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
asyncReqBundle.ready :=
|
|
||||||
asyncReqBundle.valid & asyncReqBundle.bits.isStart & ~TxStartFrm & io.isTxIdle |
|
|
||||||
io.TxUsedData & Flop & ~TxEndFrm |
|
|
||||||
TxStartFrm & io.TxUsedData & Flop
|
|
||||||
|
|
||||||
when( asyncReqBundle.fire ){
|
|
||||||
TxData := asyncReqBundle.bits.data
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
assert( ~(asyncReqBundle.ready & ~asyncReqBundle.valid) )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
txReq_ToAsync <> ToAsyncBundle( syncReqBundle )
|
|
||||||
withClockAndReset(io.MTxClk.asClock, io.asyncReset) {
|
|
||||||
asyncReqBundle <> FromAsyncBundle( txReq_ToAsync )
|
|
||||||
}
|
|
||||||
|
|
||||||
val BlockingTxStatusWrite = RegInit(false.B)
|
|
||||||
|
|
||||||
withClockAndReset( io.MTxClk.asClock, io.asyncReset ){
|
|
||||||
val BlockingTxStatusWrite_sync = ShiftRegister( BlockingTxStatusWrite, 2, false.B, true.B)
|
|
||||||
io.RstDeferLatched := BlockingTxStatusWrite_sync & ~RegNext(BlockingTxStatusWrite_sync, false.B)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val TxAbortSync = ShiftRegister( io.TxAbort, 2, false.B, true.B )
|
|
||||||
val TxDoneSync = ShiftRegister( io.TxDone, 2, false.B, true.B )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val txDonePulse = TxDoneSync & ~RegNext(TxDoneSync, false.B)
|
|
||||||
val txAbortPulse = TxAbortSync & ~RegNext(TxAbortSync, false.B)
|
|
||||||
|
|
||||||
|
|
||||||
io.PerPacketCrcEn := false.B
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
when( txDonePulse | txAbortPulse ){
|
|
||||||
|
|
||||||
when(io.RetryLimit) {printf("Warning, io.RetryLimit\n")}
|
|
||||||
when(io.LateCollLatched) {printf("Warning, io.LateCollLatched\n")}
|
|
||||||
when(io.DeferLatched) {printf("Warning, io.DeferLatched\n")}
|
|
||||||
when(io.CarrierSenseLost) {printf("Warning, io.CarrierSenseLost\n")}
|
|
||||||
when(txAbortPulse) {printf("Warning, txAbortPulse\n")}
|
|
||||||
}
|
|
||||||
|
|
||||||
val killTrans = RegInit(false.B)
|
|
||||||
|
|
||||||
when( (io.txDeq.fire & io.txDeq.bits.isLast) | ~io.txDeq.valid ){
|
|
||||||
killTrans := false.B
|
|
||||||
} .elsewhen( txAbortPulse ){
|
|
||||||
killTrans := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val isTxEnable = RegInit(false.B)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
when( io.txDeq.fire & io.txDeq.bits.isLast & ~io.r_TxEn ){
|
|
||||||
isTxEnable := false.B
|
|
||||||
} .elsewhen( io.r_TxEn ){
|
|
||||||
isTxEnable := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
io.txDeq.ready := Mux( killTrans, true.B, isTxEnable & syncReqBundle.ready )
|
|
||||||
syncReqBundle.valid := Mux( killTrans, false.B, isTxEnable & io.txDeq.valid )
|
|
||||||
syncReqBundle.bits := io.txDeq.bits
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
when(~TxDoneSync & ~TxAbortSync){
|
|
||||||
BlockingTxStatusWrite := false.B
|
|
||||||
} .elsewhen(txDonePulse | txAbortPulse){
|
|
||||||
BlockingTxStatusWrite := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,399 +0,0 @@
|
|||||||
package MAC
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
|
|
||||||
|
|
||||||
class MacTxIO extends Bundle{
|
|
||||||
|
|
||||||
val TxStartFrm = Input(Bool()) // Transmit packet start frame
|
|
||||||
val TxEndFrm = Input(Bool()) // Transmit packet end frame
|
|
||||||
val TxData = Input(UInt(8.W)) // Transmit packet data byte
|
|
||||||
val CarrierSense = Input(Bool()) // Carrier sense (synchronized)
|
|
||||||
val Collision = Input(Bool()) // Collision (synchronized)
|
|
||||||
|
|
||||||
val CrcEn = Input(Bool()) // Crc enable (from register)
|
|
||||||
val FullD = Input(Bool()) // Full duplex (from register)
|
|
||||||
val IPGT = Input(UInt(7.W)) // Back to back transmit inter packet gap parameter (from register)
|
|
||||||
val IPGR1 = Input(UInt(7.W)) // Non back to back transmit inter packet gap parameter IPGR1 (from register)
|
|
||||||
val IPGR2 = Input(UInt(7.W)) // Non back to back transmit inter packet gap parameter IPGR2 (from register)
|
|
||||||
val CollValid = Input(UInt(6.W)) // Valid collision window (from register)
|
|
||||||
val ExDfrEn = Input(Bool()) // Excessive defferal enable (from register)
|
|
||||||
|
|
||||||
val MTxD = Output(UInt(4.W)) // Transmit nibble (to PHY)
|
|
||||||
val MTxEn = Output(Bool()) // Transmit enable (to PHY)
|
|
||||||
val TxDone = Output(Bool()) // Transmit packet done (to RISC)
|
|
||||||
val TxAbort = Output(Bool()) // Transmit packet abort (to RISC)
|
|
||||||
val TxUsedData = Output(Bool()) // Transmit packet used data (to RISC)
|
|
||||||
val WillTransmit = Output(Bool()) // Will transmit (to RxEthMAC)
|
|
||||||
val ResetCollision = Output(Bool()) // Reset Collision (for synchronizing collision)
|
|
||||||
val StartTxDone = Output(Bool())
|
|
||||||
val StartTxAbort = Output(Bool())
|
|
||||||
val MaxCollisionOccured= Output(Bool())
|
|
||||||
val LateCollision = Output(Bool())
|
|
||||||
val DeferIndication = Output(Bool())
|
|
||||||
val StatePreamble = Output(Bool())
|
|
||||||
val StateData = Output(UInt(2.W))
|
|
||||||
|
|
||||||
val isTxIdle = Output(Bool())
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class MacTxBase extends Module with RequireAsyncReset{
|
|
||||||
val io: MacTxIO = IO(new MacTxIO)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val StartIPG = Wire(Bool())
|
|
||||||
val StartPreamble = Wire(Bool())
|
|
||||||
val StartData = Wire( Vec(2,Bool()))
|
|
||||||
val StartFCS = Wire(Bool())
|
|
||||||
val StartJam = Wire(Bool())
|
|
||||||
val StartDefer = Wire(Bool())
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val StateSFD = Wire(Bool())
|
|
||||||
|
|
||||||
val CrcError = Wire(Bool())
|
|
||||||
|
|
||||||
|
|
||||||
val NibbleMinFl = Wire(Bool())
|
|
||||||
val ExcessiveDefer = Wire(Bool())
|
|
||||||
|
|
||||||
val StateIPG = RegInit(false.B)
|
|
||||||
val StateIdle = RegInit(false.B)
|
|
||||||
val StatePreamble = RegInit(false.B); io.StatePreamble := StatePreamble
|
|
||||||
val StateData = RegNext( Cat(StartData(1), StartData(0)), 0.U(2.W)); io.StateData := StateData
|
|
||||||
val StatePAD = RegInit(false.B)
|
|
||||||
val StateFCS = RegInit(false.B)
|
|
||||||
val StateJam = RegInit(false.B)
|
|
||||||
val StateJam_q = RegNext(StateJam, false.B)
|
|
||||||
val StateDefer = RegInit(true.B)
|
|
||||||
val Rule1 = RegInit(false.B)
|
|
||||||
|
|
||||||
val ColWindow = RegInit(true.B)
|
|
||||||
val PacketFinished_q = RegInit(false.B)
|
|
||||||
val ByteCnt = RegInit(0.U(16.W)) // Transmit Byte Counter
|
|
||||||
val NibCnt = RegInit(0.U(16.W)) // Nibble Counter
|
|
||||||
val NibCntEq7 = NibCnt === 7.U
|
|
||||||
val NibCntEq15 = NibCnt === 15.U
|
|
||||||
|
|
||||||
io.isTxIdle := StateIdle
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
trait MacTxFSM { this: MacTxBase =>
|
|
||||||
|
|
||||||
// Defining the next state
|
|
||||||
StartIPG := StateDefer & ~ExcessiveDefer & ~io.CarrierSense
|
|
||||||
|
|
||||||
val StartIdle = StateIPG & (Rule1 & NibCnt(6,0) >= io.IPGT | ~Rule1 & NibCnt(6,0) >= io.IPGR2)
|
|
||||||
|
|
||||||
StartPreamble := StateIdle & io.TxStartFrm & ~io.CarrierSense
|
|
||||||
|
|
||||||
StartData(0) := ~io.Collision & (StatePreamble & NibCntEq15 | StateData(1) & ~io.TxEndFrm)
|
|
||||||
StartData(1) := ~io.Collision & StateData(0)
|
|
||||||
|
|
||||||
val StartPAD = ~io.Collision & StateData(1) & io.TxEndFrm & ~NibbleMinFl
|
|
||||||
|
|
||||||
StartFCS :=
|
|
||||||
(~io.Collision & StateData(1) & io.TxEndFrm & NibbleMinFl & io.CrcEn) |
|
|
||||||
(~io.Collision & StatePAD & NibbleMinFl & io.CrcEn)
|
|
||||||
|
|
||||||
StartJam := (io.Collision ) & ((StatePreamble & NibCntEq15) | (StateData(1) | StateData(0)) | StatePAD | StateFCS)
|
|
||||||
|
|
||||||
StartDefer :=
|
|
||||||
(StateIPG & ~Rule1 & io.CarrierSense & NibCnt(6,0) <= io.IPGR1 & NibCnt(6,0) =/= io.IPGR2) |
|
|
||||||
(StateIdle & io.CarrierSense) |
|
|
||||||
(StateJam & NibCntEq7) |
|
|
||||||
io.StartTxDone
|
|
||||||
|
|
||||||
io.DeferIndication := StateIdle & io.CarrierSense
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
when(StartDefer | StartIdle){
|
|
||||||
StateIPG := false.B
|
|
||||||
}.elsewhen(StartIPG){
|
|
||||||
StateIPG := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
when(StartDefer | StartPreamble){
|
|
||||||
StateIdle := false.B
|
|
||||||
}.elsewhen(StartIdle){
|
|
||||||
StateIdle := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
when(StartData(0) | StartJam){
|
|
||||||
StatePreamble := false.B
|
|
||||||
} .elsewhen(StartPreamble){
|
|
||||||
StatePreamble := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
when(StartFCS | StartJam | StartDefer){
|
|
||||||
StatePAD := false.B
|
|
||||||
}.elsewhen(StartPAD){
|
|
||||||
StatePAD := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
when(StartJam | StartDefer){
|
|
||||||
StateFCS := false.B
|
|
||||||
} .elsewhen(StartFCS){
|
|
||||||
StateFCS := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
when(StartDefer){
|
|
||||||
StateJam := false.B
|
|
||||||
} .elsewhen(StartJam){
|
|
||||||
StateJam := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
when(StartIPG){
|
|
||||||
StateDefer := false.B
|
|
||||||
} .elsewhen(StartDefer){
|
|
||||||
StateDefer := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
// This sections defines which interpack gap rule to use
|
|
||||||
when(StateIdle){
|
|
||||||
Rule1 := false.B
|
|
||||||
} .elsewhen(StatePreamble | io.FullD){
|
|
||||||
Rule1 := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
trait MacTxCounter { this: MacTxBase =>
|
|
||||||
|
|
||||||
val ByteCntMax = Wire(Bool())
|
|
||||||
|
|
||||||
val IncrementNibCnt =
|
|
||||||
StateIPG | StatePreamble |
|
|
||||||
(StateData(1) | StateData(0)) |
|
|
||||||
StatePAD | StateFCS | StateJam |
|
|
||||||
(StateDefer & ~ExcessiveDefer & io.TxStartFrm)
|
|
||||||
|
|
||||||
|
|
||||||
val ResetNibCnt =
|
|
||||||
(StateDefer & ExcessiveDefer & ~io.TxStartFrm) |
|
|
||||||
(StatePreamble & NibCntEq15) |
|
|
||||||
(StateJam & NibCntEq7) |
|
|
||||||
StateIdle | StartDefer | StartIPG | StartFCS | StartJam
|
|
||||||
|
|
||||||
|
|
||||||
when(ResetNibCnt){
|
|
||||||
NibCnt := 0.U
|
|
||||||
} .elsewhen(IncrementNibCnt){
|
|
||||||
NibCnt := NibCnt + 1.U
|
|
||||||
}
|
|
||||||
|
|
||||||
NibbleMinFl := NibCnt >= (((64.U-4.U)<<1) - 1.U) // FCS should not be included in NibbleMinFl
|
|
||||||
|
|
||||||
ExcessiveDefer := NibCnt(13,0) === "h17b7".U & ~io.ExDfrEn; // 6071 nibbles
|
|
||||||
|
|
||||||
val IncrementByteCnt =
|
|
||||||
(StateData(1) & ~ByteCntMax) |
|
|
||||||
((StatePAD | StateFCS) & NibCnt.extract(0) & ~ByteCntMax)
|
|
||||||
|
|
||||||
val ResetByteCnt =
|
|
||||||
(StateIdle & io.TxStartFrm) |
|
|
||||||
PacketFinished_q
|
|
||||||
|
|
||||||
|
|
||||||
ByteCntMax := ByteCnt.andR
|
|
||||||
when(ResetByteCnt){
|
|
||||||
ByteCnt := 0.U
|
|
||||||
} .elsewhen(IncrementByteCnt){
|
|
||||||
ByteCnt := ByteCnt + 1.U
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
trait MacTxCRC{ this: MacTxBase =>
|
|
||||||
|
|
||||||
val Initialize_Crc = StateIdle | StatePreamble
|
|
||||||
val Enable_Crc = ~StateFCS
|
|
||||||
|
|
||||||
val Data_Crc =
|
|
||||||
Mux1H(Seq(
|
|
||||||
StateData(0) -> Cat( io.TxData(0), io.TxData(1), io.TxData(2), io.TxData(3) ),
|
|
||||||
StateData(1) -> Cat( io.TxData(4), io.TxData(5), io.TxData(6), io.TxData(7) ),
|
|
||||||
))
|
|
||||||
|
|
||||||
val Crc = RegInit("hFFFFFFFF".U(32.W))
|
|
||||||
|
|
||||||
when( Initialize_Crc ){
|
|
||||||
Crc := "hFFFFFFFF".U
|
|
||||||
} .otherwise{
|
|
||||||
Crc := Cat(
|
|
||||||
Crc.extract(27),
|
|
||||||
Crc.extract(26),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Crc.extract(31))) ^ Crc.extract(25),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(2) ^ Crc.extract(30))) ^ Crc.extract(24),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(1) ^ Crc.extract(29))) ^ Crc.extract(23),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(0) ^ Crc.extract(31) ^ Crc.extract(28))) ^ Crc.extract(22),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(2) ^ Crc.extract(31) ^ Crc.extract(30))) ^ Crc.extract(21),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(2) ^ Data_Crc.extract(1) ^ Crc.extract(30) ^ Crc.extract(29))) ^ Crc.extract(20),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(1) ^ Data_Crc.extract(0) ^ Crc.extract(29) ^ Crc.extract(28))) ^ Crc.extract(19),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(0) ^ Crc.extract(28))) ^ Crc.extract(18),
|
|
||||||
Crc.extract(17),
|
|
||||||
Crc.extract(16),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Crc.extract(31))) ^ Crc.extract(15),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(2) ^ Crc.extract(30))) ^ Crc.extract(14),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(1) ^ Crc.extract(29))) ^ Crc.extract(13),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(0) ^ Crc.extract(28))) ^ Crc.extract(12),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Crc.extract(31))) ^ Crc.extract(11),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(2) ^ Crc.extract(30) ^ Crc.extract(31))) ^ Crc.extract(10),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(2) ^ Data_Crc.extract(1) ^ Crc.extract(29) ^ Crc.extract(30) ^ Crc.extract(31))) ^ Crc.extract(9),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(2) ^ Data_Crc.extract(1) ^ Data_Crc.extract(0) ^ Crc.extract(28) ^ Crc.extract(29) ^ Crc.extract(30))) ^ Crc.extract(8),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(1) ^ Data_Crc.extract(0) ^ Crc.extract(28) ^ Crc.extract(29) ^ Crc.extract(31))) ^ Crc.extract(7),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(2) ^ Data_Crc.extract(0) ^ Crc.extract(28) ^ Crc.extract(30) ^ Crc.extract(31))) ^ Crc.extract(6),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(2) ^ Data_Crc.extract(1) ^ Crc.extract(29) ^ Crc.extract(30))) ^ Crc.extract(5),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(1) ^ Data_Crc.extract(0) ^ Crc.extract(28) ^ Crc.extract(29) ^ Crc.extract(31))) ^ Crc.extract(4),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(2) ^ Data_Crc.extract(0) ^ Crc.extract(28) ^ Crc.extract(30) ^ Crc.extract(31))) ^ Crc.extract(3),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(2) ^ Data_Crc.extract(1) ^ Crc.extract(29) ^ Crc.extract(30))) ^ Crc.extract( 2),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(1) ^ Data_Crc.extract(0) ^ Crc.extract(28) ^ Crc.extract(29) ^ Crc.extract(31))) ^ Crc.extract(1),
|
|
||||||
(Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(2) ^ Data_Crc.extract(0) ^ Crc.extract(28) ^ Crc.extract(30) ^ Crc.extract(31))) ^ Crc.extract(0),
|
|
||||||
Enable_Crc & (Data_Crc.extract(3) ^ Data_Crc.extract(2) ^ Data_Crc.extract(1) ^ Crc.extract(29) ^ Crc.extract(30) ^ Crc.extract(31)),
|
|
||||||
Enable_Crc & (Data_Crc.extract(2) ^ Data_Crc.extract(1) ^ Data_Crc.extract(0) ^ Crc.extract(28) ^ Crc.extract(29) ^ Crc.extract(30)),
|
|
||||||
Enable_Crc & (Data_Crc.extract(1) ^ Data_Crc.extract(0) ^ Crc.extract(28) ^ Crc.extract(29)),
|
|
||||||
Enable_Crc & (Data_Crc.extract(0) ^ Crc.extract(28))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
CrcError := Crc =/= "hc704dd7b".U // CRC not equal to magic number
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class MacTx extends MacTxBase with MacTxFSM with MacTxCounter with MacTxCRC {
|
|
||||||
val MTxD = RegInit(0.U(4.W)); io.MTxD := MTxD
|
|
||||||
val StopExcessiveDeferOccured = RegInit(false.B)
|
|
||||||
|
|
||||||
val StatusLatch = RegInit(false.B)
|
|
||||||
val TxUsedData = RegNext(StartData(0) | StartData(1), false.B); io.TxUsedData := TxUsedData
|
|
||||||
val TxDone = RegInit(false.B); io.TxDone := ~io.TxStartFrm & TxDone
|
|
||||||
val TxAbort = RegInit(false.B); io.TxAbort := ~io.TxStartFrm & TxAbort
|
|
||||||
|
|
||||||
val MTxEn = RegNext(StatePreamble | (StateData(0) | StateData(1)) | StatePAD | StateFCS | StateJam, false.B); io.MTxEn := MTxEn
|
|
||||||
|
|
||||||
val WillTransmit = RegNext(StartPreamble | StatePreamble | (StateData(0) | StateData(1)) | StatePAD | StateFCS | StateJam, false.B); io.WillTransmit := WillTransmit// WillTransmit
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
io.ResetCollision := ~(StatePreamble | (StateData(0) | StateData(1)) | StatePAD | StateFCS)
|
|
||||||
val ExcessiveDeferOccured = io.TxStartFrm & StateDefer & ExcessiveDefer & ~StopExcessiveDeferOccured
|
|
||||||
|
|
||||||
io.StartTxDone :=
|
|
||||||
~io.Collision &
|
|
||||||
( (StateFCS & NibCntEq7) |
|
|
||||||
(StateData(1) & io.TxEndFrm & NibbleMinFl & ~io.CrcEn) |
|
|
||||||
(StatePAD & NibbleMinFl & ~io.CrcEn) )
|
|
||||||
|
|
||||||
io.LateCollision := StartJam & ~ColWindow
|
|
||||||
io.MaxCollisionOccured := StartJam & ColWindow;
|
|
||||||
StateSFD := StatePreamble & NibCntEq15;
|
|
||||||
io.StartTxAbort := ExcessiveDeferOccured | io.LateCollision | io.MaxCollisionOccured
|
|
||||||
|
|
||||||
when(~io.TxStartFrm){
|
|
||||||
StopExcessiveDeferOccured := false.B
|
|
||||||
}.elsewhen(ExcessiveDeferOccured){
|
|
||||||
StopExcessiveDeferOccured := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Collision Window
|
|
||||||
when(~io.Collision & ByteCnt(5,0) === io.CollValid & (StateData(1) | StatePAD & NibCnt.extract(0) | StateFCS & NibCnt.extract(0))){
|
|
||||||
ColWindow := false.B
|
|
||||||
} .elsewhen(StateIdle | StateIPG){
|
|
||||||
ColWindow := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Start Window
|
|
||||||
when(~io.TxStartFrm){
|
|
||||||
StatusLatch := false.B
|
|
||||||
} .elsewhen(ExcessiveDeferOccured | StateIdle){
|
|
||||||
StatusLatch := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Transmit packet done
|
|
||||||
when(io.TxStartFrm & ~StatusLatch){
|
|
||||||
TxDone := false.B
|
|
||||||
}.elsewhen(io.StartTxDone){
|
|
||||||
TxDone := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Transmit packet abort
|
|
||||||
when(io.TxStartFrm & ~StatusLatch & ~ExcessiveDeferOccured){
|
|
||||||
TxAbort := false.B
|
|
||||||
} .elsewhen(io.StartTxAbort){
|
|
||||||
TxAbort := true.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
when( true.B ){
|
|
||||||
MTxD := // Transmit nibble
|
|
||||||
Mux(
|
|
||||||
StateData(0), io.TxData(3,0), // Lower nibble
|
|
||||||
Mux(StateData(1), io.TxData(7,4), // Higher nibble
|
|
||||||
Mux( StateFCS, Cat(~Crc.extract(28), ~Crc.extract(29), ~Crc.extract(30), ~Crc.extract(31)), // Crc
|
|
||||||
Mux(StateJam, 9.U, // Jam pattern
|
|
||||||
Mux(
|
|
||||||
StatePreamble, Mux(NibCntEq15, "hd".U, 5.U),// SFD,Preamble
|
|
||||||
0.U
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val PacketFinished_d = io.StartTxDone | io.LateCollision | io.MaxCollisionOccured | ExcessiveDeferOccured;
|
|
||||||
val PacketFinished = RegNext(PacketFinished_d, false.B)
|
|
||||||
when(true.B){
|
|
||||||
PacketFinished_q := PacketFinished
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
package Wrapeer
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
import chisel3.experimental.dataview._
|
|
||||||
|
|
||||||
import org.chipsalliance.cde.config._
|
|
||||||
import freechips.rocketchip.diplomacy._
|
|
||||||
import freechips.rocketchip.tilelink._
|
|
||||||
import freechips.rocketchip.interrupts._
|
|
||||||
|
|
||||||
import MAC._
|
|
||||||
import Switch._
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class EfablessTopIO(implicit p: Parameters) extends SwitchIO{
|
|
||||||
|
|
||||||
val wbs_stb_i = Input(Bool())
|
|
||||||
val wbs_cyc_i = Input(Bool())
|
|
||||||
val wbs_we_i = Input(Bool())
|
|
||||||
val wbs_sel_i = Input(UInt(4.W))
|
|
||||||
val wbs_dat_i = Input(UInt(32.W))
|
|
||||||
val wbs_adr_i = Input(UInt(32.W))
|
|
||||||
val wbs_ack_o = Output(Bool())
|
|
||||||
val wbs_dat_o = Output(UInt(32.W))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class EfablessTop(implicit p: Parameters) extends LazyModule with HasSwitchParameters{
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val eSwitch = LazyModule(new Switch)
|
|
||||||
|
|
||||||
|
|
||||||
val wbCnvMasterNode = TLClientNode(Seq(TLMasterPortParameters.v1(
|
|
||||||
Seq(TLMasterParameters.v1(
|
|
||||||
name = "wishbone",
|
|
||||||
sourceId = IdRange(0, 1),
|
|
||||||
))
|
|
||||||
)))
|
|
||||||
|
|
||||||
val sram = TLRAM(
|
|
||||||
address = AddressSet(0x30002000L, 0x00001fffL),
|
|
||||||
cacheable = false,
|
|
||||||
executable = false,
|
|
||||||
atomics = false,
|
|
||||||
beatBytes = 4
|
|
||||||
)
|
|
||||||
|
|
||||||
val wbXbar = TLXbar()
|
|
||||||
val sramXbar = TLXbar()
|
|
||||||
|
|
||||||
eSwitch.macReg(0).configNode := TLBuffer() := wbXbar
|
|
||||||
eSwitch.macReg(1).configNode := TLBuffer() := wbXbar
|
|
||||||
eSwitch.dmaReg.configNode := TLBuffer() := wbXbar
|
|
||||||
sram := TLBuffer() := sramXbar := TLBuffer() := wbXbar := TLBuffer() := wbCnvMasterNode
|
|
||||||
sramXbar := TLBuffer() := eSwitch.tlClientNode
|
|
||||||
|
|
||||||
|
|
||||||
val intSinkNode = for( i <- 0 until chn ) yield { IntSinkNode(IntSinkPortSimple()) }
|
|
||||||
intSinkNode(0) := eSwitch.macReg(0).int_node
|
|
||||||
intSinkNode(1) := eSwitch.macReg(1).int_node
|
|
||||||
|
|
||||||
val int0 = InModuleBody {
|
|
||||||
intSinkNode(0).makeIOs()
|
|
||||||
}
|
|
||||||
|
|
||||||
val int1 = InModuleBody {
|
|
||||||
intSinkNode(1).makeIOs()
|
|
||||||
}
|
|
||||||
|
|
||||||
lazy val module = new EfablessTopImp(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class EfablessTopImp(outer: EfablessTop)(implicit p: Parameters) extends LazyModuleImp(outer) with HasSwitchParameters{
|
|
||||||
val io: EfablessTopIO = IO(new EfablessTopIO)
|
|
||||||
|
|
||||||
io.viewAsSupertype(new SwitchIO) <> outer.eSwitch.module.io
|
|
||||||
|
|
||||||
val ( wb_bus, wb_edge ) = outer.wbCnvMasterNode.out.head
|
|
||||||
|
|
||||||
|
|
||||||
val wbAck = RegInit(false.B)
|
|
||||||
val wbDato = Reg(UInt(32.W))
|
|
||||||
|
|
||||||
val isBusy = RegInit(false.B)
|
|
||||||
val wbAValid = RegInit(false.B)
|
|
||||||
val wbABits = Reg(new TLBundleA(wb_edge.bundle))
|
|
||||||
|
|
||||||
when( io.wbs_cyc_i & io.wbs_stb_i & ~isBusy ){
|
|
||||||
assert( ~wbAValid )
|
|
||||||
wbAValid := true.B
|
|
||||||
isBusy := true.B
|
|
||||||
when( io.wbs_we_i ){
|
|
||||||
wbABits :=
|
|
||||||
wb_edge.Put(
|
|
||||||
fromSource = 0.U,
|
|
||||||
toAddress = io.wbs_adr_i,
|
|
||||||
lgSize = log2Ceil(32/8).U,
|
|
||||||
data = io.wbs_dat_i,
|
|
||||||
mask = io.wbs_sel_i,
|
|
||||||
)._2
|
|
||||||
} .otherwise{
|
|
||||||
wbABits :=
|
|
||||||
wb_edge.Get(
|
|
||||||
fromSource = 0.U,
|
|
||||||
toAddress = io.wbs_adr_i,
|
|
||||||
lgSize = log2Ceil(32/8).U,
|
|
||||||
)._2
|
|
||||||
}
|
|
||||||
} .elsewhen( wb_bus.a.fire ){
|
|
||||||
wbAValid := false.B
|
|
||||||
} .elsewhen( wb_bus.d.fire ){
|
|
||||||
wbAck := true.B
|
|
||||||
wbDato := wb_bus.d.bits.data
|
|
||||||
} .elsewhen( (~io.wbs_cyc_i | ~io.wbs_stb_i) & isBusy ){
|
|
||||||
isBusy := false.B
|
|
||||||
wbAck := false.B
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
wb_bus.d.ready := true.B
|
|
||||||
wb_bus.a.valid := wbAValid
|
|
||||||
wb_bus.a.bits := wbABits
|
|
||||||
|
|
||||||
io.wbs_ack_o := wbAck & io.wbs_cyc_i & io.wbs_stb_i
|
|
||||||
io.wbs_dat_o := wbDato
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -8,11 +8,11 @@ import chisel3.util._
|
|||||||
class CDRInIO extends Bundle{
|
class CDRInIO extends Bundle{
|
||||||
val axis = Decoupled(new AXIS_Bundle(8))
|
val axis = Decoupled(new AXIS_Bundle(8))
|
||||||
val serDat = Input(Bool())
|
val serDat = Input(Bool())
|
||||||
|
val flush = Input(Bool())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
abstract class CDRInBase extends Module{
|
abstract class CDRInBase extends Module with RequireAsyncReset{
|
||||||
|
|
||||||
|
|
||||||
val io: CDRInIO = IO(new CDRInIO)
|
val io: CDRInIO = IO(new CDRInIO)
|
||||||
@@ -21,48 +21,6 @@ abstract class CDRInBase extends Module{
|
|||||||
val syncSerDat = Wire(Bool())
|
val syncSerDat = Wire(Bool())
|
||||||
}
|
}
|
||||||
|
|
||||||
trait CDRInOverSample{ this: CDRInBase =>
|
|
||||||
|
|
||||||
val overCLK = IO(Input(Bool()))
|
|
||||||
val sampleRate: Int = 4
|
|
||||||
require(sampleRate >= 4)
|
|
||||||
|
|
||||||
val sampleReg = withClockAndReset(overCLK.asClock, reset.asBool){ ShiftRegisters( RegNext(io.serDat), sampleRate+3 ) }
|
|
||||||
|
|
||||||
val flitReg = for( i <- 0 until sampleRate ) yield {
|
|
||||||
withClockAndReset(overCLK.asClock, reset.asBool){
|
|
||||||
RegNext(
|
|
||||||
(sampleReg(i) & sampleReg(i+1)) |
|
|
||||||
(sampleReg(i) & sampleReg(i+2)) |
|
|
||||||
(sampleReg(i+1) & sampleReg(i+2)), false.B
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val arbCnt = withClockAndReset(overCLK.asClock, reset.asBool){ RegInit("b00000001".U(sampleRate.W)) }
|
|
||||||
arbCnt := Cat( arbCnt(sampleRate-2,0), arbCnt.extract(sampleRate-1) )
|
|
||||||
val arbLock = withClockAndReset(overCLK.asClock, reset.asBool){ RegInit("b00000001".U(sampleRate.W)) }
|
|
||||||
withClockAndReset(overCLK.asClock, reset.asBool){
|
|
||||||
when( flitReg(0) ^ flitReg(1) ){
|
|
||||||
arbLock := arbCnt
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
val asyncSerDat = withClockAndReset(overCLK.asClock, reset.asBool){ RegNext(
|
|
||||||
Mux1H(
|
|
||||||
(for { i <- 0 until sampleRate; j <- 0 until sampleRate } yield {
|
|
||||||
//跳变沿到来锁定的位置 锁定拍当前所在的位置 选择锁定拍后一拍的值认为是正确值
|
|
||||||
((arbLock === (1.U << i)) & (arbCnt === (1.U << j))) -> flitReg((sampleRate + 2 - i + j) % sampleRate)
|
|
||||||
})
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
|
|
||||||
|
|
||||||
syncSerDat := ShiftRegister( asyncSerDat, 2 )
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
trait CDRInMultiSample{ this: CDRInBase =>
|
trait CDRInMultiSample{ this: CDRInBase =>
|
||||||
|
|
||||||
@@ -133,8 +91,6 @@ trait CDRInMultiSample{ this: CDRInBase =>
|
|||||||
|
|
||||||
//优先级电路,优先选择跳变的后一相进行操作,电路上需要做成可调的
|
//优先级电路,优先选择跳变的后一相进行操作,电路上需要做成可调的
|
||||||
|
|
||||||
// val diff = Wire(UInt( (log2Ceil(clkNum)).W ))
|
|
||||||
// diff := arbLock - j.U
|
|
||||||
when( ~isLock ){
|
when( ~isLock ){
|
||||||
for( i <- 3 until 19 ){
|
for( i <- 3 until 19 ){
|
||||||
val j = 19 - i - 1
|
val j = 19 - i - 1
|
||||||
@@ -156,7 +112,9 @@ trait CDRInMultiSample{ this: CDRInBase =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
when( ~isLock ){
|
when( io.flush ){
|
||||||
|
isLock := false.B
|
||||||
|
} .elsewhen( ~isLock ){
|
||||||
for( i <- 3 until 19 ){
|
for( i <- 3 until 19 ){
|
||||||
val j = 19 - i - 1
|
val j = 19 - i - 1
|
||||||
when( flitReg(j) ^ flitReg(j+1) ){
|
when( flitReg(j) ^ flitReg(j+1) ){
|
||||||
@@ -199,23 +157,34 @@ trait CDRInAxis{ this: CDRInBase =>
|
|||||||
val bitCnt = Reg(UInt(4.W))
|
val bitCnt = Reg(UInt(4.W))
|
||||||
val byteCnt = RegInit(0.U((12+1).W))
|
val byteCnt = RegInit(0.U((12+1).W))
|
||||||
|
|
||||||
val checkSFD = RegInit( 0.U(20.W) ); checkSFD := Cat( checkSFD(18,0), syncSerDat )
|
val checkSFD = RegInit( 0.U(20.W) )
|
||||||
|
|
||||||
|
when( io.flush ){
|
||||||
|
checkSFD := 0.U
|
||||||
|
} .otherwise{
|
||||||
|
checkSFD := Cat( checkSFD(18,0), syncSerDat )
|
||||||
|
}
|
||||||
|
|
||||||
val shiftData = Dualb4b5Decoder(checkSFD(9,0))
|
val shiftData = Dualb4b5Decoder(checkSFD(9,0))
|
||||||
|
|
||||||
val payloadLen = RegInit(0.U(12.W))
|
val payloadLen = RegInit(0.U(12.W))
|
||||||
when( byteCnt === 0.U & bitCnt === 9.U & stateCurr === STATE_HEADER ){
|
|
||||||
|
when( io.flush ){
|
||||||
|
payloadLen := 0.U
|
||||||
|
} .elsewhen( byteCnt === 0.U & bitCnt === 9.U & stateCurr === STATE_HEADER ){
|
||||||
payloadLen := Cat( shiftData, 0.U(4.W) )
|
payloadLen := Cat( shiftData, 0.U(4.W) )
|
||||||
} .elsewhen( byteCnt === 1.U & bitCnt === 9.U & stateCurr === STATE_HEADER ){
|
} .elsewhen( byteCnt === 1.U & bitCnt === 9.U & stateCurr === STATE_HEADER ){
|
||||||
payloadLen := Cat( payloadLen(11,4), shiftData(7,4) )
|
payloadLen := Cat( payloadLen(11,4), shiftData(7,4) )
|
||||||
}
|
}
|
||||||
|
|
||||||
stateNext :=
|
stateNext :=
|
||||||
|
Mux( io.flush, STATE_IDLE,
|
||||||
Mux1H(Seq(
|
Mux1H(Seq(
|
||||||
(stateCurr === STATE_IDLE) -> ( Mux( checkSFD === Cat(ETH_PRE , ETH_SFD), STATE_HEADER, STATE_IDLE )), //IDLE
|
(stateCurr === STATE_IDLE) -> ( Mux( checkSFD === Cat(ETH_PRE , ETH_SFD), STATE_HEADER, STATE_IDLE )), //IDLE
|
||||||
(stateCurr === STATE_HEADER) -> ( Mux( (byteCnt === (HeaderByte-1).U) & (bitCnt === 9.U), STATE_PAYLOAD, STATE_HEADER ) ),
|
(stateCurr === STATE_HEADER) -> ( Mux( (byteCnt === (HeaderByte-1).U) & (bitCnt === 9.U), STATE_PAYLOAD, STATE_HEADER ) ),
|
||||||
(stateCurr === STATE_PAYLOAD) -> ( Mux( (byteCnt === (payloadLen + (4 - 1).U) ) & (bitCnt === 9.U), STATE_IDLE, STATE_PAYLOAD )), // PAYLOAD
|
(stateCurr === STATE_PAYLOAD) -> ( Mux( (byteCnt === (payloadLen + (4 - 1).U) ) & (bitCnt === 9.U), STATE_IDLE, STATE_PAYLOAD )), // PAYLOAD
|
||||||
)) //crc
|
)) //crc
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -231,7 +200,9 @@ trait CDRInAxis{ this: CDRInBase =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
when( stateCurr === STATE_IDLE & ( checkSFD === Cat(ETH_PRE, ETH_SFD) ) ){ //first align
|
when( io.flush ){
|
||||||
|
byteCnt := 0.U
|
||||||
|
} .elsewhen( stateCurr === STATE_IDLE & ( checkSFD === Cat(ETH_PRE, ETH_SFD) ) ){ //first align
|
||||||
byteCnt := 0.U
|
byteCnt := 0.U
|
||||||
} .elsewhen( bitCnt === 9.U ){
|
} .elsewhen( bitCnt === 9.U ){
|
||||||
when( stateCurr === STATE_HEADER ){
|
when( stateCurr === STATE_HEADER ){
|
||||||
@@ -250,26 +221,29 @@ trait CDRInAxis{ this: CDRInBase =>
|
|||||||
val axis_valid = RegInit(false.B)
|
val axis_valid = RegInit(false.B)
|
||||||
val axis_tdata = RegEnable( shiftData, bitCnt === 9.U & ( stateCurr === STATE_HEADER | stateCurr === STATE_PAYLOAD ) )
|
val axis_tdata = RegEnable( shiftData, bitCnt === 9.U & ( stateCurr === STATE_HEADER | stateCurr === STATE_PAYLOAD ) )
|
||||||
val axis_tuser = false.B
|
val axis_tuser = false.B
|
||||||
val axis_tlast = RegNext( stateCurr === STATE_PAYLOAD & stateNext === STATE_IDLE, false.B )
|
val axis_tlast = RegInit( false.B )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
io.axis.valid := axis_valid
|
io.axis.valid := axis_valid
|
||||||
io.axis.bits.tdata := axis_tdata
|
io.axis.bits.tdata := axis_tdata
|
||||||
io.axis.bits.tuser := axis_tuser
|
io.axis.bits.tuser := axis_tuser
|
||||||
io.axis.bits.tlast := axis_tlast
|
io.axis.bits.tlast := axis_tlast
|
||||||
|
|
||||||
|
when( io.flush ){
|
||||||
when( io.axis.fire ){
|
axis_valid := false.B
|
||||||
|
} .elsewhen( io.axis.fire ){
|
||||||
axis_valid := false.B
|
axis_valid := false.B
|
||||||
} .elsewhen( bitCnt === 9.U & ( stateCurr === STATE_HEADER | stateCurr === STATE_PAYLOAD ) ){
|
} .elsewhen( bitCnt === 9.U & ( stateCurr === STATE_HEADER | stateCurr === STATE_PAYLOAD ) ){
|
||||||
axis_valid := true.B
|
axis_valid := true.B
|
||||||
}
|
}
|
||||||
|
|
||||||
|
when( io.flush ){
|
||||||
|
axis_tlast := false.B
|
||||||
|
} .otherwise{
|
||||||
|
axis_tlast := (stateCurr === STATE_PAYLOAD & stateNext === STATE_IDLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
class CDRIn extends CDRInBase
|
|
||||||
with CDRInAxis
|
|
||||||
with CDRInOverSample{
|
|
||||||
require(false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class MPCDRIn extends CDRInBase
|
class MPCDRIn extends CDRInBase
|
||||||
|
|||||||
@@ -14,11 +14,13 @@ class CDROutIO extends Bundle{
|
|||||||
val axis = Flipped(Decoupled(new AXIS_Bundle(8)))
|
val axis = Flipped(Decoupled(new AXIS_Bundle(8)))
|
||||||
val serDat = Output(Bool())
|
val serDat = Output(Bool())
|
||||||
|
|
||||||
|
val flush = Input(Bool())
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class CDROut extends Module{
|
class CDROut extends Module with RequireAsyncReset{
|
||||||
val io: CDROutIO = IO(new CDROutIO)
|
val io: CDROutIO = IO(new CDROutIO)
|
||||||
def PRE_NUM = 3 //PRE_NUM should >= 3
|
def PRE_NUM = 3 //PRE_NUM should >= 3
|
||||||
|
|
||||||
@@ -39,12 +41,14 @@ class CDROut extends Module{
|
|||||||
|
|
||||||
val shiftData = RegInit(0.U(10.W))
|
val shiftData = RegInit(0.U(10.W))
|
||||||
|
|
||||||
stateNext := Mux1H(Seq(
|
stateNext :=
|
||||||
|
Mux( io.flush, STATE_IDLE,
|
||||||
|
Mux1H(Seq(
|
||||||
(stateCurr === STATE_IDLE) -> ( Mux( io.axis.valid, STATE_PREAMBLE, STATE_IDLE )),
|
(stateCurr === STATE_IDLE) -> ( Mux( io.axis.valid, STATE_PREAMBLE, STATE_IDLE )),
|
||||||
(stateCurr === STATE_PREAMBLE) -> ( Mux( (byteCnt === (PRE_NUM-1).U) & (bitCnt === 9.U), Mux( io.axis.valid, STATE_PAYLOAD, STATE_IDLE), STATE_PREAMBLE )),
|
(stateCurr === STATE_PREAMBLE) -> ( Mux( (byteCnt === (PRE_NUM-1).U) & (bitCnt === 9.U), Mux( io.axis.valid, STATE_PAYLOAD, STATE_IDLE), STATE_PREAMBLE )),
|
||||||
(stateCurr === STATE_PAYLOAD) -> ( Mux( (io.axis.fire & io.axis.bits.tlast) | (~io.axis.valid & io.axis.ready), STATE_IDLE, STATE_PAYLOAD ) ),
|
(stateCurr === STATE_PAYLOAD) -> ( Mux( (io.axis.fire & io.axis.bits.tlast) | (~io.axis.valid & io.axis.ready), STATE_IDLE, STATE_PAYLOAD ) ),
|
||||||
))
|
))
|
||||||
|
)
|
||||||
io.serDat := shiftData.extract(9)
|
io.serDat := shiftData.extract(9)
|
||||||
io.axis.ready :=
|
io.axis.ready :=
|
||||||
bitCnt === 9.U & (
|
bitCnt === 9.U & (
|
||||||
@@ -58,8 +62,9 @@ class CDROut extends Module{
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
when( io.flush ){
|
||||||
when( stateCurr === STATE_IDLE & stateNext === STATE_PREAMBLE){ //PRE
|
shiftData := 0.U
|
||||||
|
} .elsewhen( stateCurr === STATE_IDLE & stateNext === STATE_PREAMBLE){ //PRE
|
||||||
shiftData := ETH_PRE
|
shiftData := ETH_PRE
|
||||||
} .otherwise{
|
} .otherwise{
|
||||||
when( bitCnt =/= 9.U ){
|
when( bitCnt =/= 9.U ){
|
||||||
|
|||||||
@@ -86,12 +86,13 @@ import chisel3.util._
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
class crc32_8() extends Module{
|
class crc32_8() extends Module with RequireAsyncReset{
|
||||||
class crc32IO_Bundle extends Bundle{
|
class crc32IO_Bundle extends Bundle{
|
||||||
val isEnable = Input(Bool())
|
val isEnable = Input(Bool())
|
||||||
val dataIn = Input(UInt(8.W))
|
val dataIn = Input(UInt(8.W))
|
||||||
|
|
||||||
val crc = Output(UInt(32.W))
|
val crc = Output(UInt(32.W))
|
||||||
|
val flush = Input(Bool())
|
||||||
}
|
}
|
||||||
|
|
||||||
val io = IO( new crc32IO_Bundle )
|
val io = IO( new crc32IO_Bundle )
|
||||||
@@ -99,7 +100,16 @@ class crc32_8() extends Module{
|
|||||||
// val LFSR_POLY = "h4c11db7".U
|
// val LFSR_POLY = "h4c11db7".U
|
||||||
|
|
||||||
val lfsr_c = for( i <- 0 until 32 ) yield Wire(Bool())
|
val lfsr_c = for( i <- 0 until 32 ) yield Wire(Bool())
|
||||||
val lfsr_q = for( i <- 0 until 32 ) yield RegEnable( lfsr_c(i), true.B, io.isEnable )
|
val lfsr_q = for( i <- 0 until 32 ) yield RegInit( true.B )
|
||||||
|
|
||||||
|
for( i <- 0 until 32 ){
|
||||||
|
when( io.flush ){
|
||||||
|
lfsr_q(i) := true.B
|
||||||
|
} .elsewhen( io.isEnable ){
|
||||||
|
lfsr_q(i) := lfsr_c(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
io.crc := Cat( lfsr_q )
|
io.crc := Cat( lfsr_q )
|
||||||
|
|
||||||
val dataIn = Wire(UInt(8.W))
|
val dataIn = Wire(UInt(8.W))
|
||||||
@@ -142,67 +152,3 @@ class crc32_8() extends Module{
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class crc32_32() extends Module{
|
|
||||||
val io = IO(new Bundle{
|
|
||||||
val enq = Flipped(Valid(UInt(32.W)))
|
|
||||||
val crc = Output(UInt(32.W))
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2009 OutputLogic.com
|
|
||||||
// This source file may be used and distributed without restriction
|
|
||||||
// provided that this copyright statement is not removed from the file
|
|
||||||
// and that any derivative work contains the original copyright notice
|
|
||||||
// and the associated disclaimer.
|
|
||||||
//
|
|
||||||
// THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS
|
|
||||||
// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
|
||||||
// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// CRC module for data(31:0) , crc(31:0)=1+x^1+x^2+x^4+x^5+x^7+x^8+x^10+x^11+x^12+x^16+x^22+x^23+x^26+x^32;
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
val lfsr_c = Wire(Vec(32, UInt(1.W)))
|
|
||||||
val lfsr_q = RegEnable( Cat(lfsr_c.reverse), "hffffffff".U(32.W), io.enq.valid)
|
|
||||||
|
|
||||||
io.crc := lfsr_q
|
|
||||||
|
|
||||||
lfsr_c( 0) := lfsr_q(0) ^ lfsr_q(6) ^ lfsr_q( 9) ^ lfsr_q(10) ^ lfsr_q(12) ^ lfsr_q(16) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(30) ^ lfsr_q(31) ^ io.enq.bits(0) ^ io.enq.bits(6) ^ io.enq.bits(9) ^ io.enq.bits(10) ^ io.enq.bits(12) ^ io.enq.bits(16) ^ io.enq.bits(24) ^ io.enq.bits(25) ^ io.enq.bits(26) ^ io.enq.bits(28) ^ io.enq.bits(29) ^ io.enq.bits(30) ^ io.enq.bits(31);
|
|
||||||
lfsr_c( 1) := lfsr_q(0) ^ lfsr_q(1) ^ lfsr_q( 6) ^ lfsr_q( 7) ^ lfsr_q( 9) ^ lfsr_q(11) ^ lfsr_q(12) ^ lfsr_q(13) ^ lfsr_q(16) ^ lfsr_q(17) ^ lfsr_q(24) ^ lfsr_q(27) ^ lfsr_q(28) ^ io.enq.bits(0) ^ io.enq.bits(1) ^ io.enq.bits(6) ^ io.enq.bits(7) ^ io.enq.bits(9) ^ io.enq.bits(11) ^ io.enq.bits(12) ^ io.enq.bits(13) ^ io.enq.bits(16) ^ io.enq.bits(17) ^ io.enq.bits(24) ^ io.enq.bits(27) ^ io.enq.bits(28);
|
|
||||||
lfsr_c( 2) := lfsr_q(0) ^ lfsr_q(1) ^ lfsr_q( 2) ^ lfsr_q( 6) ^ lfsr_q( 7) ^ lfsr_q( 8) ^ lfsr_q( 9) ^ lfsr_q(13) ^ lfsr_q(14) ^ lfsr_q(16) ^ lfsr_q(17) ^ lfsr_q(18) ^ lfsr_q(24) ^ lfsr_q(26) ^ lfsr_q(30) ^ lfsr_q(31) ^ io.enq.bits(0) ^ io.enq.bits(1) ^ io.enq.bits(2) ^ io.enq.bits(6) ^ io.enq.bits(7) ^ io.enq.bits(8) ^ io.enq.bits(9) ^ io.enq.bits(13) ^ io.enq.bits(14) ^ io.enq.bits(16) ^ io.enq.bits(17) ^ io.enq.bits(18) ^ io.enq.bits(24) ^ io.enq.bits(26) ^ io.enq.bits(30) ^ io.enq.bits(31);
|
|
||||||
lfsr_c( 3) := lfsr_q(1) ^ lfsr_q(2) ^ lfsr_q( 3) ^ lfsr_q( 7) ^ lfsr_q( 8) ^ lfsr_q( 9) ^ lfsr_q(10) ^ lfsr_q(14) ^ lfsr_q(15) ^ lfsr_q(17) ^ lfsr_q(18) ^ lfsr_q(19) ^ lfsr_q(25) ^ lfsr_q(27) ^ lfsr_q(31) ^ io.enq.bits(1) ^ io.enq.bits(2) ^ io.enq.bits(3) ^ io.enq.bits(7) ^ io.enq.bits(8) ^ io.enq.bits(9) ^ io.enq.bits(10) ^ io.enq.bits(14) ^ io.enq.bits(15) ^ io.enq.bits(17) ^ io.enq.bits(18) ^ io.enq.bits(19) ^ io.enq.bits(25) ^ io.enq.bits(27) ^ io.enq.bits(31);
|
|
||||||
lfsr_c( 4) := lfsr_q(0) ^ lfsr_q(2) ^ lfsr_q( 3) ^ lfsr_q( 4) ^ lfsr_q( 6) ^ lfsr_q( 8) ^ lfsr_q(11) ^ lfsr_q(12) ^ lfsr_q(15) ^ lfsr_q(18) ^ lfsr_q(19) ^ lfsr_q(20) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(29) ^ lfsr_q(30) ^ lfsr_q(31) ^ io.enq.bits(0) ^ io.enq.bits(2) ^ io.enq.bits(3) ^ io.enq.bits(4) ^ io.enq.bits(6) ^ io.enq.bits(8) ^ io.enq.bits(11) ^ io.enq.bits(12) ^ io.enq.bits(15) ^ io.enq.bits(18) ^ io.enq.bits(19) ^ io.enq.bits(20) ^ io.enq.bits(24) ^ io.enq.bits(25) ^ io.enq.bits(29) ^ io.enq.bits(30) ^ io.enq.bits(31);
|
|
||||||
lfsr_c( 5) := lfsr_q(0) ^ lfsr_q(1) ^ lfsr_q( 3) ^ lfsr_q( 4) ^ lfsr_q( 5) ^ lfsr_q( 6) ^ lfsr_q( 7) ^ lfsr_q(10) ^ lfsr_q(13) ^ lfsr_q(19) ^ lfsr_q(20) ^ lfsr_q(21) ^ lfsr_q(24) ^ lfsr_q(28) ^ lfsr_q(29) ^ io.enq.bits(0) ^ io.enq.bits(1) ^ io.enq.bits(3) ^ io.enq.bits(4) ^ io.enq.bits(5) ^ io.enq.bits(6) ^ io.enq.bits(7) ^ io.enq.bits(10) ^ io.enq.bits(13) ^ io.enq.bits(19) ^ io.enq.bits(20) ^ io.enq.bits(21) ^ io.enq.bits(24) ^ io.enq.bits(28) ^ io.enq.bits(29);
|
|
||||||
lfsr_c( 6) := lfsr_q(1) ^ lfsr_q(2) ^ lfsr_q( 4) ^ lfsr_q( 5) ^ lfsr_q( 6) ^ lfsr_q( 7) ^ lfsr_q( 8) ^ lfsr_q(11) ^ lfsr_q(14) ^ lfsr_q(20) ^ lfsr_q(21) ^ lfsr_q(22) ^ lfsr_q(25) ^ lfsr_q(29) ^ lfsr_q(30) ^ io.enq.bits(1) ^ io.enq.bits(2) ^ io.enq.bits(4) ^ io.enq.bits(5) ^ io.enq.bits(6) ^ io.enq.bits(7) ^ io.enq.bits(8) ^ io.enq.bits(11) ^ io.enq.bits(14) ^ io.enq.bits(20) ^ io.enq.bits(21) ^ io.enq.bits(22) ^ io.enq.bits(25) ^ io.enq.bits(29) ^ io.enq.bits(30);
|
|
||||||
lfsr_c( 7) := lfsr_q(0) ^ lfsr_q(2) ^ lfsr_q( 3) ^ lfsr_q( 5) ^ lfsr_q( 7) ^ lfsr_q( 8) ^ lfsr_q(10) ^ lfsr_q(15) ^ lfsr_q(16) ^ lfsr_q(21) ^ lfsr_q(22) ^ lfsr_q(23) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(28) ^ lfsr_q(29) ^ io.enq.bits(0) ^ io.enq.bits(2) ^ io.enq.bits(3) ^ io.enq.bits(5) ^ io.enq.bits(7) ^ io.enq.bits(8) ^ io.enq.bits(10) ^ io.enq.bits(15) ^ io.enq.bits(16) ^ io.enq.bits(21) ^ io.enq.bits(22) ^ io.enq.bits(23) ^ io.enq.bits(24) ^ io.enq.bits(25) ^ io.enq.bits(28) ^ io.enq.bits(29);
|
|
||||||
lfsr_c( 8) := lfsr_q(0) ^ lfsr_q(1) ^ lfsr_q( 3) ^ lfsr_q( 4) ^ lfsr_q( 8) ^ lfsr_q(10) ^ lfsr_q(11) ^ lfsr_q(12) ^ lfsr_q(17) ^ lfsr_q(22) ^ lfsr_q(23) ^ lfsr_q(28) ^ lfsr_q(31) ^ io.enq.bits(0) ^ io.enq.bits(1) ^ io.enq.bits(3) ^ io.enq.bits(4) ^ io.enq.bits(8) ^ io.enq.bits(10) ^ io.enq.bits(11) ^ io.enq.bits(12) ^ io.enq.bits(17) ^ io.enq.bits(22) ^ io.enq.bits(23) ^ io.enq.bits(28) ^ io.enq.bits(31);
|
|
||||||
lfsr_c( 9) := lfsr_q(1) ^ lfsr_q(2) ^ lfsr_q( 4) ^ lfsr_q( 5) ^ lfsr_q( 9) ^ lfsr_q(11) ^ lfsr_q(12) ^ lfsr_q(13) ^ lfsr_q(18) ^ lfsr_q(23) ^ lfsr_q(24) ^ lfsr_q(29) ^ io.enq.bits(1) ^ io.enq.bits(2) ^ io.enq.bits(4) ^ io.enq.bits(5) ^ io.enq.bits(9) ^ io.enq.bits(11) ^ io.enq.bits(12) ^ io.enq.bits(13) ^ io.enq.bits(18) ^ io.enq.bits(23) ^ io.enq.bits(24) ^ io.enq.bits(29);
|
|
||||||
lfsr_c(10) := lfsr_q(0) ^ lfsr_q(2) ^ lfsr_q( 3) ^ lfsr_q( 5) ^ lfsr_q( 9) ^ lfsr_q(13) ^ lfsr_q(14) ^ lfsr_q(16) ^ lfsr_q(19) ^ lfsr_q(26) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(31) ^ io.enq.bits(0) ^ io.enq.bits(2) ^ io.enq.bits(3) ^ io.enq.bits(5) ^ io.enq.bits(9) ^ io.enq.bits(13) ^ io.enq.bits(14) ^ io.enq.bits(16) ^ io.enq.bits(19) ^ io.enq.bits(26) ^ io.enq.bits(28) ^ io.enq.bits(29) ^ io.enq.bits(31);
|
|
||||||
lfsr_c(11) := lfsr_q(0) ^ lfsr_q(1) ^ lfsr_q( 3) ^ lfsr_q( 4) ^ lfsr_q( 9) ^ lfsr_q(12) ^ lfsr_q(14) ^ lfsr_q(15) ^ lfsr_q(16) ^ lfsr_q(17) ^ lfsr_q(20) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(31) ^ io.enq.bits(0) ^ io.enq.bits(1) ^ io.enq.bits(3) ^ io.enq.bits(4) ^ io.enq.bits(9) ^ io.enq.bits(12) ^ io.enq.bits(14) ^ io.enq.bits(15) ^ io.enq.bits(16) ^ io.enq.bits(17) ^ io.enq.bits(20) ^ io.enq.bits(24) ^ io.enq.bits(25) ^ io.enq.bits(26) ^ io.enq.bits(27) ^ io.enq.bits(28) ^ io.enq.bits(31);
|
|
||||||
lfsr_c(12) := lfsr_q(0) ^ lfsr_q(1) ^ lfsr_q( 2) ^ lfsr_q( 4) ^ lfsr_q( 5) ^ lfsr_q( 6) ^ lfsr_q( 9) ^ lfsr_q(12) ^ lfsr_q(13) ^ lfsr_q(15) ^ lfsr_q(17) ^ lfsr_q(18) ^ lfsr_q(21) ^ lfsr_q(24) ^ lfsr_q(27) ^ lfsr_q(30) ^ lfsr_q(31) ^ io.enq.bits(0) ^ io.enq.bits(1) ^ io.enq.bits(2) ^ io.enq.bits(4) ^ io.enq.bits(5) ^ io.enq.bits(6) ^ io.enq.bits(9) ^ io.enq.bits(12) ^ io.enq.bits(13) ^ io.enq.bits(15) ^ io.enq.bits(17) ^ io.enq.bits(18) ^ io.enq.bits(21) ^ io.enq.bits(24) ^ io.enq.bits(27) ^ io.enq.bits(30) ^ io.enq.bits(31);
|
|
||||||
lfsr_c(13) := lfsr_q(1) ^ lfsr_q(2) ^ lfsr_q( 3) ^ lfsr_q( 5) ^ lfsr_q( 6) ^ lfsr_q( 7) ^ lfsr_q(10) ^ lfsr_q(13) ^ lfsr_q(14) ^ lfsr_q(16) ^ lfsr_q(18) ^ lfsr_q(19) ^ lfsr_q(22) ^ lfsr_q(25) ^ lfsr_q(28) ^ lfsr_q(31) ^ io.enq.bits(1) ^ io.enq.bits(2) ^ io.enq.bits(3) ^ io.enq.bits(5) ^ io.enq.bits(6) ^ io.enq.bits(7) ^ io.enq.bits(10) ^ io.enq.bits(13) ^ io.enq.bits(14) ^ io.enq.bits(16) ^ io.enq.bits(18) ^ io.enq.bits(19) ^ io.enq.bits(22) ^ io.enq.bits(25) ^ io.enq.bits(28) ^ io.enq.bits(31);
|
|
||||||
lfsr_c(14) := lfsr_q(2) ^ lfsr_q(3) ^ lfsr_q( 4) ^ lfsr_q( 6) ^ lfsr_q( 7) ^ lfsr_q( 8) ^ lfsr_q(11) ^ lfsr_q(14) ^ lfsr_q(15) ^ lfsr_q(17) ^ lfsr_q(19) ^ lfsr_q(20) ^ lfsr_q(23) ^ lfsr_q(26) ^ lfsr_q(29) ^ io.enq.bits(2) ^ io.enq.bits(3) ^ io.enq.bits(4) ^ io.enq.bits(6) ^ io.enq.bits(7) ^ io.enq.bits(8) ^ io.enq.bits(11) ^ io.enq.bits(14) ^ io.enq.bits(15) ^ io.enq.bits(17) ^ io.enq.bits(19) ^ io.enq.bits(20) ^ io.enq.bits(23) ^ io.enq.bits(26) ^ io.enq.bits(29);
|
|
||||||
lfsr_c(15) := lfsr_q(3) ^ lfsr_q(4) ^ lfsr_q( 5) ^ lfsr_q( 7) ^ lfsr_q( 8) ^ lfsr_q( 9) ^ lfsr_q(12) ^ lfsr_q(15) ^ lfsr_q(16) ^ lfsr_q(18) ^ lfsr_q(20) ^ lfsr_q(21) ^ lfsr_q(24) ^ lfsr_q(27) ^ lfsr_q(30) ^ io.enq.bits(3) ^ io.enq.bits(4) ^ io.enq.bits(5) ^ io.enq.bits(7) ^ io.enq.bits(8) ^ io.enq.bits(9) ^ io.enq.bits(12) ^ io.enq.bits(15) ^ io.enq.bits(16) ^ io.enq.bits(18) ^ io.enq.bits(20) ^ io.enq.bits(21) ^ io.enq.bits(24) ^ io.enq.bits(27) ^ io.enq.bits(30);
|
|
||||||
lfsr_c(16) := lfsr_q(0) ^ lfsr_q(4) ^ lfsr_q( 5) ^ lfsr_q( 8) ^ lfsr_q(12) ^ lfsr_q(13) ^ lfsr_q(17) ^ lfsr_q(19) ^ lfsr_q(21) ^ lfsr_q(22) ^ lfsr_q(24) ^ lfsr_q(26) ^ lfsr_q(29) ^ lfsr_q(30) ^ io.enq.bits(0) ^ io.enq.bits(4) ^ io.enq.bits(5) ^ io.enq.bits(8) ^ io.enq.bits(12) ^ io.enq.bits(13) ^ io.enq.bits(17) ^ io.enq.bits(19) ^ io.enq.bits(21) ^ io.enq.bits(22) ^ io.enq.bits(24) ^ io.enq.bits(26) ^ io.enq.bits(29) ^ io.enq.bits(30);
|
|
||||||
lfsr_c(17) := lfsr_q(1) ^ lfsr_q(5) ^ lfsr_q( 6) ^ lfsr_q( 9) ^ lfsr_q(13) ^ lfsr_q(14) ^ lfsr_q(18) ^ lfsr_q(20) ^ lfsr_q(22) ^ lfsr_q(23) ^ lfsr_q(25) ^ lfsr_q(27) ^ lfsr_q(30) ^ lfsr_q(31) ^ io.enq.bits(1) ^ io.enq.bits(5) ^ io.enq.bits(6) ^ io.enq.bits(9) ^ io.enq.bits(13) ^ io.enq.bits(14) ^ io.enq.bits(18) ^ io.enq.bits(20) ^ io.enq.bits(22) ^ io.enq.bits(23) ^ io.enq.bits(25) ^ io.enq.bits(27) ^ io.enq.bits(30) ^ io.enq.bits(31);
|
|
||||||
lfsr_c(18) := lfsr_q(2) ^ lfsr_q(6) ^ lfsr_q( 7) ^ lfsr_q(10) ^ lfsr_q(14) ^ lfsr_q(15) ^ lfsr_q(19) ^ lfsr_q(21) ^ lfsr_q(23) ^ lfsr_q(24) ^ lfsr_q(26) ^ lfsr_q(28) ^ lfsr_q(31) ^ io.enq.bits(2) ^ io.enq.bits(6) ^ io.enq.bits(7) ^ io.enq.bits(10) ^ io.enq.bits(14) ^ io.enq.bits(15) ^ io.enq.bits(19) ^ io.enq.bits(21) ^ io.enq.bits(23) ^ io.enq.bits(24) ^ io.enq.bits(26) ^ io.enq.bits(28) ^ io.enq.bits(31);
|
|
||||||
lfsr_c(19) := lfsr_q(3) ^ lfsr_q(7) ^ lfsr_q( 8) ^ lfsr_q(11) ^ lfsr_q(15) ^ lfsr_q(16) ^ lfsr_q(20) ^ lfsr_q(22) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(27) ^ lfsr_q(29) ^ io.enq.bits(3) ^ io.enq.bits(7) ^ io.enq.bits(8) ^ io.enq.bits(11) ^ io.enq.bits(15) ^ io.enq.bits(16) ^ io.enq.bits(20) ^ io.enq.bits(22) ^ io.enq.bits(24) ^ io.enq.bits(25) ^ io.enq.bits(27) ^ io.enq.bits(29);
|
|
||||||
lfsr_c(20) := lfsr_q(4) ^ lfsr_q(8) ^ lfsr_q( 9) ^ lfsr_q(12) ^ lfsr_q(16) ^ lfsr_q(17) ^ lfsr_q(21) ^ lfsr_q(23) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(28) ^ lfsr_q(30) ^ io.enq.bits(4) ^ io.enq.bits(8) ^ io.enq.bits(9) ^ io.enq.bits(12) ^ io.enq.bits(16) ^ io.enq.bits(17) ^ io.enq.bits(21) ^ io.enq.bits(23) ^ io.enq.bits(25) ^ io.enq.bits(26) ^ io.enq.bits(28) ^ io.enq.bits(30);
|
|
||||||
lfsr_c(21) := lfsr_q(5) ^ lfsr_q(9) ^ lfsr_q(10) ^ lfsr_q(13) ^ lfsr_q(17) ^ lfsr_q(18) ^ lfsr_q(22) ^ lfsr_q(24) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(29) ^ lfsr_q(31) ^ io.enq.bits(5) ^ io.enq.bits(9) ^ io.enq.bits(10) ^ io.enq.bits(13) ^ io.enq.bits(17) ^ io.enq.bits(18) ^ io.enq.bits(22) ^ io.enq.bits(24) ^ io.enq.bits(26) ^ io.enq.bits(27) ^ io.enq.bits(29) ^ io.enq.bits(31);
|
|
||||||
lfsr_c(22) := lfsr_q(0) ^ lfsr_q(9) ^ lfsr_q(11) ^ lfsr_q(12) ^ lfsr_q(14) ^ lfsr_q(16) ^ lfsr_q(18) ^ lfsr_q(19) ^ lfsr_q(23) ^ lfsr_q(24) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(29) ^ lfsr_q(31) ^ io.enq.bits(0) ^ io.enq.bits(9) ^ io.enq.bits(11) ^ io.enq.bits(12) ^ io.enq.bits(14) ^ io.enq.bits(16) ^ io.enq.bits(18) ^ io.enq.bits(19) ^ io.enq.bits(23) ^ io.enq.bits(24) ^ io.enq.bits(26) ^ io.enq.bits(27) ^ io.enq.bits(29) ^ io.enq.bits(31);
|
|
||||||
lfsr_c(23) := lfsr_q(0) ^ lfsr_q(1) ^ lfsr_q( 6) ^ lfsr_q( 9) ^ lfsr_q(13) ^ lfsr_q(15) ^ lfsr_q(16) ^ lfsr_q(17) ^ lfsr_q(19) ^ lfsr_q(20) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(29) ^ lfsr_q(31) ^ io.enq.bits(0) ^ io.enq.bits(1) ^ io.enq.bits(6) ^ io.enq.bits(9) ^ io.enq.bits(13) ^ io.enq.bits(15) ^ io.enq.bits(16) ^ io.enq.bits(17) ^ io.enq.bits(19) ^ io.enq.bits(20) ^ io.enq.bits(26) ^ io.enq.bits(27) ^ io.enq.bits(29) ^ io.enq.bits(31);
|
|
||||||
lfsr_c(24) := lfsr_q(1) ^ lfsr_q(2) ^ lfsr_q( 7) ^ lfsr_q(10) ^ lfsr_q(14) ^ lfsr_q(16) ^ lfsr_q(17) ^ lfsr_q(18) ^ lfsr_q(20) ^ lfsr_q(21) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(30) ^ io.enq.bits(1) ^ io.enq.bits(2) ^ io.enq.bits(7) ^ io.enq.bits(10) ^ io.enq.bits(14) ^ io.enq.bits(16) ^ io.enq.bits(17) ^ io.enq.bits(18) ^ io.enq.bits(20) ^ io.enq.bits(21) ^ io.enq.bits(27) ^ io.enq.bits(28) ^ io.enq.bits(30);
|
|
||||||
lfsr_c(25) := lfsr_q(2) ^ lfsr_q(3) ^ lfsr_q( 8) ^ lfsr_q(11) ^ lfsr_q(15) ^ lfsr_q(17) ^ lfsr_q(18) ^ lfsr_q(19) ^ lfsr_q(21) ^ lfsr_q(22) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(31) ^ io.enq.bits(2) ^ io.enq.bits(3) ^ io.enq.bits(8) ^ io.enq.bits(11) ^ io.enq.bits(15) ^ io.enq.bits(17) ^ io.enq.bits(18) ^ io.enq.bits(19) ^ io.enq.bits(21) ^ io.enq.bits(22) ^ io.enq.bits(28) ^ io.enq.bits(29) ^ io.enq.bits(31);
|
|
||||||
lfsr_c(26) := lfsr_q(0) ^ lfsr_q(3) ^ lfsr_q( 4) ^ lfsr_q( 6) ^ lfsr_q(10) ^ lfsr_q(18) ^ lfsr_q(19) ^ lfsr_q(20) ^ lfsr_q(22) ^ lfsr_q(23) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(28) ^ lfsr_q(31) ^ io.enq.bits(0) ^ io.enq.bits(3) ^ io.enq.bits(4) ^ io.enq.bits(6) ^ io.enq.bits(10) ^ io.enq.bits(18) ^ io.enq.bits(19) ^ io.enq.bits(20) ^ io.enq.bits(22) ^ io.enq.bits(23) ^ io.enq.bits(24) ^ io.enq.bits(25) ^ io.enq.bits(26) ^ io.enq.bits(28) ^ io.enq.bits(31);
|
|
||||||
lfsr_c(27) := lfsr_q(1) ^ lfsr_q(4) ^ lfsr_q( 5) ^ lfsr_q( 7) ^ lfsr_q(11) ^ lfsr_q(19) ^ lfsr_q(20) ^ lfsr_q(21) ^ lfsr_q(23) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(29) ^ io.enq.bits(1) ^ io.enq.bits(4) ^ io.enq.bits(5) ^ io.enq.bits(7) ^ io.enq.bits(11) ^ io.enq.bits(19) ^ io.enq.bits(20) ^ io.enq.bits(21) ^ io.enq.bits(23) ^ io.enq.bits(24) ^ io.enq.bits(25) ^ io.enq.bits(26) ^ io.enq.bits(27) ^ io.enq.bits(29);
|
|
||||||
lfsr_c(28) := lfsr_q(2) ^ lfsr_q(5) ^ lfsr_q( 6) ^ lfsr_q( 8) ^ lfsr_q(12) ^ lfsr_q(20) ^ lfsr_q(21) ^ lfsr_q(22) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(30) ^ io.enq.bits(2) ^ io.enq.bits(5) ^ io.enq.bits(6) ^ io.enq.bits(8) ^ io.enq.bits(12) ^ io.enq.bits(20) ^ io.enq.bits(21) ^ io.enq.bits(22) ^ io.enq.bits(24) ^ io.enq.bits(25) ^ io.enq.bits(26) ^ io.enq.bits(27) ^ io.enq.bits(28) ^ io.enq.bits(30);
|
|
||||||
lfsr_c(29) := lfsr_q(3) ^ lfsr_q(6) ^ lfsr_q( 7) ^ lfsr_q( 9) ^ lfsr_q(13) ^ lfsr_q(21) ^ lfsr_q(22) ^ lfsr_q(23) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(31) ^ io.enq.bits(3) ^ io.enq.bits(6) ^ io.enq.bits(7) ^ io.enq.bits(9) ^ io.enq.bits(13) ^ io.enq.bits(21) ^ io.enq.bits(22) ^ io.enq.bits(23) ^ io.enq.bits(25) ^ io.enq.bits(26) ^ io.enq.bits(27) ^ io.enq.bits(28) ^ io.enq.bits(29) ^ io.enq.bits(31);
|
|
||||||
lfsr_c(30) := lfsr_q(4) ^ lfsr_q(7) ^ lfsr_q( 8) ^ lfsr_q(10) ^ lfsr_q(14) ^ lfsr_q(22) ^ lfsr_q(23) ^ lfsr_q(24) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(30) ^ io.enq.bits(4) ^ io.enq.bits(7) ^ io.enq.bits(8) ^ io.enq.bits(10) ^ io.enq.bits(14) ^ io.enq.bits(22) ^ io.enq.bits(23) ^ io.enq.bits(24) ^ io.enq.bits(26) ^ io.enq.bits(27) ^ io.enq.bits(28) ^ io.enq.bits(29) ^ io.enq.bits(30);
|
|
||||||
lfsr_c(31) := lfsr_q(5) ^ lfsr_q(8) ^ lfsr_q( 9) ^ lfsr_q(11) ^ lfsr_q(15) ^ lfsr_q(23) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(30) ^ lfsr_q(31) ^ io.enq.bits(5) ^ io.enq.bits(8) ^ io.enq.bits(9) ^ io.enq.bits(11) ^ io.enq.bits(15) ^ io.enq.bits(23) ^ io.enq.bits(24) ^ io.enq.bits(25) ^ io.enq.bits(27) ^ io.enq.bits(28) ^ io.enq.bits(29) ^ io.enq.bits(30) ^ io.enq.bits(31);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ class InterfaceIO extends Bundle{
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
abstract class InterfaceBase extends Module{
|
abstract class InterfaceBase extends Module with RequireAsyncReset{
|
||||||
val io: InterfaceIO = IO(new InterfaceIO)
|
val io: InterfaceIO = IO(new InterfaceIO)
|
||||||
|
|
||||||
val oSpi = Module(new SSpiInterface)
|
val oSpi = Module(new SSpiInterface)
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class MasterParserIO extends Bundle{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class MasterParserBase extends Module{
|
abstract class MasterParserBase extends Module with RequireAsyncReset{
|
||||||
val io: MasterParserIO = IO(new MasterParserIO)
|
val io: MasterParserIO = IO(new MasterParserIO)
|
||||||
|
|
||||||
val txCnt = Reg(UInt(12.W))
|
val txCnt = Reg(UInt(12.W))
|
||||||
@@ -167,11 +167,11 @@ abstract class MasterParserBase extends Module{
|
|||||||
|
|
||||||
txcrc.io.isEnable := io.downOut.fire & txCnt < txLen
|
txcrc.io.isEnable := io.downOut.fire & txCnt < txLen
|
||||||
txcrc.io.dataIn := io.downOut.bits.tdata
|
txcrc.io.dataIn := io.downOut.bits.tdata
|
||||||
txcrc.reset := reset.asBool | reqReady
|
txcrc.io.flush := reqReady
|
||||||
|
|
||||||
rxcrc.io.isEnable := io.upIn.fire & rxCnt < rxLen
|
rxcrc.io.isEnable := io.upIn.fire & rxCnt < rxLen
|
||||||
rxcrc.io.dataIn := io.upIn.bits.tdata
|
rxcrc.io.dataIn := io.upIn.bits.tdata
|
||||||
rxcrc.reset := reset.asBool | io.rsp.fire
|
rxcrc.io.flush := io.rsp.fire
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -33,9 +33,11 @@ class SMUnitIO(depth: Int) extends Bundle {
|
|||||||
val sram = Flipped(Vec(depth, new SRAM2kIO))
|
val sram = Flipped(Vec(depth, new SRAM2kIO))
|
||||||
val cnt = Output(UInt(8.W))
|
val cnt = Output(UInt(8.W))
|
||||||
|
|
||||||
|
val flush = Input(Bool())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class SMUnitBase(depth: Int = 4) extends Module {
|
abstract class SMUnitBase(depth: Int = 4) extends Module with RequireAsyncReset{
|
||||||
val io: SMUnitIO = IO(new SMUnitIO(depth))
|
val io: SMUnitIO = IO(new SMUnitIO(depth))
|
||||||
|
|
||||||
|
|
||||||
@@ -43,18 +45,19 @@ abstract class SMUnitBase(depth: Int = 4) extends Module {
|
|||||||
val rPtr = RegInit(0.U((log2Ceil(depth)+1).W))
|
val rPtr = RegInit(0.U((log2Ceil(depth)+1).W))
|
||||||
|
|
||||||
val isFull = (wPtr ^ rPtr) === (1.U << log2Ceil(depth))
|
val isFull = (wPtr ^ rPtr) === (1.U << log2Ceil(depth))
|
||||||
// ( wPtr.extract(2) =/= rPtr.extract(2) ) & ( wPtr(1,0) === rPtr(1,0) )
|
|
||||||
|
|
||||||
|
|
||||||
val isEmpty = ( wPtr === rPtr )
|
val isEmpty = ( wPtr === rPtr )
|
||||||
|
|
||||||
|
when(io.flush){
|
||||||
when( io.enq & ~isFull ){
|
wPtr := 0.U
|
||||||
|
} .elsewhen( io.enq & ~isFull ){
|
||||||
wPtr := wPtr + 1.U
|
wPtr := wPtr + 1.U
|
||||||
// assert( ~isFull)
|
// assert( ~isFull)
|
||||||
}
|
}
|
||||||
|
|
||||||
when( io.deq & ~isEmpty ){
|
when(io.flush){
|
||||||
|
rPtr := 0.U
|
||||||
|
} .elsewhen( io.deq & ~isEmpty ){
|
||||||
rPtr := rPtr + 1.U
|
rPtr := rPtr + 1.U
|
||||||
// assert( ~isEmpty )
|
// assert( ~isEmpty )
|
||||||
}
|
}
|
||||||
@@ -87,7 +90,9 @@ abstract class SMUnitBase(depth: Int = 4) extends Module {
|
|||||||
|
|
||||||
val cnt = RegInit(0.U((log2Ceil(depth+1)).W)); io.cnt := cnt
|
val cnt = RegInit(0.U((log2Ceil(depth+1)).W)); io.cnt := cnt
|
||||||
|
|
||||||
when( io.enq & ~isFull ){
|
when( io.flush ){
|
||||||
|
cnt := 0.U
|
||||||
|
} .elsewhen( io.enq & ~isFull ){
|
||||||
cnt := cnt + 1.U
|
cnt := cnt + 1.U
|
||||||
assert(cnt =/= depth.U)
|
assert(cnt =/= depth.U)
|
||||||
} .elsewhen( io.deq & ~isEmpty ){
|
} .elsewhen( io.deq & ~isEmpty ){
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class ShinTopIO extends Bundle{
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
abstract class ShinTopBase extends Module{
|
abstract class ShinTopBase extends Module with RequireAsyncReset{
|
||||||
|
|
||||||
val io: ShinTopIO = IO(new ShinTopIO)
|
val io: ShinTopIO = IO(new ShinTopIO)
|
||||||
|
|
||||||
@@ -160,7 +160,7 @@ abstract class ShinTopBase extends Module{
|
|||||||
|
|
||||||
for( i <- 0 until 8 ){
|
for( i <- 0 until 8 ){
|
||||||
interface.io.smUsedDepth(i) := smUnit(i).io.cnt
|
interface.io.smUsedDepth(i) := smUnit(i).io.cnt
|
||||||
smUnit(i).reset := reset.asBool | interface.io.isSMReset(i)
|
smUnit(i).io.flush := interface.io.isSMReset(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -380,10 +380,10 @@ trait ShinTopSlave{ this: ShinTopBase =>
|
|||||||
|
|
||||||
slaveParser.io.intHWClr(0) := interface.io.intHWTrig(0) & interface.io.intHWClr(0)
|
slaveParser.io.intHWClr(0) := interface.io.intHWTrig(0) & interface.io.intHWClr(0)
|
||||||
slaveParser.io.intHWClr(1) := interface.io.intHWTrig(1) & interface.io.intHWClr(1)
|
slaveParser.io.intHWClr(1) := interface.io.intHWTrig(1) & interface.io.intHWClr(1)
|
||||||
downCDRIn.reset := reset.asBool | RegNext( interface.io.intHWTrig(0) & interface.io.intHWClr(0) )
|
downCDRIn.io.flush := RegNext( interface.io.intHWTrig(0) & interface.io.intHWClr(0) )
|
||||||
upCDRIn.reset := reset.asBool | RegNext( interface.io.intHWTrig(1) & interface.io.intHWClr(1) )
|
upCDRIn.io.flush := RegNext( interface.io.intHWTrig(1) & interface.io.intHWClr(1) )
|
||||||
downCDROut.reset := reset.asBool | RegNext( interface.io.intHWTrig(0) & interface.io.intHWClr(0) )
|
downCDROut.io.flush := RegNext( interface.io.intHWTrig(0) & interface.io.intHWClr(0) )
|
||||||
upCDROut.reset := reset.asBool | RegNext( interface.io.intHWTrig(1) & interface.io.intHWClr(1) )
|
upCDROut.io.flush := RegNext( interface.io.intHWTrig(1) & interface.io.intHWClr(1) )
|
||||||
|
|
||||||
interface.io.lvds <> slaveParser.io.lvds
|
interface.io.lvds <> slaveParser.io.lvds
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ class SlaveParserIO extends Bundle{
|
|||||||
val upRecStat = Output(new Stat_IO_Bundle)
|
val upRecStat = Output(new Stat_IO_Bundle)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class SlaveParserBase extends Module{
|
abstract class SlaveParserBase extends Module with RequireAsyncReset{
|
||||||
val io: SlaveParserIO = IO(new SlaveParserIO)
|
val io: SlaveParserIO = IO(new SlaveParserIO)
|
||||||
|
|
||||||
val sReg = io.sReg
|
val sReg = io.sReg
|
||||||
@@ -991,11 +991,11 @@ with SlaveParserProbe{
|
|||||||
io.intHWTrig(0) := downRecParser.io.isError
|
io.intHWTrig(0) := downRecParser.io.isError
|
||||||
io.intHWTrig(1) := upRecParser.io.isError
|
io.intHWTrig(1) := upRecParser.io.isError
|
||||||
|
|
||||||
downRecParser.reset := reset.asBool | RegNext(downRecParser.io.isError & io.intHWClr(0))
|
downRecParser.io.flush := RegNext(downRecParser.io.isError & io.intHWClr(0))
|
||||||
downSendGen.reset := reset.asBool | RegNext(downRecParser.io.isError & io.intHWClr(0))
|
downSendGen.io.flush := RegNext(downRecParser.io.isError & io.intHWClr(0))
|
||||||
|
|
||||||
upRecParser.reset := reset.asBool | RegNext(upRecParser.io.isError & io.intHWClr(1))
|
upRecParser.io.flush := RegNext(upRecParser.io.isError & io.intHWClr(1))
|
||||||
upSendGen.reset := reset.asBool | RegNext(upRecParser.io.isError & io.intHWClr(1))
|
upSendGen.io.flush := RegNext(upRecParser.io.isError & io.intHWClr(1))
|
||||||
|
|
||||||
io.downRecStat := downRecParser.io.stat
|
io.downRecStat := downRecParser.io.stat
|
||||||
io.upRecStat := upRecParser.io.stat
|
io.upRecStat := upRecParser.io.stat
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ class SlaveRecParserIO extends Bundle{
|
|||||||
|
|
||||||
val stat = Output(new Stat_IO_Bundle)
|
val stat = Output(new Stat_IO_Bundle)
|
||||||
|
|
||||||
|
val flush = Input(Bool())
|
||||||
}
|
}
|
||||||
|
|
||||||
class SlaveRecParser extends Module{
|
class SlaveRecParser extends Module with RequireAsyncReset{
|
||||||
val io: SlaveRecParserIO = IO(new SlaveRecParserIO)
|
val io: SlaveRecParserIO = IO(new SlaveRecParserIO)
|
||||||
|
|
||||||
val crc = Module(new crc32_8)
|
val crc = Module(new crc32_8)
|
||||||
@@ -53,7 +53,7 @@ class SlaveRecParser extends Module{
|
|||||||
|
|
||||||
crc.io.dataIn := io.rec.bits.tdata
|
crc.io.dataIn := io.rec.bits.tdata
|
||||||
|
|
||||||
crc.reset := reset.asBool | stateCurr === STATE_IDLE
|
crc.io.flush := stateCurr === STATE_IDLE | io.flush
|
||||||
|
|
||||||
val crcData = Reg(UInt(32.W))
|
val crcData = Reg(UInt(32.W))
|
||||||
val isCrcPass = crc.io.crc === Cat( crcData(23,0), io.rec.bits.tdata )
|
val isCrcPass = crc.io.crc === Cat( crcData(23,0), io.rec.bits.tdata )
|
||||||
@@ -96,7 +96,9 @@ class SlaveRecParser extends Module{
|
|||||||
|
|
||||||
io.subMsgTailReq.bits.workCnt := subMsgTail.workCnt | io.rec.bits.tdata(7,0)
|
io.subMsgTailReq.bits.workCnt := subMsgTail.workCnt | io.rec.bits.tdata(7,0)
|
||||||
|
|
||||||
when( io.rec.fire ){
|
when( io.flush ){
|
||||||
|
lengthCnt := 0.U
|
||||||
|
} .elsewhen( io.rec.fire ){
|
||||||
when( stateCurr =/= stateNext ){
|
when( stateCurr =/= stateNext ){
|
||||||
lengthCnt := 0.U
|
lengthCnt := 0.U
|
||||||
} .otherwise{
|
} .otherwise{
|
||||||
@@ -177,6 +179,7 @@ class SlaveRecParser extends Module{
|
|||||||
|
|
||||||
|
|
||||||
stateNext :=
|
stateNext :=
|
||||||
|
Mux( io.flush, STATE_IDLE,
|
||||||
Mux1H(Seq(
|
Mux1H(Seq(
|
||||||
//必须使用上升沿触发,以避免前一帧长度超过预期
|
//必须使用上升沿触发,以避免前一帧长度超过预期
|
||||||
( stateCurr === STATE_IDLE ) -> Mux( ~RegNext(io.rec.valid) & io.rec.valid, STATE_HEADER, STATE_IDLE ),
|
( stateCurr === STATE_IDLE ) -> Mux( ~RegNext(io.rec.valid) & io.rec.valid, STATE_HEADER, STATE_IDLE ),
|
||||||
@@ -207,6 +210,7 @@ class SlaveRecParser extends Module{
|
|||||||
),
|
),
|
||||||
( stateCurr === STATE_ERROR ) -> STATE_ERROR,
|
( stateCurr === STATE_ERROR ) -> STATE_ERROR,
|
||||||
))
|
))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,12 +22,14 @@ class SlaveSendGenIO extends Bundle{
|
|||||||
|
|
||||||
val isError = Output(Bool())
|
val isError = Output(Bool())
|
||||||
val stateCurr = Output(UInt(3.W))
|
val stateCurr = Output(UInt(3.W))
|
||||||
|
|
||||||
|
val flush = Input(Bool())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SlaveSendGen extends Module{
|
class SlaveSendGen extends Module with RequireAsyncReset{
|
||||||
val io: SlaveSendGenIO = IO(new SlaveSendGenIO)
|
val io: SlaveSendGenIO = IO(new SlaveSendGenIO)
|
||||||
|
|
||||||
|
|
||||||
@@ -60,7 +62,7 @@ class SlaveSendGen extends Module{
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
crc.reset := reset.asBool | stateCurr === STATE_IDLE
|
crc.io.flush := stateCurr === STATE_IDLE | io.flush
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -112,7 +114,9 @@ class SlaveSendGen extends Module{
|
|||||||
assert( ~(io.subMsgTailReq.ready & ~io.subMsgTailReq.valid) )
|
assert( ~(io.subMsgTailReq.ready & ~io.subMsgTailReq.valid) )
|
||||||
|
|
||||||
|
|
||||||
stateNext := Mux1H(Seq(
|
stateNext :=
|
||||||
|
Mux( io.flush, STATE_IDLE,
|
||||||
|
Mux1H(Seq(
|
||||||
(stateCurr === STATE_IDLE) -> Mux( io.frameReq.fire, STATE_FRAME_HEADER, STATE_IDLE ),
|
(stateCurr === STATE_IDLE) -> Mux( io.frameReq.fire, STATE_FRAME_HEADER, STATE_IDLE ),
|
||||||
(stateCurr === STATE_FRAME_HEADER) -> Mux( io.send.fire, Mux( lengthCnt === (4-1).U, Mux(
|
(stateCurr === STATE_FRAME_HEADER) -> Mux( io.send.fire, Mux( lengthCnt === (4-1).U, Mux(
|
||||||
frameInfo.frameStyle === FRAME_STYLE_COMMON,
|
frameInfo.frameStyle === FRAME_STYLE_COMMON,
|
||||||
@@ -136,6 +140,7 @@ class SlaveSendGen extends Module{
|
|||||||
// (stateCurr === STATE_ERROR) -> Mux( io.send.fire, STATE_IDLE, STATE_ERROR),
|
// (stateCurr === STATE_ERROR) -> Mux( io.send.fire, STATE_IDLE, STATE_ERROR),
|
||||||
(stateCurr === STATE_WAIT) -> Mux( io.subMsgHeadReq.valid, STATE_SUBMSG_HEADER, STATE_WAIT),
|
(stateCurr === STATE_WAIT) -> Mux( io.subMsgHeadReq.valid, STATE_SUBMSG_HEADER, STATE_WAIT),
|
||||||
))
|
))
|
||||||
|
)
|
||||||
|
|
||||||
io.data(0).ready := io.send.fire & (stateCurr === STATE_SUBMSG_DATA) & (subMsgHeadInfo.source === 0.U)
|
io.data(0).ready := io.send.fire & (stateCurr === STATE_SUBMSG_DATA) & (subMsgHeadInfo.source === 0.U)
|
||||||
io.data(1).ready := io.send.fire & (stateCurr === STATE_SUBMSG_DATA) & (subMsgHeadInfo.source === 1.U)
|
io.data(1).ready := io.send.fire & (stateCurr === STATE_SUBMSG_DATA) & (subMsgHeadInfo.source === 1.U)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class RegAccessInterfaceIO extends Bundle{
|
|||||||
val isEnR = Output(Bool())
|
val isEnR = Output(Bool())
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class SpiInterfaceBase extends Module{
|
abstract class SpiInterfaceBase extends Module with RequireAsyncReset{
|
||||||
val io = IO(new RegAccessInterfaceIO)
|
val io = IO(new RegAccessInterfaceIO)
|
||||||
|
|
||||||
val sck = Wire(Bool())
|
val sck = Wire(Bool())
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
package test
|
package test
|
||||||
|
|
||||||
import MAC._
|
|
||||||
import BACK._
|
import BACK._
|
||||||
import Switch._
|
|
||||||
|
|
||||||
import chisel3._
|
import chisel3._
|
||||||
import chisel3.stage._
|
import chisel3.stage._
|
||||||
import freechips.rocketchip.diplomacy._
|
|
||||||
|
|
||||||
import org.chipsalliance.cde.config._
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user