Skip to content

Commit

Permalink
addr_decode: Add a variant suited for online configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
thommythomaso committed Sep 26, 2023
1 parent 69c5eef commit 949abc0
Show file tree
Hide file tree
Showing 7 changed files with 308 additions and 178 deletions.
163 changes: 84 additions & 79 deletions Bender.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package:
- "Manuel Eggimann <[email protected]>"
- "Stefan Mach <[email protected]>"
- "Wolfgang Roenninger <[email protected]>"
- "Thomas Benz <[email protected]>"

dependencies:
common_verification: { git: "https://github.com/pulp-platform/common_verification.git", version: 0.2.0 }
Expand All @@ -20,91 +21,95 @@ sources:
# Source files grouped in levels. Files in level 0 have no dependencies on files in this package.
# Files in level 1 only depend on files in level 0, files in level 2 on files in levels 1 and 0,
# etc. Files within a level are ordered alphabetically.

# Level 0
- src/binary_to_gray.sv

- target: not(all(xilinx,vivado_ipx))
files:
- src/cb_filter_pkg.sv
- src/cc_onehot.sv
- src/cf_math_pkg.sv
- src/clk_int_div.sv
- src/delta_counter.sv
- src/ecc_pkg.sv
- src/edge_propagator_tx.sv
- src/exp_backoff.sv
- src/fifo_v3.sv
- src/gray_to_binary.sv
- src/isochronous_4phase_handshake.sv
- src/isochronous_spill_register.sv
- src/lfsr.sv
- src/lfsr_16bit.sv
- src/lfsr_8bit.sv
- src/mv_filter.sv
- src/onehot_to_bin.sv
- src/plru_tree.sv
- src/popcount.sv
- src/rr_arb_tree.sv
- src/rstgen_bypass.sv
- src/serial_deglitch.sv
- src/shift_reg.sv
- src/shift_reg_gated.sv
- src/spill_register_flushable.sv
- src/stream_demux.sv
- src/stream_filter.sv
- src/stream_fork.sv
- src/stream_intf.sv
- src/stream_join_dynamic.sv
- src/stream_mux.sv
- src/stream_throttle.sv
- src/lossy_valid_to_stream.sv
- src/sub_per_hash.sv
- src/sync.sv
- src/sync_wedge.sv
- src/unread.sv
- src/read.sv
- src/cdc_reset_ctrlr_pkg.sv
# Level 1
- src/clk_int_div_static.sv
- src/addr_decode_napot.sv
- src/cdc_2phase.sv
- src/cdc_4phase.sv
- src/addr_decode.sv
- src/multiaddr_decode.sv
- src/cb_filter_pkg.sv
- src/cc_onehot.sv
- src/cdc_reset_ctrlr_pkg.sv
- src/cf_math_pkg.sv
- src/clk_int_div.sv
- src/delta_counter.sv
- src/ecc_pkg.sv
- src/edge_propagator_tx.sv
- src/exp_backoff.sv
- src/fifo_v3.sv
- src/gray_to_binary.sv
- src/isochronous_4phase_handshake.sv
- src/isochronous_spill_register.sv
- src/lfsr.sv
- src/lfsr_16bit.sv
- src/lfsr_8bit.sv
- src/lossy_valid_to_stream.sv
- src/mv_filter.sv
- src/onehot_to_bin.sv
- src/plru_tree.sv
- src/popcount.sv
- src/rr_arb_tree.sv
- src/rstgen_bypass.sv
- src/serial_deglitch.sv
- src/shift_reg.sv
- src/shift_reg_gated.sv
- src/spill_register_flushable.sv
- src/stream_demux.sv
- src/stream_filter.sv
- src/stream_fork.sv
- src/stream_intf.sv
- src/stream_join_dynamic.sv
- src/stream_mux.sv
- src/stream_throttle.sv
- src/sub_per_hash.sv
- src/sync.sv
- src/sync_wedge.sv
- src/unread.sv
- src/read.sv
# Level 1
- src/addr_decode_dync.sv
- src/cdc_2phase.sv
- src/cdc_4phase.sv
- src/clk_int_div_static.sv
# Level 2
- src/addr_decode.sv
- src/addr_decode_napot.sv
- src/multiaddr_decode.sv
- target: not(all(xilinx,vivado_ipx))
files:
- src/cb_filter.sv
- src/cdc_fifo_2phase.sv
- src/counter.sv
- src/ecc_decode.sv
- src/ecc_encode.sv
- src/edge_detect.sv
- src/lzc.sv
- src/max_counter.sv
- src/rstgen.sv
- src/spill_register.sv
- src/stream_delay.sv
- src/stream_fifo.sv
- src/stream_fork_dynamic.sv
- src/stream_join.sv
- src/clk_mux_glitch_free.sv
# Level 2
- src/cdc_reset_ctrlr.sv
- src/cdc_fifo_gray.sv
- src/fall_through_register.sv
- src/id_queue.sv
- src/stream_to_mem.sv
- src/stream_arbiter_flushable.sv
- src/stream_fifo_optimal_wrap.sv
- src/stream_register.sv
- src/stream_xbar.sv
# Level 3
- src/cdc_fifo_gray_clearable.sv
- src/cdc_2phase_clearable.sv
- src/mem_to_banks_detailed.sv
- src/stream_arbiter.sv
- src/stream_omega_net.sv
# Level 4
- src/mem_to_banks.sv
- src/cb_filter.sv
- src/cdc_fifo_2phase.sv
- src/clk_mux_glitch_free.sv
- src/counter.sv
- src/ecc_decode.sv
- src/ecc_encode.sv
- src/edge_detect.sv
- src/lzc.sv
- src/max_counter.sv
- src/rstgen.sv
- src/spill_register.sv
- src/stream_delay.sv
- src/stream_fifo.sv
- src/stream_fork_dynamic.sv
- src/stream_join.sv
# Level 2
- src/cdc_reset_ctrlr.sv
- src/cdc_fifo_gray.sv
- src/fall_through_register.sv
- src/id_queue.sv
- src/stream_to_mem.sv
- src/stream_arbiter_flushable.sv
- src/stream_fifo_optimal_wrap.sv
- src/stream_register.sv
- src/stream_xbar.sv
# Level 3
- src/cdc_fifo_gray_clearable.sv
- src/cdc_2phase_clearable.sv
- src/mem_to_banks_detailed.sv
- src/stream_arbiter.sv
- src/stream_omega_net.sv
# Level 4
- src/mem_to_banks.sv

