cocotb 1.9.2__cp37-cp37m-win_amd64.whl → 2.0.0rc2__cp37-cp37m-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cocotb might be problematic. Click here for more details.
- cocotb/_ANSI.py +65 -0
- cocotb/__init__.py +81 -327
- cocotb/_base_triggers.py +515 -0
- cocotb/_bridge.py +186 -0
- cocotb/_decorators.py +515 -0
- cocotb/_deprecation.py +3 -3
- cocotb/_exceptions.py +7 -0
- cocotb/_extended_awaitables.py +419 -0
- cocotb/_gpi_triggers.py +385 -0
- cocotb/_init.py +301 -0
- cocotb/_outcomes.py +54 -0
- cocotb/_profiling.py +46 -0
- cocotb/_py_compat.py +114 -29
- cocotb/_scheduler.py +448 -0
- cocotb/_test.py +248 -0
- cocotb/_test_factory.py +312 -0
- cocotb/_test_functions.py +42 -0
- cocotb/_typing.py +7 -0
- cocotb/_utils.py +274 -0
- cocotb/_version.py +3 -7
- cocotb/_xunit_reporter.py +66 -0
- cocotb/clock.py +353 -108
- cocotb/debug.py +24 -0
- cocotb/handle.py +1370 -793
- cocotb/libs/cocotb.dll +0 -0
- cocotb/libs/cocotb.exp +0 -0
- cocotb/libs/cocotb.lib +0 -0
- cocotb/libs/cocotbfli_modelsim.dll +0 -0
- cocotb/libs/cocotbfli_modelsim.exp +0 -0
- cocotb/libs/cocotbfli_modelsim.lib +0 -0
- cocotb/libs/cocotbutils.dll +0 -0
- cocotb/libs/cocotbutils.exp +0 -0
- cocotb/libs/cocotbutils.lib +0 -0
- cocotb/libs/cocotbvhpi_aldec.dll +0 -0
- cocotb/libs/cocotbvhpi_aldec.exp +0 -0
- cocotb/libs/cocotbvhpi_aldec.lib +0 -0
- cocotb/libs/cocotbvhpi_modelsim.dll +0 -0
- cocotb/libs/cocotbvhpi_modelsim.exp +0 -0
- cocotb/libs/cocotbvhpi_modelsim.lib +0 -0
- cocotb/libs/cocotbvpi_aldec.dll +0 -0
- cocotb/libs/cocotbvpi_aldec.exp +0 -0
- cocotb/libs/cocotbvpi_aldec.lib +0 -0
- cocotb/libs/cocotbvpi_ghdl.dll +0 -0
- cocotb/libs/cocotbvpi_ghdl.exp +0 -0
- cocotb/libs/cocotbvpi_ghdl.lib +0 -0
- cocotb/libs/cocotbvpi_icarus.exp +0 -0
- cocotb/libs/cocotbvpi_icarus.lib +0 -0
- cocotb/libs/cocotbvpi_icarus.vpl +0 -0
- cocotb/libs/cocotbvpi_modelsim.dll +0 -0
- cocotb/libs/cocotbvpi_modelsim.exp +0 -0
- cocotb/libs/cocotbvpi_modelsim.lib +0 -0
- cocotb/libs/embed.dll +0 -0
- cocotb/libs/embed.exp +0 -0
- cocotb/libs/embed.lib +0 -0
- cocotb/libs/gpi.dll +0 -0
- cocotb/libs/gpi.exp +0 -0
- cocotb/libs/gpi.lib +0 -0
- cocotb/libs/gpilog.dll +0 -0
- cocotb/libs/gpilog.exp +0 -0
- cocotb/libs/gpilog.lib +0 -0
- cocotb/libs/pygpilog.dll +0 -0
- cocotb/libs/pygpilog.exp +0 -0
- cocotb/libs/pygpilog.lib +0 -0
- cocotb/logging.py +424 -0
- cocotb/queue.py +103 -57
- cocotb/regression.py +680 -717
- cocotb/result.py +17 -188
- cocotb/share/def/aldec.exp +0 -0
- cocotb/share/def/aldec.lib +0 -0
- cocotb/share/def/ghdl.exp +0 -0
- cocotb/share/def/ghdl.lib +0 -0
- cocotb/share/def/icarus.exp +0 -0
- cocotb/share/def/icarus.lib +0 -0
- cocotb/share/def/modelsim.def +1 -0
- cocotb/share/def/modelsim.exp +0 -0
- cocotb/share/def/modelsim.lib +0 -0
- cocotb/share/include/cocotb_utils.h +9 -32
- cocotb/share/include/embed.h +7 -30
- cocotb/share/include/gpi.h +331 -137
- cocotb/share/include/gpi_logging.h +221 -142
- cocotb/share/include/py_gpi_logging.h +8 -5
- cocotb/share/include/vpi_user_ext.h +4 -26
- cocotb/share/lib/verilator/verilator.cpp +80 -67
- cocotb/simtime.py +230 -0
- cocotb/simulator.cp37-win_amd64.exp +0 -0
- cocotb/simulator.cp37-win_amd64.lib +0 -0
- cocotb/simulator.cp37-win_amd64.pyd +0 -0
- cocotb/task.py +478 -213
- cocotb/triggers.py +55 -1092
- cocotb/types/__init__.py +28 -47
- cocotb/types/_abstract_array.py +151 -0
- cocotb/types/_array.py +295 -0
- cocotb/types/_indexing.py +17 -0
- cocotb/types/_logic.py +333 -0
- cocotb/types/_logic_array.py +868 -0
- cocotb/types/{range.py → _range.py} +47 -48
- cocotb/types/_resolve.py +76 -0
- cocotb/utils.py +58 -646
- {cocotb-1.9.2.dist-info → cocotb-2.0.0rc2.dist-info}/LICENSE +1 -0
- cocotb-2.0.0rc2.dist-info/METADATA +46 -0
- cocotb-2.0.0rc2.dist-info/RECORD +142 -0
- cocotb-2.0.0rc2.dist-info/entry_points.txt +2 -0
- {cocotb-1.9.2.dist-info → cocotb-2.0.0rc2.dist-info}/top_level.txt +1 -0
- cocotb_tools/_coverage.py +33 -0
- cocotb_tools/_vendor/__init__.py +3 -0
- cocotb_tools/check_results.py +65 -0
- cocotb_tools/combine_results.py +152 -0
- cocotb_tools/config.py +241 -0
- {cocotb → cocotb_tools}/ipython_support.py +29 -22
- cocotb_tools/makefiles/Makefile.deprecations +27 -0
- {cocotb/share → cocotb_tools}/makefiles/Makefile.inc +77 -55
- {cocotb/share → cocotb_tools}/makefiles/Makefile.sim +16 -33
- {cocotb/share → cocotb_tools}/makefiles/simulators/Makefile.activehdl +9 -16
- cocotb_tools/makefiles/simulators/Makefile.cvc +61 -0
- cocotb_tools/makefiles/simulators/Makefile.dsim +39 -0
- {cocotb/share → cocotb_tools}/makefiles/simulators/Makefile.ghdl +13 -42
- cocotb_tools/makefiles/simulators/Makefile.icarus +80 -0
- cocotb_tools/makefiles/simulators/Makefile.ius +93 -0
- cocotb_tools/makefiles/simulators/Makefile.modelsim +9 -0
- cocotb_tools/makefiles/simulators/Makefile.nvc +60 -0
- cocotb_tools/makefiles/simulators/Makefile.questa +29 -0
- cocotb/share/makefiles/simulators/Makefile.questa → cocotb_tools/makefiles/simulators/Makefile.questa-compat +26 -54
- cocotb_tools/makefiles/simulators/Makefile.questa-qisqrun +149 -0
- {cocotb/share → cocotb_tools}/makefiles/simulators/Makefile.riviera +17 -56
- cocotb_tools/makefiles/simulators/Makefile.vcs +65 -0
- {cocotb/share → cocotb_tools}/makefiles/simulators/Makefile.verilator +15 -22
- {cocotb/share → cocotb_tools}/makefiles/simulators/Makefile.xcelium +20 -52
- cocotb_tools/runner.py +1868 -0
- cocotb/_sim_versions.py → cocotb_tools/sim_versions.py +16 -21
- pygpi/entry.py +34 -18
- cocotb/ANSI.py +0 -92
- cocotb/binary.py +0 -858
- cocotb/config.py +0 -289
- cocotb/decorators.py +0 -332
- cocotb/log.py +0 -303
- cocotb/memdebug.py +0 -35
- cocotb/outcomes.py +0 -56
- cocotb/runner.py +0 -1400
- cocotb/scheduler.py +0 -1099
- cocotb/share/makefiles/Makefile.deprecations +0 -12
- cocotb/share/makefiles/simulators/Makefile.cvc +0 -94
- cocotb/share/makefiles/simulators/Makefile.icarus +0 -111
- cocotb/share/makefiles/simulators/Makefile.ius +0 -125
- cocotb/share/makefiles/simulators/Makefile.modelsim +0 -32
- cocotb/share/makefiles/simulators/Makefile.nvc +0 -64
- cocotb/share/makefiles/simulators/Makefile.vcs +0 -98
- cocotb/types/array.py +0 -309
- cocotb/types/logic.py +0 -292
- cocotb/types/logic_array.py +0 -298
- cocotb/wavedrom.py +0 -199
- cocotb/xunit_reporter.py +0 -80
- cocotb-1.9.2.dist-info/METADATA +0 -168
- cocotb-1.9.2.dist-info/RECORD +0 -121
- cocotb-1.9.2.dist-info/entry_points.txt +0 -2
- {cocotb-1.9.2.dist-info → cocotb-2.0.0rc2.dist-info}/WHEEL +0 -0
- {cocotb/_vendor → cocotb_tools}/__init__.py +0 -0
- {cocotb → cocotb_tools}/_vendor/distutils_version.py +0 -0
|
@@ -20,9 +20,12 @@
|
|
|
20
20
|
#if VM_TRACE
|
|
21
21
|
#if VM_TRACE_FST
|
|
22
22
|
#include <verilated_fst_c.h>
|
|
23
|
+
using verilated_trace_t = VerilatedFstC;
|
|
23
24
|
#else
|
|
24
25
|
#include <verilated_vcd_c.h>
|
|
26
|
+
using verilated_trace_t = VerilatedVcdC;
|
|
25
27
|
#endif
|
|
28
|
+
static verilated_trace_t *tfp;
|
|
26
29
|
#endif
|
|
27
30
|
|
|
28
31
|
static vluint64_t main_time = 0; // Current simulation time
|
|
@@ -50,18 +53,46 @@ static inline bool settle_value_callbacks() {
|
|
|
50
53
|
return cbs_called;
|
|
51
54
|
}
|
|
52
55
|
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
void wrap_up() {
|
|
57
|
+
VerilatedVpi::callCbs(cbEndOfSimulation);
|
|
58
|
+
|
|
59
|
+
#if VM_TRACE
|
|
60
|
+
if (tfp) {
|
|
61
|
+
delete tfp;
|
|
62
|
+
tfp = nullptr;
|
|
63
|
+
}
|
|
64
|
+
#endif
|
|
65
|
+
|
|
66
|
+
// VM_COVERAGE is a define which is set if Verilator is
|
|
67
|
+
// instructed to collect coverage (when compiling the simulation)
|
|
68
|
+
#if VM_COVERAGE
|
|
69
|
+
VerilatedCov::write(); // Uses +verilator+coverage+file+<filename>,
|
|
70
|
+
// defaults to coverage.dat
|
|
71
|
+
#endif
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
int main(int argc, char **argv) {
|
|
55
75
|
#if VM_TRACE_FST
|
|
56
|
-
const char*
|
|
76
|
+
const char *traceFile = "dump.fst";
|
|
57
77
|
#else
|
|
58
|
-
const char*
|
|
78
|
+
const char *traceFile = "dump.vcd";
|
|
59
79
|
#endif
|
|
80
|
+
bool traceOn = false;
|
|
81
|
+
bool traceFlush = false;
|
|
60
82
|
|
|
61
83
|
for (int i = 1; i < argc; i++) {
|
|
62
84
|
std::string arg = std::string(argv[i]);
|
|
63
85
|
if (arg == "--trace") {
|
|
86
|
+
#if VM_TRACE
|
|
64
87
|
traceOn = true;
|
|
88
|
+
#else
|
|
89
|
+
fprintf(stderr,
|
|
90
|
+
"Error: --trace requires the design to be built with trace "
|
|
91
|
+
"support\n");
|
|
92
|
+
return -1;
|
|
93
|
+
#endif
|
|
94
|
+
} else if (arg == "--trace-flush") {
|
|
95
|
+
traceFlush = true;
|
|
65
96
|
} else if (arg == "--trace-file") {
|
|
66
97
|
if (++i < argc) {
|
|
67
98
|
traceFile = argv[i];
|
|
@@ -70,16 +101,18 @@ int main(int argc, char** argv) {
|
|
|
70
101
|
return -1;
|
|
71
102
|
}
|
|
72
103
|
} else if (arg == "--help") {
|
|
73
|
-
fprintf(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
104
|
+
fprintf(
|
|
105
|
+
stderr,
|
|
106
|
+
"usage: %s [--trace] [--trace-flush] [--trace-file TRACEFILE]\n"
|
|
107
|
+
"\n"
|
|
108
|
+
"cocotb + Verilator sim\n"
|
|
109
|
+
"\n"
|
|
110
|
+
"options:\n"
|
|
111
|
+
" --trace Enable tracing (VCD or FST)\n"
|
|
112
|
+
" --trace-flush Flush trace at each time step (slow)\n"
|
|
113
|
+
" --trace-file Specify the trace file name (%s by "
|
|
114
|
+
"default)\n",
|
|
115
|
+
basename(argv[0]), traceFile);
|
|
83
116
|
return 0;
|
|
84
117
|
}
|
|
85
118
|
}
|
|
@@ -95,58 +128,48 @@ int main(int argc, char** argv) {
|
|
|
95
128
|
Verilated::internalsDump();
|
|
96
129
|
#endif
|
|
97
130
|
|
|
98
|
-
vlog_startup_routines_bootstrap();
|
|
99
|
-
VerilatedVpi::callCbs(cbStartOfSimulation);
|
|
100
|
-
|
|
101
131
|
#if VM_TRACE
|
|
102
|
-
|
|
103
|
-
std::unique_ptr<VerilatedFstC> tfp(new VerilatedFstC);
|
|
104
|
-
#else
|
|
105
|
-
std::unique_ptr<VerilatedVcdC> tfp(new VerilatedVcdC);
|
|
106
|
-
#endif
|
|
107
|
-
|
|
132
|
+
Verilated::traceEverOn(true);
|
|
108
133
|
if (traceOn) {
|
|
109
|
-
|
|
110
|
-
top->trace(tfp
|
|
134
|
+
tfp = new verilated_trace_t;
|
|
135
|
+
top->trace(tfp, 99);
|
|
111
136
|
tfp->open(traceFile);
|
|
112
137
|
}
|
|
113
138
|
#endif
|
|
114
139
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
VerilatedVpi::callTimedCbs();
|
|
120
|
-
|
|
121
|
-
// Call Value Change callbacks triggered by Timer callbacks
|
|
122
|
-
// These can modify signal values
|
|
123
|
-
settle_value_callbacks();
|
|
124
|
-
|
|
125
|
-
// We must evaluate whole design until we process all 'events'
|
|
126
|
-
bool again = true;
|
|
127
|
-
while (again) {
|
|
128
|
-
// Evaluate design
|
|
129
|
-
top->eval_step();
|
|
130
|
-
|
|
131
|
-
// Call Value Change callbacks triggered by eval()
|
|
132
|
-
// These can modify signal values
|
|
133
|
-
again = settle_value_callbacks();
|
|
140
|
+
vlog_startup_routines_bootstrap();
|
|
141
|
+
Verilated::addExitCb([](void *) { wrap_up(); }, nullptr);
|
|
142
|
+
VerilatedVpi::callCbs(cbStartOfSimulation);
|
|
143
|
+
settle_value_callbacks();
|
|
134
144
|
|
|
135
|
-
|
|
136
|
-
|
|
145
|
+
while (!Verilated::gotFinish()) {
|
|
146
|
+
do {
|
|
147
|
+
// We must evaluate whole design until we process all 'events' for
|
|
148
|
+
// this time step
|
|
149
|
+
do {
|
|
150
|
+
top->eval_step();
|
|
151
|
+
VerilatedVpi::clearEvalNeeded();
|
|
152
|
+
VerilatedVpi::doInertialPuts();
|
|
153
|
+
settle_value_callbacks();
|
|
154
|
+
} while (VerilatedVpi::evalNeeded());
|
|
155
|
+
|
|
156
|
+
// Run ReadWrite callback as we are done processing this eval step
|
|
157
|
+
VerilatedVpi::callCbs(cbReadWriteSynch);
|
|
158
|
+
VerilatedVpi::doInertialPuts();
|
|
159
|
+
settle_value_callbacks();
|
|
160
|
+
} while (VerilatedVpi::evalNeeded());
|
|
137
161
|
|
|
138
|
-
// Call Value Change callbacks triggered by ReadWrite callbacks
|
|
139
|
-
// These can modify signal values
|
|
140
|
-
again |= settle_value_callbacks();
|
|
141
|
-
}
|
|
142
162
|
top->eval_end_step();
|
|
143
163
|
|
|
144
164
|
// Call ReadOnly callbacks
|
|
145
165
|
VerilatedVpi::callCbs(cbReadOnlySynch);
|
|
146
166
|
|
|
147
167
|
#if VM_TRACE
|
|
148
|
-
if (
|
|
168
|
+
if (tfp) {
|
|
149
169
|
tfp->dump(main_time);
|
|
170
|
+
if (traceFlush) {
|
|
171
|
+
tfp->flush();
|
|
172
|
+
}
|
|
150
173
|
}
|
|
151
174
|
#endif
|
|
152
175
|
// cocotb controls the clock inputs using cbAfterDelay so
|
|
@@ -169,28 +192,18 @@ int main(int argc, char** argv) {
|
|
|
169
192
|
// It should be called in simulation cycle before everything else
|
|
170
193
|
// but not on first cycle
|
|
171
194
|
VerilatedVpi::callCbs(cbNextSimTime);
|
|
195
|
+
settle_value_callbacks();
|
|
172
196
|
|
|
173
|
-
// Call
|
|
174
|
-
// These
|
|
197
|
+
// Call registered timed callbacks (e.g. clock timer)
|
|
198
|
+
// These are called at the beginning of the time step
|
|
199
|
+
// before the iterative regions (IEEE 1800-2012 4.4.1)
|
|
200
|
+
VerilatedVpi::callTimedCbs();
|
|
175
201
|
settle_value_callbacks();
|
|
176
202
|
}
|
|
177
203
|
|
|
178
|
-
VerilatedVpi::callCbs(cbEndOfSimulation);
|
|
179
|
-
|
|
180
204
|
top->final();
|
|
181
205
|
|
|
182
|
-
|
|
183
|
-
if (traceOn) {
|
|
184
|
-
tfp->close();
|
|
185
|
-
}
|
|
186
|
-
#endif
|
|
187
|
-
|
|
188
|
-
// VM_COVERAGE is a define which is set if Verilator is
|
|
189
|
-
// instructed to collect coverage (when compiling the simulation)
|
|
190
|
-
#if VM_COVERAGE
|
|
191
|
-
VerilatedCov::write(); // Uses +verilator+coverage+file+<filename>,
|
|
192
|
-
// defaults to coverage.dat
|
|
193
|
-
#endif
|
|
206
|
+
wrap_up();
|
|
194
207
|
|
|
195
208
|
return 0;
|
|
196
209
|
}
|
cocotb/simtime.py
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# Copyright cocotb contributors
|
|
2
|
+
# Copyright (c) 2013 Potential Ventures Ltd
|
|
3
|
+
# Copyright (c) 2013 SolarFlare Communications Inc
|
|
4
|
+
# Licensed under the Revised BSD License, see LICENSE for details.
|
|
5
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
|
6
|
+
|
|
7
|
+
"""Tools for dealing with simulated time."""
|
|
8
|
+
|
|
9
|
+
import warnings
|
|
10
|
+
from decimal import Decimal
|
|
11
|
+
from fractions import Fraction
|
|
12
|
+
from functools import lru_cache
|
|
13
|
+
from math import ceil, floor
|
|
14
|
+
from typing import Union, cast, overload
|
|
15
|
+
|
|
16
|
+
from cocotb import simulator
|
|
17
|
+
from cocotb._py_compat import Literal, TypeAlias
|
|
18
|
+
from cocotb._typing import RoundMode, TimeUnit
|
|
19
|
+
|
|
20
|
+
__all__ = (
|
|
21
|
+
"convert",
|
|
22
|
+
"get_sim_time",
|
|
23
|
+
"time_precision",
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
Steps: TypeAlias = Literal["step"]
|
|
28
|
+
TimeUnitWithoutSteps: TypeAlias = Literal["fs", "ps", "ns", "us", "ms", "sec"]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@overload
|
|
32
|
+
def convert(
|
|
33
|
+
value: Union[float, Fraction, Decimal],
|
|
34
|
+
unit: TimeUnit,
|
|
35
|
+
*,
|
|
36
|
+
to: Steps,
|
|
37
|
+
round_mode: RoundMode = "error",
|
|
38
|
+
) -> int: ...
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@overload
|
|
42
|
+
def convert(
|
|
43
|
+
value: Union[float, Fraction, Decimal],
|
|
44
|
+
unit: TimeUnit,
|
|
45
|
+
*,
|
|
46
|
+
to: TimeUnitWithoutSteps,
|
|
47
|
+
round_mode: RoundMode = "error",
|
|
48
|
+
) -> float: ...
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def convert(
|
|
52
|
+
value: Union[float, Decimal, Fraction],
|
|
53
|
+
unit: TimeUnit,
|
|
54
|
+
*,
|
|
55
|
+
to: TimeUnit,
|
|
56
|
+
round_mode: RoundMode = "error",
|
|
57
|
+
) -> float:
|
|
58
|
+
"""Convert time values from one unit to another unit.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
value: The time value.
|
|
62
|
+
|
|
63
|
+
unit: The unit of *value* (one of ``'step'``, ``'fs'``, ``'ps'``, ``'ns'``, ``'us'``, ``'ms'``, ``'sec'``).
|
|
64
|
+
|
|
65
|
+
to: The unit to convert *value* to (one of ``'step'``, ``'fs'``, ``'ps'``, ``'ns'``, ``'us'``, ``'ms'``, ``'sec'``).
|
|
66
|
+
|
|
67
|
+
round_mode:
|
|
68
|
+
How to handle non-integral step values (one of ``'error'``, ``'round'``, ``'ceil'``, ``'floor'``).
|
|
69
|
+
|
|
70
|
+
When *round_mode* is ``"error"``, a :exc:`ValueError` is thrown if the value cannot
|
|
71
|
+
be accurately represented in terms of simulator time steps.
|
|
72
|
+
When *round_mode* is ``"round"``, ``"ceil"``, or ``"floor"``, the corresponding
|
|
73
|
+
rounding function from the standard library will be used to round to a simulator
|
|
74
|
+
time step.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
The value scaled by the difference in units.
|
|
78
|
+
|
|
79
|
+
.. versionadded:: 2.0
|
|
80
|
+
"""
|
|
81
|
+
if unit == "step":
|
|
82
|
+
steps = cast("int", value)
|
|
83
|
+
else:
|
|
84
|
+
steps = _get_sim_steps(value, unit, round_mode=round_mode)
|
|
85
|
+
if to == "step":
|
|
86
|
+
return steps
|
|
87
|
+
else:
|
|
88
|
+
return _get_time_from_sim_steps(steps, to)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def get_sim_time(unit: TimeUnit = "step", *, units: None = None) -> float:
|
|
92
|
+
"""Retrieve the simulation time from the simulator.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
unit: String specifying the unit of the result
|
|
96
|
+
(one of ``'step'``, ``'fs'``, ``'ps'``, ``'ns'``, ``'us'``, ``'ms'``, ``'sec'``).
|
|
97
|
+
``'step'`` will return the raw simulation time.
|
|
98
|
+
|
|
99
|
+
.. versionchanged:: 2.0
|
|
100
|
+
Passing ``None`` as the *unit* argument was removed, use ``'step'`` instead.
|
|
101
|
+
|
|
102
|
+
.. versionchanged:: 2.0
|
|
103
|
+
Renamed from ``units``.
|
|
104
|
+
|
|
105
|
+
Raises:
|
|
106
|
+
ValueError: If *unit* is not a valid unit.
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
The simulation time in the specified unit.
|
|
110
|
+
|
|
111
|
+
.. versionchanged:: 1.6
|
|
112
|
+
Support ``'step'`` as the the *unit* argument to mean "simulator time step".
|
|
113
|
+
|
|
114
|
+
.. versionchanged:: 2.0
|
|
115
|
+
Moved from :mod:`cocotb.utils` to :mod:`cocotb.simtime`.
|
|
116
|
+
"""
|
|
117
|
+
if units is not None:
|
|
118
|
+
warnings.warn(
|
|
119
|
+
"The 'units' argument has been renamed to 'unit'.",
|
|
120
|
+
DeprecationWarning,
|
|
121
|
+
stacklevel=2,
|
|
122
|
+
)
|
|
123
|
+
unit = units
|
|
124
|
+
timeh, timel = simulator.get_sim_time()
|
|
125
|
+
steps = timeh << 32 | timel
|
|
126
|
+
return _get_time_from_sim_steps(steps, unit) if unit != "step" else steps
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
@overload
|
|
130
|
+
def _ldexp10(frac: float, exp: int) -> float: ...
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@overload
|
|
134
|
+
def _ldexp10(frac: Fraction, exp: int) -> Fraction: ...
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
@overload
|
|
138
|
+
def _ldexp10(frac: Decimal, exp: int) -> Decimal: ...
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def _ldexp10(
|
|
142
|
+
frac: Union[float, Fraction, Decimal], exp: int
|
|
143
|
+
) -> Union[float, Fraction, Decimal]:
|
|
144
|
+
"""Like :func:`math.ldexp`, but base 10."""
|
|
145
|
+
# using * or / separately prevents rounding errors if `frac` is a
|
|
146
|
+
# high-precision type
|
|
147
|
+
if exp > 0:
|
|
148
|
+
return frac * (10**exp)
|
|
149
|
+
else:
|
|
150
|
+
return frac / (10**-exp)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def _get_time_from_sim_steps(
|
|
154
|
+
steps: int,
|
|
155
|
+
unit: TimeUnit,
|
|
156
|
+
) -> float:
|
|
157
|
+
if unit == "step":
|
|
158
|
+
return steps
|
|
159
|
+
return _ldexp10(steps, time_precision - _get_log_time_scale(unit))
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def _get_sim_steps(
|
|
163
|
+
time: Union[float, Fraction, Decimal],
|
|
164
|
+
unit: TimeUnit = "step",
|
|
165
|
+
*,
|
|
166
|
+
round_mode: RoundMode = "error",
|
|
167
|
+
) -> int:
|
|
168
|
+
result: Union[float, Fraction, Decimal]
|
|
169
|
+
if unit != "step":
|
|
170
|
+
result = _ldexp10(time, _get_log_time_scale(unit) - time_precision)
|
|
171
|
+
else:
|
|
172
|
+
result = time
|
|
173
|
+
|
|
174
|
+
if round_mode == "error":
|
|
175
|
+
result_rounded = floor(result)
|
|
176
|
+
if result_rounded != result:
|
|
177
|
+
raise ValueError(
|
|
178
|
+
f"Unable to accurately represent {time}({unit}) with the simulator precision of 1e{time_precision}"
|
|
179
|
+
)
|
|
180
|
+
elif round_mode == "ceil":
|
|
181
|
+
result_rounded = ceil(result)
|
|
182
|
+
elif round_mode == "round":
|
|
183
|
+
result_rounded = round(result)
|
|
184
|
+
elif round_mode == "floor":
|
|
185
|
+
result_rounded = floor(result)
|
|
186
|
+
else:
|
|
187
|
+
raise ValueError(f"Invalid round_mode specifier: {round_mode}")
|
|
188
|
+
|
|
189
|
+
return result_rounded
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
@lru_cache(maxsize=None)
|
|
193
|
+
def _get_log_time_scale(unit: TimeUnitWithoutSteps) -> int:
|
|
194
|
+
"""Retrieve the ``log10()`` of the scale factor for a given time unit.
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
unit: String specifying the unit
|
|
198
|
+
(one of ``'fs'``, ``'ps'``, ``'ns'``, ``'us'``, ``'ms'``, ``'sec'``).
|
|
199
|
+
|
|
200
|
+
.. versionchanged:: 2.0
|
|
201
|
+
Renamed from ``units``.
|
|
202
|
+
|
|
203
|
+
Raises:
|
|
204
|
+
ValueError: If *unit* is not a valid unit.
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
The ``log10()`` of the scale factor for the time unit.
|
|
208
|
+
"""
|
|
209
|
+
scale = {"fs": -15, "ps": -12, "ns": -9, "us": -6, "ms": -3, "sec": 0}
|
|
210
|
+
|
|
211
|
+
unit_lwr = unit.lower()
|
|
212
|
+
if unit_lwr not in scale:
|
|
213
|
+
raise ValueError(f"Invalid unit ({unit}) provided")
|
|
214
|
+
else:
|
|
215
|
+
return scale[unit_lwr]
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
time_precision: int = _get_log_time_scale("fs")
|
|
219
|
+
"""The precision of time in the current simulation.
|
|
220
|
+
|
|
221
|
+
The value is seconds in powers of tens,
|
|
222
|
+
i.e. ``-15`` is ``10**-15`` seconds or 1 femtosecond.
|
|
223
|
+
|
|
224
|
+
.. versionadded:: 2.0
|
|
225
|
+
"""
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def _init() -> None:
|
|
229
|
+
global time_precision
|
|
230
|
+
time_precision = simulator.get_precision()
|
|
Binary file
|
|
Binary file
|
|
Binary file
|