Expand description
§gwr-components
Simulation components are the basic building blocks of any GWR model.
The GWR Engine runs components that are connected together using ports.
The gwr_components library provides a collection of connectable component
primitives to be used when building models.
§Testing
Components can be tested by connecting them into a small simulation and driving
their ports directly. For simple cases this can be done by hand with
OutPort/InPort, but most component tests need the same testbench structure:
- Create an engine and the device under test (DUT).
- Connect driver ports to DUT input ports.
- Connect receiver ports to DUT output ports.
- Run a sequence of sends, expects, delays, and no-traffic checks.
The build_component_harness! macro will generate the repeated testbench code.
It generates the harness struct, Port/Step enums, helper macros, etc.
Harnesses are usually declared inside a small test module. This keeps generated
names such as Port, Step, and the helper macros local to the harness and
avoids clashes with other harnesses in the same test file.
For example, the harness around a Delay component is created and used below:
mod delay_harness {
use std::rc::Rc;
use gwr_components::build_component_harness;
use gwr_components::delay::Delay;
use gwr_engine::test_helpers::start_test;
build_component_harness! {
harness DelayHarness<T> {
component: delay: Rc<Delay<T>>,
rx ports: {
Rx<T> => rx,
},
tx ports: {
Tx<T> => tx,
},
}
}
#[test]
fn delay_forwards_values() {
let mut engine = start_test(file!());
let clock = engine.default_clock();
let delay = Delay::new_and_register(&engine, &clock, engine.top(), "delay", 5).unwrap();
let mut harness = DelayHarness::new(engine, delay);
harness.run_steps([
send_rx!(10),
expect_no_traffic!(&[Port::Tx], 4),
expect_tx!(10),
]);
}
}The macro supports scalar RX/TX ports and RX/TX port arrays. Each port section
is optional, so a source-only component can define only tx ports and a
sink-only component can define only rx ports.
Step can be a send, expect, delay, no-traffic check, Seq(Vec<Step<...>>)
that runs child steps in order, or Par(Vec<Step<...>>) that runs child steps
concurrently and waits for all of them before moving on. The generated seq!
and par! helper macros build those recursive control structures and record
their source location, so tests can express parallel sequences on different
ports while keeping error messages tied to the call site.
The harness checks that each step is used on a compatible port; for example, using an expect step on an RX port or a send step on a TX port will fail the test.
Use run_steps([Step<...>]) for fixed test sequences and
run_step_generator(iterator) for stateful generators that yield steps as the
test progresses.
§Further reading
The components chapter of the gwr-developer-guide contains details on the creation and use of new components.
Modules§
- arbiter
- Perform arbitration between a number of interfaces.
- connect
- Helper connection macros
- delay
- A component that adds
delay_ticksbetween receiving anything and sending it on to its output. - flow_
controls - Components used for flow-control.
- queue
- Generic queues.
- router
- Perform routing between an input interface and a number number of outputs.
- sink
- A data sink.
- source
- A data source.
- store
- A data store.
- test_
helpers - types
- Shared types.
Macros§
- borrow_
option - Get a reference to a variable stored in a
RefCell<Option<>>. - borrow_
option_ mut - Get a mutable reference to a variable stored in a
RefCell<Option<>>. - build_
component_ harness - Build a simulation test harness around a component.
- connect_
dummy_ rx - Create and connect a dummy RX port
- connect_
dummy_ tx - Create and connect a dummy TX port
- connect_
port - Connect an OutPort port to an InPort
- connect_
tx - Connect a tx port for a subcomponent.
- connect_
tx_ i - Connect a tx port for a subcomponent where the port is one of an array.
- option_
box_ chain - option_
box_ repeat - option_
rc_ limiter - port_rx
- Access rx port for a subcomponent.
- port_
rx_ i - Access an individual index of an rx port array for a subcomponent.
- rc_
limiter - Create a RateLimiter wrapped in an Rc.
- take_
option - Take a variable out of a
RefCell<Option<>>.