Coder Social home page Coder Social logo

t-k-233 / chipyard-fpga-shells Goto Github PK

View Code? Open in Web Editor NEW

This project forked from chipsalliance/rocket-chip-fpga-shells

0.0 0.0 0.0 788 KB

Wrapper shells enabling designs generated by rocket-chip to map onto certain FPGA boards

License: Apache License 2.0

Scala 73.46% Tcl 10.08% Verilog 8.75% SystemVerilog 7.58% Makefile 0.14%

chipyard-fpga-shells's Introduction

FPGA Shells for the Rocket Chip Generator

An FPGA shell is a Chisel module designed to wrap any Rocket Chip subsystem configuration. The goal of the fpga-shell system is to reduce the number of wrappers so as to have only one for each physical device rather than one for every combination of physical device and core configuration.

This repository replaces https://github.com/sifive/fpga-shells

Each shell consists of Overlays which use dependency injection to create and connect peripheral device interfaces in an FPGADesign to the toplevel shell module.

Most devices already have an overlay defined for them in src/main/scala/shell[/xilinx]. If you're using a Xilinx device, you'll probably want to use the xilinx-specific overlay because it defines a few things that you'd otherwise have to specify yourself.

Generally, you'll want to create a device shell that extends Series7Shell or UltraScaleShell. If you need different functionality (or you're not using a Xilinx device), you can extend Shell and implement abstract members. Some Microsemi devices are supported by fgpa-shells as well (and can be found in src/main/scala/shell/microsemi)

For example:

class DeviceShell()(implicit p: Parameters) extends UltraScaleShell {
  // create Overlays
  val myperipheral = Overlay(PeripheralOverlayKey) (new PeripheralOverlay(_,_,_))
  // ...

  // assign abstract members
  val pllReset = InModuleBody { Wire(Bool()) }
  val topDesign = LazyModule(p(DesignKey)(designParameters))

  // ensure clocks are connected
  designParameters(ClockInputOverlayKey).foreach { unused =>
    val source = unused(ClockInputOverlayParams())
    val sink = ClockSinkNode(Seq(ClockSinkParameters()))
    sink := source
  }

  // override module implementation to connect reset
  override lazy val module = new LazyRawModuleImp(this) {
    val reset = IO(Input(Bool()))
    pllReset := reset
  }
}

Each peripheral device to be added to the shell must define an Overlay, which creates the device and connects it to the toplevel shell. In addition, in order to access the overlay, the device needs to have a case class OverlayParams and a case object OverlayKey

case class PeripheralOverlayParams()(implicit val p: Parameters)
case object PeripheralOverlayKey extends Field[Seq[DesignOverlay[PeripheralOverlayParams, PeripheralDesignOutput]]](Nil)

If the device is parameterizable, then each parameter for the device creation can be passed to the PeripheralOverlayParams constructor by adding a field for said parameter. Typically, devices are connected to a TileLink bus for processor control, so PeripheralDesignOutput can usually be substituted with TLInwardNode.

The Overlay extends IOOverlay which is paramerized by the device's IO (in this case PeripheralDeviceIO is a subtype of Data and is a port specification for the peripheral device) and DesignOutput.

abstract class AbstractPeripheralOverlay(val params: PeripheralOverlayParams)
  extends IOOverlay[PeripheralDeviceIO, PeripheralDesignOutput]
{
  // assign abstract member p (used to access overlays with their key)
  // e.g. p(PeripheralOverlayKey) will return a Seq[DesignOverlay[PeripheralOverlayParams, PeripheralDesignOutput]]
  implicit val p = params.p
}

Continuing our example with a DeviceShell shell, the actual overlay is constructed by extending our abstract PeripheralOverlay

class ConcretePeripheralOverlay(val shell: DeviceShell, val name: String, params: PeripheralOverlayParams)
  extends AbstractPeripheralOverlay(params)
{
  val device = LazyModule(new PeripheralDevice(PeripheralDeviceParams(???))) // if your peripheral device isn't parameterizable, then it'll have an empty constructor

  def ioFactory = new PeripheralDeviceIO // ioFactory defines interface of val io
  val designOutput = device.node

  // this is where "code-injection" starts
  val ioSource = BundleBridgeSource(() => device.module.io.cloneType) // create a bridge between device (source) and shell (sink)
  val ioSink = shell { ioSource.makeSink() }

  InModuleBody { ioSource.bundle <> device.module.io }

  shell { InModuleBody {
    val port = ioSink.bundle

    io <> port // io is the bundle of shell-level IO as specified by ioFactory
  } }
}

The actual device implementation (where the device's functionality is defined) will be something like this:

case class PeripheralDeviceParams(param1: Param1Type, ???) // only necessary if your device is parameterizable
class PeripheralDevice(c: PeripheralDeviceParams)(implicit p: Parameters) extends LazyModule {
  
  val node: PeripheralDesignOutput = ???

  // device implementation
  lazy val module = new LazyModuleImp(this) {
    val io = ???
    ???
  }
}

chipyard-fpga-shells's People

Contributors

erikdanie avatar terpstra avatar rmac-sifive avatar cyril-jean avatar henrystyles avatar sequencer avatar mwachs5 avatar zaddan avatar hcook avatar jerryz123 avatar donthus avatar jackkoenig avatar ernie-sifive avatar albertchen-sifive avatar rajeshvaradharajan avatar ss2783 avatar singularitykchen avatar reedafoster avatar kowshiksifive avatar mcd500 avatar aswaterman avatar abejgonzalez avatar kimdh727 avatar mmjconolly avatar mhtwn avatar oceans2000 avatar soheil-shababi avatar richardxia avatar felixonmars avatar jacka1201 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.