Jlm
Loading...
Searching...
No Matches
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
17namespace jlm::hls
18{
19
20using namespace circt;
21using namespace llvm;
22
23bool
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