CIRCT 23.0.0git
Loading...
Searching...
No Matches
ArcRuntime.cpp
Go to the documentation of this file.
1//===- ArcRuntime.cpp - Default implementation of the ArcRuntime-----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file provides the default implementation of a runtime library for
10// arcilator simulations.
11//
12//===----------------------------------------------------------------------===//
13
14#define ARC_RUNTIME_ENABLE_EXPORT
15
23#include "llvm/ADT/APInt.h"
24#include "llvm/ADT/ArrayRef.h"
25#include "llvm/ADT/SmallVector.h"
26#include "llvm/Support/raw_ostream.h"
27
28#ifdef ARC_RUNTIME_JIT_BIND
29#define ARC_RUNTIME_JITBIND_FNDECL
31#endif
32
33#include <cassert>
34#include <cstdarg>
35#include <cstdint>
36#include <cstdlib>
37#include <iostream>
38
39using namespace circt::arc::runtime;
40
41static inline impl::ModelInstance *getModelInstance(const ArcState *instance) {
42 assert(instance->impl != nullptr && "Instance is null");
43 return reinterpret_cast<impl::ModelInstance *>(instance->impl);
44}
45
47 const char *args) {
48 if (model->apiVersion != ARC_RUNTIME_API_VERSION) {
49 impl::fatalError("API version mismatch.\nMake sure to use an ArcRuntime "
50 "release matching "
51 "the arcilator version used to build the hardware model.");
52 return nullptr;
53 }
54
55 auto *statePtr = reinterpret_cast<ArcState *>(
56 calloc(1, sizeof(ArcState) + model->numStateBytes));
57 assert(reinterpret_cast<intptr_t>(&statePtr->modelState[0]) % 16 == 0 &&
58 "Simulation state must be 16 byte aligned");
59 statePtr->impl = new impl::ModelInstance(model, args, statePtr);
60 statePtr->magic = ARC_RUNTIME_MAGIC;
61 return statePtr;
62}
63
65 if (instance->impl)
66 delete reinterpret_cast<impl::ModelInstance *>(instance->impl);
67 free(instance);
68}
69
71
72void arcRuntimeOnEval(ArcState *instance) {
73 getModelInstance(instance)->onEval(instance);
74}
75
77 getModelInstance(instance)->onInitialized(instance);
78}
79
81 uint64_t offset) {
82 if (!modelState)
83 impl::fatalError("State pointer is null");
84 uint8_t *modPtr = static_cast<uint8_t *>(modelState) - offset;
85 ArcState *statePtr = reinterpret_cast<ArcState *>(modPtr - sizeof(ArcState));
86 if (statePtr->magic != ARC_RUNTIME_MAGIC)
87 impl::fatalError("Incorrect magic number for state");
88 return statePtr;
89}
90
91// --- IR Exports ---
92
94 const char *args) {
95 ArcState *statePtr = arcRuntimeAllocateInstance(model, args);
96 return statePtr->modelState;
97}
98
99void arcRuntimeIR_onEval(uint8_t *modelState) {
101}
102
103void arcRuntimeIR_onInitialized(uint8_t *modelState) {
105}
106
110
111void arcRuntimeIR_format(const FmtDescriptor *fmt, ...) {
112 va_list args;
113 va_start(args, fmt);
114
115 llvm::raw_ostream &os = llvm::outs();
116 while (fmt->action != FmtDescriptor::Action_End) {
117 switch (fmt->action) {
119 std::string_view s(va_arg(args, const char *), fmt->literal.width);
120 os << s;
121 break;
122 }
124 std::string_view s(fmt->smallLiteral.data);
125 os << s;
126 break;
127 }
129 uint64_t *words = va_arg(args, uint64_t *);
130 int64_t numWords = llvm::divideCeil(fmt->intFmt.bitwidth, 64);
131 llvm::APInt apInt(fmt->intFmt.bitwidth, llvm::ArrayRef(words, numWords));
132 std::optional<int32_t> specifierWidth;
133 if (fmt->intFmt.specifierWidth >= 0)
134 specifierWidth = fmt->intFmt.specifierWidth;
135 circt::formatInteger(os, apInt, fmt->intFmt.radix,
137 fmt->intFmt.paddingChar, specifierWidth,
138 fmt->intFmt.isSigned);
139 break;
140 }
142 os << static_cast<char>(va_arg(args, int));
143 break;
145 break;
146 }
147 fmt++;
148 }
149
150 va_end(args);
151}
152
153uint64_t *arcRuntimeIR_swapTraceBuffer(const uint8_t *modelState) {
154 auto *modPtr = static_cast<const uint8_t *>(modelState);
155 auto *statePtr =
156 reinterpret_cast<const ArcState *>(modPtr - sizeof(ArcState));
157 if (statePtr->magic != ARC_RUNTIME_MAGIC)
158 impl::fatalError("Incorrect magic number for state");
159 return getModelInstance(statePtr)->swapTraceBuffer();
160}
161
162#ifdef ARC_RUNTIME_JIT_BIND
163namespace circt::arc::runtime {
164
165static const APICallbacks apiCallbacksGlobal{
169
170const APICallbacks &getArcRuntimeAPICallbacks() { return apiCallbacksGlobal; }
171
172} // namespace circt::arc::runtime
173#endif
ArcState * arcRuntimeAllocateInstance(const ArcRuntimeModelInfo *model, const char *args)
uint64_t arcRuntimeGetAPIVersion()
Return the API version of the runtime library.
void arcRuntimeDeleteInstance(ArcState *instance)
Destroy and deallocate the state of a model instance.
void arcRuntimeOnEval(ArcState *instance)
Pre-Eval hook. Must be called by the driver once before every eval step.
void arcRuntimeIR_format(const FmtDescriptor *fmt,...)
Prints a formatted string to stdout.
uint8_t * arcRuntimeIR_allocInstance(const ArcRuntimeModelInfo *model, const char *args)
Allocate and initialize the state for a new instance of the given hardware model.
void arcRuntimeOnInitialized(ArcState *instance)
Must be called by the driver after the model's initial function and before the first onEval call.
uint64_t * arcRuntimeIR_swapTraceBuffer(const uint8_t *modelState)
Release the active trace buffer and request an empty new buffer.
void arcRuntimeIR_deleteInstance(uint8_t *modelState)
Destroy and deallocate the state of a model instance.
ArcState * arcRuntimeGetStateFromModelState(uint8_t *modelState, uint64_t offset)
Project a pointer to the model state to its ArcState container.
static impl::ModelInstance * getModelInstance(const ArcState *instance)
void arcRuntimeIR_onEval(uint8_t *modelState)
Pre-Eval hook of the runtime library.
void arcRuntimeIR_onInitialized(uint8_t *modelState)
Post-initialization hook of the runtime library.
assert(baseType &&"element must be base type")
ARC_IR_EXPORT uint8_t * arcRuntimeIR_allocInstance(const ArcRuntimeModelInfo *model, const char *args)
Allocate and initialize the state for a new instance of the given hardware model.
ARC_IR_EXPORT void arcRuntimeIR_deleteInstance(uint8_t *modelState)
Destroy and deallocate the state of a model instance.
ARC_IR_EXPORT void arcRuntimeIR_onEval(uint8_t *modelState)
Pre-Eval hook of the runtime library.
ARC_IR_EXPORT void arcRuntimeIR_onInitialized(uint8_t *modelState)
Post-initialization hook of the runtime library.
ARC_IR_EXPORT uint64_t * arcRuntimeIR_swapTraceBuffer(const uint8_t *modelState)
Release the active trace buffer and request an empty new buffer.
ARC_IR_EXPORT void arcRuntimeIR_format(const circt::arc::runtime::FmtDescriptor *fmt,...)
Prints a formatted string to stdout.
#define ARC_RUNTIME_MAGIC
Magic number used to assert the presence of an ArcState struct.
Definition Common.h:30
#define ARC_RUNTIME_API_VERSION
Version of the combined public and internal API.
Definition Common.h:27
void formatInteger(llvm::raw_ostream &os, const llvm::APInt &value, unsigned radix, bool isUpperCase, bool isLeftAligned, char paddingChar, std::optional< int32_t > specifierWidth, bool isSigned)
Format value in the given radix and emit it to os, padded to a field width.
Static information for a compiled hardware model, generated by the MLIR lowering.
Definition Common.h:70
uint64_t apiVersion
Runtime API version used when compiling the model.
Definition Common.h:72
uint64_t numStateBytes
Number of bytes required for the model's state.
Definition Common.h:74
Combined runtime and model state for a hardware model instance.
Definition Common.h:44
void * impl
Runtime implementation specific data. Usually points to a custom struct.
Definition Common.h:46
uint8_t modelState[]
Definition Common.h:58
uint32_t magic
Runtime magic number. Must be set to ARC_RUNTIME_MAGIC.
Definition Common.h:54
bool isLeftAligned
Whether the value is left aligned.
bool isSigned
Whether to treat the value as signed.
bool isUpperCase
Whether to use uppercase hex letters.
char paddingChar
Padding character (NUL if no padding is desired).
int16_t specifierWidth
The minumum width of the output in characters.
int16_t bitwidth
The bitwidth of the integer value.
int8_t radix
The radix to use for formatting. Must be one of {2, 8, 10, 16}.
int64_t width
The width of the literal string in characters.
A format descriptor, to be given to arcRuntimeFormat.
@ Action_Char
Prints a character (c).
@ Action_Literal
Prints a literal string.
@ Action_End
End of the format string, no action to take.
@ Action_LiteralSmall
Prints a literal string (small string optimization).