Subversion Repositories pentevo

Rev

Rev 684 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
668 lvd 1
// ZX-Evo Base Configuration (c) NedoPC 2008,2009,2010,2011,2012,2013,2014
4 lvd 2
//
3
// Z80 memory manager: routes ROM/RAM accesses, makes wait-states for 14MHz or stall condition, etc.
668 lvd 4
 
5
/*
6
    This file is part of ZX-Evo Base Configuration firmware.
7
 
8
    ZX-Evo Base Configuration firmware is free software:
9
    you can redistribute it and/or modify it under the terms of
10
    the GNU General Public License as published by
11
    the Free Software Foundation, either version 3 of the License, or
12
    (at your option) any later version.
13
 
14
    ZX-Evo Base Configuration firmware is distributed in the hope that
15
    it will be useful, but WITHOUT ANY WARRANTY; without even
16
    the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
    See the GNU General Public License for more details.
18
 
19
    You should have received a copy of the GNU General Public License
20
    along with ZX-Evo Base Configuration firmware.
21
    If not, see <http://www.gnu.org/licenses/>.
22
*/
23
 
4 lvd 24
//
25
// fclk    _/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\
26
//          |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
27
// zclk     /```\___/```\___/```\___/```````\_______/```````\_______/```````````````\_______________/```````````````\_______________/`
28
//          |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
29
// zpos     `\___/```\___/```\___/```\___________/```\___________/```\___________________________/```\___________________________/```\
30
//          |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
31
// zneg     _/```\___/```\___/```\_______/```\___________/```\___________________/```\___________________________/```\________________
32
 
