1 |
2 |
joff |
/* Copyright 2005-2006, Technologic Systems
|
2 |
|
|
* All Rights Reserved.
|
3 |
|
|
*
|
4 |
|
|
* Author(s): Jesse Off <joff@embeddedARM.com>
|
5 |
|
|
*
|
6 |
|
|
* Boilerplate Verilog for use in Technologic Systems TS-7300 FPGA computer
|
7 |
|
|
* at http://www.embeddedarm.com/epc/ts7300-spec-h.htm. Implements bus cycle
|
8 |
|
|
* demultiplexing to an internal 16 and 32 bit WISHBONE bus, and 10/100
|
9 |
|
|
* ethernet interface.
|
10 |
|
|
*
|
11 |
|
|
* Full-featured FPGA bitstream from Technologic Systems includes "TS-SDCORE"
|
12 |
|
|
* SD card core, 8 "TS-UART" serial ports, "TS-VIDCORE" VGA video framebuffer and
|
13 |
|
|
* accelerator, and 2 PWM/Timer/Counter "TS-XDIO" cores for the various GPIO
|
14 |
|
|
* pins. Binary bitstream comes with board. Contact Technologic Systems
|
15 |
|
|
* for custom FPGA development on the TS-7300 or for non-GPL licensing of this
|
16 |
|
|
* or any of the above (not-included-here) TS-cores and OS drivers.
|
17 |
|
|
*
|
18 |
|
|
* To load the bitstream to the FPGA on the TS-7300, Technologic Systems provides
|
19 |
|
|
* a Linux program "load_ts7300" that takes the ts7300_top.rbf file generated
|
20 |
|
|
* by Altera's Quartus II on the Linux flash filesystem (yaffs, ext2,
|
21 |
|
|
* jffs2, etc..) and loads the FPGA. Loading the FPGA takes approx 0.2 seconds
|
22 |
|
|
* this way and can be done (and re-done) at any time during power-up without
|
23 |
|
|
* any special JTAG/ISP cables.
|
24 |
|
|
*/
|
25 |
|
|
|
26 |
|
|
/*
|
27 |
|
|
* This program is free software; you can redistribute it and/or modify
|
28 |
|
|
* it under the terms of the GNU General Public License v2 as published by
|
29 |
|
|
* the Free Software Foundation.
|
30 |
|
|
*
|
31 |
|
|
* This program is distributed in the hope that it will be useful,
|
32 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
33 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
34 |
|
|
* GNU General Public License for more details.
|
35 |
|
|
|
36 |
|
|
* You should have received a copy of the GNU General Public License
|
37 |
|
|
* along with this program; if not, write to the Free Software
|
38 |
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
39 |
|
|
*/
|
40 |
|
|
|
41 |
|
|
/* This module is a sample dummy stub that can be filled in by the user. Any access's on
|
42 |
|
|
* the TS-7300 CPU for address 0x72a00000 to 0x72fffffc arrive here. Keep in mind
|
43 |
|
|
* the address is a word address not the byte address and address 0x0 is 0x72000000.
|
44 |
|
|
* The interface used here is the WISHBONE bus, described in detail on
|
45 |
|
|
* http://www.opencores.org
|
46 |
|
|
*
|
47 |
|
|
* There is a 40-pin header next to the FPGA. It is broken up into 2 20 pin
|
48 |
|
|
* connectors. One is labeled DIO2 and contains the 18 dedicated GPIO pins. The
|
49 |
|
|
* other contains 17 signals that are used by the TS-VIDCORE but can also be used
|
50 |
|
|
* as GPIO if video is not used. DO NOT DRIVE THESE SIGNALS OVER 3.3V!!! They
|
51 |
|
|
* go straight into the FPGA pads unbuffered.
|
52 |
|
|
* ___________________________________________________________
|
53 |
|
|
* | 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40|
|
54 |
|
|
* | 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39|
|
55 |
|
|
* \-----------------------------------------------------------/
|
56 |
|
|
* * | * DIO2
|
57 |
|
|
*
|
58 |
|
|
* pins #2 and #22 are grounds
|
59 |
|
|
* pin #20 is fused 5V (polyfuse)
|
60 |
|
|
* pin #40 is regulated 3.3V
|
61 |
|
|
* pin #18 can be externally driven high to disable DB15 VGA connector DACs
|
62 |
|
|
* pin #36 and #38 also go to the red and green LEDs (active low)
|
63 |
|
|
* pin #39 is a dedicated clock input and cannot be programmed for output
|
64 |
|
|
*
|
65 |
|
|
*/
|
66 |
|
|
module ts7300_wishbone_slave(
|
67 |
|
|
/* 75Mhz clock is fed to this module */
|
68 |
|
|
wb_clk_i,
|
69 |
|
|
wb_rst_i,
|
70 |
|
|
wb_adr_i,
|
71 |
|
|
wb_dat_i,
|
72 |
|
|
wb_cyc_i,
|
73 |
|
|
wb_stb_i,
|
74 |
|
|
wb_we_i,
|
75 |
|
|
wb_ack_o,
|
76 |
|
|
wb_dat_o,
|
77 |
|
|
|
78 |
|
|
/* This is the 40 pin header next to the FPGA */
|
79 |
|
|
headerpin_i,
|
80 |
|
|
headerpin_o,
|
81 |
|
|
headerpin_oe_o, /* output enable */
|
82 |
|
|
|
83 |
|
|
/* Use this for an IRQ on ARM IRQ #40 -- In Linux, be sure to
|
84 |
|
|
* use request_irq() with the SA_SHIRQ flag which enables
|
85 |
|
|
* sharing interrupts with the Linux ethernet driver.
|
86 |
|
|
*/
|
87 |
|
|
irq_o
|
88 |
|
|
);
|
89 |
|
|
|
90 |
|
|
input wb_clk_i;
|
91 |
|
|
input wb_rst_i;
|
92 |
|
|
input wb_cyc_i;
|
93 |
|
|
input wb_stb_i;
|
94 |
|
|
input wb_we_i;
|
95 |
|
|
input [21:0] wb_adr_i;
|
96 |
|
|
input [31:0] wb_dat_i;
|
97 |
|
|
output [31:0] wb_dat_o;
|
98 |
|
|
output wb_ack_o;
|
99 |
|
|
input [40:1] headerpin_i;
|
100 |
|
|
output [40:1] headerpin_o, headerpin_oe_o;
|
101 |
|
|
output irq_o;
|
102 |
|
|
|
103 |
|
|
/*
|
104 |
|
|
* BEGIN USER-SERVICEABLE SECTION
|
105 |
|
|
*
|
106 |
|
|
* The default here is to alias the entire space onto one 32-bit register "dummyreg"
|
107 |
|
|
* On reset, it is set to 0xdeadbeef but then retains the value last written to it.
|
108 |
|
|
* The value of this register drives GPIO pins 9-40 on the FPGA connector described
|
109 |
|
|
* above.
|
110 |
|
|
*/
|
111 |
|
|
|
112 |
|
|
reg [31:0] dummyreg;
|
113 |
|
|
|
114 |
|
|
assign wb_ack_o = wb_cyc_i && wb_stb_i; /* 0-wait state WISHBONE */
|
115 |
|
|
assign wb_dat_o = dummyreg;
|
116 |
|
|
assign headerpin_oe_o[40:1] = 40'hffffffffff; /* All outputs */
|
117 |
|
|
assign headerpin_o[40:1] = {dummyreg, 8'd0};
|
118 |
|
|
assign irq_o = 1'b0;
|
119 |
|
|
|
120 |
|
|
always @(posedge wb_clk_i) begin
|
121 |
|
|
if (wb_rst_i) dummyreg <= 32'hdeadbeef;
|
122 |
|
|
else if (wb_cyc_i && wb_stb_i && wb_we_i) dummyreg <= wb_dat_i;
|
123 |
|
|
end
|
124 |
|
|
|
125 |
|
|
/*
|
126 |
|
|
* END USER-SERVICEABLE SECTION
|
127 |
|
|
*/
|
128 |
|
|
|
129 |
|
|
endmodule
|
130 |
|
|
|
131 |
|
|
|
132 |
|
|
/* Now begins the real guts of the TS-7300 Cyclone2 EP2C8 FPGA
|
133 |
|
|
* boilerplate. You should only have to look below here if the above
|
134 |
|
|
* stub module isn't enough for you.
|
135 |
|
|
*/
|
136 |
|
|
module ts7300_top(
|
137 |
|
|
fl_d_pad,
|
138 |
|
|
bd_pad,
|
139 |
|
|
isa_add11_pad,
|
140 |
|
|
isa_add12_pad,
|
141 |
|
|
isa_add14_pad,
|
142 |
|
|
isa_add15_pad,
|
143 |
|
|
isa_add1_pad,
|
144 |
|
|
add_pad,
|
145 |
|
|
start_cycle_pad,
|
146 |
|
|
bd_oe_pad,
|
147 |
|
|
dio0to8_pad,
|
148 |
|
|
dio9_pad,
|
149 |
|
|
dio10to17_pad,
|
150 |
|
|
sdram_data_pad,
|
151 |
|
|
clk_25mhz_pad,
|
152 |
|
|
clk_75mhz_pad,
|
153 |
|
|
isa_wait_pad,
|
154 |
|
|
dma_req_pad,
|
155 |
|
|
irq7_pad,
|
156 |
|
|
sd_soft_power_pad,
|
157 |
|
|
sd_hard_power_pad,
|
158 |
|
|
sd_wprot_pad,
|
159 |
|
|
sd_present_pad,
|
160 |
|
|
sd_dat_pad,
|
161 |
|
|
sd_clk_pad,
|
162 |
|
|
sd_cmd_pad,
|
163 |
|
|
eth_mdio_pad,
|
164 |
|
|
eth_mdc_pad,
|
165 |
|
|
eth_rxdat_pad,
|
166 |
|
|
eth_rxdv_pad,
|
167 |
|
|
eth_rxclk_pad,
|
168 |
|
|
eth_rxerr_pad,
|
169 |
|
|
eth_txdat_pad,
|
170 |
|
|
eth_txclk_pad,
|
171 |
|
|
eth_txen_pad,
|
172 |
|
|
eth_txerr_pad,
|
173 |
|
|
eth_col_pad,
|
174 |
|
|
eth_crs_pad,
|
175 |
|
|
eth_pd_pad,
|
176 |
|
|
sdram_add_pad,
|
177 |
|
|
sdram_ras_pad,
|
178 |
|
|
sdram_cas_pad,
|
179 |
|
|
sdram_we_pad,
|
180 |
|
|
sdram_ba_pad,
|
181 |
|
|
sdram_clk_pad,
|
182 |
|
|
wr_232_pad,
|
183 |
|
|
rd_mux_pad,
|
184 |
|
|
mux_cntrl_pad,
|
185 |
|
|
mux_pad,
|
186 |
|
|
blue_pad,
|
187 |
|
|
red_pad,
|
188 |
|
|
green_pad,
|
189 |
|
|
hsync_pad,
|
190 |
|
|
vsync_pad
|
191 |
|
|
);
|
192 |
|
|
|
193 |
|
|
inout [7:0] fl_d_pad;
|
194 |
|
|
inout [7:0] bd_pad;
|
195 |
|
|
input isa_add11_pad;
|
196 |
|
|
input isa_add12_pad;
|
197 |
|
|
input isa_add14_pad;
|
198 |
|
|
input isa_add15_pad;
|
199 |
|
|
input isa_add1_pad;
|
200 |
|
|
input [3:0] add_pad;
|
201 |
|
|
input start_cycle_pad;
|
202 |
|
|
input bd_oe_pad;
|
203 |
|
|
inout reg [8:0] dio0to8_pad;
|
204 |
|
|
input dio9_pad;
|
205 |
|
|
inout reg [7:0] dio10to17_pad;
|
206 |
|
|
inout [15:0] sdram_data_pad;
|
207 |
|
|
input clk_25mhz_pad;
|
208 |
|
|
output clk_75mhz_pad;
|
209 |
|
|
inout isa_wait_pad;
|
210 |
|
|
inout dma_req_pad;
|
211 |
|
|
inout irq7_pad;
|
212 |
|
|
output sd_soft_power_pad;
|
213 |
|
|
output sd_hard_power_pad;
|
214 |
|
|
input sd_wprot_pad;
|
215 |
|
|
input sd_present_pad;
|
216 |
|
|
inout [3:0] sd_dat_pad;
|
217 |
|
|
output sd_clk_pad;
|
218 |
|
|
inout sd_cmd_pad;
|
219 |
|
|
inout eth_mdio_pad;
|
220 |
|
|
output eth_mdc_pad;
|
221 |
|
|
input [3:0] eth_rxdat_pad;
|
222 |
|
|
input eth_rxdv_pad;
|
223 |
|
|
input eth_rxclk_pad;
|
224 |
|
|
input eth_rxerr_pad;
|
225 |
|
|
output [3:0] eth_txdat_pad;
|
226 |
|
|
input eth_txclk_pad;
|
227 |
|
|
output eth_txen_pad;
|
228 |
|
|
output eth_txerr_pad;
|
229 |
|
|
input eth_col_pad;
|
230 |
|
|
input eth_crs_pad;
|
231 |
|
|
output eth_pd_pad;
|
232 |
|
|
output [12:0] sdram_add_pad;
|
233 |
|
|
output sdram_ras_pad;
|
234 |
|
|
output sdram_cas_pad;
|
235 |
|
|
output sdram_we_pad;
|
236 |
|
|
output [1:0] sdram_ba_pad;
|
237 |
|
|
output wr_232_pad;
|
238 |
|
|
output rd_mux_pad;
|
239 |
|
|
output mux_cntrl_pad;
|
240 |
|
|
inout [3:0] mux_pad;
|
241 |
|
|
inout reg [4:0] blue_pad;
|
242 |
|
|
inout reg [4:0] red_pad;
|
243 |
|
|
inout reg [4:0] green_pad;
|
244 |
|
|
inout reg hsync_pad;
|
245 |
|
|
inout reg vsync_pad;
|
246 |
|
|
output sdram_clk_pad;
|
247 |
|
|
|
248 |
4 |
joff |
/* Set to 1'b0 to disable ethernet. If you disable this, don't
|
249 |
|
|
* attempt to load the ethernet driver module! */
|
250 |
|
|
parameter ethernet = 1'b1;
|
251 |
|
|
|
252 |
2 |
joff |
/* Bus cycles from the ep9302 processor come in to the FPGA multiplexed by
|
253 |
|
|
* the MAX2 CPLD on the TS-7300. Any access on the ep9302 for addresses
|
254 |
|
|
* 0x72000000 - 0x72ffffff are routed to the FPGA. The ep9302 CS7 SMCBCR register
|
255 |
|
|
* at 0x8008001c physical should be set to 0x10004508 -- 16-bit,
|
256 |
|
|
* ~120 nS bus cycle. The FPGA must be loaded and sending 75Mhz to the MAX2
|
257 |
|
|
* on clk_75mhz_pad before any bus cycles are attempted.
|
258 |
|
|
*
|
259 |
|
|
* Since the native multiplexed bus is a little unfriendly to deal with
|
260 |
|
|
* and non-standard, as our first order of business we translate it into
|
261 |
|
|
* something more easily understood and better documented: a 16 bit WISHBONE bus.
|
262 |
|
|
*/
|
263 |
|
|
|
264 |
|
|
reg epwbm_done, epwbm_done32;
|
265 |
|
|
reg isa_add1_pad_q;
|
266 |
|
|
reg [23:0] ep93xx_address;
|
267 |
|
|
reg epwbm_we_o, epwbm_stb_o;
|
268 |
|
|
wire [23:0] epwbm_adr_o;
|
269 |
|
|
reg [15:0] epwbm_dat_o;
|
270 |
|
|
reg [15:0] epwbm_dat_i;
|
271 |
|
|
reg [15:0] ep93xx_dat_latch;
|
272 |
|
|
reg epwbm_ack_i;
|
273 |
|
|
wire epwbm_clk_o = clk_75mhz_pad;
|
274 |
|
|
wire epwbm_cyc_o = start_cycle_posedge_q;
|
275 |
|
|
wire ep93xx_databus_oe = !epwbm_we_o && start_cycle_posedge && !bd_oe_pad;
|
276 |
|
|
wire pll_locked, clk_150mhz;
|
277 |
|
|
wire epwbm_rst_o = !pll_locked;
|
278 |
|
|
|
279 |
|
|
assign fl_d_pad[7:0] = ep93xx_databus_oe ?
|
280 |
|
|
ep93xx_dat_latch[7:0] : 8'hzz;
|
281 |
|
|
assign bd_pad[7:0] = ep93xx_databus_oe ?
|
282 |
|
|
ep93xx_dat_latch[15:8] : 8'hzz;
|
283 |
|
|
assign isa_wait_pad = start_cycle_negedge ? epwbm_done : 1'bz;
|
284 |
|
|
assign epwbm_adr_o[23:2] = ep93xx_address[23:2];
|
285 |
3 |
joff |
reg ep93xx_address1_q;
|
286 |
2 |
joff |
assign epwbm_adr_o[0] = ep93xx_address[0];
|
287 |
3 |
joff |
assign epwbm_adr_o[1] = ep93xx_address1_q;
|
288 |
2 |
joff |
|
289 |
|
|
/* Use Altera's PLL to multiply 25Mhz from the ethernet PHY to 75Mhz */
|
290 |
|
|
pll clkgencore(
|
291 |
|
|
.inclk0(clk_25mhz_pad),
|
292 |
|
|
.c0(clk_150mhz),
|
293 |
|
|
.c1(clk_75mhz_pad),
|
294 |
|
|
.locked(pll_locked)
|
295 |
|
|
);
|
296 |
|
|
|
297 |
|
|
reg ep93xx_end, ep93xx_end_q;
|
298 |
|
|
reg start_cycle_negedge, start_cycle_posedge, bd_oe_negedge, bd_oe_posedge;
|
299 |
|
|
reg start_cycle_negedge_q, start_cycle_posedge_q;
|
300 |
|
|
reg bd_oe_negedge_q, bd_oe_posedge_q;
|
301 |
|
|
|
302 |
|
|
always @(posedge clk_75mhz_pad) begin
|
303 |
|
|
start_cycle_negedge_q <= start_cycle_negedge;
|
304 |
|
|
start_cycle_posedge_q <= start_cycle_posedge;
|
305 |
|
|
bd_oe_negedge_q <= bd_oe_negedge;
|
306 |
|
|
bd_oe_posedge_q <= bd_oe_posedge;
|
307 |
|
|
isa_add1_pad_q <= isa_add1_pad;
|
308 |
|
|
|
309 |
3 |
joff |
if ((bd_oe_negedge_q && epwbm_we_o) ||
|
310 |
|
|
(start_cycle_posedge_q && !epwbm_we_o) && !epwbm_done) begin
|
311 |
2 |
joff |
epwbm_stb_o <= 1'b1;
|
312 |
3 |
joff |
ep93xx_address1_q <= isa_add1_pad_q;
|
313 |
2 |
joff |
epwbm_dat_o <= {bd_pad[7:0], fl_d_pad[7:0]};
|
314 |
|
|
end
|
315 |
|
|
|
316 |
|
|
if (epwbm_stb_o && epwbm_ack_i) begin
|
317 |
|
|
epwbm_stb_o <= 1'b0;
|
318 |
|
|
epwbm_done <= 1'b1;
|
319 |
|
|
ep93xx_dat_latch <= epwbm_dat_i;
|
320 |
|
|
end
|
321 |
|
|
|
322 |
3 |
joff |
if (epwbm_done && !epwbm_done32 && (ep93xx_address[1] != isa_add1_pad_q)) begin
|
323 |
2 |
joff |
epwbm_done <= 1'b0;
|
324 |
|
|
epwbm_done32 <= 1'b1;
|
325 |
|
|
end
|
326 |
|
|
|
327 |
|
|
ep93xx_end_q <= 1'b0;
|
328 |
|
|
|
329 |
3 |
joff |
if ((start_cycle_negedge_q && start_cycle_posedge_q &&
|
330 |
|
|
bd_oe_negedge_q && bd_oe_posedge) || !pll_locked) begin
|
331 |
2 |
joff |
ep93xx_end <= 1'b1;
|
332 |
|
|
ep93xx_end_q <= 1'b0;
|
333 |
|
|
end
|
334 |
|
|
|
335 |
|
|
if (ep93xx_end) begin
|
336 |
|
|
ep93xx_end <= 1'b0;
|
337 |
|
|
ep93xx_end_q <= 1'b1;
|
338 |
|
|
epwbm_done32 <= 1'b0;
|
339 |
|
|
epwbm_stb_o <= 1'b0;
|
340 |
|
|
epwbm_done <= 1'b0;
|
341 |
|
|
start_cycle_negedge_q <= 1'b0;
|
342 |
|
|
start_cycle_posedge_q <= 1'b0;
|
343 |
|
|
bd_oe_negedge_q <= 1'b0;
|
344 |
|
|
bd_oe_posedge_q <= 1'b0;
|
345 |
|
|
end
|
346 |
|
|
end
|
347 |
|
|
|
348 |
|
|
wire start_cycle_negedge_aset = !start_cycle_pad && pll_locked;
|
349 |
|
|
always @(posedge ep93xx_end_q or posedge start_cycle_negedge_aset) begin
|
350 |
|
|
if (start_cycle_negedge_aset) start_cycle_negedge <= 1'b1;
|
351 |
|
|
else start_cycle_negedge <= 1'b0;
|
352 |
|
|
end
|
353 |
|
|
|
354 |
4 |
joff |
always @(posedge start_cycle_pad or posedge ep93xx_end_q) begin
|
355 |
|
|
if (ep93xx_end_q) start_cycle_posedge <= 1'b0;
|
356 |
|
|
else if (start_cycle_negedge) start_cycle_posedge <= 1'b1;
|
357 |
2 |
joff |
end
|
358 |
|
|
|
359 |
|
|
always @(posedge start_cycle_pad) begin
|
360 |
|
|
epwbm_we_o <= fl_d_pad[7];
|
361 |
|
|
ep93xx_address[23] <= fl_d_pad[0];
|
362 |
|
|
ep93xx_address[22] <= fl_d_pad[1];
|
363 |
|
|
ep93xx_address[21] <= fl_d_pad[2];
|
364 |
|
|
ep93xx_address[20:17] <= add_pad[3:0];
|
365 |
|
|
ep93xx_address[16] <= fl_d_pad[3];
|
366 |
|
|
ep93xx_address[15] <= isa_add15_pad;
|
367 |
|
|
ep93xx_address[14] <= isa_add14_pad;
|
368 |
|
|
ep93xx_address[13] <= fl_d_pad[4];
|
369 |
|
|
ep93xx_address[12] <= isa_add12_pad;
|
370 |
|
|
ep93xx_address[11] <= isa_add11_pad;
|
371 |
|
|
ep93xx_address[10] <= bd_pad[0];
|
372 |
|
|
ep93xx_address[9] <= bd_pad[1];
|
373 |
|
|
ep93xx_address[8] <= bd_pad[2];
|
374 |
|
|
ep93xx_address[7] <= bd_pad[3];
|
375 |
|
|
ep93xx_address[6] <= bd_pad[4];
|
376 |
|
|
ep93xx_address[5] <= bd_pad[5];
|
377 |
|
|
ep93xx_address[4] <= bd_pad[6];
|
378 |
|
|
ep93xx_address[3] <= bd_pad[7];
|
379 |
|
|
ep93xx_address[2] <= fl_d_pad[5];
|
380 |
|
|
ep93xx_address[1] <= isa_add1_pad;
|
381 |
|
|
ep93xx_address[0] <= fl_d_pad[6];
|
382 |
|
|
end
|
383 |
|
|
|
384 |
4 |
joff |
always @(negedge bd_oe_pad or posedge ep93xx_end_q) begin
|
385 |
|
|
if (ep93xx_end_q) bd_oe_negedge <= 1'b0;
|
386 |
|
|
else if (start_cycle_posedge) bd_oe_negedge <= 1'b1;
|
387 |
2 |
joff |
end
|
388 |
|
|
|
389 |
|
|
always @(posedge bd_oe_pad or posedge ep93xx_end_q) begin
|
390 |
|
|
if (ep93xx_end_q) bd_oe_posedge <= 1'b0;
|
391 |
|
|
else if (bd_oe_negedge) bd_oe_posedge <= 1'b1;
|
392 |
|
|
end
|
393 |
|
|
|
394 |
|
|
wire [15:0] epwbm_wb32m_bridgecore_dat;
|
395 |
|
|
wire epwbm_wb32m_bridgecore_ack;
|
396 |
|
|
wire [31:0] wb32m_dat_o;
|
397 |
|
|
reg [31:0] wb32m_dat_i;
|
398 |
|
|
wire [21:0] wb32m_adr_o;
|
399 |
|
|
wire [3:0] wb32m_sel_o;
|
400 |
|
|
wire wb32m_cyc_o, wb32m_stb_o, wb32m_we_o;
|
401 |
|
|
reg wb32m_ack_i;
|
402 |
|
|
wire wb32m_clk_o = epwbm_clk_o;
|
403 |
|
|
wire wb32m_rst_o = epwbm_rst_o;
|
404 |
|
|
wb32_bridge epwbm_wb32m_bridgecore(
|
405 |
|
|
.wb_clk_i(epwbm_clk_o),
|
406 |
|
|
.wb_rst_i(epwbm_rst_o),
|
407 |
|
|
|
408 |
|
|
.wb16_adr_i(epwbm_adr_o[23:1]),
|
409 |
|
|
.wb16_dat_i(epwbm_dat_o),
|
410 |
|
|
.wb16_dat_o(epwbm_wb32m_bridgecore_dat),
|
411 |
|
|
.wb16_cyc_i(epwbm_cyc_o),
|
412 |
|
|
.wb16_stb_i(epwbm_stb_o),
|
413 |
|
|
.wb16_we_i(epwbm_we_o),
|
414 |
|
|
.wb16_ack_o(epwbm_wb32m_bridgecore_ack),
|
415 |
|
|
|
416 |
|
|
.wbm_adr_o(wb32m_adr_o),
|
417 |
|
|
.wbm_dat_o(wb32m_dat_o),
|
418 |
|
|
.wbm_dat_i(wb32m_dat_i),
|
419 |
|
|
.wbm_cyc_o(wb32m_cyc_o),
|
420 |
|
|
.wbm_stb_o(wb32m_stb_o),
|
421 |
|
|
.wbm_we_o(wb32m_we_o),
|
422 |
|
|
.wbm_ack_i(wb32m_ack_i),
|
423 |
|
|
.wbm_sel_o(wb32m_sel_o)
|
424 |
|
|
);
|
425 |
|
|
|
426 |
|
|
/* At this point we have turned the multiplexed ep93xx bus cycle into a
|
427 |
|
|
* WISHBONE master bus cycle with the local regs/wires:
|
428 |
|
|
*
|
429 |
|
|
* [15:0] epwbm_dat_i -- WISHBONE master 16-bit databus input
|
430 |
|
|
* [15:0] epwbm_dat_o -- WISHBONE master 16-bit databus output
|
431 |
|
|
* epwbm_clk_o -- WISHBONE master clock output (75 Mhz)
|
432 |
|
|
* epwbm_rst_o -- WISHBONE master reset output
|
433 |
|
|
* [23:0] epwbm_adr_o -- WISHBONE byte address output
|
434 |
|
|
* epwbm_we_o -- WISHBONE master write enable output
|
435 |
|
|
* epwbm_stb_o -- WISHBONE master strobe output
|
436 |
|
|
* epwbm_cyc_o -- WISHBONE master cycle output
|
437 |
|
|
* epwbm_ack_i -- WISHBONE master ack input
|
438 |
|
|
*
|
439 |
|
|
* The WISHBONE slave or WISHBONE interconnect can withhold the bus cycle ack
|
440 |
|
|
* as long as necessary as the above logic will ensure the processor will be
|
441 |
|
|
* halted until the cycle is complete. In that regard, it is possible
|
442 |
|
|
* to lock up the processor if nothing acks the WISHBONE bus cycle. (!)
|
443 |
|
|
*
|
444 |
|
|
* Note that the above is only a 16-bit WISHBONE bus. A special WISHBONE
|
445 |
|
|
* to WISHBONE bridge is used to combine two back-to-back 16 bit reads or
|
446 |
|
|
* writes into a single atomic 32-bit WISHBONE bus cycle. Care should be
|
447 |
|
|
* taken to never issue a byte or halfword ARM insn (ldrh, strh, ldrb, strb) to
|
448 |
|
|
* address space handled here. This bridge is presented as a secondary
|
449 |
|
|
* WISHBONE master bus prefixed with wb32m_:
|
450 |
|
|
*
|
451 |
|
|
* [31:0] wb32m_dat_i -- WISHBONE master 32-bit databus input
|
452 |
|
|
* [31:0] wb32m_dat_o -- WISHBONE master 32-bit databus output
|
453 |
|
|
* wb32m_clk_o -- WISHBONE master clock output (75 Mhz)
|
454 |
|
|
* wb32m_rst_o -- WISHBONE master reset output
|
455 |
|
|
* [21:0] wb32m_adr_o -- WISHBONE master word address
|
456 |
|
|
* wb32m_we_o -- WISHBONE master write enable output
|
457 |
|
|
* wb32m_stb_o -- WISHBONE master strobe output
|
458 |
|
|
* wb32m_cyc_o -- WISHBONE master cycle output
|
459 |
|
|
* wb32m_ack_i -- WISHBONE master ack input
|
460 |
|
|
* wb32m_sel_o -- WISHBONE master select output -- always 4'b1111
|
461 |
|
|
*/
|
462 |
|
|
|
463 |
|
|
wire ethwbm_cyc_o, ethwbm_stb_o, ethwbm_we_o, ethwbm_ack_i;
|
464 |
|
|
wire [3:0] ethwbm_sel_o;
|
465 |
|
|
wire [31:0] ethwbm_dat_i, ethwbm_dat_o, ethwbm_adr_o;
|
466 |
|
|
wire ethramcore_ack;
|
467 |
|
|
wire [31:0] ethramcore_dat;
|
468 |
|
|
|
469 |
|
|
/* Ethernet packet ram from 0x7210_0000 - 0x7210_ffff (32-bit, 8Kbyte)
|
470 |
|
|
* This core is connected both to the ethernet core and to the 32-bit
|
471 |
|
|
* WISHBONE bridge for access by the ep9302 CPU. It has an internal 2-way
|
472 |
|
|
* arbiter between both its WISHBONE slave interfaces. It also endian-swaps
|
473 |
|
|
* so the CPU doesn't have to and Linux can just memcpy()* to copy from/to
|
474 |
|
|
* this 8Kbyte packet RAM 32-bits at a time. Technologic Systems provides
|
475 |
|
|
* an GPL Linux 2.4 driver for this implementation of the open ethernet
|
476 |
|
|
* core at these addresses.
|
477 |
|
|
*
|
478 |
|
|
* -- *Actually, it can't memcpy() if it uses the ARM ldm* and stm*
|
479 |
|
|
* instructions in this bus space since the ep9302 SMC strobes are
|
480 |
|
|
* not deasserted between consecutive accesses. CPU has to use memcpy()
|
481 |
|
|
* in terms of ldr and str ARM insns.
|
482 |
|
|
*/
|
483 |
|
|
reg ethramcore_stb;
|
484 |
|
|
wb32_blockram #(.endian_swap(1'b1)) ethramcore(
|
485 |
4 |
joff |
.wb_clk_i(wb32m_clk_o && ethernet),
|
486 |
2 |
joff |
.wb_rst_i(wb32m_rst_o),
|
487 |
4 |
joff |
.wb2_cyc_i(wb32m_cyc_o && ethernet),
|
488 |
2 |
joff |
.wb2_stb_i(ethramcore_stb),
|
489 |
|
|
.wb2_we_i(wb32m_we_o),
|
490 |
|
|
.wb2_adr_i(wb32m_adr_o[10:0]),
|
491 |
|
|
.wb2_dat_i(wb32m_dat_o),
|
492 |
|
|
.wb2_dat_o(ethramcore_dat),
|
493 |
|
|
.wb2_sel_i(wb32m_sel_o),
|
494 |
|
|
.wb2_ack_o(ethramcore_ack),
|
495 |
|
|
|
496 |
4 |
joff |
.wb1_cyc_i(ethwbm_cyc_o && ethernet),
|
497 |
2 |
joff |
.wb1_stb_i(ethwbm_stb_o),
|
498 |
|
|
.wb1_we_i(ethwbm_we_o),
|
499 |
|
|
.wb1_adr_i(ethwbm_adr_o[12:2]),
|
500 |
|
|
.wb1_dat_i(ethwbm_dat_o),
|
501 |
|
|
.wb1_dat_o(ethwbm_dat_i),
|
502 |
|
|
.wb1_sel_i(ethwbm_sel_o),
|
503 |
|
|
.wb1_ack_o(ethwbm_ack_i)
|
504 |
|
|
);
|
505 |
|
|
|
506 |
|
|
wire [31:0] ethcore_dat;
|
507 |
|
|
wire ethcore_ack, ethcore_irq;
|
508 |
|
|
wire ethcore_mdo, ethcore_mdoe;
|
509 |
|
|
reg ethcore_mdo_q, ethcore_mdoe_q;
|
510 |
|
|
reg ethcore_stb;
|
511 |
|
|
assign eth_mdio_pad = ethcore_mdoe_q ? ethcore_mdo_q : 1'bz;
|
512 |
|
|
eth_top ethcore(
|
513 |
4 |
joff |
.wb_clk_i(wb32m_clk_o && ethernet),
|
514 |
2 |
joff |
.wb_rst_i(wb32m_rst_o),
|
515 |
|
|
.wb_dat_i(wb32m_dat_o),
|
516 |
|
|
.wb_dat_o(ethcore_dat),
|
517 |
|
|
.wb_adr_i(wb32m_adr_o[9:0]),
|
518 |
|
|
.wb_sel_i(wb32m_sel_o),
|
519 |
|
|
.wb_we_i(wb32m_we_o),
|
520 |
|
|
.wb_cyc_i(wb32m_cyc_o),
|
521 |
|
|
.wb_stb_i(ethcore_stb),
|
522 |
|
|
.wb_ack_o(ethcore_ack),
|
523 |
|
|
|
524 |
|
|
.m_wb_adr_o(ethwbm_adr_o),
|
525 |
|
|
.m_wb_sel_o(ethwbm_sel_o),
|
526 |
|
|
.m_wb_we_o(ethwbm_we_o),
|
527 |
|
|
.m_wb_dat_o(ethwbm_dat_o),
|
528 |
|
|
.m_wb_dat_i(ethwbm_dat_i),
|
529 |
|
|
.m_wb_cyc_o(ethwbm_cyc_o),
|
530 |
|
|
.m_wb_stb_o(ethwbm_stb_o),
|
531 |
|
|
.m_wb_ack_i(ethwbm_ack_i),
|
532 |
|
|
|
533 |
|
|
//TX
|
534 |
4 |
joff |
.mtx_clk_pad_i(eth_txclk_pad && ethernet),
|
535 |
2 |
joff |
.mtxd_pad_o(eth_txdat_pad),
|
536 |
|
|
.mtxen_pad_o(eth_txen_pad),
|
537 |
|
|
.mtxerr_pad_o(eth_txerr_pad),
|
538 |
|
|
|
539 |
|
|
//RX
|
540 |
4 |
joff |
.mrx_clk_pad_i(eth_rxclk_pad && ethernet),
|
541 |
2 |
joff |
.mrxd_pad_i(eth_rxdat_pad),
|
542 |
|
|
.mrxdv_pad_i(eth_rxdv_pad),
|
543 |
|
|
.mrxerr_pad_i(eth_rxerr_pad),
|
544 |
|
|
.mcoll_pad_i(eth_col_pad),
|
545 |
|
|
.mcrs_pad_i(eth_crs_pad),
|
546 |
|
|
|
547 |
|
|
// MIIM
|
548 |
|
|
.mdc_pad_o(eth_mdc_pad),
|
549 |
|
|
.md_pad_i(eth_mdio_pad),
|
550 |
|
|
.md_pad_o(ethcore_mdo),
|
551 |
|
|
.md_padoe_o(ethcore_mdoe),
|
552 |
|
|
|
553 |
|
|
.int_o(ethcore_irq)
|
554 |
|
|
);
|
555 |
|
|
|
556 |
|
|
always @(posedge epwbm_clk_o) begin
|
557 |
|
|
ethcore_mdo_q <= ethcore_mdo;
|
558 |
|
|
ethcore_mdoe_q <= ethcore_mdoe;
|
559 |
|
|
end
|
560 |
|
|
|
561 |
|
|
wire [31:0] usercore_dat;
|
562 |
|
|
wire usercore_ack;
|
563 |
|
|
reg usercore_stb;
|
564 |
|
|
reg [40:1] headerpin_i;
|
565 |
|
|
wire [40:1] headerpin_oe, headerpin_o;
|
566 |
|
|
integer i;
|
567 |
|
|
always @(headerpin_o or headerpin_oe or blue_pad or green_pad or red_pad or
|
568 |
|
|
dio10to17_pad or dio0to8_pad or dio9_pad or vsync_pad or hsync_pad) begin
|
569 |
|
|
blue_pad = 5'bzzzzz;
|
570 |
|
|
red_pad = 5'bzzzzz;
|
571 |
|
|
green_pad = 5'bzzzzz;
|
572 |
|
|
for (i = 0; i < 5; i = i + 1) begin
|
573 |
|
|
headerpin_i[1 + (i * 2)] = blue_pad[i];
|
574 |
|
|
headerpin_i[11 + (i * 2)] = green_pad[i];
|
575 |
|
|
headerpin_i[4 + (i * 2)] = red_pad[i];
|
576 |
|
|
|
577 |
|
|
if (headerpin_oe[1 + (i * 2)])
|
578 |
|
|
blue_pad[i] = headerpin_o[1 + (i * 2)];
|
579 |
|
|
if (headerpin_oe[11 + (i * 2)])
|
580 |
|
|
green_pad[i] = headerpin_o[11 + (i * 2)];
|
581 |
|
|
if (headerpin_oe[4 + (i * 2)])
|
582 |
|
|
red_pad[i] = headerpin_o[4 + (i * 2)];
|
583 |
|
|
end
|
584 |
|
|
|
585 |
|
|
dio10to17_pad = 8'bzzzzzzzz;
|
586 |
|
|
dio0to8_pad = 9'bzzzzzzzzz;
|
587 |
|
|
for (i = 0; i < 8; i = i + 1) begin
|
588 |
|
|
headerpin_i[24 + (i * 2)] = dio10to17_pad[i];
|
589 |
|
|
headerpin_i[21 + (i * 2)] = dio0to8_pad[i];
|
590 |
|
|
|
591 |
|
|
if (headerpin_oe[24 + (i * 2)])
|
592 |
|
|
dio10to17_pad[i] = headerpin_o[24 + (i * 2)];
|
593 |
|
|
if (headerpin_oe[21 + (i * 2)])
|
594 |
|
|
dio0to8_pad[i] = headerpin_o[21 + (i * 2)];
|
595 |
|
|
end
|
596 |
|
|
|
597 |
|
|
if (headerpin_oe[14]) hsync_pad = headerpin_o[14];
|
598 |
|
|
else hsync_pad = 1'bz;
|
599 |
|
|
|
600 |
|
|
if (headerpin_oe[16]) vsync_pad = headerpin_o[16];
|
601 |
|
|
else vsync_pad = 1'bz;
|
602 |
|
|
|
603 |
|
|
if (headerpin_oe[37]) dio0to8_pad[8] = headerpin_o[37];
|
604 |
|
|
|
605 |
|
|
headerpin_i[39] = dio9_pad;
|
606 |
|
|
|
607 |
|
|
headerpin_i[22] = 1'b0;
|
608 |
|
|
headerpin_i[40] = 1'b1;
|
609 |
|
|
headerpin_i[2] = 1'b0;
|
610 |
|
|
headerpin_i[20] = 1'b1;
|
611 |
|
|
headerpin_i[18] = 1'b0;
|
612 |
|
|
end
|
613 |
|
|
wire usercore_drq, usercore_irq;
|
614 |
|
|
ts7300_wishbone_slave usercore(
|
615 |
|
|
.wb_clk_i(wb32m_clk_o),
|
616 |
|
|
.wb_rst_i(wb32m_rst_o),
|
617 |
|
|
.wb_cyc_i(wb32m_cyc_o),
|
618 |
|
|
.wb_stb_i(usercore_stb),
|
619 |
|
|
.wb_we_i(wb32m_we_o),
|
620 |
|
|
.wb_ack_o(usercore_ack),
|
621 |
|
|
.wb_dat_o(usercore_dat),
|
622 |
|
|
.wb_dat_i(wb32m_dat_o),
|
623 |
|
|
.wb_adr_i(wb32m_adr_o),
|
624 |
|
|
|
625 |
|
|
.headerpin_i(headerpin_i[40:1]),
|
626 |
|
|
.headerpin_o(headerpin_o[40:1]),
|
627 |
|
|
.headerpin_oe_o(headerpin_oe[40:1]),
|
628 |
|
|
|
629 |
|
|
.irq_o(usercore_irq)
|
630 |
|
|
);
|
631 |
|
|
|
632 |
|
|
/* IRQ7 is actually ep9302 VIC IRQ #40 */
|
633 |
|
|
assign irq7_pad = (ethcore_irq || usercore_irq) ? 1'b1 : 1'bz;
|
634 |
|
|
|
635 |
|
|
/* Now we set up the address decode and the return WISHBONE master
|
636 |
|
|
* databus and ack signal multiplexors. This is very simple, on the native
|
637 |
|
|
* WISHBONE bus (epwbm_*) if the address is >= 0x72100000, the 16 to 32 bit
|
638 |
|
|
* bridge is selected. The 32 bit wishbone bus contains 3 wishbone
|
639 |
|
|
* slaves: the ethernet core, the ethernet packet RAM, and the usercore. If the
|
640 |
|
|
* address >= 0x72a00000 the usercore is strobed and expected to ack, for
|
641 |
|
|
* address >= 0x72102000 the ethernet core is strobed and expected to ack
|
642 |
|
|
* otherwise the bus cycle goes to the ethernet RAM core.
|
643 |
|
|
*/
|
644 |
|
|
|
645 |
|
|
always @(epwbm_adr_o or epwbm_wb32m_bridgecore_dat or
|
646 |
|
|
epwbm_wb32m_bridgecore_ack or usercore_dat or usercore_ack or
|
647 |
|
|
ethcore_dat or ethcore_ack or ethramcore_dat or ethramcore_ack or
|
648 |
|
|
wb32m_adr_o or wb32m_stb_o) begin
|
649 |
|
|
epwbm_dat_i = 16'hxxxx;
|
650 |
|
|
epwbm_ack_i = 1'bx;
|
651 |
|
|
if (epwbm_adr_o >= 24'h100000) begin
|
652 |
|
|
epwbm_dat_i = epwbm_wb32m_bridgecore_dat;
|
653 |
|
|
epwbm_ack_i = epwbm_wb32m_bridgecore_ack;
|
654 |
|
|
end
|
655 |
|
|
|
656 |
|
|
usercore_stb = 1'b0;
|
657 |
|
|
ethcore_stb = 1'b0;
|
658 |
|
|
ethramcore_stb = 1'b0;
|
659 |
|
|
if (wb32m_adr_o >= 22'h280000) begin
|
660 |
|
|
usercore_stb = wb32m_stb_o;
|
661 |
|
|
wb32m_dat_i = usercore_dat;
|
662 |
|
|
wb32m_ack_i = usercore_ack;
|
663 |
|
|
end else if (wb32m_adr_o >= 22'h40800) begin
|
664 |
|
|
ethcore_stb = wb32m_stb_o;
|
665 |
|
|
wb32m_dat_i = ethcore_dat;
|
666 |
|
|
wb32m_ack_i = ethcore_ack;
|
667 |
|
|
end else begin
|
668 |
|
|
ethramcore_stb = wb32m_stb_o;
|
669 |
|
|
wb32m_dat_i = ethramcore_dat;
|
670 |
|
|
wb32m_ack_i = ethramcore_ack;
|
671 |
|
|
end
|
672 |
|
|
|
673 |
|
|
end
|
674 |
|
|
|
675 |
|
|
/* Various defaults for signals not used in this boilerplate project: */
|
676 |
|
|
|
677 |
|
|
/* No use for DMA -- used by TS-SDCORE on shipped bitstream */
|
678 |
|
|
assign dma_req_pad = 1'bz;
|
679 |
|
|
|
680 |
|
|
/* PHY always on */
|
681 |
|
|
assign eth_pd_pad = 1'b1;
|
682 |
|
|
|
683 |
|
|
/* SDRAM signals outputing 0's -- used by TS-VIDCORE in shipped bitstream */
|
684 |
|
|
assign sdram_add_pad = 12'd0;
|
685 |
|
|
assign sdram_ba_pad = 2'd0;
|
686 |
|
|
assign sdram_cas_pad = 1'b0;
|
687 |
|
|
assign sdram_ras_pad = 1'b0;
|
688 |
|
|
assign sdram_we_pad = 1'b0;
|
689 |
|
|
assign sdram_clk_pad = 1'b0;
|
690 |
|
|
assign sdram_data_pad = 16'd0;
|
691 |
|
|
|
692 |
|
|
/* serial (RS232) mux signals safely "parked" -- used by TS-UART */
|
693 |
|
|
assign rd_mux_pad = 1'b1;
|
694 |
|
|
assign mux_cntrl_pad = 1'b0;
|
695 |
|
|
assign wr_232_pad = 1'b1;
|
696 |
|
|
assign mux_pad = 4'hz;
|
697 |
|
|
|
698 |
|
|
/* SD flash card signals "parked" -- used by TS-SDCORE */
|
699 |
|
|
assign sd_soft_power_pad = 1'b0;
|
700 |
|
|
assign sd_hard_power_pad = 1'b1;
|
701 |
|
|
assign sd_dat_pad = 4'hz;
|
702 |
|
|
assign sd_clk_pad = 1'b0;
|
703 |
|
|
assign sd_cmd_pad = 1'bz;
|
704 |
|
|
|
705 |
|
|
endmodule
|
706 |
|
|
|