Rev 34 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 34 | Rev 122 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | // Part of NeoGS project |
1 | // Part of NeoGS project |
2 | // |
2 | // |
3 | // FPGA early and on-the-fly configuration, Z80 clock switch, |
3 | // Z80 clock switch and nothing more. config_n=coldres_n. |
4 | // 3.3v RAM buffer |
- | |
5 | // |
4 | // |
6 | // (c) 2008-2010 NedoPC |
5 | // (c) 2008-2010 NedoPC |
7 | 6 | ||
8 | module GS_cpld( |
7 | module GS_cpld( |
9 | output reg config_n, // ACEX1K config pins |
8 | output wire config_n, // ACEX1K config pins |
10 | input wire status_n, // |
9 | input wire status_n, // |
11 | input wire conf_done, // |
10 | input wire conf_done, // |
12 | output wire cs, // |
11 | output wire cs, // |
13 | input wire init_done, // |
12 | input wire init_done, // |
14 | 13 | ||
Line 21... | Line 20... | ||
21 | 20 | ||
22 | input wire clkin, // input of clkout signal, buffered, same as for Z80 |
21 | input wire clkin, // input of clkout signal, buffered, same as for Z80 |
23 | 22 | ||
24 | 23 | ||
25 | input wire coldres_n, // resets |
24 | input wire coldres_n, // resets |
26 | output reg warmres_n, |
25 | output wire warmres_n, |
27 | 26 | ||
28 | 27 | ||
29 | input wire iorq_n, // Z80 control signals |
28 | input wire iorq_n, // Z80 control signals |
30 | input wire mreq_n, |
29 | input wire mreq_n, |
31 | input wire rd_n, |
30 | input wire rd_n, |
Line 69... | Line 68... | ||
69 | 68 | ||
70 | inout wire [ 7:0] rd // memory data bus |
69 | inout wire [ 7:0] rd // memory data bus |
71 | ); |
70 | ); |
72 | 71 | ||
73 | 72 | ||
74 | - | ||
75 | - | ||
76 | reg int_mema14,int_mema15; |
- | |
77 | reg int_romcs_n,int_ramcs_n; |
- | |
78 | wire int_memoe_n,int_memwe_n; |
- | |
79 | wire int_cs; |
- | |
80 | - | ||
81 | wire ext_romcs_n, |
- | |
82 | ext_memoe_n, |
- | |
83 | ext_memwe_n; |
- | |
84 | - | ||
85 | - | ||
86 | reg [1:0] memcfg; // memcfg[1]: 1 ram, 0 roms |
- | |
87 | // memcfg[0]: 0 page0, 1 page1 -> in 8000-ffff region |
- | |
88 | - | ||
89 | reg disbl; // =1 - cpld disabled, =0 - enabled |
- | |
90 | - | ||
91 | reg was_cold_reset_n; // 1 - no cold reset, 0 - was cold reset |
- | |
92 | - | ||
93 | - | ||
94 | reg [1:0] dbout; |
- | |
95 | wire [1:0] dbin; |
- | |
96 | - | ||
97 | wire memcfg_write_n; |
- | |
98 | wire rescfg_write_n; |
- | |
99 | - | ||
100 | wire coldrstf_read_n; |
- | |
101 | wire fpgastat_read_n; |
- | |
102 | - | ||
103 | - | ||
104 | - | ||
105 | - | ||
106 | assign dbin[1] = d[7]; |
- | |
107 | assign dbin[0] = d[0]; |
- | |
108 | - | ||
109 | - | ||
110 | - | ||
111 | reg [3:0] rstcount; // counter for warm reset period |
- | |
112 | - | ||
113 | reg [2:0] disbl_sync; |
- | |
114 | - | ||
115 | // PORTS: |
- | |
116 | // {a7,a6} |
- | |
117 | // 00 - fpga ports |
- | |
118 | // 01,WR - write memcfg: d7=RAM(1)/ROM(0), d0=32k page(0/1) |
- | |
119 | // 01,RD - read cold_reset_n flag: d7=(0:was cold reset,1:no cold reset) |
- | |
120 | // 10,WR - set cold_reset_n flag & write FPGA nCONFIG: d7=1: set cold_reset_n flag, d0: nCONFIG |
- | |
121 | // 10,RD - read FPGA status: d7=nSTATUS, d0=CONF_DONE |
- | |
122 | // 11,WR - write to FPGA |
- | |
123 | // 11,RD - read from FPGA |
- | |
124 | - | ||
125 | - | ||
126 | // clock selector |
73 | // clock selector |
127 | clocker clk( .clk1(clk24in), |
74 | clocker clk( .clk1(clk24in), |
128 | .clk2(clk20in), |
75 | .clk2(clk20in), |
129 | .clksel(clksel1), |
76 | .clksel(clksel1), |
130 | .divsel(clksel0), |
77 | .divsel(clksel0), |
131 | .clkout(clkout) |
78 | .clkout(clkout) |
132 | ); |
79 | ); |
133 | 80 | ||
134 | 81 | ||
- | 82 | // memory control pins when running without configured FPGA |
|
- | 83 | assign mema14 = 1'bZ; |
|
- | 84 | assign mema15 = 1'bZ; |
|
135 | // disable control |
85 | assign mema19 = 1'bZ; |
136 | 86 | ||
137 | always @(negedge config_n,posedge init_done) |
- | |
138 | begin |
- | |
139 | if( !config_n ) // asynchronous reset |
87 | assign romcs_n = 1'bZ; |
140 | disbl <= 0; |
88 | assign memoe_n = 1'bZ; |
141 | else // posedge of init_done, synchronous set |
- | |
142 | disbl <= 1; |
89 | assign memwe_n = 1'bZ; |
143 | end |
- | |
144 | 90 | ||
- | 91 | assign cs = 1'b0; |
|
- | 92 | ||
- | 93 | assign out_ramcs0_n = 1'b1; |
|
- | 94 | assign out_ramcs1_n = 1'b1; |
|
- | 95 | ||
- | 96 | assign rd = 8'bZZZZ_ZZZZ; |
|
- | 97 | ||
- | 98 | assign warmres_n = 1'bZ; |
|
- | 99 | ||
- | 100 | assign d = 8'bZZZZ_ZZZZ; |
|
- | 101 | ||
- | 102 | assign {ra6,ra7,ra10,ra11,ra12,ra13} = 6'd0; |
|
145 | 103 | ||
146 | 104 | ||
147 | // memory control pins when running without configured FPGA |
- | |
148 | assign mema14 = disbl ? 1'bZ : int_mema14; |
- | |
149 | assign mema15 = disbl ? 1'bZ : int_mema15; |
- | |
150 | assign romcs_n = disbl ? 1'bZ : int_romcs_n; |
- | |
151 | assign memoe_n = disbl ? 1'bZ : int_memoe_n; |
- | |
152 | assign memwe_n = disbl ? 1'bZ : int_memwe_n; |
- | |
153 | assign cs = disbl ? 1'bZ : int_cs; |
- | |
154 | - | ||
155 | assign ext_romcs_n = romcs_n; |
- | |
156 | assign ext_memoe_n = memoe_n; |
- | |
157 | assign ext_memwe_n = memwe_n; |
- | |
158 | - | ||
159 | - | ||
160 | // controlling memory paging |
- | |
161 | always @* |
- | |
162 | begin |
- | |
163 | casex( {a15,a14,memcfg[1]} ) |
- | |
164 | 3'b00x: |
- | |
165 | {int_mema15,int_mema14,int_romcs_n,int_ramcs_n} <= 4'b0001; |
- | |
166 | 3'b01x: |
- | |
167 | {int_mema15,int_mema14,int_romcs_n,int_ramcs_n} <= 4'b0010; |
- | |
168 | 3'b1x0: |
- | |
169 | {int_mema15,int_mema14,int_romcs_n,int_ramcs_n} <= {memcfg[0],a14,2'b01}; |
- | |
170 | 3'b1x1: |
- | |
171 | {int_mema15,int_mema14,int_romcs_n,int_ramcs_n} <= {memcfg[0],a14,2'b10}; |
- | |
172 | endcase |
- | |
173 | end |
- | |
174 | - | ||
175 | // controlling memory /OE, /WE |
- | |
176 | assign int_memoe_n = mreq_n | rd_n; |
- | |
177 | assign int_memwe_n = mreq_n | wr_n; |
- | |
178 | - | ||
179 | - | ||
180 | // writing paging register [1:0] memcfg |
- | |
181 | assign memcfg_write_n = iorq_n | wr_n | a7 | ~a6; // {a7,a6}==01 |
- | |
182 | - | ||
183 | always @(negedge coldres_n, posedge memcfg_write_n) |
- | |
184 | begin |
- | |
185 | if( !coldres_n ) // reset on coldres_n |
- | |
186 | memcfg <= 2'b00; |
- | |
187 | else // write on memcfg_write_n |
- | |
188 | memcfg <= dbin; |
- | |
189 | end |
- | |
190 | - | ||
191 | - | ||
192 | // writing nCONFIG and cold reset "register" |
- | |
193 | assign rescfg_write_n = iorq_n | wr_n | ~a7 | a6; // {a7,a6}==10 |
- | |
194 | - | ||
195 | always @(posedge rescfg_write_n, negedge coldres_n) |
- | |
196 | begin |
- | |
197 | if( !coldres_n ) // async reset |
- | |
198 | begin |
- | |
199 | was_cold_reset_n <= 0; // there was! |
- | |
200 | config_n <= 0; // start FPGA config |
- | |
201 | end |
- | |
202 | else // sync set/load |
- | |
203 | begin |
- | |
204 | config_n <= dbin[0]; |
- | |
205 | was_cold_reset_n <= dbin[1] | was_cold_reset_n; |
- | |
206 | end |
- | |
207 | end |
- | |
208 | - | ||
209 | - | ||
210 | // controlling positive CS pin to FPGA |
- | |
211 | assign int_cs = a7 & a6; // {a7,a6}==11 |
- | |
212 | - | ||
213 | - | ||
214 | - | ||
215 | // reading control |
- | |
216 | assign coldrstf_read_n = iorq_n | rd_n | a7 | ~a6; // {a7,a6}=01 |
- | |
217 | assign fpgastat_read_n = iorq_n | rd_n | ~a7 | a6; // {a7,a6}=10 |
- | |
218 | - | ||
219 | - | ||
220 | - | ||
221 | always @* |
- | |
222 | begin |
- | |
223 | case( {coldrstf_read_n,fpgastat_read_n} ) |
- | |
224 | 2'b01: |
- | |
225 | dbout = { was_cold_reset_n, 1'bX }; |
- | |
226 | 2'b10: |
- | |
227 | dbout = { status_n, conf_done }; |
- | |
228 | default: |
- | |
229 | dbout = 2'bXX; |
- | |
230 | endcase |
- | |
231 | end |
- | |
232 | - | ||
233 | - | ||
234 | - | ||
235 | // warm resetter control |
- | |
236 | - | ||
237 | always @(posedge clkin) |
- | |
238 | begin |
- | |
239 | disbl_sync[2:0]={disbl_sync[1:0],disbl}; |
- | |
240 | end |
- | |
241 | - | ||
242 | always @(negedge coldres_n,posedge clkin) |
- | |
243 | begin |
- | |
244 | if( coldres_n==0 ) // async reset |
- | |
245 | begin |
- | |
246 | rstcount <= (-1); |
- | |
247 | warmres_n <= 0; |
- | |
248 | end |
- | |
249 | else // posedge clkin |
- | |
250 | begin |
- | |
251 | if( disbl_sync[2]==0 && disbl_sync[1]==1 ) // positive pulse |
- | |
252 | begin |
- | |
253 | warmres_n <= 0; |
- | |
254 | rstcount <= (-1); |
- | |
255 | end |
- | |
256 | else // no disbl_sync positive pulse |
- | |
257 | begin |
- | |
258 | rstcount <= rstcount - 1; |
- | |
259 | if( |rstcount == 0 ) |
- | |
260 | warmres_n <= 1'bZ; |
- | |
261 | end |
- | |
262 | end |
- | |
263 | - | ||
264 | end |
- | |
265 | - | ||
266 | - | ||
267 | - | ||
268 | // Z80 data bus control |
- | |
269 | - | ||
270 | assign d = ( (!coldrstf_read_n)||(!fpgastat_read_n) ) ? |
- | |
271 | { dbout[1], 6'bXXXXXX, dbout[0] } : |
- | |
272 | ( (ext_romcs_n&&(!ext_memoe_n)) ? rd : 8'bZZZZZZZZ ) ; |
- | |
273 | - | ||
274 | // memory data bus control |
- | |
275 | - | ||
276 | assign rd = (ext_romcs_n&&(!ext_memwe_n)) ? d : 8'bZZZZZZZZ; |
- | |
277 | - | ||
278 | // memory addresses buffering |
- | |
279 | - | ||
280 | assign ra6 = a6; |
- | |
281 | assign ra7 = a7; |
- | |
282 | assign ra10 = a10; |
- | |
283 | assign ra11 = a11; |
- | |
284 | assign ra12 = a12; |
- | |
285 | assign ra13 = a13; |
- | |
286 | 105 | ||
287 | 106 | ||
288 | // memory CS'ing |
107 | // reset FPGA at cold reset |
- | 108 | assign config_n = coldres_n; |
|
289 | 109 | ||
290 | assign out_ramcs0_n = disbl ? ( in_ramcs0_n & in_ramcs1_n ) : int_ramcs_n; |
- | |
291 | assign out_ramcs1_n = disbl ? ( in_ramcs2_n & in_ramcs3_n ) : 1'b1; |
- | |
292 | 110 | ||
293 | assign mema19 = disbl ? ( in_ramcs0_n & in_ramcs2_n ) : 1'b0; |
- | |
294 | 111 | ||
295 | 112 | ||
296 | 113 | ||
297 | endmodule |
114 | endmodule |
298 | 115 |