有人预言,RISC-V或将是继Intel和Arm之后的第三大主流处理器体系。欢迎访问全球首家只专注于RISC-V单片机行业应用的中文网站
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
本帖最后由 新ちゃん 于 2020-8-20 20:03 编辑
如何配置一个自定义的rocket-chip?这节的主要内容是教大家如何自由配置一个rocket-chip。
以下是我对rocket-chip修改后实现的特殊功能(部分我会以例子的形式进行说明):
1、 将reset_vector信号引到顶层,可以根据该信号使rocket-chip从不同地址启动。
2、 在rocket-chip的顶层引出一套采用Tilelink的SRAM,这套SRAM按物理地址访问。
3、 修改各总线(mem/MMIO)的物理访问地址。
4、 将各总线(mem/MMIO)的AXI4协议改为AHB协议。
5、 将local interrupt的信号引到rocket-chip的顶层,使除了PLIC外,还能使用local interrupt。
6、 修改ROCC的功能,扩展custom0、custom1、custom2和custom3的功能。
7、 加入DCache enable的CSR寄存器,并实现相应功能,使DCache的功能变为可选。
现在先对rocket-chip的Scala代码进行简单的介绍。 - cd /rocket-chip/src/main/scala
- ls
- amba devices groundtest jtag rocket system tilelink util
- config diplomacy interrupts regmapper subsystem tile unittest
复制代码
我决定以从顶到底的方式解释rocket-chip的Scala代码,此外我不会每个Scala文件都一一说明,某些测试的Scala文件我会跳过的。
首先说明的是/rocket-chip/src/main/scala/system目录: - Configs.scala ExampleRocketSystem.scala
- Generator.scala RocketTestSuite.scala TestHarness.scala
复制代码
Generator.scala & RocketTestSuite.scala 这两个文件是测试相关的,所以我不做说明。
第一个看的Scala文件是:TestHarness.scala
带//注释的就是解释。
- class TestHarness()(implicit p: Parameters) extends Module {
- //注释:声明一个io Bundle,里面包含一个输出、Bool类型的常量success。
- val io = new Bundle {
- val success = Bool(OUTPUT)
- }
- //注释:生成一个module,利用dut来表示这个module,这个module是调用ExampleRocketSystem的。
- //注释:在/system/ExampleRocketSystem.scala中定义。
- val dut = Module(LazyModule(new ExampleRocketSystem).module)
- //注释:dut的复位是外部reset与dut debug模块的ndreset信号的或。
- dut.reset := reset | dut.debug.ndreset
- //注释:调用dut的dontTouchPorts的方法,这个是使某些信号不被接触,我暂时也不十分理解,
- //不过我们后面不对这个进行修改,所以直接用就好。
- //注释:在/util/Annotations.scala中定义。
- dut.dontTouchPorts()
- //注释:这是我修改后的方法,主要是将dut和AHB协议的仿真SRAM对接。
- //注释:在/subsystem/Ports.scala中定义。
- dut.connectSimAHBMem()
- //注释:这个是将dut的中断信号全部接0。
- //注释:在/subsystem/InterruptBus.scala中定义。
- //dut.tieOffInterrupts()
- //注释:这些是原有的AXI接口,Mem和MMIO,因为我改了使用AHB协议,所以屏蔽。
- //注释:在/subsystem/Ports.scala中定义。
- //dut.connectSimAXIMem()
- //dut.connectSimAXIMMIO()
- //注释:这是frontend的接口,这个接口CPU是作为slave的,外部设备是作为master的,
- //功能类似于SiFive的frontport,下面两个都是frontend的接口,只是一个采用AXI4协议,一个采用Tilelink协议。
- //注释:在/subsystem/Ports.scala中定义。
- //dut.l2_frontend_bus_axi4.foreach(_.tieoff)
- //dut.l2_frontend_bus_tl.foreach(_.tieoff)
- //注释:这个也是frontend的接口,只是我修改后,采用了AHB协议。
- //注释:在/subsystem/Ports.scala中定义 。
- dut.l2_frontend_bus_ahb.foreach(_.tieoff)
- //注释:主要作用是将SimJTAG.v与dut相连,并输出io.success来确定仿真是否成功。
- //注释:SimJTAG.v在/rocket-chip/vsim/generated-src/xxx目录中可以找到。
- //注释:在/devices/debug/Periphery.scala中定义。
- dut.connectDebug(clock, reset, io.success)
- }
复制代码
下图是 TestHarness.scala 生成的连接图。
第二个看的Scala文件是:ExampleRocketSystem.scala 可以知道 TestHarness.scala 就是testbench,而 ExampleRocketSystem.scala 生成的才是我们关注的SOC, ExampleRocketSystem.scala 包括Core以外的其他外设&总线。
- /** Example Top with periphery devices and ports, and a Rocket subsystem */
- //注释:类似的,ExampleRocketSystem是在RocketSubsystem的基础上进行扩展的。
- //注释:RocketSubsystem是在/subsystem/RocketSubsystem.scala中定义的类。
- class ExampleRocketSystem(implicit p: Parameters) extends RocketSubsystem
- //注释:我修改后的SRAM,总线接口是Tilelink协议。
- //注释:在/tilelink/SRAM.scala中定义。
- with HasPeripheryRAM
- //注释:将Ext-Interrupts(PLIC的中断源)引入ibus中同步,即异步信号同步化。
- //注释:在/subsystem/InterruptBus.scala中定义。
- with HasAsyncExtInterrupts
- //注释:将Local-Interrupts引入ibus中同步,即异步信号同步化,这是我修改的。
- //注释:在/subsystem/InterruptBus.scala中定义。
- with HasAsyncLocalInterrupts
- //注释:调用AHB协议的memory_port,这个也是我修改的。
- //注释:在/subsystem/Ports.scala中定义。
- with CanHaveMasterAHBMemPort
- //注释:调用AHB协议的frontend_bus,这个也是我修改的。
- //注释:在/subsystem/Ports.scala中定义。
- with CanHaveSlaveAHBPort
- //注释:调用Tilelink协议的frontend_bus。
- //注释:在/subsystem/Ports.scala中定义。
- //with CanHaveSlaveTLPort
- //注释:调用AXI4协议的memory_port。
- //注释:在/subsystem/Ports.scala中定义。
- //with CanHaveMasterAXI4MemPort
- //注释:调用AXI4协议的mmio_port。
- //注释:在/subsystem/Ports.scala中定义。
- //with CanHaveMasterAXI4MMIOPort
- //注释:调用AXI4协议的frontend_bus。
- //注释:在/subsystem/Ports.scala中定义。
- //with CanHaveSlaveAXI4Port
- //注释:调用BootROM模块。
- //注释:在/devices/tilelink/BootROM.scala中定义。
- //with HasPeripheryBootROM
- //注释:sbus会传递Tilelink的某些Error。
- //注释:在/devices/tilelink/Error.scala中定义。
- with HasSystemErrorSlave
- {
- override lazy val module = new ExampleRocketSystemModuleImp(this)
- }
- // ExampleRocketSystemModuleImp是具体的端口连接模块。
- // RocketSubsystemModuleImp是在/subsystem/RocketSubsystem.scala中定义的类
- class ExampleRocketSystemModuleImp[+L <: ExampleRocketSystem](_outer: L) extends RocketSubsystemModuleImp(_outer)
- //注释:用于连接CLINT timer的时钟输入,可以直接将rtc_clk引到顶层中。
- //注释:在/subsystem/RTC.scala中定义。
- with HasRTCModuleImp
- //注释:将顶层的中断源(Ext-Interrupts)信号接到ExtInterruptsModule中。
- //注释:在/subsystem/InterruptBus.scala中定义。
- with HasExtInterruptsModuleImp
- //注释:将顶层的中断源(Local-Interruptss)信号接到LocalInterruptsModule中。
- //注释:在/subsystem/InterruptBus.scala中定义。
- with HasLocalInterruptsModuleImp
- //注释:将AHB协议的SRAM和DUT(ExampleRocketSystem)的memory_port总线(AHB协议)相连。
- //注释:在/subsystem/Ports.scala中定义。
- with CanHaveMasterAHBMemPortModuleImp
- //注释:将顶层的frontend_bus信号(AHB协议)接到SlaveAHBPortModule中。
- //注释:在/subsystem/Ports.scala中定义。
- with CanHaveSlaveAHBPortModuleImp
- //with CanHaveSlaveTLPortModuleImp
- //注释:将AXI4协议的SRAM和DUT(ExampleRocketSystem)的memory_port总线(AXI4协议)相连。
- //注释:在/subsystem/Ports.scala中定义。
- //with CanHaveMasterAXI4MemPortModuleImp
- //注释:将AXI4协议的SRAM和DUT(ExampleRocketSystem)的mmio_port总线(AXI4协议)相连。
- //注释:在/subsystem/Ports.scala中定义。
- //with CanHaveMasterAXI4MMIOPortModuleImp
- //注释:将顶层的frontend_bus信号(AXI4协议)接到SlaveAXI4PortModule中。
- //注释:在/subsystem/Ports.scala中定义。
- //with CanHaveSlaveAXI4PortModuleImp
- //注释:将global_reset_vector接着BootROM的地址上,固定rocket-chip从BootROM开始启动。
- //注释:在/devices/tilelink/BootROM.scala中定义。
- //with HasPeripheryBootROMModuleImp
- with DontTouch
复制代码
第三个看的Scala文件是:Configs.scala
TestHarness.scala 就是testbench,而 ExampleRocketSystem.scala 就是SOC的层次,包括Core以外的其他外设&总线,Configs.scala 就是核心Core的配置。Configs.scala 的配置比较多,我挑几个来说明。
- //注释:Core的一些基础配置,在/scala/subsystem/Configs.scala中有各个配置的详细说明。
- class BaseConfig extends Config(
- //注释:配置Mem_Port的起始地址、总线宽度、多拍数据传输的字节数。
- new WithDefaultMemPort() ++
- //注释:配置MMIO_Port的起始地址、总线宽度、多拍数据传输的字节数。
- //new WithDefaultMMIOPort() ++
- //注释:配置Slave_Port(frontend_bus)的多拍数据传输的字节数。
- new WithDefaultSlavePort() ++
- //注释:配置DTS的基础时间。
- new WithTimebase(BigInt(1000000)) ++ // 1 MHz
- //注释:配置DTS的model、compat。
- new WithDTS("freechips,rocketchip-unknown", Nil) ++
- //注释:配置Core的外部中断源数量。
- new WithNExtTopInterrupts(32) ++
- //注释:配置Core基础系统的内容,如位宽、虚拟内容的类型、各类型总线的特性、BootROM的内容、Debug的参数、CLINT的参数等。
- new BaseSubsystemConfig()
- )
- class DefaultSmallConfig extends Config(
- //注释:生成的Core带有BTB分支预测功能。
- new WithDefaultBtb ++
- //注释:生成的Core带ROCC的接口,用于定制指令的扩展。
- new WithRoccExample ++
- //注释:指定Core是32位系统,且指定浮点数据的位宽和乘除法的类型。
- new WithRV32 ++
- //注释:生成的Core带有DTM模块,兼容JTAG调试功能。
- new WithJtagDTM ++
- //注释:生成的Core去除Tilelink的Monitor模块。
- new WithoutTLMonitors ++
- //注释:指定Core中cache line的字节数,即32Bytes=8Words。
- new WithCacheBlockBytes(32) ++
- //注释:生成一个SmallCore,SmallCore配置中可以指定ICache & DCache的路数,深度等信息,有些配置会因为上面已经配置了而被覆盖。
- new WithNSmallCores(1) ++
- //注释:Core的一些基础配置,如总线、DTS & 中断等。
- new BaseConfig
- )
复制代码
欲知后事如何,请听下回分解。 有兴趣的朋友可以在评论中留下你们想改的功能,我看能不能改出来,谢谢大家。
本篇完,感谢关注:RISC-V单片机中文网
|