`include "../include/tune.v"
module top(
// clocks
input fclk,
output clkz_out,
input clkz_in,
// z80
input iorq_n,
input mreq_n,
input rd_n,
input wr_n,
input m1_n,
input rfsh_n,
output int_n,
output nmi_n,
output wait_n,
output res,
inout [7:0] d,
input [15:0] a,
// zxbus and related
output csrom,
output romoe_n,
output romwe_n,
output rompg0_n,
output dos_n, // aka rompg1
output rompg2,
output rompg3,
output rompg4,
input iorqge1,
input iorqge2,
output iorq1_n,
output iorq2_n,
// DRAM
inout [15:0] rd,
output [9:0] ra,
output rwe_n,
output rucas_n,
output rlcas_n,
output rras0_n,
output rras1_n,
// video
output [1:0] vred,
output [1:0] vgrn,
output [1:0] vblu,
output vhsync,
output vvsync,
output vcsync,
// AY control and audio/tape
output ay_clk,
output ay_bdir,
output ay_bc1,
output beep,
// IDE
output [2:0] ide_a,
inout [15:0] ide_d,
output ide_dir,
input ide_rdy,
output ide_cs0_n,
output ide_cs1_n,
output ide_rs_n,
output ide_rd_n,
output ide_wr_n,
// VG93 and diskdrive
output vg_clk,
output vg_cs_n,
output vg_res_n,
output vg_hrdy,
output vg_rclk,
output vg_rawr,
output [1:0] vg_a, // disk drive selection
output vg_wrd,
output vg_side,
input step,
input vg_sl,
input vg_sr,
input vg_tr43,
input rdat_b_n,
input vg_wf_de,
input vg_drq,
input vg_irq,
input vg_wd,
// serial links (atmega-fpga, sdcard)
output sdcs_n,
output sddo,
output sdclk,
input sddi,
input spics_n,
input spick,
input spido,
output spidi,
output spiint_n
);
wire dos;
wire zclk; // z80 clock for short
wire rst_n; // global reset
wire rrdy;
wire cbeg;
wire [15:0] rddata;
wire [4:0] rompg;
wire [7:0] zports_dout;
wire zports_dataout;
wire porthit;
wire [39:0] kbd_data;
wire [ 7:0] mus_data;
wire kbd_stb,mus_xstb,mus_ystb,mus_btnstb,kj_stb;
wire [ 4:0] kbd_port_data;
wire [ 4:0] kj_port_data;
wire [ 7:0] mus_port_data;
wire [7:0] wait_read,wait_write;
wire wait_rnw;
wire wait_start_gluclock;
wire wait_end;
wire [7:0] gluclock_addr;
wire [6:0] waits;
// config signals
wire [7:0] not_used;
wire cfg_vga_on;
wire set_nmi;
wire turbo_key;
wire noturbo_key;
wire tape_in;
wire [15:0] ideout;
wire [15:0] idein;
wire idedataout;
wire [7:0] zmem_dout;
wire zmem_dataout;
reg [3:0] ayclk_gen;
wire [7:0] received;
wire [7:0] tobesent;
wire intrq,drq;
wire vg_wrFF;
wire [1:0] rstrom;
assign zclk = clkz_in;
// RESETTER
wire genrst;
resetter myrst( .clk(fclk),
.rst_in_n(~genrst),
.rst_out_n(rst_n) );
defparam myrst.RST_CNT_SIZE = 6;
assign nmi_n = nmi_out ? 1'b0 : 1'bZ;
assign res= ~rst_n;
assign ide_rs_n = turbo;
assign ide_d = idedataout ? ideout : 16'hZZZZ;
assign idein = ide_d;
assign ide_dir = ~idedataout;
wire [7:0] p1ffd;
wire [7:0] p7ffd;
wire [7:0] peff7;
wire tape_read;
wire [2:0] comport_addr;
wire wait_start_comport;
wire cpu_req,cpu_rnw,cpu_wrbsel,cpu_strobe;
wire [20:0] cpu_addr;
wire [15:0] cpu_rddata;
wire [7:0] cpu_wrdata;
wire cend,pre_cend,go;
wire sd_start;
wire [7:0] sd_dataout,sd_datain;
//AY control
always @(posedge fclk)
begin
ayclk_gen <= ayclk_gen + 4'd1;
end
assign ay_clk = ayclk_gen[3];
assign rompg0_n = ~rompg[0];
assign dos_n = ~rompg[1];
assign rompg2 = prof1;
assign rompg3 = prof2;
assign rompg4 = 1'b0;
zclock z80clk( .fclk(fclk), .rst_n(rst_n), .zclk(zclk), .rfsh_n(rfsh_n), .zclk_out(clkz_out),
.turbo( {1'b0,turbo} ), .pre_cend(pre_cend), .cbeg(cbeg) );
wire [7:0] dout_ram;
wire ena_ram;
wire [7:0] dout_ports;
wire ena_ports;
wire prof1;
wire prof2;
wire [7:0] attr;
wire [7:0] portFF;
assign portFF = (a[7:0]==8'hff)? ((hpix && vpix)? attr : 8'hFF) : 8'hff;
wire [2:0] border;
wire drive_ff;
// data bus out: either RAM data or internal ports data or 0xFF with unused ports
assign d = ena_ram ? dout_ram : ( ena_ports ? dout_ports : ( drive_ff ? portFF : 8'bZZZZZZZZ ) );
zbus zxbus( .iorq_n(iorq_n), .rd_n(rd_n), .wr_n(wr_n), .m1_n(m1_n),
.iorq1_n(iorq1_n), .iorq2_n(iorq2_n), .iorqge1(iorqge1), .iorqge2(iorqge2),
.porthit(porthit), .drive_ff(drive_ff) );
zmem z80mem( .fclk(fclk), .rst_n(rst_n), .zpos(1'b0), .zneg(1'b0),
.cend(cend), .pre_cend(pre_cend), .za(a), .zd_in(d),
.zd_out(dout_ram), .zd_ena(ena_ram), .m1_n(m1_n),
.rfsh_n(rfsh_n), .iorq_n(iorq_n), .mreq_n(mreq_n),
.rd_n(rd_n), .wr_n(wr_n),
.win0_romnram(~p1ffd[0]),
.win1_romnram(1'b0),
.win2_romnram(1'b0),
.win3_romnram(1'b0),
.win0_page( p1ffd[0] ? 8'd0 : ( p1ffd[1] ? 8'd02 : {6'h0,dos,p7ffd[4]} )),
.win1_page(8'd5),
.win2_page(8'd2),
.win3_page( {2'b00,p1ffd[7:6],p1ffd[4],p7ffd[2:0]} ),
.dos(dos),
.rompg(rompg),
.romoe_n(romoe_n),
.romwe_n(romwe_n),
.csrom(csrom),
.cpu_req(cpu_req),
.cpu_rnw(cpu_rnw),
.cpu_wrbsel(cpu_wrbsel),
.cpu_strobe(cpu_strobe),
.cpu_addr(cpu_addr),
.cpu_wrdata(cpu_wrdata),
.cpu_rddata(cpu_rddata) );
wire [20:0] daddr;
wire dreq;
wire drnw;
wire [15:0] drddata;
wire [15:0] dwrdata;
wire [1:0] dbsel;
dram dramko( .clk(fclk),
.rst_n(rst_n),
.addr(daddr),
.req(dreq),
.rnw(drnw),
.cbeg(cbeg),
.rrdy(drrdy),
.rddata(drddata),
.wrdata(dwrdata),
.bsel(dbsel),
.ra(ra),
.rd(rd),
.rwe_n(rwe_n),
.rucas_n(rucas_n),
.rlcas_n(rlcas_n),
.rras0_n(rras0_n),
.rras1_n(rras1_n) );
wire [1:0] bw;
wire [20:0] video_addr;
wire [15:0] video_data;
wire video_strobe;
wire video_next;
arbiter dramarb( .clk(fclk),
.rst_n(rst_n),
.dram_addr(daddr),
.dram_req(dreq),
.dram_rnw(drnw),
.dram_cbeg(cbeg),
.dram_rrdy(drrdy),
.dram_bsel(dbsel),
.dram_rddata(drddata),
.dram_wrdata(dwrdata),
.cend(cend),
.pre_cend(pre_cend),
.go(go),
.bw(bw),
.video_addr(video_addr),
.video_data(video_data),
.video_strobe(video_strobe),
.video_next(video_next),
//.cpu_waitcyc(cpu_waitcyc),
//.cpu_stall(cpu_stall),
.cpu_req(cpu_req),
.cpu_rnw(cpu_rnw),
.cpu_addr(cpu_addr),
.cpu_wrbsel(cpu_wrbsel),
.cpu_wrdata(cpu_wrdata),
.cpu_rddata(cpu_rddata),
.cpu_strobe(cpu_strobe) );
wire vga_hsync,hsync,hblank,hpix,hsync_start,line_start,hint_start,scanin_start,scanout_start;
synch horiz_sync( .clk(fclk), .init(1'b0), .cend(cend), .pre_cend(pre_cend),
.hsync(hsync), .hblank(hblank), .hpix(hpix), .hsync_start(hsync_start),
.line_start(line_start), .hint_start(hint_start), .scanin_start(scanin_start) );
wire vblank,vsync,int_start,vpix;
syncv vert_sync( .clk(fclk), .hsync_start(hsync_start), .line_start(line_start),
.vblank(vblank), .vsync(vsync), .int_start(int_start),
.vpix(vpix), .hint_start(hint_start) );
vga_synch vga_synch( .clk(fclk), .hsync_start(hsync_start), .vga_hsync(vga_hsync), .scanout_start(scanout_start) );
wire [5:0] pixel;
fetch fecher( .clk(fclk), .cend(cend), .line_start(line_start), .vpix(vpix), .int_start(int_start),
.vmode( {peff7[0],peff7[5]} ), .screen(p7ffd[3]), .video_addr(video_addr), .video_data(video_data),
.video_strobe(video_strobe), .video_next(video_next), .go(go), .bw(bw), .attr(attr), .pixel(pixel) );
videoout vidia( .clk(fclk), .pixel(pixel), .border({ border[1],1'b0,border[2],1'b0,border[0],1'b0 }),
.hblank(hblank), .vblank(vblank), .hpix(hpix), .vpix(vpix), .hsync(hsync), .vsync(vsync),
.vred(vred), .vgrn(vgrn), .vga_hsync(vga_hsync), .vblu(vblu),
.vhsync(vhsync), .vvsync(vvsync), .vcsync(vcsync), .hsync_start(hsync_start),
.scanin_start(scanin_start), .scanout_start(scanout_start), .cfg_vga_on(cfg_vga_on) );
slavespi slavespi( .fclk(fclk), .rst_n(rst_n),
.spics_n(spics_n), .spidi(spidi),
.spido(spido), .spick(spick),
.status_in({wait_rnw, waits[6:0]}), .genrst(genrst),
.rstrom(rstrom), .kbd_out(kbd_data),
.kbd_stb(kbd_stb), .mus_out(mus_data),
.mus_xstb(mus_xstb), .mus_ystb(mus_ystb),
.mus_btnstb(mus_btnstb), .kj_stb(kj_stb),
.gluclock_addr(gluclock_addr),
.comport_addr (comport_addr),
.wait_write(wait_write),
.wait_read(wait_read),
.wait_rnw(wait_rnw),
.wait_end(wait_end),
.config0( { not_used[7:5], noturbo_key, turbo_key, tape_read, set_nmi, cfg_vga_on} )
);
zkbdmus zkbdmus( .fclk(fclk), .rst_n(rst_n),
.kbd_in(kbd_data), .kbd_stb(kbd_stb),
.mus_in(mus_data), .mus_xstb(mus_xstb),
.mus_ystb(mus_ystb), .mus_btnstb(mus_btnstb),
.kj_stb(kj_stb), .kj_data(kj_port_data),
.zah(a[15:8]), .kbd_data(kbd_port_data),
.mus_data(mus_port_data)
);
zports porty( .clk(zclk), .fclk(fclk), .rst_n(rst_n), .din(d), .dout(dout_ports), .dataout(ena_ports),
.a(a), .iorq_n(iorq_n), .rd_n(rd_n), .wr_n(wr_n), .porthit(porthit),
.ay_bdir(ay_bdir), .ay_bc1(ay_bc1), .border(border), .beep(beep),
.p7ffd(p7ffd), .p1ffd(p1ffd), .peff7(peff7), .mreq_n(mreq_n), .m1_n(m1_n), .dos(dos),
.rstrom(rstrom), .vg_intrq(intrq), .vg_drq(drq), .vg_wrFF(vg_wrFF),
.vg_cs_n(vg_cs_n), .sd_start(sd_start), .sd_dataout(sd_dataout),
.sd_datain(sd_datain), .sdcs_n(sdcs_n),
.idein(idein), .ideout(ideout), .idedataout(idedataout),
.ide_a(ide_a), .ide_cs0_n(ide_cs0_n), .ide_cs1_n(ide_cs1_n),
.ide_wr_n(ide_wr_n), .ide_rd_n(ide_rd_n),
.keys_in(kbd_port_data),
.mus_in(mus_port_data),
.kj_in(kj_port_data),
.tape_read(tape_read),
.turbo_key(turbo_key),
.noturbo_key(noturbo_key),
.gluclock_addr(gluclock_addr),
.comport_addr (comport_addr),
.wait_start_gluclock(wait_start_gluclock),
.wait_start_comport (wait_start_comport),
.wait_rnw(wait_rnw),
.wait_write(wait_write),
.wait_read(wait_read),
.nmi_key(set_nmi),
.nmi_out(nmi_out),
.turbo(turbo)
);
zint preryv( .fclk(fclk), .zclk(zclk), .int_start(int_start), .iorq_n(iorq_n), .m1_n(m1_n),
.int_n(int_n) );
zwait zwait( .wait_start_gluclock(wait_start_gluclock),
.wait_end(wait_end),
.rst_n(rst_n),
.wait_start_comport (wait_start_comport),
.wait_n(wait_n),
.waits(waits),
.spiint_n(spiint_n) );
assign wait_n = 1'bZ;
wire [1:0] vg_ddrv;
assign vg_a[0] = vg_ddrv[0] ? 1'b1 : 1'b0; // possibly open drain?
assign vg_a[1] = vg_ddrv[1] ? 1'b1 : 1'b0;
vg93 vgshka( .zclk(zclk), .rst_n(rst_n), .fclk(fclk), .vg_clk(vg_clk),
.vg_res_n(vg_res_n), .din(d), .intrq(intrq), .drq(drq), .vg_wrFF(vg_wrFF),
.vg_hrdy(vg_hrdy), .vg_rclk(vg_rclk), .vg_rawr(vg_rawr), .vg_a(vg_ddrv),
.vg_wrd(vg_wrd), .vg_side(vg_side), .step(step), .vg_sl(vg_sl), .vg_sr(vg_sr),
.vg_tr43(vg_tr43), .rdat_n(rdat_b_n), .vg_wf_de(vg_wf_de), .vg_drq(vg_drq),
.vg_irq(vg_irq), .vg_wd(vg_wd) );
spi2 zspi( .clock(fclk), .sck(sdclk), .sdo(sddo), .sdi(sddi), .start(sd_start),
.speed(2'b00), .din(sd_datain), .dout(sd_dataout) );
pfpzu profrom(.oe_n(!(csrom) | romoe_n),
.a({rompg[1],rompg[0],a[13:2]}),
.a16(prof1),
.a17(prof2),
.res_n(rst_n));
endmodule