From 2345382e672b652e3195449db3b2813b78622f7a Mon Sep 17 00:00:00 2001 From: Martin Erhart Date: Fri, 19 Jul 2024 18:54:14 +0200 Subject: [PATCH] [LLHD] Remove llhd-sim (#7351) --- CMakeLists.txt | 18 - CODEOWNERS | 1 - docs/dialects.dot | 20 +- docs/includes/img/dialects.png | Bin 192620 -> 183804 bytes docs/includes/img/dialects.svg | 598 +++-- include/circt/Conversion/LLHDToLLVM.h | 43 - include/circt/Conversion/Passes.h | 1 - include/circt/Conversion/Passes.td | 16 - include/circt/Dialect/LLHD/Simulator/Engine.h | 82 - include/circt/Dialect/LLHD/Simulator/State.h | 357 --- include/circt/Dialect/LLHD/Simulator/Trace.h | 79 - lib/CAPI/Conversion/CMakeLists.txt | 1 - lib/Conversion/CMakeLists.txt | 1 - lib/Conversion/LLHDToLLVM/CMakeLists.txt | 26 - lib/Conversion/LLHDToLLVM/LLHDToLLVM.cpp | 1918 ----------------- lib/Dialect/LLHD/CMakeLists.txt | 3 - lib/Dialect/LLHD/Simulator/CMakeLists.txt | 38 - lib/Dialect/LLHD/Simulator/Engine.cpp | 315 --- lib/Dialect/LLHD/Simulator/State.cpp | 314 --- lib/Dialect/LLHD/Simulator/Trace.cpp | 172 -- .../Simulator/signals-runtime-wrappers.cpp | 78 - .../LLHD/Simulator/signals-runtime-wrappers.h | 58 - test/CMakeLists.txt | 5 - .../Conversion/LLHDToLLVM/convert_entity.mlir | 29 - .../LLHDToLLVM/convert_extract.mlir | 126 -- .../Conversion/LLHDToLLVM/convert_memory.mlir | 36 - .../convert_process_persistence.mlir | 40 - .../LLHDToLLVM/convert_signals.mlir | 102 - .../Conversion/LLHDToLLVM/convert_simple.mlir | 49 - .../LLHDToLLVM/convert_wait_halt.mlir | 72 - .../LLHDToLLVM/signal-init-error.mlir | 16 - test/Conversion/LLHDToLLVM/signal-init.mlir | 77 - test/lit.cfg.py | 5 - test/lit.site.cfg.py.in | 1 - test/llhd-sim/commandline.mlir | 7 - tools/CMakeLists.txt | 1 - tools/circt-opt/CMakeLists.txt | 1 - tools/llhd-sim/CMakeLists.txt | 16 - tools/llhd-sim/llhd-sim.cpp | 234 -- 39 files changed, 299 insertions(+), 4657 deletions(-) delete mode 100644 include/circt/Conversion/LLHDToLLVM.h delete mode 100644 include/circt/Dialect/LLHD/Simulator/Engine.h delete mode 100644 include/circt/Dialect/LLHD/Simulator/State.h delete mode 100644 include/circt/Dialect/LLHD/Simulator/Trace.h delete mode 100644 lib/Conversion/LLHDToLLVM/CMakeLists.txt delete mode 100644 lib/Conversion/LLHDToLLVM/LLHDToLLVM.cpp delete mode 100644 lib/Dialect/LLHD/Simulator/CMakeLists.txt delete mode 100644 lib/Dialect/LLHD/Simulator/Engine.cpp delete mode 100644 lib/Dialect/LLHD/Simulator/State.cpp delete mode 100644 lib/Dialect/LLHD/Simulator/Trace.cpp delete mode 100644 lib/Dialect/LLHD/Simulator/signals-runtime-wrappers.cpp delete mode 100644 lib/Dialect/LLHD/Simulator/signals-runtime-wrappers.h delete mode 100644 test/Conversion/LLHDToLLVM/convert_entity.mlir delete mode 100644 test/Conversion/LLHDToLLVM/convert_extract.mlir delete mode 100644 test/Conversion/LLHDToLLVM/convert_memory.mlir delete mode 100644 test/Conversion/LLHDToLLVM/convert_process_persistence.mlir delete mode 100644 test/Conversion/LLHDToLLVM/convert_signals.mlir delete mode 100644 test/Conversion/LLHDToLLVM/convert_simple.mlir delete mode 100644 test/Conversion/LLHDToLLVM/convert_wait_halt.mlir delete mode 100644 test/Conversion/LLHDToLLVM/signal-init-error.mlir delete mode 100644 test/Conversion/LLHDToLLVM/signal-init.mlir delete mode 100644 test/llhd-sim/commandline.mlir delete mode 100644 tools/llhd-sim/CMakeLists.txt delete mode 100644 tools/llhd-sim/llhd-sim.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a1cad41882..44437c9932 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -448,24 +448,6 @@ else() endif() endif() -#------------------------------------------------------------------------------- -# llhd-sim Configuration -#------------------------------------------------------------------------------- - -if(NOT WIN32) - option(CIRCT_LLHD_SIM_ENABLED "Enables LLHD sim." ON) -else() - option(CIRCT_LLHD_SIM_ENABLED "Enables LLHD sim." OFF) -endif() - -if(CIRCT_LLHD_SIM_ENABLED) - message(STATUS "llhd-sim is enabled.") -else() - message(STATUS "llhd-sim is disabled.") -endif() - -llvm_canonicalize_cmake_booleans(CIRCT_LLHD_SIM_ENABLED) - #------------------------------------------------------------------------------- # Z3Lib Configuration (for circt-lec and SMT dialect integration tests) #------------------------------------------------------------------------------- diff --git a/CODEOWNERS b/CODEOWNERS index 3f5d4f2fc5..bc7a5abab5 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -32,7 +32,6 @@ tools/arcilator @fabianschuiki @maerhart # LLHD **/LLHD* @fabianschuiki @maerhart -tools/llhd-sim @fabianschuiki @maerhart # Pipeline **/Dialect/Pipeline @mortbopet diff --git a/docs/dialects.dot b/docs/dialects.dot index a1f46bcf9c..45205de940 100644 --- a/docs/dialects.dot +++ b/docs/dialects.dot @@ -50,7 +50,7 @@ digraph G { ESI [URL="https://circt.llvm.org/docs/Dialects/ESI/"] FSM [URL="https://circt.llvm.org/docs/Dialects/FSM/"] HWArith [URL="https://circt.llvm.org/docs/Dialects/HWArith/"] - MooreMIR [URL="https://circt.llvm.org/docs/Dialects/Moore/", label="Moore MIR"] + Moore [URL="https://circt.llvm.org/docs/Dialects/Moore/"] // Intermediate node to target when lowering to both SV and Core dialects lower_to_sv_and_core [shape=point label="" fillcolor=black] @@ -79,7 +79,6 @@ digraph G { subgraph backend_internal_tools{ node [fillcolor="#fdc086"] Arcilator - llhd_sim [label="llhd-sim"] ExportSystemC ExportVerilog [URL="https://circt.llvm.org/docs/VerilogGeneration/"] } @@ -88,7 +87,7 @@ digraph G { // External tools subgraph external_tools { node [shape=octagon fillcolor="#ffff99"] - Moore + Slang Calyx_native [label="Calyx native"] } @@ -126,13 +125,14 @@ digraph G { // Things that lower into a subset of the RTL-like dialects. Cluster these // together to avoid a massive clutter. - {Pipeline MSFT HWArith MooreMIR} -> lower_to_core [arrowhead=none] + {Pipeline MSFT HWArith Moore} -> lower_to_core [arrowhead=none] + Moore -> LLHD {ESI FIRRTL FSM} -> lower_to_sv_and_core [arrowhead=none] lower_to_sv_and_core -> SV lower_to_sv_and_core -> Comb [lhead=cluster_RTL] lower_to_core -> Comb [lhead=cluster_RTL] Seq -> SV - {HW MooreMIR} -> LLHD + LLHD -> Arcilator Interop -> Arc [ltail=cluster_RTL] Comb -> SystemC [ltail=cluster_RTL] ExportVerilog -> SVFile @@ -140,6 +140,7 @@ digraph G { // Tool flows Arc -> Arcilator Arcilator -> SimBinary + Arcilator -> VCDTrace Scheduling -> LoopSchedule [dir=both] Scheduling -> Pipeline [dir=both] Chisel -> FIRFile @@ -149,13 +150,10 @@ digraph G { ExportSystemC -> SystemCFile SV -> ExportVerilog Seq -> ExportVerilog [ltail=cluster_RTL] - HW -> llhd_sim [ltail=cluster_RTL] - SVVHDL -> Moore [weight=999] - Moore -> MooreMIR + SVVHDL -> Slang [weight=999] + Slang -> Moore Calyx -> Calyx_native Calyx_native -> lower_to_sv_and_core [arrowhead=none] - LLHD -> llhd_sim - llhd_sim -> VCDTrace ESI -> ServiceDesc MSFT -> TCL PyFile -> PyCDE @@ -170,7 +168,7 @@ digraph G { // Leave one rank free above the RTL cluster to improve routing of incoming // edges. - {FIRRTL FSM ESI MSFT HWArith MooreMIR} -> space_above_RTL [weight=999, style=invis] + {FIRRTL FSM ESI MSFT HWArith Moore} -> space_above_RTL [weight=999, style=invis] {space_above_RTL} -> {Seq HW Comb} [lhead=cluster_RTL, weight=999, style=invis] // Fix the following sink nodes below the CIRCT cluster diff --git a/docs/includes/img/dialects.png b/docs/includes/img/dialects.png index f907d7c08071001b7357d6aff0fba0b1966187a8..ca8db2e744acde485d6a9d34c01067d5db85bcd1 100644 GIT binary patch literal 183804 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%0A#v@+dw?sD;tp>JV}jL8e{Ml#En(#W4~T8Rdl%R< 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%0DFJ0?1;1D7BT8 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 NmsXT2l6ds&{{SXPs|)}D literal 192620 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

kSJfM4p$Wg1lsw`cQVwzx$^G%#B`Ls$0+#E|a; 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 diff --git a/docs/includes/img/dialects.svg b/docs/includes/img/dialects.svg index 8d0d3c7457..0cf44cd7ec 100644 --- a/docs/includes/img/dialects.svg +++ b/docs/includes/img/dialects.svg @@ -1,171 +1,171 @@ - - - + + G - + cluster_mlir_frontends - -Upstream frontends (selection) + +Upstream frontends (selection) cluster_mlir - -Upstream MLIR + +Upstream MLIR cluster_std_arith_dialect - + cluster_circt - -CIRCT + +CIRCT cluster_RTL - -Core dialects + +Core dialects cluster_input_langs - -Input languages + +Input languages PyTorch - -PyTorch + +PyTorch CF - -CF + +CF PyTorch->CF - - + + Polygeist - -Polygeist + +Polygeist Affine - -Affine + +Affine Polygeist->Affine - - + + SCF - -SCF + +SCF Calyx - -Calyx + +Calyx SCF->Calyx - - + + LoopSchedule - -LoopSchedule + +LoopSchedule Affine->LoopSchedule - - + + Arith - -Arith + +Arith Handshake - -Handshake + +Handshake Arith->Handshake - - + + Arith->Calyx - - + + FIRRTLParser - -FIRRTLParser + +FIRRTLParser FIRRTL - -FIRRTL + +FIRRTL - + FIRRTLParser->FIRRTL - - + + PyCDE - -PyCDE + +PyCDE @@ -173,68 +173,68 @@ MSFT - -MSFT + +MSFT - + PyCDE->MSFT - - + + ESI - -ESI + +ESI - + PyCDE->ESI - - + + FSM - -FSM + +FSM - + PyCDE->FSM - - + + HWArith - -HWArith + +HWArith - + PyCDE->HWArith - - + + Scheduling - -Scheduling + +Scheduling @@ -242,225 +242,225 @@ Pipeline - -Pipeline + +Pipeline - + Scheduling->Pipeline - - - + + + - + Scheduling->LoopSchedule - - - + + + SSP - -SSP + +SSP - + Scheduling->SSP - - - + + + - + Scheduling->MSFT - - - + + + Handshake->FIRRTL - - + + Calyx->FSM - - + + - + Calyx_native - -Calyx native + +Calyx native Calyx->Calyx_native - - + + lower_to_sv_and_core - + - + FIRRTL->lower_to_sv_and_core - + lower_to_core - + Pipeline->lower_to_core - + LoopSchedule->Calyx - - + + MSFT->lower_to_core - + - + TCL - - - -Placements (tcl) + + + +Placements (tcl) - + MSFT->TCL - - + + - + ESI->lower_to_sv_and_core - + - + ServiceDesc - - - -ESI system description -(JSON) + + + +ESI system description +(JSON) - + ESI->ServiceDesc - - + + - + FSM->lower_to_sv_and_core - + HWArith->lower_to_core - + - + -MooreMIR - - -Moore MIR +Moore + + +Moore - + -MooreMIR->lower_to_core - +Moore->lower_to_core + - + LLHD - -LLHD + +LLHD - - -MooreMIR->LLHD - - + + +Moore->LLHD + + Comb - -Comb + +Comb - + lower_to_sv_and_core->Comb - - + + SV - -SV + +SV - + lower_to_sv_and_core->SV - - + + - + lower_to_core->Comb - - + + Seq - -Seq + +Seq @@ -469,73 +469,55 @@ HW - -HW + +HW - + Seq->SV - - + + - + ExportVerilog - - -ExportVerilog + + +ExportVerilog - -Seq->ExportVerilog - - - - - -HW->LLHD - - - - - -llhd_sim - -llhd-sim - - -HW->llhd_sim - - +Seq->ExportVerilog + + SystemC - -SystemC + +SystemC Comb->SystemC - - + + Interop - -Interop + +Interop @@ -543,196 +525,196 @@ Arc - -Arc + +Arc Interop->Arc - - - - - -LLHD->llhd_sim - - + + Arcilator - -Arcilator + +Arcilator + + + +LLHD->Arcilator + + Arc->Arcilator - - + + - + SV->ExportVerilog - - + + - + ExportSystemC - -ExportSystemC + +ExportSystemC - + SystemC->ExportSystemC - - + + + + + +VCDTrace + + + +Trace (vcd) + + + +Arcilator->VCDTrace + + - + SimBinary - - - -Simulation Binary (obj) + + + +Simulation Binary (obj) Arcilator->SimBinary - - - - - -VCDTrace - - - -Trace (vcd) - - - -llhd_sim->VCDTrace - - + + - + SystemCFile - - - -SystemC (c++) + + + +SystemC (c++) - + ExportSystemC->SystemCFile - - + + - + SVFile - - - -SystemVerilog + + + +SystemVerilog ExportVerilog->SVFile - - + + - - -Moore - -Moore + + +Slang + +Slang - + -Moore->MooreMIR - - +Slang->Moore + + Calyx_native->lower_to_sv_and_core - + - + FIRFile - - - -.fir + + + +.fir - + FIRFile->FIRRTLParser - - + + - + Chisel - -Chisel + +Chisel - + Chisel->FIRFile - - + + - + SVVHDL - -SV/VHDL + +SV/VHDL - + -SVVHDL->Moore - - +SVVHDL->Slang + + - + PyFile - -Python + +Python - + PyFile->PyCDE - - + + - + SoftwareAPI - - - -Software API -(e.g. py/c++/c#) + + + +Software API +(e.g. py/c++/c#) - + ServiceDesc->SoftwareAPI - - + + diff --git a/include/circt/Conversion/LLHDToLLVM.h b/include/circt/Conversion/LLHDToLLVM.h deleted file mode 100644 index c83d86126b..0000000000 --- a/include/circt/Conversion/LLHDToLLVM.h +++ /dev/null @@ -1,43 +0,0 @@ -//===- LLHDToLLVM.h - LLHD to LLVM pass entry point -------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This header file defines prototypes that expose the LLHDToLLVM pass -// constructors. -// -//===----------------------------------------------------------------------===// - -#ifndef CIRCT_CONVERSION_LLHDTOLLVM_LLHDTOLLVM_H -#define CIRCT_CONVERSION_LLHDTOLLVM_LLHDTOLLVM_H - -#include "circt/Support/LLVM.h" -#include - -namespace mlir { -class LLVMTypeConverter; -} // namespace mlir - -namespace circt { - -#define GEN_PASS_DECL_CONVERTLLHDTOLLVM -#include "circt/Conversion/Passes.h.inc" - -/// Get the LLHD to LLVM type conversions -void populateLLHDToLLVMTypeConversions(mlir::LLVMTypeConverter &converter); - -/// Get the LLHD to LLVM conversion patterns. -void populateLLHDToLLVMConversionPatterns(mlir::LLVMTypeConverter &converter, - RewritePatternSet &patterns, - size_t &sigCounter, - size_t ®Counter); - -/// Create an LLHD to LLVM conversion pass. -std::unique_ptr> createConvertLLHDToLLVMPass(); - -} // namespace circt - -#endif // CIRCT_CONVERSION_LLHDTOLLVM_LLHDTOLLVM_H diff --git a/include/circt/Conversion/Passes.h b/include/circt/Conversion/Passes.h index f540554e27..6e002b0686 100644 --- a/include/circt/Conversion/Passes.h +++ b/include/circt/Conversion/Passes.h @@ -36,7 +36,6 @@ #include "circt/Conversion/HWToSystemC.h" #include "circt/Conversion/HandshakeToDC.h" #include "circt/Conversion/HandshakeToHW.h" -#include "circt/Conversion/LLHDToLLVM.h" #include "circt/Conversion/LTLToCore.h" #include "circt/Conversion/LoopScheduleToCalyx.h" #include "circt/Conversion/MooreToCore.h" diff --git a/include/circt/Conversion/Passes.td b/include/circt/Conversion/Passes.td index 96807afb88..ba69a52a64 100644 --- a/include/circt/Conversion/Passes.td +++ b/include/circt/Conversion/Passes.td @@ -519,22 +519,6 @@ def ConvertMooreToCore : Pass<"convert-moore-to-core", "mlir::ModuleOp"> { "llhd::LLHDDialect"]; } -//===----------------------------------------------------------------------===// -// LLHDToLLVM -//===----------------------------------------------------------------------===// - -def ConvertLLHDToLLVM : Pass<"convert-llhd-to-llvm", "mlir::ModuleOp"> { - let summary = "Convert LLHD to LLVM"; - let description = [{ - This pass translates LLHD to LLVM. - }]; - let constructor = "circt::createConvertLLHDToLLVMPass()"; - let dependentDialects = [ - "mlir::arith::ArithDialect", - "mlir::LLVM::LLVMDialect" - ]; -} - //===----------------------------------------------------------------------===// // HWToLLVM //===----------------------------------------------------------------------===// diff --git a/include/circt/Dialect/LLHD/Simulator/Engine.h b/include/circt/Dialect/LLHD/Simulator/Engine.h deleted file mode 100644 index 17e33322af..0000000000 --- a/include/circt/Dialect/LLHD/Simulator/Engine.h +++ /dev/null @@ -1,82 +0,0 @@ -//===- Engine.h - LLHD simulaton engine -------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the main Engine class of the LLHD simulator. -// -//===----------------------------------------------------------------------===// - -#ifndef CIRCT_DIALECT_LLHD_SIMULATOR_ENGINE_H -#define CIRCT_DIALECT_LLHD_SIMULATOR_ENGINE_H - -#include "State.h" -#include "Trace.h" - -#include "circt/Dialect/LLHD/IR/LLHDOps.h" -#include "mlir/IR/BuiltinOps.h" - -namespace mlir { -class ExecutionEngine; -} // namespace mlir - -namespace llvm { -class Error; -class Module; -} // namespace llvm - -namespace circt { -namespace llhd { -namespace sim { - -class Engine { -public: - /// Initialize an LLHD simulation engine. This initializes the state, as well - /// as the mlir::ExecutionEngine with the given module. - Engine( - llvm::raw_ostream &out, ModuleOp module, - llvm::function_ref mlirTransformer, - llvm::function_ref llvmTransformer, - std::string root, TraceMode tm, ArrayRef sharedLibPaths); - - /// Default destructor - ~Engine(); - - /// Run simulation up to n steps or maxTime picoseconds of simulation time. - /// n=0 and T=0 make the simulation run indefinitely. - int simulate(int n, uint64_t maxTime); - - /// Build the instance layout of the design. - void buildLayout(ModuleOp module); - - /// Get the MLIR module. - const ModuleOp getModule() const { return module; } - - /// Get the simulation state. - const State *getState() const { return state.get(); } - - /// Dump the instance layout stored in the State. - void dumpStateLayout(); - - /// Dump the instances each signal triggers. - void dumpStateSignalTriggers(); - -private: - void walkEntity(EntityOp entity, Instance &child); - - llvm::raw_ostream &out; - std::string root; - std::unique_ptr state; - std::unique_ptr engine; - ModuleOp module; - TraceMode traceMode; -}; - -} // namespace sim -} // namespace llhd -} // namespace circt - -#endif // CIRCT_DIALECT_LLHD_SIMULATOR_ENGINE_H diff --git a/include/circt/Dialect/LLHD/Simulator/State.h b/include/circt/Dialect/LLHD/Simulator/State.h deleted file mode 100644 index a50d8741df..0000000000 --- a/include/circt/Dialect/LLHD/Simulator/State.h +++ /dev/null @@ -1,357 +0,0 @@ -//===- State.h - Simulation state definition --------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Defines structures used to keep track of the simulation state in the LLHD -// simulator. -// -//===----------------------------------------------------------------------===// - -#ifndef CIRCT_DIALECT_LLHD_SIMULATOR_STATE_H -#define CIRCT_DIALECT_LLHD_SIMULATOR_STATE_H - -#include "llvm/ADT/APInt.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringMap.h" - -#include -#include -#include - -namespace circt { -namespace llhd { -namespace sim { - -/// The simulator's internal representation of time. -class Time { -public: - /// Empty (zero) time constructor. All the time values are defaulted to 0. - Time() = default; - - /// Construct with given time values. - Time(uint64_t time, uint64_t delta, uint64_t eps) - : time(time), delta(delta), eps(eps) {} - - /// Compare the time values in order of time, delta, eps. - bool operator<(const Time &rhs) const { - return time < rhs.time || (time == rhs.time && delta < rhs.delta) || - (time == rhs.time && delta == rhs.delta && eps < rhs.eps); - } - - /// Return true if all the time values are equal. - bool operator==(const Time &rhs) const { - return time == rhs.time && delta == rhs.delta && eps == rhs.eps; - } - - /// Add two time values. - Time operator+(const Time &rhs) const { - return Time(time + rhs.time, delta + rhs.delta, eps + rhs.eps); - } - - /// Get the stored time in a printable format. - std::string toString() const; - - uint64_t getTime() const { return time; } - -private: - /// Simulation real time. - uint64_t time; - uint64_t delta; - uint64_t eps; -}; - -/// Detail structure that can be easily accessed by the lowered code. -struct SignalDetail { - uint8_t *value; - uint64_t offset; - uint64_t instIndex; - uint64_t globalIndex; -}; - -/// The simulator's internal representation of a signal. -class Signal { -public: - /// Construct an "empty" signal. - Signal(std::string name, std::string owner) - : name(name), owner(owner), size(0), value(nullptr) {} - - /// Construct a signal with the given name, owner and initial value. - Signal(std::string name, std::string owner, uint8_t *value, uint64_t size) - : name(name), owner(owner), size(size), value(value) {} - - /// Default move constructor. - Signal(Signal &&) = default; - - /// Free 'value' since it is allocated using 'malloc' in the LLVM code - /// generated by LLHDToLLVM. - ~Signal(); - - /// Returns true if the signals match in name, owner, size and value. - bool operator==(const Signal &rhs) const { - if (owner != rhs.owner || name != rhs.name || size != rhs.size) - return false; - return std::memcmp(value, rhs.value, size); - } - - /// Returns true if the owner name is lexically smaller than rhs's owner, or - /// the name is lexically smaller than rhs's name, in case they share the same - /// owner. - bool operator<(const Signal &rhs) const { - return (owner < rhs.owner || (owner == rhs.owner && name < rhs.name)); - } - - bool isOwner(const std::string &rhs) const { return owner == rhs; }; - - std::string getOwner() const { return owner; } - - bool isValidSigName() const { - return std::regex_match(name, std::regex("(sig)?[0-9]*")); - } - - std::string getName() const { return name; } - - uint64_t getSize() const { return size; } - - uint8_t *getValue() const { return value; } - - const std::vector &getTriggeredInstanceIndices() const { - return instanceIndices; - } - - void pushInstanceIndex(unsigned i) { instanceIndices.push_back(i); } - - bool hasElement() const { return elements.size() > 0; } - - size_t getElementSize() const { return elements.size(); } - - void pushElement(std::pair val) { - elements.push_back(val); - } - - /// Store JIT allocated signal pointer and size. - void store(uint8_t *v, uint64_t s) { - value = v; - size = s; - } - - /// Update signal value when it is changed, the width of incoming signal - /// value and the stored signal value are identical. - /// As majority signals are smaller than 64 bits, this implementation - /// is much faster as it avoided memcpy in most cases. - /// @param v Pointer to signal value - /// @return true when signal is updated, false when not - bool updateWhenChanged(const uint64_t *v) { - switch (size) { - case 1: { - const uint8_t *newVal = reinterpret_cast(v); - if (*value == *newVal) - return false; - *value = *newVal; - break; - } - case 2: { - const uint16_t *newVal = reinterpret_cast(v); - if (*(uint16_t *)value == *newVal) - return false; - *(uint16_t *)value = *newVal; - break; - } - case 4: { - const uint32_t *newVal = reinterpret_cast(v); - if (*(uint32_t *)value == *newVal) - return false; - *(uint32_t *)value = *newVal; - break; - } - case 8: { - if (*(uint64_t *)value == *v) - return false; - *(uint64_t *)value = *v; - break; - } - default: { - if (std::memcmp(value, v, size) == 0) - return false; - std::memcpy(value, v, size); - break; - } - } - - return true; - } - - /// Return the value of the signal in hexadecimal string format. - std::string toHexString() const; - - /// Return the value of the i-th element of the signal in hexadecimal string - /// format. - std::string toHexString(unsigned) const; - -private: - std::string name; - std::string owner; - // The list of instances this signal triggers. - std::vector instanceIndices; - uint64_t size; - uint8_t *value; - std::vector> elements; -}; - -/// The simulator's internal representation of one queue slot. -struct Slot { - /// Create a new empty slot. - Slot(Time time) : time(time) {} - - /// Returns true if the slot's time is smaller than the compared slot's time. - bool operator<(const Slot &rhs) const; - - /// Returns true if the slot's time is greater than the compared slot's time. - bool operator>(const Slot &rhs) const; - - /// Insert a change. - void insertChange(int index, int bitOffset, uint8_t *bytes, unsigned width); - - /// Insert a scheduled process wakeup. - void insertChange(unsigned inst); - - // A map from signal indexes to change buffers. Makes it easy to sort the - // changes such that we can process one signal at a time. - llvm::SmallVector, 32> changes; - // Buffers for the signal changes. - llvm::SmallVector, 32> buffers; - // The number of used change buffers in the slot. - size_t changesSize = 0; - - // Processes with scheduled wakeup. - llvm::SmallVector scheduled; - Time time; - bool unused = false; -}; - -/// This is equivalent to and std::priorityQueue ordered using the greater -/// operator, which adds an insertion method to add changes to a slot. -class UpdateQueue : public llvm::SmallVector { - unsigned topSlot = 0; - llvm::SmallVector unused; - -public: - /// Check wheter a slot for the given time already exists. If that's the case, - /// add the new change to it, else create a new slot and push it to the queue. - void insertOrUpdate(Time time, int index, int bitOffset, uint8_t *bytes, - unsigned width); - - /// Check wheter a slot for the given time already exists. If that's the case, - /// add the scheduled wakeup to it, else create a new slot and push it to the - /// queue. - void insertOrUpdate(Time time, unsigned inst); - - /// Return a reference to a slot with the given timestamp. If such a slot - /// already exists, a reference to it will be returned. Otherwise a reference - /// to a fresh slot is returned. - Slot &getOrCreateSlot(Time time); - - /// Get a reference to the current top of the queue (the earliest event - /// available). - const Slot &top(); - - /// Pop the current top of the queue. This marks the current top slot as - /// unused and resets its internal structures such that they can be reused. - void pop(); - - unsigned events = 0; -}; - -/// State structure for process persistence across suspension. -struct ProcState { - unsigned inst; - int resume; - bool *senses; - uint8_t *resumeState; -}; - -/// The simulator internal representation of an instance. -struct Instance { - Instance() = default; - - Instance(std::string name) - : name(name), procState(nullptr), entityState(nullptr) {} - - // The instance name. - std::string name; - // The instance's hierarchical path. - std::string path; - // The instance's base unit. - std::string unit; - bool isEntity; - size_t nArgs = 0; - // The arguments and signals of this instance. - llvm::SmallVector sensitivityList; - ProcState *procState; - uint8_t *entityState; - Time expectedWakeup; - // A pointer to the base unit jitted function. - void (*unitFPtr)(void **); - - /// Free procState and entityState since they are allocated using 'malloc' in - /// the LLVM code generated in LLHDToLLVM. - ~Instance(); -}; - -/// The simulator's state. It contains the current simulation time, signal -/// values and the event queue. -struct State { - /// Construct a new empty (at 0 time) state. - State() = default; - - /// State destructor, ensures all malloc'd regions stored in the state are - /// correctly free'd. - ~State(); - - /// Pop the head of the queue and update the simulation time. - Slot popQueue(); - - /// Push a new scheduled wakeup event in the event queue. - void pushQueue(Time time, unsigned inst); - - /// Find an instance in the instances list by name and return an - /// iterator for it. - llvm::SmallVectorTemplateCommon::iterator - getInstanceIterator(std::string instName); - - /// Add a new signal to the state. Returns the index of the new signal. - int addSignal(std::string name, std::string owner); - - int addSignalData(int index, std::string owner, uint8_t *value, - uint64_t size); - - void addSignalElement(unsigned, unsigned, unsigned); - - /// Add a pointer to the process persistence state to a process instance. - void addProcPtr(std::string name, ProcState *procStatePtr); - - /// Dump a signal to the out stream. One entry is added for every instance - /// the signal appears in. - void dumpSignal(llvm::raw_ostream &out, int index); - - /// Dump the instance layout. Used for testing purposes. - void dumpLayout(); - - /// Dump the instances each signal triggers. Used for testing purposes. - void dumpSignalTriggers(); - - Time time; - std::string root; - llvm::SmallVector instances; - llvm::SmallVector signals; - UpdateQueue queue; -}; - -} // namespace sim -} // namespace llhd -} // namespace circt - -#endif // CIRCT_DIALECT_LLHD_SIMULATOR_STATE_H diff --git a/include/circt/Dialect/LLHD/Simulator/Trace.h b/include/circt/Dialect/LLHD/Simulator/Trace.h deleted file mode 100644 index bd3d83be7e..0000000000 --- a/include/circt/Dialect/LLHD/Simulator/Trace.h +++ /dev/null @@ -1,79 +0,0 @@ -//===- Trace.h - Simulation trace definition --------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the Trace class, used to handle the signal trace generation -// for the llhd-sim tool. -// -//===----------------------------------------------------------------------===// - -#ifndef CIRCT_DIALECT_LLHD_SIMULATOR_TRACE_H -#define CIRCT_DIALECT_LLHD_SIMULATOR_TRACE_H - -#include "State.h" - -#include -#include - -namespace llvm { -class raw_ostream; -} // namespace llvm - -namespace circt { -namespace llhd { -namespace sim { - -enum class TraceMode { Full, Reduced, Merged, MergedReduce, NamedOnly, None }; - -class Trace { - llvm::raw_ostream &out; - std::unique_ptr const &state; - TraceMode mode; - Time currentTime; - // Each entry defines if the respective signal is active for tracing. - std::vector isTraced; - // Buffer of changes ready to be flushed. - std::vector> changes; - // Buffer of changes for the merged formats. - std::map, std::string> mergedChanges; - // Buffer of last dumped change for each signal. - std::map, std::string> lastValue; - - /// Push one change to the changes vector. - void pushChange(unsigned inst, unsigned sigIndex, int elem); - /// Push one change for each element of a signal if it is of a structured - /// type, or the full signal otherwise. - void pushAllChanges(unsigned inst, unsigned sigIndex); - - /// Add a merged change to the change buffer. - void addChangeMerged(unsigned); - - /// Sorts the changes buffer lexicographically wrt. the hierarchical paths. - void sortChanges(); - - /// Flush the changes buffer to the output stream with full format. - void flushFull(); - // Flush the changes buffer to the output stream with merged format. - void flushMerged(); - -public: - Trace(std::unique_ptr const &state, llvm::raw_ostream &out, - TraceMode mode); - - /// Add a value change to the trace changes buffer. - void addChange(unsigned); - - /// Flush the changes buffer to the output stream. The flush can be forced for - /// merged changes, flushing even if the next real-time step has not been - /// reached. - void flush(bool force = false); -}; -} // namespace sim -} // namespace llhd -} // namespace circt - -#endif // CIRCT_DIALECT_LLHD_SIMULATOR_TRACE_H diff --git a/lib/CAPI/Conversion/CMakeLists.txt b/lib/CAPI/Conversion/CMakeLists.txt index 2c4e950177..50a409e176 100644 --- a/lib/CAPI/Conversion/CMakeLists.txt +++ b/lib/CAPI/Conversion/CMakeLists.txt @@ -25,7 +25,6 @@ add_circt_public_c_api_library(CIRCTCAPIConversion CIRCTHWToSMT CIRCTHWToSV CIRCTHWToSystemC - CIRCTLLHDToLLVM CIRCTLoopScheduleToCalyx CIRCTLTLToCore CIRCTMooreToCore diff --git a/lib/Conversion/CMakeLists.txt b/lib/Conversion/CMakeLists.txt index 2d487427d8..562779ee3d 100644 --- a/lib/Conversion/CMakeLists.txt +++ b/lib/Conversion/CMakeLists.txt @@ -20,7 +20,6 @@ add_subdirectory(HWToLLVM) add_subdirectory(HWToSMT) add_subdirectory(HWToSV) add_subdirectory(HWToSystemC) -add_subdirectory(LLHDToLLVM) add_subdirectory(LoopScheduleToCalyx) add_subdirectory(MooreToCore) add_subdirectory(PipelineToHW) diff --git a/lib/Conversion/LLHDToLLVM/CMakeLists.txt b/lib/Conversion/LLHDToLLVM/CMakeLists.txt deleted file mode 100644 index 7640e5238d..0000000000 --- a/lib/Conversion/LLHDToLLVM/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -add_circt_conversion_library(CIRCTLLHDToLLVM - LLHDToLLVM.cpp - - DEPENDS - CIRCTConversionPassIncGen - MLIRArithDialect - - LINK_COMPONENTS - Core - - LINK_LIBS PUBLIC - CIRCTLLHD - CIRCTComb - CIRCTCombToArith - CIRCTCombToLLVM - CIRCTHWToLLVM - CIRCTHW - CIRCTSupport - MLIRArithToLLVM - MLIRControlFlowToLLVM - MLIRFuncToLLVM - MLIRLLVMCommonConversion - MLIRVectorDialect - MLIRTransforms - MLIRReconcileUnrealizedCasts - ) diff --git a/lib/Conversion/LLHDToLLVM/LLHDToLLVM.cpp b/lib/Conversion/LLHDToLLVM/LLHDToLLVM.cpp deleted file mode 100644 index 91dfcda459..0000000000 --- a/lib/Conversion/LLHDToLLVM/LLHDToLLVM.cpp +++ /dev/null @@ -1,1918 +0,0 @@ -//===- LLHDToLLVM.cpp - LLHD to LLVM Conversion Pass ----------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This is the main LLHD to LLVM Conversion Pass Implementation. -// -//===----------------------------------------------------------------------===// - -#include "circt/Conversion/LLHDToLLVM.h" -#include "circt/Conversion/CombToArith.h" -#include "circt/Conversion/CombToLLVM.h" -#include "circt/Conversion/HWToLLVM.h" -#include "circt/Dialect/LLHD/IR/LLHDDialect.h" -#include "circt/Dialect/LLHD/IR/LLHDOps.h" -#include "circt/Support/LLVM.h" -#include "circt/Support/Namespace.h" -#include "mlir/Conversion/ArithToLLVM/ArithToLLVM.h" -#include "mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h" -#include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h" -#include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVMPass.h" -#include "mlir/Conversion/LLVMCommon/ConversionTarget.h" -#include "mlir/Conversion/LLVMCommon/Pattern.h" -#include "mlir/Conversion/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.h" -#include "mlir/Dialect/Arith/IR/Arith.h" -#include "mlir/Dialect/LLVMIR/LLVMDialect.h" -#include "mlir/IR/IRMapping.h" -#include "mlir/Pass/Pass.h" -#include "mlir/Transforms/DialectConversion.h" - -namespace circt { -#define GEN_PASS_DEF_CONVERTLLHDTOLLVM -#include "circt/Conversion/Passes.h.inc" -} // namespace circt - -using namespace mlir; -using namespace circt; -using namespace circt::llhd; - -//===----------------------------------------------------------------------===// -// Helpers -//===----------------------------------------------------------------------===// - -/// Get an existing global string. -static Value getGlobalString(Location loc, OpBuilder &builder, - const TypeConverter *typeConverter, - LLVM::GlobalOp &str) { - auto voidPtrTy = LLVM::LLVMPointerType::get(builder.getContext()); - auto i32Ty = IntegerType::get(builder.getContext(), 32); - - auto addr = builder.create(loc, voidPtrTy, str.getName()); - auto idx = builder.create(loc, i32Ty, - builder.getI32IntegerAttr(0)); - std::array idxs({idx, idx}); - return builder.create(loc, voidPtrTy, str.getType(), addr, idxs); -} - -/// Looks up a symbol and inserts a new functino at the beginning of the -/// module's region in case the function does not exists. If -/// insertBodyAndTerminator is set, also adds the entry block and return -/// terminator. -static LLVM::LLVMFuncOp -getOrInsertFunction(ModuleOp &module, ConversionPatternRewriter &rewriter, - Location loc, std::string name, Type signature, - bool insertBodyAndTerminator = false) { - auto func = module.lookupSymbol(name); - if (!func) { - OpBuilder moduleBuilder(module.getBodyRegion()); - func = moduleBuilder.create(loc, name, signature); - if (insertBodyAndTerminator) { - func.addEntryBlock(moduleBuilder); - OpBuilder b(func.getBody()); - b.create(loc, ValueRange()); - } - } - return func; -} - -/// Return the LLVM type used to represent a signal. It corresponds to a struct -/// with the format: {valuePtr, bitOffset, instanceIndex, globalIndex}. -static Type getLLVMSigType(LLVM::LLVMDialect *dialect) { - auto voidPtrTy = LLVM::LLVMPointerType::get(dialect->getContext()); - auto i64Ty = IntegerType::get(dialect->getContext(), 64); - return LLVM::LLVMStructType::getLiteral(dialect->getContext(), - {voidPtrTy, i64Ty, i64Ty, i64Ty}); -} - -/// Extract the details from the given signal struct. The details are returned -/// in the original struct order. -static std::vector getSignalDetail(ConversionPatternRewriter &rewriter, - LLVM::LLVMDialect *dialect, - Location loc, Value signal, - bool extractIndices = false) { - - auto voidPtrTy = LLVM::LLVMPointerType::get(dialect->getContext()); - auto i64Ty = IntegerType::get(dialect->getContext(), 64); - auto sigTy = getLLVMSigType(dialect); - - std::vector result; - - // Extract the value and offset elements. - auto sigPtrPtr = rewriter.create(loc, voidPtrTy, sigTy, signal, - ArrayRef({0, 0})); - result.push_back(rewriter.create(loc, voidPtrTy, sigPtrPtr)); - - auto offsetPtr = rewriter.create(loc, voidPtrTy, sigTy, signal, - ArrayRef({0, 1})); - result.push_back(rewriter.create(loc, i64Ty, offsetPtr)); - - // Extract the instance and global indices. - if (extractIndices) { - auto instIndexPtr = rewriter.create( - loc, voidPtrTy, sigTy, signal, ArrayRef({0, 2})); - result.push_back(rewriter.create(loc, i64Ty, instIndexPtr)); - - auto globalIndexPtr = rewriter.create( - loc, voidPtrTy, sigTy, signal, ArrayRef({0, 3})); - result.push_back(rewriter.create(loc, i64Ty, globalIndexPtr)); - } - - return result; -} - -/// Create a subsignal struct. -static Value createSubSig(LLVM::LLVMDialect *dialect, - ConversionPatternRewriter &rewriter, Location loc, - std::vector originDetail, Value newPtr, - Value newOffset) { - auto i32Ty = IntegerType::get(dialect->getContext(), 32); - auto sigTy = getLLVMSigType(dialect); - - // Create signal struct. - auto sigUndef = rewriter.create(loc, sigTy); - auto storeSubPtr = - rewriter.create(loc, sigUndef, newPtr, 0); - auto storeSubOffset = - rewriter.create(loc, storeSubPtr, newOffset, 1); - auto storeSubInstIndex = rewriter.create( - loc, storeSubOffset, originDetail[2], 2); - auto storeSubGlobalIndex = rewriter.create( - loc, storeSubInstIndex, originDetail[3], 3); - - // Allocate and store the subsignal. - auto oneC = rewriter.create(loc, i32Ty, - rewriter.getI32IntegerAttr(1)); - auto allocaSubSig = rewriter.create( - loc, LLVM::LLVMPointerType::get(dialect->getContext()), sigTy, oneC, 4); - rewriter.create(loc, storeSubGlobalIndex, allocaSubSig); - - return allocaSubSig; -} - -/// Returns true if the given value is passed as an argument to the destination -/// block of the given WaitOp. -static bool isWaitDestArg(WaitOp op, Value val) { - for (auto arg : op.getDestOps()) { - if (arg == val) - return true; - } - return false; -} - -// Returns true if the given operation is used as a destination argument in a -// WaitOp. -static bool isWaitDestArg(Operation *op) { - for (auto user : op->getUsers()) { - if (auto wait = dyn_cast(user)) - return isWaitDestArg(wait, op->getResult(0)); - } - return false; -} - -/// Gather the types of values that are used outside of the block they're -/// defined in. An LLVMType structure containing those types, in order of -/// appearance, is returned. -static Type getProcPersistenceTy(LLVM::LLVMDialect *dialect, - const TypeConverter *converter, ProcOp &proc) { - SmallVector types = SmallVector(); - proc.walk([&](Operation *op) -> void { - if (op->isUsedOutsideOfBlock(op->getBlock()) || isWaitDestArg(op)) { - auto ty = op->getResult(0).getType(); - auto convertedTy = converter->convertType(ty); - types.push_back(convertedTy); - } - }); - - // Also persist block arguments escaping their defining block. - for (auto &block : proc.getBlocks()) { - // Skip entry block (contains the function signature in its args). - if (block.isEntryBlock()) - continue; - - for (auto arg : block.getArguments()) { - if (arg.isUsedOutsideOfBlock(&block)) { - types.push_back(converter->convertType(arg.getType())); - } - } - } - - return LLVM::LLVMStructType::getLiteral(dialect->getContext(), types); -} - -/// Insert a comparison block that either jumps to the trueDest block, if the -/// resume index mathces the current index, or to falseDest otherwise. If no -/// falseDest is provided, the next block is taken insead. -static void insertComparisonBlock(ConversionPatternRewriter &rewriter, - LLVM::LLVMDialect *dialect, Location loc, - Region *body, Value resumeIdx, int currIdx, - Block *trueDest, ValueRange trueDestArgs, - Block *falseDest = nullptr) { - auto i32Ty = IntegerType::get(dialect->getContext(), 32); - auto secondBlock = ++body->begin(); - auto newBlock = rewriter.createBlock(body, secondBlock); - auto cmpIdx = rewriter.create( - loc, i32Ty, rewriter.getI32IntegerAttr(currIdx)); - auto cmpRes = rewriter.create(loc, LLVM::ICmpPredicate::eq, - resumeIdx, cmpIdx); - - // Default to jumping to the next block for the false case, if no explicit - // block is provided. - if (!falseDest) - falseDest = &*secondBlock; - - rewriter.create(loc, cmpRes, trueDest, trueDestArgs, - falseDest, ValueRange()); - - // Redirect the entry block terminator to the new comparison block. - auto entryTer = body->front().getTerminator(); - entryTer->setSuccessor(newBlock, 0); -} - -/// Insert a GEP operation to the pointer of the i-th value in the process -/// persistence table. -static Value gepPersistenceState(LLVM::LLVMDialect *dialect, Location loc, - ConversionPatternRewriter &rewriter, - Type stateTy, int index, Value state) { - return rewriter.create( - loc, LLVM::LLVMPointerType::get(dialect->getContext()), stateTy, state, - ArrayRef({0, 3, index})); -} - -/// Persist a `Value` by storing it into the process persistence table, and -/// substituting the uses that escape the block the operation is defined in with -/// a load from the persistence table. -static void persistValue(LLVM::LLVMDialect *dialect, Location loc, - const TypeConverter *converter, - ConversionPatternRewriter &rewriter, Type stateTy, - int &i, Value state, Value persist) { - auto elemTy = cast( - cast(stateTy).getBody()[3]) - .getBody()[i]; - - if (auto arg = dyn_cast(persist)) { - rewriter.setInsertionPointToStart(arg.getParentBlock()); - } else { - rewriter.setInsertionPointAfter(persist.getDefiningOp()); - } - - Value convPersist = converter->materializeTargetConversion( - rewriter, loc, converter->convertType(persist.getType()), {persist}); - - auto gep0 = gepPersistenceState(dialect, loc, rewriter, stateTy, i, state); - - Value toStore; - if (auto ptr = dyn_cast(persist.getType())) { - // Unwrap the pointer and store it's value. - auto elemTy = converter->convertType(ptr.getUnderlyingType()); - toStore = rewriter.create(loc, elemTy, convPersist); - } else if (isa(persist.getType())) { - // Unwrap and store the signal struct. - toStore = rewriter.create(loc, getLLVMSigType(dialect), - convPersist); - } else { - // Store the value directly. - toStore = convPersist; - } - - rewriter.create(loc, toStore, gep0); - - // Load the value from the persistence table and substitute the original - // use with it, whenever it is in a different block. - for (auto &use : llvm::make_early_inc_range(persist.getUses())) { - auto user = use.getOwner(); - if (isa(persist.getType()) && user != toStore.getDefiningOp() && - user != convPersist.getDefiningOp() && - persist.getParentBlock() == user->getBlock()) { - // Redirect uses of the pointer in the same block to the pointer in the - // persistence state. This ensures that stores and loads all operate on - // the same value. - use.set(gep0); - } else if (persist.getParentBlock() != user->getBlock() || - (isa(user) && - isWaitDestArg(cast(user), persist))) { - // The destination args of a wait op have to be loaded in the entry block - // of the function, before jumping to the resume destination, so they can - // be passed as block arguments by the comparison block. - if (isa(user) && isWaitDestArg(cast(user), persist)) - rewriter.setInsertionPoint( - user->getParentRegion()->front().getTerminator()); - else - rewriter.setInsertionPointToStart(user->getBlock()); - - auto gep1 = - gepPersistenceState(dialect, loc, rewriter, stateTy, i, state); - // Use the pointer in the state struct directly for pointer and signal - // types. - if (isa(persist.getType())) { - use.set(gep1); - } else { - auto load1 = rewriter.create(loc, elemTy, gep1); - // Load the value otherwise. - use.set(load1); - } - } - } - i++; -} - -/// Insert the blocks and operations needed to persist values across suspension, -/// as well as ones needed to resume execution at the right spot. -static void insertPersistence(const TypeConverter *converter, - ConversionPatternRewriter &rewriter, - LLVM::LLVMDialect *dialect, Location loc, - ProcOp &proc, Type &stateTy, - LLVM::LLVMFuncOp &converted, - Operation *splitEntryBefore) { - auto i32Ty = IntegerType::get(dialect->getContext(), 32); - - auto &firstBB = converted.getBody().front(); - - // Split entry block such that all the operations contained in it in the - // original process appear after the comparison blocks. - auto splitFirst = - rewriter.splitBlock(&firstBB, splitEntryBefore->getIterator()); - - // Insert dummy branch terminator at the new end of the function's entry - // block. - rewriter.setInsertionPointToEnd(&firstBB); - rewriter.create(loc, ValueRange(), splitFirst); - - // Load the resume index from the process state argument. - rewriter.setInsertionPoint(firstBB.getTerminator()); - auto gep = rewriter.create( - loc, LLVM::LLVMPointerType::get(dialect->getContext()), i32Ty, - converted.getArgument(1), ArrayRef({1})); - - auto larg = rewriter.create(loc, i32Ty, gep); - - auto body = &converted.getBody(); - - // Insert an abort block as the last block. - auto abortBlock = rewriter.createBlock(body, body->end()); - rewriter.create(loc, ValueRange()); - - // Redirect the entry block to a first comparison block. If on a first - // execution, jump to the new (splitted) entry block, else the process is in - // an illegal state and jump to the abort block. - insertComparisonBlock(rewriter, dialect, loc, body, larg, 0, splitFirst, - ValueRange(), abortBlock); - - // Keep track of the index in the presistence table of the operation we - // are currently processing. - int i = 0; - // Keep track of the current resume index for comparison blocks. - int waitInd = 0; - - // Insert operations required to persist values across process suspension. - converted.walk([&](Operation *op) -> void { - if ((op->isUsedOutsideOfBlock(op->getBlock()) || isWaitDestArg(op)) && - op->getResult(0) != larg.getResult()) { - persistValue(dialect, loc, converter, rewriter, stateTy, i, - converted.getArgument(1), op->getResult(0)); - } - - // Insert a comparison block for wait operations. - if (auto wait = dyn_cast(op)) { - insertComparisonBlock(rewriter, dialect, loc, body, larg, ++waitInd, - wait.getDest(), wait.getDestOps()); - - // Insert the resume index update at the wait operation location. - rewriter.setInsertionPoint(op); - auto procState = op->getParentOfType().getArgument(1); - auto resumeIdxC = rewriter.create( - loc, i32Ty, rewriter.getI32IntegerAttr(waitInd)); - auto resumeIdxPtr = rewriter.create( - loc, LLVM::LLVMPointerType::get(dialect->getContext()), i32Ty, - procState, ArrayRef({1})); - rewriter.create(op->getLoc(), resumeIdxC, resumeIdxPtr); - } - }); - - // Also persist argument blocks escaping their defining block. - for (auto &block : converted.getBlocks()) { - // Skip entry block as it contains the function signature. - if (block.isEntryBlock()) - continue; - - for (auto arg : block.getArguments()) { - if (arg.isUsedOutsideOfBlock(&block)) { - persistValue(dialect, loc, converter, rewriter, stateTy, i, - converted.getArgument(1), arg); - } - } - } -} - -/// Return a struct type of arrays containing one entry for each RegOp condition -/// that require more than one state of the trigger to infer it (i.e. `both`, -/// `rise` and `fall`). -static LLVM::LLVMStructType getRegStateTy(LLVM::LLVMDialect *dialect, - Operation *entity) { - SmallVector types; - entity->walk([&](RegOp op) { - size_t count = 0; - for (size_t i = 0; i < op.getModes().size(); ++i) { - auto mode = op.getRegModeAt(i); - if (mode == RegMode::fall || mode == RegMode::rise || - mode == RegMode::both) - ++count; - } - if (count > 0) - types.push_back(LLVM::LLVMArrayType::get( - IntegerType::get(dialect->getContext(), 1), count)); - }); - return LLVM::LLVMStructType::getLiteral(dialect->getContext(), types); -} - -/// Create a zext operation by one bit on the given value. This is useful when -/// passing unsigned indexes to a GEP instruction, which treats indexes as -/// signed values, to avoid unexpected "sign overflows". -static Value zextByOne(Location loc, ConversionPatternRewriter &rewriter, - Value value) { - auto valueTy = value.getType(); - auto zextTy = IntegerType::get(valueTy.getContext(), - valueTy.getIntOrFloatBitWidth() + 1); - return rewriter.create(loc, zextTy, value); -} - -/// Adjust the bithwidth of value to be the same as targetTy's bitwidth. -static Value adjustBitWidth(Location loc, ConversionPatternRewriter &rewriter, - Type targetTy, Value value) { - auto valueWidth = value.getType().getIntOrFloatBitWidth(); - auto targetWidth = targetTy.getIntOrFloatBitWidth(); - - if (valueWidth < targetWidth) - return rewriter.create(loc, targetTy, value); - - if (valueWidth > targetWidth) - return rewriter.create(loc, targetTy, value); - - return value; -} - -static unsigned getIndexOfOperandResult(Operation *op, Value result) { - for (unsigned j = 0, e = op->getNumResults(); j < e; ++j) { - if (result == result.getDefiningOp()->getResult(j)) - return j; - } - llvm_unreachable( - "no way to recurse to an operation that does not return any value"); -} - -/// Recursively clone the init origin of a sig operation into the init function, -/// up to the initial constant value(s). This is required to clone the -/// initialization of array and struct signals, where the init operand cannot -/// originate from a constant operation. -static Value recursiveCloneInit(OpBuilder &initBuilder, IRMapping &mapping, - Value init) { - SmallVector clonedOperands; - Operation *initOp = init.getDefiningOp(); - - // If we end up at a value that we get via BlockArgument or as a result of a - // llhd.prb op, return a nullptr to signal that something went wrong, because - // these cases are not supported. - if (!initOp || isa(initOp)) - return nullptr; - - for (size_t i = 0, e = initOp->getNumOperands(); i < e; ++i) { - Value operand = initOp->getOperand(i); - - // If we have some value that is used multiple times (e.g., broadcasted to - // an array) then don't emit the ops to create this value several times, - // but instead remember the cloned value and use it again. - if (auto memorizedOperand = mapping.lookupOrNull(operand)) { - clonedOperands.push_back(memorizedOperand); - continue; - } - - // Recursively follow operands. - Value clonedOperand = recursiveCloneInit(initBuilder, mapping, operand); - if (!clonedOperand) - return nullptr; - - mapping.map(operand, clonedOperand); - clonedOperands.push_back(clonedOperand); - } - - Operation *clone = initOp->clone(); - clone->setOperands(clonedOperands); - - // If we have cloned an operation that returns several values, we have to - // find the result value of the cloned operation we want to return. - unsigned index = getIndexOfOperandResult(initOp, init); - return initBuilder.insert(clone)->getResult(index); -} - -/// Check if the given type is either of LLHD's ArrayType, StructType, or LLVM -/// array or struct type. -static bool isArrayOrStruct(Type type) { - return isa(type); -} - -/// Shift an integer signal pointer to obtain a view of the underlying value as -/// if it was shifted. -static std::pair -shiftIntegerSigPointer(Location loc, LLVM::LLVMDialect *dialect, - ConversionPatternRewriter &rewriter, Value pointer, - Value index) { - auto voidPtrTy = LLVM::LLVMPointerType::get(dialect->getContext()); - auto i64Ty = IntegerType::get(dialect->getContext(), 64); - - auto ptrToInt = rewriter.create(loc, i64Ty, pointer); - auto const8 = rewriter.create( - loc, index.getType(), rewriter.getI64IntegerAttr(8)); - auto ptrOffset = rewriter.create(loc, index, const8); - auto shiftedPtr = rewriter.create(loc, ptrToInt, ptrOffset); - auto newPtr = rewriter.create(loc, voidPtrTy, shiftedPtr); - - // Compute the new offset into the first byte. - auto bitOffset = rewriter.create(loc, index, const8); - - return std::make_pair(newPtr, bitOffset); -} - -/// Shift the pointer of a structured-type (array or struct) signal, to change -/// its view as if the desired slice/element was extracted. -static Value shiftStructuredSigPointer(Location loc, - ConversionPatternRewriter &rewriter, - Type elemTy, Value pointer, - LLVM::GEPArg index) { - // TODO: Remove unused args - auto voidPtrTy = LLVM::LLVMPointerType::get(rewriter.getContext()); - return rewriter.create(loc, voidPtrTy, elemTy, pointer, - ArrayRef({0, index})); -} - -/// Shift the pointer of an array-typed signal, to change its view as if the -/// desired slice/element was extracted. -static Value shiftArraySigPointer(Location loc, - ConversionPatternRewriter &rewriter, - Type arrTy, Value pointer, - LLVM::GEPArg index) { - if (auto indexValue = dyn_cast(index)) - index = zextByOne(loc, rewriter, indexValue); - return shiftStructuredSigPointer(loc, rewriter, arrTy, pointer, index); -} - -//===----------------------------------------------------------------------===// -// Type conversions -//===----------------------------------------------------------------------===// - -static Type convertSigType(SigType type, LLVMTypeConverter &converter) { - auto &context = converter.getContext(); - // auto i64Ty = IntegerType::get(&context, 64); - auto voidPtrTy = LLVM::LLVMPointerType::get(&context); - // LLVM::LLVMStructType::getLiteral(&context, {voidPtrTy, i64Ty, i64Ty, - // i64Ty}) - return voidPtrTy; -} - -static Type convertTimeType(TimeType type, LLVMTypeConverter &converter) { - auto i64Ty = IntegerType::get(&converter.getContext(), 64); - return LLVM::LLVMArrayType::get(i64Ty, 3); -} - -static Type convertPtrType(PtrType type, LLVMTypeConverter &converter) { - // converter.convertType(type.getUnderlyingType()) - return LLVM::LLVMPointerType::get(type.getContext()); -} - -//===----------------------------------------------------------------------===// -// Unit conversions -//===----------------------------------------------------------------------===// - -namespace { -/// Convert an `llhd.entity` entity to LLVM dialect. The result is an -/// `llvm.func` which takes a pointer to the global simulation state, a pointer -/// to the entity's local state, and a pointer to the instance's signal table as -/// arguments. -struct EntityOpConversion : public ConvertToLLVMPattern { - explicit EntityOpConversion(MLIRContext *ctx, - LLVMTypeConverter &typeConverter, - size_t &sigCounter, size_t ®Counter) - : ConvertToLLVMPattern(llhd::EntityOp::getOperationName(), ctx, - typeConverter), - sigCounter(sigCounter), regCounter(regCounter) {} - - LogicalResult - matchAndRewrite(Operation *op, ArrayRef operands, - ConversionPatternRewriter &rewriter) const override { - // Get adapted operands. - EntityOpAdaptor transformed(operands); - // Get entity operation. - auto entityOp = cast(op); - - // Collect used llvm types. - auto voidTy = getVoidType(); - auto voidPtrTy = getVoidPtrType(); - auto sigTy = getLLVMSigType(&getDialect()); - - regCounter = 0; - - // Use an intermediate signature conversion to add the arguments for the - // state and signal table pointer arguments. - LLVMTypeConverter::SignatureConversion intermediate( - entityOp.getNumArguments()); - // Add state and signal table arguments. - intermediate.addInputs( - std::array({voidPtrTy, voidPtrTy, voidPtrTy})); - for (size_t i = 0, e = entityOp.getNumArguments(); i < e; ++i) - intermediate.addInputs(i, voidTy); - rewriter.applySignatureConversion(entityOp.getBodyBlock(), intermediate, - typeConverter); - - OpBuilder bodyBuilder = - OpBuilder::atBlockBegin(&entityOp.getBlocks().front()); - LLVMTypeConverter::SignatureConversion final( - intermediate.getConvertedTypes().size()); - final.addInputs(0, voidPtrTy); - final.addInputs(1, voidPtrTy); - final.addInputs(2, voidPtrTy); - - // The first n elements of the signal table represent the entity arguments, - // while the remaining elements represent the entity's owned signals. - sigCounter = entityOp.getNumArguments(); - for (size_t i = 0; i < sigCounter; ++i) { - // Create gep operations from the signal table for each original argument. - auto gep = bodyBuilder.create(op->getLoc(), voidPtrTy, sigTy, - entityOp.getArgument(2), - LLVM::GEPArg(i)); - // Remap i-th original argument to the gep'd signal pointer. - final.remapInput(i + 3, gep.getResult()); - } - - rewriter.applySignatureConversion(entityOp.getBodyBlock(), final, - typeConverter); - - // Get the converted entity signature. - auto funcTy = - LLVM::LLVMFunctionType::get(voidTy, {voidPtrTy, voidPtrTy, voidPtrTy}); - - // Create the a new llvm function to house the lowered entity. - auto llvmFunc = rewriter.create( - op->getLoc(), entityOp.getName(), funcTy); - - // Add a return to the entity for later inclusion into the LLVM function. - rewriter.setInsertionPointToEnd(&entityOp.getBlocks().front()); - rewriter.create(op->getLoc(), ValueRange{}); - - // Inline the entity region in the new llvm function. - rewriter.inlineRegionBefore(entityOp.getBody(), llvmFunc.getBody(), - llvmFunc.end()); - - // Erase the original operation. - rewriter.eraseOp(op); - - return success(); - } - -private: - size_t &sigCounter; - size_t ®Counter; -}; -} // namespace - -namespace { -/// Convert an `llhd.proc` operation to LLVM dialect. This inserts the required -/// logic to resume execution after an `llhd.wait` operation, as well as state -/// keeping for values that need to persist across suspension. -struct ProcOpConversion : public ConvertToLLVMPattern { - explicit ProcOpConversion(MLIRContext *ctx, LLVMTypeConverter &typeConverter) - : ConvertToLLVMPattern(ProcOp::getOperationName(), ctx, typeConverter) {} - - LogicalResult - matchAndRewrite(Operation *op, ArrayRef operands, - ConversionPatternRewriter &rewriter) const override { - auto procOp = cast(op); - - // Get adapted operands. - ProcOpAdaptor transformed(operands); - - // Collect used llvm types. - auto voidTy = getVoidType(); - auto voidPtrTy = getVoidPtrType(); - auto i32Ty = IntegerType::get(rewriter.getContext(), 32); - auto stateTy = LLVM::LLVMStructType::getLiteral( - rewriter.getContext(), - {/*currentInstance=*/i32Ty, /*resumeIndex=*/i32Ty, - /*senseFlags=*/voidPtrTy /*senseTableTy*/, - /*persistence=*/ - getProcPersistenceTy(&getDialect(), typeConverter, procOp)}); - auto sigTy = getLLVMSigType(&getDialect()); - - // Keep track of the original first operation of the process, to know where - // to split the first block to insert comparison blocks. - auto &firstOp = op->getRegion(0).front().front(); - - // Have an intermediate signature conversion to add the arguments for the - // state, process-specific state and signal table. - LLVMTypeConverter::SignatureConversion intermediate( - procOp.getNumArguments()); - // Add state, process state table and signal table arguments. - std::array procArgTys({voidPtrTy, voidPtrTy, voidPtrTy}); - intermediate.addInputs(procArgTys); - for (size_t i = 0, e = procOp.getNumArguments(); i < e; ++i) - intermediate.addInputs(i, voidTy); - rewriter.applySignatureConversion(&procOp.getBlocks().front(), intermediate, - typeConverter); - - // Get the final signature conversion. - OpBuilder bodyBuilder = - OpBuilder::atBlockBegin(&procOp.getBlocks().front()); - LLVMTypeConverter::SignatureConversion final( - intermediate.getConvertedTypes().size()); - final.addInputs(0, voidPtrTy); - final.addInputs(1, voidPtrTy); - final.addInputs(2, voidPtrTy); - - for (size_t i = 0, e = procOp.getNumArguments(); i < e; ++i) { - // Create gep operations from the signal table for each original argument. - auto gep = bodyBuilder.create(op->getLoc(), voidPtrTy, sigTy, - procOp.getArgument(2), - LLVM::GEPArg(i)); - - // Remap the i-th original argument to the gep'd value. - final.remapInput(i + 3, gep.getResult()); - } - - // Get the converted process signature. - auto funcTy = - LLVM::LLVMFunctionType::get(voidTy, {voidPtrTy, voidPtrTy, voidPtrTy}); - // Create a new llvm function to house the lowered process. - auto llvmFunc = rewriter.create(op->getLoc(), - procOp.getName(), funcTy); - llvmFunc->setAttr("llhd.argument_count", - rewriter.getI32IntegerAttr(procOp.getNumArguments())); - - // Inline the process region in the new llvm function. - rewriter.inlineRegionBefore(procOp.getBody(), llvmFunc.getBody(), - llvmFunc.end()); - - insertPersistence(typeConverter, rewriter, &getDialect(), op->getLoc(), - procOp, stateTy, llvmFunc, &firstOp); - - // Convert the block argument types after inserting the persistence, as this - // would otherwise interfere with the persistence generation. - if (failed(rewriter.convertRegionTypes(&llvmFunc.getBody(), *typeConverter, - &final))) { - return failure(); - } - - rewriter.eraseOp(op); - - return success(); - } -}; -} // namespace - -namespace { -/// Convert an `llhd.halt` operation to LLVM dialect. This zeroes out all the -/// senses and returns, effectively making the process unable to be invoked -/// again. -struct HaltOpConversion : public ConvertToLLVMPattern { - explicit HaltOpConversion(MLIRContext *ctx, LLVMTypeConverter &typeConverter) - : ConvertToLLVMPattern(HaltOp::getOperationName(), ctx, typeConverter) {} - - LogicalResult - matchAndRewrite(Operation *op, ArrayRef operands, - ConversionPatternRewriter &rewriter) const override { - auto i1Ty = IntegerType::get(rewriter.getContext(), 1); - auto voidPtrTy = LLVM::LLVMPointerType::get(rewriter.getContext()); - auto llvmFunc = op->getParentOfType(); - auto procState = llvmFunc.getArgument(1); - - // Get senses ptr from the process state argument. - auto sensePtrGep = - rewriter.create(op->getLoc(), voidPtrTy, voidPtrTy, - procState, ArrayRef({2})); - auto sensePtr = - rewriter.create(op->getLoc(), voidPtrTy, sensePtrGep); - - // Zero out all the senses flags. - unsigned numSenseEntries = - llvmFunc->getAttrOfType("llhd.argument_count") - .getValue() - .getZExtValue(); - auto zeroB = rewriter.create(op->getLoc(), i1Ty, - rewriter.getBoolAttr(false)); - for (unsigned i = 0; i < numSenseEntries; ++i) { - auto senseElemPtr = rewriter.create( - op->getLoc(), voidPtrTy, i1Ty, sensePtr, ArrayRef({i})); - rewriter.create(op->getLoc(), zeroB, senseElemPtr); - } - - rewriter.replaceOpWithNewOp(op, ValueRange()); - return success(); - } -}; -} // namespace - -namespace { -/// Convert an `llhd.wait` operation to LLVM dialect. This sets the current -/// resume point, sets the observed senses (if present) and schedules the timed -/// wake up (if present). -struct WaitOpConversion : public ConvertToLLVMPattern { - explicit WaitOpConversion(MLIRContext *ctx, LLVMTypeConverter &typeConverter) - : ConvertToLLVMPattern(WaitOp::getOperationName(), ctx, typeConverter) {} - - LogicalResult - matchAndRewrite(Operation *op, ArrayRef operands, - ConversionPatternRewriter &rewriter) const override { - auto waitOp = cast(op); - WaitOpAdaptor transformed(operands, op->getAttrDictionary()); - auto llvmFunc = op->getParentOfType(); - - auto voidTy = getVoidType(); - auto voidPtrTy = getVoidPtrType(); - auto i1Ty = IntegerType::get(rewriter.getContext(), 1); - auto i64Ty = IntegerType::get(rewriter.getContext(), 64); - - // Get the llhdSuspend runtime function. - auto llhdSuspendTy = LLVM::LLVMFunctionType::get( - voidTy, {voidPtrTy, voidPtrTy, i64Ty, i64Ty, i64Ty}); - auto module = op->getParentOfType(); - auto llhdSuspendFunc = getOrInsertFunction(module, rewriter, op->getLoc(), - "llhdSuspend", llhdSuspendTy); - - auto statePtr = llvmFunc.getArgument(0); - auto procState = llvmFunc.getArgument(1); - - // Get senses ptr. - auto sensePtrGep = - rewriter.create(op->getLoc(), voidPtrTy, voidPtrTy, - procState, ArrayRef({2})); - auto sensePtr = - rewriter.create(op->getLoc(), voidPtrTy, sensePtrGep); - - // Reset sense table, if not all signals are observed. - unsigned numSenseEntries = - llvmFunc->getAttrOfType("llhd.argument_count") - .getValue() - .getZExtValue(); - if (waitOp.getObs().size() < numSenseEntries) { - auto zeroB = rewriter.create( - op->getLoc(), i1Ty, rewriter.getBoolAttr(false)); - for (size_t i = 0; i < numSenseEntries; ++i) { - auto senseElemPtr = - rewriter.create(op->getLoc(), voidPtrTy, i1Ty, - sensePtr, ArrayRef({i})); - rewriter.create(op->getLoc(), zeroB, senseElemPtr); - } - } - - // Set sense flags for observed signals. - for (auto observed : transformed.getObs()) { - auto instIndexPtr = - rewriter.create(op->getLoc(), voidPtrTy, i64Ty, observed, - ArrayRef({2})); - auto instIndex = - rewriter.create(op->getLoc(), i64Ty, instIndexPtr) - .getResult(); - auto oneB = rewriter.create(op->getLoc(), i1Ty, - rewriter.getBoolAttr(true)); - auto senseElementPtr = - rewriter.create(op->getLoc(), voidPtrTy, i1Ty, sensePtr, - ArrayRef({instIndex})); - rewriter.create(op->getLoc(), oneB, senseElementPtr); - } - - // Update and store the new resume index in the process state. - // Spawn scheduled event, if present. - if (waitOp.getTime()) { - auto realTime = rewriter.create( - op->getLoc(), transformed.getTime(), 0); - auto delta = rewriter.create( - op->getLoc(), transformed.getTime(), 1); - auto eps = rewriter.create( - op->getLoc(), transformed.getTime(), 2); - - std::array args({statePtr, procState, realTime, delta, eps}); - rewriter.create(op->getLoc(), std::nullopt, - SymbolRefAttr::get(llhdSuspendFunc), args); - } - - rewriter.replaceOpWithNewOp(op, ValueRange()); - return success(); - } -}; -} // namespace - -namespace { -/// Lower an llhd.inst operation to LLVM dialect. This generates malloc calls -/// and allocSignal calls (to store the pointer into the state) for each signal -/// in the instantiated entity. -struct InstOpConversion : public ConvertToLLVMPattern { - explicit InstOpConversion(MLIRContext *ctx, LLVMTypeConverter &typeConverter) - : ConvertToLLVMPattern(InstOp::getOperationName(), ctx, typeConverter) {} - - LogicalResult - matchAndRewrite(Operation *op, ArrayRef operands, - ConversionPatternRewriter &rewriter) const override { - // Get the inst operation. - auto instOp = cast(op); - // Get the parent module. - auto module = op->getParentOfType(); - auto entity = op->getParentOfType(); - - auto voidTy = getVoidType(); - auto voidPtrTy = getVoidPtrType(); - auto i1Ty = IntegerType::get(rewriter.getContext(), 1); - auto i32Ty = IntegerType::get(rewriter.getContext(), 32); - auto i64Ty = IntegerType::get(rewriter.getContext(), 64); - - // Init function signature: (i8* %state) -> void. - auto initFuncTy = LLVM::LLVMFunctionType::get(voidTy, {voidPtrTy}); - auto initFunc = - getOrInsertFunction(module, rewriter, op->getLoc(), "llhd_init", - initFuncTy, /*insertBodyAndTerminator=*/true); - - // Get or insert the malloc function definition. - // Malloc function signature: (i64 %size) -> i8* %pointer. - auto mallocSigFuncTy = LLVM::LLVMFunctionType::get(voidPtrTy, {i64Ty}); - auto mallFunc = getOrInsertFunction(module, rewriter, op->getLoc(), - "malloc", mallocSigFuncTy); - - // Get or insert the allocSignal library call definition. - // allocSignal function signature: (i8* %state, i8* %sig_name, i8* - // %sig_owner, i32 %value) -> i32 %sig_index. - auto allocSigFuncTy = LLVM::LLVMFunctionType::get( - i32Ty, {voidPtrTy, i32Ty, voidPtrTy, voidPtrTy, i64Ty}); - auto sigFunc = getOrInsertFunction(module, rewriter, op->getLoc(), - "allocSignal", allocSigFuncTy); - - // Add information about the elements of an array signal to the state. - // Signature: (i8* state, i32 signalIndex, i32 size, i32 numElements) -> - // void - auto addSigArrElemFuncTy = - LLVM::LLVMFunctionType::get(voidTy, {voidPtrTy, i32Ty, i32Ty, i32Ty}); - auto addSigElemFunc = - getOrInsertFunction(module, rewriter, op->getLoc(), - "addSigArrayElements", addSigArrElemFuncTy); - - // Add information about one element of a struct signal to the state. - // Signature: (i8* state, i32 signalIndex, i32 offset, i32 size) -> void - auto addSigStructElemFuncTy = - LLVM::LLVMFunctionType::get(voidTy, {voidPtrTy, i32Ty, i32Ty, i32Ty}); - auto addSigStructFunc = - getOrInsertFunction(module, rewriter, op->getLoc(), - "addSigStructElement", addSigStructElemFuncTy); - - // Get or insert allocProc library call definition. - auto allocProcFuncTy = - LLVM::LLVMFunctionType::get(voidTy, {voidPtrTy, voidPtrTy, voidPtrTy}); - auto allocProcFunc = getOrInsertFunction(module, rewriter, op->getLoc(), - "allocProc", allocProcFuncTy); - - // Get or insert allocEntity library call definition. - auto allocEntityFuncTy = - LLVM::LLVMFunctionType::get(voidTy, {voidPtrTy, voidPtrTy, voidPtrTy}); - auto allocEntityFunc = getOrInsertFunction( - module, rewriter, op->getLoc(), "allocEntity", allocEntityFuncTy); - - Value initStatePtr = initFunc.getArgument(0); - - // Get a builder for the init function. - OpBuilder initBuilder = - OpBuilder::atBlockTerminator(&initFunc.getBody().getBlocks().front()); - - // Use the instance name to retrieve the instance from the state. - auto ownerName = entity.getName().str() + "." + instOp.getName().str(); - - // Get or create owner name string - Value owner; - auto parentSym = - module.lookupSymbol("instance." + ownerName); - if (!parentSym) { - owner = LLVM::createGlobalString( - op->getLoc(), initBuilder, "instance." + ownerName, ownerName + '\0', - LLVM::Linkage::Internal); - parentSym = module.lookupSymbol("instance." + ownerName); - } else { - owner = - getGlobalString(op->getLoc(), initBuilder, typeConverter, parentSym); - } - - // Handle entity instantiation. - if (auto child = module.lookupSymbol(instOp.getCallee())) { - auto regStateTy = getRegStateTy(&getDialect(), child.getOperation()); - - // Get reg state size. - auto regNull = initBuilder.create(op->getLoc(), voidPtrTy); - auto regGep = - initBuilder.create(op->getLoc(), voidPtrTy, regStateTy, - regNull, ArrayRef({1})); - auto regSize = - initBuilder.create(op->getLoc(), i64Ty, regGep); - - // Malloc reg state. - auto regMall = initBuilder - .create(op->getLoc(), voidPtrTy, - SymbolRefAttr::get(mallFunc), - ArrayRef({regSize})) - .getResult(); - auto zeroB = initBuilder.create( - op->getLoc(), i1Ty, rewriter.getBoolAttr(false)); - - // Zero-initialize reg state entries. - for (size_t i = 0, - e = cast(regStateTy).getBody().size(); - i < e; ++i) { - size_t f = cast( - cast(regStateTy).getBody()[i]) - .getNumElements(); - for (size_t j = 0; j < f; ++j) { - auto regGep = initBuilder.create( - op->getLoc(), voidPtrTy, regStateTy, regMall, - ArrayRef({0, i, j})); - initBuilder.create(op->getLoc(), zeroB, regGep); - } - } - - // Add reg state pointer to global state. - initBuilder.create( - op->getLoc(), std::nullopt, SymbolRefAttr::get(allocEntityFunc), - ArrayRef({initStatePtr, owner, regMall})); - - // Index of the signal in the entity's signal table. - int initCounter = 0; - // Walk over the entity and generate mallocs for each one of its signals. - WalkResult sigWalkResult = child.walk([&](SigOp op) -> WalkResult { - // if (auto sigOp = dyn_cast(op)) { - auto underlyingTy = typeConverter->convertType(op.getInit().getType()); - // Get index constant of the signal in the entity's signal table. - auto indexConst = initBuilder.create( - op.getLoc(), i32Ty, rewriter.getI32IntegerAttr(initCounter)); - initCounter++; - - // Clone and insert the operation that defines the signal's init - // operand (assmued to be a constant/array op) - IRMapping mapping; - Value initDef = recursiveCloneInit(initBuilder, mapping, op.getInit()); - - if (!initDef) - return WalkResult::interrupt(); - - Value initDefCast = typeConverter->materializeTargetConversion( - initBuilder, initDef.getLoc(), - typeConverter->convertType(initDef.getType()), initDef); - - // Compute the required space to malloc. - auto twoC = initBuilder.create( - op.getLoc(), i64Ty, rewriter.getI32IntegerAttr(2)); - auto nullPtr = initBuilder.create(op.getLoc(), voidPtrTy); - auto sizeGep = initBuilder.create( - op.getLoc(), voidPtrTy, underlyingTy, nullPtr, - ArrayRef({1})); - auto size = - initBuilder.create(op.getLoc(), i64Ty, sizeGep); - // Malloc double the required space to make sure signal - // shifts do not segfault. - auto mallocSize = - initBuilder.create(op.getLoc(), i64Ty, size, twoC); - std::array margs({mallocSize}); - auto mall = - initBuilder - .create(op.getLoc(), voidPtrTy, - SymbolRefAttr::get(mallFunc), margs) - .getResult(); - - // Store the initial value. - initBuilder.create(op.getLoc(), initDefCast, mall); - - // Get the amount of bytes required to represent an integer underlying - // type. Use the whole size of the type if not an integer. - Value passSize; - if (auto intTy = dyn_cast(underlyingTy)) { - auto byteWidth = llvm::divideCeil(intTy.getWidth(), 8); - passSize = initBuilder.create( - op.getLoc(), i64Ty, rewriter.getI64IntegerAttr(byteWidth)); - } else { - passSize = size; - } - - std::array args( - {initStatePtr, indexConst, owner, mall, passSize}); - auto sigIndex = - initBuilder - .create(op.getLoc(), i32Ty, - SymbolRefAttr::get(sigFunc), args) - .getResult(); - - // Add structured underlying type information. - if (auto arrayTy = dyn_cast(underlyingTy)) { - auto numElements = initBuilder.create( - op.getLoc(), i32Ty, - rewriter.getI32IntegerAttr(arrayTy.getNumElements())); - - // Get element size. - auto null = initBuilder.create(op.getLoc(), voidPtrTy); - auto gepFirst = initBuilder.create( - op.getLoc(), voidPtrTy, arrayTy, null, - ArrayRef({0, 1})); - auto toInt = initBuilder.create(op.getLoc(), i32Ty, - gepFirst); - - // Add information to the state. - initBuilder.create( - op.getLoc(), std::nullopt, SymbolRefAttr::get(addSigElemFunc), - ArrayRef({initStatePtr, sigIndex, toInt, numElements})); - } else if (auto structTy = - dyn_cast(underlyingTy)) { - auto null = initBuilder.create(op.getLoc(), voidPtrTy); - for (size_t i = 0, e = structTy.getBody().size(); i < e; ++i) { - // Get pointer offset. - auto gepElem = initBuilder.create( - op.getLoc(), voidPtrTy, structTy, null, - ArrayRef({0, i})); - auto elemToInt = initBuilder.create( - op.getLoc(), i32Ty, gepElem); - - // Get element size. - auto elemNull = - initBuilder.create(op.getLoc(), voidPtrTy); - auto gepElemSize = initBuilder.create( - op.getLoc(), voidPtrTy, structTy.getBody()[i], elemNull, - ArrayRef({1})); - auto elemSizeToInt = initBuilder.create( - op.getLoc(), i32Ty, gepElemSize); - - // Add information to the state. - initBuilder.create( - op.getLoc(), std::nullopt, SymbolRefAttr::get(addSigStructFunc), - ArrayRef( - {initStatePtr, sigIndex, elemToInt, elemSizeToInt})); - } - } - return WalkResult::advance(); - }); - - if (sigWalkResult.wasInterrupted()) - return failure(); - - } else if (auto proc = module.lookupSymbol(instOp.getCallee())) { - // Handle process instantiation. - auto sensesTy = LLVM::LLVMArrayType::get(i1Ty, proc.getNumArguments()); - auto procStateTy = LLVM::LLVMStructType::getLiteral( - rewriter.getContext(), - {i32Ty, i32Ty, voidPtrTy /*ptr(sensesTy)*/, - getProcPersistenceTy(&getDialect(), typeConverter, proc)}); - - auto zeroC = initBuilder.create( - op->getLoc(), i32Ty, rewriter.getI32IntegerAttr(0)); - - // Malloc space for the process state. - auto procStateNullPtr = - initBuilder.create(op->getLoc(), voidPtrTy); - auto procStateGep = initBuilder.create( - op->getLoc(), voidPtrTy, procStateTy, procStateNullPtr, - ArrayRef({1})); - auto procStateSize = initBuilder.create( - op->getLoc(), i64Ty, procStateGep); - std::array procStateMArgs({procStateSize}); - auto procStateMall = initBuilder - .create( - op->getLoc(), voidPtrTy, - SymbolRefAttr::get(mallFunc), procStateMArgs) - .getResult(); - - // Store the initial resume index. - auto resumeGep = initBuilder.create( - op->getLoc(), voidPtrTy, procStateTy, procStateMall, - ArrayRef({0, 1})); - initBuilder.create(op->getLoc(), zeroC, resumeGep); - - // Malloc space for the senses table. - auto sensesNullPtr = - initBuilder.create(op->getLoc(), voidPtrTy); - auto sensesGep = initBuilder.create( - op->getLoc(), voidPtrTy, sensesTy, sensesNullPtr, - ArrayRef({1})); - auto sensesSize = - initBuilder.create(op->getLoc(), i64Ty, sensesGep); - std::array senseMArgs({sensesSize}); - auto sensesMall = - initBuilder - .create(op->getLoc(), voidPtrTy, - SymbolRefAttr::get(mallFunc), senseMArgs) - .getResult(); - - // Set all initial senses to 1. - auto oneB = initBuilder.create( - op->getLoc(), i1Ty, rewriter.getBoolAttr(true)); - for (size_t i = 0, e = sensesTy.getNumElements(); i < e; ++i) { - auto senseGep = initBuilder.create( - op->getLoc(), voidPtrTy, i1Ty, sensesMall, - ArrayRef({i})); - initBuilder.create(op->getLoc(), oneB, senseGep); - } - - // Store the senses pointer in the process state. - auto procStateSensesPtr = initBuilder.create( - op->getLoc(), voidPtrTy, procStateTy, procStateMall, - ArrayRef({0, 2})); - initBuilder.create(op->getLoc(), sensesMall, - procStateSensesPtr); - - std::array allocProcArgs({initStatePtr, owner, procStateMall}); - initBuilder.create(op->getLoc(), std::nullopt, - SymbolRefAttr::get(allocProcFunc), - allocProcArgs); - } - - rewriter.eraseOp(op); - return success(); - } -}; -} // namespace - -//===----------------------------------------------------------------------===// -// Signal conversions -//===----------------------------------------------------------------------===// - -namespace { -/// Convert an `llhd.sig` operation to LLVM dialect. The i-th signal of an -/// entity get's lowered to a load of the i-th element of the signal table, -/// passed as an argument. -struct SigOpConversion : public ConvertToLLVMPattern { - explicit SigOpConversion(MLIRContext *ctx, LLVMTypeConverter &typeConverter, - size_t &sigCounter) - : ConvertToLLVMPattern(llhd::SigOp::getOperationName(), ctx, - typeConverter), - sigCounter(sigCounter) {} - - LogicalResult - matchAndRewrite(Operation *op, ArrayRef operands, - ConversionPatternRewriter &rewriter) const override { - // Get the adapted opreands. - SigOpAdaptor transformed(operands); - - // Collect the used llvm types. - auto voidPtrTy = LLVM::LLVMPointerType::get(rewriter.getContext()); - auto sigTy = getLLVMSigType(&getDialect()); - - // Get the signal table pointer from the arguments. - Value sigTablePtr = op->getParentOfType().getArgument(2); - - // Get the index in the signal table and increase counter. - // Insert a gep to the signal index in the signal table argument. - rewriter.replaceOpWithNewOp(op, voidPtrTy, sigTy, sigTablePtr, - LLVM::GEPArg(sigCounter)); - ++sigCounter; - - return success(); - } - -private: - size_t &sigCounter; -}; -} // namespace - -namespace { -/// Convert an `llhd.prb` operation to LLVM dialect. The result is a library -/// call to the -/// `@probe_signal` function. The signal details are then extracted and used to -/// load the final probe value. -struct PrbOpConversion : public ConvertToLLVMPattern { - explicit PrbOpConversion(MLIRContext *ctx, LLVMTypeConverter &typeConverter) - : ConvertToLLVMPattern(llhd::PrbOp::getOperationName(), ctx, - typeConverter) {} - - LogicalResult - matchAndRewrite(Operation *op, ArrayRef operands, - ConversionPatternRewriter &rewriter) const override { - // Get the adapted operands. - PrbOpAdaptor transformed(operands); - // Get the prb operation. - auto prbOp = cast(op); - - // Collect the used llvm types. - auto resTy = prbOp.getType(); - auto finalTy = typeConverter->convertType(resTy); - - // Get the signal details from the signal struct. - auto sigDetail = getSignalDetail(rewriter, &getDialect(), op->getLoc(), - transformed.getSignal()); - - if (isa(resTy)) { - // Get the amount of bytes to load. An extra byte is always loaded to - // cover the case where a subsignal spans halfway in the last byte. - int resWidth = resTy.getIntOrFloatBitWidth(); - int loadWidth = (llvm::divideCeil(resWidth, 8) + 1) * 8; - auto loadTy = IntegerType::get(rewriter.getContext(), loadWidth); - - auto loadSig = - rewriter.create(op->getLoc(), loadTy, sigDetail[0]); - - // Shift the loaded value by the offset and truncate to the final width. - auto trOff = adjustBitWidth(op->getLoc(), rewriter, loadTy, sigDetail[1]); - auto shifted = - rewriter.create(op->getLoc(), loadTy, loadSig, trOff); - rewriter.replaceOpWithNewOp(op, finalTy, shifted); - - return success(); - } - - if (isa(resTy)) { - rewriter.replaceOpWithNewOp(op, finalTy, sigDetail[0]); - - return success(); - } - - return failure(); - } -}; -} // namespace - -namespace { -/// Convert an `llhd.drv` operation to LLVM dialect. The result is a library -/// call to the -/// `@driveSignal` function, which declaration is inserted at the beginning of -/// the module if missing. The required arguments are either generated or -/// fetched. -struct DrvOpConversion : public ConvertToLLVMPattern { - explicit DrvOpConversion(MLIRContext *ctx, LLVMTypeConverter &typeConverter) - : ConvertToLLVMPattern(llhd::DrvOp::getOperationName(), ctx, - typeConverter) {} - - LogicalResult - matchAndRewrite(Operation *op, ArrayRef operands, - ConversionPatternRewriter &rewriter) const override { - // Get the adapted operands. - DrvOpAdaptor transformed(operands); - // Get the drive operation. - auto drvOp = cast(op); - // Get the parent module. - auto module = op->getParentOfType(); - - // Collect used llvm types. - auto voidTy = getVoidType(); - auto voidPtrTy = getVoidPtrType(); - auto i1Ty = IntegerType::get(rewriter.getContext(), 1); - auto i32Ty = IntegerType::get(rewriter.getContext(), 32); - auto i64Ty = IntegerType::get(rewriter.getContext(), 64); - - // Get or insert the drive library call. - auto drvFuncTy = LLVM::LLVMFunctionType::get( - voidTy, {voidPtrTy, voidPtrTy, voidPtrTy, i64Ty, i64Ty, i64Ty, i64Ty}); - auto drvFunc = getOrInsertFunction(module, rewriter, op->getLoc(), - "driveSignal", drvFuncTy); - - // Get the state pointer from the function arguments. - Value statePtr = op->getParentOfType().getArgument(0); - - // Get signal width. - Value sigWidth; - auto underlyingTy = drvOp.getValue().getType(); - if (isArrayOrStruct(underlyingTy)) { - auto underlyingTyConv = typeConverter->convertType(underlyingTy); - auto eightC = rewriter.create( - op->getLoc(), i64Ty, rewriter.getI64IntegerAttr(8)); - auto nullPtr = rewriter.create(op->getLoc(), voidPtrTy); - auto gepOne = rewriter.create(op->getLoc(), voidPtrTy, - underlyingTyConv, nullPtr, - ArrayRef({1})); - auto toInt = - rewriter.create(op->getLoc(), i64Ty, gepOne); - sigWidth = rewriter.create(op->getLoc(), toInt, eightC); - } else { - sigWidth = rewriter.create( - op->getLoc(), i64Ty, - rewriter.getI64IntegerAttr(underlyingTy.getIntOrFloatBitWidth())); - } - - // Insert enable comparison. Skip if the enable operand is 0. - if (auto gate = drvOp.getEnable()) { - auto block = op->getBlock(); - auto continueBlock = - rewriter.splitBlock(rewriter.getInsertionBlock(), op->getIterator()); - auto drvBlock = rewriter.createBlock(continueBlock); - rewriter.setInsertionPointToEnd(drvBlock); - rewriter.create(op->getLoc(), ValueRange(), continueBlock); - - rewriter.setInsertionPointToEnd(block); - auto oneC = rewriter.create( - op->getLoc(), i1Ty, rewriter.getI16IntegerAttr(1)); - auto cmp = rewriter.create( - op->getLoc(), LLVM::ICmpPredicate::eq, transformed.getEnable(), oneC); - rewriter.create(op->getLoc(), cmp, drvBlock, - continueBlock); - - rewriter.setInsertionPointToStart(drvBlock); - } - - Type valTy = typeConverter->convertType(transformed.getValue().getType()); - Value castVal = typeConverter->materializeTargetConversion( - rewriter, transformed.getValue().getLoc(), valTy, - transformed.getValue()); - - auto oneConst = rewriter.create( - op->getLoc(), i32Ty, rewriter.getI32IntegerAttr(1)); - - // This assumes that alloca does always allocate full bytes (round up to a - // multiple of 8 bits). - auto alloca = rewriter.create(op->getLoc(), voidPtrTy, - valTy, oneConst, 4); - rewriter.create(op->getLoc(), castVal, alloca); - - // Get the time values. - auto realTime = rewriter.create( - op->getLoc(), transformed.getTime(), 0); - auto delta = rewriter.create( - op->getLoc(), transformed.getTime(), 1); - auto eps = rewriter.create(op->getLoc(), - transformed.getTime(), 2); - - // Define the driveSignal library call arguments. - std::array args({statePtr, transformed.getSignal(), alloca, - sigWidth, realTime, delta, eps}); - // Create the library call. - rewriter.create(op->getLoc(), std::nullopt, - SymbolRefAttr::get(drvFunc), args); - - rewriter.eraseOp(op); - return success(); - } -}; -} // namespace - -namespace { -/// Convert an `llhd.reg` operation to LLVM dialect. This generates a series of -/// comparisons (blocks) that end up driving the signal with the arguments of -/// the first matching trigger from the trigger list. -struct RegOpConversion : public ConvertToLLVMPattern { - explicit RegOpConversion(MLIRContext *ctx, LLVMTypeConverter &typeConverter, - size_t ®Counter) - : ConvertToLLVMPattern(RegOp::getOperationName(), ctx, typeConverter), - regCounter(regCounter) {} - - LogicalResult - matchAndRewrite(Operation *op, ArrayRef operands, - ConversionPatternRewriter &rewriter) const override { - auto regOp = cast(op); - RegOpAdaptor transformed(operands, op->getAttrDictionary()); - - auto voidPtrTy = LLVM::LLVMPointerType::get(rewriter.getContext()); - auto i1Ty = IntegerType::get(rewriter.getContext(), 1); - auto func = op->getParentOfType(); - - // Retrieve and update previous trigger values for rising/falling edge - // detection. - size_t triggerIndex = 0; - SmallVector prevTriggers; - for (int i = 0, e = regOp.getValues().size(); i < e; ++i) { - auto mode = regOp.getRegModeAt(i); - if (mode == RegMode::both || mode == RegMode::fall || - mode == RegMode::rise) { - auto gep = rewriter.create( - op->getLoc(), voidPtrTy, i1Ty, func.getArgument(1), - ArrayRef({0, regCounter, triggerIndex++})); - prevTriggers.push_back( - rewriter.create(op->getLoc(), i1Ty, gep)); - rewriter.create(op->getLoc(), - transformed.getTriggers()[i], gep); - } - } - - // Create blocks for drive and continue. - auto block = op->getBlock(); - auto continueBlock = block->splitBlock(op); - - auto drvBlock = rewriter.createBlock(continueBlock); - auto valArg = drvBlock->addArgument(transformed.getValues()[0].getType(), - transformed.getValues()[0].getLoc()); - auto delayArg = drvBlock->addArgument(transformed.getDelays()[0].getType(), - transformed.getDelays()[0].getLoc()); - auto gateArg = drvBlock->addArgument(i1Ty, rewriter.getUnknownLoc()); - - // Create a drive with the block arguments. - rewriter.setInsertionPointToStart(drvBlock); - rewriter.create(op->getLoc(), regOp.getSignal(), valArg, delayArg, - gateArg); - rewriter.create(op->getLoc(), ValueRange(), continueBlock); - - int j = prevTriggers.size() - 1; - // Create a comparison block for each of the reg tuples. - for (int i = regOp.getValues().size() - 1, e = i; i >= 0; --i) { - auto cmpBlock = rewriter.createBlock(block->getNextNode()); - rewriter.setInsertionPointToStart(cmpBlock); - - Value gate; - if (regOp.hasGate(i)) { - gate = regOp.getGateAt(i); - } else { - gate = rewriter.create(op->getLoc(), i1Ty, - rewriter.getBoolAttr(true)); - } - - auto drvArgs = std::array( - {transformed.getValues()[i], transformed.getDelays()[i], gate}); - - RegMode mode = regOp.getRegModeAt(i); - - // Create comparison constants for all modes other than both. - Value rhs; - if (mode == RegMode::low || mode == RegMode::fall) { - rhs = rewriter.create(op->getLoc(), i1Ty, - rewriter.getBoolAttr(false)); - } else if (mode == RegMode::high || mode == RegMode::rise) { - rhs = rewriter.create(op->getLoc(), i1Ty, - rewriter.getBoolAttr(true)); - } - - // Create comparison for non-both modes. - Value comp; - if (rhs) - comp = - rewriter.create(op->getLoc(), LLVM::ICmpPredicate::eq, - transformed.getTriggers()[i], rhs); - - // Create comparison for modes needing more than one state of the trigger. - Value brCond; - if (mode == RegMode::rise || mode == RegMode::fall || - mode == RegMode::both) { - - auto cmpPrev = rewriter.create( - op->getLoc(), LLVM::ICmpPredicate::ne, transformed.getTriggers()[i], - prevTriggers[j--]); - if (mode == RegMode::both) - brCond = cmpPrev; - else - brCond = - rewriter.create(op->getLoc(), i1Ty, comp, cmpPrev); - } else { - brCond = comp; - } - - Block *nextBlock; - nextBlock = cmpBlock->getNextNode(); - // Don't go to next block for last comparison's false branch (skip the - // drive block). - if (i == e) - nextBlock = continueBlock; - - rewriter.create(op->getLoc(), brCond, drvBlock, drvArgs, - nextBlock, ValueRange()); - } - - rewriter.setInsertionPointToEnd(block); - rewriter.create(op->getLoc(), ArrayRef(), - block->getNextNode()); - - rewriter.eraseOp(op); - - ++regCounter; - - return success(); - } - -private: - size_t ®Counter; -}; // namespace -} // namespace - -//===----------------------------------------------------------------------===// -// Value creation conversions -//===----------------------------------------------------------------------===// - -namespace { -/// Lower an LLHD constant operation to an equivalent LLVM dialect constant -/// operation. -struct ConstantTimeOpConversion : public ConvertToLLVMPattern { - explicit ConstantTimeOpConversion(MLIRContext *ctx, - LLVMTypeConverter &typeConverter) - : ConvertToLLVMPattern(llhd::ConstantTimeOp::getOperationName(), ctx, - typeConverter) {} - - LogicalResult - matchAndRewrite(Operation *op, ArrayRef operand, - ConversionPatternRewriter &rewriter) const override { - // Get the ConstOp. - auto constOp = cast(op); - // Get the constant's attribute. - TimeAttr timeAttr = constOp.getValueAttr(); - // Handle the time const special case: create a new array containing the - // three time values. - auto timeTy = typeConverter->convertType(constOp.getResult().getType()); - - // Convert real-time element to ps. - llvm::StringMap map = { - {"s", 12}, {"ms", 9}, {"us", 6}, {"ns", 3}, {"ps", 0}}; - uint64_t adjusted = - std::pow(10, map[timeAttr.getTimeUnit()]) * timeAttr.getTime(); - - // Get sub-steps. - uint64_t delta = timeAttr.getDelta(); - uint64_t eps = timeAttr.getEpsilon(); - - // Create time constant. - auto denseAttr = - DenseElementsAttr::get(RankedTensorType::get(3, rewriter.getI64Type()), - {adjusted, delta, eps}); - rewriter.replaceOpWithNewOp(op, timeTy, denseAttr); - return success(); - } -}; -} // namespace - -//===----------------------------------------------------------------------===// -// Extraction operation conversions -//===----------------------------------------------------------------------===// - -namespace { -/// Convert a DynExtractSliceOp to LLVM dialect. -struct SigArraySliceOpConversion - : public ConvertOpToLLVMPattern { - using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern; - - LogicalResult - matchAndRewrite(llhd::SigArraySliceOp op, OpAdaptor adaptor, - ConversionPatternRewriter &rewriter) const override { - - Type llvmArrTy = typeConverter->convertType(op.getInputArrayType()); - Type inputTy = typeConverter->convertType(op.getInput().getType()); - Type lowIndexTy = typeConverter->convertType(op.getLowIndex().getType()); - Value castInput = typeConverter->materializeTargetConversion( - rewriter, op->getLoc(), inputTy, op.getInput()); - Value castLowIndex = typeConverter->materializeTargetConversion( - rewriter, op->getLoc(), lowIndexTy, op.getLowIndex()); - - auto sigDetail = getSignalDetail(rewriter, &getDialect(), op->getLoc(), - castInput, /*extractIndices=*/true); - - auto adjustedPtr = shiftArraySigPointer(op->getLoc(), rewriter, llvmArrTy, - sigDetail[0], castLowIndex); - rewriter.replaceOp(op, createSubSig(&getDialect(), rewriter, op->getLoc(), - sigDetail, adjustedPtr, sigDetail[1])); - return success(); - } -}; -} // namespace - -namespace { -/// Convert a DynExtractSliceOp to LLVM dialect. -struct SigExtractOpConversion - : public ConvertOpToLLVMPattern { - using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern; - - LogicalResult - matchAndRewrite(llhd::SigExtractOp op, OpAdaptor adaptor, - ConversionPatternRewriter &rewriter) const override { - - Type inputTy = typeConverter->convertType(op.getInput().getType()); - Type lowBitTy = typeConverter->convertType(op.getLowBit().getType()); - Value castInput = typeConverter->materializeTargetConversion( - rewriter, op->getLoc(), inputTy, op.getInput()); - Value castLowBit = typeConverter->materializeTargetConversion( - rewriter, op->getLoc(), lowBitTy, op.getLowBit()); - - auto sigDetail = getSignalDetail(rewriter, &getDialect(), op->getLoc(), - castInput, /*extractIndices=*/true); - - auto zextStart = adjustBitWidth(op->getLoc(), rewriter, - rewriter.getI64Type(), castLowBit); - // Adjust the slice starting point by the signal's offset. - auto adjustedStart = - rewriter.create(op->getLoc(), sigDetail[1], zextStart); - - auto adjusted = shiftIntegerSigPointer( - op->getLoc(), &getDialect(), rewriter, sigDetail[0], adjustedStart); - // Create a new subsignal with the new pointer and offset. - rewriter.replaceOp(op, createSubSig(&getDialect(), rewriter, op->getLoc(), - sigDetail, adjusted.first, - adjusted.second)); - return success(); - } -}; -} // namespace - -namespace { -/// Convert -struct SigStructExtractOpConversion - : public ConvertOpToLLVMPattern { - using ConvertOpToLLVMPattern< - llhd::SigStructExtractOp>::ConvertOpToLLVMPattern; - - LogicalResult - matchAndRewrite(llhd::SigStructExtractOp op, OpAdaptor adaptor, - ConversionPatternRewriter &rewriter) const override { - - Type llvmStructTy = typeConverter->convertType(op.getStructType()); - Type inputTy = typeConverter->convertType(op.getInput().getType()); - Value castInput = typeConverter->materializeTargetConversion( - rewriter, op->getLoc(), inputTy, op.getInput()); - - std::vector sigDetail = - getSignalDetail(rewriter, &getDialect(), op->getLoc(), castInput, - /*extractIndices=*/true); - - uint32_t index = HWToLLVMEndianessConverter::llvmIndexOfStructField( - op.getStructType(), op.getField()); - - Value adjusted = shiftStructuredSigPointer( - op->getLoc(), rewriter, llvmStructTy, sigDetail[0], index); - - rewriter.replaceOp(op, createSubSig(&getDialect(), rewriter, op->getLoc(), - sigDetail, adjusted, sigDetail[1])); - - return success(); - } -}; -} // namespace - -namespace { -/// Convert a DynExtractElementOp to LLVM dialect. -struct SigArrayGetOpConversion - : public ConvertOpToLLVMPattern { - using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern; - - LogicalResult - matchAndRewrite(llhd::SigArrayGetOp op, OpAdaptor adaptor, - ConversionPatternRewriter &rewriter) const override { - - auto llvmArrTy = typeConverter->convertType(op.getArrayType()); - Type inputTy = typeConverter->convertType(op.getInput().getType()); - Type indexTy = typeConverter->convertType(op.getIndex().getType()); - Value castInput = typeConverter->materializeTargetConversion( - rewriter, op->getLoc(), inputTy, op.getInput()); - Value castIndex = typeConverter->materializeTargetConversion( - rewriter, op->getLoc(), indexTy, op.getIndex()); - - auto sigDetail = getSignalDetail(rewriter, &getDialect(), op->getLoc(), - castInput, /*extractIndices=*/true); - - auto adjustedPtr = shiftArraySigPointer(op->getLoc(), rewriter, llvmArrTy, - sigDetail[0], castIndex); - rewriter.replaceOp(op, createSubSig(&getDialect(), rewriter, op->getLoc(), - sigDetail, adjustedPtr, sigDetail[1])); - - return success(); - } -}; -} // namespace - -//===----------------------------------------------------------------------===// -// Memory operations -//===----------------------------------------------------------------------===// - -namespace { -/// Lower a `llhd.var` operation to the LLVM dialect. This results in an alloca, -/// followed by storing the initial value. -struct VarOpConversion : ConvertToLLVMPattern { - explicit VarOpConversion(MLIRContext *ctx, LLVMTypeConverter &typeConverter) - : ConvertToLLVMPattern(VarOp::getOperationName(), ctx, typeConverter) {} - - LogicalResult - matchAndRewrite(Operation *op, ArrayRef operands, - ConversionPatternRewriter &rewriter) const override { - VarOpAdaptor transformed(operands); - - auto i32Ty = IntegerType::get(rewriter.getContext(), 32); - Type initTy = typeConverter->convertType(transformed.getInit().getType()); - - auto oneC = rewriter.create( - op->getLoc(), i32Ty, rewriter.getI32IntegerAttr(1)); - auto alloca = rewriter.create( - op->getLoc(), LLVM::LLVMPointerType::get(rewriter.getContext()), initTy, - oneC, 4); - rewriter.create(op->getLoc(), transformed.getInit(), alloca); - rewriter.replaceOp(op, alloca.getResult()); - return success(); - } -}; -} // namespace - -namespace { -/// Convert an `llhd.store` operation to LLVM. This lowers the store -/// one-to-one as an LLVM store, but with the operands flipped. -struct StoreOpConversion : ConvertToLLVMPattern { - explicit StoreOpConversion(MLIRContext *ctx, LLVMTypeConverter &typeConverter) - : ConvertToLLVMPattern(llhd::StoreOp::getOperationName(), ctx, - typeConverter) {} - - LogicalResult - matchAndRewrite(Operation *op, ArrayRef operands, - ConversionPatternRewriter &rewriter) const override { - llhd::StoreOpAdaptor transformed(operands); - - rewriter.replaceOpWithNewOp(op, transformed.getValue(), - transformed.getPointer()); - - return success(); - } -}; -} // namespace - -using LoadOpConversion = - OneToOneConvertToLLVMPattern; - -//===----------------------------------------------------------------------===// -// Pass initialization -//===----------------------------------------------------------------------===// - -namespace { -struct LLHDToLLVMLoweringPass - : public circt::impl::ConvertLLHDToLLVMBase { - void runOnOperation() override; -}; -} // namespace - -void circt::populateLLHDToLLVMConversionPatterns(LLVMTypeConverter &converter, - RewritePatternSet &patterns, - size_t &sigCounter, - size_t ®Counter) { - MLIRContext *ctx = converter.getDialect()->getContext(); - - // Value creation conversion patterns. - patterns.add(ctx, converter); - - // Extract conversion patterns. - patterns.add( - converter); - - // Unit conversion patterns. - patterns.add(ctx, - converter); - patterns.add(ctx, converter, sigCounter, regCounter); - - // Signal conversion patterns. - patterns.add(ctx, converter); - patterns.add(ctx, converter, sigCounter); - patterns.add(ctx, converter, regCounter); - - // Memory conversion patterns. - patterns.add(ctx, converter); - patterns.add(converter); -} - -void circt::populateLLHDToLLVMTypeConversions(LLVMTypeConverter &converter) { - converter.addConversion( - [&](SigType sig) { return convertSigType(sig, converter); }); - converter.addConversion( - [&](TimeType time) { return convertTimeType(time, converter); }); - converter.addConversion( - [&](PtrType ptr) { return convertPtrType(ptr, converter); }); -} - -void LLHDToLLVMLoweringPass::runOnOperation() { - Namespace globals; - SymbolCache cache; - cache.addDefinitions(getOperation()); - globals.add(cache); - - // Keep a counter to infer a signal's index in his entity's signal table. - size_t sigCounter = 0; - - // Keep a counter to infer a reg's index in his entity. - size_t regCounter = 0; - - RewritePatternSet patterns(&getContext()); - auto converter = mlir::LLVMTypeConverter(&getContext()); - populateLLHDToLLVMTypeConversions(converter); - - // Also populate with HW type conversions - populateHWToLLVMTypeConversions(converter); - - // Apply a partial conversion first, lowering only the instances, to generate - // the init function. - patterns.add(&getContext(), converter); - - LLVMConversionTarget target(getContext()); - target.addIllegalOp(); - cf::populateControlFlowToLLVMConversionPatterns(converter, patterns); - arith::populateArithToLLVMConversionPatterns(converter, patterns); - - // Apply the partial conversion. - if (failed( - applyPartialConversion(getOperation(), target, std::move(patterns)))) - return signalPassFailure(); - patterns.clear(); - - // Setup the full conversion. - populateFuncToLLVMConversionPatterns(converter, patterns); - populateLLHDToLLVMConversionPatterns(converter, patterns, sigCounter, - regCounter); - - // Populate with HW and Comb conversion patterns - DenseMap, LLVM::GlobalOp> constAggregateGlobalsMap; - populateHWToLLVMConversionPatterns(converter, patterns, globals, - constAggregateGlobalsMap); - populateCombToLLVMConversionPatterns(converter, patterns); - populateCombToArithConversionPatterns(converter, patterns); - arith::populateArithToLLVMConversionPatterns(converter, patterns); - - target.addLegalOp(); - - if (failed(applyFullConversion(getOperation(), target, std::move(patterns)))) - return signalPassFailure(); -} - -/// Create an LLHD to LLVM conversion pass. -std::unique_ptr> circt::createConvertLLHDToLLVMPass() { - return std::make_unique(); -} diff --git a/lib/Dialect/LLHD/CMakeLists.txt b/lib/Dialect/LLHD/CMakeLists.txt index e2b2ca840d..9f57627c32 100644 --- a/lib/Dialect/LLHD/CMakeLists.txt +++ b/lib/Dialect/LLHD/CMakeLists.txt @@ -1,5 +1,2 @@ add_subdirectory(IR) -if(CIRCT_LLHD_SIM_ENABLED) - add_subdirectory(Simulator) -endif() add_subdirectory(Transforms) diff --git a/lib/Dialect/LLHD/Simulator/CMakeLists.txt b/lib/Dialect/LLHD/Simulator/CMakeLists.txt deleted file mode 100644 index e5cef915fd..0000000000 --- a/lib/Dialect/LLHD/Simulator/CMakeLists.txt +++ /dev/null @@ -1,38 +0,0 @@ -set(LLVM_OPTIONAL_SOURCES - State.cpp - Engine.cpp - signals-runtime-wrappers.cpp - Trace.cpp -) - -add_circt_library(CIRCTLLHDSimState - State.cpp -) - -add_circt_library(CIRCTLLHDSimTrace - Trace.cpp - - LINK_LIBS PUBLIC - CIRCTLLHDSimState -) - -add_circt_library(circt-llhd-signals-runtime-wrappers SHARED - signals-runtime-wrappers.cpp - - LINK_LIBS PUBLIC - CIRCTLLHDSimState -) -set_target_properties(circt-llhd-signals-runtime-wrappers - PROPERTIES CXX_VISIBILITY_PRESET "default") - -add_circt_library(CIRCTLLHDSimEngine - Engine.cpp - - LINK_LIBS PUBLIC - CIRCTLLHD - CIRCTLLHDToLLVM - CIRCTLLHDSimState - CIRCTLLHDSimTrace - circt-llhd-signals-runtime-wrappers - MLIRExecutionEngine - ) diff --git a/lib/Dialect/LLHD/Simulator/Engine.cpp b/lib/Dialect/LLHD/Simulator/Engine.cpp deleted file mode 100644 index be5f246469..0000000000 --- a/lib/Dialect/LLHD/Simulator/Engine.cpp +++ /dev/null @@ -1,315 +0,0 @@ -//===- Engine.cpp - Simulator Engine class implementation -------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file implements the Engine class. -// -//===----------------------------------------------------------------------===// - -#include "circt/Dialect/LLHD/Simulator/Engine.h" -#include "circt/Conversion/LLHDToLLVM.h" - -#include "mlir/ExecutionEngine/ExecutionEngine.h" -#include "mlir/IR/Builders.h" - -#include "llvm/Support/TargetSelect.h" - -using namespace circt::llhd::sim; - -Engine::Engine( - llvm::raw_ostream &out, ModuleOp module, - llvm::function_ref mlirTransformer, - llvm::function_ref llvmTransformer, - std::string root, TraceMode tm, ArrayRef sharedLibPaths) - : out(out), root(root), traceMode(tm) { - state = std::make_unique(); - state->root = root + '.' + root; - - buildLayout(module); - - auto rootEntity = module.lookupSymbol(root); - - // Insert explicit instantiation of the design root. - OpBuilder insertInst = - OpBuilder::atBlockEnd(&rootEntity.getBody().getBlocks().front()); - insertInst.create(rootEntity.getBlocks().front().back().getLoc(), - std::nullopt, root, root, ArrayRef(), - ArrayRef()); - - if (failed(mlirTransformer(module))) { - llvm::errs() << "failed to apply the MLIR passes\n"; - exit(EXIT_FAILURE); - } - - this->module = module; - - llvm::InitializeNativeTarget(); - llvm::InitializeNativeTargetAsmPrinter(); - - mlir::ExecutionEngineOptions options; - options.transformer = llvmTransformer; - options.sharedLibPaths = sharedLibPaths; - auto maybeEngine = mlir::ExecutionEngine::create(this->module, options); - assert(maybeEngine && "failed to create JIT"); - engine = std::move(*maybeEngine); -} - -Engine::~Engine() = default; - -void Engine::dumpStateLayout() { state->dumpLayout(); } - -void Engine::dumpStateSignalTriggers() { state->dumpSignalTriggers(); } - -int Engine::simulate(int n, uint64_t maxTime) { - assert(engine && "engine not found"); - assert(state && "state not found"); - - auto tm = static_cast(traceMode); - Trace trace(state, out, tm); - - SmallVector arg({&state}); - // Initialize tbe simulation state. - auto invocationResult = engine->invokePacked("llhd_init", arg); - if (invocationResult) { - llvm::errs() << "Failed invocation of llhd_init: " << invocationResult; - return -1; - } - - if (traceMode != TraceMode::None) { - // Add changes for all the signals' initial values. - for (size_t i = 0, e = state->signals.size(); i < e; ++i) { - trace.addChange(i); - } - } - - // Add a dummy event to get the simulation started. - state->queue.push_back(Slot(Time())); - ++state->queue.events; - - // Keep track of the instances that need to wakeup. - llvm::SmallVector wakeupQueue; - - // Add all instances to the wakeup queue for the first run and add the jitted - // function pointers to all of the instances to make them readily available. - for (size_t i = 0, e = state->instances.size(); i < e; ++i) { - wakeupQueue.push_back(i); - auto &inst = state->instances[i]; - auto expectedFPtr = engine->lookupPacked(inst.unit); - if (!expectedFPtr) { - llvm::errs() << "Could not lookup " << inst.unit << "!\n"; - return -1; - } - inst.unitFPtr = *expectedFPtr; - } - - int cycle = 0; - while (state->queue.events > 0) { - const auto &pop = state->queue.top(); - - // Interrupt the simulation if a stop condition is met. - if ((n > 0 && cycle >= n) || - (maxTime > 0 && pop.time.getTime() > maxTime)) { - break; - } - - // Update the simulation time. - state->time = pop.time; - - if (traceMode != TraceMode::None) - trace.flush(); - - // Process signal changes. - size_t i = 0, e = pop.changesSize; - while (i < e) { - const auto sigIndex = pop.changes[i].first; - auto &curr = state->signals[sigIndex]; - APInt buff(curr.getSize() * 8, 0); - llvm::LoadIntFromMemory(buff, curr.getValue(), curr.getSize()); - - // Apply the changes to the buffer until we reach the next signal. - while (i < e && pop.changes[i].first == sigIndex) { - const auto &change = pop.buffers[pop.changes[i].second]; - const auto offset = change.first; - const auto &drive = change.second; - if (drive.getBitWidth() < buff.getBitWidth()) - buff.insertBits(drive, offset); - else - buff = drive; - - ++i; - } - - if (!curr.updateWhenChanged(buff.getRawData())) - continue; - - // Add sensitive instances. - for (auto inst : curr.getTriggeredInstanceIndices()) { - // Skip if the process is not currently sensible to the signal. - if (!state->instances[inst].isEntity) { - const auto &sensList = state->instances[inst].sensitivityList; - auto it = std::find_if(sensList.begin(), sensList.end(), - [sigIndex](const SignalDetail &sig) { - return sig.globalIndex == sigIndex; - }); - if (sensList.end() != it && - state->instances[inst].procState->senses[it - sensList.begin()] == - 0) - continue; - - // Invalidate scheduled wakeup - state->instances[inst].expectedWakeup = Time(); - } - wakeupQueue.push_back(inst); - } - - // Dump the updated signal. - if (traceMode != TraceMode::None) - trace.addChange(sigIndex); - } - - // Add scheduled process resumes to the wakeup queue. - for (auto inst : pop.scheduled) { - if (state->time == state->instances[inst].expectedWakeup) - wakeupQueue.push_back(inst); - } - - state->queue.pop(); - - std::sort(wakeupQueue.begin(), wakeupQueue.end()); - wakeupQueue.erase(std::unique(wakeupQueue.begin(), wakeupQueue.end()), - wakeupQueue.end()); - - // Run the instances present in the wakeup queue. - for (auto i : wakeupQueue) { - auto &inst = state->instances[i]; - auto signalTable = inst.sensitivityList.data(); - - // Gather the instance arguments for unit invocation. - SmallVector args; - if (inst.isEntity) - args.assign({&state, &inst.entityState, &signalTable}); - else { - args.assign({&state, &inst.procState, &signalTable}); - } - // Run the unit. - (*inst.unitFPtr)(args.data()); - } - - // Clear wakeup queue. - wakeupQueue.clear(); - ++cycle; - } - - if (traceMode != TraceMode::None) { - // Flush any remainign changes - trace.flush(/*force=*/true); - } - - llvm::errs() << "Finished at " << state->time.toString() << " (" << cycle - << " cycles)\n"; - return 0; -} - -void Engine::buildLayout(ModuleOp module) { - // Start from the root entity. - auto rootEntity = module.lookupSymbol(root); - assert(rootEntity && "root entity not found!"); - - // Build root instance, the parent and instance names are the same for the - // root. - Instance rootInst(state->root); - rootInst.unit = root; - rootInst.path = root; - - // Recursively walk the units starting at root. - walkEntity(rootEntity, rootInst); - - // The root is always an instance. - rootInst.isEntity = true; - // Store the root instance. - state->instances.push_back(std::move(rootInst)); - - // Add triggers to signals. - for (size_t i = 0, e = state->instances.size(); i < e; ++i) { - auto &inst = state->instances[i]; - for (auto trigger : inst.sensitivityList) { - state->signals[trigger.globalIndex].pushInstanceIndex(i); - } - } -} - -void Engine::walkEntity(EntityOp entity, Instance &child) { - entity.walk([&](Operation *op) { - assert(op); - - // Add a signal to the signal table. - if (auto sig = dyn_cast(op)) { - uint64_t index = state->addSignal(sig.getName().str(), child.name); - child.sensitivityList.push_back( - SignalDetail({nullptr, 0, child.sensitivityList.size(), index})); - } - - // Build (recursive) instance layout. - if (auto inst = dyn_cast(op)) { - // Skip self-recursion. - if (inst.getCallee() == child.name) - return; - if (auto e = - op->getParentOfType().lookupSymbol(inst.getCallee())) { - Instance newChild(child.unit + '.' + inst.getName().str()); - newChild.unit = inst.getCallee().str(); - newChild.nArgs = inst.getNumOperands(); - newChild.path = child.path + "/" + inst.getName().str(); - - // Add instance arguments to sensitivity list. The first nArgs signals - // in the sensitivity list represent the unit's arguments, while the - // following ones represent the unit-defined signals. - llvm::SmallVector args; - args.insert(args.end(), inst.getInputs().begin(), - inst.getInputs().end()); - args.insert(args.end(), inst.getOutputs().begin(), - inst.getOutputs().end()); - - for (size_t i = 0, e = args.size(); i < e; ++i) { - // The signal comes from an instance's argument. - if (auto blockArg = dyn_cast(args[i])) { - auto detail = child.sensitivityList[blockArg.getArgNumber()]; - detail.instIndex = i; - newChild.sensitivityList.push_back(detail); - } else if (auto sigOp = dyn_cast(args[i].getDefiningOp())) { - // The signal comes from one of the instance's owned signals. - auto it = std::find_if( - child.sensitivityList.begin(), child.sensitivityList.end(), - [&](SignalDetail &detail) { - return state->signals[detail.globalIndex].getName() == - sigOp.getName() && - state->signals[detail.globalIndex].getOwner() == - child.name; - }); - if (it != child.sensitivityList.end()) { - auto detail = *it; - detail.instIndex = i; - newChild.sensitivityList.push_back(detail); - } - } - } - - // Recursively walk a new entity, otherwise it is a process and cannot - // define new signals or instances. - if (auto ent = dyn_cast(e)) { - newChild.isEntity = true; - walkEntity(ent, newChild); - } else { - newChild.isEntity = false; - } - - // Store the created instance. - state->instances.push_back(std::move(newChild)); - } - } - }); -} diff --git a/lib/Dialect/LLHD/Simulator/State.cpp b/lib/Dialect/LLHD/Simulator/State.cpp deleted file mode 100644 index db5be41970..0000000000 --- a/lib/Dialect/LLHD/Simulator/State.cpp +++ /dev/null @@ -1,314 +0,0 @@ -//===- State.cpp - LLHD simulator state -------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file implements the constructs used to keep track of the simulation -// state in the LLHD simulator. -// -//===----------------------------------------------------------------------===// - -#include "circt/Dialect/LLHD/Simulator/State.h" - -#include "llvm/Support/Format.h" -#include "llvm/Support/raw_ostream.h" - -#include - -using namespace llvm; -using namespace circt::llhd::sim; - -//===----------------------------------------------------------------------===// -// Time -//===----------------------------------------------------------------------===// - -std::string Time::toString() const { - return std::to_string(time) + "ps " + std::to_string(delta) + "d " + - std::to_string(eps) + "e"; -} - -//===----------------------------------------------------------------------===// -// Signal -//===----------------------------------------------------------------------===// - -std::string Signal::toHexString() const { - std::string ret; - raw_string_ostream ss(ret); - ss << "0x"; - for (int i = size - 1; i >= 0; --i) { - ss << format_hex_no_prefix(static_cast(value[i]), 2); - } - return ret; -} - -std::string Signal::toHexString(unsigned elemIndex) const { - assert(elements.size() > 0 && "the signal type has to be tuple or array!"); - auto elemSize = elements[elemIndex].second; - auto *ptr = value + elements[elemIndex].first; - std::string ret; - raw_string_ostream ss(ret); - ss << "0x"; - for (int i = elemSize - 1; i >= 0; --i) { - ss << format_hex_no_prefix(static_cast(ptr[i]), 2); - } - return ret; -} - -Signal::~Signal() { - std::free(value); - value = nullptr; -} - -//===----------------------------------------------------------------------===// -// Slot -//===----------------------------------------------------------------------===// - -bool Slot::operator<(const Slot &rhs) const { return time < rhs.time; } - -bool Slot::operator>(const Slot &rhs) const { return rhs.time < time; } - -void Slot::insertChange(int index, int bitOffset, uint8_t *bytes, - unsigned width) { - // Get the amount of 64 bit words required to store the value in an APInt. - auto size = llvm::divideCeil(width, 8); - - APInt buffer(width, 0); - llvm::LoadIntFromMemory(buffer, bytes, size); - auto offsetBufferPair = std::make_pair(bitOffset, buffer); - - if (changesSize >= buffers.size()) { - // Create a new change buffer if we don't have any unused one available for - // reuse. - buffers.push_back(offsetBufferPair); - } else { - // Reuse the first available buffer. - buffers[changesSize] = offsetBufferPair; - } - - // Map the signal index to the change buffer so we can retrieve - // it after sorting. - changes.push_back(std::make_pair(index, changesSize)); - ++changesSize; -} - -void Slot::insertChange(unsigned inst) { scheduled.push_back(inst); } - -//===----------------------------------------------------------------------===// -// UpdateQueue -//===----------------------------------------------------------------------===// -void UpdateQueue::insertOrUpdate(Time time, int index, int bitOffset, - uint8_t *bytes, unsigned width) { - auto &slot = getOrCreateSlot(time); - slot.insertChange(index, bitOffset, bytes, width); -} - -void UpdateQueue::insertOrUpdate(Time time, unsigned inst) { - auto &slot = getOrCreateSlot(time); - slot.insertChange(inst); -} - -Slot &UpdateQueue::getOrCreateSlot(Time time) { - auto &top = begin()[topSlot]; - - // Directly add to top slot. - if (!top.unused && time == top.time) { - return top; - } - - // We need to search through the queue for an existing slot only if we're - // spawning an event later than the top slot. Adding to an existing slot - // scheduled earlier than the top slot should never happens, as then it should - // be the top. - if (events > 0 && top.time < time) { - for (size_t i = 0, e = size(); i < e; ++i) { - if (time == begin()[i].time) { - return begin()[i]; - } - } - } - - // Spawn new event using an existing slot. - if (!unused.empty()) { - auto firstUnused = unused.pop_back_val(); - auto &newSlot = begin()[firstUnused]; - newSlot.unused = false; - newSlot.time = time; - - // Update the top of the queue either if it is currently unused or the new - // timestamp is earlier than it. - if (top.unused || time < top.time) - topSlot = firstUnused; - - ++events; - return newSlot; - } - - // We do not have pre-allocated slots available, generate a new one. - push_back(Slot(time)); - - // Update the top of the queue either if it is currently unused or the new - // timestamp is earlier than it. - if (top.unused || time < top.time) - topSlot = size() - 1; - - ++events; - return back(); -} - -const Slot &UpdateQueue::top() { - assert(topSlot < size() && "top is pointing out of bounds!"); - - // Sort the changes of the top slot such that all changes to the same signal - // are in succession. - auto &top = begin()[topSlot]; - llvm::sort(top.changes.begin(), top.changes.begin() + top.changesSize); - return top; -} - -void UpdateQueue::pop() { - // Reset internal structures and decrease the event counter. - auto &curr = begin()[topSlot]; - curr.unused = true; - curr.changesSize = 0; - curr.scheduled.clear(); - curr.changes.clear(); - curr.time = Time(); - --events; - - // Add to unused slots list for easy retrieval. - unused.push_back(topSlot); - - // Update the current top of the queue. - topSlot = std::distance( - begin(), - std::min_element(begin(), end(), [](const auto &a, const auto &b) { - // a is "smaller" than b if either a's timestamp is earlier than b's, or - // b is unused (i.e. b has no actual meaning). - return !a.unused && (a < b || b.unused); - })); -} - -//===----------------------------------------------------------------------===// -// Instance -//===----------------------------------------------------------------------===// - -Instance::~Instance() { - std::free(procState); - procState = nullptr; - std::free(entityState); - entityState = nullptr; -} - -//===----------------------------------------------------------------------===// -// State -//===----------------------------------------------------------------------===// - -State::~State() { - for (auto &inst : instances) { - if (inst.procState) { - std::free(inst.procState->senses); - } - } -} - -Slot State::popQueue() { - assert(!queue.empty() && "the event queue is empty"); - Slot pop = queue.top(); - queue.pop(); - return pop; -} - -void State::pushQueue(Time t, unsigned inst) { - Time newTime = time + t; - queue.insertOrUpdate(newTime, inst); - instances[inst].expectedWakeup = newTime; -} - -llvm::SmallVectorTemplateCommon::iterator -State::getInstanceIterator(std::string instName) { - auto it = - std::find_if(instances.begin(), instances.end(), - [&](const auto &inst) { return instName == inst.name; }); - - assert(it != instances.end() && "instance does not exist!"); - - return it; -} - -int State::addSignal(std::string name, std::string owner) { - signals.push_back(Signal(name, owner)); - return signals.size() - 1; -} - -void State::addProcPtr(std::string name, ProcState *procStatePtr) { - auto it = getInstanceIterator(name); - - // Store instance index in process state. - procStatePtr->inst = it - instances.begin(); - (*it).procState = procStatePtr; -} - -int State::addSignalData(int index, std::string owner, uint8_t *value, - uint64_t size) { - auto it = getInstanceIterator(owner); - - uint64_t globalIdx = (*it).sensitivityList[index + (*it).nArgs].globalIndex; - auto &sig = signals[globalIdx]; - - // Add pointer and size to global signal table entry. - sig.store(value, size); - - // Add the value pointer to the signal detail struct for each instance this - // signal appears in. - for (auto inst : signals[globalIdx].getTriggeredInstanceIndices()) { - for (auto &detail : instances[inst].sensitivityList) { - if (detail.globalIndex == globalIdx) { - detail.value = sig.getValue(); - } - } - } - return globalIdx; -} - -void State::addSignalElement(unsigned index, unsigned offset, unsigned size) { - signals[index].pushElement(std::make_pair(offset, size)); -} - -void State::dumpSignal(llvm::raw_ostream &out, int index) { - auto &sig = signals[index]; - for (auto inst : sig.getTriggeredInstanceIndices()) { - out << time.toString() << " " << instances[inst].path << "/" - << sig.getName() << " " << sig.toHexString() << "\n"; - } -} - -void State::dumpLayout() { - llvm::errs() << "::------------------- Layout -------------------::\n"; - for (const auto &inst : instances) { - llvm::errs() << inst.name << ":\n"; - llvm::errs() << "---path: " << inst.path << "\n"; - llvm::errs() << "---isEntity: " << inst.isEntity << "\n"; - llvm::errs() << "---sensitivity list: "; - for (auto in : inst.sensitivityList) { - llvm::errs() << in.globalIndex << " "; - } - llvm::errs() << "\n"; - } - llvm::errs() << "::----------------------------------------------::\n"; -} - -void State::dumpSignalTriggers() { - llvm::errs() << "::------------- Signal information -------------::\n"; - for (size_t i = 0, e = signals.size(); i < e; ++i) { - llvm::errs() << signals[i].getOwner() << "/" << signals[i].getName() - << " triggers: "; - for (auto trig : signals[i].getTriggeredInstanceIndices()) { - llvm::errs() << trig << " "; - } - llvm::errs() << "\n"; - } - llvm::errs() << "::----------------------------------------------::\n"; -} diff --git a/lib/Dialect/LLHD/Simulator/Trace.cpp b/lib/Dialect/LLHD/Simulator/Trace.cpp deleted file mode 100644 index 07cc48c578..0000000000 --- a/lib/Dialect/LLHD/Simulator/Trace.cpp +++ /dev/null @@ -1,172 +0,0 @@ -//===- Trace.cpp - Simulation trace implementation ------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file implements the Trace class, used to handle the signal trace -// generation for the llhd-sim tool. -// -//===----------------------------------------------------------------------===// - -#include "circt/Dialect/LLHD/Simulator/Trace.h" - -#include "llvm/Support/raw_ostream.h" - -using namespace circt::llhd::sim; - -Trace::Trace(std::unique_ptr const &state, llvm::raw_ostream &out, - TraceMode mode) - : out(out), state(state), mode(mode) { - auto root = state->root; - for (auto &sig : state->signals) { - bool done = (mode != TraceMode::Full && mode != TraceMode::Merged && - !sig.isOwner(root)) || - (mode == TraceMode::NamedOnly && sig.isValidSigName()); - isTraced.push_back(!done); - } -} - -//===----------------------------------------------------------------------===// -// Changes gathering methods -//===----------------------------------------------------------------------===// - -void Trace::pushChange(unsigned inst, unsigned sigIndex, int elem = -1) { - auto &sig = state->signals[sigIndex]; - std::string valueDump; - std::string path; - llvm::raw_string_ostream ss(path); - - ss << state->instances[inst].path << '/' << sig.getName(); - - if (elem >= 0) { - // Add element index to the hierarchical path. - ss << '[' << elem << ']'; - // Get element value dump. - valueDump = sig.toHexString(elem); - } else { - // Get signal value dump. - valueDump = sig.toHexString(); - } - - // Check wheter we have an actual change from last value. - auto lastValKey = std::make_pair(path, elem); - if (valueDump != lastValue[lastValKey]) { - changes.push_back(std::make_pair(path, valueDump)); - lastValue[lastValKey] = valueDump; - } -} - -void Trace::pushAllChanges(unsigned inst, unsigned sigIndex) { - auto &sig = state->signals[sigIndex]; - if (sig.hasElement()) { - // Push changes for all signal elements. - for (size_t i = 0, e = sig.getElementSize(); i < e; ++i) { - pushChange(inst, sigIndex, i); - } - } else { - // Push one change for the whole signal. - pushChange(inst, sigIndex); - } -} - -void Trace::addChange(unsigned sigIndex) { - currentTime = state->time; - if (isTraced[sigIndex]) { - if (mode == TraceMode::Full) { - auto &sig = state->signals[sigIndex]; - // Add a change for each connected instance. - for (auto inst : sig.getTriggeredInstanceIndices()) { - pushAllChanges(inst, sigIndex); - } - } else if (mode == TraceMode::Reduced) { - // The root is always the last instance in the instances list. - pushAllChanges(state->instances.size() - 1, sigIndex); - } else if (mode == TraceMode::Merged || mode == TraceMode::MergedReduce || - mode == TraceMode::NamedOnly) { - addChangeMerged(sigIndex); - } - } -} - -void Trace::addChangeMerged(unsigned sigIndex) { - auto &sig = state->signals[sigIndex]; - if (sig.hasElement()) { - // Add a change for all sub-elements - for (size_t i = 0, e = sig.getElementSize(); i < e; ++i) { - auto valueDump = sig.toHexString(i); - mergedChanges[std::make_pair(sigIndex, i)] = valueDump; - } - } else { - // Add one change for the whole signal. - auto valueDump = sig.toHexString(); - mergedChanges[std::make_pair(sigIndex, -1)] = valueDump; - } -} - -//===----------------------------------------------------------------------===// -// Flush methods -//===----------------------------------------------------------------------===// - -void Trace::sortChanges() { - std::sort(changes.begin(), changes.end(), - [](std::pair &lhs, - std::pair &rhs) -> bool { - return lhs.first < rhs.first; - }); -} - -void Trace::flush(bool force) { - if (mode == TraceMode::Full || mode == TraceMode::Reduced) - flushFull(); - else if (mode == TraceMode::Merged || mode == TraceMode::MergedReduce || - mode == TraceMode::NamedOnly) - if (state->time.getTime() > currentTime.getTime() || force) - flushMerged(); -} - -void Trace::flushFull() { - if (changes.size() > 0) { - sortChanges(); - - auto timeDump = currentTime.toString(); - for (auto change : changes) { - out << timeDump << " " << change.first << " " << change.second << "\n"; - } - changes.clear(); - } -} - -void Trace::flushMerged() { - // Move the merged changes to the changes vector for dumping. - for (auto elem : mergedChanges) { - auto sigIndex = elem.first.first; - auto sigElem = elem.first.second; - auto &sig = state->signals[sigIndex]; - auto change = elem.second; - - if (mode == TraceMode::Merged) { - // Add the changes for all connected instances. - for (auto inst : sig.getTriggeredInstanceIndices()) { - pushChange(inst, sigIndex, sigElem); - } - } else { - // The root is always the last instance in the instances list. - pushChange(state->instances.size() - 1, sigIndex, sigElem); - } - } - - if (changes.size() > 0) { - sortChanges(); - - // Flush the changes to output stream. - out << currentTime.getTime() << "ps\n"; - for (auto change : changes) { - out << " " << change.first << " " << change.second << "\n"; - } - mergedChanges.clear(); - changes.clear(); - } -} diff --git a/lib/Dialect/LLHD/Simulator/signals-runtime-wrappers.cpp b/lib/Dialect/LLHD/Simulator/signals-runtime-wrappers.cpp deleted file mode 100644 index e26c1b0320..0000000000 --- a/lib/Dialect/LLHD/Simulator/signals-runtime-wrappers.cpp +++ /dev/null @@ -1,78 +0,0 @@ -//===- signals-runtime-wrappers.cpp - Runtime library implementation ------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file implements the runtime library used in LLHD simulation. -// -//===----------------------------------------------------------------------===// - -#include "signals-runtime-wrappers.h" - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/Support/raw_ostream.h" - -using namespace llvm; -using namespace circt::llhd::sim; - -//===----------------------------------------------------------------------===// -// Runtime interface -//===----------------------------------------------------------------------===// - -int allocSignal(State *state, int index, char *owner, uint8_t *value, - int64_t size) { - assert(state && "alloc_signal: state not found"); - std::string sOwner(owner); - - return state->addSignalData(index, sOwner, value, size); -} - -void addSigArrayElements(State *state, unsigned index, unsigned size, - unsigned numElements) { - for (size_t i = 0; i < numElements; ++i) - state->addSignalElement(index, size * i, size); -} - -void addSigStructElement(State *state, unsigned index, unsigned offset, - unsigned size) { - state->addSignalElement(index, offset, size); -} - -void allocProc(State *state, char *owner, ProcState *procState) { - assert(state && "alloc_proc: state not found"); - std::string sOwner(owner); - state->addProcPtr(sOwner, procState); -} - -void allocEntity(State *state, char *owner, uint8_t *entityState) { - assert(state && "alloc_entity: state not found"); - auto it = state->getInstanceIterator(owner); - (*it).entityState = entityState; -} - -void driveSignal(State *state, SignalDetail *detail, uint8_t *value, - uint64_t width, int time, int delta, int eps) { - assert(state && "drive_signal: state not found"); - - auto globalIndex = detail->globalIndex; - auto offset = detail->offset; - - int bitOffset = - (detail->value - state->signals[globalIndex].getValue()) * 8 + offset; - - // Spawn a new event. - state->queue.insertOrUpdate(state->time + Time(time, delta, eps), globalIndex, - bitOffset, value, width); -} - -void llhdSuspend(State *state, ProcState *procState, int time, int delta, - int eps) { - // Add a new scheduled wake up if a time is specified. - if (time || delta || eps) { - Time sTime(time, delta, eps); - state->pushQueue(sTime, procState->inst); - } -} diff --git a/lib/Dialect/LLHD/Simulator/signals-runtime-wrappers.h b/lib/Dialect/LLHD/Simulator/signals-runtime-wrappers.h deleted file mode 100644 index 13f4cbeea4..0000000000 --- a/lib/Dialect/LLHD/Simulator/signals-runtime-wrappers.h +++ /dev/null @@ -1,58 +0,0 @@ -//===- signals-runtime-wrappers.h - Simulation runtime library --*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Defines the runtime library used in LLHD simulation. -// -//===----------------------------------------------------------------------===// - -#ifndef CIRCT_DIALECT_LLHD_SIMULATOR_SIGNALS_RUNTIME_WRAPPERS_H -#define CIRCT_DIALECT_LLHD_SIMULATOR_SIGNALS_RUNTIME_WRAPPERS_H - -#include "circt/Dialect/LLHD/Simulator/State.h" - -extern "C" { - -//===----------------------------------------------------------------------===// -// Runtime interfaces -//===----------------------------------------------------------------------===// - -/// Allocate a new signal. The index of the new signal in the state's list of -/// signals is returned. -int allocSignal(circt::llhd::sim::State *state, int index, char *owner, - uint8_t *value, int64_t size); - -/// Add offset and size information for the elements of an array signal. -void addSigArrayElements(circt::llhd::sim::State *state, unsigned index, - unsigned size, unsigned numElements); - -/// Add offset and size information for one element of a struct signal. Elements -/// are assumed to be added (by calling this function) in sequential order, from -/// first to last. -void addSigStructElement(circt::llhd::sim::State *state, unsigned index, - unsigned offset, unsigned size); - -/// Add allocated constructs to a process instance. -void allocProc(circt::llhd::sim::State *state, char *owner, - circt::llhd::sim::ProcState *procState); - -/// Add allocated entity state to the given instance. -void allocEntity(circt::llhd::sim::State *state, char *owner, - uint8_t *entityState); - -/// Drive a value onto a signal. -void driveSignal(circt::llhd::sim::State *state, - circt::llhd::sim::SignalDetail *index, uint8_t *value, - uint64_t width, int time, int delta, int eps); - -/// Suspend a process. -void llhdSuspend(circt::llhd::sim::State *state, - circt::llhd::sim::ProcState *procState, int time, int delta, - int eps); -} - -#endif // CIRCT_DIALECT_LLHD_SIMULATOR_SIGNALS_RUNTIME_WRAPPERS_H diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5ba60ae931..11738c2363 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -38,11 +38,6 @@ if (CIRCT_GTEST_AVAILABLE) list(APPEND CIRCT_TEST_DEPENDS CIRCTUnitTests) endif() -if(CIRCT_LLHD_SIM_ENABLED) - list(APPEND CIRCT_TEST_DEPENDS llhd-sim) - list(APPEND CIRCT_TEST_DEPENDS circt-llhd-signals-runtime-wrappers) -endif() - if(CIRCT_SLANG_FRONTEND_ENABLED) list(APPEND CIRCT_TEST_DEPENDS circt-verilog) endif() diff --git a/test/Conversion/LLHDToLLVM/convert_entity.mlir b/test/Conversion/LLHDToLLVM/convert_entity.mlir deleted file mode 100644 index 343683c95d..0000000000 --- a/test/Conversion/LLHDToLLVM/convert_entity.mlir +++ /dev/null @@ -1,29 +0,0 @@ -// RUN: circt-opt %s --convert-llhd-to-llvm --reconcile-unrealized-casts --split-input-file | FileCheck %s - -// CHECK-LABEL: llvm.func @convert_empty( -// CHECK-SAME: %arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) { -// CHECK: llvm.return -// CHECK: } -llhd.entity @convert_empty() -> () {} - -// CHECK-LABEL: llvm.func @convert_one_input( -// CHECK-SAME: %arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) { -// CHECK: [[IN0:%.+]] = llvm.getelementptr %arg2[0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> -// CHECK: llvm.return -// CHECK: } -llhd.entity @convert_one_input(%in0 : !llhd.sig) -> () {} - -// CHECK-LABEL: llvm.func @convert_one_output( -// CHECK-SAME: %arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) { -// CHECK: [[OUT0:%.*]] = llvm.getelementptr %arg2[0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> -// CHECK: llvm.return -// CHECK: } -llhd.entity @convert_one_output () -> (%out0 : !llhd.sig) {} - -// CHECK-LABEL: llvm.func @convert_input_and_output( -// CHECK-SAME: %arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) { -// CHECK: [[IN0:%.*]] = llvm.getelementptr %arg2[0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> -// CHECK: [[OUT0:%.*]] = llvm.getelementptr %arg2[1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> -// CHECK: llvm.return -// CHECK: } -llhd.entity @convert_input_and_output (%in0 : !llhd.sig) -> (%out0 : !llhd.sig) {} diff --git a/test/Conversion/LLHDToLLVM/convert_extract.mlir b/test/Conversion/LLHDToLLVM/convert_extract.mlir deleted file mode 100644 index 09816d6cc3..0000000000 --- a/test/Conversion/LLHDToLLVM/convert_extract.mlir +++ /dev/null @@ -1,126 +0,0 @@ -// RUN: circt-opt %s --convert-llhd-to-llvm --reconcile-unrealized-casts | FileCheck %s - -// CHECK-LABEL: llvm.func @convertSigExtract( -// CHECK-SAME: %arg0: i5, %arg1: !llvm.ptr) -func.func @convertSigExtract(%arg0: i5, %arg1: !llhd.sig) { - // CHECK: [[TMP:%.+]] = llvm.getelementptr %arg1[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[VALUE_PTR:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> !llvm.ptr - // CHECK: [[TMP:%.+]] = llvm.getelementptr %arg1[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[OFFSET:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> i64 - // CHECK: [[TMP:%.+]] = llvm.getelementptr %arg1[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[INST_IDX:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> i64 - // CHECK: [[TMP:%.+]] = llvm.getelementptr %arg1[0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[GLOBAL_IDX:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> i64 - - // Adjust offset - // CHECK: [[TMP:%.+]] = llvm.zext %arg0 : i5 to i64 - // CHECK: [[NEW_OFFSET:%.+]] = llvm.add [[OFFSET]], [[TMP]] - - // Adjust value pointer to closest byte - // CHECK: [[TMP1:%.+]] = llvm.ptrtoint [[VALUE_PTR]] - // CHECK: [[C8_I64:%.+]] = llvm.mlir.constant(8 : - // CHECK: [[BYTE_OFFSET:%.+]] = llvm.udiv [[NEW_OFFSET]], [[C8_I64]] - // CHECK: [[TMP2:%.+]] = llvm.add [[TMP1]], [[BYTE_OFFSET]] - // CHECK: [[VALUE_PTR:%.+]] = llvm.inttoptr [[TMP2]] - - // Adjust offset to closest byte - // CHECK: [[OFFSET:%.+]] = llvm.urem [[NEW_OFFSET]], [[C8_I64]] - - // Create new signal struct on the stack. - // CHECK: [[TMP1:%.+]] = llvm.mlir.undef : !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[TMP2:%.+]] = llvm.insertvalue [[VALUE_PTR]], [[TMP1]][0] - // CHECK: [[TMP3:%.+]] = llvm.insertvalue [[OFFSET]], [[TMP2]][1] - // CHECK: [[TMP4:%.+]] = llvm.insertvalue [[INST_IDX]], [[TMP3]][2] - // CHECK: [[TMP5:%.+]] = llvm.insertvalue [[GLOBAL_IDX]], [[TMP4]][3] - // CHECK: [[BUF:%.+]] = llvm.alloca {{%.+}} x !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: llvm.store [[TMP5]], [[BUF]] - - llhd.sig.extract %arg1 from %arg0 : (!llhd.sig) -> !llhd.sig - return -} - -// CHECK-LABEL: llvm.func @convertSigArrayGet( -// CHECK-SAME: %arg0: i2, %arg1: !llvm.ptr) -func.func @convertSigArrayGet(%arg0 : i2, %arg1 : !llhd.sig>) { - // CHECK: [[TMP:%.+]] = llvm.getelementptr %arg1[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[VALUE_PTR:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> !llvm.ptr - // CHECK: [[TMP:%.+]] = llvm.getelementptr %arg1[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[OFFSET:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> i64 - // CHECK: [[TMP:%.+]] = llvm.getelementptr %arg1[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[INST_IDX:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> i64 - // CHECK: [[TMP:%.+]] = llvm.getelementptr %arg1[0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[GLOBAL_IDX:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> i64 - - // Adjust value pointer - // CHECK: [[TMP:%.+]] = llvm.zext %arg0 : i2 to i3 - // CHECK: [[NEW_VALUE_PTR:%.+]] = llvm.getelementptr [[VALUE_PTR]][0, [[TMP]]] : (!llvm.ptr, i3) -> !llvm.ptr, !llvm.array<4 x i4> - - // Create new signal struct on the stack. - // CHECK: [[TMP1:%.+]] = llvm.mlir.undef : !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[TMP2:%.+]] = llvm.insertvalue [[NEW_VALUE_PTR]], [[TMP1]][0] - // CHECK: [[TMP3:%.+]] = llvm.insertvalue [[OFFSET]], [[TMP2]][1] - // CHECK: [[TMP4:%.+]] = llvm.insertvalue [[INST_IDX]], [[TMP3]][2] - // CHECK: [[TMP5:%.+]] = llvm.insertvalue [[GLOBAL_IDX]], [[TMP4]][3] - // CHECK: [[BUF:%.+]] = llvm.alloca {{%.+}} x !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: llvm.store [[TMP5]], [[BUF]] - - llhd.sig.array_get %arg1[%arg0] : !llhd.sig> - return -} - -// CHECK-LABEL: llvm.func @convertSigArraySlice( -// CHECK-SAME: %arg0: i2, %arg1: !llvm.ptr) -func.func @convertSigArraySlice(%arg0: i2, %arg1: !llhd.sig>) { - // CHECK: [[TMP:%.+]] = llvm.getelementptr %arg1[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[VALUE_PTR:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> !llvm.ptr - // CHECK: [[TMP:%.+]] = llvm.getelementptr %arg1[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[OFFSET:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> i64 - // CHECK: [[TMP:%.+]] = llvm.getelementptr %arg1[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[INST_IDX:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> i64 - // CHECK: [[TMP:%.+]] = llvm.getelementptr %arg1[0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[GLOBAL_IDX:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> i64 - - // Adjust value pointer - // CHECK: [[TMP:%.+]] = llvm.zext %arg0 : i2 to i3 - // CHECK: [[NEW_VALUE_PTR:%.+]] = llvm.getelementptr [[VALUE_PTR]][0, [[TMP]]] : (!llvm.ptr, i3) -> !llvm.ptr, !llvm.array<4 x i4> - - // Create new signal struct on the stack. - // CHECK: [[TMP1:%.+]] = llvm.mlir.undef : !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[TMP2:%.+]] = llvm.insertvalue [[NEW_VALUE_PTR]], [[TMP1]][0] - // CHECK: [[TMP3:%.+]] = llvm.insertvalue [[OFFSET]], [[TMP2]][1] - // CHECK: [[TMP4:%.+]] = llvm.insertvalue [[INST_IDX]], [[TMP3]][2] - // CHECK: [[TMP5:%.+]] = llvm.insertvalue [[GLOBAL_IDX]], [[TMP4]][3] - // CHECK: [[BUF:%.+]] = llvm.alloca {{%.+}} x !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: llvm.store [[TMP5]], [[BUF]] - - llhd.sig.array_slice %arg1 at %arg0 : (!llhd.sig>) -> !llhd.sig> - return -} - -// CHECK-LABEL: llvm.func @convertSigStructExtract( -// CHECK-SAME: %arg0: !llvm.ptr) -func.func @convertSigStructExtract(%arg0: !llhd.sig>) { - // CHECK: [[TMP:%.+]] = llvm.getelementptr %arg0[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[VALUE_PTR:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> !llvm.ptr - // CHECK: [[TMP:%.+]] = llvm.getelementptr %arg0[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[OFFSET:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> i64 - // CHECK: [[TMP:%.+]] = llvm.getelementptr %arg0[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[INST_IDX:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> i64 - // CHECK: [[TMP:%.+]] = llvm.getelementptr %arg0[0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[GLOBAL_IDX:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> i64 - - // Adjust value pointer - // CHECK: [[NEW_VALUE_PTR:%.+]] = llvm.getelementptr [[VALUE_PTR]][0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i3, i2, i1)> - - // Create new signal struct on the stack. - // CHECK: [[TMP1:%.+]] = llvm.mlir.undef : !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[TMP2:%.+]] = llvm.insertvalue [[NEW_VALUE_PTR]], [[TMP1]][0] - // CHECK: [[TMP3:%.+]] = llvm.insertvalue [[OFFSET]], [[TMP2]][1] - // CHECK: [[TMP4:%.+]] = llvm.insertvalue [[INST_IDX]], [[TMP3]][2] - // CHECK: [[TMP5:%.+]] = llvm.insertvalue [[GLOBAL_IDX]], [[TMP4]][3] - // CHECK: [[BUF:%.+]] = llvm.alloca {{%.+}} x !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: llvm.store [[TMP5]], [[BUF]] - - llhd.sig.struct_extract %arg0["bar"] : !llhd.sig> - return -} diff --git a/test/Conversion/LLHDToLLVM/convert_memory.mlir b/test/Conversion/LLHDToLLVM/convert_memory.mlir deleted file mode 100644 index fd323964fe..0000000000 --- a/test/Conversion/LLHDToLLVM/convert_memory.mlir +++ /dev/null @@ -1,36 +0,0 @@ -// RUN: circt-opt %s --convert-llhd-to-llvm --reconcile-unrealized-casts | FileCheck %s - -// CHECK-LABEL: llvm.func @lower_var( -// CHECK-SAME: %arg0: i1, %arg1: i32) { -func.func @lower_var(%arg0: i1, %arg1: i32) { - // CHECK: [[VAR0:%.+]] = llvm.alloca {{%.+}} x i1 - // CHECK: llvm.store %arg0, [[VAR0]] - %0 = llhd.var %arg0 : i1 - // CHECK: [[VAR1:%.+]] = llvm.alloca {{%.+}} x i32 - // CHECK: llvm.store %arg1, [[VAR1]] - %1 = llhd.var %arg1 : i32 - // CHECK: llvm.return - return -} - -// CHECK-LABEL: llvm.func @lower_load( -// CHECK-SAME: %arg0: !llvm.ptr, %arg1: !llvm.ptr) { -func.func @lower_load(%arg0: !llhd.ptr, %arg1: !llhd.ptr) { - // CHECK: llvm.load %arg0 : !llvm.ptr -> i1 - %0 = llhd.load %arg0 : !llhd.ptr - // CHECK: llvm.load %arg1 : !llvm.ptr -> i32 - %1 = llhd.load %arg1 : !llhd.ptr - // CHECK: llvm.return - return -} - -// CHECK-LABEL: llvm.func @lower_store( -// CHECK-SAME: %arg0: i1, %arg1: !llvm.ptr, %arg2: i32, %arg3: !llvm.ptr) { -func.func @lower_store(%arg0: i1, %arg1: !llhd.ptr, %arg2: i32, %arg3: !llhd.ptr) { - // CHECK: llvm.store %arg0, %arg1 : i1, !llvm.ptr - llhd.store %arg1, %arg0 : !llhd.ptr - // CHECK: llvm.store %arg2, %arg3 : i32, !llvm.ptr - llhd.store %arg3, %arg2 : !llhd.ptr - // CHECK: llvm.return - return -} diff --git a/test/Conversion/LLHDToLLVM/convert_process_persistence.mlir b/test/Conversion/LLHDToLLVM/convert_process_persistence.mlir deleted file mode 100644 index c2fedd1d4b..0000000000 --- a/test/Conversion/LLHDToLLVM/convert_process_persistence.mlir +++ /dev/null @@ -1,40 +0,0 @@ -// RUN: circt-opt %s --convert-llhd-to-llvm --reconcile-unrealized-casts | FileCheck %s - -// CHECK: @dummyA -// CHECK: @dummyB -func.func private @dummyA(%arg0: i42) -func.func private @dummyB(%arg0: !llhd.ptr) - -// CHECK-LABEL: llvm.func @PersistValuesAcrossPotentialResumePoints( -// CHECK-SAME: %arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -llhd.proc @PersistValuesAcrossPotentialResumePoints () -> () { - // Values used across basic blocks get persisted directly - // CHECK: [[TMP1:%.+]] = llvm.mlir.constant(1337 : - // CHECK: [[PERSIST_PTR1:%.+]] = llvm.getelementptr %arg1[0, 3, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i32, i32, ptr, struct<(i42, ptr)>)> - // CHECK: llvm.store [[TMP1]], [[PERSIST_PTR1]] : i42, !llvm.ptr - %0 = hw.constant 1337 : i42 - - // Variables used across basic blocks get persisted by loading their value - // CHECK: [[TMP2:%.+]] = llvm.alloca {{%.+}} x i42 - // CHECK: llvm.store [[TMP1]], [[TMP2]] : i42, !llvm.ptr - // CHECK: [[PERSIST_PTR2:%.+]] = llvm.getelementptr %arg1[0, 3, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i32, i32, ptr, struct<(i42, ptr)>)> - // CHECK: [[TMP3:%.+]] = llvm.load [[TMP2]] : !llvm.ptr -> i42 - // CHECK: llvm.store [[TMP3]], [[PERSIST_PTR2]] : i42, !llvm.ptr - %1 = llhd.var %0 : i42 - - // CHECK: llvm.br [[BB:\^.+]] - cf.br ^resume - - // CHECK: [[BB]]: -^resume: - // CHECK: [[PERSIST_PTR2:%.+]] = llvm.getelementptr %arg1[0, 3, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i32, i32, ptr, struct<(i42, ptr)>)> - // CHECK: [[PERSIST_PTR1:%.+]] = llvm.getelementptr %arg1[0, 3, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i32, i32, ptr, struct<(i42, ptr)>)> - // CHECK: [[TMP1:%.+]] = llvm.load [[PERSIST_PTR1]] : !llvm.ptr -> i42 - // CHECK: llvm.call @dummyA([[TMP1]]) - // CHECK: llvm.call @dummyB([[PERSIST_PTR2]]) - func.call @dummyA(%0) : (i42) -> () - func.call @dummyB(%1) : (!llhd.ptr) -> () - - // CHECK: llvm.br [[BB]] - cf.br ^resume -} diff --git a/test/Conversion/LLHDToLLVM/convert_signals.mlir b/test/Conversion/LLHDToLLVM/convert_signals.mlir deleted file mode 100644 index 50dff9f5e0..0000000000 --- a/test/Conversion/LLHDToLLVM/convert_signals.mlir +++ /dev/null @@ -1,102 +0,0 @@ -// RUN: circt-opt %s --convert-llhd-to-llvm --reconcile-unrealized-casts | FileCheck %s - -// CHECK-LABEL: llvm.func @driveSignal(!llvm.ptr, !llvm.ptr, !llvm.ptr, i64, i64, i64, i64) - -// CHECK-LABEL: llvm.func @convert_sig( -// CHECK-SAME: %arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) { -llhd.entity @convert_sig() -> () { - // Unused in entity definition. Only used at instantiation site. - %0 = hw.constant 0 : i1 - %1 = hw.array_create %0, %0, %0, %0 : i1 - - // CHECK: llvm.getelementptr %arg2[0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: llvm.getelementptr %arg2[1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - llhd.sig "sig0" %0 : i1 - llhd.sig "sig1" %1 : !hw.array<4xi1> -} - -// CHECK-LABEL: llvm.func @convert_prb( -// CHECK-SAME: %arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) { -llhd.entity @convert_prb(%a: !llhd.sig, %b: !llhd.sig>) -> () { - // CHECK: [[SIGPTR_A:%.+]] = llvm.getelementptr %arg2[0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[SIGPTR_B:%.+]] = llvm.getelementptr %arg2[1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - - // CHECK: [[TMP:%.+]] = llvm.getelementptr [[SIGPTR_A]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[VALUEPTR_A:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> !llvm.ptr - // CHECK: [[TMP:%.+]] = llvm.getelementptr [[SIGPTR_A]][0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[OFFSET_A:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> i64 - // CHECK: [[VALUE_A:%.+]] = llvm.load [[VALUEPTR_A]] : !llvm.ptr -> i16 - // CHECK: [[TMP1:%.+]] = llvm.trunc [[OFFSET_A]] : i64 to i16 - // CHECK: [[TMP2:%.+]] = llvm.lshr [[VALUE_A]], [[TMP1]] : i16 - // CHECK: [[VALUE_A:%.+]] = llvm.trunc [[TMP2]] : i16 to i1 - %0 = llhd.prb %a : !llhd.sig - - // CHECK: [[TMP:%.+]] = llvm.getelementptr [[SIGPTR_B]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[VALUEPTR_B:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> !llvm.ptr - // CHECK: [[VALUE_B:%.+]] = llvm.load [[VALUEPTR_B]] : !llvm.ptr -> !llvm.array<3 x i5> - %1 = llhd.prb %b : !llhd.sig> -} - -// CHECK-LABEL: llvm.func @convert_drv( -// CHECK-SAME: %arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) { -llhd.entity @convert_drv(%a: !llhd.sig, %b: !llhd.sig>) -> () { - // CHECK: [[SIGPTR_A:%.+]] = llvm.getelementptr %arg2[0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[SIGPTR_B:%.+]] = llvm.getelementptr %arg2[1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - - // CHECK: [[C0_I1:%.+]] = llvm.mlir.constant(false) : i1 - // CHECK: [[C0_I5:%.+]] = llvm.mlir.constant(0 : i5) : i5 - %c0_i1 = hw.constant 0 : i1 - %c0_i5 = hw.constant 0 : i5 - - // CHECK: [[ARRPTR:%.+]] = llvm.mlir.addressof {{@.+}} : !llvm.ptr - // CHECK: [[ARR:%.+]] = llvm.load [[ARRPTR]] : !llvm.ptr -> !llvm.array<3 x i5> - %0 = hw.array_create %c0_i5, %c0_i5, %c0_i5 : i5 - - // CHECK: [[DT:%.+]] = llvm.mlir.constant(dense<[1000, 0, 0]> - %1 = llhd.constant_time #llhd.time<1ns, 0d, 0e> - - // CHECK: [[C1_I64:%.+]] = llvm.mlir.constant(1 : i64) : i64 - // CHECK: [[C1_I32:%.+]] = llvm.mlir.constant(1 : i32) : i32 - // CHECK: [[BUF:%.+]] = llvm.alloca [[C1_I32]] x i1 - // CHECK: llvm.store [[C0_I1]], [[BUF]] : i1, !llvm.ptr - // CHECK: [[DTS:%.+]] = llvm.extractvalue [[DT]][0] : !llvm.array<3 x i64> - // CHECK: [[DTD:%.+]] = llvm.extractvalue [[DT]][1] : !llvm.array<3 x i64> - // CHECK: [[DTE:%.+]] = llvm.extractvalue [[DT]][2] : !llvm.array<3 x i64> - // CHECK: llvm.call @driveSignal(%arg0, [[SIGPTR_A]], [[BUF]], [[C1_I64]], [[DTS]], [[DTD]], [[DTE]]) - llhd.drv %a, %c0_i1 after %1 : !llhd.sig - - // CHECK: [[C8_I64:%.+]] = llvm.mlir.constant(8 : i64) : i64 - // CHECK: [[TMP1:%.+]] = llvm.mlir.zero : !llvm.ptr - // CHECK: [[TMP2:%.+]] = llvm.getelementptr [[TMP1]][1] : (!llvm.ptr) -> !llvm.ptr, !llvm.array<3 x i5> - // CHECK: [[ARRBYTES:%.+]] = llvm.ptrtoint [[TMP2]] : !llvm.ptr to i64 - // CHECK: [[ARRBITS:%.+]] = llvm.mul [[ARRBYTES]], [[C8_I64]] - - // CHECK: [[C1_I32:%.+]] = llvm.mlir.constant(1 : i32) : i32 - // CHECK: [[BUF:%.+]] = llvm.alloca [[C1_I32]] x !llvm.array<3 x i5> - // CHECK: llvm.store [[ARR]], [[BUF]] : !llvm.array<3 x i5>, !llvm.ptr - // CHECK: [[DTS:%.+]] = llvm.extractvalue [[DT]][0] : !llvm.array<3 x i64> - // CHECK: [[DTD:%.+]] = llvm.extractvalue [[DT]][1] : !llvm.array<3 x i64> - // CHECK: [[DTE:%.+]] = llvm.extractvalue [[DT]][2] : !llvm.array<3 x i64> - // CHECK: llvm.call @driveSignal(%arg0, [[SIGPTR_B]], [[BUF]], [[ARRBITS]], [[DTS]], [[DTD]], [[DTE]]) - llhd.drv %b, %0 after %1 : !llhd.sig> -} - -// CHECK-LABEL: llvm.func @convert_drv_enable( -// CHECK-SAME: %arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) { -llhd.entity @convert_drv_enable(%a: !llhd.sig) -> () { - // Last piece of read logic. - // CHECK: [[VALUE_A:%.+]] = llvm.trunc {{%.+}} : i16 to i1 - %0 = llhd.prb %a : !llhd.sig - %1 = llhd.constant_time #llhd.time<1ns, 0d, 0e> - - // CHECK: [[C1_I1:%.+]] = llvm.mlir.constant(1 {{.*}}) : i1 - // CHECK: [[ENABLE:%.+]] = llvm.icmp "eq" {{%.+}}, [[C1_I1]] : i1 - // CHECK: llvm.cond_br [[ENABLE]], ^bb1, ^bb2 - // CHECK: ^bb1: - // CHECK: llvm.call @driveSignal - // CHECK: llvm.br ^bb2 - // CHECK: ^bb2: - llhd.drv %a, %0 after %1 if %0 : !llhd.sig -} - -// TODO: Fix `llhd.reg` code generation and add test. diff --git a/test/Conversion/LLHDToLLVM/convert_simple.mlir b/test/Conversion/LLHDToLLVM/convert_simple.mlir deleted file mode 100644 index 56595fcd55..0000000000 --- a/test/Conversion/LLHDToLLVM/convert_simple.mlir +++ /dev/null @@ -1,49 +0,0 @@ -// RUN: circt-opt %s --convert-llhd-to-llvm --reconcile-unrealized-casts | FileCheck %s - -// CHECK-LABEL: llvm.func @driveSignal(!llvm.ptr, !llvm.ptr, !llvm.ptr, i64, i64, i64, i64) - -// CHECK-LABEL: llvm.func @Foo( -// CHECK-SAME: %arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) { -llhd.entity @Foo () -> () { - // Unused in entity definition. Only used at instantiation site. - // CHECK: [[C0:%.+]] = llvm.mlir.constant(false) : i1 - %0 = hw.constant 0 : i1 - - // CHECK: [[SIG_PTR:%.+]] = llvm.getelementptr %arg2[0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - %toggle = llhd.sig "toggle" %0 : i1 - - // CHECK: [[TMP:%.+]] = llvm.getelementptr [[SIG_PTR]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[SIG_VALUE_PTR:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> !llvm.ptr - // CHECK: [[TMP:%.+]] = llvm.getelementptr [[SIG_PTR]][0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[SIG_OFFSET:%.+]] = llvm.load [[TMP]] : !llvm.ptr -> i64 - // CHECK: [[SIG_VALUE:%.+]] = llvm.load [[SIG_VALUE_PTR]] : !llvm.ptr -> i16 - // CHECK: [[TMP:%.+]] = llvm.trunc [[SIG_OFFSET]] : i64 to i16 - // CHECK: [[SIG_VALUE_SHIFTED:%.+]] = llvm.lshr [[SIG_VALUE]], [[TMP]] : i16 - // CHECK: [[SIG_VALUE:%.+]] = llvm.trunc [[SIG_VALUE_SHIFTED]] : i16 to i1 - %1 = llhd.prb %toggle : !llhd.sig - - // CHECK: [[DRV_VALUE:%.+]] = llvm.xor - %allset = hw.constant 1 : i1 - %2 = comb.xor %1, %allset : i1 - - // CHECK: [[DT:%.+]] = llvm.mlir.constant(dense<[1000, 0, 0]> - %dt = llhd.constant_time #llhd.time<1ns, 0d, 0e> - - // CHECK: [[C1_I64:%.+]] = llvm.mlir.constant(1 : i64) : i64 - // CHECK: [[C1_I32:%.+]] = llvm.mlir.constant(1 : i32) : i32 - // CHECK: [[BUF:%.+]] = llvm.alloca [[C1_I32]] x i1 - // CHECK: llvm.store [[DRV_VALUE]], [[BUF]] : i1, !llvm.ptr - // CHECK: [[DT_S:%.+]] = llvm.extractvalue [[DT]][0] : !llvm.array<3 x i64> - // CHECK: [[DT_D:%.+]] = llvm.extractvalue [[DT]][1] : !llvm.array<3 x i64> - // CHECK: [[DT_E:%.+]] = llvm.extractvalue [[DT]][2] : !llvm.array<3 x i64> - // CHECK: llvm.call @driveSignal(%arg0, [[SIG_PTR]], [[BUF]], [[C1_I64]], [[DT_S]], [[DT_D]], [[DT_E]]) - llhd.drv %toggle, %2 after %dt : !llhd.sig -} - -// CHECK-LABEL: @convertConstantTime -llvm.func @convertConstantTime() { - // CHECK-NEXT: {{%.+}} = llvm.mlir.constant(dense<[0, 1, 2]> : tensor<3xi64>) : !llvm.array<3 x i64> - %2 = llhd.constant_time #llhd.time<0ns, 1d, 2e> - // CHECK-NEXT: llvm.return - llvm.return -} diff --git a/test/Conversion/LLHDToLLVM/convert_wait_halt.mlir b/test/Conversion/LLHDToLLVM/convert_wait_halt.mlir deleted file mode 100644 index bc4e714310..0000000000 --- a/test/Conversion/LLHDToLLVM/convert_wait_halt.mlir +++ /dev/null @@ -1,72 +0,0 @@ -// RUN: circt-opt %s --convert-llhd-to-llvm --reconcile-unrealized-casts | FileCheck %s - -// CHECK-LABEL: llvm.func @llhdSuspend(!llvm.ptr, !llvm.ptr, i64, i64, i64) - -// CHECK-LABEL: llvm.func @convert_wait( -// CHECK-SAME: %arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -llhd.proc @convert_wait(%a: !llhd.sig, %b: !llhd.sig) -> () { - // CHECK: [[SIGPTR_A:%.+]] = llvm.getelementptr %arg2[0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - // CHECK: [[SIGPTR_B:%.+]] = llvm.getelementptr %arg2[1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i64, i64)> - - // CHECK: [[RESUME_PTR:%.+]] = llvm.getelementptr %arg1[1] : (!llvm.ptr) -> !llvm.ptr, i32 - // CHECK: [[RESUME:%.+]] = llvm.load [[RESUME_PTR]] : !llvm.ptr -> i32 - // CHECK: llvm.br [[BB:\^.+]] - // CHECK: [[BB]]: - - // Resume 1 (after wait) - // CHECK: [[C1_I32:%.+]] = llvm.mlir.constant(1 : - // CHECK: [[EQ:%.+]] = llvm.icmp "eq" [[RESUME]], [[C1_I32]] - // CHECK: llvm.cond_br [[EQ]], [[BB_END:\^.+]], [[BB:\^.+]] - // CHECK: [[BB]]: - - // Resume 0 (entry point) - // CHECK: [[C0_I32:%.+]] = llvm.mlir.constant(0 : - // CHECK: [[EQ:%.+]] = llvm.icmp "eq" [[RESUME]], [[C0_I32]] - // CHECK: llvm.cond_br [[EQ]], [[BB_ENTRY:\^.+]], {{\^.+}} - - // CHECK: [[BB_ENTRY]]: - %0 = llhd.constant_time #llhd.time<1ns, 0d, 0e> - - // Update resume index to 1 (after wait) - // CHECK: [[C1_I32:%.+]] = llvm.mlir.constant(1 : - // CHECK: [[RESUME_PTR:%.+]] = llvm.getelementptr %arg1[1] - // CHECK: llvm.store [[C1_I32]], [[RESUME_PTR]] - - // Clear sensitivity flags for all signals. - // CHECK: [[TMP:%.+]] = llvm.getelementptr %arg1[2] - // CHECK: [[SENSE_PTR:%.+]] = llvm.load [[TMP]] - // CHECK: [[FALSE:%.+]] = llvm.mlir.constant(false) - // CHECK: [[SENSE_A:%.+]] = llvm.getelementptr [[SENSE_PTR]][0] - // CHECK: llvm.store [[FALSE]], [[SENSE_A]] : i1, !llvm.ptr - // CHECK: [[SENSE_B:%.+]] = llvm.getelementptr [[SENSE_PTR]][1] - // CHECK: llvm.store [[FALSE]], [[SENSE_B]] : i1, !llvm.ptr - - // Set sensitivity flag for signal "b" (index 1). - // CHECK: [[SIGIDX_PTR:%.+]] = llvm.getelementptr [[SIGPTR_B]][2] - // CHECK: [[SIGIDX:%.+]] = llvm.load [[SIGIDX_PTR]] : !llvm.ptr -> i64 - // CHECK: [[TRUE:%.+]] = llvm.mlir.constant(true) - // CHECK: [[SENSE:%.+]] = llvm.getelementptr [[SENSE_PTR]][[[SIGIDX]]] - // CHECK: llvm.store [[TRUE]], [[SENSE]] : i1, !llvm.ptr - - // CHECK: llvm.call @llhdSuspend(%arg0, %arg1, {{%.+}}, {{%.+}}, {{%.+}}) - llhd.wait for %0, (%b : !llhd.sig), ^end - - // CHECK: [[BB_END]]: - // CHECK: llvm.br [[BB_END]] -^end: - cf.br ^end -} - -// CHECK-LABEL: llvm.func @convert_halt( -// CHECK-SAME: %arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -llhd.proc @convert_halt() -> (%a: !llhd.sig, %b: !llhd.sig) { - // Clear sensitivity flags for all signals. - // CHECK: [[TMP:%.+]] = llvm.getelementptr %arg1[2] - // CHECK: [[SENSE_PTR:%.+]] = llvm.load [[TMP]] - // CHECK: [[FALSE:%.+]] = llvm.mlir.constant(false) - // CHECK: [[SENSE_A:%.+]] = llvm.getelementptr [[SENSE_PTR]][0] - // CHECK: llvm.store [[FALSE]], [[SENSE_A]] : i1, !llvm.ptr - // CHECK: [[SENSE_B:%.+]] = llvm.getelementptr [[SENSE_PTR]][1] - // CHECK: llvm.store [[FALSE]], [[SENSE_B]] : i1, !llvm.ptr - llhd.halt -} diff --git a/test/Conversion/LLHDToLLVM/signal-init-error.mlir b/test/Conversion/LLHDToLLVM/signal-init-error.mlir deleted file mode 100644 index e43dc66591..0000000000 --- a/test/Conversion/LLHDToLLVM/signal-init-error.mlir +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: circt-opt %s --convert-llhd-to-llvm --verify-diagnostics --split-input-file - -llhd.entity @root() -> () { - // expected-error @+1 {{failed to legalize operation 'llhd.inst'}} - llhd.inst "inst" @initUsesProbedValue () -> () : () -> () -} - -llhd.entity @initUsesProbedValue () -> () { - %0 = hw.constant 0 : i1 - %1 = llhd.sig "sig" %0 : i1 - %2 = llhd.prb %1 : !llhd.sig - %3 = hw.array_create %2, %2 : i1 - %4 = llhd.sig "sig1" %3 : !hw.array<2xi1> -} - -// TODO: add testcase where the init value of llhd.sig comes from a block argument diff --git a/test/Conversion/LLHDToLLVM/signal-init.mlir b/test/Conversion/LLHDToLLVM/signal-init.mlir deleted file mode 100644 index 1fc1499a58..0000000000 --- a/test/Conversion/LLHDToLLVM/signal-init.mlir +++ /dev/null @@ -1,77 +0,0 @@ -// RUN: circt-opt %s --convert-llhd-to-llvm --reconcile-unrealized-casts | FileCheck %s - -// CHECK-LABEL: llvm.func @llhd_init -// CHECK-SAME: %arg0: !llvm.ptr) { -llhd.entity @Root() -> () { - // CHECK: [[SIZE:%.+]] = llvm.ptrtoint - // CHECK: [[MEM:%.+]] = llvm.call @malloc([[SIZE]]) - // CHECK: llvm.call @allocEntity(%arg0, [[OWNER:%.+]], [[MEM]]) - - // sig0 - // CHECK: [[VALUE:%.+]] = llvm.mlir.constant(1337 : i42) : i42 - // CHECK: llvm.store [[VALUE]], [[BUF:%.+]] : i42, !llvm.ptr - // CHECK: [[SIZE:%.+]] = llvm.mlir.constant(6 : - // CHECK: llvm.call @allocSignal(%arg0, {{%.+}}, [[OWNER]], [[BUF]], [[SIZE]]) - - // sig1 - // CHECK: [[TMP:%.+]] = llvm.getelementptr {{%.+}}[1] : (!llvm.ptr) -> !llvm.ptr, !llvm.array<2 x i1> - // CHECK: [[SIZE:%.+]] = llvm.ptrtoint [[TMP]] : !llvm.ptr to i64 - // CHECK: llvm.store {{%.+}}, [[BUF:%.+]] : !llvm.array<2 x i1>, !llvm.ptr - // CHECK: [[SIGID1:%.+]] = llvm.call @allocSignal(%arg0, {{%.+}}, [[OWNER]], [[BUF]], [[SIZE]]) - // sig1 layout details - // CHECK: [[ELEMENT_COUNT:%.+]] = llvm.mlir.constant(2 : - // CHECK: [[TMP:%.+]] = llvm.getelementptr {{%.+}}[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.array<2 x i1> - // CHECK: [[ELEMENT_SIZE:%.+]] = llvm.ptrtoint [[TMP]] - // CHECK: llvm.call @addSigArrayElements(%arg0, [[SIGID1]], [[ELEMENT_SIZE]], [[ELEMENT_COUNT]]) - - // sig2 - // CHECK: [[TMP:%.+]] = llvm.getelementptr {{%.+}}[1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i5, i1)> - // CHECK: [[SIZE:%.+]] = llvm.ptrtoint [[TMP]] : !llvm.ptr to i64 - // CHECK: llvm.store {{%.+}}, [[BUF:%.+]] : !llvm.struct<(i5, i1)>, !llvm.ptr - // CHECK: [[SIGID2:%.+]] = llvm.call @allocSignal(%arg0, {{%.+}}, [[OWNER]], [[BUF]], [[SIZE]]) - // sig2 layout details f2 - // CHECK: [[TMP:%.+]] = llvm.getelementptr {{%.+}}[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i5, i1)> - // CHECK: [[ELEMENT_OFFSET:%.+]] = llvm.ptrtoint [[TMP]] - // CHECK: [[TMP:%.+]] = llvm.getelementptr {{%.+}}[1] : (!llvm.ptr) -> !llvm.ptr, i5 - // CHECK: [[ELEMENT_SIZE:%.+]] = llvm.ptrtoint [[TMP]] - // CHECK: llvm.call @addSigStructElement(%arg0, [[SIGID2]], [[ELEMENT_OFFSET]], [[ELEMENT_SIZE]]) - // sig2 layout details f1 - // CHECK: [[TMP:%.+]] = llvm.getelementptr {{%.+}}[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i5, i1)> - // CHECK: [[ELEMENT_OFFSET:%.+]] = llvm.ptrtoint [[TMP]] - // CHECK: [[TMP:%.+]] = llvm.getelementptr {{%.+}}[1] : (!llvm.ptr) -> !llvm.ptr, i1 - // CHECK: [[ELEMENT_SIZE:%.+]] = llvm.ptrtoint [[TMP]] - // CHECK: llvm.call @addSigStructElement(%arg0, [[SIGID2]], [[ELEMENT_OFFSET]], [[ELEMENT_SIZE]]) - - llhd.inst "inst0" @Signals () -> () : () -> () - - // CHECK: llvm.call @allocEntity(%arg0, [[OWNER:%.+]], {{%.+}}) - - // sig3 - // CHECK-DAG: [[FALSE:%.+]] = llvm.mlir.constant(false) - // CHECK-DAG: [[TMP1:%.+]] = llvm.mlir.undef - // CHECK-DAG: [[TMP2:%.+]] = llvm.insertvalue [[FALSE]], [[TMP1]][0] - // CHECK-DAG: [[TMP3:%.+]] = llvm.insertvalue [[FALSE]], [[TMP2]][1] - // CHECK: llvm.store [[TMP3]], [[BUF:%.+]] : !llvm.array<2 x i1>, !llvm.ptr - // CHECK: [[SIGID3:%.+]] = llvm.call @allocSignal(%arg0, {{%.+}}, [[OWNER]], [[BUF]], {{%.+}}) - - llhd.inst "inst1" @PartiallyLowered () -> () : () -> () - // llhd.inst "inst2" @MultipleResults () -> () : () -> () -} - -llhd.entity @Signals () -> () { - %0 = hw.constant 1337 : i42 - %1 = llhd.sig "sig0" %0 : i42 - %2 = hw.aggregate_constant [0 : i1, 1 : i1] : !hw.array<2xi1> - %3 = llhd.sig "sig1" %2 : !hw.array<2xi1> - %4 = hw.aggregate_constant [0 : i1, 1 : i5] : !hw.struct - %5 = llhd.sig "sig2" %4 : !hw.struct -} - -llhd.entity @PartiallyLowered () -> () { - %0 = llvm.mlir.constant(false) : i1 - %1 = llvm.mlir.undef : !llvm.array<2 x i1> - %2 = llvm.insertvalue %0, %1[0] : !llvm.array<2 x i1> - %3 = llvm.insertvalue %0, %2[1] : !llvm.array<2 x i1> - %4 = builtin.unrealized_conversion_cast %3 : !llvm.array<2 x i1> to !hw.array<2xi1> - %5 = llhd.sig "sig3" %4 : !hw.array<2xi1> -} diff --git a/test/lit.cfg.py b/test/lit.cfg.py index 6807b90e2f..7db81a899a 100644 --- a/test/lit.cfg.py +++ b/test/lit.cfg.py @@ -75,11 +75,6 @@ if config.zlib == "1": if config.scheduling_or_tools != "": config.available_features.add('or-tools') -# Add llhd-sim if it is built. -if config.llhd_sim_enabled: - config.available_features.add('llhd-sim') - tools.append('llhd-sim') - # Add circt-verilog if the Slang frontend is enabled. if config.slang_frontend_enabled: config.available_features.add('slang') diff --git a/test/lit.site.cfg.py.in b/test/lit.site.cfg.py.in index 1c1e7215f2..3eb9be6b7a 100644 --- a/test/lit.site.cfg.py.in +++ b/test/lit.site.cfg.py.in @@ -38,7 +38,6 @@ config.circt_shlib_dir = "@LLVM_LIBRARY_OUTPUT_INTDIR@" config.verilator_path = "@VERILATOR_PATH@" config.zlib = "@HAVE_ZLIB@" config.scheduling_or_tools = "@SCHEDULING_OR_TOOLS@" -config.llhd_sim_enabled = @CIRCT_LLHD_SIM_ENABLED@ config.slang_frontend_enabled = @CIRCT_SLANG_FRONTEND_ENABLED@ # Support substitution of the tools_dir with user parameters. This is diff --git a/test/llhd-sim/commandline.mlir b/test/llhd-sim/commandline.mlir deleted file mode 100644 index c952231d74..0000000000 --- a/test/llhd-sim/commandline.mlir +++ /dev/null @@ -1,7 +0,0 @@ -// REQUIRES: llhd-sim -// RUN: llhd-sim --help | FileCheck %s --implicit-check-not='{{[Oo]}}ptions:' - -// CHECK: OVERVIEW: LLHD simulator -// CHECK: OPTIONS -// CHECK: Generic Options -// CHECK: llhd-sim Options diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index c74fb9f95a..7614afa486 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -12,7 +12,6 @@ add_subdirectory(firtool) add_subdirectory(handshake-runner) add_subdirectory(hlstool) add_subdirectory(ibistool) -add_subdirectory(llhd-sim) add_subdirectory(om-linker) add_subdirectory(py-split-input-file) diff --git a/tools/circt-opt/CMakeLists.txt b/tools/circt-opt/CMakeLists.txt index d8d575554b..be49d8901a 100644 --- a/tools/circt-opt/CMakeLists.txt +++ b/tools/circt-opt/CMakeLists.txt @@ -46,7 +46,6 @@ target_link_libraries(circt-opt CIRCTHandshakeTransforms CIRCTLECTransforms CIRCTLLHD - CIRCTLLHDToLLVM CIRCTHWToLLVM CIRCTCombToArith CIRCTCombToLLVM diff --git a/tools/llhd-sim/CMakeLists.txt b/tools/llhd-sim/CMakeLists.txt deleted file mode 100644 index 059abee197..0000000000 --- a/tools/llhd-sim/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -set(LIBS - CIRCTLLHD - CIRCTComb - CIRCTHW - CIRCTLLHDToLLVM - CIRCTLLHDSimEngine - ) - -# llhd-sim fails to link on Windows with MSVC. -IF(CIRCT_LLHD_SIM_ENABLED) - add_circt_tool(llhd-sim - llhd-sim.cpp) - - llvm_update_compile_flags(llhd-sim) - target_link_libraries(llhd-sim PRIVATE ${LIBS}) -endif() diff --git a/tools/llhd-sim/llhd-sim.cpp b/tools/llhd-sim/llhd-sim.cpp deleted file mode 100644 index 7cc27fca19..0000000000 --- a/tools/llhd-sim/llhd-sim.cpp +++ /dev/null @@ -1,234 +0,0 @@ -//===- llhd-sim.cpp - LLHD simulator tool -----------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file implements a command line tool to run LLHD simulation. -// -//===----------------------------------------------------------------------===// - -#include "circt/Conversion/LLHDToLLVM.h" -#include "circt/Dialect/Comb/CombDialect.h" -#include "circt/Dialect/HW/HWDialect.h" -#include "circt/Dialect/LLHD/IR/LLHDDialect.h" -#include "circt/Dialect/LLHD/Simulator/Engine.h" -#include "circt/Dialect/LLHD/Simulator/Trace.h" -#include "circt/Support/Version.h" - -#include "mlir/Conversion/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.h" -#include "mlir/Dialect/ControlFlow/IR/ControlFlow.h" -#include "mlir/Dialect/Func/IR/FuncOps.h" -#include "mlir/Dialect/LLVMIR/LLVMDialect.h" -#include "mlir/ExecutionEngine/OptUtils.h" -#include "mlir/Parser/Parser.h" -#include "mlir/Pass/PassManager.h" -#include "mlir/Support/FileUtilities.h" -#include "mlir/Target/LLVMIR/Dialect/Builtin/BuiltinToLLVMIRTranslation.h" -#include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h" -#include "mlir/Target/LLVMIR/Export.h" -#include "mlir/Transforms/Passes.h" - -#include "llvm/Support/Error.h" -#include "llvm/Support/InitLLVM.h" -#include "llvm/Support/SourceMgr.h" -#include "llvm/Support/ToolOutputFile.h" - -using namespace llvm; -using namespace mlir; -using namespace mlir::func; -using namespace circt; -using namespace circt::llhd::sim; - -static cl::OptionCategory mainCategory("llhd-sim Options"); - -static cl::opt inputFilename(cl::Positional, - cl::desc(""), - cl::init("-"), cl::cat(mainCategory)); - -static cl::opt outputFilename("o", cl::desc("Output filename"), - cl::value_desc("filename"), - cl::init("-"), - cl::cat(mainCategory)); - -static cl::opt nSteps("n", cl::desc("Set the maximum number of steps"), - cl::value_desc("max-steps"), cl::cat(mainCategory)); - -static cl::opt maxTime( - "T", - cl::desc("Stop the simulation after the given amount of simulation time in " - "picoseconds, including all sub-steps for that real-time step"), - cl::value_desc("max-time"), cl::cat(mainCategory)); - -static cl::opt - dumpLLVMDialect("dump-llvm-dialect", - cl::desc("Dump the LLVM IR dialect module"), - cl::cat(mainCategory)); - -static cl::opt dumpLLVMIR("dump-llvm-ir", - cl::desc("Dump the LLVM IR module"), - cl::cat(mainCategory)); - -static cl::opt dumpMLIR("dump-mlir", - cl::desc("Dump the original MLIR module"), - cl::cat(mainCategory)); - -static cl::opt dumpLayout("dump-layout", - cl::desc("Dump the gathered instance layout"), - cl::cat(mainCategory)); - -static cl::opt root( - "root", - cl::desc("Specify the name of the entity to use as root of the design"), - cl::value_desc("root_name"), cl::init("root"), cl::cat(mainCategory)); -static cl::alias rootA("r", cl::desc("Alias for -root"), cl::aliasopt(root), - cl::cat(mainCategory)); - -enum OptLevel { O0, O1, O2, O3 }; - -static cl::opt - optimizationLevel(cl::desc("Choose optimization level:"), cl::init(O2), - cl::values(clEnumVal(O0, "Run passes and codegen at O0"), - clEnumVal(O1, "Run passes and codegen at O1"), - clEnumVal(O2, "Run passes and codegen at O2"), - clEnumVal(O3, "Run passes and codegen at O3")), - cl::cat(mainCategory)); - -static cl::opt traceMode( - "trace-format", cl::desc("Choose the dump format:"), - cl::init(TraceMode::Full), - cl::values( - clEnumValN(TraceMode::Full, "full", - "Dump signal changes for every time step and sub-step, " - "for all instances"), - clEnumValN(TraceMode::Reduced, "reduced", - "Dump signal changes for every time-step and " - "sub-step, only for the top-level instance"), - clEnumValN(TraceMode::Merged, "merged", - "Only dump changes for real-time steps, for all instances"), - clEnumValN(TraceMode::MergedReduce, "merged-reduce", - "Only dump changes for real-time steps, only for the " - "top-level instance"), - clEnumValN( - TraceMode::NamedOnly, "named-only", - "Only dump changes for real-time steps, only for top-level " - "instance and signals not having the default name '(sig)?[0-9]*'"), - clEnumValN(TraceMode::None, "none", "Don't dump a signal trace")), - cl::cat(mainCategory)); - -static cl::list - sharedLibs("shared-libs", - cl::desc("Libraries to link dynamically. Specify absolute path " - "to llhd-signals-runtime-wrappers for GCC or Windows. " - "Optional otherwise."), - cl::ZeroOrMore, cl::MiscFlags::CommaSeparated, - cl::cat(mainCategory)); - -static int dumpLLVM(ModuleOp module, MLIRContext &context) { - if (dumpLLVMDialect) { - module.dump(); - llvm::errs() << "\n"; - return 0; - } - - // Translate the module, that contains the LLVM dialect, to LLVM IR. - llvm::LLVMContext llvmContext; - auto llvmModule = mlir::translateModuleToLLVMIR(module, llvmContext); - if (!llvmModule) { - llvm::errs() << "Failed to emit LLVM IR\n"; - return -1; - } - - auto llvmTransformer = - makeOptimizingTransformer(optimizationLevel, 0, nullptr); - - if (auto err = llvmTransformer(llvmModule.get())) { - llvm::errs() << "Failed to optimize LLVM IR " << err << "\n"; - return -1; - } - - llvm::errs() << *llvmModule << "\n"; - return 0; -} - -static LogicalResult applyMLIRPasses(ModuleOp module) { - PassManager pm(module.getContext()); - - pm.addPass(createConvertLLHDToLLVMPass()); - pm.addPass(::mlir::createReconcileUnrealizedCastsPass()); - - return pm.run(module); -} - -int main(int argc, char **argv) { - InitLLVM y(argc, argv); - - // Set the bug report message to indicate users should file issues on - // llvm/circt and not llvm/llvm-project. - setBugReportMsg(circtBugReportMsg); - - // Hide default LLVM options, other than for this tool. - cl::HideUnrelatedOptions(mainCategory); - - cl::ParseCommandLineOptions(argc, argv, "LLHD simulator\n"); - - // Set up the input and output files. - std::string errorMessage; - auto file = openInputFile(inputFilename, &errorMessage); - if (!file) { - llvm::errs() << errorMessage << "\n"; - return 1; - } - - auto output = openOutputFile(outputFilename, &errorMessage); - if (!output) { - llvm::errs() << errorMessage << "\n"; - exit(1); - } - - // Parse the input file. - SourceMgr mgr; - mgr.AddNewSourceBuffer(std::move(file), SMLoc()); - - MLIRContext context; - // Load the dialects - context - .loadDialect(); - mlir::registerLLVMDialectTranslation(context); - mlir::registerBuiltinDialectTranslation(context); - - mlir::OwningOpRef module( - parseSourceFile(mgr, &context)); - - if (dumpMLIR) { - module->dump(); - llvm::errs() << "\n"; - return 0; - } - - SmallVector sharedLibPaths(sharedLibs.begin(), - sharedLibs.end()); - - llhd::sim::Engine engine( - output->os(), *module, &applyMLIRPasses, - makeOptimizingTransformer(optimizationLevel, 0, nullptr), root, traceMode, - sharedLibPaths); - - if (dumpLLVMDialect || dumpLLVMIR) { - return dumpLLVM(engine.getModule(), context); - } - - if (dumpLayout) { - engine.dumpStateLayout(); - engine.dumpStateSignalTriggers(); - return 0; - } - - engine.simulate(nSteps, maxTime); - - output->keep(); - return 0; -}