]> git.ozlabs.org Git - minimigmac.git/blob - fpga/minimigmac.v
Initial commit
[minimigmac.git] / fpga / minimigmac.v
1 `timescale 1ns / 100ps
2
3 /*
4  * Note about interrupt wiring:
5  * 
6  * Level IPL 0 <- VIA
7  *       IPL 1 <- SCC
8  *       IPL 2 <- xxx
9  * 
10  * With debug switch clamping all 3 down
11  */
12
13 module minimigmac
14 (
15         /* m68k CPU pins */
16         inout   [15:0] cpu_data,        // m68k data bus
17         input   [23:1] cpu_address,     // m68k address bus
18         output  [2:0] _cpu_ipl,         // m68k interrupt request
19         input   _cpu_as,                // m68k address strobe
20         input   _cpu_uds,               // m68k upper data strobe
21         input   _cpu_lds,               // m68k lower data strobe
22         input   cpu_r_w,                // m68k read / write
23         output  _cpu_dtack,             // m68k data acknowledge
24         inout   _cpu_reset,             // m68k reset
25         output  cpu_clk,                // m68k clock
26
27         /* SRAM pins */
28         inout   [15:0] ram_data,        // sram data bus
29         output  [19:1] ram_address,     // sram address bus
30         output  [3:0] _ram_ce,          // sram chip enable
31         output  _ram_bhe,               // sram upper byte select
32         output  _ram_ble,               // sram lower byte select
33         output  _ram_we,                // sram write enable
34         output  _ram_oe,                // sram output enable
35
36         /* RS232 pins */
37         input   rxd,                    // rs232 receive
38         output  txd,                    // rs232 send
39         input   cts,                    // rs232 clear to send
40         output  rts,                    // rs232 request to send
41
42         /* Joystick ports */
43         input   [5:0]_joy1,             // joystick 1 [fire2,fire,up,down,left,right]
44         input   [5:0]_joy2,             // joystick 2 [fire2,fire,up,down,left,right]
45
46         /* PS2 ports */
47         inout   msdat,                  // PS2 mouse data
48         inout   msclk,                  // PS2 mouse clk
49         inout   kbddat,                 // PS2 keyboard data
50         inout   kbdclk,                 // PS2 keyboard clk
51
52         /* Video pins */
53         output  _hsync,                 // horizontal sync
54         output  _vsync,                 // vertical sync
55         output  [3:0] red,              // red
56         output  [3:0] green,            // green
57         output  [3:0] blue,             // blue
58
59         /* Audio pins */
60         output  left,                   // audio bitstream left
61         output  right,                  // audio bitstream right
62
63         /* System pins */
64         input   mclk,                   // master system clock (4.433619 Mhz)
65         output  pwrled,                 // power led
66         output  init_b,
67         input   _15khz,                 // scandoubler disable (jumper, unused)
68         output  gpio,
69         output  scsi_hshake,            // handshake for scsi fifo
70         input   nmi,                    // macsbug !
71
72         /* SPI pins */
73         input   _spi_cs,                // SPI chip select
74         input   sdi,                    // SPI data input
75         inout   sdo,                    // SPI data output
76         input   sck                     // SPI clock
77 );
78         /* Internal clocks */
79         wire    sysclk16;
80         wire    sysclk33;
81         wire    pixclk; 
82
83         /* Backbus SPI interface */
84         wire [5:0]      bb_addr;
85         wire [7:0]      bb_wdata;
86         wire [7:0]      bb_rdata;
87         wire            bb_strobe;
88         wire            bb_wr;
89
90         /* Chip-selects & rdata for backbus clients */
91         wire            bb_cs_scope;
92         wire [7:0]      bb_rdata_scope;
93         wire            bb_cs_ctrl;
94         wire [7:0]      bb_rdata_ctrl;
95         wire            bb_cs_cpu;
96         wire [7:0]      bb_rdata_cpu;
97         wire            bb_cs_iwm;
98         wire [7:0]      bb_rdata_iwm;
99         wire            bb_cs_scsi;
100         wire [7:0]      bb_rdata_scsi;
101         wire            bb_cs_mem;
102         wire [7:0]      bb_rdata_mem;
103         
104         /* Signals for the scope module */
105         wire [63:0]     scoped_sigs;    
106
107         /* Main bus between CPU and devices */
108         wire [23:1]     bus_addr;
109         wire [15:0]     bus_wdata;
110         wire            bus_ube;
111         wire            bus_lbe;
112         wire            bus_we;
113         wire            bus_phase;
114         wire            bus_cs_ram;
115         wire            bus_cs_rom;
116         wire            bus_ack_mem;
117         wire [15:0]     bus_rdata_mem;
118         wire            bus_cs_scsi;
119         wire            bus_ack_scsi;
120         wire [7:0]      bus_rdata_scsi;
121         wire            bus_cs_scc;
122         wire            bus_ack_scc;
123         wire [7:0]      bus_rdata_scc;
124         wire            bus_cs_via;
125         wire            bus_ack_via;
126         wire [7:0]      bus_rdata_via;
127         wire            bus_cs_iwm;
128         wire            bus_ack_iwm;
129         wire [7:0]      bus_rdata_iwm;
130
131         /* VIA wires */
132         wire [2:0]      via_pa_sndvol;
133         wire            via_pa_sndbuf_sel;      /* 1=main, 0=alt */            
134         wire            via_pa_rom_ovl;         /* 1=overlay */
135         wire            via_pa_disksel;
136         wire            via_pa_vidbuf_sel;      /* 1=main, 0=alt */
137         wire            via_pa_scc_wreq;
138         wire            via_pb_mouse_switch;
139         wire            via_pb_mouse_x2;
140         wire            via_pb_mouse_y2;
141         wire            via_pb_snddis;          /* 1=disabled */
142         wire [7:0]      via_kbd_out;
143         wire            via_kbd_out_strobe;
144         wire [7:0]      via_kbd_in;
145         wire            via_kbd_in_strobe;
146
147         /* Video wires */
148         wire            vid_req;
149         wire            vid_ack;
150         wire [15:0]     vid_pixels;
151         wire            vid_hblank;
152         
153         /* SCC additional wires */
154         wire            scc_mouse_x1;
155         wire            scc_mouse_y1;
156
157         /* RTC wires */
158         wire            rtc_onesec;     
159         wire            rtc_data_in;
160         wire            rtc_data_out;
161         wire            rtc_data_clock;
162         wire            _rtc_data_enable;
163
164         /* IRQs */
165         wire            _via_irq;
166         wire            _scc_irq;
167         reg             _prg_irq;       
168         reg             nmi_sync;       
169         
170         /* Control lines */
171         reg             led;
172
173         /* Reset hack */
174         reg [3:0]       reset_ctl = 4'b0000;/* Xilinx tool should cope */
175         wire            reset;
176         wire            ctrl_cpu_reset; 
177
178         /* Led test hack */
179         reg [31:0]      led_cnt;
180
181         /* Scope test hack */
182         reg [7:0]       scope_test;
183
184         /* PS2 mouse & kbd port debug */
185         wire [15:0]     ps2m_dbg;
186         wire [15:0]     ps2k_dbg;
187         
188         /* Not real synchronizers but will do */
189         reg             _vblank_sync;
190         reg             hblank_sync;
191
192         /* Instanciate clock generator */
193         clockgen clocks(.mclk(mclk),
194                         .sysclk16(sysclk16),
195                         .sysclk33(sysclk33),
196                         .pixclk(pixclk));
197
198         /* Low skew clock out trick from Matt */
199         OFDDRCPE OFDDRCPE_inst (\r
200                 .Q(cpu_clk), // Data output (connect directly to
201                                              // top-level port)\r
202                 .C0(sysclk16), // 0 degree clock input\r
203                 .C1(~sysclk16), // 180 degree clock input\r
204                 .CE(1'b1), // Clock enable input\r
205                 .CLR(1'b0), // Asynchronous reset input\r
206                 .D0(1'b1), // Posedge data input\r
207                 .D1(1'b0), // Negedge data input\r
208                 .PRE(1'b0) // Asynchronous preset input\r
209         );
210         
211         /* Instanciate backbus/SPI interface. Use 16Mhz clock for now */
212         spi_backbus spi_bb(.sysclk(sysclk16),
213                            .reset(reset),
214                            ._scs(_spi_cs),
215                            .sdi(sdi),
216                            .sdo(sdo),
217                            .sck(sck),
218                            .bb_addr(bb_addr),
219                            .bb_wdata(bb_wdata),
220                            .bb_rdata(bb_rdata),
221                            .bb_strobe(bb_strobe),
222                            .bb_wr(bb_wr));
223
224         /* Our reset currently comes reset_ctl, this will deassert it
225          * after 4clk of config (gives time to slower components like
226          * video to reset)
227          */
228         assign reset = ~reset_ctl[0];
229         always@(posedge sysclk16)
230           if (!ctrl_cpu_reset && !_cpu_reset)
231             reset_ctl <= 0;
232           else
233             reset_ctl[3:0] <= { 1'b1, reset_ctl[3:1] };
234         assign _cpu_reset = ctrl_cpu_reset ? 1'b0 : 1'bz;       
235
236         /* Instanciate scope module */
237         scope scop0(.sysclk(sysclk16),
238                     .capclk(sysclk16),
239                     .reset(reset),
240                     .sigs(scoped_sigs),
241                     .bb_addr(bb_addr),
242                     .bb_wdata(bb_wdata),
243                     .bb_rdata(bb_rdata_scope),
244                     .bb_strobe(bb_strobe && bb_cs_scope),
245                     .bb_wr(bb_wr));       
246
247 `ifdef __disabled__
248         assign scoped_sigs = { msclk,   /* 63 */
249                                msdat,           /* 62 */
250                                cpu_data,        /* 61..46 */
251                                cpu_address,     /* 45..23 */
252                                _cpu_ipl,        /* 22..20 */
253                                _cpu_as,         /* 19 */
254                                _cpu_uds,        /* 18 */
255                                _cpu_lds,        /* 17 */
256                                cpu_r_w,         /* 16 */
257                                _cpu_dtack,      /* 15 */
258                                _cpu_reset,      /* 14 */
259                                6'b111111,
260                                scope_test};
261 `else
262         assign scoped_sigs = 0;
263 `endif
264         always@(posedge reset or posedge sysclk16) begin
265                 if (reset) begin
266                         scope_test <= 0;
267                 end else begin
268                         scope_test <= scope_test + 1;
269                 end
270         end
271
272         /* Instanciate the CPU interface */
273         cpu_intf cpu0(.sysclk(sysclk16),
274                       .reset(reset),
275                       .cpu_data(cpu_data),
276                       .cpu_addr(cpu_address),
277                       ._cpu_as(_cpu_as),
278                       ._cpu_uds(_cpu_uds),
279                       ._cpu_lds(_cpu_lds),
280                       .cpu_r_w(cpu_r_w),
281                       ._cpu_dtack(_cpu_dtack),
282                       .bb_addr(bb_addr),
283                       .bb_wdata(bb_wdata),
284                       .bb_rdata(bb_rdata_cpu),
285                       .bb_strobe(bb_strobe && bb_cs_cpu),
286                       .bb_wr(bb_wr),
287                       .bus_addr(bus_addr),
288                       .bus_wdata(bus_wdata),
289                       .bus_ube(bus_ube),
290                       .bus_lbe(bus_lbe),
291                       .bus_we(bus_we),
292                       .bus_phase(bus_phase),
293                       .bus_cs_ram(bus_cs_ram),
294                       .bus_cs_rom(bus_cs_rom),
295                       .bus_ack_mem(bus_ack_mem),
296                       .bus_rdata_mem(bus_rdata_mem),
297                       .bus_cs_scsi(bus_cs_scsi),
298                       .bus_ack_scsi(bus_ack_scsi),
299                       .bus_rdata_scsi(bus_rdata_scsi),
300                       .bus_cs_scc(bus_cs_scc),
301                       .bus_ack_scc(bus_ack_scc),
302                       .bus_rdata_scc(bus_rdata_scc),
303                       .bus_cs_via(bus_cs_via),
304                       .bus_ack_via(bus_ack_via),
305                       .bus_rdata_via(bus_rdata_via),
306                       .bus_cs_iwm(bus_cs_iwm),
307                       .bus_ack_iwm(bus_ack_iwm),
308                       .bus_rdata_iwm(bus_rdata_iwm),
309                       .rom_ovl(via_pa_rom_ovl));
310
311         /* CPU interrupt inputs */
312         /* 
313          * Don't assert _via_irq if _scc_irq is asserted
314          * a temporary spurrious is fine but the ROM will not
315          * handle otherwise a level 3 (it just RTEs).
316          */
317         assign _cpu_ipl = _prg_irq ?
318                           {1'b1, _scc_irq, _via_irq | ~_scc_irq }
319                           : 3'b000;     
320
321         /* Instanciate memory interface */
322         mem_intf mem0(.sysclk(sysclk16),
323                       .reset(reset),
324                       .ram_data(ram_data),
325                       .ram_address(ram_address),
326                       ._ram_ce(_ram_ce),
327                       ._ram_bhe(_ram_bhe),
328                       ._ram_ble(_ram_ble),
329                       ._ram_we(_ram_we),
330                       ._ram_oe(_ram_oe),
331                       .bus_cs_ram(bus_cs_ram),
332                       .bus_cs_rom(bus_cs_rom),
333                       .bus_we(bus_we),
334                       .bus_ack(bus_ack_mem),
335                       .bus_addr(bus_addr[22:1]),
336                       .bus_ube(bus_ube),
337                       .bus_lbe(bus_lbe),
338                       .bus_phase(bus_phase),
339                       .bus_wdata(bus_wdata),
340                       .bus_rdata(bus_rdata_mem),
341                       .bb_addr(bb_addr),
342                       .bb_wdata(bb_wdata),
343                       .bb_rdata(bb_rdata_mem),
344                       .bb_strobe(bb_strobe & bb_cs_mem),
345                       .bb_wr(bb_wr),
346                       .vid_bufsel(via_pa_vidbuf_sel),
347                       .vid_req(vid_req),
348                       .vid_ack(vid_ack),
349                       .vid_pixels(vid_pixels)); 
350                               
351         /* Instanciate VIA */
352         via6522 via0(.sysclk(sysclk16),
353                      .reset(reset),
354                      .cs(bus_cs_via & bus_phase),
355                      .we(bus_we),
356                      .rs(bus_addr[12:9]),
357                      .wdata(bus_wdata[15:8]),
358                      .rdata(bus_rdata_via),
359                      ._irq(_via_irq),
360                      .pa_in7(via_pa_scc_wreq),
361                      .pa_out({via_pa_vidbuf_sel,
362                               via_pa_disksel,
363                               via_pa_rom_ovl,
364                               via_pa_sndbuf_sel,
365                               via_pa_sndvol}),
366                      .pb_out2_0({_rtc_data_enable,
367                                  rtc_data_clock,
368                                  rtc_data_out}),
369                      .pb_out7(via_pb_snddis),
370                      .pb_in6_3({hblank_sync,
371                                 via_pb_mouse_y2,
372                                 via_pb_mouse_x2,
373                                 via_pb_mouse_switch}),
374                      .pb_in0(rtc_data_in),
375                      .sr_in(via_kbd_in),
376                      .sr_in_strobe(via_kbd_in_strobe),
377                      .sr_out(via_kbd_out),
378                      .sr_out_strobe(via_kbd_out_strobe),
379                      .ca1(_vblank_sync),
380                      .ca2(rtc_onesec));
381           
382         /* Simplified one-phase interface */
383         assign bus_ack_via = bus_cs_via;
384
385         /* Instanciate the RTC */
386         rtc rtc0(.sysclk(sysclk16),
387                  .reset(reset),
388                  .onesec(rtc_onesec),
389                  .data_in(rtc_data_in),
390                  .data_out(rtc_data_out),
391                  .data_clock(rtc_data_clock),
392                  ._data_enable(_rtc_data_enable));
393                  
394         /* Instanciate scc */
395         scc scc0(.sysclk(sysclk16),
396                  .reset_hw(reset),
397                  .cs(bus_cs_scc & bus_phase),
398                  .we(bus_we),
399                  .rs(bus_addr[2:1]),
400                  .wdata(bus_wdata[15:8]),
401                  .rdata(bus_rdata_scc),
402                  ._irq(_scc_irq),
403                  .rxd(rxd),
404                  .txd(txd),
405                  .cts(cts),
406                  .rts(rts),
407                  .dcd_a(scc_mouse_x1),
408                  .dcd_b(scc_mouse_y1),
409                  .wreq(via_pa_scc_wreq));
410         /* Simplified one-phase interface */
411         assign bus_ack_scc = bus_cs_scc;        
412
413         /* Instanciate iwm */
414         iwm iwm0(.sysclk(sysclk16),
415                  .reset(reset),
416                  .cs(bus_cs_iwm),
417                  .we(bus_we),
418                  .ack(bus_ack_iwm),
419                  .phase(bus_phase),
420                  .rs(bus_addr[12:9]),
421                  .wdata(bus_wdata[7:0]),
422                  .rdata(bus_rdata_iwm),
423                  .bb_addr(bb_addr),
424                  .bb_wdata(bb_wdata),
425                  .bb_rdata(bb_rdata_iwm),
426                  .bb_strobe(bb_strobe && bb_cs_iwm),
427                  .bb_wr(bb_wr),
428                  .via_sel(via_pa_disksel));
429         
430         /* Instanciate scsi */
431         ncr5380 scsi0(.sysclk(sysclk16),
432                       .reset(reset),
433                       .bus_cs(bus_cs_scsi),
434                       .bus_we(bus_we),
435                       .bus_ack(bus_ack_scsi),
436                       .bus_phase(bus_phase),
437                       .bus_rs(bus_addr[6:4]),
438                       .dack(bus_addr[9]),
439                       .wdata(bus_wdata[15:8]),
440                       .rdata(bus_rdata_scsi),
441                       .scsi_hshake(scsi_hshake),
442                       .bb_addr(bb_addr),
443                       .bb_wdata(bb_wdata),
444                       .bb_rdata(bb_rdata_scsi),
445                       .bb_strobe(bb_strobe && bb_cs_scsi),
446                       .bb_wr(bb_wr));
447
448         /* Instanciate video output module */
449         video video0(.pixclk(pixclk),
450                      .reset(reset),
451                      .pixels(vid_pixels),
452                      .req_pix(vid_req),
453                      .ack_pix(vid_ack),
454                      ._hsync(_hsync),
455                      ._vsync(_vsync),
456                      .red(red),
457                      .green(green),
458                      .blue(blue),
459                      .hblank(vid_hblank));
460
461         /* Instanciate the PS/2 mouse interface */
462         ps2_mouse mouse0(.sysclk(sysclk16),
463                          .reset(reset),
464                          .ps2dat(msdat),
465                          .ps2clk(msclk),
466                          .x1(scc_mouse_x1),
467                          .y1(scc_mouse_y1),
468                          .x2(via_pb_mouse_x2),
469                          .y2(via_pb_mouse_y2),
470                          .button(via_pb_mouse_switch),
471                          .debug(ps2m_dbg));
472
473         /* Instanciate the PS/2 keyboard interface */
474         ps2_kbd kbd0(.sysclk(sysclk16),
475                      .reset(reset),
476                      .ps2dat(kbddat),
477                      .ps2clk(kbdclk),
478                      .data_out(via_kbd_out),
479                      .strobe_out(via_kbd_out_strobe),
480                      .data_in(via_kbd_in),
481                      .strobe_in(via_kbd_in_strobe),
482                      .debug(ps2k_dbg));
483
484         /* Instanciate global backbus control registers */
485         ctrl ctrl0(.sysclk(sysclk16),
486                    .reset(reset),
487                    .bb_addr(bb_addr),
488                    .bb_wdata(bb_wdata),
489                    .bb_rdata(bb_rdata_ctrl),
490                    .bb_strobe(bb_strobe && bb_cs_ctrl),
491                    .bb_wr(bb_wr),
492                    .ps2m_dbg(ps2m_dbg),
493                    .ps2k_dbg(ps2k_dbg),
494                    .cpu_reset(ctrl_cpu_reset));
495
496         /* Generate backbus chip selects and mux the backbus read data */
497         assign bb_cs_ctrl  = bb_addr[5:3] == 3'b000;
498         assign bb_cs_cpu   = bb_addr[5:4] == 3'b001;
499         assign bb_cs_mem   = bb_addr[5:3] == 3'b100;
500         assign bb_cs_iwm   = bb_addr[5:3] == 3'b101;
501         assign bb_cs_scsi  = bb_addr[5:3] == 3'b110;
502         assign bb_cs_scope = bb_addr[5:3] == 3'b111;
503
504         assign bb_rdata = bb_cs_ctrl  ? bb_rdata_ctrl :
505                           bb_cs_cpu   ? bb_rdata_cpu :
506                           bb_cs_iwm   ? bb_rdata_iwm :
507                           bb_cs_scsi  ? bb_rdata_scsi :
508                           bb_cs_mem   ? bb_rdata_mem :
509                           bb_cs_scope ? bb_rdata_scope : 8'hff;
510
511         /* Test LED */
512         always@(posedge sysclk16) begin
513                 if (reset) begin
514                         led <= 0;
515                         led_cnt <= 0;
516                 end else begin
517                         led_cnt <= led_cnt + 1;
518                         if (led_cnt == 1000000) begin
519                                 led_cnt <= 0;
520                                 led <= ~led;
521                         end
522                 end
523         end
524
525         /* Programmer switch, latch the button */
526         always@(posedge sysclk16) begin
527                 if (reset) begin
528                         nmi_sync <= 0;
529                         _prg_irq <= 1;
530                 end else begin
531                         nmi_sync <= nmi;
532                         _prg_irq <= ~nmi_sync;
533                 end
534         end     
535
536         /* Not real synchronizers but will do */
537         always@(posedge sysclk16 or posedge reset) begin
538                 if (reset) begin
539                         _vblank_sync <= 1;
540                         hblank_sync <= 0;
541                 end else begin
542                         _vblank_sync <= _vsync;
543                         hblank_sync <= vid_hblank;
544                 end
545         end
546
547         /* LED output powered by a weak pullup */
548         assign pwrled = led ? 1'b1 : 1'bz;
549                 
550         /* Unused output signals */
551         assign kbddat = 1'bz;
552         assign kbdclk = 1'bz;   
553
554         assign left = 0;
555         assign right = 0;
556
557         assign init_b = 0;
558         assign gpio = 1'bz;     
559         
560 endmodule // mimigmac