mirror of
https://github.com/MiSTer-devel/ZX-Spectrum_MISTer.git
synced 2026-05-17 03:04:59 +00:00
Support for Direct Video.
This commit is contained in:
@@ -2,12 +2,14 @@
|
||||
module hdmi_config
|
||||
(
|
||||
// Host Side
|
||||
input iCLK,
|
||||
input iRST_N,
|
||||
input iCLK,
|
||||
input iRST_N,
|
||||
|
||||
input dvi_mode,
|
||||
input audio_96k,
|
||||
input hdmi_limited,
|
||||
input limited,
|
||||
input ypbpr,
|
||||
|
||||
output reg done,
|
||||
|
||||
// I2C Side
|
||||
@@ -105,34 +107,32 @@ wire [15:0] init_data[82] =
|
||||
|
||||
{8'h17, 8'b01100010}, // Aspect ratio 16:9 [1]=1, 4:3 [1]=0
|
||||
|
||||
{8'h18, hdmi_limited, // CSC enable [7]. 0 - Off. 1 - On.
|
||||
7'h0D}, // CSC Scaling Factors and Coefficients for RGB Full->Limited.
|
||||
{8'h19, 8'hBC}, // Taken from table in ADV7513 Programming Guide.
|
||||
{8'h1A, 8'h00}, // CSC Channel A.
|
||||
{8'h1B, 8'h00},
|
||||
{8'h1C, 8'h00},
|
||||
{8'h1D, 8'h00},
|
||||
{8'h1E, 8'h01},
|
||||
{8'h18, ypbpr ? 8'h88 : limited ? 8'h8D : 8'h00}, // CSC Scaling Factors and Coefficients for RGB Full->Limited.
|
||||
{8'h19, ypbpr ? 8'h2E : 8'hBC}, // Taken from table in ADV7513 Programming Guide.
|
||||
{8'h1A, ypbpr ? 8'h18 : 8'h00}, // CSC Channel A.
|
||||
{8'h1B, ypbpr ? 8'h93 : 8'h00},
|
||||
{8'h1C, ypbpr ? 8'h1F : 8'h00},
|
||||
{8'h1D, ypbpr ? 8'h3F : 8'h00},
|
||||
{8'h1E, ypbpr ? 8'h08 : 8'h01},
|
||||
{8'h1F, 8'h00},
|
||||
|
||||
{8'h20, 8'h00}, // CSC Channel B.
|
||||
{8'h21, 8'h00},
|
||||
{8'h22, 8'h0D},
|
||||
{8'h23, 8'hBC},
|
||||
{8'h24, 8'h00},
|
||||
{8'h25, 8'h00},
|
||||
{8'h26, 8'h01},
|
||||
|
||||
{8'h20, ypbpr ? 8'h03 : 8'h00}, // CSC Channel B.
|
||||
{8'h21, ypbpr ? 8'h67 : 8'h00},
|
||||
{8'h22, ypbpr ? 8'h0B : 8'h0D},
|
||||
{8'h23, ypbpr ? 8'h71 : 8'hBC},
|
||||
{8'h24, ypbpr ? 8'h01 : 8'h00},
|
||||
{8'h25, ypbpr ? 8'h28 : 8'h00},
|
||||
{8'h26, ypbpr ? 8'h00 : 8'h01},
|
||||
{8'h27, 8'h00},
|
||||
|
||||
{8'h28, 8'h00}, // CSC Channel C.
|
||||
{8'h29, 8'h00},
|
||||
{8'h2A, 8'h00},
|
||||
{8'h2B, 8'h00},
|
||||
{8'h2C, 8'h0D},
|
||||
{8'h2D, 8'hBC},
|
||||
{8'h2E, 8'h01},
|
||||
|
||||
{8'h28, ypbpr ? 8'h1E : 8'h00}, // CSC Channel C.
|
||||
{8'h29, ypbpr ? 8'h21 : 8'h00},
|
||||
{8'h2A, ypbpr ? 8'h19 : 8'h00},
|
||||
{8'h2B, ypbpr ? 8'hB2 : 8'h00},
|
||||
{8'h2C, ypbpr ? 8'h08 : 8'h0D},
|
||||
{8'h2D, ypbpr ? 8'h2D : 8'hBC},
|
||||
{8'h2E, ypbpr ? 8'h08 : 8'h01},
|
||||
{8'h2F, 8'h00},
|
||||
|
||||
|
||||
{8'h3B, 8'b0000_0000}, // Pixel repetition [6:5] b00 AUTO. [4:3] b00 x1 mult of input clock. [2:1] b00 x1 pixel rep to send to HDMI Rx.
|
||||
|
||||
@@ -152,7 +152,7 @@ wire [15:0] init_data[82] =
|
||||
|
||||
{8'h57, 1'b0, // [7] IT Content. 0 - No. 1 - Yes (type set in register h59).
|
||||
3'b000, // [6:4] Color space (ignored for RGB)
|
||||
hdmi_limited ? 2'b01 : 2'b10, // [3:2] RGB Quantization range
|
||||
(ypbpr | limited) ? 2'b01 : 2'b10, // [3:2] RGB Quantization range
|
||||
2'b00}, // [1:0] Non-Uniform Scaled: 00 - None. 01 - Horiz. 10 - Vert. 11 - Both.
|
||||
|
||||
16'h7301,
|
||||
|
||||
@@ -83,12 +83,13 @@ module hps_io #(parameter STRLEN=0, PS2DIV=0, WIDE=0, VDNUM=1, PS2WE=0)
|
||||
output reg [DW:0] sd_buff_dout,
|
||||
input [DW:0] sd_buff_din,
|
||||
output reg sd_buff_wr,
|
||||
input [15:0] sd_req_type,
|
||||
|
||||
// ARM -> FPGA download
|
||||
output reg ioctl_download = 0, // signal indicating an active download
|
||||
output reg [7:0] ioctl_index, // menu index used to upload the file
|
||||
output reg ioctl_wr,
|
||||
output reg [24:0] ioctl_addr, // in WIDE mode address will be incremented by 2
|
||||
output reg [26:0] ioctl_addr, // in WIDE mode address will be incremented by 2
|
||||
output reg [DW:0] ioctl_dout,
|
||||
output reg [31:0] ioctl_file_ext,
|
||||
input ioctl_wait,
|
||||
@@ -199,7 +200,7 @@ always @(posedge clk_vid) begin
|
||||
|
||||
if(old_vs & ~vs) begin
|
||||
vid_int <= {vid_int[0],f1};
|
||||
if(~f1) begin
|
||||
if(~f1) begin
|
||||
if(hcnt && vcnt) begin
|
||||
old_vmode <= new_vmode;
|
||||
|
||||
@@ -390,6 +391,7 @@ always@(posedge clk_sys) begin
|
||||
1: io_dout <= sd_cmd;
|
||||
2: io_dout <= sd_lba[15:0];
|
||||
3: io_dout <= sd_lba[31:16];
|
||||
4: io_dout <= sd_req_type;
|
||||
endcase
|
||||
|
||||
// send SD config IO -> FPGA
|
||||
@@ -571,7 +573,7 @@ always@(posedge clk_sys) begin
|
||||
reg [15:0] cmd;
|
||||
reg [2:0] cnt;
|
||||
reg has_cmd;
|
||||
reg [24:0] addr;
|
||||
reg [26:0] addr;
|
||||
reg wr;
|
||||
|
||||
ioctl_wr <= wr;
|
||||
|
||||
@@ -3,7 +3,7 @@ create_clock -period "50.0 MHz" [get_ports FPGA_CLK1_50]
|
||||
create_clock -period "50.0 MHz" [get_ports FPGA_CLK2_50]
|
||||
create_clock -period "50.0 MHz" [get_ports FPGA_CLK3_50]
|
||||
create_clock -period "100.0 MHz" [get_pins -compatibility_mode *|h2f_user0_clk]
|
||||
create_clock -period 10.0 [get_pins -compatibility_mode spi|sclk_out] -name spi_sck
|
||||
create_clock -period 10.0ns [get_pins -compatibility_mode spi|sclk_out] -name spi_sck
|
||||
|
||||
derive_pll_clocks
|
||||
|
||||
@@ -20,8 +20,8 @@ set_clock_groups -asynchronous \
|
||||
-group [get_clocks { *|h2f_user0_clk}] \
|
||||
-group [get_clocks { FPGA_CLK1_50 FPGA_CLK2_50 FPGA_CLK3_50}]
|
||||
|
||||
set_output_delay -max -clock HDMI_CLK 2.0ns [get_ports {HDMI_TX_D[*] HDMI_TX_DE HDMI_TX_HS HDMI_TX_VS}]
|
||||
set_output_delay -min -clock HDMI_CLK -1.5ns [get_ports {HDMI_TX_D[*] HDMI_TX_DE HDMI_TX_HS HDMI_TX_VS}]
|
||||
set_output_delay -max -clock HDMI_CLK 3.0ns [get_ports {HDMI_TX_D[*] HDMI_TX_DE HDMI_TX_HS HDMI_TX_VS}]
|
||||
set_output_delay -min -clock HDMI_CLK 2.0ns [get_ports {HDMI_TX_D[*] HDMI_TX_DE HDMI_TX_HS HDMI_TX_VS}]
|
||||
|
||||
set_false_path -from {*} -to [get_registers {wcalc[*] hcalc[*]}]
|
||||
|
||||
@@ -36,3 +36,4 @@ set_false_path -from * -to [get_ports {VGA_*}]
|
||||
set_false_path -from * -to [get_ports {AUDIO_SPDIF}]
|
||||
set_false_path -from * -to [get_ports {AUDIO_L}]
|
||||
set_false_path -from * -to [get_ports {AUDIO_R}]
|
||||
set_false_path -from * -to [get_keepers {cfg[*]}]
|
||||
|
||||
138
sys/sys_top.v
138
sys/sys_top.v
@@ -257,12 +257,13 @@ reg cfg_set = 0;
|
||||
wire hdmi_limited = cfg[8];
|
||||
wire dvi_mode = cfg[7];
|
||||
wire audio_96k = cfg[6];
|
||||
wire direct_video = cfg[10];
|
||||
wire csync = cfg[3];
|
||||
wire ypbpr_en = cfg[5];
|
||||
wire io_osd_vga= io_ss1 & ~io_ss2;
|
||||
`ifndef DUAL_SDRAM
|
||||
wire sog = cfg[9];
|
||||
wire ypbpr_en = cfg[5];
|
||||
wire csync = cfg[3];
|
||||
wire vga_scaler= cfg[2];
|
||||
wire io_osd_vga= io_ss1 & ~io_ss2;
|
||||
`endif
|
||||
|
||||
reg cfg_custom_t = 0;
|
||||
@@ -431,7 +432,7 @@ always @(posedge FPGA_CLK2_50) begin
|
||||
end
|
||||
|
||||
wire clk_100m;
|
||||
wire clk_hdmi = ~HDMI_TX_CLK; // Internal HDMI clock, inverted in relation to external clock
|
||||
wire clk_hdmi = hdmi_tx_clk;
|
||||
wire clk_audio = FPGA_CLK3_50;
|
||||
wire clk_pal = FPGA_CLK3_50;
|
||||
|
||||
@@ -496,6 +497,7 @@ wire [127:0] vbuf_writedata;
|
||||
wire [15:0] vbuf_byteenable;
|
||||
wire vbuf_write;
|
||||
|
||||
wire hdmi_vs, hdmi_hs;
|
||||
ascal
|
||||
#(
|
||||
.RAMBASE(32'h20000000),
|
||||
@@ -528,8 +530,8 @@ ascal
|
||||
.o_r (hdmi_data[23:16]),
|
||||
.o_g (hdmi_data[15:8]),
|
||||
.o_b (hdmi_data[7:0]),
|
||||
.o_hs (HDMI_TX_HS),
|
||||
.o_vs (HDMI_TX_VS),
|
||||
.o_hs (hdmi_hs),
|
||||
.o_vs (hdmi_vs),
|
||||
.o_de (hdmi_de),
|
||||
.o_lltune (lltune),
|
||||
.htotal (WIDTH + HFP + HBP + HS),
|
||||
@@ -687,13 +689,14 @@ fbpal fbpal
|
||||
|
||||
///////////////////////// HDMI output /////////////////////////////////
|
||||
|
||||
wire hdmi_tx_clk;
|
||||
pll_hdmi pll_hdmi
|
||||
(
|
||||
.refclk(FPGA_CLK1_50),
|
||||
.rst(reset_req),
|
||||
.reconfig_to_pll(reconfig_to_pll),
|
||||
.reconfig_from_pll(reconfig_from_pll),
|
||||
.outclk_0(HDMI_TX_CLK)
|
||||
.outclk_0(hdmi_tx_clk)
|
||||
);
|
||||
|
||||
//1920x1080@60 PCLK=148.5MHz CEA
|
||||
@@ -772,7 +775,8 @@ hdmi_config hdmi_config
|
||||
|
||||
.dvi_mode(dvi_mode),
|
||||
.audio_96k(audio_96k),
|
||||
.hdmi_limited(hdmi_limited)
|
||||
.limited(hdmi_limited),
|
||||
.ypbpr(ypbpr_en & direct_video)
|
||||
);
|
||||
|
||||
wire [23:0] hdmi_data;
|
||||
@@ -790,6 +794,8 @@ scanlines #(1) HDMI_scanlines
|
||||
.vs(HDMI_TX_VS)
|
||||
);
|
||||
|
||||
wire [23:0] hdmi_tx_d;
|
||||
wire hdmi_tx_de;
|
||||
osd hdmi_osd
|
||||
(
|
||||
.clk_sys(clk_sys),
|
||||
@@ -800,56 +806,102 @@ osd hdmi_osd
|
||||
|
||||
.clk_video(clk_hdmi),
|
||||
.din(hdmi_data_sl),
|
||||
.dout(HDMI_TX_D),
|
||||
.dout(hdmi_tx_d),
|
||||
.de_in(hdmi_de),
|
||||
.de_out(HDMI_TX_DE),
|
||||
.de_out(hdmi_tx_de),
|
||||
|
||||
.osd_status(osd_status)
|
||||
);
|
||||
|
||||
reg [23:0] dv_d;
|
||||
reg dv_hs, dv_vs, dv_de;
|
||||
always @(negedge clk_vid) begin
|
||||
reg [23:0] dv_d1, dv_d2;
|
||||
reg dv_de1, dv_de2, dv_hs1, dv_hs2, dv_vs1, dv_vs2;
|
||||
reg [12:0] vsz, vcnt;
|
||||
reg old_hs, old_vs;
|
||||
reg vde;
|
||||
reg [3:0] hss;
|
||||
|
||||
if(ce_pix) begin
|
||||
hss <= (hss << 1) | hs;
|
||||
|
||||
old_hs <= hs;
|
||||
if(~old_hs && hs) begin
|
||||
old_vs <= vs;
|
||||
if(~&vcnt) vcnt <= vcnt + 1'd1;
|
||||
if(~old_vs & vs & ~f1) vsz <= vcnt;
|
||||
if(old_vs & ~vs) vcnt <= 0;
|
||||
|
||||
if(vcnt == 1) vde <= 1;
|
||||
if(vcnt == vsz - 3) vde <= 0;
|
||||
end
|
||||
|
||||
dv_de1 <= !{hss,hs} && vde;
|
||||
dv_hs1 <= csync ? (vs ^ hs) : hs;
|
||||
dv_vs1 <= vs;
|
||||
end
|
||||
|
||||
dv_d1 <= vga_q;
|
||||
dv_d2 <= dv_d1;
|
||||
dv_de2 <= dv_de1;
|
||||
dv_hs2 <= dv_hs1;
|
||||
dv_vs2 <= dv_vs1;
|
||||
|
||||
dv_d <= dv_d2;
|
||||
dv_de <= dv_de2;
|
||||
dv_hs <= dv_hs2;
|
||||
dv_vs <= dv_vs2;
|
||||
end
|
||||
|
||||
assign HDMI_TX_CLK = direct_video ? clk_vid : hdmi_tx_clk;
|
||||
assign HDMI_TX_HS = direct_video ? dv_hs : hdmi_hs ;
|
||||
assign HDMI_TX_VS = direct_video ? dv_vs : hdmi_vs ;
|
||||
assign HDMI_TX_D = direct_video ? dv_d : hdmi_tx_d ;
|
||||
assign HDMI_TX_DE = direct_video ? dv_de : hdmi_tx_de ;
|
||||
|
||||
///////////////////////// VGA output //////////////////////////////////
|
||||
|
||||
wire [23:0] vga_data_sl;
|
||||
|
||||
scanlines #(0) VGA_scanlines
|
||||
(
|
||||
.clk(clk_vid),
|
||||
|
||||
.scanlines(scanlines),
|
||||
.din(de ? {r_out, g_out, b_out} : 24'd0),
|
||||
.dout(vga_data_sl),
|
||||
.hs(hs),
|
||||
.vs(vs)
|
||||
);
|
||||
|
||||
wire [23:0] vga_q;
|
||||
osd vga_osd
|
||||
(
|
||||
.clk_sys(clk_sys),
|
||||
|
||||
.io_osd(io_osd_vga),
|
||||
.io_strobe(io_strobe),
|
||||
.io_din(io_din),
|
||||
|
||||
.clk_video(clk_vid),
|
||||
.din(vga_data_sl),
|
||||
.dout(vga_q),
|
||||
.de_in(de)
|
||||
);
|
||||
|
||||
`ifndef DUAL_SDRAM
|
||||
wire [23:0] vga_data_sl;
|
||||
|
||||
scanlines #(0) VGA_scanlines
|
||||
(
|
||||
.clk(clk_vid),
|
||||
|
||||
.scanlines(scanlines),
|
||||
.din(de ? {r_out, g_out, b_out} : 24'd0),
|
||||
.dout(vga_data_sl),
|
||||
.hs(hs1),
|
||||
.vs(vs1)
|
||||
);
|
||||
|
||||
osd vga_osd
|
||||
(
|
||||
.clk_sys(clk_sys),
|
||||
|
||||
.io_osd(io_osd_vga),
|
||||
.io_strobe(io_strobe),
|
||||
.io_din(io_din),
|
||||
|
||||
.clk_video(clk_vid),
|
||||
.din(vga_data_sl),
|
||||
.dout(vga_q),
|
||||
.de_in(de)
|
||||
);
|
||||
|
||||
wire [23:0] vga_q;
|
||||
wire [23:0] vga_o;
|
||||
|
||||
vga_out vga_out
|
||||
(
|
||||
.ypbpr_full(1),
|
||||
.ypbpr_full(0),
|
||||
.ypbpr_en(ypbpr_en),
|
||||
.dout(vga_o),
|
||||
.din(vga_scaler ? {24{HDMI_TX_DE}} & HDMI_TX_D : vga_q)
|
||||
.din(vga_scaler ? {24{hdmi_tx_de}} & hdmi_tx_d : vga_q)
|
||||
);
|
||||
|
||||
wire vs1 = vga_scaler ? HDMI_TX_VS : vs;
|
||||
wire hs1 = vga_scaler ? HDMI_TX_HS : hs;
|
||||
wire vs1 = vga_scaler ? hdmi_vs : vs;
|
||||
wire hs1 = vga_scaler ? hdmi_hs : hs;
|
||||
|
||||
assign VGA_VS = (VGA_EN | SW[3]) ? 1'bZ : csync ? 1'b1 : ~vs1;
|
||||
assign VGA_HS = (VGA_EN | SW[3]) ? 1'bZ : csync ? ~(vs1 ^ hs1) : ~hs1;
|
||||
|
||||
7
video.sv
7
video.sv
@@ -111,17 +111,17 @@ always @(posedge clk_sys) begin
|
||||
sync <= 0;
|
||||
if(!mZX) begin
|
||||
if(hc == 312) HBlank <= 1;
|
||||
if(hc == 338) {HSync,sync} <= 3;
|
||||
if(hc == 338) sync <= 1;
|
||||
if(hc == 370) HSync <= 0;
|
||||
if(hc == 420) HBlank <= 0;
|
||||
end else if(m128) begin
|
||||
if(hc == 312) HBlank <= 1;
|
||||
if(hc == 340) {HSync,sync} <= 3; //ULA 6C
|
||||
if(hc == 340) sync <= 1; //ULA 6C
|
||||
if(hc == 372) HSync <= 0; //ULA 6C
|
||||
if(hc == 424) HBlank <= 0;
|
||||
end else begin
|
||||
if(hc == 300) HBlank <= 1;
|
||||
if(hc == 336) {HSync,sync} <= 3; //ULA 5C
|
||||
if(hc == 336) sync <= 1; //ULA 5C
|
||||
if(hc == 368) HSync <= 0; //ULA 5C
|
||||
if(hc == 428) HBlank <= 0;
|
||||
end
|
||||
@@ -129,6 +129,7 @@ always @(posedge clk_sys) begin
|
||||
if(wide) HBlank <= !(hc < 312 || hc >= ((mZX && m128) ? 455-33 : 447-33));
|
||||
|
||||
if(sync) begin
|
||||
HSync <= 1;
|
||||
if(mZX) begin
|
||||
if(vc == 236) VBlank <= 1;
|
||||
if(vc == 240) VSync <= 1;
|
||||
|
||||
Reference in New Issue
Block a user