forked from pulp-platform/common_cells
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcc_addr_decode_napot.sv
More file actions
102 lines (95 loc) · 3.79 KB
/
Copy pathcc_addr_decode_napot.sv
File metadata and controls
102 lines (95 loc) · 3.79 KB
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
97
98
99
100
101
102
// Copyright 2019 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this 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.
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
// Author: Paul Scheffler <paulsc@iis.ee.ethz.ch>
/// This module wraps `cc_addr_decode_dync` in its naturally-aligned power of two (NAPOT) variant,
/// alleviating the need to set the `Napot` parameter and using more descriptive `rule_t`
/// field names. See the `cc_addr_decode`documentation for details.
module cc_addr_decode_napot #(
/// Highest index which can happen in a rule.
parameter int unsigned NoIndices = 32'd0,
/// Total number of rules.
parameter int unsigned NoRules = 32'd1,
/// Address type inside the rules and to decode.
parameter type addr_t = logic,
/// The output index type `idx_t` can be specified either with the width `IdxWidth`
/// or directly with the type `idx_t`. By default, it will use the maximum index
/// `NoIndices` to calculate the required width.
parameter int unsigned IdxWidth = cc_pkg::idx_width(NoIndices),
parameter type idx_t = logic [IdxWidth-1:0],
/// Rule packed struct type.
/// The NAPOT address decoder expects three fields in `rule_t`:
///
/// typedef struct packed {
/// idx_t idx;
/// addr_t base;
/// addr_t mask;
/// } rule_t;
///
/// - `idx`: index of the rule, has to be < `NoIndices`.
/// - `base`: base address whose specified bits should match `addr_i`.
/// - `mask`: set for bits which are to be checked to determine a match.
// verilog_lint: waive typedef-structs-unions
parameter type rule_t = struct packed {
idx_t idx;
addr_t base;
addr_t mask;
}
) (
/// Address to decode.
input addr_t addr_i,
/// Address map: rule with the highest array position wins on collision
input rule_t [NoRules-1:0] addr_map_i,
/// Decoded index.
output idx_t idx_o,
/// Decode is valid.
output logic dec_valid_o,
/// Decode is not valid, no matching rule found.
output logic dec_error_o,
/// Enable default port mapping.
///
/// When not used, tie to `0`.
input logic en_default_idx_i,
/// Default port index.
///
/// When `en_default_idx_i` is `1`, this will be the index when no rule matches.
///
/// When not used, tie to `0`.
input idx_t default_idx_i
);
// Rename struct field names to those expected by `cc_addr_decode`
typedef struct packed {
idx_t idx;
addr_t start_addr;
addr_t end_addr;
} rule_range_t;
rule_range_t [NoRules-1:0] range_addr_map;
for (genvar i = 0; i < NoRules; i++) begin : gen_rule_assign
assign range_addr_map[i].idx = addr_map_i[i].idx;
assign range_addr_map[i].start_addr = addr_map_i[i].base;
assign range_addr_map[i].end_addr = addr_map_i[i].mask;
end
cc_addr_decode_dync #(
.NoIndices ( NoIndices ) ,
.NoRules ( NoRules ),
.addr_t ( addr_t ),
.rule_t ( rule_range_t ),
.Napot ( 1 )
) i_addr_decode_dync (
.addr_i,
.addr_map_i ( range_addr_map ),
.idx_o,
.dec_valid_o,
.dec_error_o,
.en_default_idx_i,
.default_idx_i,
.config_ongoing_i ( 1'b0 )
);
endmodule