Skip to content

Commit 770bd74

Browse files
authored
Merge pull request #2149 from Pinata-Consulting/mock-array-post-synthesis-simulation
mock-array: read_power_activities MockArray.vcd test case
2 parents b71aee2 + 51f2cf4 commit 770bd74

File tree

15 files changed

+11592
-47
lines changed

15 files changed

+11592
-47
lines changed

flow/designs/asap7/mock-array/config.mk

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,16 @@ verilog:
4040
export MOCK_ARRAY_COLS=$(word 2, $(MOCK_ARRAY_TABLE)) ; \
4141
./designs/asap7/mock-array/verilog.sh
4242

43+
.PHONY: simulate
44+
simulate:
45+
export MOCK_ARRAY_ROWS=$(word 1, $(MOCK_ARRAY_TABLE)) ; \
46+
export MOCK_ARRAY_COLS=$(word 2, $(MOCK_ARRAY_TABLE)) ; \
47+
./designs/asap7/mock-array/simulate.sh
48+
49+
.PHONY: power
50+
power:
51+
$(OPENSTA_EXE) -no_init -exit designs/asap7/mock-array/power.tcl
52+
4353
# If this design isn't quickly done in detailed routing, something is wrong.
4454
# At time of adding this option, only 12 iterations were needed for 0
4555
# violations.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
foreach libFile $::env(LIB_FILES) {
2+
if {[lsearch -exact $::env(ADDITIONAL_LIBS) $libFile] == -1} {
3+
read_liberty $libFile
4+
}
5+
}
6+
7+
read_verilog results/asap7/mock-array_Element/base/6_final.v
8+
read_verilog $::env(RESULTS_DIR)/6_final.v
9+
read_verilog $::env(PLATFORM_DIR)/verilog/stdcell/empty.v
10+
11+
link_design MockArray
12+
13+
read_sdc $::env(RESULTS_DIR)/6_final.sdc
14+
read_spef $::env(RESULTS_DIR)/6_final.spef
15+
for {set x 0} {$x < 8} {incr x} {
16+
for {set y 0} {$y < 8} {incr y} {
17+
read_spef -path ces_${x}_${y} results/asap7/mock-array_Element/base/6_final.spef
18+
}
19+
}
20+
21+
report_parasitic_annotation
22+
report_power
23+
read_power_activities -scope TOP/MockArrayTestbench/postSynthesis -vcd designs/src/mock-array/MockArrayTestbench.vcd
24+
report_power
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env bash
2+
set -ex
3+
4+
# allow this script to be invoked from any folder
5+
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
6+
BASE=$DIR/../..
7+
8+
cd $DIR
9+
10+
cd ../../src/mock-array
11+
cp ../../../results/asap7/mock-array/base/6_final.v post/MockArrayFinal.v
12+
cp ../../../results/asap7/mock-array_Element/base/6_final.v post/MockArrayElementFinal.v
13+
14+
pwd
15+
rm -rf test_run_dir/
16+
sbt -Duser.home="$HOME" -Djline.terminal=jline.UnsupportedTerminal -batch \
17+
"test:runMain SimulatePostSynthesis --width ${MOCK_ARRAY_COLS} --height ${MOCK_ARRAY_ROWS} --dataWidth ${MOCK_ARRAY_DATAWIDTH}"
18+
19+
cp test_run_dir/MockArray_should_Wiggle_some_wires/MockArrayTestbench.vcd .
20+

flow/designs/asap7/mock-array/verilog.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,8 @@ sbt -Duser.home="$HOME" -Djline.terminal=jline.UnsupportedTerminal -batch \
1414

1515
# reduce git noise as these comments will change if the line numbers in Chisel changes
1616
find . -name "*.v" -type f -exec sed -i 's/ \/\/.*$//' {} \;
17+
18+
sbt -Duser.home="$HOME" -Djline.terminal=jline.UnsupportedTerminal -batch \
19+
"test:runMain GenerateMockArray --width ${MOCK_ARRAY_COLS} --height ${MOCK_ARRAY_ROWS} --dataWidth ${MOCK_ARRAY_DATAWIDTH} -- --emit-modules verilog --emission-options disableMemRandomization,disableRegisterRandomization --target-dir ."
20+
21+
cp test_run_dir/MockArray_should_Wiggle_some_wires/MockArray.vcd .

flow/designs/src/mock-array/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ target/
77
.bloop/
88
.bsp/
99
test_run_dir/
10+
MockArrayTestbench.vcd

