Extending Rocket Chip with Verilog Peripheral IPs

SiFive RISC-V/Chisel线下交流会, 中科院信息工程研究所的宋威老师分享。


1.Extending Rocket Chip with Verilog Peripheral IPs Wei Song (宋威) Former hardware designer for lowRISC (v0.1 – v0.4) 8th September, 2018

2.lowRISC Project • lowRISC is a not for profit organization from the University of Cambridge. – Provide open-source and free SoCs. – Linux capable. – Highly customizable. – Based on Rocket-chip (RV64G). – Do not enforce the use of Chisel. • Encapsulated Chisel islands of Rocket and caches. • SystemVerilog top-level and interconnects. • SystemVerilog AXI interfaces for peripheral IPs. 2

3. lowRISC SoC Today’s topic: A generic and extendable AXI interface. 3

4.Rocket’s Way of Adding Peripherals • Each peripheral is wrapped by a TileLink Node, either an AXI4Port or a dedicated TLNode. • The peripheral’s parameter is back- propagated to each L1 cache and the global device tree. • L1 cache can check IO access violations accordingly. • Example memory map: bootrom: 0x00000000 – 0x00004000 RX RTC: 0x10000000 – 0x10004000 WR uart: 0x10004000 – 0x10008000 WR bram: 0x20000000 – 0x20800000 WRX • Access to 0x10009000 would cause a synchronous exception in L1 $. 4

5.What lowRISC Expects • A single AXI port is exposed. • Peripherals can be attached to this single AXI bus using Verilog. • Peripherals’ parameters are still back- propagated to the global device tree and all L1 $. • Using AXI4MMIOPort provided by Rocket-chip: bootrom: 0x00000000 – 0x00004000 RX RTC: 0x10000000 – 0x10004000 WR AXI: 0x20000000 – 0x40000000 WRX (shared by UART and BRAM) - UART 0x20000000 – 0x20004000 WR - BRAM 0x30000000 – 0x30800000 WRX 5 • Access to 0x20009000 would NOT cause any exception in L1 $!

6.The Problem • The AXI4MMIOPort is by default represented by a single node in the device tree and address map. • To use this node, end user needs to: – Manually calculate the combined address map for the IO bus. – Manually allocate interrupt lines. – No direct method to add device into the generated device tree. • Our solution: – Extend the diplomacy package to implement an AXI4VirtualBusNode which is the root of a virtual tree representing the IO bus. – This AXI4VirtualBusNode can automatically derive the parameters, add nodes in the device tree and connect interrupts. – It also produces an AXI4 port like the AXI4MMIOPort for the external Verilog peripherals. 6

7.Overview of Diplomacy • Diplomacy is a framework for negotiating the parameterization of protocol implementations. • Compile time negotiation of parameters. • Every agent is a diplomacy node. • Node is a software entity rather than a real hardware module. 7

8. Virtual Bus • AXI4VirtualBusNode: Produce an AXI port to the external Verilog and act as the root diplomacy node for the external AXI bus. • AXI4VirtualSlaveNode: For each peripheral added to the global configuration, the SoC generator adds a slave node accordingly. • The virtual diplomacy tree back-propagates address map, interrupts for the global device tree similar to normal diplomacy nodes. 8

9.Implementation of Virtual Nodes • TileLink – MixedNode is the common base class • (BaseNode, InwardNode, OutwardNode) > MixedNode – Bus(crossbar) • MixedNode > MixedNexusNode > NexusNode > TLNexusNode – Peripheral device • MixedNode > SinkNode > AXI4SlaveNode • lowRISC extension – VirtualNode is the common base class • (BaseNode, InwardNode, OutwardNode) > VirtualNode • Remove the bundle connection – Bus(port) • VirtualNode > VirtualBusNode > AXI4VirtualBusNode • Produce a port – Peripheral device (diplomacy node only) • VirtualNode > VirtualSlaveNode > AXI4VirtualSlaveNode 9

10.Global Configuration // define a peripheral case class ExSlaveParams( name: String, device: () => SimpleDevice, base: BigInt, size: BigInt, resource: Option[String] = None, Define the parameters interrupts: Int = 0, of a single peripheral burstBytes: Int = 64, // needs to be set >= 64 readable: Boolean = true, writeable: Boolean = true, executable: Boolean = false ) // a collection of all Verilog peripherals case class ExPeriperalsParams( beatBytes: Int, Collect all peripherals idBits: Int, in a global object slaves: Seq[ExSlaveParams] ) 10

11.Chip Generator trait HasAXI4VirtualBus extends HasPeripheryBus { val mmio_axi4 = AXI4VirtualBusNode(…) AXI port p(ExPeriperals).slaves.foreach( d => { val slave = AXI4VirtualSlaveNode( Seq(AXI4SlavePortParameters(slaves = Seq(AXI4SlaveParameters( address = Seq(AddressSet(d.base, d.size - 1)), resources = d.resource.map(device.reg(_)).getOrElse(device.reg), … Generate )), virtual node beatBytes = p(ExPeriperals).beatBytes for each ))) peripheral slave :*= mmio_axi4 if(d.interrupts > 0) { val intnode = IntInternalInputNode(…) ibus.fromSync := intnode }) connect port mmio_axi4 := AXI4Buffer()(AXI4UserYanker()(AXI4Deinterleaver()(AXI4IdIndexer(p(ExPeriperals).idBits)( TLToAXI4(p(ExPeriperals).beatBytes)(pbus.toVariableWidthSlaves))))) } 11

12.Adding a UART class LoRCCoreplexModule[+L <: LoRCCoreplex](_outer: L) extends RocketCoreplexModule(_outer) with HasRTCModuleImp with HasMasterAXI4MemPortModuleImp Add VirtualBus with HasAXI4VirtualBusModuleImp into the cake with HasSlaveAXI4PortModuleImp pattern with HasPeripheryBootROMModuleImp class WithUART extends Config(Parameters.empty) { SlaveDevice.entries += ExSlaveParams( name = "uart", Write a device = () => new SimpleDevice("serial",Seq("xlnx,uart16550")), configuration base = 0x41002000, class for the size = 0x00002000, // 8KB interrupts = 1 UART ) } class LoRCNexys4Config extends Config( new WithUART ++ new WithBootRAM ++ Use the UART new WithNBigCores(1) ++ new LoRCBaseConfig) configuration 12

13. Conclusions • Diplomacy is a powerful software package to enable compile time parameter negotiation, much powerful than the parameters in SystemVerilog. • A diplomacy node is not necessarily attached to a Chisel hardware module. • By extending the diplomacy package with some extension in the Rocket-Chip generator, we can easily support automatic device tree generation for Verilog peripherals. – Diplomacy: 190 lines https://github.com/lowRISC/lowrisc-chip/blob/update/src/main/scala/diplomacy/VNodes.scala – Rocket-Chip generator: 300 lines https://github.com/lowRISC/lowrisc-chip/tree/update/src/main/scala/lowrisc 13

14.Thank You! 14