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
22#include "llvm/ADT/APInt.h"
23#include "llvm/ADT/ArrayRef.h"
24#include "llvm/ADT/SmallVector.h"
25#include "llvm/Support/raw_ostream.h"
26
27#ifdef ARC_RUNTIME_JIT_BIND
28#define ARC_RUNTIME_JITBIND_FNDECL
30#endif
31
32#include <cassert>
33#include <cstdarg>
34#include <cstdint>
35#include <cstdlib>
36#include <iostream>
37
38using namespace circt::arc::runtime;
39
40static inline impl::ModelInstance *getModelInstance(const ArcState *instance) {
41 assert(instance->impl != nullptr && "Instance is null");
42 return reinterpret_cast<impl::ModelInstance *>(instance->impl);
43}
44
46 const char *args) {
47 if (model->apiVersion != ARC_RUNTIME_API_VERSION) {
48 impl::fatalError("API version mismatch.\nMake sure to use an ArcRuntime "
49 "release matching "
50 "the arcilator version used to build the hardware model.");
51 return nullptr;
52 }
53
54 auto *statePtr = reinterpret_cast<ArcState *>(
55 calloc(1, sizeof(ArcState) + model->numStateBytes));
56 assert(reinterpret_cast<intptr_t>(&statePtr->modelState[0]) % 16 == 0 &&
57 "Simulation state must be 16 byte aligned");
58 statePtr->impl = new impl::ModelInstance(model, args, statePtr);
59 statePtr->magic = ARC_RUNTIME_MAGIC;
60 return statePtr;
61}
62
64 if (instance->impl)
65 delete reinterpret_cast<impl::ModelInstance *>(instance->impl);
66 free(instance);
67}
68
70
71void arcRuntimeOnEval(ArcState *instance) {
72 getModelInstance(instance)->onEval(instance);
73}
74
76 getModelInstance(instance)->onInitialized(instance);
77}
78
80 uint64_t offset) {
81 if (!modelState)
82 impl::fatalError("State pointer is null");
83 uint8_t *modPtr = static_cast<uint8_t *>(modelState) - offset;
84 ArcState *statePtr = reinterpret_cast<ArcState *>(modPtr - sizeof(ArcState));
85 if (statePtr->magic != ARC_RUNTIME_MAGIC)
86 impl::fatalError("Incorrect magic number for state");
87 return statePtr;
88}
89
90// --- IR Exports ---
91
93 const char *args) {
94 ArcState *statePtr = arcRuntimeAllocateInstance(model, args);
95 return statePtr->modelState;
96}
97
98void arcRuntimeIR_onEval(uint8_t *modelState) {
100}
101
102void arcRuntimeIR_onInitialized(uint8_t *modelState) {
104}
105
109
110// Emits an integer to `os` using the given format specifiers.
111//
112// Note that this is a copy of formatIntegersByRadix from SimOps.cpp.
113static void formatIntegersByRadix(llvm::raw_ostream &os, int width, int radix,
114 const llvm::APInt &value, bool isUpperCase,
115 bool isLeftAligned, char paddingChar,
116 int specifierWidth, bool isSigned) {
117 llvm::SmallVector<char, 32> strBuf;
118 value.toString(strBuf, radix, isSigned, false, isUpperCase);
119 int strBufSize = static_cast<int>(strBuf.size());
120
121 int padWidth;
122 switch (radix) {
123 case 2:
124 padWidth = width;
125 break;
126 case 8:
127 padWidth = (width + 2) / 3;
128 break;
129 case 16:
130 padWidth = (width + 3) / 4;
131 break;
132 default:
133 padWidth = width;
134 break;
135 }
136
137 int numSpaces = 0;
138 if (specifierWidth >= 0 &&
139 (specifierWidth > std::max(padWidth, strBufSize))) {
140 numSpaces = std::max(0, specifierWidth - std::max(padWidth, strBufSize));
141 }
142
143 llvm::SmallVector<char, 1> spacePadding(numSpaces, ' ');
144
145 padWidth = padWidth > strBufSize ? padWidth - strBufSize : 0;
146
147 llvm::SmallVector<char, 32> padding(padWidth, paddingChar);
148
149 if (isLeftAligned) {
150 os << padding << strBuf << spacePadding;
151 } else {
152 os << spacePadding << padding << strBuf;
153 }
154}
155
156void arcRuntimeIR_format(const FmtDescriptor *fmt, ...) {
157 va_list args;
158 va_start(args, fmt);
159
160 llvm::raw_ostream &os = llvm::outs();
161 while (fmt->action != FmtDescriptor::Action_End) {
162 switch (fmt->action) {
164 std::string_view s(va_arg(args, const char *), fmt->literal.width);
165 os << s;
166 break;
167 }
169 std::string_view s(fmt->smallLiteral.data);
170 os << s;
171 break;
172 }
174 uint64_t *words = va_arg(args, uint64_t *);
175 int64_t numWords = llvm::divideCeil(fmt->intFmt.bitwidth, 64);
176 llvm::APInt apInt(fmt->intFmt.bitwidth, llvm::ArrayRef(words, numWords));
177 formatIntegersByRadix(os, fmt->intFmt.bitwidth, fmt->intFmt.radix, apInt,
180 fmt->intFmt.isSigned);
181 break;
182 }
184 os << static_cast<char>(va_arg(args, int));
185 break;
187 break;
188 }
189 fmt++;
190 }
191
192 va_end(args);
193}
194
195uint64_t *arcRuntimeIR_swapTraceBuffer(const uint8_t *modelState) {
196 auto *modPtr = static_cast<const uint8_t *>(modelState);
197 auto *statePtr =
198 reinterpret_cast<const ArcState *>(modPtr - sizeof(ArcState));
199 if (statePtr->magic != ARC_RUNTIME_MAGIC)
200 impl::fatalError("Incorrect magic number for state");
201 return getModelInstance(statePtr)->swapTraceBuffer();
202}
203
204#ifdef ARC_RUNTIME_JIT_BIND
205namespace circt::arc::runtime {
206
207static const APICallbacks apiCallbacksGlobal{
211
212const APICallbacks &getArcRuntimeAPICallbacks() { return apiCallbacksGlobal; }
213
214} // namespace circt::arc::runtime
215#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.
static void formatIntegersByRadix(llvm::raw_ostream &os, int width, int radix, const llvm::APInt &value, bool isUpperCase, bool isLeftAligned, char paddingChar, int specifierWidth, bool isSigned)
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)
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 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
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).