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