首页 > 其他分享 >详解Cake Pattern in rocket-chip

详解Cake Pattern in rocket-chip

时间:2023-02-16 01:11:26浏览次数:82  
标签:LazyModule adding optionally Diplomacy Pattern chip Cake Enables class

下面分别对cake pattern中的关键概念进行说明,最后以chipyard为例对cake pattern的用法进行说明,cake pattern对Diplomacy机制至关重要。

一、Lazy Module

定义惰性模块,实现延迟加载,这和scala中lazy val的概念有些相似,但在chisel中,lazy module是diplomacy的基础。 LazyModule提供一个框架,以容纳内部LazyModule和节点, LazyModuleImp实现LazyModule的逻辑,如果把LazyModule和LazyModuleImp作为一个整体看的话,又可以把他们理解为一个硬件模块:包含了输入输出,包含了内部的子模块(LazyModule)和子节点(Node)。

下图是一个Diplomacy框架下的模块:

 

  •  LazyModule:用于进行参数协商。可以理解为对内部Chisel代码的一个封装。
  • LazyModuleImp:内部包含实际的Chisel代码,在chisel实际进行电路生成的过程中,可以访问在上一步Diplomacy协商过程中得到edge中的参数进行实际电路构架。
  • node:进行参数传递和自动连线的接口,需要在 LazyModule内部进行声明,一个LazyModule可以有多个node。node之间使用 := 在在该模块外部进行绑定声明,这里的绑定并不是Chisel中的连线操作,而是Diplomacy中的互联关系声明。Diplomacy在运行过程中,参数会沿着node绑定形成的有向无环图进行传递。
  • edge:edge用于描述两个node之间的连接关系的数据结构的统称,每次绑定,就会在这两个node之间例化一组edge。edge具体包括例化两侧模块所需的参数;用于自动化接线的信号类型;用于进行模块间交互所用的方法。

在使用Diplomacy协议后,硬件生成前需要进行参数协商,根据用户对LazyModule的声明和对node的绑定声明生成描述各个模块之间连接关系的数据结构,Diplomacy按照这个图中进行参数传播并依此例化每个模块的外壳,每个模块根据自己的需要抓取来自协商阶段传递得到的参数并进行符合自身要求的检查。将模块的外壳用线进行互联,线的类型来自上一步的参数传递得到:标准总线协议或clock、中断等。

在chipyard中,用cake pattern进行混入新特征时也要遵循Diplomacy,反映到底层即需要继承两个"cake",一个是"LazyModule",一个是"LazyModuleImp"。

The lazy module defines all the logical connections between generators and exchanges configuration information among them, while the lazy module implementation performs the actual Chisel RTL elaboration.

DigitalTop的config,遵循cake pattern
class DigitalTop(implicit p: Parameters) extends ChipyardSystem with testchipip.CanHavePeripheryCustomBootPin // Enables optional custom boot pin with testchipip.HasPeripheryBootAddrReg // Use programmable boot address register with testchipip.CanHaveTraceIO // Enables optionally adding trace IO with testchipip.CanHaveBackingScratchpad // Enables optionally adding a backing scratchpad with testchipip.CanHavePeripheryBlockDevice // Enables optionally adding the block device with testchipip.CanHavePeripheryTLSerial // Enables optionally adding the backing memory and serial adapter with sifive.blocks.devices.i2c.HasPeripheryI2C // Enables optionally adding the sifive I2C with sifive.blocks.devices.pwm.HasPeripheryPWM // Enables optionally adding the sifive PWM with sifive.blocks.devices.uart.HasPeripheryUART // Enables optionally adding the sifive UART with sifive.blocks.devices.gpio.HasPeripheryGPIO // Enables optionally adding the sifive GPIOs with sifive.blocks.devices.spi.HasPeripherySPIFlash // Enables optionally adding the sifive SPI flash controller with sifive.blocks.devices.spi.HasPeripherySPI // Enables optionally adding the sifive SPI port with icenet.CanHavePeripheryIceNIC // Enables optionally adding the IceNIC for FireSim with chipyard.example.CanHavePeripheryInitZero // Enables optionally adding the initzero example widget with chipyard.example.CanHavePeripheryGCD // Enables optionally adding the GCD example widget with chipyard.example.CanHavePeripheryStreamingFIR // Enables optionally adding the DSPTools FIR example widget with chipyard.example.CanHavePeripheryStreamingPassthrough // Enables optionally adding the DSPTools streaming-passthrough example widget with nvidia.blocks.dla.CanHavePeripheryNVDLA // Enables optionally having an NVDLA with chipyard.clocking.HasChipyardPRCI // Use Chipyard reset/clock distribution with fftgenerator.CanHavePeripheryFFT // Enables optionally having an MMIO-based FFT block with constellation.soc.CanHaveGlobalNoC // Support instantiating a global NoC interconnect { override lazy val module = new DigitalTopModule(this) } class DigitalTopModule[+L <: DigitalTop](l: L) extends ChipyardSystemModule(l) with testchipip.CanHaveTraceIOModuleImp with sifive.blocks.devices.i2c.HasPeripheryI2CModuleImp with sifive.blocks.devices.pwm.HasPeripheryPWMModuleImp with sifive.blocks.devices.uart.HasPeripheryUARTModuleImp with sifive.blocks.devices.gpio.HasPeripheryGPIOModuleImp with sifive.blocks.devices.spi.HasPeripherySPIFlashModuleImp with sifive.blocks.devices.spi.HasPeripherySPIModuleImp with chipyard.example.CanHavePeripheryGCDModuleImp with freechips.rocketchip.util.DontTouch

 

