Loop Timing Witness
Native controller and runtime interfaces; hardware qualification pending
Toggle main menu visibility
Loading...
Searching...
No Matches
process_protocol.h
Go to the documentation of this file.
1
// SPDX-License-Identifier: AGPL-3.0-or-later
2
// Commercial license available
3
// © Concepts 1996–2026 Miroslav Šotek. All rights reserved.
4
// © Code 2020–2026 Miroslav Šotek. All rights reserved.
5
// ORCID: 0009-0009-3560-0851
6
// Contact: www.anulum.li | protoscience@anulum.li
7
// Loop Timing Witness — shared native register process protocol
8
12
13
#ifndef WITNESS_PROCESS_PROTOCOL_H
14
#define WITNESS_PROCESS_PROTOCOL_H
15
16
#include <charconv>
17
#include "
refusal.h
"
18
#include <cstdint>
19
#include <iostream>
20
#include <limits>
21
#include <sstream>
22
#include <stdexcept>
23
#include <string>
24
25
namespace
witness {
27
constexpr
std::uint64_t
advance_limit
= 10000000;
29
struct
ProtocolReply
{
30
unsigned
response
;
31
std::uint32_t
data
;
32
};
33
35
inline
std::uint64_t
number
(std::istream &input, std::uint64_t maximum) {
36
std::string token;
37
if
(!(input >> token) || token.find_first_not_of(
"0123456789"
) != std::string::npos)
38
throw
witness::RuntimeRefused
(
"invalid unsigned argument"
);
39
std::uint64_t value = 0;
40
const
auto
parsed = std::from_chars(token.data(), token.data() + token.size(), value);
41
if
(parsed.ec != std::errc{} || parsed.ptr != token.data() + token.size() || value > maximum)
42
throw
witness::RuntimeRefused
(
"argument outside range"
);
43
return
value;
44
}
45
47
inline
void
end_request
(std::istream &input) {
48
std::string extra;
49
if
(input >> extra)
50
throw
witness::RuntimeRefused
(
"unexpected argument"
);
51
}
52
53
template
<
class
Device>
int
serve
(Device &device) {
54
std::string line;
55
while
(std::getline(std::cin, line)) {
56
std::istringstream input(line);
57
std::string operation;
58
input >> operation;
59
ProtocolReply
result{};
60
if
(operation ==
"R"
) {
61
const
auto
address =
number
(input, 255);
62
end_request
(input);
63
const
auto
reply = device.read(
static_cast<
std::uint8_t
>
(address));
64
result = {reply.response, reply.data};
65
}
else
if
(operation ==
"W"
) {
66
const
auto
address =
number
(input, 255);
67
const
auto
data =
number
(input, std::numeric_limits<std::uint32_t>::max());
68
const
auto
strobes =
number
(input, 15);
69
end_request
(input);
70
const
auto
reply =
71
device.write(
static_cast<
std::uint8_t
>
(address),
static_cast<
std::uint32_t
>
(data),
72
static_cast<
std::uint8_t
>
(strobes));
73
result = {reply.response, reply.data};
74
result.
data
= 0;
75
}
else
if
(operation ==
"T"
|| operation ==
"I"
) {
76
const
auto
duration =
number
(input,
advance_limit
);
77
end_request
(input);
78
if
(operation ==
"T"
)
79
device.advance(duration);
80
else
81
result.
data
= device.wait_interrupt(duration);
82
}
else
if
(operation ==
"Q"
) {
83
end_request
(input);
84
return
0;
85
}
else
86
throw
witness::RuntimeRefused
(
"unknown request"
);
87
std::cout << result.
response
<<
','
<< result.
data
<<
','
<< device.time() << std::endl;
88
if
(!std::cout)
89
throw
witness::RuntimeRefused
(
"cannot write AXI response"
);
90
}
91
if
(!std::cin.eof())
92
throw
witness::RuntimeRefused
(
"cannot read AXI request"
);
93
return
0;
94
}
95
}
// namespace witness
102
103
#endif
witness::RuntimeRefused
Definition
refusal.h:19
witness::number
std::uint64_t number(std::istream &input, std::uint64_t maximum)
Definition
process_protocol.h:35
witness::end_request
void end_request(std::istream &input)
Definition
process_protocol.h:47
witness::serve
int serve(Device &device)
Definition
process_protocol.h:53
witness::advance_limit
constexpr std::uint64_t advance_limit
Definition
process_protocol.h:27
refusal.h
witness::ProtocolReply
Definition
process_protocol.h:29
witness::ProtocolReply::response
unsigned response
Definition
process_protocol.h:30
witness::ProtocolReply::data
std::uint32_t data
Definition
process_protocol.h:31
runtime
process_protocol.h
Generated by
1.18.0