Jlm
FirrtlToVerilogConverter.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2024 Magnus Sjalander <work@sjalander.com>
3  * See COPYING for terms of redistribution.
4  */
5 
7 
8 #include <circt/Conversion/ExportVerilog.h>
9 #include <circt/Dialect/FIRRTL/FIRParser.h>
10 #include <circt/Dialect/HW/HWOps.h>
11 #include <circt/Dialect/SV/SVPasses.h>
12 #include <circt/Firtool/Firtool.h>
13 #include <llvm/Support/SourceMgr.h>
14 #include <mlir/IR/BuiltinOps.h>
15 #include <mlir/Support/FileUtilities.h>
16 
17 namespace jlm::hls
18 {
19 
20 using namespace circt;
21 using namespace llvm;
22 
23 bool
25  const util::FilePath inputFirrtlFile,
26  const util::FilePath outputVerilogFile)
27 {
28  mlir::MLIRContext context;
29  mlir::TimingScope ts;
30 
31  // Set up and read the input FIRRTL file
32  std::string errorMessage;
33  auto input = mlir::openInputFile(inputFirrtlFile.to_str(), &errorMessage);
34  if (!input)
35  {
36  std::cerr << errorMessage << std::endl;
37  return false;
38  }
39  llvm::SourceMgr sourceMgr;
40  sourceMgr.AddNewSourceBuffer(std::move(input), llvm::SMLoc());
41  mlir::SourceMgrDiagnosticVerifierHandler sourceMgrHandler(sourceMgr, &context);
42 
43  firrtl::FIRParserOptions options;
44  options.infoLocatorHandling = firrtl::FIRParserOptions::InfoLocHandling::IgnoreInfo;
45  options.numAnnotationFiles = 0;
46  options.scalarizePublicModules = true;
47  options.scalarizeExtModules = true;
48  auto module = importFIRFile(sourceMgr, &context, ts, options);
49  if (!module)
50  {
51  std::cerr << "Failed to parse FIRRTL input" << std::endl;
52  return false;
53  }
54 
55  // Manually set the options for the firtool
56  firtool::FirtoolOptions firtoolOptions;
57  firtoolOptions.setOutputFilename(outputVerilogFile.to_str());
58  firtoolOptions.setPreserveAggregate(firrtl::PreserveAggregate::PreserveMode::None);
59  firtoolOptions.setPreserveValues(firrtl::PreserveValues::PreserveMode::Named);
60  firtoolOptions.setBuildMode(firtool::FirtoolOptions::BuildModeDefault);
61  firtoolOptions.setChiselInterfaceOutDirectory("");
62  firtoolOptions.setDisableHoistingHWPassthrough(true);
63  firtoolOptions.setOmirOutFile("");
64  firtoolOptions.setBlackBoxRootPath("");
65  firtoolOptions.setReplSeqMemFile("");
66  firtoolOptions.setOutputAnnotationFilename("");
67 
68  // Populate the pass manager and apply them to the module
69  mlir::PassManager pm(&context);
70  if (failed(firtool::populatePreprocessTransforms(pm, firtoolOptions)))
71  {
72  std::cerr << "Failed to populate preprocess transforms" << std::endl;
73  return false;
74  }
75 
76  // Firtool sets a blackBoxRoot based on the inputFilename path, but this functionality is not used
77  // so we set it to an empty string (the final argument)
78  if (failed(firtool::populateCHIRRTLToLowFIRRTL(pm, firtoolOptions, "")))
79  {
80  std::cerr << "Failed to populate CHIRRTL to LowFIRRTL" << std::endl;
81  return false;
82  }
83  if (failed(firtool::populateLowFIRRTLToHW(pm, firtoolOptions)))
84  {
85  std::cerr << "Failed to populate LowFIRRTL to HW" << std::endl;
86  return false;
87  }
88  if (failed(firtool::populateHWToSV(pm, firtoolOptions)))
89  {
90  std::cerr << "Failed to populate HW to SV" << std::endl;
91  return false;
92  }
93  std::error_code errorCode;
94  llvm::raw_fd_ostream os(outputVerilogFile.to_str(), errorCode);
95  if (failed(firtool::populateExportVerilog(pm, firtoolOptions, os)))
96  {
97  std::cerr << "Failed to populate Export Verilog" << std::endl;
98  return false;
99  }
100 
101  if (failed(pm.run(module.get())))
102  {
103  std::cerr << "Failed to run pass manager" << std::endl;
104  return false;
105  }
106 
107  (void)module.release();
108  return true;
109 }
110 
111 } // namespace jlm::hls
static bool Convert(const util::FilePath inputFirrtlFile, const util::FilePath outputVerilogFile)
const std::string & to_str() const noexcept
Definition: file.hpp:275