Skip to content

Commit 0d6ab60

Browse files
donnkanndil
andauthored
Update nix-eda, nl2bench (#52)
* update nix-eda to `0814aa6c` * update nl2bench to 0.5.0 -- new pyosys-based version * add experimental support for podemquest Co-authored-by: Youssef Kandil <youssefkandil@aucegypt.edu>
1 parent 6500183 commit 0d6ab60

File tree

15 files changed

+364
-269
lines changed

15 files changed

+364
-269
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,4 @@ parsetab.py
2929

3030
.swiftpm/
3131
abc.history
32+
temp.txt

.swift-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5.4
1+
5.8

Benchmarks/Benchmarks/aes128.v

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
* limitations under the License.
1515
*/
1616

17-
module aes128(clk, state, key, out);
17+
module aes128(clk, state, key, out, reset);
1818
input clk;
19+
input reset;
1920
input [127:0] state, key;
2021
output [127:0] out;
2122
reg [127:0] s0, k0;

Benchmarks/test.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ function usage() {
1010
echo " --all Runs Fault's complete flow"
1111
echo " --synth Runs synthesis script"
1212
echo " --cut Runs cut option on the synthesized netlist"
13-
echo " -g, --tvgen Runs fault simulation using the specified TV generator (swift, atalanta, LFSR, PODEM)"
13+
echo " -g, --tvgen Runs fault simulation using the specified TV generator (swift, atalanta, LFSR, PODEM, PodemQuest)"
1414
echo " --delay Runs the transition fault simulator"
1515
echo " --chain Runs chain option on the synthesized netlist"
1616
echo " --tap Runs tap option on the chained netlist"
@@ -194,7 +194,7 @@ do
194194
ignoring="-i $ignored_input,$clock_signal,$reset_signal"
195195
fi
196196
# Check tvgen type
197-
if [ $tvgen = "atalanta" ] || [ $tvgen = "podem" ];
197+
if [ $tvgen = "atalanta" ] || [ $tvgen = "podem" ] || [ $tvgen = "PodemQuest" ];
198198
then
199199
bench=$cut_netlist.bench
200200
echo "Generating bench circuit for $cut_netlist"

Sources/Fault/Entries/atpg.swift

Lines changed: 108 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -12,97 +12,131 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
import ArgumentParser
1516
import BigInt
1617
import Collections
17-
import ArgumentParser
18-
import CoreFoundation // Not automatically imported on Linux
18+
import CoreFoundation // Not automatically imported on Linux
1919
import Defile
2020
import Foundation
2121
import PythonKit
2222
import Yams
2323

24-
2524
extension Fault {
2625
struct ATPG: ParsableCommand {
2726
static let configuration = CommandConfiguration(
28-
abstract: "Generate/import test vectors for a particular circuit and calculate coverage."
27+
abstract:
28+
"Generate/import test vectors for a particular circuit and calculate coverage."
29+
)
30+
31+
@Option(
32+
name: [.short, .long], help: "Path to the output JSON file. (Default: input + .tv.json)"
2933
)
30-
31-
@Option(name: [.short, .long], help: "Path to the output JSON file. (Default: input + .tv.json)")
3234
var output: String?
33-
35+
3436
@Option(help: "Path to the output SVF file. (Default: input + .tv.svf)")
3537
var outputSvf: String?
36-
37-
@Option(name: [.long, .customLong("output-faultPoints")], help: "Path to the output yml file listing all generated fault points. (Default: nil)")
38+
39+
@Option(
40+
name: [.long, .customLong("output-faultPoints")],
41+
help: "Path to the output yml file listing all generated fault points. (Default: nil)")
3842
var outputFaultPoints: String?
39-
40-
@Option(name: [.long, .customLong("output-covered")], help: "Path to the output yml file listing coverage metadata, i.e., ratio and fault points covered. (Default: nil)")
43+
44+
@Option(
45+
name: [.long, .customLong("output-covered")],
46+
help:
47+
"Path to the output yml file listing coverage metadata, i.e., ratio and fault points covered. (Default: nil)"
48+
)
4149
var outputCoverageMetadata: String?
42-
43-
@Option(name: [.short, .long, .customLong("cellModel")], help: "A Verilog model with which standard cells can be simulated.")
50+
51+
@Option(
52+
name: [.short, .long, .customLong("cellModel")],
53+
help: "A Verilog model with which standard cells can be simulated.")
4454
var cellModel: String
45-
46-
@Option(name: [.customShort("v"), .long], help: "Number of test vectors to generate in the first batch.")
55+
56+
@Option(
57+
name: [.customShort("v"), .long],
58+
help: "Number of test vectors to generate in the first batch.")
4759
var tvCount: Int = 100
48-
49-
@Option(name: [.customShort("r"), .long], help: "Increment in test vector count in subsequent batches should sufficient coverage not be reached.")
60+
61+
@Option(
62+
name: [.customShort("r"), .long],
63+
help:
64+
"Increment in test vector count in subsequent batches should sufficient coverage not be reached."
65+
)
5066
var increment: Int = 50
51-
52-
@Option(name: [.short, .long], help: "The minimum coverage to reach before ceasing increments. If set to 0, only the initial batch is run.")
67+
68+
@Option(
69+
name: [.short, .long],
70+
help:
71+
"The minimum coverage to reach before ceasing increments. If set to 0, only the initial batch is run."
72+
)
5373
var minCoverage: Float = 80
54-
55-
@Option(help: "Ceiling for Test Vector increments: if this number is reached, no more increments will occur regardless the coverage.")
74+
75+
@Option(
76+
help:
77+
"Ceiling for Test Vector increments: if this number is reached, no more increments will occur regardless the coverage."
78+
)
5679
var ceiling: Int?
57-
80+
5881
@Option(help: "Type of the pseudo-random internal test-vector-generator.")
5982
var tvGen: String = "swift"
60-
61-
@Option(help: "A \(MemoryLayout<UInt>.size)-byte value to use as an RNG seed for test vector generators, provided as a hexadecimal string (without 0x).")
83+
84+
@Option(
85+
help:
86+
"A \(MemoryLayout<UInt>.size)-byte value to use as an RNG seed for test vector generators, provided as a hexadecimal string (without 0x)."
87+
)
6288
var rngSeed: String = "DEADCAFEDEADF00D"
63-
64-
@Option(name: [.customShort("g"), .long], help: "Use an external TV Generator: Atalanta or PODEM.")
89+
90+
@Option(
91+
name: [.customShort("g"), .long],
92+
help: "Use an external TV Generator: Atalanta or PODEM.")
6593
var etvGen: String?
66-
67-
@Option(name: [.short, .long], help: "Netlist in bench format. (Required iff generator is set to Atalanta or PODEM.)")
94+
95+
@Option(
96+
name: [.short, .long],
97+
help: "Netlist in bench format. (Required iff generator is set to Atalanta or PODEM.)")
6898
var bench: String?
69-
99+
70100
@Flag(help: "Generate only one testbench for inspection, and do not delete it.")
71101
var sampleRun: Bool = false
72-
102+
73103
@OptionGroup
74104
var bypass: BypassOptions
75-
76-
@Option(help: "If provided, this JSON file's test vectors are simulated and no generation is attempted.")
77-
var externalTVSet: String?
78-
79-
@Option(help: "If provided, this JSON file's test vector are used as the initial set of test vectors, with iterations taking place with them in mind.")
105+
106+
@Option(
107+
help:
108+
"If provided, this JSON file's test vector are used as the initial set of test vectors, with iterations taking place with them in mind."
109+
)
80110
var iteratingUpon: String?
81-
82-
@Option(name: [.customShort("D"), .customLong("define")], help: "Define statements to include during simulations.")
111+
112+
@Option(
113+
name: [.customShort("D"), .customLong("define")],
114+
help: "Define statements to include during simulations.")
83115
var defines: [String] = []
84-
85-
@Option(name: [.customShort("I"), .customLong("include")], help: "Extra verilog models to include during simulations.")
116+
117+
@Option(
118+
name: [.customShort("I"), .customLong("include")],
119+
help: "Extra verilog models to include during simulations.")
86120
var includes: [String] = []
87-
121+
88122
@Argument(help: "The cutaway netlist to generate patterns for.")
89123
var file: String
90-
124+
91125
mutating func run() throws {
92-
126+
93127
if !TVGeneratorFactory.validNames.contains(tvGen) {
94128
throw ValidationError("Invalid test-vector generator \(tvGen).")
95129
}
96-
130+
97131
let fileManager = FileManager()
98132
guard fileManager.fileExists(atPath: file) else {
99133
throw ValidationError("File '\(file)' not found.")
100134
}
101-
135+
102136
guard fileManager.fileExists(atPath: cellModel) else {
103137
throw ValidationError("Cell model file '\(cellModel)' not found.")
104138
}
105-
139+
106140
if !cellModel.hasSuffix(".v"), !cellModel.hasSuffix(".sv") {
107141
Stderr.print(
108142
"Warning: Cell model file provided does not end with .v or .sv."
@@ -111,7 +145,7 @@ extension Fault {
111145

112146
let jsonOutput = output ?? file.replacingExtension(".cut.v", with: ".tv.json")
113147
let svfOutput = outputSvf ?? file.replacingExtension(".cut.v", with: ".tv.svf")
114-
148+
115149
// MARK: Importing Python and Pyverilog
116150

117151
let parse = Python.import("pyverilog.vparser.parser").parse
@@ -143,46 +177,36 @@ extension Fault {
143177
var etvSetVectors: [TestVector] = []
144178
var etvSetInputs: [Port] = []
145179

146-
if let tvSetTest = externalTVSet {
147-
if !fileManager.fileExists(atPath: tvSetTest) {
148-
throw ValidationError("TVs JSON file '\(tvSetTest)' not found.")
149-
}
150-
if tvSetTest.hasSuffix(".json") {
151-
(etvSetVectors, etvSetInputs) = try TVSet.readFromJson(file: tvSetTest)
152-
} else {
153-
(etvSetVectors, etvSetInputs) = try TVSet.readFromText(file: tvSetTest)
154-
}
155-
print("Read \(etvSetVectors.count) externally-generated vectors to verify.")
156-
}
157-
158180
if let tvGenerator = etvGen {
159181
guard let etvgen = ETVGFactory.get(name: tvGenerator) else {
160182
Stderr.print("Unknown external test vector generator '\(tvGenerator)'.")
161183
Foundation.exit(EX_USAGE)
162184
}
163-
164-
let benchUnwrapped = bench! // Program exits if etvGen.value isn't nil and bench.value is or vice versa
185+
186+
let benchUnwrapped = bench! // Program exits if etvGen.value isn't nil and bench.value is or vice versa
165187

166188
if !fileManager.fileExists(atPath: benchUnwrapped) {
167189
throw ValidationError("Bench file '\(benchUnwrapped)' not found.")
168190
}
169-
(etvSetVectors, etvSetInputs) = etvgen.generate(file: benchUnwrapped, module: "\(definition.name)")
191+
(etvSetVectors, etvSetInputs) = etvgen.generate(
192+
file: benchUnwrapped, module: "\(definition.name)")
170193

171194
if etvSetVectors.count == 0 {
172-
Stderr.print("Bench netlist appears invalid (no vectors generated). Are you sure there are no floating nets/outputs?")
195+
Stderr.print(
196+
"Bench netlist appears invalid (no vectors generated). Are you sure there are no floating nets/outputs?"
197+
)
173198
Foundation.exit(EX_DATAERR)
174199
} else {
175-
print("Generated \(etvSetVectors.count) test vectors using external utilties to verify.")
200+
print(
201+
"Generated \(etvSetVectors.count) test vectors using external utilties to verify."
202+
)
176203
}
177204
}
178205

179206
let tvMinimumCoverage = minCoverage / 100
180-
let finalTvCeiling: Int = ceiling ?? (
181-
etvSetVectors.count == 0 ?
182-
1000 :
183-
etvSetVectors.count
184-
)
185-
207+
let finalTvCeiling: Int =
208+
ceiling ?? (etvSetVectors.count == 0 ? 1000 : etvSetVectors.count)
209+
186210
let finalRNGSeed = UInt(rngSeed, radix: 16)!
187211

188212
do {
@@ -217,7 +241,7 @@ extension Fault {
217241
evtInputsMinusIgnored.append(input)
218242
}
219243
}
220-
assert(inputsMinusIgnored.count == evtInputsMinusIgnored.count);
244+
assert(inputsMinusIgnored.count == evtInputsMinusIgnored.count)
221245
inputsMinusIgnored = evtInputsMinusIgnored
222246
}
223247

@@ -230,7 +254,7 @@ extension Fault {
230254
} else {
231255
let minimum = min(port.from, port.to)
232256
let maximum = max(port.from, port.to)
233-
for i in minimum ... maximum {
257+
for i in minimum...maximum {
234258
faultPoints.insert("\(port.name) [\(i)]")
235259
}
236260
}
@@ -255,10 +279,14 @@ extension Fault {
255279
}
256280

257281
if warnAboutDFF {
258-
print("Warning: D-flipflops were found in this netlist. Are you sure you ran it through 'fault cut'?")
282+
print(
283+
"Warning: D-flipflops were found in this netlist. Are you sure you ran it through 'fault cut'?"
284+
)
259285
}
260286

261-
print("Found \(faultPoints.count) fault sites in \(gateCount) gates and \(ports.count) ports.")
287+
print(
288+
"Found \(faultPoints.count) fault sites in \(gateCount) gates and \(ports.count) ports."
289+
)
262290

263291
// MARK: Load Initial Set
264292

@@ -314,16 +342,18 @@ extension Fault {
314342
coverageList: result.coverageList
315343
)
316344
let jsonRawOutput = jsonOutput.replacingExtension(".tv.json", with: ".raw_tv.json")
317-
345+
318346
print("Writing raw generated test vectors in Fault JSON format to \(jsonOutput)")
319347
try encoder.encode(rawTVInfo).write(to: URL(fileURLWithPath: jsonRawOutput))
320-
348+
321349
let tvInfo = TVInfo(
322350
inputs: inputsMinusIgnored,
323351
outputs: outputs,
324352
coverageList: Compactor.compact(coverageList: result.coverageList)
325353
)
326-
print("Writing compacted generated test vectors in Fault JSON format to \(jsonOutput)")
354+
print(
355+
"Writing compacted generated test vectors in Fault JSON format to \(jsonOutput)"
356+
)
327357
try encoder.encode(tvInfo).write(to: URL(fileURLWithPath: jsonOutput))
328358

329359
// try File.open(svfOutput, mode: .write) {
@@ -332,7 +362,8 @@ extension Fault {
332362
// }
333363

334364
if let coverageMetaFilePath = outputCoverageMetadata {
335-
print("Writing YAML file of final coverage metadata to \(coverageMetaFilePath)")
365+
print(
366+
"Writing YAML file of final coverage metadata to \(coverageMetaFilePath)")
336367
try File.open(coverageMetaFilePath, mode: .write) {
337368
try $0.write(string: YAMLEncoder().encode(result.coverageMeta))
338369
}

0 commit comments

Comments
 (0)