flow/designs/src/mock-array/build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import scala.io.Source
33

44
organization := "edu.berkeley.cs"
55

6-
scalaVersion := "2.13.6"
6+
scalaVersion := "2.13.10"
77

88
scalacOptions ++= Seq("-deprecation", "-feature", "-unchecked", "-language:reflectiveCalls")
99

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
MockArray*.v

flow/designs/src/mock-array/src/main/scala/MockArray.scala

Lines changed: 121 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
import chisel3._
55

66
import org.scalatest._
7+
import chiseltest._
8+
import chiseltest.simulator.SimulatorDebugAnnotation
9+
import chiseltest.simulator.VerilatorFlags
10+
import org.scalatest.flatspec.AnyFlatSpec
711

812
import chisel3._
913
import chisel3.util._
@@ -13,6 +17,7 @@ import scopt.OParser
1317
import System.err
1418
import scopt.RenderingMode
1519
import scala.collection.immutable.SeqMap
20+
import java.nio.file.Paths
1621

1722
object Routes extends Enumeration {
1823
type Routes = Value
@@ -44,14 +49,15 @@ class BusesVec(singleElementWidth: Int, width: Int, height: Int)
4449
def asSeq: Seq[Vec[UInt]] = routes.map(_._2).toSeq
4550
}
4651

