Merge branch 'feature/FSMC' into main

This commit is contained in:
Ruige Lee
2025-02-08 15:47:08 +08:00
2 changed files with 247 additions and 21 deletions

View File

@@ -3,40 +3,38 @@ package BACK
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._
import org.chipsalliance.cde.config._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
class FSMCMemIO extends Bundle{
class FSMCSlvIO extends Bundle{
val FSMC = new FSMC_Port_Bundle val FSMC = new FSMC_Port_Bundle
val CDRIn = Flipped(Valid(new CDRData)) val tla = Flipped(new DecoupledIO(new TLBundleA(edge.bundle)))
val CDROut = Valid(new CDRData) val tld = new DecoupledIO(new TLBundleD(edge.bundle))
} }
class FSMCSlvBase extends Module{ abstract class FSMCMemBase(val edge: TLEdgeIn)(implicit p: Parameters) extends BackModule{
val io: FSMCSlvIO = IO(new FSMCSlvIO) val io: FSMCMemIO = IO(new FSMCMemIO)
val sram = Module(new )
mirror.io.datar_b,
mirror.io.ce_b,
mirror.io.we_b,
mirror.io.[10:0] addr_b,
mirror.io.[7:0] dataw_b
} }
trait MirrorSRAM { this: FSMCSlvBase => trait FSMCMemFSMC{ this: FSMCMemBase =>
} }
trait FSMCMemTileLink { this: FSMCMemBase =>
}
class FSMCMem(edge: TLEdgeIn)(implicit p: Parameters) extends FSMCMemBase(edge)
with FSMCMemFSMC
with FSMCMemTileLink
{
}

View File

@@ -0,0 +1,228 @@
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)
}
}
}