Loading [MathJax]/extensions/tex2jax.js
CIRCT 21.0.0git
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RandomizeRegisterInit.cpp
Go to the documentation of this file.
1//===- RandomizeRegisterInit.cpp - Randomize register initialization ------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the RandomizeRegisterInit pass.
10//
11//===----------------------------------------------------------------------===//
12
17#include "mlir/IR/Attributes.h"
18#include "mlir/IR/Builders.h"
19#include "mlir/Pass/Pass.h"
20
21namespace circt {
22namespace firrtl {
23#define GEN_PASS_DEF_RANDOMIZEREGISTERINIT
24#include "circt/Dialect/FIRRTL/Passes.h.inc"
25} // namespace firrtl
26} // namespace circt
27
28using namespace mlir;
29using namespace circt;
30using namespace firrtl;
31
32namespace {
33struct RandomizeRegisterInitPass
34 : public circt::firrtl::impl::RandomizeRegisterInitBase<
35 RandomizeRegisterInitPass> {
36 void runOnOperation() override;
37};
38
39} // end anonymous namespace
40
42 return std::make_unique<RandomizeRegisterInitPass>();
43}
44
45/// Create attributes indicating the required size of random initialization
46/// values for each register in the module, and mark which range of these values
47/// each register should consume. The goal is for registers to always read the
48/// same random bits for the same seed, regardless of optimizations that might
49/// remove registers.
50static void createRandomizationAttributes(FModuleOp mod) {
51 OpBuilder builder(mod);
52
53 // Walk all registers.
54 uint64_t currentWidth = 0;
55 auto ui64Type = builder.getIntegerType(64, false);
56 mod.walk([&](Operation *op) {
57 if (!isa<RegOp, RegResetOp>(op))
58 return;
59
60 // Compute the width of all registers, and remember which bits are assigned
61 // to each register.
62 auto regType = type_cast<FIRRTLBaseType>(op->getResult(0).getType());
63 std::optional<int64_t> regWidth = getBitWidth(regType);
64 assert(regWidth.has_value() && "register must have a valid FIRRTL width");
65
66 auto start = builder.getIntegerAttr(ui64Type, currentWidth);
67 op->setAttr("firrtl.random_init_start", start);
68
69 currentWidth += *regWidth;
70 });
71}
72
73void RandomizeRegisterInitPass::runOnOperation() {
74 createRandomizationAttributes(getOperation());
75}
assert(baseType &&"element must be base type")
static void createRandomizationAttributes(FModuleOp mod)
Create attributes indicating the required size of random initialization values for each register in t...
std::unique_ptr< mlir::Pass > createRandomizeRegisterInitPass()
std::optional< int64_t > getBitWidth(FIRRTLBaseType type, bool ignoreFlip=false)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.