Expand description
Provide effective bandwidth limit for a component.
A RateLimiter is a component that is given a
clock and a rate in bits per tick.
It uses this rate limit to enforce a delay determined by the object that is
being rate limited.
The RateLimiter therefore requires objects to implement the TotalBytes trait so that the number of bits of the object can be determined.
§Ports
This component has the following ports:
- One input port:
rx - One output port:
tx
§Creating a Rate Limiter
RateLimiters should normally be constructed using the
rc_limiter! macro. This returns a
Result<Rc<RateLimiter>, SimError>, rejecting a zero rate. Components
normally accept an Rc<RateLimiter> as a rate limiter argument.
They are Rced because they are used immutably and as a result the same
rate limiter can be shared by all components that have the same bandwidth.
§Examples:
Here is a basic example of a rate limiter being used by the Limiter component which is connected between a source and sink.
A source is used to produce 4-byte packets. The rate limiter is configured to run on a 1GHz clock at a rate of 16 bits per tick.
As a result, the total time for the simulation should be 20.0ns because
each of the 10 packets should take 2 clock ticks to pass through the
Limiter and be consumed by the
Sink.
// Create the engine.
let mut engine = Engine::default();
// Create a 1GHz clock.
let clock = engine.clock_ghz(1.0);
// And build a 16 bits-per-tick rate limiter.
let rate_limiter = rc_limiter!(&clock, 16).unwrap();
// Build the source (initially with no generator).
let source = Source::new_and_register(&engine, engine.top(), "source", None);
// Create a packet that uses the source as its trace-control entity.
let packet = 0; // TODO implement a packet type to use here
// Configure the source to produce ten of these packets.
source.set_generator(option_box_repeat!(packet ; 10));
// Create the a limiter component to enforce the limit
let limiter = Limiter::new_and_register(&engine, &clock, engine.top(), "limit", rate_limiter);
// Create the sink to accept these packets.
let sink = Sink::new_and_register(&engine, &clock, engine.top(), "sink");
// Connect the components.
connect_port!(source, tx => limiter, rx)
.expect("should be able to connect `Source` to `Limiter`");
connect_port!(limiter, tx => sink, rx)
.expect("should be able to connect `Limiter` to `Sink`");
// Run the simulation.
run_simulation!(engine);
// Ensure the time is as expected.
assert_eq!(engine.time_now_ns(), 20.0);