Code Monkey home page Code Monkey logo

rocket-chip-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 = ???
    ???
  }
}

rocket-chip-fpga-shells's People

Contributors

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

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rocket-chip-fpga-shells's Issues

Issue when using vc707 in chipyard

Hi, I'm currently using vc707 with the chipyard project. During compilation, vivado emits an error and quits. The terminal shows something like this

****** Vivado v2021.2 (64-bit)                                                                                                           
  **** SW Build 3367213 on Tue Oct 19 02:47:39 MDT 2021                                                                                  
  **** IP Build 3369179 on Thu Oct 21 08:25:16 MDT 2021                                                                                  
    ** Copyright 1986-2021 Xilinx, Inc. All Rights Reserved.                                                                             
                                                                                                                                         
source /home/loriland/Documents/chipyard/fpga/fpga-shells/xilinx/common/tcl/vivado.tcl                                                   
# set scriptdir [file dirname [info script]]                                                                                             
# source [file join $scriptdir "prologue.tcl"]                                                                                           
## set ip_vivado_tcls {}                                                                                                                 
## while {[llength $argv]} {                                                                                                             
##   set argv [lassign $argv[set argv {}] flag]                                                                                          
##   switch -glob $flag {                                                                                                                
##     -top-module {                                                                                                                     
##       set argv [lassign $argv[set argv {}] top]                                                                                       
##     }                                                                                                                                 
##     -F {                                                                                                                              
##       # This should be a simple file format with one filepath per line                                                                
##       set argv [lassign $argv[set argv {}] vsrc_manifest]                                                                             
##     }                                                                                                                                 
##     -board {                                                                                                                          
##       set argv [lassign $argv[set argv {}] board]                                                                                     
##     }                                                                                                                                 
##     -ip-vivado-tcls {                                                                                                                 
##       set argv [lassign $argv[set argv {}] ip_vivado_tcls]                                                                            
##     }                                                                                                                                 
##     -pre-impl-debug-tcl {                                                                                                             
##       set argv [lassign $argv[set argv {}] pre_impl_debug_tcl]                                                                        
##     }                                                                                                                                 
##     -post-impl-debug-tcl {                                                                                                            
##       set argv [lassign $argv[set argv {}] post_impl_debug_tcl]                                                                       
##     }                                                                                                                                 
##     -env-var-srcs {                                                                                                                   
##       set argv [lassign $argv[set argv {}] env_var_srcs]                                                                              
##     }                                                                                                                                 
##     default {                                                                                                                         
##       return -code error [list {unknown option} $flag]                                                                                
##     }                                                                                                                                 
##   }                                                                                                                                   
## }                                                                                                                                     
## if {![info exists top]} {                                                                                                             
##   return -code error [list {--top-module option is required}]                                                                         
## }                                                                                                                                     
## if {![info exists vsrc_manifest]} {                                                                                                   
##   return -code error [list {-F option is required}]                                                                                   
## }                                                                                                                                     
## if {![info exists board]} {                                                                                                           
##   return -code error [list {--board option is required}]                                                                              
## }                                                                                                                                     
## set commondir [file dirname $scriptdir]
## set boarddir [file join [file dirname $commondir] $board]
## source [file join $boarddir tcl board.tcl]
### set name {vc707}
### set part_fpga {xc7vx485tffg1761-2}
### set part_board {xilinx.com:vc707:part0:1.3} 
## set constraintsdir [file join $boarddir constraints]
## set srcdir [file join $commondir vsrc]
## set wrkdir [file join [pwd] obj]
## set ipdir [file join $wrkdir ip]
## create_project -part $part_fpga -force $top
create_project: Time (s): cpu = 00:00:04 ; elapsed = 00:00:07 . Memory (MB): peak = 2506.340 ; gain = 0.000 ; free physical = 20050 ; fre
e virtual = 60480
## set_param messaging.defaultLimit 1000000
## set_property -dict [list \
##      BOARD_PART $part_board \
##      TARGET_LANGUAGE {Verilog} \
##      DEFAULT_LIB {xil_defaultlib} \
##      IP_REPO_PATHS $ipdir \
##      ] [current_project]
ERROR: [Board 49-71] The board_part definition was not found for xilinx.com:vc707:part0:1.3. The project's board_part property was not se
t, but the project's part property was set to xc7vx485tffg1761-2. Valid board_part values can be retrieved with the 'get_board_parts' Tcl
 command. Check if board.repoPaths parameter is set and the board_part is installed from the tcl app store.
INFO: [Common 17-17] undo 'set_property'

    while executing
"rdi::add_properties -dict {BOARD_PART xilinx.com:vc707:part0:1.3 TARGET_LANGUAGE Verilog DEFAULT_LIB xil_defaultlib IP_REPO_PATHS /home/
loriland/Docum..."
    invoked from within
"set_property -dict [list \
        BOARD_PART $part_board \
        TARGET_LANGUAGE {Verilog} \
        DEFAULT_LIB {xil_defaultlib} \
        IP_REPO_PATHS $ipdir \
        ] [current_..."
    (file "/home/loriland/Documents/chipyard/fpga/fpga-shells/xilinx/common/tcl/prologue.tcl" line 78)

    while executing
"source [file join $scriptdir "prologue.tcl"]"
    (file "/home/loriland/Documents/chipyard/fpga/fpga-shells/xilinx/common/tcl/vivado.tcl" line 7)
INFO: [Common 17-206] Exiting Vivado at Mon Nov 14 21:01:25 2022...
make: *** [Makefile:129: /home/loriland/Documents/chipyard/fpga/generated-src/chipyard.fpga.vc707.VC707FPGATestHarness.RocketVC707Config/
obj/VC707FPGATestHarness.bit] Error 1

Went to xilinx/vc707/tcl/board.tcl to check, found that if I modify the part_board value from xilinx.com:vc707:part0:1.3 to xilinx.com:vc707:part0:1.4, program runs correctly.

Not sure if this is a bug, but probably need a fix

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.