// |-size--| |-selector @function(mux_demo, @out: 0:2, 0:4, @in: 0:1, 0:2, 0:4, // input case 0 0:2, 0:4, // input case 1 0:2, 0:4, // input case 2 0:2, 0:4, // input case 3 0:2, 0:4) // input case 4 @plugin(mux_v0, strict);
The Mux v0 Plugin
The mux_v0
plugin provides a multiplexer functionality.
Operations
Two multiplexer behaviors are provided, each having a different error behavior when the selector bit exceeds the number of input cases.
permissive
-
Produces zeroes when the selector bit exceeds the number of inputs.
strict
-
Fails an
@assert_zero
when the selector bit exceeds the number of inputs.
These operations do not use any additional plugin operations. The size of each input is recognized by the size of the output, and the number of inputs is recognized by the repetition of the output sizes over the inputs. Here is an example.
In this example, there are two output ranges — 0:2
and 0:4
, and that shape is repeated 5 times as input cases.
Formally, using type t
, and sizes s1
through sn
, the following parameters are allowed.
When t
is of boolean type, the selector may have width w
.
-
Output
t:s1
: first output range -
…
-
Output
t:sn
: last output range -
Input
t:1
ort:w
: selector wire or selector range (boolean only) -
For each input case:
-
Input
t:s1
: input range corresponding to the first output range -
…
-
Input
t:sn
: input range corresponding to the last output range
-
-
Plugin Name:
mux_v0
-
Operation:
permissive
orstrict
Note
|
Currently, WizToolKit supports only arithmetic multiplexers. |
Implementing the Mux v0 Plugin
You can implement the mux_v0
plugin by subclassing a few classes, or you can rely on WziToolKit’s fallback implementation.
Implementing your own Multiplexer
The core of your multiplexer will implement the wtk::plugins::MuxOperation<Number_T, Wire_T>::evaluateMux(…)
method (from #include <wtk/plugins/Multiplexer.h>
).
Remember you will need to implement both the strict
and permissive
multiplexer operations: either with one subclass handling both or with two subclasses.
The outputs
and inputs
vectors are groups of wire ranges.
Each Wire_T*
of outputs
and Wire_T const*
of inputs
is a pointer to the first element of a range, length determined by sizes
.
inputs
is nested vector, because each multiplexer case is a group of ranges congruent to the outputs
.
virtual void evaluateMux(std::vector<size_t> const& sizes,
std::vector<Wire_T*>& outputs,
Wire_T const* const selector,
std::vector<std::vector<Wire_T const*>>& inputs) override
{
/* Your code here */
}
You must also subclass wtk::plugins::MultiplexerPlugin<Number_T, Wire_T>
, as essentially a factory for mux operations.
The Fallback Multiplexer
WizToolKit provides the wtk::plugins::FallbackMultiplexerPlugin<Number_T, Wire_T>
using Fermat’s Little Theorem to check equality of the selector with each case number.
Setting up the Multiplexer plugin
To setup the multiplexer plugin, all you need do is pass a plugin object to the PluginsManager<Number_T, Wire_Ts…>
for every Wire_T
which you intend to support the plugin (so typically all of them).
wtk::plugins::PluginsManager<Number, WireA, Wire_B> plugins_manager;
std::unique_ptr<MyMuxPlugin<Number, WireA>> mux_a(
new MyMuxPlugin<Number, WireA>());
plugins_manager.addPlugin("mux_v0", std::move(mux_a));
std::unique_ptr<MyMuxPlugin<Number, WireB>> mux_b(
new MyMuxPlugin<Number, WireB>());
plugins_manager.addPlugin("mux_v0", std::move(mux_b));
For more details, see the general plugins section of this manual.