Skip to content

Commit 475beac

Browse files
author
Oron Port
committed
fix verilog.v95/v2001 backend to use delays without time units and set the timescale according to the minimum.
1 parent 36f7b93 commit 475beac

File tree

5 files changed

+56
-13
lines changed

5 files changed

+56
-13
lines changed

compiler/ir/src/main/scala/dfhdl/compiler/ir/DFType.scala

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,15 @@ case object DFTime extends DFType.Companion[DFTime, (BigDecimal, DFTime.Unit)] w
594594
case `sec` => value * BigDecimal(1000000000000L)
595595
case `min` => value * BigDecimal(60000000000000L)
596596
case `hr` => value * BigDecimal(3600000000000000L)
597+
def to_basic_unit(value: BigDecimal): (BigDecimal, Unit) =
598+
val psVal = to_ps(value)
599+
if psVal < 1000 then (psVal, DFTime.Unit.ps)
600+
else if psVal < 1000000 then (psVal / 1000, DFTime.Unit.ns)
601+
else if psVal < 1000000000 then (psVal / 1000, DFTime.Unit.us)
602+
else if psVal < 1000000000000L then (psVal / 1000000000L, DFTime.Unit.ms)
603+
else (psVal / 1000000000000L, DFTime.Unit.sec)
604+
end Unit
605+
end DFTime
597606

598607
sealed trait DFFreq extends DFPhysical[DFFreq.Unit]
599608
case object DFFreq extends DFType.Companion[DFFreq, (BigDecimal, DFFreq.Unit)] with DFFreq:
@@ -610,9 +619,9 @@ case object DFFreq extends DFType.Companion[DFFreq, (BigDecimal, DFFreq.Unit)] w
610619
BigDecimal(1e12) / to_hz(value)
611620
def to_period(value: BigDecimal): (BigDecimal, DFTime.Unit) =
612621
val psVal = to_ps(value)
613-
if psVal < BigDecimal(1000) then (psVal, DFTime.Unit.ps)
614-
else if psVal < BigDecimal(1000000) then (psVal / 1000, DFTime.Unit.ns)
615-
else if psVal < BigDecimal(1000000000) then (psVal / 1000, DFTime.Unit.us)
622+
if psVal < 1000 then (psVal, DFTime.Unit.ps)
623+
else if psVal < 1000000 then (psVal / 1000, DFTime.Unit.ns)
624+
else if psVal < 1000000000 then (psVal / 1000, DFTime.Unit.us)
616625
else if psVal < 1000000000000L then (psVal / 1000000000L, DFTime.Unit.ms)
617626
else if psVal < 1000000000000000L then (psVal / 1000000000000L, DFTime.Unit.sec)
618627
else (psVal / 60000000000000L, DFTime.Unit.min)

compiler/ir/src/main/scala/dfhdl/compiler/printing/Printer.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,10 @@ trait Printer
155155
final def formatCode(cs: String, withColor: Boolean = printerOptions.color): String =
156156
val alignedContents = if (printerOptions.align) alignCode(cs) else cs
157157
if (withColor) colorCode(alignedContents) else alignedContents
158+
private var currentDesign: Option[DFDesignBlock] = None
159+
def getCurrentDesign: DFDesignBlock = currentDesign.get
158160
final def csFile(design: DFDesignBlock): String =
161+
currentDesign = Some(design)
159162
val designDcl = design.instMode match
160163
case InstMode.Def => csDFDesignDefDcl(design)
161164
case _ => csDFDesignBlockDcl(design)

