f655180e0d8ac059f4f0b84dcc7348b9c9715da4
[mw/milkymist.git] / cores / conbus / rtl / conbus.v
1 /*
2  * Wishbone Arbiter and Address Decoder
3  * Copyright (C) 2008, 2009, 2010 Sebastien Bourdeauducq
4  * Copyright (C) 2000 Johny Chi - chisuhua@yahoo.com.cn
5  * This file is part of Milkymist.
6  *
7  * This source file may be used and distributed without
8  * restriction provided that this copyright statement is not
9  * removed from the file and that any derivative work contains
10  * the original copyright notice and the associated disclaimer.
11  *
12  * This source file is free software; you can redistribute it
13  * and/or modify it under the terms of the GNU Lesser General
14  * Public License as published by the Free Software Foundation;
15  * either version 2.1 of the License, or (at your option) any
16  * later version.
17  *
18  * This source is distributed in the hope that it will be
19  * useful, but WITHOUT ANY WARRANTY; without even the implied
20  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
21  * PURPOSE.  See the GNU Lesser General Public License for more
22  * details.
23  *
24  * You should have received a copy of the GNU Lesser General
25  * Public License along with this source; if not, download it
26  * from http://www.opencores.org/lgpl.shtml.
27  */
28
29 module conbus #(
30         parameter s_addr_w = 4,
31         parameter s0_addr = 4'h0,
32         parameter s1_addr = 4'h1,
33         parameter s2_addr = 4'h2,
34         parameter s3_addr = 4'h3,
35         parameter s4_addr = 4'h4
36 ) (
37         input sys_clk,
38         input sys_rst,
39         
40         // Master 0 Interface
41         input   [31:0]  m0_dat_i,
42         output  [31:0]  m0_dat_o,
43         input   [31:0]  m0_adr_i,
44         input   [2:0]   m0_cti_i,
45         input   [3:0]   m0_sel_i,
46         input           m0_we_i,
47         input           m0_cyc_i,
48         input           m0_stb_i,
49         output          m0_ack_o,
50         
51         // Master 1 Interface
52         input   [31:0]  m1_dat_i,
53         output  [31:0]  m1_dat_o,
54         input   [31:0]  m1_adr_i,
55         input   [2:0]   m1_cti_i,
56         input   [3:0]   m1_sel_i,
57         input           m1_we_i,
58         input           m1_cyc_i,
59         input           m1_stb_i,
60         output          m1_ack_o,
61         
62         // Master 2 Interface
63         input   [31:0]  m2_dat_i,
64         output  [31:0]  m2_dat_o,
65         input   [31:0]  m2_adr_i,
66         input   [2:0]   m2_cti_i,
67         input   [3:0]   m2_sel_i,
68         input           m2_we_i,
69         input           m2_cyc_i,
70         input           m2_stb_i,
71         output          m2_ack_o,
72         
73         // Master 3 Interface
74         input   [31:0]  m3_dat_i,
75         output  [31:0]  m3_dat_o,
76         input   [31:0]  m3_adr_i,
77         input   [2:0]   m3_cti_i,
78         input   [3:0]   m3_sel_i,
79         input           m3_we_i,
80         input           m3_cyc_i,
81         input           m3_stb_i,
82         output          m3_ack_o,
83         
84         // Master 4 Interface
85         input   [31:0]  m4_dat_i,
86         output  [31:0]  m4_dat_o,
87         input   [31:0]  m4_adr_i,
88         input   [2:0]   m4_cti_i,
89         input   [3:0]   m4_sel_i,
90         input           m4_we_i,
91         input           m4_cyc_i,
92         input           m4_stb_i,
93         output          m4_ack_o,
94
95         // Master 5 Interface
96         input   [31:0]  m5_dat_i,
97         output  [31:0]  m5_dat_o,
98         input   [31:0]  m5_adr_i,
99         input   [2:0]   m5_cti_i,
100         input   [3:0]   m5_sel_i,
101         input           m5_we_i,
102         input           m5_cyc_i,
103         input           m5_stb_i,
104         output          m5_ack_o,
105
106         // Master 6 Interface
107         input   [31:0]  m6_dat_i,
108         output  [31:0]  m6_dat_o,
109         input   [31:0]  m6_adr_i,
110         input   [2:0]   m6_cti_i,
111         input   [3:0]   m6_sel_i,
112         input           m6_we_i,
113         input           m6_cyc_i,
114         input           m6_stb_i,
115         output          m6_ack_o,
116
117         
118         // Slave 0 Interface
119         input   [31:0]  s0_dat_i,
120         output  [31:0]  s0_dat_o,
121         output  [31:0]  s0_adr_o,
122         output  [2:0]   s0_cti_o,
123         output  [3:0]   s0_sel_o,
124         output          s0_we_o,
125         output          s0_cyc_o,
126         output          s0_stb_o,
127         input           s0_ack_i,
128         
129         // Slave 1 Interface
130         input   [31:0]  s1_dat_i,
131         output  [31:0]  s1_dat_o,
132         output  [31:0]  s1_adr_o,
133         output  [2:0]   s1_cti_o,
134         output  [3:0]   s1_sel_o,
135         output          s1_we_o,
136         output          s1_cyc_o,
137         output          s1_stb_o,
138         input           s1_ack_i,
139         
140         // Slave 2 Interface
141         input   [31:0]  s2_dat_i,
142         output  [31:0]  s2_dat_o,
143         output  [31:0]  s2_adr_o,
144         output  [2:0]   s2_cti_o,
145         output  [3:0]   s2_sel_o,
146         output          s2_we_o,
147         output          s2_cyc_o,
148         output          s2_stb_o,
149         input           s2_ack_i,
150         
151         // Slave 3 Interface
152         input   [31:0]  s3_dat_i,
153         output  [31:0]  s3_dat_o,
154         output  [31:0]  s3_adr_o,
155         output  [2:0]   s3_cti_o,
156         output  [3:0]   s3_sel_o,
157         output          s3_we_o,
158         output          s3_cyc_o,
159         output          s3_stb_o,
160         input           s3_ack_i,
161         
162         // Slave 4 Interface
163         input   [31:0]  s4_dat_i,
164         output  [31:0]  s4_dat_o,
165         output  [31:0]  s4_adr_o,
166         output  [2:0]   s4_cti_o,
167         output  [3:0]   s4_sel_o,
168         output          s4_we_o,
169         output          s4_cyc_o,
170         output          s4_stb_o,
171         input           s4_ack_i
172 );
173
174 // address + CTI + data + byte select
175 // + cyc + we + stb
176 `define mbusw_ls  32 + 3 + 32 + 4 + 3
177
178 wire [4:0] slave_sel;
179 wire [6:0] gnt;
180 wire [`mbusw_ls -1:0] i_bus_m;  // internal shared bus, master data and control to slave
181 wire [31:0] i_dat_s;            // internal shared bus, slave data to master
182 wire i_bus_ack;                 // internal shared bus, ack signal
183
184 // master 0
185 assign m0_dat_o = i_dat_s;
186 assign m0_ack_o = i_bus_ack & gnt[0];
187
188 // master 1
189 assign m1_dat_o = i_dat_s;
190 assign m1_ack_o = i_bus_ack & gnt[1];
191
192 // master 2
193 assign m2_dat_o = i_dat_s;
194 assign m2_ack_o = i_bus_ack & gnt[2];
195
196 // master 3
197 assign m3_dat_o = i_dat_s;
198 assign m3_ack_o = i_bus_ack & gnt[3];
199
200 // master 4
201 assign m4_dat_o = i_dat_s;
202 assign m4_ack_o = i_bus_ack & gnt[4];
203
204 // master 5
205 assign m5_dat_o = i_dat_s;
206 assign m5_ack_o = i_bus_ack & gnt[5];
207
208 // master 6
209 assign m6_dat_o = i_dat_s;
210 assign m6_ack_o = i_bus_ack & gnt[6];
211
212 assign i_bus_ack = s0_ack_i | s1_ack_i | s2_ack_i | s3_ack_i | s4_ack_i;
213
214 // slave 0
215 assign {s0_adr_o, s0_cti_o, s0_sel_o, s0_dat_o, s0_we_o, s0_cyc_o} = i_bus_m[`mbusw_ls -1:1];
216 assign s0_stb_o = i_bus_m[1] & i_bus_m[0] & slave_sel[0];  // stb_o = cyc_i & stb_i & slave_sel
217
218 // slave 1
219 assign {s1_adr_o, s1_cti_o, s1_sel_o, s1_dat_o, s1_we_o, s1_cyc_o} = i_bus_m[`mbusw_ls -1:1];
220 assign s1_stb_o = i_bus_m[1] & i_bus_m[0] & slave_sel[1];
221
222 // slave 2
223 assign {s2_adr_o, s2_cti_o, s2_sel_o, s2_dat_o, s2_we_o, s2_cyc_o} = i_bus_m[`mbusw_ls -1:1];
224 assign s2_stb_o = i_bus_m[1] & i_bus_m[0] & slave_sel[2];
225
226 // slave 3
227 assign {s3_adr_o, s3_cti_o, s3_sel_o, s3_dat_o, s3_we_o, s3_cyc_o} = i_bus_m[`mbusw_ls -1:1];
228 assign s3_stb_o = i_bus_m[1] & i_bus_m[0] & slave_sel[3];
229
230 // slave 4
231 assign {s4_adr_o, s4_cti_o, s4_sel_o, s4_dat_o, s4_we_o, s4_cyc_o} = i_bus_m[`mbusw_ls -1:1];
232 assign s4_stb_o = i_bus_m[1] & i_bus_m[0] & slave_sel[4];
233
234 assign i_bus_m =
235          ({`mbusw_ls{gnt[0]}} & {m0_adr_i, m0_cti_i, m0_sel_i, m0_dat_i, m0_we_i, m0_cyc_i, m0_stb_i})
236         |({`mbusw_ls{gnt[1]}} & {m1_adr_i, m1_cti_i, m1_sel_i, m1_dat_i, m1_we_i, m1_cyc_i, m1_stb_i})
237         |({`mbusw_ls{gnt[2]}} & {m2_adr_i, m2_cti_i, m2_sel_i, m2_dat_i, m2_we_i, m2_cyc_i, m2_stb_i})
238         |({`mbusw_ls{gnt[3]}} & {m3_adr_i, m3_cti_i, m3_sel_i, m3_dat_i, m3_we_i, m3_cyc_i, m3_stb_i})
239         |({`mbusw_ls{gnt[4]}} & {m4_adr_i, m4_cti_i, m4_sel_i, m4_dat_i, m4_we_i, m4_cyc_i, m4_stb_i})
240         |({`mbusw_ls{gnt[5]}} & {m5_adr_i, m5_cti_i, m5_sel_i, m5_dat_i, m5_we_i, m5_cyc_i, m5_stb_i})
241         |({`mbusw_ls{gnt[6]}} & {m6_adr_i, m6_cti_i, m6_sel_i, m6_dat_i, m6_we_i, m6_cyc_i, m6_stb_i});
242
243 assign i_dat_s =
244                  ({32{slave_sel[ 0]}} & s0_dat_i)
245                 |({32{slave_sel[ 1]}} & s1_dat_i)
246                 |({32{slave_sel[ 2]}} & s2_dat_i)
247                 |({32{slave_sel[ 3]}} & s3_dat_i)
248                 |({32{slave_sel[ 4]}} & s4_dat_i);
249
250 wire [6:0] req = {m6_cyc_i, m5_cyc_i, m4_cyc_i, m3_cyc_i, m2_cyc_i, m1_cyc_i, m0_cyc_i};
251
252 conbus_arb conbus_arb(
253         .sys_clk(sys_clk),
254         .sys_rst(sys_rst),
255         .req(req),
256         .gnt(gnt)
257 );
258
259 assign slave_sel[0] = (i_bus_m[`mbusw_ls-1 : `mbusw_ls-s_addr_w] == s0_addr);
260 assign slave_sel[1] = (i_bus_m[`mbusw_ls-1 : `mbusw_ls-s_addr_w] == s1_addr);
261 assign slave_sel[2] = (i_bus_m[`mbusw_ls-1 : `mbusw_ls-s_addr_w] == s2_addr);
262 assign slave_sel[3] = (i_bus_m[`mbusw_ls-1 : `mbusw_ls-s_addr_w] == s3_addr);
263 assign slave_sel[4] = (i_bus_m[`mbusw_ls-1 : `mbusw_ls-s_addr_w] == s4_addr);
264
265 endmodule