52+
class MockArrayBundle(width: Int, height: Int, singleElementWidth: Int) extends Bundle {
53+
val ins = Input(new BusesVec(singleElementWidth, width, height))
54+
val outs = Output(new BusesVec(singleElementWidth, width, height))
55+
val lsbs = Output(Vec(width * height, Bool()))
56+
}
57+
4758
class MockArray(width: Int, height: Int, singleElementWidth: Int)
4859
extends Module {
49-
val io = IO(new Bundle {
50-
val ins = Input(new BusesVec(singleElementWidth, width, height))
51-
val outs = Output(new BusesVec(singleElementWidth, width, height))
52-
53-
val lsbs = Output(Vec(width * height, Bool()))
54-
})
60+
val io = IO(new MockArrayBundle(width, height, singleElementWidth))
5561

5662
class Element extends Module {
5763
val io =
@@ -147,49 +153,118 @@ case class ArrayConfig(
147153
remainingArgs: Seq[String] = Seq.empty
148154
)
149155

150-
object GenerateMockArray extends App {
156+
class MockArrayPostSynthesis(width:Int, height:Int, singleElementWidth:Int)
157+
extends BlackBox with HasBlackBoxPath {
158+
override def desiredName = "MockArray"
159+
val io = IO(new Bundle {
160+
val clock = Input(Clock())
161+
val reset = Input(Bool())
162+
val io = new MockArrayBundle(width, height, singleElementWidth)
163+
})
164+
val platformDir = sys.env.getOrElse("PLATFORM_DIR", "defaultPath") + "/verilog/stdcell/"
165+
(Seq("asap7sc7p5t_AO_RVT_TT_201020.v",
166+
"dff.v",
167+
"asap7sc7p5t_SIMPLE_RVT_TT_201020.v",
168+
"asap7sc7p5t_INVBUF_RVT_TT_201020.v",
169+
"empty.v").map(p=>Paths.get(platformDir + p)) ++
170+
Seq(
171+
"MockArrayFinal.v",
172+
"MockArrayElementFinal.v").map(p=>Paths.get("post/" + p)))
173+
.foreach(p=> addPath(p.toAbsolutePath().toString()))
174+
}
151175

152-
val builder = OParser.builder[ArrayConfig]
153-
val parser = {
154-
import builder._
155-
OParser.sequence(
156-
programName("my-program"),
157-
opt[Int]('w', "width")
158-
.required()
159-
.valueName("Array width")
160-
.action((width, c) => c.copy(width = width))
161-
.text("input file is required"),
162-
opt[Int]('h', "height")
163-
.required()
164-
.valueName("height")
165-
.action((height, c) => c.copy(height = height))
166-
.text("Array height"),
167-
opt[Int]('d', "dataWidth")
168-
.required()
169-
.valueName("dataWidth")
170-
.action((dataWidth, c) => c.copy(dataWidth = dataWidth))
171-
.text("data path width")
172-
)
176+
class MockArrayTestbench(width:Int, height:Int, singleElementWidth:Int) extends Module {
177+
val io = IO(new MockArrayBundle(width, height, singleElementWidth))
178+
val postSynthesis = Module(new MockArrayPostSynthesis(width, height, singleElementWidth))
179+
postSynthesis.io.io <> io
180+
postSynthesis.io.reset := reset.asBool
181+
postSynthesis.io.clock := clock
182+
}
183+
184+
185+
class MockArrayTest(width:Int, height:Int, singleElementWidth:Int) extends AnyFlatSpec with ChiselScalatestTester {
186+
behavior of "MockArray"
187+
188+
it should "Wiggle some wires" in {
189+
// find full path foo.v in scala/src/resources
190+
test(new MockArrayTestbench(width, height, singleElementWidth)).
191+
withAnnotations(Seq(WriteVcdAnnotation,
192+
VerilatorBackendAnnotation,
193+
SimulatorDebugAnnotation,
194+
// DD flip flops use UDP Tables, unsupported by Verilator
195+
VerilatorFlags(Seq())
196+
)) { dut =>
197+
for (j <- 0 until 5) {
198+
dut.io.ins.routes.foreach { case (route, vec) =>
199+
vec.zipWithIndex.foreach { case (wire, i) =>
200+
wire.poke((i+j).U)
201+
dut.clock.step(1)
202+
}
203+
}
204+
}
205+
}
173206
}
207+
}
208+
209+
210+
object parse {
211+
def apply(args:Array[String]) : (ArrayConfig, Array[String]) = {
212+
val builder = OParser.builder[ArrayConfig]
213+
val parser = {
214+
import builder._
215+
OParser.sequence(
216+
programName("my-program"),
217+
opt[Int]('w', "width")
218+
.required()
219+
.valueName("Array width")
220+
.action((width, c) => c.copy(width = width))
221+
.text("input file is required"),
222+
opt[Int]('h', "height")
223+
.required()
224+
.valueName("height")
225+
.action((height, c) => c.copy(height = height))
226+
.text("Array height"),
227+
opt[Int]('d', "dataWidth")
228+
.required()
229+
.valueName("dataWidth")
230+
.action((dataWidth, c) => c.copy(dataWidth = dataWidth))
231+
.text("data path width")
232+
)
233+
}
234+
235+
val (configArgs, afterDelimiter) = args.span(_ != "--")
236+
val chiselArgs = afterDelimiter.drop(1)
174237

175-
val (configArgs, afterDelimiter) = args.span(_ != "--")
176-
val chiselArgs = afterDelimiter.drop(1)
177-
178-
OParser.parse(parser, configArgs, ArrayConfig()) match {
179-
case Some(c) =>
180-
new ChiselStage()
181-
.execute(
182-
chiselArgs,
183-
Seq(
184-
ChiselGeneratorAnnotation(() =>
185-
new MockArray(c.width, c.height, c.dataWidth)
186-
)
187-
)
188-
)
189238

190-
case _ =>
191-
// arguments are invalid
192-
OParser.usage(parser, RenderingMode.TwoColumns)
193-
sys.exit(1)
239+
240+
OParser.parse(parser, configArgs, ArrayConfig()) match {
241+
case Some(c) =>
242+
return (c, chiselArgs)
243+
244+
case _ =>
245+
// arguments are invalid
246+
OParser.usage(parser, RenderingMode.TwoColumns)
247+
sys.exit(1)
248+
}
194249
}
250+
251+
}
252+
253+
object GenerateMockArray extends App {
254+
val (c, chiselArgs) = parse(args)
255+
256+
new ChiselStage()
257+
.execute(
258+
chiselArgs,
259+
Seq(
260+
ChiselGeneratorAnnotation(() =>
261+
new MockArray(c.width, c.height, c.dataWidth)
262+
)
263+
)
264+
)
265+
}
266+
267+
object SimulatePostSynthesis extends App {
268+
val (c, chiselArgs) = parse(args)
269+
new MockArrayTest(c.width, c.height, c.dataWidth).execute()
195270
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
ASAP7 behavioral model files
2+
============================
3+
4+
These are unmodified files from
5+
https://github.com/The-OpenROAD-Project/asap7sc7p5t_28/tree/main/Verilog
6+
7+
Note that some tools, notably Verilator, might struggle with some
8+
of the SystemVerilog features used by the behavioral logic files in
9+
the ASAP7 PDK.
10+
11+
To work around this ORFS re-implements some behavioral such as the dff.v
12+
and empty.v to allow for post-synthesis simulation to use OpenSTA
13+
read_power_activities features.
14+
15+

0 commit comments

Comments
 (0)