Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explicit Muxes in Scan-chain and SCL Configuration YAMLs #40

Merged
merged 5 commits into from
Jan 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,7 @@ Netlists
*.test
*.log
*.vvp
parsetab.py
parsetab.py

.swiftpm/
abc.history
1 change: 1 addition & 0 deletions .swift-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
5.4
10 changes: 2 additions & 8 deletions Contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,7 @@ Make your changes and then submit them as a pull requests to the `main` branch.

Consult [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more information on using pull requests.

## The Approval Process
For a PR to be merged, there are two requirements:

- It must pass all automated checks.
- An OpenLane team member must inspect and approve the PR.

# Licensing and Copyright
Please add you (or your employer's) copyright headers to any files to which you have made major edits.
Please add your (or your employer's) copyright headers to any files to which you have made major edits.

Please note all code contributions must have the same license as Fault, i.e., the Apache License, version 2.0.
Please note all code contributions must have the same license as Fault, i.e., the Apache License, version 2.0.
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ RUN cp /lib64/libtcl8.5.so /build/lib
# Fault Setup
WORKDIR /fault
COPY . .
ENV CC=clang
ENV CXX=clang++
RUN swift build --static-swift-stdlib -c release
RUN cp /fault/.build/x86_64-unknown-linux-gnu/release/Fault /build/bin/fault
WORKDIR /
Expand All @@ -93,4 +95,4 @@ ENV PATH=/build/bin:$PATH\
FAULT_IVERILOG=/build/bin/iverilog\
FAULT_VVP=/build/bin/vvp

CMD [ "/bin/bash" ]
CMD [ "/bin/bash" ]
9 changes: 9 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@
"revision": "c77231820148515a77e9bba5016a57e5a88ef007",
"version": null
}
},
{
"package": "Yams",
"repositoryURL": "https://github.com/jpsim/Yams.git",
"state": {
"branch": null,
"revision": "0d9ee7ea8c4ebd4a489ad7a73d5c6cad55d6fed3",
"version": "5.0.6"
}
}
]
},
Expand Down
13 changes: 7 additions & 6 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// swift-tools-version:5.0
// swift-tools-version:5.4
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "Fault",
platforms: [
.macOS(.v10_13) // executableURL and a bunch of other things are not available before High Sierra
.macOS(.v11), // executableURL and a bunch of other things are not available before High Sierra
],
dependencies: [
// Dependencies declare other packages that this package depends on.
Expand All @@ -15,19 +15,20 @@ let package = Package(
.package(url: "https://github.com/pvieito/PythonKit", .branch("master")),
.package(url: "https://github.com/pvieito/CommandLineKit", .branch("master")),
.package(url: "https://github.com/donn/Defile.git", from: "5.2.1"),
.package(url: "https://github.com/attaswift/BigInt.git", from: "5.2.1")
.package(url: "https://github.com/attaswift/BigInt.git", from: "5.2.1"),
.package(url: "https://github.com/jpsim/Yams.git", from: "5.0.6"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(
.executableTarget(
name: "Fault",
dependencies: ["PythonKit", "CommandLineKit", "Defile", "OrderedDictionary", "BigInt"],
dependencies: ["PythonKit", "CommandLineKit", "Defile", "OrderedDictionary", "BigInt", "Yams"],
path: "Sources"
),
.testTarget(
name: "FaultTests",
dependencies: ["Fault"]
)
),
]
)
2 changes: 1 addition & 1 deletion Readme.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# 🧪 Fault
![Swift 5.2+](https://img.shields.io/badge/Swift-5.2-orange?logo=swift) ![Docker Image Available for x86-64](https://img.shields.io/static/v1?logo=docker&label=docker&message=x86_64) ![AppImage Available for Linux x86-64](https://img.shields.io/static/v1?label=appimage&message=x86_64&color=blue)
![Swift 5.4+](https://img.shields.io/badge/Swift-5.4-orange?logo=swift) ![Docker Image Available for x86-64](https://img.shields.io/static/v1?logo=docker&label=docker&message=x86_64) ![AppImage Available for Linux x86-64](https://img.shields.io/static/v1?label=appimage&message=x86_64&color=blue)

Fault is a complete open source design for testing (DFT) Solution that includes automatic test pattern generation for netlists, scan chain stitching, synthesis scripts and a number of other convenience features.

Expand Down
67 changes: 36 additions & 31 deletions Sources/Fault/Bench.swift
Original file line number Diff line number Diff line change
@@ -1,28 +1,39 @@
// Copyright (C) 2019 The American University in Cairo
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import Foundation
import PythonKit

struct BenchCircuit: Codable {
var cells: [BenchCell]

init(cells: [BenchCell]){
init(cells: [BenchCell]) {
self.cells = cells
}

static func extract(definitions: PythonObject) throws -> [BenchCell] {

var cells: [BenchCell] = []
for definition in definitions {

let type = Python.type(definition).__name__

if type == "ModuleDef" {

let (_, inputs, outputs) = try Port.extract(from: definition)
let cellName = definition.name

var cellStatements: [String] = []
var cellOutput: String = ""

var cellOutput = ""
for output in outputs {
cellOutput = String(describing: output.name)
}
Expand All @@ -33,23 +44,21 @@ struct BenchCircuit: Codable {
}

for item in definition.items {

let type = Python.type(item).__name__

if type == "InstanceList" {
let instance = item.instances[0]

let outArgname = String(describing: instance.portlist[0].argname)
let output = (outArgname == cellOutput) ? outArgname : "__\(outArgname)___"
let outArgname = String(describing: instance.portlist[0].argname)
let output = (outArgname == cellOutput) ? outArgname : "__\(outArgname)___"

var benchStatement = "("
for hook in instance.portlist[1...]{
for hook in instance.portlist[1...] {
let argname = String(describing: hook.argname)

if cellInputs.contains(argname) {
benchStatement += "\(hook.argname), "
}
else {
} else {
benchStatement += "__\(hook.argname)___, "
}
}
Expand All @@ -60,25 +69,20 @@ struct BenchCircuit: Codable {
switch instance.module {
case "and":
cellStatements.append("\(output) = AND" + benchStatement)
break
case "or":
cellStatements.append("\(output) = OR" + benchStatement)
break
case "xor":
let inputA = instance.portlist[1].argname
let inputB = instance.portlist[2].argname
cellStatements.append(contentsOf: [
"__or_out___ = OR(\(inputA), \(inputB))",
"__nand_out___ = NAND(\(inputA), \(inputB))",
"\(output) = AND(__or_out___, __nand_out___)"
"\(output) = AND(__or_out___, __nand_out___)",
])
break
case "buf":
cellStatements.append("\(output) = BUFF" + benchStatement)
break
case "not":
cellStatements.append("\(output) = NOT" + benchStatement)
break
default:
print("[Warning]: can't expand \(instance.module) in \(cellName) to primitive cells")
}
Expand All @@ -97,7 +101,6 @@ struct BenchCircuit: Codable {

return cells
}

}

struct BenchCell: Codable {
Expand All @@ -111,46 +114,48 @@ struct BenchCell: Codable {
inputs: [String],
output: String,
statements: [String]
){
) {
self.name = name
self.inputs = inputs
self.output = output
self.statements = statements
}

func extract(name: String, inputs: [String:String], output: [String]) throws -> String {
func extract(name: String, inputs: [String: String], output: [String]) throws -> String {
do {
let regexOutput = try NSRegularExpression(pattern: "\(self.output) = ")
let regexWires = try NSRegularExpression(pattern: "___")
let outputName = (output[0].hasPrefix("\\")) ? "\\\(output[0])" : "\(output[0])"

var benchStatements = self.statements
var benchStatements = statements
for (index, _) in statements.enumerated() {

var range = NSRange(benchStatements[index].startIndex..., in: benchStatements[index])
benchStatements[index] = regexOutput.stringByReplacingMatches(
in: benchStatements[index],
options: [],
range: range,
withTemplate: "\(outputName) = ")
withTemplate: "\(outputName) = "
)

range = NSRange(benchStatements[index].startIndex..., in: benchStatements[index])
range = NSRange(benchStatements[index].startIndex..., in: benchStatements[index])
benchStatements[index] = regexWires.stringByReplacingMatches(
in: benchStatements[index],
options: [],
range: range,
withTemplate: "__\(name)")
withTemplate: "__\(name)"
)

for input in self.inputs {
let regexInput = try NSRegularExpression(pattern: "(?<=\\(|,)\\s*\(input)(?=\\s*,|\\s*\\))")
let name = (inputs[input]!.hasPrefix("\\")) ? "\\\(inputs[input]!)" : "\(inputs[input]!)"

range = NSRange(benchStatements[index].startIndex..., in: benchStatements[index])
range = NSRange(benchStatements[index].startIndex..., in: benchStatements[index])
benchStatements[index] = regexInput.stringByReplacingMatches(
in: benchStatements[index],
options: [],
range: NSRange(benchStatements[index].startIndex..., in: benchStatements[index]),
withTemplate: name )
withTemplate: name
)
}
}

Expand All @@ -166,4 +171,4 @@ struct BenchCell: Codable {
return ""
}
}
}
}
44 changes: 29 additions & 15 deletions Sources/Fault/BoundaryScanRegister.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
// Copyright (C) 2019 The American University in Cairo
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import Foundation
import PythonKit

Expand All @@ -6,7 +20,7 @@ class BoundaryScanRegisterCreator {
private var inputName: String
private var outputName: String
var counter: Int = 0

var clock: String
var reset: String
var resetActive: Simulator.Active
Expand All @@ -30,22 +44,22 @@ class BoundaryScanRegisterCreator {
using Node: PythonObject
) {
self.name = name
self.inputName = "\(name)_input"
self.outputName = "\(name)_output"
inputName = "\(name)_input"
outputName = "\(name)_output"

self.clock = clock
self.clockIdentifier = Node.Identifier(clock)
clockIdentifier = Node.Identifier(clock)

self.reset = reset
self.resetIdentifier = Node.Identifier(reset)
resetIdentifier = Node.Identifier(reset)

self.resetActive = resetActive

self.testing = testing
self.testingIdentifier = Node.Identifier(testing)
testingIdentifier = Node.Identifier(testing)

self.shift = shift
self.shiftIdentifier = Node.Identifier(shift)
shiftIdentifier = Node.Identifier(shift)

self.Node = Node
}
Expand All @@ -66,8 +80,8 @@ class BoundaryScanRegisterCreator {
let ordinalConstant = Node.Constant(ordinal)

let name = input ? inputName : outputName
let dinArg = (max == 0) ? dinIdentifier: Node.Pointer(dinIdentifier, ordinalConstant)
let doutArg = (max == 0) ? doutIdentifier: Node.Pointer(doutIdentifier, ordinalConstant)
let dinArg = (max == 0) ? dinIdentifier : Node.Pointer(dinIdentifier, ordinalConstant)
let doutArg = (max == 0) ? doutIdentifier : Node.Pointer(doutIdentifier, ordinalConstant)

let portArguments = [
Node.PortArg("din", dinArg),
Expand All @@ -77,7 +91,7 @@ class BoundaryScanRegisterCreator {
Node.PortArg("clock", clockIdentifier),
Node.PortArg("reset", resetIdentifier),
Node.PortArg("testing", testingIdentifier),
Node.PortArg("shift", shiftIdentifier)
Node.PortArg("shift", shiftIdentifier),
]

let submoduleInstance = Node.Instance(
Expand All @@ -97,7 +111,7 @@ class BoundaryScanRegisterCreator {
}

var inputDefinition: String {
return """
"""
module \(inputName) (
din,
dout,
Expand All @@ -123,12 +137,12 @@ class BoundaryScanRegisterCreator {
assign sout = store;
assign dout = testing ? store : din;
endmodule

"""
}

var outputDefinition: String {
return """
"""
module \(outputName) (
din,
dout,
Expand All @@ -153,7 +167,7 @@ class BoundaryScanRegisterCreator {
assign sout = store;
assign dout = din;
endmodule

"""
}
}
}
Loading
Loading