pass tx rx status ctrl
This commit is contained in:
1278
project/.bloop/riscv-mac-swich-build.json
Normal file
1278
project/.bloop/riscv-mac-swich-build.json
Normal file
File diff suppressed because it is too large
Load Diff
6
project/metals.sbt
Normal file
6
project/metals.sbt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
// DO NOT EDIT! This file is auto-generated.
|
||||||
|
|
||||||
|
// This file enables sbt-bloop to create bloop config files.
|
||||||
|
|
||||||
|
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.6")
|
||||||
|
|
||||||
1279
project/project/.bloop/riscv-mac-swich-build-build.json
Normal file
1279
project/project/.bloop/riscv-mac-swich-build-build.json
Normal file
File diff suppressed because it is too large
Load Diff
6
project/project/metals.sbt
Normal file
6
project/project/metals.sbt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
// DO NOT EDIT! This file is auto-generated.
|
||||||
|
|
||||||
|
// This file enables sbt-bloop to create bloop config files.
|
||||||
|
|
||||||
|
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.6")
|
||||||
|
|
||||||
6
project/project/project/metals.sbt
Normal file
6
project/project/project/metals.sbt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
// DO NOT EDIT! This file is auto-generated.
|
||||||
|
|
||||||
|
// This file enables sbt-bloop to create bloop config files.
|
||||||
|
|
||||||
|
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.6")
|
||||||
|
|
||||||
447
src/main/scala/mac/MacControl.scala
Normal file
447
src/main/scala/mac/MacControl.scala
Normal file
@@ -0,0 +1,447 @@
|
|||||||
|
package MAC
|
||||||
|
|
||||||
|
import chisel3._
|
||||||
|
import chisel3.util._
|
||||||
|
|
||||||
|
class MacControlIO extends Bundle{
|
||||||
|
val MTxClk = Input(Bool()) // Transmit clock (from PHY)
|
||||||
|
val MRxClk = Input(Bool()) // Receive clock (from PHY)
|
||||||
|
val TxReset = Input(Bool()) // Transmit reset
|
||||||
|
val RxReset = Input(Bool()) // Receive reset
|
||||||
|
val TPauseRq = Input(Bool()) // Transmit control frame (from host)
|
||||||
|
val TxDataIn = Input(UInt(8.W)) // Transmit packet data byte (from host)
|
||||||
|
val TxStartFrmIn = Input(Bool()) // Transmit packet start frame input (from host)
|
||||||
|
val TxUsedDataIn = Input(Bool()) // Transmit packet used data (from TxEthMAC)
|
||||||
|
val TxEndFrmIn = Input(Bool()) // Transmit packet end frame input (from host)
|
||||||
|
val TxDoneIn = Input(Bool()) // Transmit packet done (from TxEthMAC)
|
||||||
|
val TxAbortIn = Input(Bool()) // Transmit packet abort (input from TxEthMAC)
|
||||||
|
val PadIn = Input(Bool()) // Padding (input from registers)
|
||||||
|
val CrcEnIn = Input(Bool()) // Crc append (input from registers)
|
||||||
|
val RxData = Input(UInt(8.W)) // Receive Packet Data (from RxEthMAC)
|
||||||
|
val RxValid = Input(Bool()) // Received a valid packet
|
||||||
|
val RxStartFrm = Input(Bool()) // Receive packet start frame (input from RxEthMAC)
|
||||||
|
val RxEndFrm = Input(Bool()) // Receive packet end frame (input from RxEthMAC)
|
||||||
|
val ReceiveEnd = Input(Bool()) // End of receiving of the current packet (input from RxEthMAC)
|
||||||
|
val ReceivedPacketGood = Input(Bool()) // Received packet is good
|
||||||
|
val ReceivedLengthOK = Input(Bool()) // Length of the received packet is OK
|
||||||
|
val TxFlow = Input(Bool()) // Tx flow control (from registers)
|
||||||
|
val RxFlow = Input(Bool()) // Rx flow control (from registers)
|
||||||
|
val DlyCrcEn = Input(Bool()) // Delayed CRC enabled (from registers)
|
||||||
|
val TxPauseTV = Input(UInt(16.W)) // Transmit Pause Timer Value (from registers)
|
||||||
|
val MAC = Input(UInt(48.W)) // MAC address (from registers)
|
||||||
|
val RxStatusWriteLatched_sync2 = Input(Bool())
|
||||||
|
val r_PassAll = Input(Bool())
|
||||||
|
|
||||||
|
val TxDataOut = Output(UInt(8.W)) // Transmit Packet Data (to TxEthMAC)
|
||||||
|
val TxStartFrmOut = Output(Bool()) // Transmit packet start frame (output to TxEthMAC)
|
||||||
|
val TxEndFrmOut = Output(Bool()) // Transmit packet end frame (output to TxEthMAC)
|
||||||
|
val TxDoneOut = Output(Bool()) // Transmit packet done (to host)
|
||||||
|
val TxAbortOut = Output(Bool()) // Transmit packet aborted (to host)
|
||||||
|
val TxUsedDataOut = Output(Bool()) // Transmit packet used data (to host)
|
||||||
|
val PadOut = Output(Bool()) // Padding (output to TxEthMAC)
|
||||||
|
val CrcEnOut = Output(Bool()) // Crc append (output to TxEthMAC)
|
||||||
|
val WillSendControlFrame = Output(Bool())
|
||||||
|
val TxCtrlEndFrm = Output(Bool())
|
||||||
|
val ReceivedPauseFrm = Output(Bool())
|
||||||
|
val ControlFrmAddressOK = Output(Bool())
|
||||||
|
val SetPauseTimer = Output(Bool())
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class MacControl extends RawModule{
|
||||||
|
val io: MacControlIO = IO(new MacControlIO)
|
||||||
|
|
||||||
|
val Pause_wire = Wire(Bool())
|
||||||
|
|
||||||
|
val SlotFinished = Wire(Bool())
|
||||||
|
|
||||||
|
// Reserved multicast address and Type/Length for PAUSE control
|
||||||
|
val ReservedMulticast = "h0180C2000001".U(48.W)
|
||||||
|
val TypeLength = "h8808".U(16.W)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
val DecrementPauseTimer = Wire(Bool())
|
||||||
|
val PauseTimerEq0 = Wire(Bool())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
val ControlEnd = Wire(Bool())
|
||||||
|
|
||||||
|
val MuxedCtrlData = Wire(UInt(8.W))
|
||||||
|
val EnableCnt = Wire(Bool())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
withClockAndReset( io.MTxClk.asClock, io.TxReset ) {
|
||||||
|
val BlockTxDone = RegInit(false.B)
|
||||||
|
val SendingCtrlFrm = RegInit(false.B) // Sending Control Frame (enables padding and CRC)
|
||||||
|
val CtrlMux = RegInit(false.B)
|
||||||
|
val ControlData = RegInit(0.U(8.W))
|
||||||
|
val TxCtrlStartFrm = RegInit(false.B)
|
||||||
|
|
||||||
|
val DlyCrcCnt = RegInit(0.U(4.W))
|
||||||
|
val ByteCnt = RegInit(0.U(6.W))
|
||||||
|
val ControlEnd_q = RegNext(ControlEnd)
|
||||||
|
|
||||||
|
val TxCtrlStartFrm_q = RegNext(TxCtrlStartFrm)
|
||||||
|
val TxCtrlEndFrm = RegNext(ControlEnd | ControlEnd_q, false.B); io.TxCtrlEndFrm := TxCtrlEndFrm // Generation of the transmit control packet end frame
|
||||||
|
val TxUsedDataIn_q = RegNext(io.TxUsedDataIn, false.B)
|
||||||
|
|
||||||
|
val WillSendControlFrame = RegInit(false.B); io.WillSendControlFrame := WillSendControlFrame // A command for Sending the control frame is active (latched)
|
||||||
|
|
||||||
|
val TxUsedDataOutDetected = RegInit(false.B)
|
||||||
|
|
||||||
|
// Synchronization of the pause timer
|
||||||
|
val PauseTimerEq0_sync1 = RegNext(PauseTimerEq0, true.B)
|
||||||
|
val PauseTimerEq0_sync2 = RegNext(PauseTimerEq0_sync1, true.B)
|
||||||
|
|
||||||
|
val Pause = RegInit(false.B); Pause_wire := Pause // Pause signal generation
|
||||||
|
|
||||||
|
|
||||||
|
when((io.TxDoneIn | io.TxAbortIn | ~TxUsedDataOutDetected) & ~io.TxStartFrmOut){
|
||||||
|
Pause := io.RxFlow & ~PauseTimerEq0_sync2
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signal TxUsedDataOut was detected (a transfer is already in progress)
|
||||||
|
when(io.TxDoneIn | io.TxAbortIn){
|
||||||
|
TxUsedDataOutDetected := false.B
|
||||||
|
} .elsewhen(io.TxUsedDataOut){
|
||||||
|
TxUsedDataOutDetected := true.B
|
||||||
|
}
|
||||||
|
|
||||||
|
// Latching variables
|
||||||
|
val TxAbortInLatched = RegNext(io.TxAbortIn, false.B)
|
||||||
|
val TxDoneInLatched = RegNext(io.TxDoneIn, false.B)
|
||||||
|
|
||||||
|
|
||||||
|
val MuxedAbort = RegInit(false.B) // Generating muxed abort signal
|
||||||
|
|
||||||
|
when(io.TxStartFrmIn){
|
||||||
|
MuxedAbort := false.B
|
||||||
|
} .elsewhen(io.TxAbortIn & ~TxAbortInLatched & TxUsedDataOutDetected){
|
||||||
|
MuxedAbort := true.B
|
||||||
|
}
|
||||||
|
|
||||||
|
val MuxedDone = RegInit(false.B) // Generating muxed done signal
|
||||||
|
|
||||||
|
when(io.TxStartFrmIn){
|
||||||
|
MuxedDone := false.B
|
||||||
|
} .elsewhen(io.TxDoneIn & (~TxDoneInLatched) & TxUsedDataOutDetected){
|
||||||
|
MuxedDone := true.B
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
when(TxCtrlEndFrm & CtrlMux){
|
||||||
|
WillSendControlFrame := false.B
|
||||||
|
} .elsewhen(io.TPauseRq & io.TxFlow){
|
||||||
|
WillSendControlFrame := true.B
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Generation of the transmit control packet start frame
|
||||||
|
when(TxUsedDataIn_q & CtrlMux){
|
||||||
|
TxCtrlStartFrm := false.B
|
||||||
|
} .elsewhen(WillSendControlFrame & ~io.TxUsedDataOut & (io.TxDoneIn | io.TxAbortIn | io.TxStartFrmIn | (~TxUsedDataOutDetected))){
|
||||||
|
TxCtrlStartFrm := true.B
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generation of the multiplexer signal (controls muxes for switching between
|
||||||
|
// normal and control packets)
|
||||||
|
when(WillSendControlFrame & ~io.TxUsedDataOut){
|
||||||
|
CtrlMux := true.B
|
||||||
|
} .elsewhen(io.TxDoneIn){
|
||||||
|
CtrlMux := false.B
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generation of the Sending Control Frame signal (enables padding and CRC)
|
||||||
|
when(WillSendControlFrame & TxCtrlStartFrm){
|
||||||
|
SendingCtrlFrm := true.B
|
||||||
|
} .elsewhen(io.TxDoneIn){
|
||||||
|
SendingCtrlFrm := false.B
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generation of the signal that will block sending the Done signal to the eth_wishbone module
|
||||||
|
// While sending the control frame
|
||||||
|
when(TxCtrlStartFrm){
|
||||||
|
BlockTxDone := true.B
|
||||||
|
} .elsewhen(io.TxStartFrmIn){
|
||||||
|
BlockTxDone := false.B
|
||||||
|
}
|
||||||
|
|
||||||
|
val IncrementDlyCrcCnt = CtrlMux & io.TxUsedDataIn & ~DlyCrcCnt.extract(2)
|
||||||
|
val ResetByteCnt = io.TxReset | (~TxCtrlStartFrm & (io.TxDoneIn | io.TxAbortIn))
|
||||||
|
|
||||||
|
// Delayed CRC counter
|
||||||
|
when(ResetByteCnt){
|
||||||
|
DlyCrcCnt := 0.U
|
||||||
|
} .elsewhen(IncrementDlyCrcCnt){
|
||||||
|
DlyCrcCnt := DlyCrcCnt + 1.U
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val IncrementByteCnt = CtrlMux & (TxCtrlStartFrm & ~TxCtrlStartFrm_q & ~io.TxUsedDataIn | io.TxUsedDataIn & ~ControlEnd)
|
||||||
|
val IncrementByteCntBy2 = CtrlMux & TxCtrlStartFrm & (~TxCtrlStartFrm_q) & io.TxUsedDataIn // When TxUsedDataIn and CtrlMux are set at the same time
|
||||||
|
|
||||||
|
EnableCnt := (~io.DlyCrcEn | io.DlyCrcEn & (DlyCrcCnt(1,0).andR))
|
||||||
|
|
||||||
|
|
||||||
|
// Byte counter
|
||||||
|
when(ResetByteCnt){
|
||||||
|
ByteCnt := 0.U
|
||||||
|
} .elsewhen(IncrementByteCntBy2 & EnableCnt){
|
||||||
|
ByteCnt := ByteCnt + 2.U
|
||||||
|
} .elsewhen(IncrementByteCnt & EnableCnt){
|
||||||
|
ByteCnt := ByteCnt + 1.U
|
||||||
|
}
|
||||||
|
|
||||||
|
ControlEnd := ByteCnt === "h22".U
|
||||||
|
|
||||||
|
MuxedCtrlData := // Control data generation (goes to the TxEthMAC module)
|
||||||
|
Mux1H(Seq(
|
||||||
|
(ByteCnt === 0.U) -> Mux(~io.DlyCrcEn | io.DlyCrcEn & (DlyCrcCnt(1,0).andR), 1.U, 0.U),
|
||||||
|
(ByteCnt === 2.U) -> "h80".U,
|
||||||
|
(ByteCnt === 4.U) -> "hC2".U,
|
||||||
|
(ByteCnt === 6.U) -> "h00".U,
|
||||||
|
(ByteCnt === 8.U) -> "h00".U,
|
||||||
|
(ByteCnt === 10.U) -> "h01".U,
|
||||||
|
(ByteCnt === 12.U) -> io.MAC(47,40),
|
||||||
|
(ByteCnt === 14.U) -> io.MAC(39,32),
|
||||||
|
(ByteCnt === 16.U) -> io.MAC(31,24),
|
||||||
|
(ByteCnt === 18.U) -> io.MAC(23,16),
|
||||||
|
(ByteCnt === 20.U) -> io.MAC(15, 8),
|
||||||
|
(ByteCnt === 22.U) -> io.MAC( 7, 0),
|
||||||
|
(ByteCnt === 24.U) -> "h88".U, // Type/Length
|
||||||
|
(ByteCnt === 26.U) -> "h08".U,
|
||||||
|
(ByteCnt === 28.U) -> "h00".U, // Opcode
|
||||||
|
(ByteCnt === 30.U) -> "h01".U,
|
||||||
|
(ByteCnt === 32.U) -> io.TxPauseTV(15,8), // Pause timer value
|
||||||
|
(ByteCnt === 34.U) -> io.TxPauseTV( 7,0),
|
||||||
|
))
|
||||||
|
|
||||||
|
// Latched Control data
|
||||||
|
when(~ByteCnt.extract(0)){
|
||||||
|
ControlData := MuxedCtrlData
|
||||||
|
}
|
||||||
|
|
||||||
|
io.TxDoneOut := Mux(CtrlMux, ((~io.TxStartFrmIn) & (~BlockTxDone) & MuxedDone), ((~io.TxStartFrmIn) & (~BlockTxDone) & io.TxDoneIn)) // TxDoneOut
|
||||||
|
io.TxAbortOut := Mux(CtrlMux, ((~io.TxStartFrmIn) & (~BlockTxDone) & MuxedAbort), ((~io.TxStartFrmIn) & (~BlockTxDone) & io.TxAbortIn)) // TxAbortOut
|
||||||
|
io.TxUsedDataOut := ~CtrlMux & io.TxUsedDataIn // TxUsedDataOut
|
||||||
|
io.TxStartFrmOut := Mux(CtrlMux, TxCtrlStartFrm, (io.TxStartFrmIn & ~Pause)) // TxStartFrmOut
|
||||||
|
io.TxEndFrmOut := Mux(CtrlMux, TxCtrlEndFrm, io.TxEndFrmIn) // TxEndFrmOut
|
||||||
|
io.TxDataOut := Mux(CtrlMux, ControlData, io.TxDataIn ) // TxDataOut[7:0]
|
||||||
|
io.PadOut := io.PadIn | SendingCtrlFrm // PadOut
|
||||||
|
io.CrcEnOut := io.CrcEnIn | SendingCtrlFrm // CrcEnOut
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
withClockAndReset( io.MRxClk.asClock, io.RxReset ) {
|
||||||
|
val AddressOK = RegInit(false.B); io.ControlFrmAddressOK := AddressOK // Multicast or unicast address detected
|
||||||
|
val TypeLengthOK = RegInit(false.B) // Type/Length field contains 0x8808
|
||||||
|
val DetectionWindow = RegInit(true.B) // Detection of the PAUSE frame is possible within this window
|
||||||
|
val OpCodeOK = RegInit(false.B) // PAUSE opcode detected (0x0001)
|
||||||
|
val DlyCrcCnt = RegInit(0.U(3.W))
|
||||||
|
val ByteCnt = RegInit(0.U(5.W))
|
||||||
|
val AssembledTimerValue = RegInit(0.U(16.W))
|
||||||
|
val LatchedTimerValue = RegInit(0.U(16.W))
|
||||||
|
val ReceivedPauseFrmWAddr = RegInit(false.B)
|
||||||
|
val PauseTimer = RegInit(0.U(16.W))
|
||||||
|
|
||||||
|
val ByteCntEq0 = io.RxValid & ByteCnt === "h0".U
|
||||||
|
val ByteCntEq1 = io.RxValid & ByteCnt === "h1".U
|
||||||
|
val ByteCntEq2 = io.RxValid & ByteCnt === "h2".U
|
||||||
|
val ByteCntEq3 = io.RxValid & ByteCnt === "h3".U
|
||||||
|
val ByteCntEq4 = io.RxValid & ByteCnt === "h4".U
|
||||||
|
val ByteCntEq5 = io.RxValid & ByteCnt === "h5".U
|
||||||
|
val ByteCntEq12 = io.RxValid & ByteCnt === "h0C".U
|
||||||
|
val ByteCntEq13 = io.RxValid & ByteCnt === "h0D".U
|
||||||
|
val ByteCntEq14 = io.RxValid & ByteCnt === "h0E".U
|
||||||
|
val ByteCntEq15 = io.RxValid & ByteCnt === "h0F".U
|
||||||
|
val ByteCntEq16 = io.RxValid & ByteCnt === "h10".U
|
||||||
|
val ByteCntEq17 = io.RxValid & ByteCnt === "h11".U
|
||||||
|
val ByteCntEq18 = io.RxValid & ByteCnt === "h12".U & DetectionWindow
|
||||||
|
|
||||||
|
// Address Detection (Multicast or unicast)
|
||||||
|
when(DetectionWindow & ByteCntEq0){
|
||||||
|
AddressOK := io.RxData === ReservedMulticast(47,40) | io.RxData === io.MAC(47,40)
|
||||||
|
} .elsewhen(DetectionWindow & ByteCntEq1){
|
||||||
|
AddressOK := (io.RxData === ReservedMulticast(39,32) | io.RxData === io.MAC(39,32)) & AddressOK;
|
||||||
|
} .elsewhen(DetectionWindow & ByteCntEq2){
|
||||||
|
AddressOK := (io.RxData === ReservedMulticast(31,24) | io.RxData === io.MAC(31,24)) & AddressOK;
|
||||||
|
} .elsewhen(DetectionWindow & ByteCntEq3){
|
||||||
|
AddressOK := (io.RxData === ReservedMulticast(23,16) | io.RxData === io.MAC(23,16)) & AddressOK;
|
||||||
|
} .elsewhen(DetectionWindow & ByteCntEq4){
|
||||||
|
AddressOK := (io.RxData === ReservedMulticast(15,8) | io.RxData === io.MAC(15,8)) & AddressOK;
|
||||||
|
} .elsewhen(DetectionWindow & ByteCntEq5){
|
||||||
|
AddressOK := (io.RxData === ReservedMulticast(7,0) | io.RxData === io.MAC(7,0)) & AddressOK;
|
||||||
|
} .elsewhen(io.ReceiveEnd){
|
||||||
|
AddressOK := false.B
|
||||||
|
}
|
||||||
|
|
||||||
|
// TypeLengthOK (Type/Length Control frame detected)
|
||||||
|
when(DetectionWindow & ByteCntEq12){
|
||||||
|
TypeLengthOK := ByteCntEq12 & (io.RxData === TypeLength(15,8));
|
||||||
|
} .elsewhen(DetectionWindow & ByteCntEq13){
|
||||||
|
TypeLengthOK := ByteCntEq13 & (io.RxData === TypeLength(7,0)) & TypeLengthOK;
|
||||||
|
} .elsewhen(io.ReceiveEnd){
|
||||||
|
TypeLengthOK := false.B
|
||||||
|
}
|
||||||
|
|
||||||
|
// Latch Control Frame Opcode
|
||||||
|
|
||||||
|
when(ByteCntEq16){
|
||||||
|
OpCodeOK := false.B
|
||||||
|
} .otherwise{
|
||||||
|
when(DetectionWindow & ByteCntEq14){
|
||||||
|
OpCodeOK := ByteCntEq14 & io.RxData === 0.U
|
||||||
|
}
|
||||||
|
when(DetectionWindow & ByteCntEq15){
|
||||||
|
OpCodeOK := ByteCntEq15 & io.RxData === 1.U & OpCodeOK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReceivedPauseFrmWAddr (+Address Check)
|
||||||
|
when(io.ReceiveEnd){
|
||||||
|
ReceivedPauseFrmWAddr := false.B
|
||||||
|
} .elsewhen(ByteCntEq16 & TypeLengthOK & OpCodeOK & AddressOK){
|
||||||
|
ReceivedPauseFrmWAddr := true.B
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assembling 16-bit timer value from two 8-bit data
|
||||||
|
when(io.RxStartFrm){
|
||||||
|
AssembledTimerValue := 0.U
|
||||||
|
} .otherwise{
|
||||||
|
when(DetectionWindow & ByteCntEq16){
|
||||||
|
AssembledTimerValue := Cat(io.RxData, AssembledTimerValue(7,0))
|
||||||
|
}
|
||||||
|
when(DetectionWindow & ByteCntEq17){
|
||||||
|
AssembledTimerValue := Cat(AssembledTimerValue(15,8), io.RxData )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detection window (while PAUSE detection is possible)
|
||||||
|
when(ByteCntEq18){
|
||||||
|
DetectionWindow := false.B
|
||||||
|
} .elsewhen(io.ReceiveEnd){
|
||||||
|
DetectionWindow := true.B
|
||||||
|
}
|
||||||
|
|
||||||
|
// Latching Timer Value
|
||||||
|
when(DetectionWindow & ReceivedPauseFrmWAddr & ByteCntEq18){
|
||||||
|
LatchedTimerValue := AssembledTimerValue
|
||||||
|
} .elsewhen(io.ReceiveEnd){
|
||||||
|
LatchedTimerValue := 0.U
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delayed CEC counter
|
||||||
|
when(io.RxValid & io.RxEndFrm){
|
||||||
|
DlyCrcCnt := 0.U
|
||||||
|
}.elsewhen(io.RxValid & ~io.RxEndFrm & ~DlyCrcCnt.extract(2)){
|
||||||
|
DlyCrcCnt := DlyCrcCnt + 1.U
|
||||||
|
}
|
||||||
|
|
||||||
|
val IncrementByteCnt =
|
||||||
|
io.RxValid & DetectionWindow & ~ByteCntEq18 &
|
||||||
|
(~io.DlyCrcEn | io.DlyCrcEn & DlyCrcCnt.extract(2))
|
||||||
|
|
||||||
|
// Byte counter
|
||||||
|
when(io.RxEndFrm){
|
||||||
|
ByteCnt := 0.U
|
||||||
|
} .elsewhen(IncrementByteCnt){
|
||||||
|
ByteCnt := ByteCnt + 1.U
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
when(io.SetPauseTimer){
|
||||||
|
PauseTimer := LatchedTimerValue
|
||||||
|
} .elsewhen(DecrementPauseTimer){
|
||||||
|
PauseTimer := PauseTimer - 1.U
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val Divider2 = RegInit(false.B) // Divider2 is used for incrementing the Slot timer every other clock
|
||||||
|
|
||||||
|
when(PauseTimer.orR & io.RxFlow){
|
||||||
|
Divider2 := ~Divider2
|
||||||
|
} .otherwise{
|
||||||
|
Divider2 := false.B
|
||||||
|
}
|
||||||
|
|
||||||
|
val SlotTimer = RegInit(0.U(6.W)) // SlotTimer
|
||||||
|
|
||||||
|
when(io.RxReset){
|
||||||
|
SlotTimer := 0.U
|
||||||
|
} .elsewhen(Pause_wire & io.RxFlow & Divider2){
|
||||||
|
SlotTimer := SlotTimer + 1.U
|
||||||
|
}
|
||||||
|
|
||||||
|
val ReceivedPauseFrm = RegInit(false.B); io.ReceivedPauseFrm := ReceivedPauseFrm // Pause Frame received
|
||||||
|
|
||||||
|
when((io.RxStatusWriteLatched_sync2 & io.r_PassAll) | (ReceivedPauseFrm & (~io.r_PassAll))){
|
||||||
|
ReceivedPauseFrm := false.B
|
||||||
|
} .elsewhen(ByteCntEq16 & TypeLengthOK & OpCodeOK){
|
||||||
|
ReceivedPauseFrm := true.B
|
||||||
|
}
|
||||||
|
|
||||||
|
io.SetPauseTimer :=
|
||||||
|
io.ReceiveEnd & ReceivedPauseFrmWAddr & io.ReceivedPacketGood & io.ReceivedLengthOK & io.RxFlow
|
||||||
|
|
||||||
|
DecrementPauseTimer := SlotFinished & PauseTimer.orR
|
||||||
|
PauseTimerEq0 := ~PauseTimer.orR
|
||||||
|
|
||||||
|
SlotFinished := SlotTimer.andR & Pause_wire & io.RxFlow & Divider2 // Slot is 512 bits (64 bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
6
src/main/scala/mac/MacRegisters.scala
Normal file
6
src/main/scala/mac/MacRegisters.scala
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package MAC
|
||||||
|
|
||||||
|
import chisel3._
|
||||||
|
import chisel3.util._
|
||||||
|
|
||||||
|
|
||||||
@@ -1,5 +1,167 @@
|
|||||||
package MAC
|
package MAC
|
||||||
|
|
||||||
import chisel3._
|
import chisel3._
|
||||||
import chisel3.util
|
import chisel3.util._
|
||||||
|
|
||||||
|
class MacStatusIO extends Bundle{
|
||||||
|
val RxCrcError = Input(Bool())
|
||||||
|
val MRxErr = 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 RxByteCntMaxFrame = Input(Bool())
|
||||||
|
val MRxD = Input(UInt(4.W))
|
||||||
|
val Collision = Input(Bool())
|
||||||
|
val CollValid = Input(UInt(6.W))
|
||||||
|
val r_RecSmall = Input(Bool())
|
||||||
|
val r_MinFL = Input(UInt(16.W))
|
||||||
|
val r_MaxFL = Input(UInt(16.W))
|
||||||
|
val r_HugEn = Input(Bool())
|
||||||
|
val StartTxDone = Input(Bool())
|
||||||
|
val StartTxAbort = Input(Bool())
|
||||||
|
val RetryCnt = Input(UInt(4.W))
|
||||||
|
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 TxUsedData = Input(Bool())
|
||||||
|
val Loopback = Input(Bool())
|
||||||
|
val r_FullD = Input(Bool())
|
||||||
|
val RstDeferLatched = Input(Bool())
|
||||||
|
|
||||||
|
val ReceivedLengthOK = Output(Bool())
|
||||||
|
val ReceiveEnd = Output(Bool())
|
||||||
|
val ReceivedPacketGood = Output(Bool())
|
||||||
|
val InvalidSymbol = Output(Bool())
|
||||||
|
val LatchedCrcError = Output(Bool())
|
||||||
|
val RxLateCollision = Output(Bool())
|
||||||
|
val ShortFrame = Output(Bool())
|
||||||
|
val DribbleNibble = Output(Bool())
|
||||||
|
val ReceivedPacketTooBig = Output(Bool())
|
||||||
|
val LoadRxStatus = Output(Bool())
|
||||||
|
val RetryCntLatched = Output(UInt(4.W))
|
||||||
|
val RetryLimit = Output(Bool())
|
||||||
|
val LateCollLatched = Output(Bool())
|
||||||
|
val DeferLatched = Output(Bool())
|
||||||
|
val CarrierSenseLost = Output(Bool())
|
||||||
|
val LatchedMRxErr = Output(Bool())
|
||||||
|
}
|
||||||
|
|
||||||
|
class MacStatus extends Module{
|
||||||
|
val io: MacStatusIO = IO(new MacStatusIO)
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val LatchedMRxErr = RegInit(false.B); io.LatchedMRxErr := LatchedMRxErr // LatchedMRxErr
|
||||||
|
|
||||||
|
when(io.MRxErr & io.MRxDV & (io.RxStatePreamble | io.RxStateSFD | io.RxStateData.orR | io.RxStateIdle & ~io.Transmitting)){
|
||||||
|
LatchedMRxErr := true.B
|
||||||
|
} .otherwise{
|
||||||
|
LatchedMRxErr := false.B
|
||||||
|
}
|
||||||
|
|
||||||
|
io.ReceivedPacketGood := ~LatchedCrcError // ReceivedPacketGood
|
||||||
|
io.ReceivedLengthOK := io.RxByteCnt >= io.r_MinFL & io.RxByteCnt <= io.r_MaxFL // ReceivedLengthOK
|
||||||
|
|
||||||
|
// Time to take a sample
|
||||||
|
val TakeSample =
|
||||||
|
(io.RxStateData.orR & ~io.MRxDV) |
|
||||||
|
(io.RxStateData.extract(0) & io.MRxDV & io.RxByteCntMaxFrame)
|
||||||
|
|
||||||
|
|
||||||
|
val LoadRxStatus = RegNext(TakeSample, false.B); io.LoadRxStatus := LoadRxStatus // LoadRxStatus
|
||||||
|
val ReceiveEnd = RegNext(LoadRxStatus, false.B); io.ReceiveEnd := ReceiveEnd // ReceiveEnd
|
||||||
|
val SetInvalidSymbol = io.MRxDV & io.MRxErr & io.MRxD === "he".U // Invalid symbol was received during reception in 100Mbps
|
||||||
|
val InvalidSymbol = RegInit(false.B); io.InvalidSymbol := InvalidSymbol // InvalidSymbol
|
||||||
|
|
||||||
|
when(LoadRxStatus & ~SetInvalidSymbol){
|
||||||
|
InvalidSymbol := false.B
|
||||||
|
} .elsewhen(SetInvalidSymbol){
|
||||||
|
InvalidSymbol := true.B
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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) & (~RxColWindow | io.r_RecSmall)){
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
val ShortFrame = RegInit(false.B); io.ShortFrame := ShortFrame //ShortFrame
|
||||||
|
when(LoadRxStatus){
|
||||||
|
ShortFrame := false.B
|
||||||
|
} .elsewhen(TakeSample){
|
||||||
|
ShortFrame := io.RxByteCnt < io.r_MinFL
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val ReceivedPacketTooBig = RegInit(false.B); io.ReceivedPacketTooBig := ReceivedPacketTooBig
|
||||||
|
|
||||||
|
when(LoadRxStatus){
|
||||||
|
ReceivedPacketTooBig := false.B
|
||||||
|
} .elsewhen(TakeSample){
|
||||||
|
ReceivedPacketTooBig := ~io.r_HugEn & io.RxByteCnt > io.r_MaxFL
|
||||||
|
}
|
||||||
|
|
||||||
|
val RetryCntLatched = RegEnable( io.RetryCnt, 0.U(4.W), io.StartTxDone | io.StartTxAbort); io.RetryCntLatched := RetryCntLatched
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ abstract class MacTxBase extends Module{
|
|||||||
|
|
||||||
val UnderRun = Wire(Bool())
|
val UnderRun = Wire(Bool())
|
||||||
val TooBig = Wire(Bool())
|
val TooBig = Wire(Bool())
|
||||||
val Crc = Wire(UInt(32.W))
|
|
||||||
val CrcError = Wire(Bool())
|
val CrcError = Wire(Bool())
|
||||||
|
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ abstract class MacTxBase extends Module{
|
|||||||
val NibCntEq7 = NibCnt === 7.U
|
val NibCntEq7 = NibCnt === 7.U
|
||||||
val NibCntEq15 = NibCnt === 15.U
|
val NibCntEq15 = NibCnt === 15.U
|
||||||
|
|
||||||
val RetryCnt = RegInit(0.U(4.W))
|
val RetryCnt = RegInit(0.U(4.W)); io.RetryCnt := RetryCnt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ abstract class MacTxBase extends Module{
|
|||||||
trait MacTxFSM { this: MacTxBase =>
|
trait MacTxFSM { this: MacTxBase =>
|
||||||
|
|
||||||
// Defining the next state
|
// Defining the next state
|
||||||
io.StartIPG := StateDefer & ~ExcessiveDefer & ~io.CarrierSense
|
StartIPG := StateDefer & ~ExcessiveDefer & ~io.CarrierSense
|
||||||
|
|
||||||
val StartIdle = StateIPG & (Rule1 & NibCnt(6,0) >= io.IPGT | ~Rule1 & NibCnt(6,0) >= io.IPGR2)
|
val StartIdle = StateIPG & (Rule1 & NibCnt(6,0) >= io.IPGT | ~Rule1 & NibCnt(6,0) >= io.IPGR2)
|
||||||
|
|
||||||
@@ -118,26 +118,29 @@ trait MacTxFSM { this: MacTxBase =>
|
|||||||
|
|
||||||
val StartPAD = ~io.Collision & StateData(1) & io.TxEndFrm & io.Pad & ~NibbleMinFl
|
val StartPAD = ~io.Collision & StateData(1) & io.TxEndFrm & io.Pad & ~NibbleMinFl
|
||||||
|
|
||||||
val StartFCS = ~io.Collision & StateData(1) & io.TxEndFrm & (~io.Pad | io.Pad & NibbleMinFl) & io.CrcEn
|
StartFCS :=
|
||||||
| ~io.Collision & StatePAD & NibbleMinFl & io.CrcEn
|
(~io.Collision & StateData(1) & io.TxEndFrm & (~io.Pad | io.Pad & NibbleMinFl) & io.CrcEn) |
|
||||||
|
(~io.Collision & StatePAD & NibbleMinFl & io.CrcEn)
|
||||||
|
|
||||||
StartJam := (io.Collision | UnderRun) & ((StatePreamble & NibCntEq15) | (StateData(1) | StateData(0)) | StatePAD | StateFCS)
|
StartJam := (io.Collision | UnderRun) & ((StatePreamble & NibCntEq15) | (StateData(1) | StateData(0)) | StatePAD | StateFCS)
|
||||||
|
|
||||||
StartBackoff := StateJam & ~RandomEq0 & ColWindow & ~RetryMax & NibCntEq7 & ~io.NoBckof
|
StartBackoff := StateJam & ~RandomEq0 & ColWindow & ~RetryMax & NibCntEq7 & ~io.NoBckof
|
||||||
|
|
||||||
StartDefer := StateIPG & ~Rule1 & io.CarrierSense & NibCnt(6,0) <= io.IPGR1 & NibCnt(6,0) =/= io.IPGR2
|
StartDefer :=
|
||||||
| StateIdle & io.CarrierSense
|
(StateIPG & ~Rule1 & io.CarrierSense & NibCnt(6,0) <= io.IPGR1 & NibCnt(6,0) =/= io.IPGR2) |
|
||||||
| StateJam & NibCntEq7 & (io.NoBckof | RandomEq0 | ~ColWindow | RetryMax)
|
(StateIdle & io.CarrierSense) |
|
||||||
| StateBackOff & (io.TxUnderRun | RandomEqByteCnt)
|
(StateJam & NibCntEq7 & (io.NoBckof | RandomEq0 | ~ColWindow | RetryMax)) |
|
||||||
| io.StartTxDone | TooBig;
|
(StateBackOff & (io.TxUnderRun | RandomEqByteCnt)) |
|
||||||
|
io.StartTxDone |
|
||||||
|
TooBig
|
||||||
|
|
||||||
io.DeferIndication := StateIdle & io.CarrierSense;
|
io.DeferIndication := StateIdle & io.CarrierSense
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
when(StartDefer | StartIdle){
|
when(StartDefer | StartIdle){
|
||||||
StateIPG := false.B
|
StateIPG := false.B
|
||||||
}.elsewhen(io.StartIPG){
|
}.elsewhen(StartIPG){
|
||||||
StateIPG := true.B
|
StateIPG := true.B
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +180,7 @@ trait MacTxFSM { this: MacTxBase =>
|
|||||||
StateBackOff := true.B
|
StateBackOff := true.B
|
||||||
}
|
}
|
||||||
|
|
||||||
when(io.StartIPG){
|
when(StartIPG){
|
||||||
StateDefer := false.B
|
StateDefer := false.B
|
||||||
} .elsewhen(StartDefer){
|
} .elsewhen(StartDefer){
|
||||||
StateDefer := true.B
|
StateDefer := true.B
|
||||||
@@ -208,7 +211,7 @@ trait MacTxCounter { this: MacTxBase =>
|
|||||||
(StateDefer & ExcessiveDefer & ~io.TxStartFrm) |
|
(StateDefer & ExcessiveDefer & ~io.TxStartFrm) |
|
||||||
(StatePreamble & NibCntEq15) |
|
(StatePreamble & NibCntEq15) |
|
||||||
(StateJam & NibCntEq7) |
|
(StateJam & NibCntEq7) |
|
||||||
StateIdle | StartDefer | io.StartIPG | StartFCS | StartJam
|
StateIdle | StartDefer | StartIPG | StartFCS | StartJam
|
||||||
|
|
||||||
|
|
||||||
when(ResetNibCnt){
|
when(ResetNibCnt){
|
||||||
@@ -217,7 +220,7 @@ trait MacTxCounter { this: MacTxBase =>
|
|||||||
NibCnt := NibCnt + 1.U
|
NibCnt := NibCnt + 1.U
|
||||||
}
|
}
|
||||||
|
|
||||||
NibbleMinFl := NibCnt >= (((MinFL-4.U)<<1) - 1.U) // FCS should not be included in NibbleMinFl
|
NibbleMinFl := NibCnt >= (((io.MinFL-4.U)<<1) - 1.U) // FCS should not be included in NibbleMinFl
|
||||||
|
|
||||||
ExcessiveDefer := NibCnt(13,0) === "h17b7".U & ~io.ExDfrEn; // 6071 nibbles
|
ExcessiveDefer := NibCnt(13,0) === "h17b7".U & ~io.ExDfrEn; // 6071 nibbles
|
||||||
|
|
||||||
@@ -258,10 +261,12 @@ trait MacTxCRC{ this: MacTxBase =>
|
|||||||
|
|
||||||
val Data_Crc =
|
val Data_Crc =
|
||||||
Mux1H(Seq(
|
Mux1H(Seq(
|
||||||
StateData(0) -> Cat( TxData(3), TxData(2), TxData(1), TxData(0) ),
|
StateData(0) -> Cat( io.TxData(0), io.TxData(1), io.TxData(2), io.TxData(3) ),
|
||||||
StateData(1) -> Cat( TxData(7), TxData(6), TxData(5), TxData(4) ),
|
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 ){
|
when( Initialize_Crc ){
|
||||||
Crc := "hFFFFFFFF".U
|
Crc := "hFFFFFFFF".U
|
||||||
} .otherwise{
|
} .otherwise{
|
||||||
@@ -337,25 +342,25 @@ trait MacTxRandom{ this: MacTxBase =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MacTx extends MacTxBase with MacTxFSM with MacTxCounter with MacTxCRC with MacTxRandom{
|
class MacTx extends MacTxBase with MacTxFSM with MacTxCounter with MacTxCRC with MacTxRandom{
|
||||||
val MTxD = RegInit(UInt(4.W)); io.MTxD := MTxD
|
val MTxD = RegInit(0.U(4.W)); io.MTxD := MTxD
|
||||||
val StopExcessiveDeferOccured = RegInit(false.B)
|
val StopExcessiveDeferOccured = RegInit(false.B)
|
||||||
|
|
||||||
val StatusLatch = RegInit(false.B)
|
val StatusLatch = RegInit(false.B)
|
||||||
val TxUsedData = RegNext(StartData.orR, false.B)
|
val TxUsedData = RegNext(StartData(0) | StartData(1), false.B); io.TxUsedData := TxUsedData
|
||||||
val TxDone = RegInit(false.B)
|
val TxDone = RegInit(false.B); io.TxDone := TxDone
|
||||||
val TxRetry = RegInit(false.B)
|
val TxRetry = RegInit(false.B); io.TxRetry := TxRetry
|
||||||
val TxAbort = RegInit(false.B)
|
val TxAbort = RegInit(false.B); io.TxAbort := TxAbort
|
||||||
|
|
||||||
val MTxEn = RegNext(StatePreamble | (StateData(0) | StateData(1)) | StatePAD | StateFCS | StateJam, false.B); io.MTxEn := MTxEn
|
val MTxEn = RegNext(StatePreamble | (StateData(0) | StateData(1)) | StatePAD | StateFCS | StateJam, false.B); io.MTxEn := MTxEn
|
||||||
val MTxErr = RegNext( TooBig | UnderRun, false.B) // Transmit error
|
val MTxErr = RegNext( TooBig | UnderRun, false.B); io.MTxErr := MTxErr// Transmit error
|
||||||
|
|
||||||
val WillTransmit = RegNext(StartPreamble | StatePreamble | (StateData(0) | StateData(1)) | StatePAD | StateFCS | StateJam, false.B) // WillTransmit
|
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)
|
io.ResetCollision := ~(StatePreamble | (StateData(0) | StateData(1)) | StatePAD | StateFCS)
|
||||||
val ExcessiveDeferOccured = io.TxStartFrm & StateDefer & ExcessiveDefer & ~StopExcessiveDeferOccured
|
val ExcessiveDeferOccured = io.TxStartFrm & StateDefer & ExcessiveDefer & ~StopExcessiveDeferOccured
|
||||||
io.StartTxDone = ~io.Collision & (StateFCS & NibCntEq7 | StateData(1) & io.TxEndFrm & (~io.Pad | io.Pad & NibbleMinFl) & ~io.CrcEn)
|
io.StartTxDone := ~io.Collision & (StateFCS & NibCntEq7 | StateData(1) & io.TxEndFrm & (~io.Pad | io.Pad & NibbleMinFl) & ~io.CrcEn)
|
||||||
UnderRun := StateData(0) & io.TxUnderRun & ~io.Collision
|
UnderRun := StateData(0) & io.TxUnderRun & ~io.Collision
|
||||||
TooBig := ~io.Collision & MaxFrame & (StateData(0) & ~io.TxUnderRun | StateFCS);
|
TooBig := ~io.Collision & MaxFrame & (StateData(0) & ~io.TxUnderRun | StateFCS);
|
||||||
val StartTxRetry = StartJam & (ColWindow & ~RetryMax) & ~UnderRun;
|
val StartTxRetry = StartJam & (ColWindow & ~RetryMax) & ~UnderRun;
|
||||||
@@ -424,8 +429,8 @@ class MacTx extends MacTxBase with MacTxFSM with MacTxCounter with MacTxCRC with
|
|||||||
when( true.B ){
|
when( true.B ){
|
||||||
MTxD := // Transmit nibble
|
MTxD := // Transmit nibble
|
||||||
Mux(
|
Mux(
|
||||||
StateData(0), TxData(3,0), // Lower nibble
|
StateData(0), io.TxData(3,0), // Lower nibble
|
||||||
Mux(StateData(1), TxData(7,4), // Higher 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( StateFCS, Cat(~Crc.extract(28), ~Crc.extract(29), ~Crc.extract(30), ~Crc.extract(31)), // Crc
|
||||||
Mux(StateJam, 9.U, // Jam pattern
|
Mux(StateJam, 9.U, // Jam pattern
|
||||||
Mux(
|
Mux(
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import chisel3.stage._
|
|||||||
object testModule extends App {
|
object testModule extends App {
|
||||||
(new chisel3.stage.ChiselStage).execute( Array("--target-dir", "generated/", "-e", "verilog" ) ++ args, Seq(
|
(new chisel3.stage.ChiselStage).execute( Array("--target-dir", "generated/", "-e", "verilog" ) ++ args, Seq(
|
||||||
ChiselGeneratorAnnotation(() => {
|
ChiselGeneratorAnnotation(() => {
|
||||||
new MacRx()
|
new MacControl()
|
||||||
})
|
})
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user