-
Notifications
You must be signed in to change notification settings - Fork 4
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
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
/*- | ||
* Copyright (c) 2020 Jonas Fiala | ||
* All rights reserved. | ||
* | ||
* This software was developed by SRI International and the University of | ||
* Cambridge Computer Laboratory (Department of Computer Science and | ||
* Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the | ||
* DARPA SSITH research programme. | ||
* | ||
* @BERI_LICENSE_HEADER_START@ | ||
* | ||
* Licensed to BERI Open Systems C.I.C. (BERI) under one or more contributor | ||
* license agreements. See the NOTICE file distributed with this work for | ||
* additional information regarding copyright ownership. BERI licenses this | ||
* file to you under the BERI Hardware-Software License, Version 1.0 (the | ||
* "License"); you may not use this file except in compliance with the | ||
* License. You may obtain a copy of the License at: | ||
* | ||
* http://www.beri-open-systems.org/legal/license-1-0.txt | ||
* | ||
* Unless required by applicable law or agreed to in writing, Work distributed | ||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | ||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations under the License. | ||
* | ||
* @BERI_LICENSE_HEADER_END@ | ||
*/ | ||
|
||
package SpecialWires; | ||
|
||
export mkDCWire; | ||
export mkCDWire; | ||
|
||
export mkDWireOR; | ||
export mkWireOP; | ||
|
||
import List :: *; | ||
|
||
// Default Concurent Wire, less logical name for CDWire | ||
module mkDCWire #( Integer n | ||
, a_bits init | ||
) (Array #(Wire #(a_bits))) provisos ( | ||
Bits #(a_bits, bit_size)); | ||
|
||
let ifc <- mkCDWire (n, init); | ||
return ifc; | ||
endmodule | ||
|
||
// Concurent DWire, similar to CReg but for DWire | ||
module mkCDWire #( Integer n | ||
, a_bits init | ||
) (Array #(Wire #(a_bits))) provisos ( | ||
Bits #(a_bits, bit_size)); | ||
|
||
if (n < 0) error (quote ("mkCDWire") + " cannot have a negative number of ports"); | ||
|
||
Wire#(a_bits) ifc[n]; | ||
List #(RWire #(a_bits)) newVal <- replicateM (n, mkRWire); | ||
List #(Wire #(a_bits)) prevVal <- replicateM (n, mkWire); | ||
if (n > 0) rule defVal; prevVal[0] <= init; endrule | ||
for (Integer i = 0; i < n; i = i + 1) begin | ||
a_bits readVal = fromMaybe (prevVal[i], newVal[i].wget); | ||
if (i < n-1) rule propagateVal; prevVal[i+1] <= readVal; endrule | ||
ifc[i] = interface Wire; | ||
method _write = newVal[i].wset; | ||
method _read = readVal; | ||
endinterface; | ||
end | ||
return ifc; | ||
endmodule | ||
|
||
// 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 ifc <- mkWireOP (n, mkDWire (init), \| ); | ||
return ifc; | ||
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 ifc <- mkWireOP_Core (n, wire_module, op); | ||
return ifc; | ||
endmodule | ||
|
||
// NOTE: values are reduced in a binary tree-like structure | ||
// so beware if op is not associative or commutative | ||
// 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)); | ||
|
||
Wire#(a_bits) ifc[n]; | ||
for (Integer i = 0; i < n; i = i + 1) begin | ||
ifc[i] = interface Wire; | ||
method _read = op_read; | ||
method _write = writeReg (wires[i]); | ||
endinterface; | ||
end | ||
return ifc; | ||
endmodule | ||
|
||
endpackage |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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.