Skip to content

Commit 791e714

Browse files
committed
allow ignoring outputs
1 parent 2d6cbf6 commit 791e714

File tree

1 file changed

+62
-14
lines changed

1 file changed

+62
-14
lines changed

Sources/Fault/Entries/atpg.swift

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ extension Fault {
3838

3939
@Option(
4040
name: [.long, .customLong("output-faultPoints")],
41-
help: "Path to the output yml file listing all generated fault points. (Default: nil)")
41+
help: "Path to the output yml file listing all generated fault points. (Default: nil)"
42+
)
4243
var outputFaultPoints: String?
4344

4445
@Option(
@@ -50,12 +51,14 @@ extension Fault {
5051

5152
@Option(
5253
name: [.short, .long, .customLong("cellModel")],
53-
help: "A Verilog model with which standard cells can be simulated.")
54+
help: "A Verilog model with which standard cells can be simulated."
55+
)
5456
var cellModel: String
5557

5658
@Option(
5759
name: [.customShort("v"), .long],
58-
help: "Number of test vectors to generate in the first batch.")
60+
help: "Number of test vectors to generate in the first batch."
61+
)
5962
var tvCount: Int = 100
6063

6164
@Option(
@@ -89,14 +92,24 @@ extension Fault {
8992

9093
@Option(
9194
name: [.customShort("g"), .long],
92-
help: "Use an external TV Generator: Atalanta or PODEM.")
95+
help: "Use an external TV Generator: Atalanta or PODEM."
96+
)
9397
var etvGen: String?
9498

9599
@Option(
96100
name: [.short, .long],
97-
help: "Netlist in bench format. (Required iff generator is set to Atalanta or PODEM.)")
101+
help:
102+
"Netlist in bench format. (Required if generator is set to Atalanta or PODEM and a liberty file is not passed.)"
103+
)
98104
var bench: String?
99105

106+
@Option(
107+
name: [.customShort("l"), .long],
108+
help:
109+
"Liberty file. (Required if generator is set to Atalanta or PODEM and a bench file is not passed.)"
110+
)
111+
var liberty: String?
112+
100113
@Flag(help: "Generate only one testbench for inspection, and do not delete it.")
101114
var sampleRun: Bool = false
102115

@@ -111,19 +124,20 @@ extension Fault {
111124

112125
@Option(
113126
name: [.customShort("D"), .customLong("define")],
114-
help: "Define statements to include during simulations.")
127+
help: "Define statements to include during simulations."
128+
)
115129
var defines: [String] = []
116130

117131
@Option(
118132
name: [.customShort("I"), .customLong("include")],
119-
help: "Extra verilog models to include during simulations.")
133+
help: "Extra verilog models to include during simulations."
134+
)
120135
var includes: [String] = []
121136

122137
@Argument(help: "The cutaway netlist to generate patterns for.")
123138
var file: String
124139

125140
mutating func run() throws {
126-
127141
if !TVGeneratorFactory.validNames.contains(tvGen) {
128142
throw ValidationError("Invalid test-vector generator \(tvGen).")
129143
}
@@ -182,14 +196,36 @@ extension Fault {
182196
Stderr.print("Unknown external test vector generator '\(tvGenerator)'.")
183197
Foundation.exit(EX_USAGE)
184198
}
199+
if bench == nil, liberty == nil {
200+
Stderr.print(
201+
"Either --bench or --liberty must be passed when using an external test vector generator."
202+
)
203+
Foundation.exit(EX_USAGE)
204+
}
185205

186-
let benchUnwrapped = bench! // Program exits if etvGen.value isn't nil and bench.value is or vice versa
206+
let benchUnwrapped =
207+
bench
208+
?? {
209+
let nl2bench = Python.import("nl2bench")
210+
let pyPath = Python.import("pathlib").Path
211+
let benchPath = file.replacingExtension(".v", with: ".bench")
212+
let benchPathF = Python.open(benchPath, "w", encoding: "utf8")
213+
nl2bench.nl2bench.verilog_netlist_to_bench(
214+
pyPath(file),
215+
[
216+
liberty!
217+
],
218+
benchPathF, Array(bypass.bypassedIOs)
219+
)
220+
return benchPath
221+
}()
187222

188223
if !fileManager.fileExists(atPath: benchUnwrapped) {
189224
throw ValidationError("Bench file '\(benchUnwrapped)' not found.")
190225
}
191226
(etvSetVectors, etvSetInputs) = etvgen.generate(
192-
file: benchUnwrapped, module: "\(definition.name)")
227+
file: benchUnwrapped, module: "\(definition.name)"
228+
)
193229

194230
if etvSetVectors.count == 0 {
195231
Stderr.print(
@@ -245,10 +281,22 @@ extension Fault {
245281
inputsMinusIgnored = evtInputsMinusIgnored
246282
}
247283

284+
var inputSimulationValues: OrderedDictionary<String, Simulator.Behavior> = [:]
285+
var portsMinusBypassedOutputs: [String: Port] = ports
286+
var outputsMinusBypassed: [Port] = []
248287
for (_, port) in ports {
249288
if bypass.bypassedIOs.contains(port.name) {
289+
print("Bypassing \(port.name)")
290+
if port.polarity == .input {
291+
inputSimulationValues[port.name] = bypass.simulationValues[port.name]
292+
} else {
293+
portsMinusBypassedOutputs.removeValue(forKey: port.name)
294+
}
250295
continue
251296
}
297+
if port.polarity == .output {
298+
outputsMinusBypassed.append(port)
299+
}
252300
if port.width == 1 {
253301
faultPoints.insert(port.name)
254302
} else {
@@ -311,8 +359,8 @@ extension Fault {
311359
with: models,
312360
ports: ports,
313361
inputs: inputsMinusIgnored,
314-
bypassingWithBehavior: bypass.simulationValues,
315-
outputs: outputs,
362+
bypassingWithBehavior: inputSimulationValues,
363+
outputs: outputsMinusBypassed,
316364
initialVectorCount: tvCount,
317365
incrementingBy: increment,
318366
minimumCoverage: tvMinimumCoverage,
@@ -338,7 +386,7 @@ extension Fault {
338386

339387
let rawTVInfo = TVInfo(
340388
inputs: inputsMinusIgnored,
341-
outputs: outputs,
389+
outputs: outputsMinusBypassed,
342390
coverageList: result.coverageList
343391
)
344392
let jsonRawOutput = jsonOutput.replacingExtension(".tv.json", with: ".raw_tv.json")
@@ -348,7 +396,7 @@ extension Fault {
348396

349397
let tvInfo = TVInfo(
350398
inputs: inputsMinusIgnored,
351-
outputs: outputs,
399+
outputs: outputsMinusBypassed,
352400
coverageList: Compactor.compact(coverageList: result.coverageList)
353401
)
354402
print(

0 commit comments

Comments
 (0)