-
Notifications
You must be signed in to change notification settings - Fork 14
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
[Experimental][export-smv] Introduce the export-smv tool #67
base: main
Are you sure you want to change the base?
Conversation
this is the inital commit for the export-smv tool, which converts a canonicalized handshake ir to a smv netlist and a library of dataflow unit written in smv
now support abstract operators and deciders.
this commit adds the smv description of dataflow units that are not parametrized. The implementation of the parametrized units will be generated on the fly.
…ic-mlir into experimental-export-smv
internal pipelines
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the contribution! I left a couple of super minor comments.
Operation *dst = oprd.getOwner(); | ||
|
||
// Locate value in source results and destination operands | ||
const size_t resIdx = findIndexInRange(src->getResults(), val); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you are sure that val
is the result of an operation you can just do
const size_t resIdx = cast<OpResult>(val).getResultNumber();
|
||
// Locate value in source results and destination operands | ||
const size_t resIdx = findIndexInRange(src->getResults(), val); | ||
const size_t argIdx = findIndexInRange(dst->getOperands(), val); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can just do
const size_t argIdx = oprd.getOperandNumber();
StringRef unitName = getUniqueName(op); | ||
|
||
os << "VAR " << unitName << " : "; | ||
if (failed(getUnitType(op, os, timingDB))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: unnecessary brackets
|
||
for (auto [idx, arg] : llvm::enumerate(op->getOperands())) { | ||
os << unitName << "_dataIn" << idx << ", " << unitName << "_pValid" << idx; | ||
if (idx < op->getNumOperands() - 1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: unnecessary brackets
|
||
for (auto [idx, arg] : llvm::enumerate(op->getResults())) { | ||
os << unitName << "_nReady" << idx; | ||
if (idx < op->getNumResults() - 1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: unnecessary brackets
return success(); | ||
} | ||
|
||
LogicalResult getOperatorImpl(unsigned numInputs, unsigned lat, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None of the for
's in this function need brackets
os << "DEFINE valid0 := b" << slots - (transp) << ".valid0; \n"; | ||
os << "DEFINE ready0 := b0.ready0; \n"; | ||
if (transp) { | ||
assert(std::size(data) == slots); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: we use the size()
method on vectors across the repository instead of std::size
assert(nOutputs >= 2 && "received a fork with 0 or 1 output ports!"); | ||
// interface | ||
os << "\nMODULE fork_1_" << nOutputs << "(dataIn0, pValid0, "; | ||
for (unsigned i = 0; i < nOutputs - 1; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: unnecessary brackets
} | ||
os << "nReady" << nOutputs - 1 << ")\n"; | ||
os << "forkStop := "; | ||
for (unsigned i = 0; i < nOutputs - 1; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: unnecessary brackets
"this file"), | ||
cl::init("data/components.json"), cl::cat(mainCategory)); | ||
|
||
static size_t findIndexInRange(ValueRange range, Value val) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No longer needed after changes proposed below
…ic-mlir into experimental-export-smv
This PR introduces the export-smv tool, which converts a handshake-level IR to the nuXmv input format,
.smv
(https://nuxmv.fbk.eu/).This allows us to run model-checking on an abstracted dataflow circuit model.
Example use:
Prepare the following nuXmv batch script,
commands.cmd
And we can launch a verification run by using
nuXmv -int commands.cmd
The current implementation prints a netlist and a library of units in the SMV format to stdout.
Since this language does not support parametrized instantiation, we generate one implementation for each parametrization of a unit, e.g., it generates one implementation for 2-output, 3-output, and 4-output eager fork.