- 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 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(
tpe: String,
name: String,
width: Int,
height: Int,
supplySetNum: Option[Int],
verilog: String) {
tpe: String,
name: String,
width: Int,
height: Int,
supplySetNum: Option[Int],
verilog: String)
extends HasFoundryPadFields {
def padInstName = "PAD"
@@ -38,8 +57,10 @@ case class FoundryPad(
// Supply pads don't have IO
require(!verilog.contains("{{#if isInput}}"), "Supply pad template must not contain '{{#if isInput}}'")
require(
verilog.contains(s"${padInstName}["), "All supply pad templates should have instance arrays" +
" called ${padInstName}[n:0], where n = ${getSupplySetNum-1}")
verilog.contains(s"${padInstName}["),
"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!")
SupplyPad
case _ => throw new Exception("Illegal pad type in config!")
@@ -53,14 +74,14 @@ case class FoundryPad(
private[barstools] val correctedName = name.replace(" ", "_")
case class TemplateParams(
// isInput only used with digital pads
isInput: Boolean,
isHorizontal: Boolean) {
// isInput only used with digital pads
isInput: Boolean,
isHorizontal: Boolean) {
private val orient = if (isHorizontal) Horizontal.serialize else Vertical.serialize
private val dir = padType match {
case AnalogPad => "inout"
case SupplyPad => "none"
case AnalogPad => "inout"
case SupplyPad => "none"
case DigitalPad => if (isInput) Input.serialize else Output.serialize
}
val name = {
@@ -84,13 +105,23 @@ case class FoundryPad(
object FoundryPadsYaml extends DefaultYamlProtocol {
val exampleResource = "/FoundryPads.yaml"
implicit val _pad = yamlFormat6(FoundryPad)
implicit val _pad = yamlFormat6(FoundryPadFields)
def parse(techDir: String): Seq[FoundryPad] = {
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!")
}
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)
require(padNames.distinct.length == padNames.length, "Pad names must be unique!")
out

View File

@@ -8,6 +8,7 @@ import barstools.tapeout.transforms.HasSetTechnologyLocation
import chisel3._
import chisel3.experimental._
import chisel3.iotesters._
import chisel3.stage.ChiselStage
import chisel3.util.HasBlackBoxInline
import firrtl._
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 {
val optionsManager = new ExecutionOptionsManager("barstools") with HasChiselExecutionOptions with HasFirrtlOptions {
firrtlOptions = firrtlOptions.copy(
compilerName = "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
val dir = "test_run_dir/PadsVerilog"
(new ChiselStage).emitFirrtl(
new ExampleTopModuleWithBB,
Array("-td", dir, "-X", "verilog")
)
checkOutputs(dir)
}