- target: simulation
files:
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Please note that cells with status *deprecated* are not to be used for new desig
| Name | Description | Status | Superseded By |
|----------------------------|-----------------------------------------------------------------------------------------------------------|--------------|---------------|
| `addr_decode` | Address map decoder | active | |
| `addr_decode_dync` | Address map decoder extended to support dynamic online configuration | active | |
| `addr_decode_napot` | Address map decoder using naturally-aligned power of two (NAPOT) regions | active | |
| `multiaddr_decode` | Address map decoder using NAPOT regions and allowing for multiple address inputs | active | |
| `ecc_decode` | SECDED Decoder (Single Error Correction, Double Error Detection) | active | |
Expand Down
6 changes: 4 additions & 2 deletions common_cells.core
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ filesets:
# Source files grouped in levels. Files in level 0 have no dependencies on files in this package.
# Files in level 1 only depend on files in level 0, files in level 2 on files in levels 1 and 0,
# etc. Files within a level are ordered alphabetically.
# Level 0
- src/binary_to_gray.sv
- src/cb_filter_pkg.sv
- src/cc_onehot.sv
Expand Down Expand Up @@ -50,10 +51,9 @@ filesets:
- src/read.sv
- src/cdc_reset_ctrlr_pkg.sv
# Level 1
- src/addr_decode_dync.sv
- src/cdc_2phase.sv
- src/cdc_4phase.sv
- src/addr_decode.sv
- src/addr_decode_napot.sv
- src/cb_filter.sv
- src/cdc_fifo_2phase.sv
- src/counter.sv
Expand All @@ -69,6 +69,8 @@ filesets:
- src/stream_fork_dynamic.sv
- src/clk_mux_glitch_free.sv
# Level 2
- src/addr_decode.sv
- src/addr_decode_napot.sv
- src/cdc_reset_ctrlr.sv
- src/cdc_fifo_gray.sv
- src/fall_through_register.sv
Expand Down
111 changes: 20 additions & 91 deletions src/addr_decode.sv
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

// Author: Wolfgang Roenninger <[email protected]>
// Authors:
// - Wolfgang Roenninger <[email protected]>
// - Thomas Benz <[email protected]>

/// Address Decoder: Maps the input address combinatorially to an index.
/// The address map `addr_map_i` is a packed array of rule_t structs.
Expand Down Expand Up @@ -88,95 +90,22 @@ module addr_decode #(
input idx_t default_idx_i
);

