- FoundryPadsYaml would not parse yaml
- Made separate case class for data - Now parses - Fails later with UnknownType in firrt compiler - Fixed similar parsing problem with PadPlacement
This commit is contained in:
@@ -8,13 +8,32 @@ import firrtl._
|
|||||||
import firrtl.ir._
|
import firrtl.ir._
|
||||||
import barstools.tapeout.transforms._
|
import barstools.tapeout.transforms._
|
||||||
|
|
||||||
|
trait HasFoundryPadFields {
|
||||||
|
val tpe: String
|
||||||
|
val name: String
|
||||||
|
val width: Int
|
||||||
|
val height: Int
|
||||||
|
val supplySetNum: Option[Int]
|
||||||
|
val verilog: String
|
||||||
|
}
|
||||||
|
|
||||||
|
case class FoundryPadFields(
|
||||||
|
tpe: String,
|
||||||
|
name: String,
|
||||||
|
width: Int,
|
||||||
|
height: Int,
|
||||||
|
supplySetNum: Option[Int],
|
||||||
|
verilog: String)
|
||||||
|
extends HasFoundryPadFields
|
||||||
|
|
||||||
case class FoundryPad(
|
case class FoundryPad(
|
||||||
tpe: String,
|
tpe: String,
|
||||||
name: String,
|
name: String,
|
||||||
width: Int,
|
width: Int,
|
||||||
height: Int,
|
height: Int,
|
||||||
supplySetNum: Option[Int],
|
supplySetNum: Option[Int],
|
||||||
verilog: String) {
|
verilog: String)
|
||||||
|
extends HasFoundryPadFields {
|
||||||
|
|
||||||
def padInstName = "PAD"
|
def padInstName = "PAD"
|
||||||
|
|
||||||
@@ -38,8 +57,10 @@ case class FoundryPad(
|
|||||||
// Supply pads don't have IO
|
// Supply pads don't have IO
|
||||||
require(!verilog.contains("{{#if isInput}}"), "Supply pad template must not contain '{{#if isInput}}'")
|
require(!verilog.contains("{{#if isInput}}"), "Supply pad template must not contain '{{#if isInput}}'")
|
||||||
require(
|
require(
|
||||||
verilog.contains(s"${padInstName}["), "All supply pad templates should have instance arrays" +
|
verilog.contains(s"${padInstName}["),
|
||||||
" called ${padInstName}[n:0], where n = ${getSupplySetNum-1}")
|
"All supply pad templates should have instance arrays" +
|
||||||
|
" called ${padInstName}[n:0], where n = ${getSupplySetNum-1}"
|
||||||
|
)
|
||||||
require(supplySetNum.nonEmpty, "# of grouped supply pads 'supplySetNum' should be specified!")
|
require(supplySetNum.nonEmpty, "# of grouped supply pads 'supplySetNum' should be specified!")
|
||||||
SupplyPad
|
SupplyPad
|
||||||
case _ => throw new Exception("Illegal pad type in config!")
|
case _ => throw new Exception("Illegal pad type in config!")
|
||||||
@@ -53,14 +74,14 @@ case class FoundryPad(
|
|||||||
private[barstools] val correctedName = name.replace(" ", "_")
|
private[barstools] val correctedName = name.replace(" ", "_")
|
||||||
|
|
||||||
case class TemplateParams(
|
case class TemplateParams(
|
||||||
// isInput only used with digital pads
|
// isInput only used with digital pads
|
||||||
isInput: Boolean,
|
isInput: Boolean,
|
||||||
isHorizontal: Boolean) {
|
isHorizontal: Boolean) {
|
||||||
|
|
||||||
private val orient = if (isHorizontal) Horizontal.serialize else Vertical.serialize
|
private val orient = if (isHorizontal) Horizontal.serialize else Vertical.serialize
|
||||||
private val dir = padType match {
|
private val dir = padType match {
|
||||||
case AnalogPad => "inout"
|
case AnalogPad => "inout"
|
||||||
case SupplyPad => "none"
|
case SupplyPad => "none"
|
||||||
case DigitalPad => if (isInput) Input.serialize else Output.serialize
|
case DigitalPad => if (isInput) Input.serialize else Output.serialize
|
||||||
}
|
}
|
||||||
val name = {
|
val name = {
|
||||||
@@ -84,13 +105,23 @@ case class FoundryPad(
|
|||||||
|
|
||||||
object FoundryPadsYaml extends DefaultYamlProtocol {
|
object FoundryPadsYaml extends DefaultYamlProtocol {
|
||||||
val exampleResource = "/FoundryPads.yaml"
|
val exampleResource = "/FoundryPads.yaml"
|
||||||
implicit val _pad = yamlFormat6(FoundryPad)
|
implicit val _pad = yamlFormat6(FoundryPadFields)
|
||||||
def parse(techDir: String): Seq[FoundryPad] = {
|
def parse(techDir: String): Seq[FoundryPad] = {
|
||||||
val file = techDir + exampleResource
|
val file = techDir + exampleResource
|
||||||
if(techDir != "" && !(new java.io.File(file)).exists()) {
|
if (techDir != "" && !(new java.io.File(file)).exists()) {
|
||||||
throw new Exception(s"Technology directory $techDir must contain FoundryPads.yaml!")
|
throw new Exception(s"Technology directory $techDir must contain FoundryPads.yaml!")
|
||||||
}
|
}
|
||||||
val out = (new YamlFileReader(exampleResource)).parse[FoundryPad](if (techDir == "") "" else file)
|
val fieldsArray = (new YamlFileReader(exampleResource)).parse[FoundryPadFields](if (techDir == "") "" else file)
|
||||||
|
val out = fieldsArray.map { fields =>
|
||||||
|
FoundryPad(
|
||||||
|
tpe = fields.tpe,
|
||||||
|
name = fields.name,
|
||||||
|
width = fields.width,
|
||||||
|
height = fields.height,
|
||||||
|
supplySetNum = fields.supplySetNum,
|
||||||
|
verilog = fields.verilog
|
||||||
|
)
|
||||||
|
}
|
||||||
val padNames = out.map(x => x.correctedName)
|
val padNames = out.map(x => x.correctedName)
|
||||||
require(padNames.distinct.length == padNames.length, "Pad names must be unique!")
|
require(padNames.distinct.length == padNames.length, "Pad names must be unique!")
|
||||||
out
|
out
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import barstools.tapeout.transforms.HasSetTechnologyLocation
|
|||||||
import chisel3._
|
import chisel3._
|
||||||
import chisel3.experimental._
|
import chisel3.experimental._
|
||||||
import chisel3.iotesters._
|
import chisel3.iotesters._
|
||||||
|
import chisel3.stage.ChiselStage
|
||||||
import chisel3.util.HasBlackBoxInline
|
import chisel3.util.HasBlackBoxInline
|
||||||
import firrtl._
|
import firrtl._
|
||||||
import org.scalatest.{FlatSpec, Matchers}
|
import org.scalatest.{FlatSpec, Matchers}
|
||||||
@@ -255,20 +256,11 @@ class IOPadSpec extends FlatSpec with Matchers {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
it should "create proper IO pads + black box in verilog" in {
|
it should "create proper IO pads + black box in verilog" in {
|
||||||
val optionsManager = new ExecutionOptionsManager("barstools") with HasChiselExecutionOptions with HasFirrtlOptions {
|
val dir = "test_run_dir/PadsVerilog"
|
||||||
firrtlOptions = firrtlOptions.copy(
|
(new ChiselStage).emitFirrtl(
|
||||||
compilerName = "verilog"
|
new ExampleTopModuleWithBB,
|
||||||
)
|
Array("-td", dir, "-X", "verilog")
|
||||||
commonOptions = commonOptions.copy(targetDirName = "test_run_dir/PadsVerilog")
|
)
|
||||||
//commonOptions = commonOptions.copy(globalLogLevel = logger.LogLevel.Info)
|
|
||||||
}
|
|
||||||
val success = chisel3.Driver.execute(optionsManager, () => new ExampleTopModuleWithBB) match {
|
|
||||||
case ChiselExecutionSuccess(_, chirrtl, Some(FirrtlExecutionSuccess(_, verilog))) =>
|
|
||||||
true
|
|
||||||
case _ => false
|
|
||||||
}
|
|
||||||
success should be(true)
|
|
||||||
val dir = optionsManager.commonOptions.targetDirName
|
|
||||||
checkOutputs(dir)
|
checkOutputs(dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user