{"id":13648909,"url":"https://github.com/sifive/fpga-shells","last_synced_at":"2025-08-15T22:12:08.558Z","repository":{"id":24924648,"uuid":"98235760","full_name":"sifive/fpga-shells","owner":"sifive","description":null,"archived":false,"fork":false,"pushed_at":"2022-05-13T18:08:40.000Z","size":954,"stargazers_count":135,"open_issues_count":21,"forks_count":65,"subscribers_count":41,"default_branch":"master","last_synced_at":"2025-06-24T06:08:18.185Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sifive.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-07-24T21:17:22.000Z","updated_at":"2025-05-19T09:03:30.000Z","dependencies_parsed_at":"2022-08-03T04:15:46.273Z","dependency_job_id":null,"html_url":"https://github.com/sifive/fpga-shells","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sifive/fpga-shells","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sifive%2Ffpga-shells","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sifive%2Ffpga-shells/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sifive%2Ffpga-shells/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sifive%2Ffpga-shells/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sifive","download_url":"https://codeload.github.com/sifive/fpga-shells/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sifive%2Ffpga-shells/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270637241,"owners_count":24620425,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-15T02:00:12.559Z","response_time":110,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T01:04:38.312Z","updated_at":"2025-08-15T22:12:08.497Z","avatar_url":"https://github.com/sifive.png","language":"Scala","readme":"# fpga-shells\n\nAn FPGA shell is a Chisel module designed to wrap any SiFive core configuration.\nThe goal of the fpga-shell system is to reduce the number of wrappers to have only\none for each physical device rather than one for every combination of physical device and core configuration.\n\nEach shell consists of Overlays which use dependency injection to create and connect peripheral device interfaces in an FPGADesign to the toplevel shell module.\n\nMost devices already have an overlay defined for them in `src/main/scala/shell[/xilinx]`.\nIf you're using a Xilinx device, you'll probably want to use the xilinx-specific overlay\nbecause it defines a few things that you'd otherwise have to specify yourself.\n\nGenerally, you'll want to create a device shell that extends `Series7Shell` or `UltraScaleShell`.\nIf you need different functionality (or you're not using a Xilinx device), you can extend `Shell` and implement abstract members.\nSome Microsemi devices are supported by fgpa-shells as well (and can be found in `src/main/scala/shell/microsemi`)\n\nFor example:\n\n```Scala\nclass DeviceShell()(implicit p: Parameters) extends UltraScaleShell {\n  // create Overlays\n  val myperipheral = Overlay(PeripheralOverlayKey) (new PeripheralOverlay(_,_,_))\n  // ...\n\n  // assign abstract members\n  val pllReset = InModuleBody { Wire(Bool()) }\n  val topDesign = LazyModule(p(DesignKey)(designParameters))\n\n  // ensure clocks are connected\n  designParameters(ClockInputOverlayKey).foreach { unused =\u003e\n    val source = unused(ClockInputOverlayParams())\n    val sink = ClockSinkNode(Seq(ClockSinkParameters()))\n    sink := source\n  }\n\n  // override module implementation to connect reset\n  override lazy val module = new LazyRawModuleImp(this) {\n    val reset = IO(Input(Bool()))\n    pllReset := reset\n  }\n}\n```\n\nEach peripheral device to be added to the shell must define an `Overlay`, which creates the device and connects it to the toplevel shell.\nIn addition, in order to access the overlay, the device needs to have a `case class OverlayParams` and a `case object OverlayKey`\n\n```Scala\ncase class PeripheralOverlayParams()(implicit val p: Parameters)\ncase object PeripheralOverlayKey extends Field[Seq[DesignOverlay[PeripheralOverlayParams, PeripheralDesignOutput]]](Nil)\n```\n\nIf 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.\nTypically, devices are connected to a TileLink bus for processor control, so `PeripheralDesignOutput` can usually be substituted with `TLInwardNode`.\n\nThe `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)\nand `DesignOutput`.\n\n```Scala\nabstract class AbstractPeripheralOverlay(val params: PeripheralOverlayParams)\n  extends IOOverlay[PeripheralDeviceIO, PeripheralDesignOutput]\n{\n  // assign abstract member p (used to access overlays with their key)\n  // e.g. p(PeripheralOverlayKey) will return a Seq[DesignOverlay[PeripheralOverlayParams, PeripheralDesignOutput]]\n  implicit val p = params.p\n}\n```\n\nContinuing our example with a `DeviceShell` shell, the actual overlay is constructed by extending our abstract `PeripheralOverlay`\n```Scala\nclass ConcretePeripheralOverlay(val shell: DeviceShell, val name: String, params: PeripheralOverlayParams)\n  extends AbstractPeripheralOverlay(params)\n{\n  val device = LazyModule(new PeripheralDevice(PeripheralDeviceParams(???))) // if your peripheral device isn't parameterizable, then it'll have an empty constructor\n\n  def ioFactory = new PeripheralDeviceIO // ioFactory defines interface of val io\n  val designOutput = device.node\n\n  // this is where \"code-injection\" starts\n  val ioSource = BundleBridgeSource(() =\u003e device.module.io.cloneType) // create a bridge between device (source) and shell (sink)\n  val ioSink = shell { ioSource.makeSink() }\n\n  InModuleBody { ioSource.bundle \u003c\u003e device.module.io }\n\n  shell { InModuleBody {\n    val port = ioSink.bundle\n\n    io \u003c\u003e port // io is the bundle of shell-level IO as specified by ioFactory\n  } }\n}\n```\n\nThe actual device implementation (where the device's functionality is defined) will be something like this:\n```Scala\ncase class PeripheralDeviceParams(param1: Param1Type, ???) // only necessary if your device is parameterizable\nclass PeripheralDevice(c: PeripheralDeviceParams)(implicit p: Parameters) extends LazyModule {\n  \n  val node: PeripheralDesignOutput = ???\n\n  // device implementation\n  lazy val module = new LazyModuleImp(this) {\n    val io = ???\n    ???\n  }\n}\n```\n","funding_links":[],"categories":["Scala","FPGA Learning Resources","Resources"],"sub_categories":["Interfaces","Mesh networks"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsifive%2Ffpga-shells","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsifive%2Ffpga-shells","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsifive%2Ffpga-shells/lists"}