- 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:
chick
2020-09-14 09:32:18 -07:00
parent 67de39e957
commit d06d8cc16c
2 changed files with 53 additions and 30 deletions

View File

@@ -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

View File

@@ -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)
} }