二、Outer and Inner

Note that the outer class extends LazyModule, and the inner class extends LazyModuleImp -- LazyModuleImp is passed a reference to the matching outer class. Both are defined in the Diplomacy package.

即”一“中实现Diplomacy的lazymodule和lazymoduleImp,下面看一个例子来说明:

//This is the outer class
class Example1TileModule(implicit p: Parameters) extends LazyModule {

    // When creating a class (module) that has a TL connection, there is special code that is in a library
    // and has to be pulled in. This special code is what participates in Diplomacy negotiations and this
    // special code implements the actual TL wires. Below, TLClientNode is the name of this special code
    // (there are a few other types of such special code in the TL library). It will generate verilog, and
    // the verilog wires of the TL channels will be wired to the verilog generated from TLClientNode.
    // It is weird syntax because of Scala language mechanics. Use "Seq" to package multiple parameters 
    // that are passed to TLClientNode. Best to just copy-paste and follow the pattern.

    val Node0 = TLClientNode(Seq(TLClientPortParameters(
        Seq(TLClientParameters(
            name = "IdentifierForThisTLConnection",  // shows up when Diplomacy reports an error
            sourceId = IdRange(0, 1)))))) // says at most 1 TL transaction can be outstanding (in-flight) 
                                          // on this TL connection, increase if want more
 
    // Instantiate the inner module! By instantiating here, the inner module can create Chisel wires to node0
    lazy val module = new ExampleTileModuleImp(this) 

    //Note, this all that you put in outer module!! All logic, wires, etc go inside inner module.
}

// This is the inner class. This is where the RTL behavior code goes.
class Example1TileModuleImp (outer: ExampleTileModule) extends LazyModuleImp(outer) {
    val (tl0, edge0) = outer.dmanode0.out(0)
    val addrBits0 = edge0.bundle.addressBits
    val beatBytes = (edge0.bundle.dataBits / 8)

    val blackbox_inst = Module(new tile_blackbox)
    tl0.a <> blackbox_inst.io.tile_a_chan
    tl0.d <> blackbox_inst.io.tile_d_chan

}

 

三、Mixins

Mixin is a class that contains methods for use by other classes without having to be the parent class of those other classes. Mixins are sometimes described as being "included" rather than "inherited".   //定义

Mixins generally use the "trait" keyword and the "with" keyword. The thing you want included is declared using "trait" keyword, and then included using "with" keyword.. (However, once you have created at trait, you can still use "extends" to inherit that trait as the superclass.)   //用法

Here lies the important difference between the concepts of mixins and inheritance, in that the child class can still inherit all the features of the parent class, but, the semantics about the child "being a kind of" the parent need not be necessarily applied.  //区别

一个简单的实例:

abstract class A {
  val message: String
}
class B extends A {
  val message = "I'm an instance of class B"
}
trait C extends A {
  def loudMessage = message.toUpperCase()
}
class D extends B with C

val d = new D
println(d.message)  // I'm an instance of class B
println(d.loudMessage)  // I'M AN INSTANCE OF CLASS B

在上面的例子中,D有一个父类B和一个混入特征C,class可以有多个mixins但只能有一个superclass。

更多有关mixins的内容参见:trait, with, Mixins · librecores/riscv-sodor Wiki (github.com)

https://docs.google.com/document/d/1uitsrMXCNGNCOWTkbR36DLpZAZm2y-Ss7Fu1w3Y7wPA/edit

有关cake pattern的更多信息,参见:Cake Pattern · Intensivate/learning-journey Wiki (github.com)

四、Chipyard中扩展MMIO

chipyard版本:1.8.1

为了基于tilelink添加MMIO外设,我们需要做三件事:

(1)在generators/chipyard/src/main/scala/example目录下创建我们要包含的外设模块

(2)修改DigitalTop.scala以混入特征

(3)在RocketConfig.scala中添加新的配置

