CIRCT  19.0.0git
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 
13 #include "PassDetails.h"
20 #include "mlir/IR/Attributes.h"
21 #include "mlir/IR/Builders.h"
22 #include "llvm/Support/Parallel.h"
23 
24 using namespace mlir;
25 using namespace circt;
26 using namespace firrtl;
27 
28 namespace {
29 struct RandomizeRegisterInitPass
30  : public RandomizeRegisterInitBase<RandomizeRegisterInitPass> {
31  void runOnOperation() override;
32 };
33 
34 } // end anonymous namespace
35 
36 std::unique_ptr<mlir::Pass> circt::firrtl::createRandomizeRegisterInitPass() {
37  return std::make_unique<RandomizeRegisterInitPass>();
38 }
39 
40 /// Create attributes indicating the required size of random initialization
41 /// values for each register in the module, and mark which range of these values
42 /// each register should consume. The goal is for registers to always read the
43 /// same random bits for the same seed, regardless of optimizations that might
44 /// remove registers.
45 static void createRandomizationAttributes(FModuleOp mod) {
46  OpBuilder builder(mod);
47 
48  // Walk all registers.
49  uint64_t currentWidth = 0;
50  auto ui64Type = builder.getIntegerType(64, false);
51  mod.walk([&](Operation *op) {
52  if (!isa<RegOp, RegResetOp>(op))
53  return;
54 
55  // Compute the width of all registers, and remember which bits are assigned
56  // to each register.
57  auto regType = type_cast<FIRRTLBaseType>(op->getResult(0).getType());
58  std::optional<int64_t> regWidth = getBitWidth(regType);
59  assert(regWidth.has_value() && "register must have a valid FIRRTL width");
60 
61  auto start = builder.getIntegerAttr(ui64Type, currentWidth);
62  op->setAttr("firrtl.random_init_start", start);
63 
64  currentWidth += *regWidth;
65  });
66 }
67 
68 void RandomizeRegisterInitPass::runOnOperation() {
69  createRandomizationAttributes(getOperation());
70 }
assert(baseType &&"element must be base type")
Builder builder
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.
Definition: DebugAnalysis.h:21