-
Notifications
You must be signed in to change notification settings - Fork 43
/
Annuller.html
97 lines (87 loc) · 4.22 KB
/
Annuller.html
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<html>
<head>
<link rel="shortcut icon" href="./favicon.ico">
<link rel="stylesheet" type="text/css" href="./style.css">
<link rel="canonical" href="./Annuller.html">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Takes in a word-wide signal, and passes it through, unless `annul` is high, then the signal is gated to zero. We put something this simple into a module since it conveys design intent (e.g.: "turn this opcode into a no-op"), and avoids an RTL schematic cluttered with a bunch of gates.">
<title>Annuller</title>
</head>
<body>
<p class="inline bordered"><b><a href="./Annuller.v">Source</a></b></p>
<p class="inline bordered"><b><a href="./legal.html">License</a></b></p>
<p class="inline bordered"><b><a href="./index.html">Index</a></b></p>
<h1>Annuller (Both Kinds)</h1>
<p>Takes in a word-wide signal, and passes it through, unless <code>annul</code> is high,
then the signal is gated to zero. We put something this simple into
a module since it conveys design intent (e.g.: "turn this opcode into
a no-op"), and avoids an RTL schematic cluttered with a bunch of gates.</p>
<p>Annulling shows up in many designs: instead of using a multiplexer, we can
selectively annul all but one input and OR-reduce to a result, which uses
the final LUTs more efficiently.
While this is how a multiplexer works internally, breaking it open like
this allows us to control the pipelining directly (which is relevant if you
are going to have a lot of inputs), and allows us to select alternative
conflict resolutions if two or more inputs remain after annulling:</p>
<ul>
<li>reduce them to a single result using AND/OR/XOR,</li>
<li>feed them to an arbiter so you can process each remaining input in sequence,</li>
<li>have multiple final stages do different things in parallel with the remaining inputs.</li>
</ul>
<p>Essentially, Annulling allows us to easily think about calculating multiple
things in parallel and keeping only the results we want. However, throwing
away work increases performance at the expense of efficiency. Try to use
the lost information if you can.</p>
<h2>Implementation Options</h2>
<p>Some experimentation by others has shown that CAD tools will pattern-match
on the description of the gating operation, resulting in different
synth results depending on whether you describe the signal gating using
a multiplexer or an AND gate. The synthesized logic may end up using the
reset/clear pin of a flip-flop, or may create AND-gate logic after the
flip-flop, which then gets folded into other LUT logic. Thus, both
implementation are available via the <code>IMPLEMENTATION</code> parameter.</p>
<p>The Annuller implementation does not generally matter. However, on FPGAs, the
reset/clear signal is common to all flip-flops in a group (<em>known as a CLB
(Common Logic Block) for Xilinx, or a LAB (Logic Array block) for Intel</em>).
Thus, flip-flops driven by different reset/clear logic cannot be packed
together, though since an Annuller applies the same reset/clear logic to
all signals, they should pack normally.</p>
<p>Register retiming may also be affected, again due to the reset/clear
signals, but again, this is a minor problem if one at all. Assume things
are fine, and check your synthesis results if a bottleneck appears.</p>
<pre>
`default_nettype none
module <a href="./Annuller.html">Annuller</a>
#(
parameter WORD_WIDTH = 0,
parameter IMPLEMENTATION = ""
)
(
input wire annul,
input wire [WORD_WIDTH-1:0] data_in,
output reg [WORD_WIDTH-1:0] data_out
);
localparam ZERO = {WORD_WIDTH{1'b0}};
initial begin
data_out = ZERO;
end
generate
if (IMPLEMENTATION == "MUX") begin : gen_mux
always @(*) begin
data_out = (annul == 1'b0) ? data_in : ZERO;
end
end
else
if (IMPLEMENTATION == "AND") begin : gen_and
always @(*) begin
data_out = data_in & {WORD_WIDTH{annul == 1'b0}};
end
end
endgenerate
endmodule
</pre>
<hr>
<p><a href="./index.html">Back to FPGA Design Elements</a>
<center><a href="https://fpgacpu.ca/">fpgacpu.ca</a></center>
</body>
</html>