diff --git a/src/main/scala/backBoard/pico/BackSubSystem.scala b/src/main/scala/backBoard/pico/BackSubSystem.scala new file mode 100644 index 0000000..901c81d --- /dev/null +++ b/src/main/scala/backBoard/pico/BackSubSystem.scala @@ -0,0 +1,139 @@ +package BACK + +import chisel3._ +import chisel3.util._ + +import org.chipsalliance.cde.config._ + +abstract class BackModule(implicit val p: Parameters) extends Module with HasBackParameters { def io: Record } +abstract class BackBundle(implicit val p: Parameters) extends Bundle with HasBackParameters + +case object BackParamsKey extends Field[BackSetting] + + + + +case class BackSetting( +){ + +} + +trait HasBackParameters { + implicit val p: Parameters + + val backSetting = p(BackParamsKey) +} + + + + + + + + + + + + + + + + +class BackSubSys( )(implicit p: Parameters) extends LazyModule with HasBackParameters { + + class AXI4MasterNode(portParams: Seq[AXI4MasterPortParameters]) + val AXI4SlaveNode(portParams: Seq[AXI4SlavePortParameters]) + + + + val cdrNode = TLManagerNode(Seq(TLSlavePortParameters.v1( + managers = Seq(TLSlaveParameters.v1( + address = Seq(AddressSet(0x40000000L, 0xffL)), + regionType = RegionType.UNCACHED, + executable = true, + supportsGet = TransferSizes(32/8, 32/8), + supportsPutFull = TransferSizes(32/8, 32/8), + supportsPutPartial = TransferSizes(32/8, 32/8) + )), + beatBytes = 32/8))) + + val sram = LazyModule(new AXI4RAM( + address = Seq(AddressSet(0x80000000L, 0xffffL)), + cacheable = false, + executable = true, + beatBytes = 4, + devName = Some("SRAM"), + wcorrupt = false)) + + + val uart = LazyModule( new UART( + busWidthBytes = 4, + c = UARTParams( + address = BigInt(0x50000000L), + initBaudRate = BigInt(115200), + )) ) + + val gpio = LazyModule(new GPIO(busWidthBytes = 4, c = GPIOParams( + address = BigInt(0x60000000L), + width = 16, + ))) + + + + + + + + + + lazy val module: BackSubSysImp = new BackSubSysImp(this) +} + +class BackSubSysImp(outer: BackSubSys) extends LazyModuleImp(outer) with HasBackParameters { + class BackSubSysIO extends Bundle{ + val overCLK = Input(Bool()) + val uDatIn = Input(Bool()) + val uDatOut = Output(Bool()) + val dDatIn = Input(Bool()) + val dDatOut = Output(Bool()) + } + + + val ( bus, edge ) = chipLinkMasterNode.in.head + + + val io: BackSubSysIO = IO(new BackSubSysIO) + + val cdr = for( i <- 0 until 2 ) yield { Module(new TLCDR(edge)) } + + cdr(0).io.overCLK := io.overCLK + cdr(1).io.overCLK := io.overCLK + + cdr(0).io.datIn := io.uDatIn + io.uDatOut := cdr(0).io.uDatOut + cdr(1).io.datIn := io.dDatIn + io.dDatOut := cdr(1).io.uDatOut + + + cdr(0).io.tla.valid := bus.a.valid & bus.a.address(7) === "h0".U + cdr(1).io.tla.valid := bus.a.valid & bus.a.address(7) === "h1".U + cdr(0).io.tla.bits := bus.a.bits + bus.a.ready := + (bus.a.address(7) === "h0".U & cdr(0).io.tla.ready) | + (bus.a.address(7) === "h1".U & cdr(1).io.tla.ready) + + bus.d.valid := cdr(0).io.tld.valid | cdr(1).io.tld.valid + bus.d.bits := Mux1H(Seq( + cdr(0).io.tld.valid -> cdr(0).io.tld.bits + cdr(1).io.tld.valid -> cdr(1).io.tld.bits + )) + assert( ~(cdr(0).io.tld.valid & cdr(1).io.tld.valid), "Assert Failed! Two CDR can never resp at the same cycle!" ) + + cdr(0).io.tld.ready := bus.d.ready + cdr(1).io.tld.ready := bus.d.ready + + + val tla = Flipped(new DecoupledIO(new TLBundleA(edge.bundle))) + val tld = new DecoupledIO(new TLBundleD(edge.bundle)) + +} \ No newline at end of file diff --git a/src/main/scala/backBoard/pico/TLCDR.scala b/src/main/scala/backBoard/pico/TLCDR.scala new file mode 100644 index 0000000..11a08ad --- /dev/null +++ b/src/main/scala/backBoard/pico/TLCDR.scala @@ -0,0 +1,239 @@ +package BACK + +import chisel3._ +import chisel3.util._ + +import org.chipsalliance.cde.config._ +import freechips.rocketchip.amba.axi4._ + + +abstract class TLCDRBase(val edge: TLEdgeIn)(implicit p: Parameters) extends BackModule { + class TLCDRIO extends Bundle{ + val overCLK = Input(Bool()) + val datIn = Input(Bool()) + val datOut = Output(Bool()) + + + val tla = Flipped(new DecoupledIO(new TLBundleA(edge.bundle))) + val tld = new DecoupledIO(new TLBundleD(edge.bundle)) + } + + val io: TLCDRIO: IO(new TLCDRIO) + + val CDRIn = Module(new CDRIn) + CDRIn.io.serDat := io.datIn + CDRIn.io.overCLK := io.overCLK + + val CDROut = Module(new CDROut) + io.datOut := CDROut.io serDat + + + // CDRIn.io.axis = Decoupled(new AXIS_Bundle(8)) + // CDROut.io.axis = Flipped(Decoupled(new AXIS_Bundle(8))) + + + val txFifo = Module(new Queue(UInt(32.W), 8)) + val rxFifo = Module(new Queue(UInt(32.W), 8)) + +} + + +trait TLCDRTx{ this: TLCDRBase => + + val isTLReadTxStatus = io.tla.fire & io.tla.bits.address(7,0) === "h0".U & ( io.tla.bits.opcode === 4.U ) + val isTLWriteTxLen = io.tla.fire & io.tla.bits.address(7,0) === "h4".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) ) + val isTLWriteTxFifo = io.tla.fire & io.tla.bits.address(7,0) === "h8".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) ) + val isTLWriteTxSoftReset = isTLWriteTxLen + + + val txLen = RegInit(0.U(32.W)) + val isTxBusy = RegInit(false.B) + val isTxFull = ~txFifo.io.enq.ready + val isTxError = RegInit(false.B) + + val intTxError = ~RegNext(isTxError, false.B) & isTxError + val intTxFifoFull = ~RegNext(isTxFull, false.B) & isTxFull + val intTxFinish = CDROut.io.axis.fire & CDROut.io.axis.bits.tlast + + val txCnt = Reg(UInt(2.W)) + + val txData = RegEnable( txFifo.io.deq.bits, txFifo.io.deq.fire) + txFifo.io.deq.ready := + Mux( isTxBusy, CDROut.io.axis.fire & txCnt === 3.U, true.B ) + + txFifo.reset := reset.asBool | isTLWriteTxLen + + CDROut.io.axis.bits.tdata := Mux1H(Seq( + (txCnt === 0.U) -> txData( 7, 0), + (txCnt === 1.U) -> txData(15, 8), + (txCnt === 2.U) -> txData(23, 16), + (txCnt === 3.U) -> txData(31, 24), + )) + + CDROut.io.axis.bits.tlast := txLen === 0.U & ~txFifo.io.deq.valid & txCnt === 3.U + CDROut.io.axis.bits.tuser := isTxError + CDROut.io.axis.bits.valid := isTxBusy + + + when( isTLWriteTxLen ){ + isTxBusy := false.B + }.elsewhen( txFifo.io.deq.fire & ~isTxBusy ){ + isTxBusy := true.B + } .elsewhen( CDROut.io.axis.fire & CDROut.io.axis.bits.tlast ){ + isTxBusy := false.B + } + + + when( isTLWriteTxLen ){ + txCnt := 0.U + } .elsewhen( CDROut.io.axis.fire ){ + txCnt := txCnt + 1.U + } + + + when( isTLWriteTxLen ){ + txLen := io.tla.bits.data + } .elsewhen( CDROut.io.axis.fire ){ + txLen := txLen - 1.U + } + + txFifo.io.enq.bits := io.tla.bits.data + txFifo.io.enq.valid := isTLWriteTxFifo & txLen =/= 0.U + + when( isTLReadTxStatus | isTLWriteTxLen ){ + isTxError := false.B + } .elsewhen( isTxFull & isTLWriteTxFifo ){ + isTxError := true.B + } .elsewhen( txLen === 0.U & isTLWriteTxFifo ){ + isTxError := true.B + } + + + +} + + +trait TLCDRRx{ this: TLCDRBase => + + val isTLWriteRxSoftReset = io.tla.fire & io.tla.bits.address(7,0) === "h10".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) ) + val isTLReadRxStatus = io.tla.fire & io.tla.bits.address(7,0) === "h14".U & ( io.tla.bits.opcode === 4.U ) + val isTLReadRxLen = io.tla.fire & io.tla.bits.address(7,0) === "h18".U & ( io.tla.bits.opcode === 4.U ) + val isTLReadRxFifo = io.tla.fire & io.tla.bits.address(7,0) === "h1c".U & ( io.tla.bits.opcode === 4.U ) + + val rxLen = RegInit(0.U(32.W)) + // val isRxBusy = RegInit(false.B) + val isRxValid = rxFifo.io.enq.fire + val isRxError = RegInit(false.B) + + val intRxError = ~RegNext(isRxError, false.B) & isRxError + val intRxValid = ~RegNext(isRxValid, false.B) & isRxValid + + + val rxCnt = RegInit(0.U(2.W)) + val rxData = Reg(UInt(24.W)) + + + when( isTLWriteRxSoftReset ){ + rxCnt := 0.U + } .elsewhen( CDRIn.io.axis.fire ){ + rxCnt := rxCnt + 1.U + + rxData := Mux1H(Seq( + (rxCnt === 0.U) -> Cat( 0.U(24.W), CDRIn.io.axis.bits.tdata ) + (rxCnt === 1.U) -> Cat( 0.U(16.W), CDRIn.io.axis.bits.tdata, rxData( 7,0) ) + (rxCnt === 2.U) -> Cat( 0.U(8.W ), CDRIn.io.axis.bits.tdata, rxData(15,0) ) + // (rxCnt === 3.U) -> Cat( CDRIn.io.axis.bits.tdata, rxData(23,0) ) + )) + } + + when( isTLWriteRxSoftReset ){ + rxLen := 0.U + } .elsewhen( CDRIn.io.axis.fire ){ + rxLen := rxLen + 1.U + } + + rxFifo.io.enq.valid := CDRIn.io.axis.fire & ( rxCnt === 3.U | CDRIn.io.axis.bits.last ) + rxFifo.io.enq.bits := Mux1H(Seq( + (rxCnt === 0.U) -> Cat( 0.U(24.W), CDRIn.io.axis.bits.tdata ) + (rxCnt === 1.U) -> Cat( 0.U(16.W), CDRIn.io.axis.bits.tdata, rxData( 7,0) ) + (rxCnt === 2.U) -> Cat( 0.U(8.W ), CDRIn.io.axis.bits.tdata, rxData(15,0) ) + (rxCnt === 3.U) -> Cat( CDRIn.io.axis.bits.tdata, rxData(23,0) ) + )) + CDRIn.io.axis.ready := true.B + + rxFifo.reset := reset.asBool | isTLWriteRxSoftReset + + rxFifo.io.deq.ready := isTLReadRxFifo + + + when( isTLWriteRxSoftReset ){ + isRxError := false.B + } .elsewhen( rxFifo.io.enq.valid & ~rxFifo.io.enq.ready ){ + isRxError := true.B + printf("Warning, RxFifo Overflow!\n") + } + + + +} + +class TLCDR(edge: TLEdgeIn)(implicit p: Parameters) extends TLCDRBase(edge) with TLCDRTx with TLCDRRx{ + + val tlaInfo = Reg(new TLBundleA(edge.bundle)) + val rdata = Reg(UInt(32.W)) + val tlAReady = RegInit(true.B) + val tlDValid = RegInit(false.B) + + val isRead = Reg(Bool()) + + io.tla.ready := tlAReady + io.tld.valid := tlDValid + + + when( io.tla.fire ) { + tlaInfo := io.tla.bits + when( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) ) { + isRead := false.B + } .elsewhen( io.tla.bits.opcode === 4.U ) { + isRead := true.B + } .otherwise{ + assert( false.B, "Assert Failed! Unsupport Operation!" ) + } + } + + when( io.tla.fire ){ + tlAReady := false.B + tlDValid := true.B + } .elsewhen( io.tld.fire ) { + tlAReady := true.B + tlDValid := false.B + } + + when(isRead) { + io.tld.bits := edge.AccessAck(tlaInfo, rdata) + } .otherwise { + io.tld.bits := edge.AccessAck(tlaInfo) + } + + + when( isTLReadTxStatus){ + rdata := Cat( isTxBusy, isTxFull, isTxError ) + } .elsewhen(isTLWriteTxLen ){ + rdata := 0.U + } .elsewhen(isTLWriteTxFifo ){ + rdata := 0.U + } .elsewhen(isTLWriteTxSoftReset){ + rdata := 0.U + } .elsewhen(isTLWriteRxSoftReset){ + rdata := 0.U + } .elsewhen(isTLReadRxStatus ){ + rdata := Cat( isRxValid, isRxError ) + } .elsewhen(isTLReadRxLen ){ + rdata := rxLen + } .elsewhen(isTLReadRxFifo ){ + rdata := rxFifo.io.deq.bits + } + +} + + diff --git a/src/main/scala/backBoard/pico/picorv32.scala b/src/main/scala/backBoard/pico/picorv32.scala new file mode 100644 index 0000000..f658bbb --- /dev/null +++ b/src/main/scala/backBoard/pico/picorv32.scala @@ -0,0 +1,6 @@ +package BACK + +import chisel3._ +import chisel3.util._ + +