CIRCT 21.0.0git
Loading...
Searching...
No Matches
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
41/// Create attributes indicating the required size of random initialization
42/// values for each register in the module, and mark which range of these values
43/// each register should consume. The goal is for registers to always read the
44/// same random bits for the same seed, regardless of optimizations that might
45/// remove registers.
46static void createRandomizationAttributes(FModuleOp mod) {
47 OpBuilder builder(mod);
48
49 // Walk all registers.
50 uint64_t currentWidth = 0;
51 auto ui64Type = builder.getIntegerType(64, false);
52 mod.walk([&](Operation *op) {
53 if (!isa<RegOp, RegResetOp>(op))
54 return;
55
56 // Compute the width of all registers, and remember which bits are assigned
57 // to each register.
58 auto regType = type_cast<FIRRTLBaseType>(op->getResult(0).getType());
59 std::optional<int64_t> regWidth = getBitWidth(regType);
60 assert(regWidth.has_value() && "register must have a valid FIRRTL width");
61
62 auto start = builder.getIntegerAttr(ui64Type, currentWidth);
63 op->setAttr("firrtl.random_init_start", start);
64
65 currentWidth += *regWidth;
66 });
67}
68
69void RandomizeRegisterInitPass::runOnOperation() {
70 createRandomizationAttributes(getOperation());
71}
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::optional< int64_t > getBitWidth(FIRRTLBaseType type, bool ignoreFlip=false)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.