blob: 45a43010484508ae22ca1e955027745193be8539 [file] [log] [blame]
Sylvain Munaut21b03ba2020-09-14 10:01:45 +02001/*
2 * soc_iobuf.v
3 *
4 * vim: ts=4 sw=4
5 *
6 * Copyright (C) 2019-2020 Sylvain Munaut <tnt@246tNt.com>
7 * SPDX-License-Identifier: CERN-OHL-S-2.0
8 */
9
10`default_nettype none
11
12module soc_iobuf (
13 // Wishbone slave (from CPU)
14 input wire [15:0] wb_cpu_addr,
15 output wire [31:0] wb_cpu_rdata,
16 input wire [31:0] wb_cpu_wdata,
17 input wire [ 3:0] wb_cpu_wmsk,
18 input wire wb_cpu_we,
19 input wire [ 2:0] wb_cpu_cyc, // 0=EP buf, 1=SPRAM, 2=DMA
20 output wire [ 2:0] wb_cpu_ack,
21
22 // Wishbone slave (from E1)
23 input wire [13:0] wb_e1_addr,
24 output wire [31:0] wb_e1_rdata,
25 input wire [31:0] wb_e1_wdata,
26 input wire [ 3:0] wb_e1_wmsk,
27 input wire wb_e1_we,
28 input wire wb_e1_cyc,
29 output wire wb_e1_ack,
30
31 // USB EP-Buf master
32 output wire [ 8:0] ep_tx_addr_0,
33 output wire [31:0] ep_tx_data_0,
34 output wire ep_tx_we_0,
35
36 output wire [ 8:0] ep_rx_addr_0,
37 input wire [31:0] ep_rx_data_1,
38 output wire ep_rx_re_0,
39
40 /* Clock / Reset */
41 input wire clk,
42 input wire rst
43);
44
45 // Signals
46 // -------
47
48 // SPRAM
49 wire [13:0] spr_addr;
50 wire [31:0] spr_rdata;
51 wire [31:0] spr_wdata;
52 wire [ 3:0] spr_wmsk;
53 wire spr_we;
54 wire spr_cyc;
55 wire spr_ack;
56
57 wire [13:0] spr0_addr;
58 wire [31:0] spr0_rdata;
59 wire [31:0] spr0_wdata;
60 wire [ 3:0] spr0_wmsk;
61 wire spr0_we;
62 wire spr0_cyc;
63 wire spr0_ack;
64
65 wire [13:0] spr1_addr;
66 wire [31:0] spr1_rdata;
67 wire [31:0] spr1_wdata;
68 wire [ 3:0] spr1_wmsk;
69 wire spr1_we;
70 wire spr1_cyc;
71 wire spr1_ack;
72
73 wire [13:0] spr2_addr;
74 wire [31:0] spr2_rdata;
75 wire [31:0] spr2_wdata;
76 wire [ 3:0] spr2_wmsk;
77 wire spr2_we;
78 wire spr2_cyc;
79 wire spr2_ack;
80
81 // EP Buffer
82 wire [ 8:0] epb_addr;
83 wire [31:0] epb_rdata;
84 wire [31:0] epb_wdata;
85 wire epb_we;
86 wire epb_cyc;
87 wire epb_ack;
88
89 wire [ 8:0] epb0_addr;
90 wire [31:0] epb0_rdata;
91 wire [31:0] epb0_wdata;
92 wire epb0_we;
93 wire epb0_cyc;
94 wire epb0_ack;
95
96 wire [ 8:0] epb1_addr;
97 wire [31:0] epb1_rdata;
98 wire [31:0] epb1_wdata;
99 wire epb1_we;
100 wire epb1_cyc;
101 wire epb1_ack;
102
103 // DMA
104 wire [31:0] wb_rdata_dma;
105
106
107 // SPRAM
108 // -----
109
110 // Instance
111 ice40_spram_wb #(
112 .DW(32),
113 .AW(14),
114 .ZERO_RDATA(0)
115 ) spram_I (
116 .wb_addr (spr_addr),
117 .wb_rdata(spr_rdata),
118 .wb_wdata(spr_wdata),
119 .wb_wmsk (spr_wmsk),
120 .wb_we (spr_we),
121 .wb_cyc (spr_cyc),
122 .wb_ack (spr_ack),
123 .clk (clk),
124 .rst (rst)
125 );
126
127 // Arbiter
128 wb_arbiter #(
129 .N(3),
130 .DW(32),
131 .AW(14)
132 ) spram_arb_I (
133 .s_addr ({spr2_addr, spr1_addr, spr0_addr}),
134 .s_rdata({spr2_rdata, spr1_rdata, spr0_rdata}),
135 .s_wdata({spr2_wdata, spr1_wdata, spr0_wdata}),
136 .s_wmsk ({spr2_wmsk, spr1_wmsk, spr0_wmsk}),
137 .s_we ({spr2_we, spr1_we, spr0_we}),
138 .s_cyc ({spr2_cyc, spr1_cyc, spr0_cyc}),
139 .s_ack ({spr2_ack, spr1_ack, spr0_ack}),
140 .m_addr (spr_addr),
141 .m_rdata(spr_rdata),
142 .m_wdata(spr_wdata),
143 .m_wmsk (spr_wmsk),
144 .m_we (spr_we),
145 .m_cyc (spr_cyc),
146 .m_ack (spr_ack),
147 .clk (clk),
148 .rst (rst)
149 );
150
151
152 // EP buffer
153 // ---------
154
155 // Instance
156 wb_epbuf #(
157 .AW(9),
158 .DW(32)
159 ) epbuf_I (
160 .wb_addr (epb_addr),
161 .wb_rdata (epb_rdata),
162 .wb_wdata (epb_wdata),
163 .wb_we (epb_we),
164 .wb_cyc (epb_cyc),
165 .wb_ack (epb_ack),
166 .ep_tx_addr_0(ep_tx_addr_0),
167 .ep_tx_data_0(ep_tx_data_0),
168 .ep_tx_we_0 (ep_tx_we_0),
169 .ep_rx_addr_0(ep_rx_addr_0),
170 .ep_rx_data_1(ep_rx_data_1),
171 .ep_rx_re_0 (ep_rx_re_0),
172 .clk (clk),
173 .rst (rst)
174 );
175
176 // Arbiter
177 wb_arbiter #(
178 .N(2),
179 .DW(32),
180 .AW(9)
181 ) epbam_arb_I (
182 .s_addr ({epb1_addr, epb0_addr}),
183 .s_rdata({epb1_rdata, epb0_rdata}),
184 .s_wdata({epb1_wdata, epb0_wdata}),
185 .s_wmsk (8'hff),
186 .s_we ({epb1_we, epb0_we}),
187 .s_cyc ({epb1_cyc, epb0_cyc}),
188 .s_ack ({epb1_ack, epb0_ack}),
189 .m_addr (epb_addr),
190 .m_rdata(epb_rdata),
191 .m_wdata(epb_wdata),
192 .m_we (epb_we),
193 .m_cyc (epb_cyc),
194 .m_ack (epb_ack),
195 .clk (clk),
196 .rst (rst)
197 );
198
199
200 // DMA
201 // ---
202
203 wb_dma #(
204 .A0W(14),
205 .A1W(9),
206 .DW(32)
207 ) dma_I (
208 .m0_addr (spr2_addr),
209 .m0_rdata (spr2_rdata),
210 .m0_wdata (spr2_wdata),
211 .m0_we (spr2_we),
212 .m0_cyc (spr2_cyc),
213 .m0_ack (spr2_ack),
214 .m1_addr (epb1_addr),
215 .m1_rdata (epb1_rdata),
216 .m1_wdata (epb1_wdata),
217 .m1_we (epb1_we),
218 .m1_cyc (epb1_cyc),
219 .m1_ack (epb1_ack),
220 .ctl_addr (wb_cpu_addr[1:0]),
221 .ctl_rdata(wb_rdata_dma),
222 .ctl_wdata(wb_cpu_wdata),
223 .ctl_we (wb_cpu_we),
224 .ctl_cyc (wb_cpu_cyc[2]),
225 .ctl_ack (wb_cpu_ack[2]),
226 .clk (clk),
227 .rst (rst)
228 );
229
230 assign spr2_wmsk = 4'h0;
231
232
233 // External accesses
234 // -----------------
235
236 // CPU
237 assign spr1_addr = wb_cpu_addr[13:0];
238 assign spr1_wdata = wb_cpu_wdata;
239 assign spr1_wmsk = wb_cpu_wmsk;
240 assign spr1_we = wb_cpu_we;
241 assign spr1_cyc = wb_cpu_cyc[1];
242 assign wb_cpu_ack[1] = spr1_ack;
243
244 assign epb0_addr = wb_cpu_addr[8:0];
245 assign epb0_wdata = wb_cpu_wdata;
246 assign epb0_we = wb_cpu_we;
247 assign epb0_cyc = wb_cpu_cyc[0];
248 assign wb_cpu_ack[0] = epb0_ack;
249
250 assign wb_cpu_rdata = spr1_rdata | epb0_rdata | wb_rdata_dma;
251
252 // E1
253 assign spr0_addr = wb_e1_addr;
254 assign spr0_wdata = wb_e1_wdata;
255 assign spr0_wmsk = wb_e1_wmsk;
256 assign spr0_we = wb_e1_we;
257 assign spr0_cyc = wb_e1_cyc;
258 assign wb_e1_rdata = spr0_rdata;
259 assign wb_e1_ack = spr0_ack;
260
261endmodule // soc_iobuf