forked from esl-epfl/x-heep
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathext_bus.sv
168 lines (143 loc) · 6.35 KB
/
ext_bus.sv
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// Copyright 2022 EPFL and Politecnico di Torino.
// Solderpad Hardware License, Version 2.1, see LICENSE.md for details.
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// File: ext_bus.sv
// Author: Michele Caon
// Date: 19/05/2023
// Description: external peripheral bus for X-HEEP testbench
module ext_bus #(
parameter int unsigned EXT_XBAR_NMASTER = 1,
parameter int unsigned EXT_XBAR_NSLAVE = 1,
// Dependent parameters: do not override
localparam int unsigned EXT_XBAR_NMASTER_RND = EXT_XBAR_NMASTER == 0 ? 1 : EXT_XBAR_NMASTER,
localparam int unsigned EXT_XBAR_NSLAVE_RND = EXT_XBAR_NSLAVE == 0 ? 1 : EXT_XBAR_NSLAVE,
localparam int unsigned IDX_WIDTH = cf_math_pkg::idx_width(EXT_XBAR_NSLAVE)
) (
input logic clk_i,
input logic rst_ni,
// Address map
input addr_map_rule_pkg::addr_map_rule_t [EXT_XBAR_NSLAVE-1:0] addr_map_i,
// Default external slave index
input logic [IDX_WIDTH-1:0] default_idx_i,
// X-HEEP master ports
input obi_pkg::obi_req_t heep_core_instr_req_i,
output obi_pkg::obi_resp_t heep_core_instr_resp_o,
input obi_pkg::obi_req_t heep_core_data_req_i,
output obi_pkg::obi_resp_t heep_core_data_resp_o,
input obi_pkg::obi_req_t heep_debug_master_req_i,
output obi_pkg::obi_resp_t heep_debug_master_resp_o,
input obi_pkg::obi_req_t heep_dma_read_ch0_req_i,
output obi_pkg::obi_resp_t heep_dma_read_ch0_resp_o,
input obi_pkg::obi_req_t heep_dma_write_ch0_req_i,
output obi_pkg::obi_resp_t heep_dma_write_ch0_resp_o,
input obi_pkg::obi_req_t heep_dma_addr_ch0_req_i,
output obi_pkg::obi_resp_t heep_dma_addr_ch0_resp_o,
// External master ports
input obi_pkg::obi_req_t [EXT_XBAR_NMASTER_RND-1:0] ext_master_req_i,
output obi_pkg::obi_resp_t [EXT_XBAR_NMASTER_RND-1:0] ext_master_resp_o,
// X-HEEP slave ports (one per external master)
output obi_pkg::obi_req_t [EXT_XBAR_NMASTER_RND-1:0] heep_slave_req_o,
input obi_pkg::obi_resp_t [EXT_XBAR_NMASTER_RND-1:0] heep_slave_resp_i,
// External slave ports
output obi_pkg::obi_req_t [EXT_XBAR_NSLAVE_RND-1:0] ext_slave_req_o,
input obi_pkg::obi_resp_t [EXT_XBAR_NSLAVE_RND-1:0] ext_slave_resp_i
);
import obi_pkg::*;
import addr_map_rule_pkg::*;
import core_v_mini_mcu_pkg::*;
// X-HEEP + external master ports
obi_req_t [core_v_mini_mcu_pkg::SYSTEM_XBAR_NMASTER+EXT_XBAR_NMASTER-1:0] master_req;
obi_resp_t [core_v_mini_mcu_pkg::SYSTEM_XBAR_NMASTER+EXT_XBAR_NMASTER-1:0] master_resp;
// Forward crossbars ports
obi_req_t [EXT_XBAR_NMASTER-1:0][1:0] demux_xbar_req;
obi_resp_t [EXT_XBAR_NMASTER-1:0][1:0] demux_xbar_resp;
// Dummy external master portp (to prevent unused warning)
obi_req_t [EXT_XBAR_NMASTER_RND-1:0] ext_master_req_unused;
obi_resp_t [EXT_XBAR_NMASTER_RND-1:0] heep_slave_resp_unused;
obi_resp_t [EXT_XBAR_NSLAVE_RND-1:0] ext_slave_resp_unused;
assign ext_master_req_unused = ext_master_req_i;
assign heep_slave_resp_unused = heep_slave_resp_i;
assign ext_slave_resp_unused = ext_slave_resp_i;
// X-HEEP + external master requests
assign master_req[CORE_INSTR_IDX] = heep_core_instr_req_i;
assign master_req[CORE_DATA_IDX] = heep_core_data_req_i;
assign master_req[DEBUG_MASTER_IDX] = heep_debug_master_req_i;
assign master_req[DMA_READ_CH0_IDX] = heep_dma_read_ch0_req_i;
assign master_req[DMA_WRITE_CH0_IDX] = heep_dma_write_ch0_req_i;
assign master_req[DMA_ADDR_CH0_IDX] = heep_dma_addr_ch0_req_i;
generate
for (genvar i = 0; i < EXT_XBAR_NMASTER; i++) begin : gen_ext_master_req_map
assign master_req[SYSTEM_XBAR_NMASTER+i] = demux_xbar_req[i][DEMUX_XBAR_EXT_SLAVE_IDX];
end
endgenerate
// X-HEEP master responses
assign heep_core_instr_resp_o = master_resp[CORE_INSTR_IDX];
assign heep_core_data_resp_o = master_resp[CORE_DATA_IDX];
assign heep_debug_master_resp_o = master_resp[DEBUG_MASTER_IDX];
assign heep_dma_read_ch0_resp_o = master_resp[DMA_READ_CH0_IDX];
assign heep_dma_write_ch0_resp_o = master_resp[DMA_WRITE_CH0_IDX];
assign heep_dma_addr_ch0_resp_o = master_resp[DMA_ADDR_CH0_IDX];
// X-HEEP slave requests
generate
for (genvar i = 0; i < EXT_XBAR_NMASTER; i++) begin
assign heep_slave_req_o[i] = demux_xbar_req[i][DEMUX_XBAR_INT_SLAVE_IDX];
end
endgenerate
// X-HEEP slave responses
generate
for (genvar i = 0; unsigned'(i) < EXT_XBAR_NMASTER; i++) begin
assign demux_xbar_resp[i][DEMUX_XBAR_INT_SLAVE_IDX] = heep_slave_resp_i[i];
end
endgenerate
// External slave responses
generate
for (genvar i = 0; unsigned'(i) < EXT_XBAR_NMASTER; i++) begin : gen_demux_master_resp_map
assign demux_xbar_resp[i][DEMUX_XBAR_EXT_SLAVE_IDX] = master_resp[SYSTEM_XBAR_NMASTER+i];
end
endgenerate
`ifndef SYNTHESIS
// show writes if requested
always_ff @(posedge clk_i, negedge rst_ni) begin : verbose_writes
if ($test$plusargs("verbose") != 0 && heep_core_data_req_i.req && heep_core_data_req_i.we)
$display("write addr=0x%08x: data=0x%08x", heep_core_data_req_i.addr,
heep_core_data_req_i.wdata);
end
`endif
// 1-to-2 forward crossbars
// ------------------------
// These crossbars forward each external master to a port on the external
// crossbar or to the corresponding slave port of X-HEEP.
generate
for (genvar i = 0; unsigned'(i) < EXT_XBAR_NMASTER; i++) begin : gen_demux_xbar
xbar_varlat_one_to_n #(
.XBAR_NSLAVE(32'd2), // internal crossbar + external crossbar
.NUM_RULES (32'd1) // only the external address space is defined
) demux_xbar_i (
.clk_i (clk_i),
.rst_ni (rst_ni),
.addr_map_i (DEMUX_XBAR_ADDR_RULES),
.default_idx_i(DEMUX_XBAR_INT_SLAVE_IDX[0:0]),
.master_req_i (ext_master_req_i[i]),
.master_resp_o(ext_master_resp_o[i]),
.slave_req_o (demux_xbar_req[i]),
.slave_resp_i (demux_xbar_resp[i])
);
end
endgenerate
// External system crossbar
// ------------------------
ext_xbar #(
.XBAR_NMASTER(SYSTEM_XBAR_NMASTER + EXT_XBAR_NMASTER),
.XBAR_NSLAVE (EXT_XBAR_NSLAVE)
) ext_xbar_i (
.clk_i(clk_i),
.rst_ni(rst_ni),
.addr_map_i(addr_map_i),
.default_idx_i(default_idx_i),
.master_req_i(master_req),
.master_resp_o(master_resp),
.slave_req_o(ext_slave_req_o),
.slave_resp_i(ext_slave_resp_i)
);
endmodule