riscv-sodor-rv32_1stage(3)
继续接图:
下面进行说明的是core.scala、tlie.scala & top.scala。这三个文件的主要作用是一层层调用,同时将调用的模块一一互连,最后生成顶层的模块,这类似于verilog的层次化结构,同时将例化的各模块一一互连。
//core.scala说明
package Sodor
{
import chisel3._
import chisel3.util._
import Common._
//声明Core模块的IO端口
//imem:声明instruction memory的接口
//dmem:声明data memory的接口
//ddpath:声明debug时,data使用的接口,且是DebugDPath()端口的反属性
//dcpath:声明debug时,instruction使用的接口,且是DebugCPath()端口的反属性
//reset:声明一个输入信号,用于复位
class CoreIo(implicit conf: SodorConfiguration) extends Bundle
{
val imem = new MemPortIo(conf.xprlen)
val dmem = new MemPortIo(conf.xprlen)
val ddpath = Flipped(new DebugDPath())
val dcpath = Flipped(new DebugCPath())
val reset = Input(Bool())
}
//Core模块的主题逻辑
//先声明一个io,调用CoreIo(),则Core模块的端口参考CoreIo()的定义
class Core(implicit conf: SodorConfiguration) extends Module
{
val io = IO(new CoreIo())
io := DontCare
//声明一个模块c,调用CtlPath()模块,相当于verilog的例化操作,例化名为c
val c = Module(new CtlPath())
//声明一个模块d,调用DtlPath()模块,相当于verilog的例化操作,例化名为d
val d = Module(new DatPath())
//将c模块io端口的ctl信号与d模块io端口的ctl相连
c.io.ctl <> d.io.ctl
//将c模块io端口的dat信号与d模块io端口的dat相连
c.io.dat <> d.io.dat
//将Core模块io端口的imem信号与c模块io端口的imem信号相连
io.imem <> c.io.imem
//将Core模块io端口的imem信号与d模块io端口的imem信号相连
io.imem <> d.io.imem
//将Core模块io端口的dmem信号与c模块io端口的dmem信号相连
io.dmem <> c.io.dmem
//将Core模块io端口的dmem信号与d模块io端口的dmem信号相连
io.dmem <> d.io.dmem
//将Core模块的io.dmem.req.valid与c模块的io.dmem.req.valid相连
io.dmem.req.valid := c.io.dmem.req.valid
//将Core模块的io.dmem.req.typ与c模块的io.dmem.req.typ相连
io.dmem.req.bits.typ := c.io.dmem.req.bits.typ
//将Core模块的io.dmem.req.bits.fcn与c模块的io.dmem.req.btis.fcn相连
io.dmem.req.bits.fcn := c.io.dmem.req.bits.fcn
//将d模块io端口的ddpath信号与Core模块的ddpath信号相连,用于debug
d.io.ddpath <> io.ddpath
//将c模块io端口的dcpath信号与Core模块的dcpath信号相连,用于debug
c.io.dcpath <> io.dcpath
}
}
/************************* 我是分割线 ******************************************************/
//tile.scala说明
package Sodor
{
import chisel3._
import chisel3.util._
import Constants._
import Common._
import Common.Util._
//定义一个叫SordorTile的类,类似于verilog的模块定义
class SodorTile(implicit val conf: SodorConfiguration) extends Module
{
//定义SordorTile的端口,调用debug的信号,debug的信号在DMIIO()中定义了,这里
//取反,并命名为dmi,这里先调用DMIIO()给dmi,然后再将dmi捆绑为io端口,所以
//最终生成的信号为io_dmi_xxx
val io = IO(new Bundle {
val dmi = Flipped(new DMIIO())
})
// notice that while the core is put into reset, the scratchpad needs to be
// alive so that the HTIF can load in the program.
//例化debug模块,调用DebugModule()
val debug = Module(new DebugModule())
//例化core模块,调用Core()
val core = Module(new Core())
core.io := DontCare
//例化memory单元,调用AsyncScratchPadMemory(num_core_ports = 2),同时生成两个连接端口
val memory = Module(new AsyncScratchPadMemory(num_core_ports = 2))
//memory的第一个端口接core模块io端口的dmem信号
core.io.dmem <> memory.io.core_ports(0)
//memory的第二个端口接core模块io端口的imem信号
core.io.imem <> memory.io.core_ports(1)
//debug的操作内容连接memory的debug_port,利用debug_port读取debug指令
debug.io.debugmem <> memory.io.debug_port
//core的复位有debug复位和reset信号或组成,这里的reset信号由顶层输入
core.reset := debug.io.resetcore | reset.toBool
//将debug模块io端口的ddpath信号与core模块io端口的ddpath信号相连
debug.io.ddpath <> core.io.ddpath
//将debug模块io端口的dcpath信号与core模块io端口的dcpath信号相连
debug.io.dcpath <> core.io.dcpath
//将debug模块io端口的dmi信号与SodorTile模块io端口的dmi信号相连
debug.io.dmi <> io.dmi
}
}
/************************* 我是分割线 ******************************************************/
//top.scala说明
package Sodor
import chisel3._
import chisel3.util._
import Constants._
import Common._
import Common.Util._
import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.HashMap
//定义一个类,叫Top,类似于testbench的作用
class Top extends Module
{
//定义Top层的端口信号,定义一个success的信号用于告诉上层仿真成功
val io = IO(new Bundle{
val success = Output(Bool())
})
//调用一些常用配置,命名为sodor_conf
implicit val sodor_conf = SodorConfiguration()
//例化一个函数tile,调用SodorTile
val tile = Module(new SodorTile)
//例化一个模块dtm,用于debug,调用SimDTM,同时连接clock,reset,success & dmi信号
val dtm = Module(new SimDTM).connect(clock, reset.toBool, tile.io.dmi, io.success)
}
//定义一个object对象,为elaborate,调用Top类,用于riscv-sodor的bulid.scala
object elaborate {
def main(args: Array[String]): Unit = {
chisel3.Driver.execute(args, () => new Top)
}
}