logic [NoRules-1:0] matched_rules; // purely for address map debugging
// wraps the dynamic configuration version of the address decoder
addr_decode_dync #(
.NoIndices ( NoIndices ),
.NoRules ( NoRules ),
.addr_t ( addr_t ),
.rule_t ( rule_t ),
.Napot ( Napot )
) i_addr_decode_dync (
.addr_i,
.addr_map_i,
.idx_o,
.dec_valid_o,
.dec_error_o,
.en_default_idx_i,
.default_idx_i,
.config_ongoing_i ( 1'b0 )
);

always_comb begin
// default assignments
matched_rules = '0;
dec_valid_o = 1'b0;
dec_error_o = (en_default_idx_i) ? 1'b0 : 1'b1;
idx_o = (en_default_idx_i) ? default_idx_i : '0;

// match the rules
for (int unsigned i = 0; i < NoRules; i++) begin
if (
!Napot && (addr_i >= addr_map_i[i].start_addr) &&
((addr_i < addr_map_i[i].end_addr) || (addr_map_i[i].end_addr == '0)) ||
Napot && (addr_map_i[i].start_addr & addr_map_i[i].end_addr) ==
(addr_i & addr_map_i[i].end_addr)
) begin
matched_rules[i] = 1'b1;
dec_valid_o = 1'b1;
dec_error_o = 1'b0;
idx_o = idx_t'(addr_map_i[i].idx);
end
end
end

// Assumptions and assertions
`ifndef VERILATOR
`ifndef XSIM
// pragma translate_off
initial begin : proc_check_parameters
assume ($bits(addr_i) == $bits(addr_map_i[0].start_addr)) else
$warning($sformatf("Input address has %d bits and address map has %d bits.",
$bits(addr_i), $bits(addr_map_i[0].start_addr)));
assume (NoRules > 0) else
$fatal(1, $sformatf("At least one rule needed"));
assume (NoIndices > 0) else
$fatal(1, $sformatf("At least one index needed"));
end

assert final ($onehot0(matched_rules)) else
$warning("More than one bit set in the one-hot signal, matched_rules");

// These following assumptions check the validity of the address map.
// The assumptions gets generated for each distinct pair of rules.
// Each assumption is present two times, as they rely on one rules being
// effectively ordered. Only one of the rules with the same function is
// active at a time for a given pair.
// check_start: Enforces a smaller start than end address.
// check_idx: Enforces a valid index in the rule.
// check_overlap: Warns if there are overlapping address regions.
always @(addr_map_i) #0 begin : proc_check_addr_map
if (!$isunknown(addr_map_i)) begin
for (int unsigned i = 0; i < NoRules; i++) begin
check_start : assume (Napot || addr_map_i[i].start_addr < addr_map_i[i].end_addr ||
addr_map_i[i].end_addr == '0) else
$fatal(1, $sformatf("This rule has a higher start than end address!!!\n\
Violating rule %d.\n\
Rule> IDX: %h START: %h END: %h\n\
#####################################################",
i ,addr_map_i[i].idx, addr_map_i[i].start_addr, addr_map_i[i].end_addr));
// check the SLV ids
check_idx : assume (addr_map_i[i].idx < NoIndices) else
$fatal(1, $sformatf("This rule has a IDX that is not allowed!!!\n\
Violating rule %d.\n\
Rule> IDX: %h START: %h END: %h\n\
Rule> MAX_IDX: %h\n\
#####################################################",
i, addr_map_i[i].idx, addr_map_i[i].start_addr, addr_map_i[i].end_addr,
(NoIndices-1)));
for (int unsigned j = i + 1; j < NoRules; j++) begin
// overlap check
check_overlap : assume (Napot ||
!((addr_map_i[j].start_addr < addr_map_i[i].end_addr) &&
(addr_map_i[j].end_addr > addr_map_i[i].start_addr)) ||
!((addr_map_i[i].end_addr == '0) &&
(addr_map_i[j].end_addr > addr_map_i[i].start_addr)) ||
!((addr_map_i[j].start_addr < addr_map_i[i].end_addr) &&
(addr_map_i[j].end_addr == '0))) else
$warning($sformatf("Overlapping address region found!!!\n\
Rule %d: IDX: %h START: %h END: %h\n\
Rule %d: IDX: %h START: %h END: %h\n\
#####################################################",
i, addr_map_i[i].idx, addr_map_i[i].start_addr, addr_map_i[i].end_addr,
j, addr_map_i[j].idx, addr_map_i[j].start_addr, addr_map_i[j].end_addr));
end
end
end
end
// pragma translate_on
`endif
`endif
endmodule
Loading

0 comments on commit 949abc0

Please sign in to comment.