Merge remote-tracking branch 'origin/master' into firrtl-1.4-remove-clk-stuff
This commit is contained in:
@@ -4,7 +4,7 @@ package barstools.iocell.chisel
|
|||||||
|
|
||||||
import chisel3._
|
import chisel3._
|
||||||
import chisel3.util.{Cat, HasBlackBoxResource}
|
import chisel3.util.{Cat, HasBlackBoxResource}
|
||||||
import chisel3.experimental.{Analog, DataMirror, IO}
|
import chisel3.experimental.{Analog, DataMirror, IO, BaseModule}
|
||||||
|
|
||||||
// The following four IO cell bundle types are bare-minimum functional connections
|
// The following four IO cell bundle types are bare-minimum functional connections
|
||||||
// for modeling 4 different IO cell scenarios. The intention is that the user
|
// for modeling 4 different IO cell scenarios. The intention is that the user
|
||||||
@@ -63,21 +63,21 @@ class DigitalInIOCellBundle extends Bundle {
|
|||||||
val ie = Input(Bool())
|
val ie = Input(Bool())
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class IOCell extends BlackBox
|
trait IOCell extends BaseModule
|
||||||
|
|
||||||
abstract class AnalogIOCell extends IOCell {
|
trait AnalogIOCell extends IOCell {
|
||||||
val io: AnalogIOCellBundle
|
val io: AnalogIOCellBundle
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class DigitalGPIOCell extends IOCell {
|
trait DigitalGPIOCell extends IOCell {
|
||||||
val io: DigitalGPIOCellBundle
|
val io: DigitalGPIOCellBundle
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class DigitalInIOCell extends IOCell {
|
trait DigitalInIOCell extends IOCell {
|
||||||
val io: DigitalInIOCellBundle
|
val io: DigitalInIOCellBundle
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class DigitalOutIOCell extends IOCell {
|
trait DigitalOutIOCell extends IOCell {
|
||||||
val io: DigitalOutIOCellBundle
|
val io: DigitalOutIOCellBundle
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,54 +85,55 @@ abstract class DigitalOutIOCell extends IOCell {
|
|||||||
// implementation of an IO cell. For building a real chip, it is important to implement
|
// implementation of an IO cell. For building a real chip, it is important to implement
|
||||||
// and use similar classes which wrap the foundry-specific IO cells.
|
// and use similar classes which wrap the foundry-specific IO cells.
|
||||||
|
|
||||||
trait IsGenericIOCell extends HasBlackBoxResource {
|
abstract class GenericIOCell extends BlackBox with HasBlackBoxResource {
|
||||||
addResource("/barstools/iocell/vsrc/IOCell.v")
|
addResource("/barstools/iocell/vsrc/IOCell.v")
|
||||||
}
|
}
|
||||||
|
|
||||||
class GenericAnalogIOCell extends AnalogIOCell with IsGenericIOCell {
|
class GenericAnalogIOCell extends GenericIOCell with AnalogIOCell {
|
||||||
val io = IO(new AnalogIOCellBundle)
|
val io = IO(new AnalogIOCellBundle)
|
||||||
}
|
}
|
||||||
|
class GenericDigitalGPIOCell extends GenericIOCell with DigitalGPIOCell {
|
||||||
class GenericDigitalGPIOCell extends DigitalGPIOCell with IsGenericIOCell {
|
|
||||||
val io = IO(new DigitalGPIOCellBundle)
|
val io = IO(new DigitalGPIOCellBundle)
|
||||||
}
|
}
|
||||||
|
class GenericDigitalInIOCell extends GenericIOCell with DigitalInIOCell {
|
||||||
class GenericDigitalInIOCell extends DigitalInIOCell with IsGenericIOCell {
|
|
||||||
val io = IO(new DigitalInIOCellBundle)
|
val io = IO(new DigitalInIOCellBundle)
|
||||||
}
|
}
|
||||||
|
class GenericDigitalOutIOCell extends GenericIOCell with DigitalOutIOCell {
|
||||||
class GenericDigitalOutIOCell extends DigitalOutIOCell with IsGenericIOCell {
|
|
||||||
val io = IO(new DigitalOutIOCellBundle)
|
val io = IO(new DigitalOutIOCellBundle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
trait IOCellTypeParams {
|
||||||
|
def analog(): AnalogIOCell
|
||||||
|
def gpio(): DigitalGPIOCell
|
||||||
|
def input(): DigitalInIOCell
|
||||||
|
def output(): DigitalOutIOCell
|
||||||
|
}
|
||||||
|
|
||||||
|
case class GenericIOCellParams() extends IOCellTypeParams {
|
||||||
|
def analog() = Module(new GenericAnalogIOCell)
|
||||||
|
def gpio() = Module(new GenericDigitalGPIOCell)
|
||||||
|
def input() = Module(new GenericDigitalInIOCell)
|
||||||
|
def output() = Module(new GenericDigitalOutIOCell)
|
||||||
|
}
|
||||||
|
|
||||||
object IOCell {
|
object IOCell {
|
||||||
|
|
||||||
def genericAnalog() = Module(new GenericAnalogIOCell)
|
|
||||||
def genericGPIO() = Module(new GenericDigitalGPIOCell)
|
|
||||||
def genericInput() = Module(new GenericDigitalInIOCell)
|
|
||||||
def genericOutput() = Module(new GenericDigitalOutIOCell)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* From within a RawModule or MultiIOModule context, generate new module IOs from a given
|
* From within a RawModule or MultiIOModule context, generate new module IOs from a given
|
||||||
* signal and return the new IO and a Seq containing all generated IO cells.
|
* signal and return the new IO and a Seq containing all generated IO cells.
|
||||||
* @param coreSignal The signal onto which to add IO cells
|
* @param coreSignal The signal onto which to add IO cells
|
||||||
* @param name An optional name or name prefix to use for naming IO cells
|
* @param name An optional name or name prefix to use for naming IO cells
|
||||||
* @param inFn A function to generate a DigitalInIOCell to use for input signals
|
|
||||||
* @param outFn A function to generate a DigitalOutIOCell to use for output signals
|
|
||||||
* @param anaFn A function to generate an AnalogIOCell to use for analog signals
|
|
||||||
* @param abstractResetAsAsync When set, will coerce abstract resets to
|
* @param abstractResetAsAsync When set, will coerce abstract resets to
|
||||||
* AsyncReset, and otherwise to Bool (sync reset)
|
* AsyncReset, and otherwise to Bool (sync reset)
|
||||||
* @return A tuple of (the generated IO data node, a Seq of all generated IO cell instances)
|
* @return A tuple of (the generated IO data node, a Seq of all generated IO cell instances)
|
||||||
*/
|
*/
|
||||||
def generateIOFromSignal[T <: Data](coreSignal: T, name: Option[String] = None,
|
def generateIOFromSignal[T <: Data](coreSignal: T, name: String,
|
||||||
inFn: () => DigitalInIOCell = IOCell.genericInput,
|
typeParams: IOCellTypeParams = GenericIOCellParams(),
|
||||||
outFn: () => DigitalOutIOCell = IOCell.genericOutput,
|
|
||||||
anaFn: () => AnalogIOCell = IOCell.genericAnalog,
|
|
||||||
abstractResetAsAsync: Boolean = false): (T, Seq[IOCell]) =
|
abstractResetAsAsync: Boolean = false): (T, Seq[IOCell]) =
|
||||||
{
|
{
|
||||||
val padSignal = IO(DataMirror.internal.chiselTypeClone[T](coreSignal))
|
val padSignal = IO(DataMirror.internal.chiselTypeClone[T](coreSignal)).suggestName(name)
|
||||||
val resetFn = if (abstractResetAsAsync) toAsyncReset else toSyncReset
|
val resetFn = if (abstractResetAsAsync) toAsyncReset else toSyncReset
|
||||||
val iocells = IOCell.generateFromSignal(coreSignal, padSignal, name, inFn, outFn, anaFn, resetFn)
|
val iocells = IOCell.generateFromSignal(coreSignal, padSignal, Some(s"iocell_$name"), typeParams, resetFn)
|
||||||
(padSignal, iocells)
|
(padSignal, iocells)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,9 +143,6 @@ object IOCell {
|
|||||||
* @param coreSignal The core-side (internal) signal onto which to connect/add IO cells
|
* @param coreSignal The core-side (internal) signal onto which to connect/add IO cells
|
||||||
* @param padSignal The pad-side (external) signal onto which to connect IO cells
|
* @param padSignal The pad-side (external) signal onto which to connect IO cells
|
||||||
* @param name An optional name or name prefix to use for naming IO cells
|
* @param name An optional name or name prefix to use for naming IO cells
|
||||||
* @param inFn A function to generate a DigitalInIOCell to use for input signals
|
|
||||||
* @param outFn A function to generate a DigitalOutIOCell to use for output signals
|
|
||||||
* @param anaFn A function to generate an AnalogIOCell to use for analog signals
|
|
||||||
* @return A Seq of all generated IO cell instances
|
* @return A Seq of all generated IO cell instances
|
||||||
*/
|
*/
|
||||||
val toSyncReset: (Reset) => Bool = _.toBool
|
val toSyncReset: (Reset) => Bool = _.toBool
|
||||||
@@ -153,9 +151,7 @@ object IOCell {
|
|||||||
coreSignal: T,
|
coreSignal: T,
|
||||||
padSignal: T,
|
padSignal: T,
|
||||||
name: Option[String] = None,
|
name: Option[String] = None,
|
||||||
inFn: () => DigitalInIOCell = IOCell.genericInput,
|
typeParams: IOCellTypeParams = GenericIOCellParams(),
|
||||||
outFn: () => DigitalOutIOCell = IOCell.genericOutput,
|
|
||||||
anaFn: () => AnalogIOCell = IOCell.genericAnalog,
|
|
||||||
concretizeResetFn : (Reset) => R = toSyncReset): Seq[IOCell] =
|
concretizeResetFn : (Reset) => R = toSyncReset): Seq[IOCell] =
|
||||||
{
|
{
|
||||||
def genCell[T <: Data](
|
def genCell[T <: Data](
|
||||||
@@ -165,7 +161,7 @@ object IOCell {
|
|||||||
padSignal: T): Seq[IOCell] = {
|
padSignal: T): Seq[IOCell] = {
|
||||||
DataMirror.directionOf(coreSignal) match {
|
DataMirror.directionOf(coreSignal) match {
|
||||||
case ActualDirection.Input => {
|
case ActualDirection.Input => {
|
||||||
val iocell = inFn()
|
val iocell = typeParams.input()
|
||||||
name.foreach(n => iocell.suggestName(n))
|
name.foreach(n => iocell.suggestName(n))
|
||||||
coreSignal := castFromBool(iocell.io.i)
|
coreSignal := castFromBool(iocell.io.i)
|
||||||
iocell.io.ie := true.B
|
iocell.io.ie := true.B
|
||||||
@@ -173,7 +169,7 @@ object IOCell {
|
|||||||
Seq(iocell)
|
Seq(iocell)
|
||||||
}
|
}
|
||||||
case ActualDirection.Output => {
|
case ActualDirection.Output => {
|
||||||
val iocell = outFn()
|
val iocell = typeParams.output()
|
||||||
name.foreach(n => iocell.suggestName(n))
|
name.foreach(n => iocell.suggestName(n))
|
||||||
iocell.io.o := castToBool(coreSignal)
|
iocell.io.o := castToBool(coreSignal)
|
||||||
iocell.io.oe := true.B
|
iocell.io.oe := true.B
|
||||||
@@ -193,7 +189,7 @@ object IOCell {
|
|||||||
Seq()
|
Seq()
|
||||||
} else {
|
} else {
|
||||||
require(coreSignal.getWidth == 1, "Analogs wider than 1 bit are not supported because we can't bit-select Analogs (https://github.com/freechipsproject/chisel3/issues/536)")
|
require(coreSignal.getWidth == 1, "Analogs wider than 1 bit are not supported because we can't bit-select Analogs (https://github.com/freechipsproject/chisel3/issues/536)")
|
||||||
val iocell = anaFn()
|
val iocell = typeParams.analog()
|
||||||
name.foreach(n => iocell.suggestName(n))
|
name.foreach(n => iocell.suggestName(n))
|
||||||
iocell.io.core <> coreSignal
|
iocell.io.core <> coreSignal
|
||||||
padSignal <> iocell.io.pad
|
padSignal <> iocell.io.pad
|
||||||
@@ -215,7 +211,7 @@ object IOCell {
|
|||||||
DataMirror.directionOf(coreSignal) match {
|
DataMirror.directionOf(coreSignal) match {
|
||||||
case ActualDirection.Input => {
|
case ActualDirection.Input => {
|
||||||
val iocells = padSignal.asBools.zipWithIndex.map { case (sig, i) =>
|
val iocells = padSignal.asBools.zipWithIndex.map { case (sig, i) =>
|
||||||
val iocell = inFn()
|
val iocell = typeParams.input()
|
||||||
// Note that we are relying on chisel deterministically naming this in the index order (which it does)
|
// Note that we are relying on chisel deterministically naming this in the index order (which it does)
|
||||||
// This has the side-effect of naming index 0 with no _0 suffix, which is how chisel names other signals
|
// This has the side-effect of naming index 0 with no _0 suffix, which is how chisel names other signals
|
||||||
// An alternative solution would be to suggestName(n + "_" + i)
|
// An alternative solution would be to suggestName(n + "_" + i)
|
||||||
@@ -230,7 +226,7 @@ object IOCell {
|
|||||||
}
|
}
|
||||||
case ActualDirection.Output => {
|
case ActualDirection.Output => {
|
||||||
val iocells = coreSignal.asBools.zipWithIndex.map { case (sig, i) =>
|
val iocells = coreSignal.asBools.zipWithIndex.map { case (sig, i) =>
|
||||||
val iocell = outFn()
|
val iocell = typeParams.output()
|
||||||
// Note that we are relying on chisel deterministically naming this in the index order (which it does)
|
// Note that we are relying on chisel deterministically naming this in the index order (which it does)
|
||||||
// This has the side-effect of naming index 0 with no _0 suffix, which is how chisel names other signals
|
// This has the side-effect of naming index 0 with no _0 suffix, which is how chisel names other signals
|
||||||
// An alternative solution would be to suggestName(n + "_" + i)
|
// An alternative solution would be to suggestName(n + "_" + i)
|
||||||
@@ -251,14 +247,14 @@ object IOCell {
|
|||||||
case (coreSignal: Vec[_], padSignal: Vec[_]) => {
|
case (coreSignal: Vec[_], padSignal: Vec[_]) => {
|
||||||
require(padSignal.size == coreSignal.size, "size of Vec for padSignal and coreSignal must be the same")
|
require(padSignal.size == coreSignal.size, "size of Vec for padSignal and coreSignal must be the same")
|
||||||
coreSignal.zip(padSignal).zipWithIndex.foldLeft(Seq.empty[IOCell]) { case (total, ((core, pad), i)) =>
|
coreSignal.zip(padSignal).zipWithIndex.foldLeft(Seq.empty[IOCell]) { case (total, ((core, pad), i)) =>
|
||||||
val ios = IOCell.generateFromSignal(core, pad, name.map(_ + "_" + i), inFn, outFn, anaFn)
|
val ios = IOCell.generateFromSignal(core, pad, name.map(_ + "_" + i), typeParams)
|
||||||
total ++ ios
|
total ++ ios
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case (coreSignal: Record, padSignal: Record) => {
|
case (coreSignal: Record, padSignal: Record) => {
|
||||||
coreSignal.elements.foldLeft(Seq.empty[IOCell]) { case (total, (eltName, core)) =>
|
coreSignal.elements.foldLeft(Seq.empty[IOCell]) { case (total, (eltName, core)) =>
|
||||||
val pad = padSignal.elements(eltName)
|
val pad = padSignal.elements(eltName)
|
||||||
val ios = IOCell.generateFromSignal(core, pad, name.map(_ + "_" + eltName), inFn, outFn, anaFn)
|
val ios = IOCell.generateFromSignal(core, pad, name.map(_ + "_" + eltName), typeParams)
|
||||||
total ++ ios
|
total ++ ios
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ sealed trait GenerateTopAndHarnessApp extends LazyLogging { this: App =>
|
|||||||
// Execute top and get list of ExtModules to avoid collisions
|
// Execute top and get list of ExtModules to avoid collisions
|
||||||
val topExtModules = executeTop()
|
val topExtModules = executeTop()
|
||||||
|
|
||||||
val externals = Seq("SimSerial", "SimDTM") ++ harnessTop ++ synTop
|
val externals = Seq("SimSerial", "SimDTM", "plusarg_reader") ++ harnessTop ++ synTop
|
||||||
|
|
||||||
val harnessAnnos =
|
val harnessAnnos =
|
||||||
tapeoutOptions.harnessDotfOut.map(BlackBoxResourceFileNameAnno(_)).toSeq ++
|
tapeoutOptions.harnessDotfOut.map(BlackBoxResourceFileNameAnno(_)).toSeq ++
|
||||||
|
|||||||
Reference in New Issue
Block a user