为了进行验证,我们需要做两件事:

(1)产生一个仿真器,没有vcs可以用verilator

(2)写c程序,交叉编译验证

 

1,params和key

 

 

2,IO接口

有关verilog和chisel的接口不同,可以参考https://github.com/Intensivate/learning-journey/wiki/Comparison-to-Verilog

 

 将上面创建的IO接口封装成trait用于mixins

 

 

3,chisel外设模块

 

 

4,Memory Mapping

顶层控制信号

 

 

5,用TLRegisterRouter将外设包装进TL接口

 

 

6,创建inner和outer twins用于cake pattern

In Rocket-chip world this is done using common practice known as the Cake Pattern. Basically, this means there will be two more traits – one of them is called inner twin, the other outer twin. The former holds the implementation of our widget, i.e. all the stuff we wrote (ChiselModule wrapped in HasRegMap extension wrapped in TileLink Register Router node) and it’s pretty much unaware of the outside world (the rest of SoC). The latter extends LazyModule, where lazy stands for the code that gets executed before any of the hardware (implementation = inner twin) is elaborated.

 

 

7,mixing

编辑Digitaltop.scala,混入outer和inner trait

 

 在rocketconfigs.scala中添加新的配置

 

 

最后在verilator中make,遗憾报错:

 

 根据提示warn可以知道:

 

 method toVariableWidthSlave in trait CanAttachTLSlaves is deprecated (since rocket-chip 1.3): Replace with e.g. bus.coupleTo(s"slave_named_${name}"){ slave.controlXing(NoCrossing) :*= TLFragmenter(bus.beatBytes, bus.blockBytes) :*= _ }

在仔细检查语法和缩进后,warning消失,但error仍在。

在尝试运用原来教程的config配置后,显示iobinder中trait不存在,显然这是由于版本原因,以前的教程在1.8.1版本上不适用了。

所以唯一可以参考的就是官方doc,尝试仿照GCD.scala进行改写:

 

标签:LazyModule,adding,optionally,Diplomacy,Pattern,chip,Cake,Enables,class
From: https://www.cnblogs.com/hwzhao/p/17125261.html

相关文章

  • [Typescript] Creating Chainable Method Abstractions with Generics and the Builde
    import{expect,it}from"vitest";import{fetchUser}from"fake-external-lib";typeMiddleware<TInput,TOutput>=(input:TInput)=>TOutput;classDyna......
  • [Typescript] Default value for Builder pattern - 04 (keyof {} -> never)
    Frompreviouspost,Builderpattern-03Ifwedothefollowingchanges:-classTypeSafeStringMap<TMapextendsRecord<string,string>={}>{+classTypeSafe......
  • [Typescript] Builder pattern - 03
    import{expect,it}from'vitest';classTypeSafeStringMap<TMapextendsRecord<string,string>={}>{privatemap:TMap;constructor(){this.map=......
  • C - Cake HDU - 1722 (数学)
    题意:就是一个蛋糕,被分成n或者m份。问最少动几刀。看一下这个图,就知道公式了,n+m-gcd(n,m);#include<cstdio>#include<iostream>usingnamespacestd;#definelllon......
  • C - Cake HDU - 1722 (数学)
    题意:就是一个蛋糕,被分成n或者m份。问最少动几刀。看一下这个图,就知道公式了,n+m-gcd(n,m);#include<cstdio>#include<iostream>usingnamespacestd;#definelllon......
  • [Typescript] Builder pattern - 02
    exportclassBuilderTuple<TListextendsany[]=[]>{list:TList;constructor(){this.list=[]asany;}push<TNumextendsnumber>(num:TNum):......
  • C - Cake HDU - 1722 (数学)
    题意:就是一个蛋糕,被分成n或者m份。问最少动几刀。看一下这个图,就知道公式了,n+m-gcd(n,m);#include<cstdio>#include<iostream>usingnamespacestd;#definelllon......
  • Chips on a Board
    ChipsonaBoard题目就是让我们求\((x-l)\)的异或和,对于减\(l\),我们不好处理,考虑在减\(l\)的限制下拆位,那么我们发现对于在\([l+2^j,l+2^{j+1}-1]\)的数最高......
  • CF1511G Chips on a Board
    CF1511GChipsonaBoard比较有启发性的一道题。询问是最简单的nim游戏,不难发现若一列上有两个棋子,那么这两个棋子对于答案是没有贡献的,因此可以令\(c_i\)表示第\(......
  • ChIP-seq 分析:原始数据质控(2)
    1.ChIPseq简介染色质免疫沉淀,然后进行深度测序(ChIPseq)是一种成熟的技术,可以在全基因组范围内识别转录因子结合位点和表观遗传标记。1.1.实验处理交联和蛋白质......