Files
TSConf_MiST/rtl/video/video_top.v

643 lines
16 KiB
Verilog

`include "tune.v"
// This module is a video top-level
module video_top
(
// clocks
input wire clk,
input wire f0, f1,
input wire h1,
input wire c0, c1, c3,
// input wire t0, // debug!!!
// video DAC
output wire [1:0] vred,
output wire [1:0] vgrn,
output wire [1:0] vblu,
// video raw (for 15 bit DAC)
output wire [4:0] vred_raw,
output wire [4:0] vgrn_raw,
output wire [4:0] vblu_raw,
output wire vdac_mode,
`ifdef IDE_VDAC2
output wire vdac2_msel,
`endif
// video syncs
output wire hsync,
output wire vsync,
output wire csync,
// Z80 controls
input wire [ 7:0] d,
input wire [15:0] zmd,
input wire [ 7:0] zma,
input wire cram_we,
input wire sfile_we,
// port write strobes
input wire zborder_wr,
input wire border_wr,
input wire zvpage_wr,
input wire vpage_wr,
input wire vconf_wr,
input wire gx_offsl_wr,
input wire gx_offsh_wr,
input wire gy_offsl_wr,
input wire gy_offsh_wr,
input wire t0x_offsl_wr,
input wire t0x_offsh_wr,
input wire t0y_offsl_wr,
input wire t0y_offsh_wr,
input wire t1x_offsl_wr,
input wire t1x_offsh_wr,
input wire t1y_offsl_wr,
input wire t1y_offsh_wr,
input wire tsconf_wr,
input wire palsel_wr,
input wire tmpage_wr,
input wire t0gpage_wr,
input wire t1gpage_wr,
input wire sgpage_wr,
input wire hint_beg_wr ,
input wire vint_begl_wr,
input wire vint_begh_wr,
// ZX controls
input wire res,
output wire int_start,
output wire line_start_s,
`ifdef PENT_312
output wire [4:0] hcnt,
output wire upper8,
`endif
// DRAM interface
output wire [20:0] video_addr,
output wire [ 4:0] video_bw,
output wire video_go,
input wire [15:0] dram_rdata, // raw, should be latched by c2
input wire video_pre_next,
input wire video_strobe,
output wire [20:0] ts_addr,
output wire ts_req,
input wire ts_pre_next,
input wire ts_next,
output wire [20:0] tm_addr,
output wire tm_req,
input wire tm_next,
// video controls
input wire cfg_60hz,
input wire vga_on
);
// video config
wire [7:0] vpage; // re-latched at line_start
wire [7:0] vconf; //
wire [8:0] gx_offs; //
wire [8:0] gy_offs; //
wire [7:0] palsel; //
wire [8:0] t0x_offs; //
wire [8:0] t1x_offs; //
wire [7:0] t0gpage; //
wire [7:0] t1gpage; //
wire [7:0] sgpage; // * not yet !!!
wire [8:0] t0y_offs;
wire [8:0] t1y_offs;
wire [7:0] tsconf;
wire [7:0] tmpage;
wire [7:0] hint_beg;
wire [8:0] vint_beg;
wire [8:0] hpix_beg;
wire [8:0] hpix_end;
wire [8:0] vpix_beg;
wire [8:0] vpix_end;
wire [8:0] hpix_beg_ts;
wire [8:0] hpix_end_ts;
wire [8:0] vpix_beg_ts;
wire [8:0] vpix_end_ts;
wire [5:0] x_tiles;
wire [9:0] x_offs_mode;
wire [4:0] go_offs;
wire [1:0] render_mode;
wire tv_hires;
wire vga_hires;
wire v60hz;
wire nogfx = vconf[5];
wire notsu = vconf[4];
`ifdef IDE_VDAC2
assign vdac2_msel = vconf[2];
`endif
wire tv_blank;
// counters
wire [7:0] cnt_col;
wire [8:0] cnt_row;
wire cptr;
wire [3:0] scnt;
wire [8:0] lcount;
// synchro
wire frame_start;
wire pix_start;
wire tv_pix_start;
wire vga_pix_start;
wire ts_start;
wire vga_blank;
wire vga_line;
wire v_ts;
wire v_pf;
wire hpix;
wire vpix;
wire hvpix;
wire hvtspix;
wire frame;
wire flash;
wire pix_stb;
// fetcher
wire [31:0] fetch_data;
wire [31:0] fetch_temp;
wire [3:0] fetch_sel;
wire [1:0] fetch_bsl;
wire fetch_stb;
// video data
wire [7:0] border;
wire [7:0] vplex;
wire [7:0] vgaplex;
// TS
wire tsr_go;
wire [5:0] tsr_addr;
wire [8:0] tsr_line;
wire [7:0] tsr_page;
wire [8:0] tsr_x;
wire [2:0] tsr_xs;
wire tsr_xf;
wire [3:0] tsr_pal;
wire tsr_rdy;
// TS-line
wire [8:0] ts_waddr;
wire [7:0] ts_wdata;
wire ts_we;
wire [8:0] ts_raddr;
// VGA-line
wire [9:0] vga_cnt_in;
wire [9:0] vga_cnt_out;
wire [7:0] ts_rdata0, ts_rdata1;
wire tl_act0 = lcount[0];
wire tl_act1 = ~lcount[0];
wire [8:0] ts_waddr0 = tl_act0 ? ts_raddr : ts_waddr;
wire [7:0] ts_wdata0 = tl_act0 ? 8'd0 : ts_wdata;
wire ts_we0 = tl_act0 ? c3 : ts_we;
wire [8:0] ts_waddr1 = tl_act1 ? ts_raddr : ts_waddr;
wire [7:0] ts_wdata1 = tl_act1 ? 8'd0 : ts_wdata;
wire ts_we1 = tl_act1 ? c3 : ts_we;
wire [7:0] ts_rdata = tl_act0 ? ts_rdata0 : ts_rdata1;
video_ports video_ports
(
.clk (clk),
.d (d),
.res (res),
.line_start_s (line_start_s),
.border_wr (border_wr),
.zborder_wr (zborder_wr),
.zvpage_wr (zvpage_wr),
.vpage_wr (vpage_wr),
.vconf_wr (vconf_wr),
.gx_offsl_wr (gx_offsl_wr),
.gx_offsh_wr (gx_offsh_wr),
.gy_offsl_wr (gy_offsl_wr),
.gy_offsh_wr (gy_offsh_wr),
.t0x_offsl_wr (t0x_offsl_wr),
.t0x_offsh_wr (t0x_offsh_wr),
.t0y_offsl_wr (t0y_offsl_wr),
.t0y_offsh_wr (t0y_offsh_wr),
.t1x_offsl_wr (t1x_offsl_wr),
.t1x_offsh_wr (t1x_offsh_wr),
.t1y_offsl_wr (t1y_offsl_wr),
.t1y_offsh_wr (t1y_offsh_wr),
.palsel_wr (palsel_wr),
.hint_beg_wr (hint_beg_wr),
.vint_begl_wr (vint_begl_wr),
.vint_begh_wr (vint_begh_wr),
.tsconf_wr (tsconf_wr),
.tmpage_wr (tmpage_wr),
.t0gpage_wr (t0gpage_wr),
.t1gpage_wr (t1gpage_wr),
.sgpage_wr (sgpage_wr),
.border (border),
.vpage (vpage),
.vconf (vconf),
.gx_offs (gx_offs),
.gy_offs (gy_offs),
.t0x_offs (t0x_offs),
.t1x_offs (t1x_offs),
.t0y_offs (t0y_offs),
.t1y_offs (t1y_offs),
.palsel (palsel),
.hint_beg (hint_beg),
.vint_beg (vint_beg),
`ifdef AUTO_INT
.int_start (int_start),
`else
.int_start (1'b0),
`endif
.tsconf (tsconf),
.tmpage (tmpage),
.t0gpage (t0gpage),
.t1gpage (t1gpage),
.sgpage (sgpage)
);
video_mode video_mode
(
.clk (clk),
.f1 (f1),
.c3 (c3),
.vpage (vpage),
.vconf (vconf),
.v60hz (v60hz),
.fetch_sel (fetch_sel),
.fetch_bsl (fetch_bsl),
.fetch_cnt (scnt),
.fetch_stb (fetch_stb),
.txt_char (fetch_temp[15:0]),
.gx_offs (gx_offs),
.x_offs_mode (x_offs_mode),
`ifdef XTR_FEAT
.ts_rres_ext (tsconf[0]),
`else
.ts_rres_ext (1'b0),
`endif
.hpix_beg (hpix_beg),
.hpix_end (hpix_end),
.vpix_beg (vpix_beg),
.vpix_end (vpix_end),
.hpix_beg_ts (hpix_beg_ts),
.hpix_end_ts (hpix_end_ts),
.vpix_beg_ts (vpix_beg_ts),
.vpix_end_ts (vpix_end_ts),
.x_tiles (x_tiles),
.go_offs (go_offs),
.cnt_col (cnt_col),
.cnt_row (cnt_row),
.cptr (cptr),
.line_start_s (line_start_s),
.pix_start (pix_start),
.tv_hires (tv_hires),
.vga_hires (vga_hires),
.pix_stb (pix_stb),
.render_mode (render_mode),
.video_addr (video_addr),
.video_bw (video_bw)
);
video_sync video_sync
(
.clk (clk),
.f1 (f1),
.c0 (c0),
.c3 (c3),
.hpix_beg (hpix_beg),
.hpix_end (hpix_end),
.vpix_beg (vpix_beg),
.vpix_end (vpix_end),
.hpix_beg_ts (hpix_beg_ts),
.hpix_end_ts (hpix_end_ts),
.vpix_beg_ts (vpix_beg_ts),
.vpix_end_ts (vpix_end_ts),
.go_offs (go_offs),
.x_offs (x_offs_mode[1:0]),
.y_offs_wr (gy_offsl_wr || gy_offsh_wr),
.line_start_s (line_start_s),
.hint_beg (hint_beg),
.vint_beg (vint_beg),
.hsync (hsync),
.vsync (vsync),
.csync (csync),
.tv_blank (tv_blank),
.vga_blank (vga_blank),
.vga_cnt_in (vga_cnt_in),
.vga_cnt_out (vga_cnt_out),
.ts_raddr (ts_raddr),
.lcount (lcount),
.cnt_col (cnt_col),
.cnt_row (cnt_row),
.cptr (cptr),
.scnt (scnt),
`ifdef PENT_312
.hcnt (hcnt),
.upper8 (upper8),
`endif
.frame (frame),
.flash (flash),
.pix_stb (pix_stb),
.pix_start (pix_start),
.ts_start (ts_start),
.cstart (x_offs_mode[9:2]),
.rstart (gy_offs),
.vga_line (vga_line),
.frame_start (frame_start),
.int_start (int_start),
.v_pf (v_pf),
.hpix (hpix),
.v_ts (v_ts),
.vpix (vpix),
.hvpix (hvpix),
.hvtspix (hvtspix),
.nogfx (nogfx),
.vga_on (vga_on),
.cfg_60hz (cfg_60hz),
.v60hz (v60hz),
.video_go (video_go),
.video_pre_next (video_pre_next)
);
video_fetch video_fetch
(
.clk (clk),
.f_sel (fetch_sel),
.b_sel (fetch_bsl),
.fetch_stb (fetch_stb),
.fetch_data (fetch_data),
.fetch_temp (fetch_temp),
.video_strobe (video_strobe),
.video_data (dram_rdata)
);
video_ts video_ts
(
.clk (clk),
.start (ts_start),
.line (lcount),
.v_ts (v_ts),
`ifdef DISABLE_TSU
.tsconf (0),
`else
.tsconf (tsconf),
// .tsconf ({3'b0, tsconf[4:0]}), // no TSU
// .tsconf ({1'b0, tsconf[6:0]}), // no sprites
// .tsconf ({tsconf[7], 2'b00, tsconf[4:0]}), // no tiles
`endif
.t0gpage (t0gpage),
.t1gpage (t1gpage),
.sgpage (sgpage),
.tmpage (tmpage),
.num_tiles (x_tiles),
.v_pf (v_pf),
.t0x_offs (t0x_offs),
.t1x_offs (t1x_offs),
.t0y_offs (t0y_offs),
.t1y_offs (t1y_offs),
.t0_palsel (palsel[5:4]),
.t1_palsel (palsel[7:6]),
.dram_addr (tm_addr),
.dram_req (tm_req),
.dram_next (tm_next),
.dram_rdata (dram_rdata),
.tsr_go (tsr_go),
.tsr_addr (tsr_addr),
.tsr_line (tsr_line),
.tsr_page (tsr_page),
.tsr_pal (tsr_pal),
.tsr_x (tsr_x),
.tsr_xs (tsr_xs),
.tsr_xf (tsr_xf),
.tsr_rdy (tsr_rdy),
.sfile_addr_in (zma),
.sfile_data_in (zmd),
.sfile_we (sfile_we)
);
video_ts_render video_ts_render
(
.clk (clk),
.reset (ts_start),
.tsr_go (tsr_go),
.addr (tsr_addr),
.line (tsr_line),
.page (tsr_page),
.pal (tsr_pal),
.x_coord (tsr_x),
.x_size (tsr_xs),
.flip (tsr_xf),
.mem_rdy (tsr_rdy),
.ts_waddr (ts_waddr),
.ts_wdata (ts_wdata),
.ts_we (ts_we),
.dram_addr (ts_addr),
.dram_req (ts_req),
.dram_pre_next (ts_pre_next),
.dram_next (ts_next),
.dram_rdata (dram_rdata)
);
video_render video_render
(
.clk (clk),
.c1 (c1),
.hvpix (hvpix),
.hvtspix (hvtspix),
.nogfx (nogfx),
.notsu (notsu),
`ifdef XTR_FEAT
.gfxovr (vconf[3]),
`else
.gfxovr (1'b0),
`endif
.flash (flash),
.hires (tv_hires),
.psel (scnt),
.palsel (palsel[3:0]),
.render_mode (render_mode),
.data (fetch_data),
.border_in (border),
.tsdata_in (ts_rdata),
.vplex_out (vplex)
);
video_out video_out
(
.clk (clk),
.c3 (c3),
.vga_on (vga_on),
.tv_blank (tv_blank),
.vga_blank (vga_blank),
.vga_line (vga_line),
.palsel (palsel[3:0]),
.plex_sel_in ({h1, f1}),
.tv_hires (tv_hires),
.vga_hires (vga_hires),
.cram_addr_in (zma),
.cram_data_in (zmd[15:0]),
.cram_we (cram_we),
.vplex_in (vplex),
.vgaplex (vgaplex),
.vred (vred),
.vgrn (vgrn),
.vblu (vblu),
.vred_raw (vred_raw),
.vgrn_raw (vgrn_raw),
.vblu_raw (vblu_raw),
.vdac_mode (vdac_mode)
);
// 2 buffers: 512 pixels * 8 bits (9x8) - used as bitmap buffer for TS overlay over graphics
dpram #(.ADDRWIDTH(9)) video_tsline0
(
.clock (clk),
.address_a (ts_waddr0),
.data_a (ts_wdata0),
.wren_a (ts_we0),
.address_b (ts_raddr),
.q_b (ts_rdata0)
);
dpram #(.ADDRWIDTH(9)) video_tsline1
(
.clock (clk),
.address_a (ts_waddr1),
.data_a (ts_wdata1),
.wren_a (ts_we1),
.address_b (ts_raddr),
.q_b (ts_rdata1)
);
/*
altdpram video_tsline0
(
.inclock (clk),
.wren (ts_we0),
.data (ts_wdata0),
.rdaddress (ts_raddr),
.wraddress (ts_waddr0),
.q (ts_rdata0),
.aclr (1'b0),
.byteena (1'b1),
.inclocken (1'b1),
.outclock (1'b1),
.outclocken (1'b1),
.rdaddressstall (1'b0),
.rden (1'b1),
.wraddressstall (1'b0)
);
defparam
video_tsline0.indata_aclr = "OFF",
video_tsline0.indata_reg = "INCLOCK",
video_tsline0.intended_device_family = "ACEX1K",
video_tsline0.lpm_type = "altdpram",
video_tsline0.outdata_aclr = "OFF",
video_tsline0.outdata_reg = "UNREGISTERED",
video_tsline0.rdaddress_aclr = "OFF",
video_tsline0.rdaddress_reg = "INCLOCK",
video_tsline0.rdcontrol_aclr = "OFF",
video_tsline0.rdcontrol_reg = "UNREGISTERED",
video_tsline0.width = 8,
video_tsline0.widthad = 9,
video_tsline0.wraddress_aclr = "OFF",
video_tsline0.wraddress_reg = "INCLOCK",
video_tsline0.wrcontrol_aclr = "OFF",
video_tsline0.wrcontrol_reg = "INCLOCK";
altdpram video_tsline1
(
.inclock (clk),
.wren (ts_we1),
.data (ts_wdata1),
.rdaddress (ts_raddr),
.wraddress (ts_waddr1),
.q (ts_rdata1),
.aclr (1'b0),
.byteena (1'b1),
.inclocken (1'b1),
.outclock (1'b1),
.outclocken (1'b1),
.rdaddressstall (1'b0),
.rden (1'b1),
.wraddressstall (1'b0)
);
defparam
video_tsline1.indata_aclr = "OFF",
video_tsline1.indata_reg = "INCLOCK",
video_tsline1.intended_device_family = "ACEX1K",
video_tsline1.lpm_type = "altdpram",
video_tsline1.outdata_aclr = "OFF",
video_tsline1.outdata_reg = "UNREGISTERED",
video_tsline1.rdaddress_aclr = "OFF",
video_tsline1.rdaddress_reg = "INCLOCK",
video_tsline1.rdcontrol_aclr = "OFF",
video_tsline1.rdcontrol_reg = "UNREGISTERED",
video_tsline1.width = 8,
video_tsline1.widthad = 9,
video_tsline1.wraddress_aclr = "OFF",
video_tsline1.wraddress_reg = "INCLOCK",
video_tsline1.wrcontrol_aclr = "OFF",
video_tsline1.wrcontrol_reg = "INCLOCK";
*/
// 2 lines * 512 pix * 8 bit (10x8) - used for VGA doubler
dpram #(.ADDRWIDTH(10)) video_vmem
(
.clock (clk),
.address_a (vga_cnt_in),
.data_a (vplex),
.wren_a (c3),
.address_b (vga_cnt_out),
.q_b (vgaplex)
);
/*
altdpram video_vmem
(
.inclock (clk),
.outclock (clk),
.wren (c3),
.data (vplex),
.rdaddress (vga_cnt_out),
.wraddress (vga_cnt_in),
.q (vgaplex),
.aclr (1'b0),
.byteena (1'b1),
.inclocken (1'b1),
.outclocken (1'b1),
.rdaddressstall (1'b0),
.rden (1'b1),
.wraddressstall (1'b0)
);
defparam
video_vmem.indata_aclr = "OFF",
video_vmem.indata_reg = "INCLOCK",
video_vmem.intended_device_family = "ACEX1K",
video_vmem.lpm_type = "altdpram",
video_vmem.outdata_aclr = "OFF",
video_vmem.outdata_reg = "OUTCLOCK",
video_vmem.rdaddress_aclr = "OFF",
video_vmem.rdaddress_reg = "INCLOCK",
video_vmem.rdcontrol_aclr = "OFF",
video_vmem.rdcontrol_reg = "UNREGISTERED",
video_vmem.width = 8,
video_vmem.widthad = 10,
video_vmem.wraddress_aclr = "OFF",
video_vmem.wraddress_reg = "INCLOCK",
video_vmem.wrcontrol_aclr = "OFF",
video_vmem.wrcontrol_reg = "INCLOCK";
*/
endmodule