9_fpga
Store definition
ExampleFpga
// SPDX-FileCopyrightText: 2020-2023 Jochem Rutgers
//
// SPDX-License-Identifier: CC0-1.0
// Any store definition is compatible with the FPGA, but there are a few
// details to mention.
// For a C++ target, /t would be a function, which is read-only. Functions
// are, however, not supported on FPGA, and will be silently ignored from the
// store VHDL file. Moreover, there is no Embedded Debugger that can be
// connected to the FPGA; it has only the synchronizer interface. A read-only
// register simply just updates it data very clock cycle.
uint32 t (clk)
(int32) ignored function
uint32 default register
uint32=101 initialized register
uint16 read-only register
uint32 default register write count
// Any data type is supported, but the AXI interface only gives access
// to variables of at most 32-bit. All others are available in the
// direct interface, but not via AXI.
bool bool
string:6 string
blob:3 blob
ExampleFpga2
// SPDX-FileCopyrightText: 2020-2023 Jochem Rutgers
//
// SPDX-License-Identifier: CC0-1.0
// I assume that the FPGA has only one Synchronizer interface,
// which is likely to be a UART, or otherwise byte-oriented stream.
// If there are multiple stores in the FPGA, like one store per module in the FPGA,
// as that matches nicely to the same amount of AXI slaves, they are daisy chained,
// such that this single UART/Synchronizer interface can access both.
int8 other store's int8
Application
// SPDX-FileCopyrightText: 2020-2024 Jochem Rutgers
//
// SPDX-License-Identifier: CC0-1.0
/*!
* \file
* \brief Example to show how to use libstored in VHDL.
*
* This is the C++ application, which can be used as a bridge between the VHDL
* simulation and a Debugger client, using named pipes.
*/
#include "ExampleFpga.h"
#include "ExampleFpga2.h"
#include <stored>
class ExampleFpga : public STORE_T(
ExampleFpga, stored::ExampleFpgaDefaultFunctions,
stored::Synchronizable, stored::ExampleFpgaBase) {
STORE_CLASS(
ExampleFpga, stored::ExampleFpgaDefaultFunctions, stored::Synchronizable,
stored::ExampleFpgaBase)
public:
ExampleFpga() is_default
};
class ExampleFpga2 : public STORE_T(
ExampleFpga2, stored::ExampleFpga2DefaultFunctions,
stored::Synchronizable, stored::ExampleFpga2Base) {
STORE_CLASS(
ExampleFpga2, stored::ExampleFpga2DefaultFunctions, stored::Synchronizable,
stored::ExampleFpga2Base)
public:
ExampleFpga2() is_default
};
int main(int argc, char** argv)
{
puts(stored::banner());
ExampleFpga exampleFpga;
ExampleFpga2 exampleFpga2;
stored::Debugger debugger("9_fpga");
debugger.map(exampleFpga, "/ExampleFpga");
debugger.map(exampleFpga2, "/ExampleFpga2");
stored::DebugZmqLayer zmq;
zmq.wrap(debugger);
if((errno = zmq.lastError())) {
perror("Cannot initialize ZMQ");
return 1;
}
stored::Synchronizer synchronizer;
synchronizer.map(exampleFpga);
synchronizer.map(exampleFpga2);
stored::SegmentationLayer segmentation(24);
synchronizer.connect(segmentation);
stored::ArqLayer arq;
arq.wrap(segmentation);
stored::Crc16Layer crc;
crc.wrap(arq);
stored::AsciiEscapeLayer ascii;
ascii.wrap(crc);
stored::TerminalLayer term;
term.wrap(ascii);
#ifdef STORED_OS_WINDOWS
stored::XsimLayer xsim("9_fpga");
#else
stored::XsimLayer xsim("/tmp/9_fpga");
#endif
xsim.wrap(term);
stored::PrintLayer print(stdout);
int verbose = 0;
for(int i = 1; i < argc; i++) {
if(strcmp(argv[i], "-v") == 0)
verbose++;
}
switch(verbose) {
case 1:
print.stack(segmentation);
break;
case 2:
print.wrap(segmentation);
break;
case 3:
print.wrap(arq);
break;
case 4:
print.wrap(crc);
break;
case 5:
print.wrap(ascii);
break;
case 6:
print.wrap(term);
break;
case 0:
default:;
}
if((errno = xsim.lastError()) && errno != EAGAIN) {
perror("Cannot initialize XSIM interface");
return 1;
}
printf("\n"
"Start XSIM with the 9_fpga example. It connects to this application.\n"
"Use a Debugger client to see interaction with the VHDL simulation.\n");
stored::Poller poller;
stored::PollableFileLayer xsimp(xsim, stored::Pollable::PollIn);
stored::PollableFileLayer xsimreqp(xsim.req(), stored::Pollable::PollIn);
stored::PollableZmqLayer zmqp(zmq, stored::Pollable::PollIn);
if((errno = poller.add(xsimp)) || (errno = poller.add(xsimreqp))
|| (errno = poller.add(zmqp))) {
perror("Cannot initialize poller");
return 1;
}
while(true) {
// 1 s timeout, to force keep alive once in a while.
stored::Poller::Result const& result = poller.poll(1000);
if(result.empty()) {
switch(errno) {
case EAGAIN:
case EINTR:
break;
default:
perror("poll failed");
return 1;
}
}
zmq.recv();
xsim.recv();
synchronizer.process();
// Inject a dummy byte to keep xsim alive, as it blocks on a read from file.
xsim.keepAlive();
}
}
FPGA
-- SPDX-FileCopyrightText: 2020-2023 Jochem Rutgers
--
-- SPDX-License-Identifier: CC0-1.0
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.libstored_pkg.all;
use work.ExampleFpga_pkg;
use work.ExampleFpga2_pkg;
entity example_9_fpga is
generic (
SYSTEM_CLK_FREQ : integer := 100e6;
SIMULATION : boolean := false
--pragma translate_off
or true
--pragma translate_on
);
port (
clk : in std_logic;
rstn : in std_logic;
rx : in std_logic := '1';
tx : out std_logic;
cts : in std_logic := '0';
rts : out std_logic
);
end entity;
architecture rtl of example_9_fpga is
function var_access return ExampleFpga_pkg.var_access_t is
variable v : ExampleFpga_pkg.var_access_t;
begin
v := ExampleFpga_pkg.VAR_ACCESS_RW;
-- Save some LUTs by limiting how we are going to access these variables.
v.\t (clk)\ := ACCESS_WO;
v.\default register write count\ := ACCESS_WO;
v.\read-only register\ := ACCESS_RO;
return v;
end function;
signal var_out : ExampleFpga_pkg.var_out_t;
signal var_in : ExampleFpga_pkg.var_in_t;
signal var2_out : ExampleFpga2_pkg.var_out_t;
signal var2_in : ExampleFpga2_pkg.var_in_t;
signal sync_in, sync_out, sync_chained_in, sync_chained_out : msg_t;
signal sync_chained_id : unsigned(15 downto 0);
signal segment_encode_in, segment_decode_out : msg_t;
signal arq_encode_in, arq_decode_out : msg_t;
signal crc16_encode_in, crc16_decode_out : msg_t;
signal ascii_encode_in, ascii_decode_out : msg_t;
signal term_encode_in, term_decode_out : msg_t;
signal uart_encode_in, uart_decode_out : msg_t;
signal segment_mtu, arq_mtu, crc16_mtu, ascii_mtu, term_mtu, uart_mtu : natural := 0;
signal clk_cnt, write_cnt : unsigned(31 downto 0);
begin
-----------------------------------------
-- Store instances
-----------------------------------------
store_inst : entity work.ExampleFpga_hdl
generic map (
SYSTEM_CLK_FREQ => SYSTEM_CLK_FREQ,
VAR_ACCESS => var_access,
SIMULATION => SIMULATION
)
port map (
clk => clk,
rstn => rstn,
var_out => var_out,
var_in => var_in,
sync_in => sync_in,
sync_out => sync_out,
sync_id => sync_chained_id,
sync_chained_in => sync_chained_out,
sync_chained_out => sync_chained_in
);
store2_inst : entity work.ExampleFpga2_hdl
generic map (
SYSTEM_CLK_FREQ => SYSTEM_CLK_FREQ,
SIMULATION => SIMULATION
)
port map (
clk => clk,
rstn => rstn,
var_out => var2_out,
var_in => var2_in,
sync_in => sync_chained_in,
sync_out => sync_chained_out,
sync_chained_id => sync_chained_id
);
-----------------------------------------
-- Protocol stack for Synchronizer
-----------------------------------------
segment_encode_in <= sync_out;
sync_in <= segment_decode_out;
SegmentationLayer_inst : entity work.SegmentationLayer
generic map (
MTU => 24
)
port map (
clk => clk,
rstn => rstn,
encode_in => segment_encode_in,
encode_out => arq_encode_in,
decode_in => arq_decode_out,
decode_out => segment_decode_out,
-- The following two lines are not required, but they
-- statically check the configured MTU.
mtu_decode_in => arq_mtu,
mtu_decode_out => segment_mtu
);
ArqLayer_inst : entity work.ArqLayer
generic map (
MTU => 24,
SYSTEM_CLK_FREQ => SYSTEM_CLK_FREQ
)
port map (
clk => clk,
rstn => rstn,
encode_in => arq_encode_in,
encode_out => crc16_encode_in,
decode_in => crc16_decode_out,
decode_out => arq_decode_out,
mtu_decode_in => crc16_mtu,
mtu_decode_out => arq_mtu
);
Crc16Layer_inst : entity work.Crc16Layer
generic map (
MTU => 25
)
port map (
clk => clk,
rstn => rstn,
encode_in => crc16_encode_in,
encode_out => ascii_encode_in,
decode_in => ascii_decode_out,
decode_out => crc16_decode_out,
mtu_decode_in => term_mtu,
mtu_decode_out => crc16_mtu
);
ASCIIEscapeLayer_inst : entity work.ASCIIEscapeLayer
port map (
clk => clk,
rstn => rstn,
encode_in => ascii_encode_in,
encode_out => term_encode_in,
decode_in => term_decode_out,
decode_out => ascii_decode_out,
mtu_decode_in => term_mtu,
mtu_decode_out => ascii_mtu
);
TerminalLayer_inst : entity work.TerminalLayer
port map (
clk => clk,
rstn => rstn,
encode_in => term_encode_in,
encode_out => uart_encode_in,
decode_in => uart_decode_out,
decode_out => term_decode_out,
mtu_decode_in => uart_mtu,
mtu_decode_out => term_mtu
);
uart_g : if not SIMULATION generate
begin
UARTLayer_inst : entity work.UARTLayer
generic map (
SYSTEM_CLK_FREQ => SYSTEM_CLK_FREQ,
XON_XOFF => true
)
port map (
clk => clk,
rstn => rstn,
encode_in => uart_encode_in,
decode_out => uart_decode_out,
rx => rx,
tx => tx,
cts => cts,
rts => rts,
mtu_decode_out => uart_mtu
);
end generate;
--pragma translate_off
xsim_g : if SIMULATION generate
function pipe_name return string is
begin
if ExampleFpga_pkg.WIN32 then
return "\\.\pipe\9_fpga";
else
return "/tmp/9_fpga";
end if;
end function;
begin
XsimLayer_inst : entity work.XsimLayer
generic map (
PIPE_PREFIX => pipe_name
)
port map (
clk => clk,
rstn => rstn,
encode_in => uart_encode_in,
decode_out => uart_decode_out,
mtu_decode_out => uart_mtu
);
end generate;
--pragma translate_on
-----------------------------------------
-- Implementation of application
-----------------------------------------
process(clk)
begin
if rising_edge(clk) then
var_in <= ExampleFpga_pkg.var_in_default;
var2_in <= ExampleFpga2_pkg.var_in_default;
-- implementation of ExampleFpga/t (clk)
var_in.\t (clk)\.value <= resize(clk_cnt, var_in.\t (clk)\.value'length);
var_in.\t (clk)\.we <= '1';
clk_cnt <= clk_cnt + 1;
if rstn /= '1' then
var_in.\t (clk)\.we <= '0';
clk_cnt <= (others => '0');
end if;
-- writes to ExampleFpga/read-only register should be ignored
var_in.\read-only register\.value <= x"abcd";
var_in.\read-only register\.we <= '1';
-- implementation of ExampleFpga/default register write count
if var_out.\default register\.updated = '1' then
write_cnt <= write_cnt + 1;
end if;
var_in.\default register write count\.value <=
resize(write_cnt, var_in.\default register write count\.value'length);
var_in.\default register write count\.we <= '1';
if rstn /= '1' then
write_cnt <= (others => '0');
var_in.\default register write count\.we <= '0';
end if;
end if;
end process;
end rtl;
Store reference
-
template<typename Base_, typename Implementation_>
class ExampleFpgaObjects All ExampleFpgaBase’s objects.
Public Members
-
impl::StoreVariantV<Base, Implementation, Type::Blob, 28u, 3u> blob
blob
-
impl::StoreVariable<Base, Implementation, bool, 34u, 1> bool_obj
bool
-
impl::StoreVariable<Base, Implementation, uint32_t, 20u, 4> default_register
default register
-
impl::StoreVariable<Base, Implementation, uint32_t, 24u, 4> default_register_write_count
default register write count
-
impl::StoreFunction<Base, Implementation, ExampleFpgaFunctionMap, 1u> ignored_function
ignored function
-
impl::StoreVariable<Base, Implementation, uint32_t, 0u, 4> initialized_register
initialized register
-
impl::StoreVariable<Base, Implementation, uint16_t, 32u, 2> read_only_register
read-only register
-
impl::StoreVariantV<Base, Implementation, Type::String, 8u, 6u> string
string
-
impl::StoreVariable<Base, Implementation, uint32_t, 16u, 4> t_clk
t (clk)
-
impl::StoreVariantV<Base, Implementation, Type::Blob, 28u, 3u> blob
-
template<typename Implementation_>
class ExampleFpgaBase : public stored::ExampleFpgaObjects<ExampleFpgaBase<Implementation_>, Implementation_> Base class with default interface of all ExampleFpga implementations.
Although there are no virtual functions in the base class, subclasses can override them. The (lowest) subclass must pass the
Implementation_
template paramater to its base, such that all calls from the base class can be directed to the proper overridden implementation.The base class cannot be instantiated. If a default implementation is required, which does not have side effects to functions, instantiate stored::ExampleFpga. This class contains all data of all variables, so it can be large. So, be aware when instantiating it on the stack. Heap is fine. Static allocations is fine too, as the constructor and destructor are trivial.
To inherit the base class, you can use the following template:
class ExampleFpga : public stored::store<ExampleFpga, ExampleFpgaBase>::type { STORE_CLASS(ExampleFpga, ExampleFpgaBase) public: // Your class implementation, such as: ExampleFpga() is_default // ... };
Some compilers or tools may get confused by the inheritance using
stored::store
orstored::store_t
. Alternatively, useSTORE_T(...)
instead, providing the template parameters ofstored::store
as macro arguments.See also
stored::ExampleFpga
See also
stored::ExampleFpgaData
Subclassed by stored::ExampleFpgaDefaultFunctions< ExampleFpgaBase< ExampleFpga > >
Public Types
-
enum [anonymous]
Values:
-
enumerator ObjectCount
Number of objects in the store.
-
enumerator VariableCount
Number of variables in the store.
-
enumerator FunctionCount
Number of functions in the store.
-
enumerator BufferSize
Buffer size.
-
enumerator ObjectCount
-
typedef Implementation_ Implementation
Type of the actual implementation, which is the (lowest) subclass.
-
typedef uintptr_t Key
Type of a key.
See also
-
typedef Map<String::type, Variant<Implementation>>::type ObjectMap
Map as generated by map().
-
typedef ExampleFpgaObjects<ExampleFpgaBase, Implementation_> Objects
-
typedef ExampleFpgaBase root
We are the root, as used by
STORE_CLASS
.
-
typedef ExampleFpgaBase self
Define
self
forstored::store
.
Public Functions
-
inline ~ExampleFpgaBase()
-
void __ignored_function(bool set, int32_t &value)
Callback for ignored function.
-
inline Key bufferToKey(void const *buffer) const noexcept
Converts a variable’s buffer to a key.
A key is unique for all variables of the same store, but identical for the same variables across different instances of the same store class. Therefore, the key can be used to synchronize between instances of the same store. A key does not contain meta data, such as type or length. It is up to the synchronization library to make sure that these properties are handled well.
For synchronization, when hookEntryX() or hookEntryRO() is invoked, one can compute the key of the object that is accessed. The key can be used, for example, in a key-to-Variant map. When data arrives from another party, the key can be used to find the proper Variant in the map.
This way, data exchange is type-safe, as the Variant can check if the data format matches the expected type. However, one cannot process data if the key is not set yet in the map.
-
inline Type::type bufferToType(void const *buffer) noexcept
Return the type of the variable, given its buffer.
-
inline Variant<Implementation> find(char const *name, size_t len = std::numeric_limits<size_t>::max()) noexcept
Finds an object with the given name.
- Returns:
the object, or an invalid stored::Variant if not found.
-
template<typename T>
inline Function<T, Implementation> function(char const *name, size_t len = std::numeric_limits<size_t>::max()) noexcept Finds a function with the given name.
The function, when it exists, must have the given (fixed) type.
-
inline Implementation const &implementation() const noexcept
Returns the reference to the implementation.
-
inline Implementation &implementation() noexcept
Returns the reference to the implementation.
-
template<typename F>
inline void list(F &&f) noexcept Calls a callback for every object in the longDirectory().
See also
-
template<typename F>
inline void list(F f, void *arg, char const *prefix, String::type *nameBuffer) noexcept Calls a callback for every object in the longDirectory().
See also
-
template<typename F>
inline void list(F f, void *arg, char const *prefix = nullptr) noexcept Calls a callback for every object in the longDirectory().
See also
-
inline uint8_t const *longDirectory() const noexcept
Retuns the long directory.
When not available, the short directory is returned.
-
inline ObjectMap map(char const *prefix = nullptr)
Create a name to Variant map for the store.
Generating the map may be expensive and the result is not cached.
-
inline char const *name() const noexcept
Returns the name of store, which can be used as prefix for stored::Debugger.
-
inline uint8_t const *shortDirectory() const noexcept
Returns the short directory.
-
template<typename T>
inline Variable<T, Implementation> variable(char const *name, size_t len = std::numeric_limits<size_t>::max()) noexcept Finds a variable with the given name.
The variable, when it exists, must have the given (fixed) type.
Public Members
-
impl::StoreVariantV<Base, Implementation, Type::Blob, 28u, 3u> blob
blob
-
impl::StoreVariable<Base, Implementation, bool, 34u, 1> bool_obj
bool
-
impl::StoreVariable<Base, Implementation, uint32_t, 20u, 4> default_register
default register
-
impl::StoreVariable<Base, Implementation, uint32_t, 24u, 4> default_register_write_count
default register write count
-
impl::StoreFunction<Base, Implementation, ExampleFpgaFunctionMap, 1u> ignored_function
ignored function
-
impl::StoreVariable<Base, Implementation, uint32_t, 0u, 4> initialized_register
initialized register
-
impl::StoreVariable<Base, Implementation, uint16_t, 32u, 2> read_only_register
read-only register
-
impl::StoreVariantV<Base, Implementation, Type::String, 8u, 6u> string
string
-
impl::StoreVariable<Base, Implementation, uint32_t, 16u, 4> t_clk
t (clk)
Public Static Functions
-
template<typename T>
static inline constexpr FreeFunction<T, Implementation> freeFunction(char const *name, size_t len = std::numeric_limits<size_t>::max()) noexcept Finds a function with the given name.
The function, when it exists, must have the given (fixed) type. It is returned as a free function; it is not bound yet to a specific store instance. This function is constexpr for C++14.
-
template<typename T>
static inline constexpr FreeVariable<T, Implementation> freeVariable(char const *name, size_t len = std::numeric_limits<size_t>::max()) noexcept Finds a variable with the given name.
The variable, when it exists, must have the given (fixed) type. It is returned as a free variable; it is not bound yet to a specific store instance. This function is constexpr for C++14.
-
static inline constexpr char const *hash() noexcept
Returns a unique hash of the store.
Friends
- friend class impl::StoreFunction
- friend class impl::StoreVariable
- friend class impl::StoreVariantF
- friend class impl::StoreVariantV
- friend class stored::FreeVariable
- friend class stored::Variant< void >
-
enum [anonymous]
-
class ExampleFpga : public stored::ExampleFpgaDefaultFunctions<stored::Synchronizable<stored::ExampleFpgaBase<ExampleFpga>>>
Public Functions
-
ExampleFpga() = default
-
ExampleFpga() = default
-
template<typename Base_, typename Implementation_>
class ExampleFpga2Objects All ExampleFpga2Base’s objects.
Public Members
-
impl::StoreVariable<Base, Implementation, int8_t, 0u, 1> other_store_s_int8
other store’s int8
-
impl::StoreVariable<Base, Implementation, int8_t, 0u, 1> other_store_s_int8
-
template<typename Implementation_>
class ExampleFpga2Base : public stored::ExampleFpga2Objects<ExampleFpga2Base<Implementation_>, Implementation_> Base class with default interface of all ExampleFpga2 implementations.
Although there are no virtual functions in the base class, subclasses can override them. The (lowest) subclass must pass the
Implementation_
template paramater to its base, such that all calls from the base class can be directed to the proper overridden implementation.The base class cannot be instantiated. If a default implementation is required, which does not have side effects to functions, instantiate stored::ExampleFpga2. This class contains all data of all variables, so it can be large. So, be aware when instantiating it on the stack. Heap is fine. Static allocations is fine too, as the constructor and destructor are trivial.
To inherit the base class, you can use the following template:
class ExampleFpga2 : public stored::store<ExampleFpga2, ExampleFpga2Base>::type { STORE_CLASS(ExampleFpga2, ExampleFpga2Base) public: // Your class implementation, such as: ExampleFpga2() is_default // ... };
Some compilers or tools may get confused by the inheritance using
stored::store
orstored::store_t
. Alternatively, useSTORE_T(...)
instead, providing the template parameters ofstored::store
as macro arguments.See also
stored::ExampleFpga2
See also
stored::ExampleFpga2Data
Subclassed by stored::ExampleFpga2DefaultFunctions< ExampleFpga2Base< ExampleFpga2 > >
Public Types
-
enum [anonymous]
Values:
-
enumerator ObjectCount
Number of objects in the store.
-
enumerator VariableCount
Number of variables in the store.
-
enumerator FunctionCount
Number of functions in the store.
-
enumerator BufferSize
Buffer size.
-
enumerator ObjectCount
-
typedef Implementation_ Implementation
Type of the actual implementation, which is the (lowest) subclass.
-
typedef uintptr_t Key
Type of a key.
See also
-
typedef Map<String::type, Variant<Implementation>>::type ObjectMap
Map as generated by map().
-
typedef ExampleFpga2Objects<ExampleFpga2Base, Implementation_> Objects
-
typedef ExampleFpga2Base root
We are the root, as used by
STORE_CLASS
.
-
typedef ExampleFpga2Base self
Define
self
forstored::store
.
Public Functions
-
inline ~ExampleFpga2Base()
-
inline Key bufferToKey(void const *buffer) const noexcept
Converts a variable’s buffer to a key.
A key is unique for all variables of the same store, but identical for the same variables across different instances of the same store class. Therefore, the key can be used to synchronize between instances of the same store. A key does not contain meta data, such as type or length. It is up to the synchronization library to make sure that these properties are handled well.
For synchronization, when hookEntryX() or hookEntryRO() is invoked, one can compute the key of the object that is accessed. The key can be used, for example, in a key-to-Variant map. When data arrives from another party, the key can be used to find the proper Variant in the map.
This way, data exchange is type-safe, as the Variant can check if the data format matches the expected type. However, one cannot process data if the key is not set yet in the map.
-
inline Type::type bufferToType(void const *buffer) noexcept
Return the type of the variable, given its buffer.
-
inline Variant<Implementation> find(char const *name, size_t len = std::numeric_limits<size_t>::max()) noexcept
Finds an object with the given name.
- Returns:
the object, or an invalid stored::Variant if not found.
-
template<typename T>
inline Function<T, Implementation> function(char const *name, size_t len = std::numeric_limits<size_t>::max()) noexcept Finds a function with the given name.
The function, when it exists, must have the given (fixed) type.
-
inline Implementation const &implementation() const noexcept
Returns the reference to the implementation.
-
inline Implementation &implementation() noexcept
Returns the reference to the implementation.
-
template<typename F>
inline void list(F &&f) noexcept Calls a callback for every object in the longDirectory().
See also
-
template<typename F>
inline void list(F f, void *arg, char const *prefix, String::type *nameBuffer) noexcept Calls a callback for every object in the longDirectory().
See also
-
template<typename F>
inline void list(F f, void *arg, char const *prefix = nullptr) noexcept Calls a callback for every object in the longDirectory().
See also
-
inline uint8_t const *longDirectory() const noexcept
Retuns the long directory.
When not available, the short directory is returned.
-
inline ObjectMap map(char const *prefix = nullptr)
Create a name to Variant map for the store.
Generating the map may be expensive and the result is not cached.
-
inline char const *name() const noexcept
Returns the name of store, which can be used as prefix for stored::Debugger.
-
inline uint8_t const *shortDirectory() const noexcept
Returns the short directory.
-
template<typename T>
inline Variable<T, Implementation> variable(char const *name, size_t len = std::numeric_limits<size_t>::max()) noexcept Finds a variable with the given name.
The variable, when it exists, must have the given (fixed) type.
Public Members
-
impl::StoreVariable<Base, Implementation, int8_t, 0u, 1> other_store_s_int8
other store’s int8
Public Static Functions
-
template<typename T>
static inline constexpr FreeFunction<T, Implementation> freeFunction(char const *name, size_t len = std::numeric_limits<size_t>::max()) noexcept Finds a function with the given name.
The function, when it exists, must have the given (fixed) type. It is returned as a free function; it is not bound yet to a specific store instance. This function is constexpr for C++14.
-
template<typename T>
static inline constexpr FreeVariable<T, Implementation> freeVariable(char const *name, size_t len = std::numeric_limits<size_t>::max()) noexcept Finds a variable with the given name.
The variable, when it exists, must have the given (fixed) type. It is returned as a free variable; it is not bound yet to a specific store instance. This function is constexpr for C++14.
-
static inline constexpr char const *hash() noexcept
Returns a unique hash of the store.
Friends
- friend class impl::StoreFunction
- friend class impl::StoreVariable
- friend class impl::StoreVariantF
- friend class impl::StoreVariantV
- friend class stored::FreeVariable
- friend class stored::Variant< void >
-
enum [anonymous]
-
class ExampleFpga2 : public stored::ExampleFpga2DefaultFunctions<stored::Synchronizable<stored::ExampleFpga2Base<ExampleFpga2>>>
Public Functions
-
ExampleFpga2() = default
-
ExampleFpga2() = default