compiler/stages/src/main/scala/dfhdl/compiler/stages/verilog/VerilogDataPrinter.scala

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,21 @@ protected trait VerilogDataPrinter extends AbstractDataPrinter:
8585
data match
8686
case Some(value) => value.toString
8787
case None => "?"
88+
val supportTimeUnits =
89+
printer.dialect match
90+
case VerilogDialect.v95 | VerilogDialect.v2001 => false
91+
case _ => true
8892
def csDFTimeData(data: (BigDecimal, DFTime.Unit)): String =
89-
val formattedValue = csBigDecimalData(data._1)
90-
data._2 match
91-
case DFTime.Unit.sec => s"${formattedValue}s"
92-
case DFTime.Unit.min => printer.unsupported
93-
case DFTime.Unit.hr => printer.unsupported
94-
case _ => s"${formattedValue}${data._2}"
93+
if (supportTimeUnits)
94+
val formattedValue = csBigDecimalData(data._1)
95+
data._2 match
96+
case DFTime.Unit.sec => s"${formattedValue}s"
97+
case DFTime.Unit.min => printer.unsupported
98+
case DFTime.Unit.hr => printer.unsupported
99+
case _ => s"${formattedValue}${data._2}"
100+
else
101+
val minTimeUnit = printer.minTimeUnitDesignMap(printer.getCurrentDesign)
102+
csBigDecimalData(data._2.to_ps(data._1) / minTimeUnit.to_ps(1))
95103
def csDFFreqData(data: (BigDecimal, DFFreq.Unit)): String = printer.unsupported
96104
def csDFNumberData(data: (BigDecimal, DFNumber.Unit)): String = printer.unsupported
97105
def scalaToVerilogString(str: String): String =

compiler/stages/src/main/scala/dfhdl/compiler/stages/verilog/VerilogOwnerPrinter.scala

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,18 @@ protected trait VerilogOwnerPrinter extends AbstractOwnerPrinter:
1414
def fileSuffix = "v"
1515
def defsName: String =
1616
s"${getSet.designDB.top.dclName}_defs"
17-
def csLibrary(inSimulation: Boolean): String =
17+
def csLibrary(inSimulation: Boolean, minTimeUnitOpt: Option[DFTime.Unit]): String =
18+
val csTimeScale = minTimeUnitOpt.map { unit =>
19+
def unitToStr(unit: DFTime.Unit): String =
20+
unit match
21+
case DFTime.Unit.sec => "s"
22+
case _ => unit.toString
23+
val scaleUnit = unitToStr(unit)
24+
val precisionUnit = unitToStr(DFTime.Unit.ps.to_basic_unit(unit.to_ps(1e-3))._2)
25+
s"`timescale 1${scaleUnit}/1${precisionUnit}"
26+
}.getOrElse(s"`timescale 1ns/1ps")
1827
s"""`default_nettype none
19-
|`timescale 1ns/1ps
28+
|$csTimeScale
2029
|`include "${printer.globalFileName}"""".stripMargin
2130
def moduleName(design: DFDesignBlock): String = design.dclName
2231
val parameterizedModuleSupport: Boolean =
@@ -101,8 +110,22 @@ protected trait VerilogOwnerPrinter extends AbstractOwnerPrinter:
101110
|${statements.hindent}
102111
|endmodule""".stripMargin
103112
end csModuleDcl
113+
lazy val minTimeUnitDesignMap = getSet.designDB.designMemberList.view.flatMap { (dsn, members) =>
114+
val minTimePSOpt = members.view.collect {
115+
case DFVal.Const(dfType = DFTime, data = (value: BigDecimal, unit: DFTime.Unit)) =>
116+
unit.to_ps(value)
117+
}.minOption
118+
minTimePSOpt.map(ps => dsn -> DFTime.Unit.ps.to_basic_unit(ps)._2)
119+
}.toMap
120+
lazy val minTimeUnitGlobalOpt =
121+
minTimeUnitDesignMap.values.view.map(_.to_ps(1)).minOption.map(ps =>
122+
DFTime.Unit.ps.to_basic_unit(ps)._2
123+
)
104124
def csDFDesignBlockDcl(design: DFDesignBlock): String =
105-
s"""${csLibrary(design.inSimulation)}
125+
// once there is a design with a set time unit, all designs must have a set time unit,
126+
// so we can use the global time unit if the design does not have a set time unit
127+
val minTimeUnitOpt = minTimeUnitDesignMap.get(design).orElse(minTimeUnitGlobalOpt)
128+
s"""${csLibrary(design.inSimulation, minTimeUnitOpt)}
106129
|
107130
|${csModuleDcl(design)}
108131
|""".stripMargin

compiler/stages/src/test/scala/StagesSpec/PrintVerilogCodeSpec.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,7 @@ class PrintVerilogCodeSpec extends StageSpec:
10161016
| end
10171017
| end
10181018
| end
1019-
| #10ns;
1019+
| #10;
10201020
| end
10211021
|endmodule""".stripMargin
10221022
)

0 commit comments

Comments
 (0)