-
Notifications
You must be signed in to change notification settings - Fork 43
/
Address_Decoder_Static.html
89 lines (76 loc) · 3.73 KB
/
Address_Decoder_Static.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
<html>
<head>
<link rel="shortcut icon" href="./favicon.ico">
<link rel="stylesheet" type="text/css" href="./style.css">
<link rel="canonical" href="./Address_Decoder_Static.html">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="A flexible address decoder. Works for any address range at any starting point. The base and bound addresses are set as parameters, so the range is fixed. This decoder works by checking if the input address lies between the base and bound (inclusive) of a range by comparing against each possible address within the range, then outputs the OR-reduction of all these checks.">
<title>Address Decoder Static</title>
</head>
<body>
<p class="inline bordered"><b><a href="./Address_Decoder_Static.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>Address Decoder (Static)</h1>
<p>A flexible address decoder. Works for any address range at any starting
point. The base and bound addresses are set as parameters, so the range is
fixed. This decoder works by checking if the input address lies between the
base and bound (inclusive) of a range by comparing against each possible
address within the range, then outputs the OR-reduction of all these
checks.</p>
<p>But there are a couple of caveats: your CAD tool will have to create
a little netlist for up to all 2^ADDR_WIDTH possible addresses, and store
the matches into a vector of up to 2^ADDR_WIDTH bits long, depending on the
base and bound addresses. Elaborating and optimizing this logic can take
a <em>very</em> long time and, as I understand it, Verilog implementations have
a maximum vector width of a million or so, so this decoder will be likley
unusable for address ranges more than 20 bits wide.</p>
<p>Also, even if your CAD tool can handle wider vectors, because we use an
integer as counter, this decoder cannot be guaranteed to work for address
ranges exceeding 32 bits, depending on your Verilog implementation.</p>
<p><strong>I do not recommend this implementation.</strong> I include it because I have put
it to good use inside a CPU for decoding register operands, and it might be
a good choice for very small, fixed address ranges if your CAD tool cannot
fully optimize the <a href="./Address_Decoder_Behavioural.html">Behavioural Address
Decoder</a>.</p>
<pre>
`default_nettype none
module <a href="./Address_Decoder_Static.html">Address_Decoder_Static</a>
#(
parameter ADDR_WIDTH = 0,
parameter ADDR_BASE = 0,
parameter ADDR_BOUND = 0
)
(
input wire [ADDR_WIDTH-1:0] addr,
output reg hit
);
localparam ADDR_COUNT = ADDR_BOUND - ADDR_BASE + 1;
localparam COUNT_ZERO = {ADDR_COUNT{1'b0}};
initial begin
hit = 1'b0;
end
integer i;
reg [ADDR_COUNT-1:0] per_addr_match = COUNT_ZERO;
</pre>
<p>Check each address in base/bound range for match, and store it in a vector
for later OR-reduction. Note that we select only the bit range we need
from the index <code>i</code> so it doesn't raise a width mismatch warning when
compared to the input address. This does mean problems if <code>ADDR_WIDTH</code> is
greater than 32 bits.</p>
<pre>
always @(*) begin
for(i = ADDR_BASE; i <= ADDR_BOUND; i = i + 1) begin : addr_decode
per_addr_match[i-ADDR_BASE] = (addr == i[ADDR_WIDTH-1:0]);
end
end
always @(*) begin : is_hit
hit = |per_addr_match;
end
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>