mirror of
https://github.com/UzixLS/TSConf_MiST.git
synced 2025-07-19 07:11:22 +03:00
244 lines
7.1 KiB
Verilog
244 lines
7.1 KiB
Verilog
`include "tune.v"
|
|
|
|
// This module generates video raster signals
|
|
|
|
module video_sync
|
|
(
|
|
// clocks
|
|
input wire clk, f1, c0, c3, pix_stb,
|
|
|
|
// video parameters
|
|
input wire [8:0] hpix_beg,
|
|
input wire [8:0] hpix_end,
|
|
input wire [8:0] vpix_beg,
|
|
input wire [8:0] vpix_end,
|
|
input wire [8:0] hpix_beg_ts,
|
|
input wire [8:0] hpix_end_ts,
|
|
input wire [8:0] vpix_beg_ts,
|
|
input wire [8:0] vpix_end_ts,
|
|
input wire [4:0] go_offs,
|
|
input wire [1:0] x_offs,
|
|
input wire [7:0] hint_beg,
|
|
input wire [8:0] vint_beg,
|
|
input wire [7:0] cstart,
|
|
input wire [8:0] rstart,
|
|
|
|
// video syncs
|
|
output reg hsync,
|
|
output reg vsync,
|
|
output reg csync,
|
|
|
|
// video controls
|
|
input wire cfg_60hz,
|
|
input wire vga_on,
|
|
output reg v60hz = 0,
|
|
input wire nogfx,
|
|
output wire v_pf,
|
|
output wire hpix,
|
|
output wire vpix,
|
|
output wire v_ts,
|
|
output wire hvpix,
|
|
output wire hvtspix,
|
|
output wire tv_blank,
|
|
output wire vga_blank,
|
|
output wire vga_line,
|
|
output wire frame_start,
|
|
output wire line_start_s,
|
|
output wire pix_start,
|
|
output wire ts_start,
|
|
output wire frame,
|
|
output wire flash,
|
|
|
|
// video counters
|
|
output wire [9:0] vga_cnt_in,
|
|
output wire [9:0] vga_cnt_out,
|
|
output wire [8:0] ts_raddr,
|
|
output reg [8:0] lcount = 0,
|
|
output reg [7:0] cnt_col = 0,
|
|
output reg [8:0] cnt_row = 0,
|
|
output reg cptr = 0,
|
|
output reg [3:0] scnt = 0,
|
|
`ifdef PENT_312
|
|
output wire [4:0] hcnt,
|
|
output wire upper8,
|
|
`endif
|
|
|
|
// DRAM
|
|
input wire video_pre_next,
|
|
output reg video_go = 0,
|
|
|
|
// ZX controls
|
|
input wire y_offs_wr,
|
|
output wire int_start
|
|
);
|
|
|
|
localparam HSYNC_BEG = 9'd11;
|
|
localparam HSYNC_END = 9'd43;
|
|
localparam HBLNK_BEG = 9'd00;
|
|
localparam HBLNK_END = 9'd88;
|
|
localparam HSYNCV_BEG = 9'd5;
|
|
localparam HSYNCV_END = 9'd31;
|
|
localparam HBLNKV_END = 9'd42;
|
|
localparam HPERIOD = 9'd448;
|
|
|
|
localparam VSYNC_BEG_50 = 9'd08;
|
|
localparam VSYNC_END_50 = 9'd11;
|
|
localparam VBLNK_BEG_50 = 9'd00;
|
|
`ifdef PENT_312
|
|
localparam VBLNK_END_50 = 9'd24;
|
|
localparam VPERIOD_50 = 9'd312;
|
|
`else
|
|
localparam VBLNK_END_50 = 9'd32;
|
|
localparam VPERIOD_50 = 9'd320;
|
|
`endif
|
|
|
|
localparam VSYNC_BEG_60 = 9'd04;
|
|
localparam VSYNC_END_60 = 9'd07;
|
|
localparam VBLNK_BEG_60 = 9'd00;
|
|
localparam VBLNK_END_60 = 9'd22;
|
|
localparam VPERIOD_60 = 9'd262;
|
|
|
|
wire [8:0] vsync_beg = v60hz ? VSYNC_BEG_60 : VSYNC_BEG_50;
|
|
wire [8:0] vsync_end = v60hz ? VSYNC_END_60 : VSYNC_END_50;
|
|
wire [8:0] vblnk_beg = v60hz ? VBLNK_BEG_60 : VBLNK_BEG_50;
|
|
wire [8:0] vblnk_end = v60hz ? VBLNK_END_60 : VBLNK_END_50;
|
|
wire [8:0] vperiod = v60hz ? VPERIOD_60 : VPERIOD_50;
|
|
|
|
`ifdef PENT_312
|
|
assign hcnt = hcount[4:0];
|
|
assign upper8 = vcount < 8;
|
|
`endif
|
|
|
|
reg [8:0] hcount = 0;
|
|
reg [8:0] vcount = 0;
|
|
reg [8:0] cnt_out = 0;
|
|
reg vga_hblank = 0;
|
|
reg vga_vblank = 0;
|
|
|
|
wire line_start = hcount == (HPERIOD - 1);
|
|
wire line_start2 = hcount == (HSYNC_END - 1);
|
|
assign line_start_s = line_start && c3;
|
|
assign frame_start = line_start && (vcount == (vperiod - 1));
|
|
wire vis_start = line_start && (vcount == (vblnk_end - 1));
|
|
assign pix_start = hcount == (hpix_beg - x_offs - 1);
|
|
wire ts_start_coarse = hcount == (hpix_beg_ts - 1);
|
|
assign ts_start = c3 && ts_start_coarse;
|
|
assign int_start = (hcount == {hint_beg, 1'b0}) && (vcount == vint_beg) && c0;
|
|
wire vga_pix_start = ((hcount == (HBLNKV_END)) || (hcount == (HBLNKV_END + HPERIOD/2)));
|
|
wire hs_vga = ((hcount >= HSYNCV_BEG) && (hcount < HSYNCV_END)) || ((hcount >= (HSYNCV_BEG + HPERIOD/2)) && (hcount < (HSYNCV_END + HPERIOD/2)));
|
|
assign vga_line = (hcount >= HPERIOD/2);
|
|
wire hs = (hcount >= HSYNC_BEG) && (hcount < HSYNC_END);
|
|
wire vs = (vcount >= vsync_beg) && (vcount < vsync_end);
|
|
assign vga_cnt_in = {vcount[0], hcount - HBLNK_END};
|
|
assign vga_cnt_out = {~vcount[0], cnt_out};
|
|
wire tv_hblank = (hcount > HBLNK_BEG) && (hcount <= HBLNK_END);
|
|
wire tv_vblank = (vcount >= vblnk_beg) && (vcount < vblnk_end);
|
|
assign vga_blank = vga_hblank || vga_vblank;
|
|
assign tv_blank = tv_hblank || tv_vblank;
|
|
|
|
// horizontal TV (7 MHz)
|
|
always @(posedge clk) if (c3)
|
|
hcount <= line_start ? 9'b0 : hcount + 9'b1;
|
|
|
|
// vertical TV (15.625 kHz)
|
|
always @(posedge clk) if (line_start_s)
|
|
vcount <= (vcount == (vperiod - 1)) ? 9'b0 : vcount + 9'b1;
|
|
|
|
// horizontal VGA (14MHz)
|
|
always @(posedge clk) if (f1)
|
|
cnt_out <= vga_pix_start && c3 ? 9'b0 : cnt_out + 9'b1;
|
|
|
|
// column address for DRAM
|
|
always @(posedge clk)
|
|
begin
|
|
if (line_start2)
|
|
begin
|
|
cnt_col <= cstart;
|
|
cptr <= 1'b0;
|
|
end
|
|
|
|
else if (video_pre_next)
|
|
begin
|
|
cnt_col <= cnt_col + 8'b1;
|
|
cptr <= ~cptr;
|
|
end
|
|
end
|
|
|
|
// row address for DRAM
|
|
reg y_offs_wr_r;
|
|
|
|
always @(posedge clk) if (c3)
|
|
if (vis_start || (line_start && y_offs_wr_r))
|
|
cnt_row <= rstart;
|
|
else
|
|
if (line_start && vpix)
|
|
cnt_row <= cnt_row + 9'b1;
|
|
|
|
// pixel counter
|
|
always @(posedge clk) if (pix_stb) // f1 or c3
|
|
scnt <= pix_start ? 4'b0 : scnt + 4'b1;
|
|
|
|
// TS-line counter
|
|
assign ts_raddr = hcount - hpix_beg_ts;
|
|
|
|
always @(posedge clk)
|
|
if (ts_start_coarse)
|
|
lcount <= vcount - vpix_beg_ts + 9'b1;
|
|
|
|
// Y offset re-latch trigger
|
|
always @(posedge clk)
|
|
if (y_offs_wr)
|
|
y_offs_wr_r <= 1'b1;
|
|
else if (line_start_s)
|
|
y_offs_wr_r <= 1'b0;
|
|
|
|
// FLASH generator
|
|
reg [4:0] flash_ctr;
|
|
assign frame = flash_ctr[0];
|
|
assign flash = flash_ctr[4];
|
|
|
|
always @(posedge clk)
|
|
if (frame_start && c3)
|
|
begin
|
|
flash_ctr <= flash_ctr + 5'b1;
|
|
// re-sync 60Hz mode selector
|
|
`ifdef FORCE_60HZ
|
|
v60hz <= 1'b1;
|
|
`elsif ENABLE_60HZ
|
|
v60hz <= !cfg_60hz;
|
|
`else
|
|
v60hz <= 1'b0;
|
|
`endif
|
|
end
|
|
|
|
// sync strobes
|
|
wire vga_hblank1 = (cnt_out > 9'd359);
|
|
always @(posedge clk) if (f1) // fix me - bydlocode !!!
|
|
vga_hblank <= vga_hblank1;
|
|
|
|
assign hvpix = hpix && vpix;
|
|
assign hpix = (hcount >= hpix_beg) && (hcount < hpix_end);
|
|
assign vpix = (vcount >= vpix_beg) && (vcount < vpix_end);
|
|
|
|
wire htspix = (hcount >= hpix_beg_ts) && (hcount < hpix_end_ts);
|
|
wire vtspix = (vcount >= vpix_beg_ts) && (vcount < vpix_end_ts);
|
|
assign hvtspix = htspix && vtspix;
|
|
|
|
assign v_ts = (vcount >= (vpix_beg_ts - 1)) && (vcount < (vpix_end_ts - 1)); // vertical TS window
|
|
assign v_pf = (vcount >= (vpix_beg_ts - 17)) && (vcount < (vpix_end_ts - 9)); // vertical tilemap prefetch window
|
|
|
|
always @(posedge clk)
|
|
video_go <= (hcount >= (hpix_beg - go_offs - x_offs)) && (hcount < (hpix_end - go_offs - x_offs + 4)) && vpix && !nogfx;
|
|
|
|
always @(posedge clk) if (line_start_s) // fix me - bydlocode !!!
|
|
vga_vblank <= tv_vblank;
|
|
|
|
always @(posedge clk)
|
|
begin
|
|
hsync <= vga_on ? hs_vga : hs;
|
|
vsync <= vs;
|
|
csync <= ~(vs ^ hs);
|
|
end
|
|
|
|
endmodule
|