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 an Rc<RateLimiter>
because that is what components normally accept 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);
// Build the source (initially with no generator).
let source = Source::new_and_register(&engine, engine.top(), "source", None)
.expect("should be able to create and register `Source`");
// 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, engine.top(), "limit", rate_limiter)
.expect("should be able to create and register `Limiter`");
// Create the sink to accept these packets.
let sink = Sink::new_and_register(&engine, engine.top(), "sink")
.expect("should be able to create and register `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);