3 module slave_dispatcher
9 output wire [17:0] S0_ADR_I
,
10 output wire [15:0] S0_DAT_I
,
11 input wire [15:0] S0_DAT_O
,
14 input wire S0_STALL_O
,
17 output wire [17:0] S1_ADR_I
,
18 output wire [15:0] S1_DAT_I
,
19 input wire [15:0] S1_DAT_O
,
22 input wire S1_STALL_O
,
25 output wire [16:0] S2_ADR_I
,
26 output wire [15:0] S2_DAT_I
,
27 input wire [15:0] S2_DAT_O
,
30 input wire S2_STALL_O
,
33 output wire [16:0] S3_ADR_I
,
34 output wire [15:0] S3_DAT_I
,
35 input wire [15:0] S3_DAT_O
,
38 input wire S3_STALL_O
,
41 output wire [16:0] S4_ADR_I
,
42 output wire [15:0] S4_DAT_I
,
43 input wire [15:0] S4_DAT_O
,
46 input wire S4_STALL_O
,
49 output wire [16:0] S5_ADR_I
,
50 output wire [15:0] S5_DAT_I
,
51 input wire [15:0] S5_DAT_O
,
54 input wire S5_STALL_O
,
56 output wire S_COMBINED_ACK_O
,
57 input wire [19:0] S_COMBINED_ADR_I
,
58 input wire [15:0] S_COMBINED_DAT_I
,
59 output wire [15:0] S_COMBINED_DAT_O
,
60 input wire S_COMBINED_STB_I
,
61 input wire S_COMBINED_WE_I
,
62 output wire S_COMBINED_STALL_O
67 wire [15:0] datas
[0:5];
68 assign acks
= {S0_ACK_O
, S1_ACK_O
, S2_ACK_O
, S3_ACK_O
, S4_ACK_O
, S5_ACK_O
};
69 assign stalls
= {S0_STALL_O
, S1_STALL_O
, S2_STALL_O
,
70 S3_STALL_O
, S4_STALL_O
, S5_STALL_O
};
71 assign datas
[0] = S0_DAT_O
;
72 assign datas
[1] = S1_DAT_O
;
73 assign datas
[2] = S2_DAT_O
;
74 assign datas
[3] = S3_DAT_O
;
75 assign datas
[4] = S4_DAT_O
;
76 assign datas
[5] = S5_DAT_O
;
78 reg [1:0] commands_awaiting
;
79 reg [2:0] slave_last_accessed
;
82 wire [2:0] slave_accessed
;
83 wire [2:0] slave_requested
;
85 wire [1:0] commands_awaiting_next_tick
;
86 assign working
= commands_awaiting || S_COMBINED_STB_I
;
87 assign slave_requested
= S_COMBINED_ADR_I
[19] ?
88 /* one of 4 smaller slaves */
89 S_COMBINED_ADR_I
[18:17] + 2 :
90 /* one of 2 bigger slaves */
91 S_COMBINED_ADR_I
[19:18];
92 assign slave_accessed
= commands_awaiting ? slave_last_accessed
:
94 assign S_COMBINED_ACK_O
= acks
[slave_accessed
] && working
;
95 assign S_COMBINED_DAT_O
= datas
[slave_accessed
];
96 assign slave_switch
= slave_accessed
!= slave_requested
;
97 assign S_COMBINED_STALL_O
= stalls
[slave_accessed
] || slave_switch ||
98 (commands_awaiting
== 3 && !S_COMBINED_ACK_O
);
99 assign commands_awaiting_next_tick
100 = commands_awaiting
- S_COMBINED_ACK_O
+
101 (S_COMBINED_STB_I
&& !S_COMBINED_STALL_O
);
104 /* anything could be latched here, this is just to avoid undefined values */
106 slave_last_accessed
<= 0;
107 commands_awaiting
<= 2; /* It is supposed to be driven low by RST */
111 always @ (posedge CLK
) begin
112 slave_last_accessed
<= slave_accessed
;
115 commands_awaiting
<= 0;
117 commands_awaiting
<= commands_awaiting_next_tick
;
120 assign S0_ADR_I
= S_COMBINED_ADR_I
[17:0];
121 assign S1_ADR_I
= S_COMBINED_ADR_I
[17:0];
122 assign S2_ADR_I
= S_COMBINED_ADR_I
[16:0];
123 assign S3_ADR_I
= S_COMBINED_ADR_I
[16:0];
124 assign S4_ADR_I
= S_COMBINED_ADR_I
[16:0];
125 assign S5_ADR_I
= S_COMBINED_ADR_I
[16:0];
127 assign S0_DAT_I
= S_COMBINED_DAT_I
;
128 assign S1_DAT_I
= S_COMBINED_DAT_I
;
129 assign S2_DAT_I
= S_COMBINED_DAT_I
;
130 assign S3_DAT_I
= S_COMBINED_DAT_I
;
131 assign S4_DAT_I
= S_COMBINED_DAT_I
;
132 assign S5_DAT_I
= S_COMBINED_DAT_I
;
135 assign pass_strobe
= S_COMBINED_STB_I
&& !slave_switch
&&
136 (commands_awaiting
!= 3 || S_COMBINED_ACK_O
);
138 assign S0_STB_I
= slave_accessed
== 0 && pass_strobe
;
139 assign S1_STB_I
= slave_accessed
== 1 && pass_strobe
;
140 assign S2_STB_I
= slave_accessed
== 2 && pass_strobe
;
141 assign S3_STB_I
= slave_accessed
== 3 && pass_strobe
;
142 assign S4_STB_I
= slave_accessed
== 4 && pass_strobe
;
143 assign S5_STB_I
= slave_accessed
== 5 && pass_strobe
;
145 assign S0_WE_I
= S_COMBINED_WE_I
;
146 assign S1_WE_I
= S_COMBINED_WE_I
;
147 assign S2_WE_I
= S_COMBINED_WE_I
;
148 assign S3_WE_I
= S_COMBINED_WE_I
;
149 assign S4_WE_I
= S_COMBINED_WE_I
;
150 assign S5_WE_I
= S_COMBINED_WE_I
;
151 endmodule // slave_dispatcher