Support for Direct Video.

This commit is contained in:
sorgelig
2019-08-25 06:08:47 +08:00
parent 4c97a986c2
commit a5da8a3c68
5 changed files with 137 additions and 81 deletions

View File

@@ -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,

View File

@@ -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;

View File

@@ -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[*]}]

View File

@@ -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;

View File

@@ -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;