Fix an issue in the `ExtractInstances` pass where certain diamond-shaped
instantiation arrangements can lead to instances with identical symbol
after extraction.
With this change, the pass uses `ModuleNamespace::newName` to ensure the
instance symbol is unique within the module it is being extracted to.
Fixing this also requires fixing an issue where a black box in a
multiply instantiated parent would not properly filter its non-local
annotations to only contain the ones that go through the parent instance
it was pulled out of.
Fixes#3089.
Run the MemToRegofVec transformation only on DUT memories and ignore any
modules in the testbench. Also retain MemOps marked with
`ExcludeMemFromMemToRegOfVec` annotation.
LowerMemory pass should not error out on CombMems, but just retain them to be
lowered by HWMemSimImpl to registers.
The assumption here is that any operation which is not a special group operation (`calyx.group_done,calyx.group_go,calyx.assign`) is some form of combinational computation that can be lifted to the wire scope.
Extend the `ExtractInstances` pass such that it marks instances of the
new `FMemModuleOp` as to be extracted. This then allows the pass to
cover the functionality of the original `ExtractSeqMems` pass on the
Scala side of things.
Fixes#3092.
This changes the memory-related metadata emitted by this pass to be
created from FMemModules instead of MemOps. The memories will have
already been lowered into modules. The pass can be simplified because
it no longer has to worry about deduplicating the memories itself.
This changing the memory op lowering to store all annotations that were
attached to the MemOp on the new instance op, instead of on the new
memory module op. This is needed because OMIR trackers distinguish
their type based on the operation they are attached to.
This commit changes to reuse existing wires as placeholder of output ports
when output ports are uniquely assigned to a wire. This change reduces
the number of temporary wires in the large design 15%.
This commit adds extra parentheses around reduction ops (e.g. `&a` and `|b`) when
their operators are emitted in a row. For example, `foo & &a` becomes `foo & (&a)`.
Fix an issue in `InferResets` where the FIRRTL input would under certain
circumstances contain a zero-length vector of resets like `Reset[0]` but
without any accompanying `x is invalid` statement. This would be the
case for an optional list of resets where the Chisel code would connect
the individual reset wires, but would just emit no connects at all since
none would be present in an empty vector.
The original Scala implementation of `InferResets` seems to either not
have to deal with this issue since zero-length vectors are removed early
on, or it just ignores them for later Verilog emission to discard them.
This commit adjusts the behaviour of `InferResets` to always infer
zero-length reset vectors to `UInt<1>`, similar to how `InvalidValueOp`
is treated.
We should identify the clocks to be same even if the clock is passed via different wires.
This should prevent creating multiple write ports for combmem. This commit changes to
use `getModuleScopedDriver` to track clock port values.
Initial implementation of LLVM graph traits for an FSM machine operation. This will most likely be a useful piece of code for building further transformations, visualizations, ... upon.
This simplifies the code, and makes the Module port logic more similar
to the Instance port logic. This should hopefully fix an issue MSVC had
with the initializer_list constructor used.
When the SFC lowers memories to ext modules, they also create a wrapper
module which just instantiates the external module. MFC did not create
this wrapper module, since the extra level of abstraction did not seem
necessary. We have found that to be a drop in replacement for SFC, we
need these wrapper modules so that Module and Instance paths are all
identical. This commit adds wrapper modules following the style of the
SFC.
This commit also fixes how non-local annotations are handled by this
pass. When the memory operation has a non-local annotation attached, we
need to move the annotation over to the new module, update the NLA to
point to the module instead of the instance, and put an NLA reference on
the instance.
ExportVerilog may end up spilling temporary declarations for
expressions that are already going to be assigned to an inout. Try to
anticipate this in PrepareForEmission, and rewrite the uses of the
expression to read from the inout when possible.
This commit adds the MemToRegOfVec transformation to the FIRRTL pipeline.
This transformation converts all comb memories, to registers.
The mem tap and Async reset transformation are also updated to align
with this transformation.
(More details in the updated FIRRTL doc)
This transformation is enabled by default.
This adds the ability to lower FIRRTL memory modules to external module
black boxes. This lowering is almost the same as FIRRTL external
modules, but without having to worry about parameterization or defname.
This adds the ability to prefix and potentially duplicate the FIRRTL
memory modules. When the new memory lowering pipeline takes over, we
can remove the `mem.group` attribute which `PrefixModules` is using to
prevent later deduplication of memories.
This adds a new FIRRTL transformation which looks for
`AddSeqMemPortsAnnotation` and attaches the extra port specified to all
SRAMs under the DUT. The extra ports are always of type UInt<> with a
user specified width. The extra ports are wired up through the top of
the DUT and tied off to 0 in the testharness.
This pass requires that memories have been lowered to modules, and will
emit an error if it finds a regular mem op in the module. This is
because it is not possible to add arbitrary ports to a `mem` op that don't
match the schema of a memory `r`/`w`/`rw` port.
* LLVM bump (as we know it)
* minor format fix
* DCMAKE_BUILD_TYPE=?
* Update lib/Dialect/MSFT/MSFTOps.cpp
Co-authored-by: Andrew Young <youngar17@gmail.com>
* Update lib/Dialect/FIRRTL/FIRRTLOps.cpp
Co-authored-by: Andrew Young <youngar17@gmail.com>
* Update lib/Dialect/Calyx/CalyxOps.cpp
Co-authored-by: Andrew Young <youngar17@gmail.com>
* removed anon module test
Co-authored-by: Andrew Young <youngar17@gmail.com>
When the FullAsyncResetTransform replaces the reset of a register it
replaces all other connections to the register with a `mux(reset,
resetValue, originalValue)`. This caused problems when the value was
connected inside of a When block. The old reset value would become gated
on the When op's condition. The original reset value needed to have
higher priority than the original conditions. This change adds an
explicit self-connect to the register which is properly muxed with the
reset.
Input:
```firrtl
reg r : UInt<8>, clock with :
(reset => (reset, UInt<8>(1)))
when cond:
r <= x
```
Original output:
```firrtl
reg r : UInt<8>, clock with :
(reset => (async, UInt<8>(0)))
when cond:
r = mux (reset, UInt<8>(1), x)
```
New output:
```firrtl
reg r : UInt<8>, clock with :
(reset => (async, UInt<8>(0)))
r <= mux(reset, UInt<8>(1), r)
when cond:
r = mux (reset, UInt<8>(1), x)
```
The infer widths pass made the assumption that the arguments to a
`MuxPrimOp` were ground types, and would trigger an assertion trying to
create a `max(high, low)` constraint on the operands. This changes the
mux constraint generation to recursively constrain the type of the
result to the maximum of the high and low signals.
This commit introduces tuple types to the handshake runner. Tuple values
are represented as vectors of values.
Tuples can be feed to the handshake runner by using the `"(val1, ...,
valN)"` syntax.
This works similarly to output-omir: if specified, the final MLIR is
written into this file. This is useful to get the final MLIR output
alongside some other output, especially split-verilog.
This would close https://github.com/llvm/circt/issues/2946.
This adds a FMemModule operation, which is an external module used for
FIRRTL SRAMs. It is almost exactly the same, except it doesn't support
FExtModule's parameterization, does not have a `defname`, and it
contains required attributes for memory metadata. It was convenient to
not use FExtModules with a bunch of extra attributes stored on it to
make sure that the attributes were properly checked.
The set of attributes stored on the memory are those needed to create all
the metadata files. The types used for the attributes were generally
the same as those used by the memory generator schema. It might make
sense to revisit the types and use signless integer types in the future.
Co-authored-by: Prithayan Barua <prithayan@gmail.com>
The helper accidentally inserted the block arguments in the reverse
order that it was supposed to. This was happening because each block
argument was inserted one at a time, causing us to have to increase the
insertion index by 1 every time we insert an argument.
This does a simple wire preservation. This means:
nodes and wires become wires if they have names
names that don't start with '_' are preserved
names don't block constant propgation, but do block deleting wires.
This commit moves the ExtractInstances pass before the GCT passes.
GCT passes can embed the instance paths into Verbatim ops, which can later be
updated by the ExtractInstances pass, causing incorrect instance paths being
generated into the verilog.
This commit should fix that bug with invalid instance paths.
We don't have to extract assertions from modules in testbench since
it already separated from DUT. This commit addsfirrtl.extract.do_not_extract
attribue to modules on LowerToHW if they are located in testbench.
And in SVExtractTestCode, we skip extractions if that attribute appears.
This change will hopefully improve simulation performance by reducing overheads
of module instantiations.
Factors out functions for building constants and registers in Calyx programs.
Note: For some reason, this change seems to partially apply canonicalization in the `compile-control.mlir` test wherein constants are moved to the cell-scope.
The verification ensures that:
- At most one continuous assignment exists for any given value
- A continuously assigned wire has no assignments inside groups.
Add a `ExtractInstances` pass which implements a combined version of the
Scala `ExtractBlackBoxes`, `ExtractClockGates`, and `ExtractSeqMems`
passes. The pass is split into two phases:
As a first step it traverses modules and instances in the design and
marks the ones appropriately annotated for extraction.
In a second step it repeatedly pushes the marked instances up one level
of the hierarchy until they reach the desired parent module (usually
indicated with a `MarkDUTAnnotation`). The extracted instances are then
optionally grouped into a submodule at their extracted location. Finally
the pass also emits a text file indicating where the extracted instances
were originally located in the design.