package BACK import chisel3._ import chisel3.util._ import org.chipsalliance.cde.config._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.diplomacy._ class MirrorSRAMDP extends BlackBox with HasBlackBoxInline { class MirrorSRAMDPIO extends Bundle{ val addrA = Input(UInt(10.W)) val datawA = Input( UInt(16.W) ) val datarA = Output( UInt(16.W) ) val enwA = Input(Bool()) val enrA = Input(Bool()) val clockA = Input(Bool()) val addrB = Input(UInt(10.W)) val datawB = Input( UInt(16.W) ) val datarB = Output( UInt(16.W) ) val enwB = Input(Bool()) val enrB = Input(Bool()) val clockB = Input(Bool()) } val io: MirrorSRAMDPIO = IO(new MirrorSRAMDPIO) setInline("MirrorSRAMDP.v", """ | module MirrorSRAMDP( | input [15:0] datawA, | input [9:0] addrA, | input enwA, | input enrA, | output [15:0] datarA, | input clockA, | | input [15:0] datawB, | input [9:0] addrB, | input enwB, | input enrB, | output [15:0] datarB, | input clockB | ); | | reg [15:0] mem[0:1023]; | reg [15:0] data_outa_reg = 16'b0; | reg [15:0] data_outb_reg = 16'b0; | | assign datarA = data_outa_reg; | assign datarB = data_outb_reg; | | always@( posedge clockA ) begin | if( enrA ) begin | end | | if( enwA ) begin | mem[addrA] <= datawA; | end else begin | data_outa_reg <= mem[addrA]; | end | end | | | always@( posedge clockB ) begin | if(enrB) begin | end | | if( enwB ) begin | mem[addrB] <= datawB; | end else begin | data_outb_reg <= mem[addrB]; | end | end | | initial begin | for( integer i = 0; i < 1024; i = i + 1 ) begin | mem[i] = $random; | end | end | | //Gowin_DPB your_instance_name( | // .douta(datarA), //output [15:0] douta | // .doutb(datarB), //output [15:0] doutb | // .clka(clockA), //input clka | // .ocea(1'b1), //input ocea | // .cea(1'b1), //input cea | // .reseta(1'b0), //input reseta | // .wrea(enwA), //input wrea | // .clkb(clockB), //input clkb | // .oceb(1'b1), //input oceb | // .ceb(1'b1), //input ceb | // .resetb(1'b0), //input resetb | // .wreb(enwB), //input wreb | // .ada(addrA), //input [3:0] ada | // .dina(datawA), //input [15:0] dina | // .adb(addrB), //input [3:0] adb | // .dinb(datawB) //input [15:0] dinb | //); | |endmodule """.stripMargin) } class FSMC_Port_Bundle extends Bundle{ val ADIn = Input(UInt(16.W)) val ADOut = Output(UInt(16.W)) val ADOEn = Output(Bool()) val csn = Input(Bool()) val rdn = Input(Bool()) val wrn = Input(Bool()) val advn = Input(Bool()) } class FSMC2TileLink(implicit p: Parameters) extends LazyModule{ val fsmcDev = new SimpleDevice("FSMC", Nil) val fsmcNode = TLManagerNode(Seq(TLSlavePortParameters.v1( managers = Seq( TLSlaveParameters.v2( address = Seq(AddressSet(0x10010000L, 0xffffL)), //64K name = Some("FSMC"), regionType = RegionType.VOLATILE, resources = fsmcDev.reg, executable = false, fifoId = Some(0), supports = TLMasterToSlaveTransferSizes( get = TransferSizes(1, 32/8), putFull = TransferSizes(1, 32/8), // putPartial = TransferSizes(1, 32/8), ), ) ), beatBytes = 32/8))) lazy val module = new Impl class Impl extends LazyModuleImp(this) { val io = IO(new FSMC_Port_Bundle) val ( fsmc_bus, fsmc_edge ) = fsmcNode.in.head // val tla = Wire(new DecoupledIO(new TLBundleA(fsmc_edge.bundle))) // val tld = Wire(new DecoupledIO(new TLBundleD(fsmc_edge.bundle))) val sram = Module(new MirrorSRAMDP()) //assert( ~(sram.io.enwA & sram.io.enrA) ) //assert( ~(sram.io.enwB & sram.io.enrB) ) sram.io.clockA := clock.asBool //system sram.io.clockB := clock.asBool //system io.ADOEn := ~io.rdn & ~io.csn & io.advn val latchAddr = RegEnable( io.ADIn, ~io.advn & ~io.csn) val activeAddr = latchAddr(9,0) sram.io.addrA := activeAddr sram.io.datawA := io.ADIn sram.io.enwA := ~io.csn & ~io.wrn sram.io.enrA := ~io.csn & ~io.rdn io.ADOut := sram.io.datarA sram.io.addrB := fsmc_bus.a.bits.address sram.io.datawB := fsmc_bus.a.bits.data sram.io.enwB := fsmc_bus.a.fire & (fsmc_bus.a.bits.opcode === 0.U | fsmc_bus.a.bits.opcode === 1.U) sram.io.enrB := fsmc_bus.a.fire & (fsmc_bus.a.bits.opcode === 4.U) val tlAReady = RegInit(true.B) val tlaInfo = Reg(new TLBundleA(fsmc_edge.bundle)) val tlDValid = RegInit(false.B) val isRead = tlaInfo.opcode === 4.U when( fsmc_bus.a.fire ) { tlaInfo := fsmc_bus.a.bits } fsmc_bus.a.ready := tlAReady fsmc_bus.d.valid := tlDValid when( fsmc_bus.a.fire ){ tlAReady := false.B } .elsewhen( fsmc_bus.d.fire ) { tlAReady := true.B } when( RegNext(fsmc_bus.a.fire) ){ tlDValid := true.B } .elsewhen( fsmc_bus.d.fire ) { tlDValid := false.B } when(isRead) { fsmc_bus.d.bits := fsmc_edge.AccessAck(tlaInfo, sram.io.datarB) } .otherwise { fsmc_bus.d.bits := fsmc_edge.AccessAck(tlaInfo) } } }