Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SpecialWires package, similar to CReg but for Wire and other Wires with multiple ports #1

Merged
merged 3 commits into from
Jul 31, 2020
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions BlueUtils/SpecialWires.bsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package SpecialWires;

export mkDWireOR;
export mkWireOP;

import List :: *;

// DWire where all writes are OR'd together
// Useful when setting fields of a Struct in
// different rules
module mkDWireOR #( Integer n
, a_bits init
) (Array #(Wire #(a_bits))) provisos (
Bits #(a_bits, bit_size));

let v <- mkWireOP (n, mkDWire (init), \| );
return v;
endmodule

// Use this for OPs on Bits
// Force the op to be on Bit #(w) so that when passing an op on Bits the compiler won't
// complain about the op being of ambiguous type
module mkWireOP #( Integer n
, function module #(Wire #(a_bits)) wire_module
, function Bit #(bit_size) op (Bit #(bit_size) arg1, Bit #(bit_size) arg2)
) (Array #(Wire #(a_bits))) provisos (
Bits #(a_bits, bit_size));

let v <- mkWireOP_Core (n, wire_module, op);
return v;
endmodule

// Only useful in rare cases when using some strange 'op'
// Most generic version, does all of the work for the wrappers
// To use with a generic Bits op (eg \|), must define helper fn. Eg:
// function Bit #(n) or_fn (Bit #(n) arg1, Bit #(n) arg2) = arg1 | arg2;
module mkWireOP_Core #( Integer n
, function module #(Wire #(a_bits)) wire_module
, function b_bits op (c_bits arg1, d_bits arg2)
) (Array #(Wire #(a_bits))) provisos (
Bits #(a_bits, bit_size)
, Bits #(b_bits, bit_size)
, Bits #(c_bits, bit_size)
, Bits #(d_bits, bit_size));

if (n<0) error(quote("mkWireOP") + " cannot have a negative number of ports");

function Bit #(bit_size) op_b (Bit #(bit_size) arg1_b, Bit #(bit_size) arg2_b) =
pack (op (unpack (arg1_b), unpack (arg2_b)));

List #(Wire #(a_bits)) wires <- replicateM (n, wire_module);
let bit_wires = map (compose (pack, readReg), wires);
a_bits op_read = unpack (fold (op_b, bit_wires));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDK to what extent this matters in practice, but since we are using the tree style reduction here, I think we require operations where associativity does not matter (and what about commutativity? We probably don't care?). All in all, I'd just mention that tree of operations in the comments.


Wire#(a_bits) v[n];
for (Integer i = 0; i < n; i = i + 1) begin
v[i] = interface Wire;
method _read = op_read;
method _write = writeReg (wires[i]);
endinterface;
end
return v;
endmodule

endpackage