-
Notifications
You must be signed in to change notification settings - Fork 1
/
OutputLayer.bsv
57 lines (46 loc) · 1.82 KB
/
OutputLayer.bsv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package OutputLayer;
import Vector :: *;
import CryptoCore :: *;
import BluelightUtils :: *;
// TODO try Mux based input fill as blockVec size is small
function Byte enableByte(Bool valid, Byte b);
return valid ? b : 0;
endfunction
module mkOutputLayer(OutputLayerIfc#(n_bytes)) provisos (Mul#(block_words, CoreWordBytes, n_bytes), Add#(a__, 4, n_bytes), Add#(1, b__, block_words), Add#(c__, 32, TMul#(n_bytes, 8)));
Reg#(Vector#(block_words, CoreWord)) blockVec <- mkRegU;
Reg#(Vector#(block_words, Bit#(CoreWordBytes))) validsVec <- mkReg(replicate(0));
let not_empty = unpack(|validsVec[0]);
let last = not_empty && !unpack(|validsVec[1]);
let do_deq <- mkPulseWire;
RWire#(Tuple2#(BlockOfSize#(n_bytes), ByteValidsOfSize#(n_bytes))) enq_wire <- mkRWireSBR;
(* fire_when_enabled *)
rule rl_enq_deq if (do_deq || isValid(enq_wire.wget));
case (enq_wire.wget) matches
tagged Valid .enqued: begin
match {.b, .v} = enqued;
blockVec <= unpack(pack(b));
validsVec <= unpack(pack(v));
end
tagged Invalid &&& do_deq: begin
blockVec <= shiftInAtN(blockVec, Vector::last(blockVec));
validsVec <= shiftInAtN(validsVec, 0);
end
endcase
endrule
method Action enq(BlockOfSize#(n_bytes) block, ByteValidsOfSize#(n_bytes) valids) if (!not_empty || (last && do_deq));
enq_wire.wset(tuple2(block, valids));
endmethod
method Action deq if (not_empty);
do_deq.send();
endmethod
method Bool notEmpty;
return not_empty;
endmethod
method CoreWord first;
return pack( zipWith(enableByte, unpack(validsVec[0]), unpack(blockVec[0])) );
endmethod
method Bool isLast;
return last;
endmethod
endmodule
endpackage