668 lvd 33
`include "../include/tune.v"
34
 
4 lvd 35
module zmem(
36
 
467 lvd 37
        input  wire fclk,
38
        input  wire rst_n,
4 lvd 39
 
467 lvd 40
        input  wire zpos, //
41
        input  wire zneg, // strobes which show positive and negative edges of zclk
4 lvd 42
 
467 lvd 43
        input  wire cbeg,      // DRAM synchronization
44
        input  wire post_cbeg, //
45
        input  wire pre_cend,  //
46
        input  wire cend,      //
4 lvd 47
 
48
 
467 lvd 49
        input  wire [15:0] za,
4 lvd 50
 
467 lvd 51
        input  wire [ 7:0] zd_in, // won't emit anything to Z80 bus, data bus mux is another module
469 lvd 52
        output wire [ 7:0] zd_out, // output to Z80 bus
4 lvd 53
 
467 lvd 54
        output wire zd_ena, // out bus to the Z80
4 lvd 55
 
467 lvd 56
        input  wire m1_n,
57
        input  wire rfsh_n,
58
        input  wire mreq_n,
59
        input  wire iorq_n,
60
        input  wire rd_n,
61
        input  wire wr_n,
4 lvd 62
 
63
 
467 lvd 64
        input  wire [ 1:0] int_turbo, // 2'b00 - 3.5,
65
                                      // 2'b01 - 7.0,
66
                                      // 2'b1x - 14.0
4 lvd 67
 
68
 
467 lvd 69
 
200 lvd 70
        input  wire        win0_romnram, // four windows, each 16k,
71
        input  wire        win1_romnram, // ==1 - there is rom,
72
        input  wire        win2_romnram, // ==0 - there is ram
73
        input  wire        win3_romnram, //
4 lvd 74
 
200 lvd 75
        input  wire [ 7:0] win0_page, // which 16k page is in given window
76
        input  wire [ 7:0] win1_page, //
77
        input  wire [ 7:0] win2_page, //
78
        input  wire [ 7:0] win3_page, //
4 lvd 79
 
674 lvd 80
        input  wire        win0_wrdisable, // ==1 - no write is possible to window
81
        input  wire        win1_wrdisable,
82
        input  wire        win2_wrdisable,
83
        input  wire        win3_wrdisable,
4 lvd 84
 
674 lvd 85
 
200 lvd 86
        input  wire        romrw_en,
4 lvd 87
 
88
 
737 lvd 89
 
90
        input  wire        nmi_buf_clr,
91
 
92
 
93
 
200 lvd 94
        output reg  [ 4:0] rompg, // output for ROM paging
95
        output wire        romoe_n,
96
        output wire        romwe_n,
97
        output wire        csrom,
4 lvd 98
 
99
 
467 lvd 100
        output wire        cpu_req,
101
        output wire        cpu_rnw,
102
        output wire [20:0] cpu_addr,
103
        output wire [ 7:0] cpu_wrdata,
104
        output wire        cpu_wrbsel,
4 lvd 105
 
467 lvd 106
        input  wire [15:0] cpu_rddata,
4 lvd 107
 
467 lvd 108
        input  wire        cpu_next,
109
        input  wire        cpu_strobe,
110
 
111
 
112
        output wire        cpu_stall // for zclock
113
 
4 lvd 114
);
115
 
116
 
117
        wire [1:0] win;
118
        reg [7:0] page;
119
        reg romnram;
674 lvd 120
        reg wrdisable;
4 lvd 121
 
467 lvd 122
 
123
 
684 lvd 124
 
469 lvd 125
        reg [15:0] rd_buf;
467 lvd 126
 
469 lvd 127
        reg [15:1] cached_addr;
128
        reg        cached_addr_valid;
467 lvd 129
 
469 lvd 130
        wire cache_hit;
131
 
132
 
467 lvd 133
        wire dram_beg;
134
        wire opfetch, memrd, memwr;
135
        wire stall14, stall7_35;
136
 
137
        wire stall14_ini;
138
        wire stall14_cyc;
139
        reg  stall14_cycrd;
140
        reg  stall14_fin;
141
 
142
        reg r_mreq_n;
143
 
144
 
145
        reg pending_cpu_req;
146
 
147
        reg cpu_rnw_r;
148
 
149
 
150
 
151
        // this is for 7/3.5mhz  
4 lvd 152
        wire ramreq;
153
        wire ramwr,ramrd;
467 lvd 154
        wire cpureq_357;
155
        reg ramrd_reg,ramwr_reg;
4 lvd 156
 
157
 
158
 
467 lvd 159
 
160
 
161
 
4 lvd 162
        // make paging
163
        assign win[1:0] = za[15:14];
164
 
165
        always @*
200 lvd 166
        case( win )
167
                2'b00: begin
674 lvd 168
                        page      = win0_page;
169
                        romnram   = win0_romnram;
170
                        wrdisable = win0_wrdisable;
4 lvd 171
                end
172
 
200 lvd 173
                2'b01: begin
674 lvd 174
                        page      = win1_page;
175
                        romnram   = win1_romnram;
176
                        wrdisable = win1_wrdisable;
4 lvd 177
                end
178
 
200 lvd 179
                2'b10: begin
674 lvd 180
                        page      = win2_page;
181
                        romnram   = win2_romnram;
182
                        wrdisable = win2_wrdisable;
4 lvd 183
                end
184
 
200 lvd 185
                2'b11: begin
674 lvd 186
                        page      = win3_page;
187
                        romnram   = win3_romnram;
188
                        wrdisable = win3_wrdisable;
4 lvd 189
                end
200 lvd 190
        endcase
4 lvd 191
 
192
 
200 lvd 193
        // rom paging - only half a megabyte addressing.
4 lvd 194
        always @*
195
        begin
200 lvd 196
                rompg[4:0] = page[4:0];
4 lvd 197
        end
198
 
199
 
200
 
201
 
674 lvd 202
        assign romwe_n = wr_n | mreq_n | (~romrw_en) | wrdisable;
200 lvd 203
        assign romoe_n = rd_n | mreq_n;
4 lvd 204
 
205
        assign csrom = romnram; // positive polarity!
206
 
207
 
208
 
467 lvd 209
        // 7/3.5mhz support
4 lvd 210
 
211
        assign ramreq = (~mreq_n) && (~romnram) && rfsh_n;
467 lvd 212
        assign ramrd = ramreq & (~rd_n);
674 lvd 213
        assign ramwr = (ramreq & (~wr_n)) & (~wrdisable);
4 lvd 214
 
467 lvd 215
        always @(posedge fclk)
216
        if( cend && (!cpu_stall) )
217
        begin
218
                ramrd_reg <= ramrd;
219
                ramwr_reg <= ramwr;
220
        end
221
 
222
        assign cpureq_357 = ( ramrd & (~ramrd_reg) ) | ( ramwr & (~ramwr_reg) );
223
 
224
 
225
 
226
 
227
        assign zd_ena = (~mreq_n) & (~rd_n) & (~romnram);
228
 
469 lvd 229
 
230
 
231
        assign cache_hit = ( (za[15:1] == cached_addr[15:1]) && cached_addr_valid );
232
 
233
 
234
 
467 lvd 235
        // strobe the beginnings of DRAM cycles
236
 
237
        always @(posedge fclk)
238
        if( zneg )
239
                r_mreq_n <= mreq_n | (~rfsh_n);
240
        //
469 lvd 241
        assign dram_beg = ( (!cache_hit) || memwr ) && zneg && r_mreq_n && (!romnram) && (!mreq_n) && rfsh_n;
467 lvd 242
 
243
        // access type
244
        assign opfetch = (~mreq_n) && (~m1_n);
245
        assign memrd   = (~mreq_n) && (~rd_n);
674 lvd 246
        assign memwr   = (~mreq_n) &&   rd_n && rfsh_n && (!wrdisable);
467 lvd 247
 
248
 
249
        // wait tables: 
250
        //
251
        // M1 opcode fetch, dram_beg coincides with:
252
        // cend:      +3
253
        // pre_cend:  +4
254
        // post_cbeg: +5
255
        // cbeg:      +6
256
        //
257
        // memory read, dram_beg coincides with:
258
        // cend:      +2
259
        // pre_cend:  +3
260
        // post_cbeg: +4
261
        // cbeg:      +5
262
        //
263
        // memory write: no wait
264
        //
265
        // special case: if dram_beg pulses 1 when cpu_next is 0,
266
        // unconditional wait has to be performed until cpu_next is 1, and
267
        // then wait as if dram_beg would coincide with cbeg
268
 
269
        assign stall14_ini = dram_beg && ( (!cpu_next) || opfetch || memrd ); // no wait at all in write cycles, if next dram cycle is available
270
 
271
 
272
        // memrd, opfetch - wait till cend & cpu_next,
273
        // memwr - wait till cpu_next
274
        assign stall14_cyc = memwr ? (!cpu_next) : stall14_cycrd;
275
        //
276
        always @(posedge fclk, negedge rst_n)
277
        if( !rst_n )
278
                stall14_cycrd <= 1'b0;
279
        else // posedge fclk
280
        begin
281
                if( cpu_next && cend )
282
                        stall14_cycrd <= 1'b0;
283
                else if( dram_beg && ( (!cend) || (!cpu_next) ) && (opfetch || memrd) )
284
                        stall14_cycrd <= 1'b1;
285
        end
286
        //
287
        always @(posedge fclk, negedge rst_n)
288
        if( !rst_n )
289
                stall14_fin <= 1'b0;
290
        else // posedge fclk
291
        begin
292
                if( stall14_fin && ( (opfetch&pre_cend) || (memrd&post_cbeg) ) )
293
                        stall14_fin <= 1'b0;
294
                else if( cpu_next && cend && cpu_req && (opfetch || memrd) )
295
                        stall14_fin <= 1'b1;
296
        end
297
 
298
 
299
        //
300
        assign cpu_stall = int_turbo[1] ? (stall14_ini | stall14_cyc | stall14_fin) : (cpureq_357 && (!cpu_next));
301
 
302
        // cpu request
303
        assign cpu_req = int_turbo[1] ? (pending_cpu_req | dram_beg) : cpureq_357;
304
        //
305
        assign cpu_rnw = int_turbo[1] ? (dram_beg ? (!memwr) : cpu_rnw_r) : ramrd;
306
        //
307
        //
308
        always @(posedge fclk, negedge rst_n)
309
        if( !rst_n )
310
                pending_cpu_req <= 1'b0;
311
        else if( cpu_next && cend )
312
                pending_cpu_req <= 1'b0;
313
        else if( dram_beg )
314
                pending_cpu_req <= 1'b1;
315
        //
316
        always @(posedge fclk)
317
        if( dram_beg )
318
                cpu_rnw_r <= !memwr;
319
 
320
 
321
 
322
        // address, data in and data out
323
        //
324
        assign cpu_wrbsel = za[0];
325
        assign cpu_addr[20:0] = { page[7:0], za[13:1] };
326
        assign cpu_wrdata = zd_in;
327
        //
328
        always @* if( cpu_strobe ) // WARNING! ACHTUNG! LATCH!!!
469 lvd 329
                rd_buf <= cpu_rddata;
330
        //
331
        assign zd_out = cpu_wrbsel ? rd_buf[7:0] : rd_buf[15:8];
467 lvd 332
 
333
 
334
 
335
 
336
 
469 lvd 337
        wire io;
338
        reg  io_r;
339
        //
340
        assign io = (~iorq_n);
341
        //
342
        always @(posedge fclk)
343
        if( zpos )
344
                io_r <= io;
345
        //
346
        always @(posedge fclk, negedge rst_n)
347
        if( !rst_n )
348
                cached_addr_valid <= 1'b0;
349
        else
350
        begin
351
                if( (zneg && r_mreq_n && (!mreq_n) && rfsh_n && romnram) ||
352
                    (zneg && r_mreq_n && memwr                         ) ||
737 lvd 353
                    (io && (!io_r) && zpos                             ) ||
354
                    (nmi_buf_clr                                       ) )
469 lvd 355
                        cached_addr_valid <= 1'b0;
356
                else if( cpu_strobe )
357
                        cached_addr_valid <= 1'b1;
358
        end
359
        //
360
        always @(posedge fclk)
361
        if( !rst_n )
362
        begin
363
                cached_addr <= 15'd0;
364
        end
365
        else if( cpu_strobe )
366
        begin
367
                cached_addr[15:1] <= za[15:1];
368
        end
4 lvd 369
 
370
 
371
 
469 lvd 372
 
4 lvd 373
endmodule
374