Update sys. Support for dynamic HDMI resolution.

This commit is contained in:
sorgelig
2018-02-21 22:39:41 +08:00
parent 1a7e4bda0b
commit b1ac401404
8 changed files with 135 additions and 146 deletions

View File

@@ -29,7 +29,7 @@ module emu
input RESET,
//Must be passed to hps_io module
inout [43:0] HPS_BUS,
inout [44:0] HPS_BUS,
//Base video clock. Usually equals to CLK_SYS.
output CLK_VIDEO,

View File

@@ -33,7 +33,7 @@
module hps_io #(parameter STRLEN=0, PS2DIV=2000, WIDE=0, VDNUM=1, PS2WE=0)
(
input clk_sys,
inout [43:0] HPS_BUS,
inout [44:0] HPS_BUS,
// parameter STRLEN and the actual length of conf_str have to match
input [(8*STRLEN)-1:0] conf_str,
@@ -155,6 +155,7 @@ wire ce_pix = HPS_BUS[41];
wire de = HPS_BUS[40];
wire hs = HPS_BUS[39];
wire vs = HPS_BUS[38];
wire vs_hdmi = HPS_BUS[44];
reg [31:0] vid_hcnt = 0;
reg [31:0] vid_vcnt = 0;
@@ -226,6 +227,23 @@ always @(posedge clk_100) begin
if(old_de2 & ~old_de) calch <= 0;
end
reg [31:0] vid_vtime_hdmi;
always @(posedge clk_100) begin
integer vtime;
reg old_vs, old_vs2;
old_vs <= vs_hdmi;
old_vs2 <= old_vs;
vtime <= vtime + 1'd1;
if(~old_vs2 & old_vs) begin
vid_vtime_hdmi <= vtime;
vtime <= 0;
end
end
/////////////////////////////////////////////////////////
reg [31:0] ps2_key_raw = 0;
@@ -397,6 +415,8 @@ always@(posedge clk_sys) begin
9: io_dout <= vid_vtime[31:16];
10: io_dout <= vid_pix[15:0];
11: io_dout <= vid_pix[31:16];
12: io_dout <= vid_vtime_hdmi[15:0];
13: io_dout <= vid_vtime_hdmi[31:16];
endcase
end

View File

@@ -1,32 +1,34 @@
// reset_source.v
// This file was auto-generated as a prototype implementation of a module
// created in component editor. It ties off all outputs to ground and
// ignores all inputs. It needs to be edited to make it do something
// useful.
//
// This file will not be automatically regenerated. You should check it in
// This file was auto-generated as a prototype implementation of a module
// created in component editor. It ties off all outputs to ground and
// ignores all inputs. It needs to be edited to make it do something
// useful.
//
// This file will not be automatically regenerated. You should check it in
// to your version control system if you want to keep it.
`timescale 1 ps / 1 ps
`timescale 1 ps / 1 ps
module reset_source
(
input wire clk, // clock.clk
input wire reset_hps, // reset_hps.reset
output wire reset_sys, // reset_sys.reset
output wire reset_cold, // reset_cold.reset
input wire cold_req, // reset_ctl.cold_req
output wire reset, // .reset
input wire reset_req, // .reset_req
input wire warm_req, // .warm_req
output wire reset_warm // reset_warm.reset
input wire clk, // clock.clk
input wire reset_hps, // reset_hps.reset
output wire reset_sys, // reset_sys.reset
output wire reset_cold, // reset_cold.reset
input wire cold_req, // reset_ctl.cold_req
output wire reset, // .reset
input wire reset_req, // .reset_req
input wire reset_vip, // .reset_vip
input wire warm_req, // .warm_req
output wire reset_warm // reset_warm.reset
);
assign reset_cold = cold_req;
assign reset_warm = warm_req;
assign reset = reset_sys;
assign reset_sys = sys_reset | reset_hps | reset_req;
wire reset_m = sys_reset | reset_hps | reset_req;
assign reset = reset_m;
assign reset_sys = reset_m | reset_vip;
reg sys_reset = 1;
always @(posedge clk) begin

View File

@@ -1,11 +1,11 @@
# TCL File Generated by Component Editor 17.0
# Wed Dec 13 01:40:19 CST 2017
# Tue Feb 20 07:55:55 CST 2018
# DO NOT MODIFY
#
# reset_source "reset_source" v17.0
# Sorgelig 2017.12.13.01:40:19
# Sorgelig 2018.02.20.07:55:55
#
#
@@ -114,6 +114,7 @@ add_interface_port reset_ctl cold_req cold_req Input 1
add_interface_port reset_ctl reset reset Output 1
add_interface_port reset_ctl reset_req reset_req Input 1
add_interface_port reset_ctl warm_req warm_req Input 1
add_interface_port reset_ctl reset_vip reset_vip Input 1
#

View File

@@ -30,7 +30,7 @@ module sys_top
output [5:0] VGA_R,
output [5:0] VGA_G,
output [5:0] VGA_B,
inout VGA_HS, // VGA_HS is secondary SD card detect when VGA_EN = 1 (inactive)
inout VGA_HS, // VGA_HS is secondary SD card detect when VGA_EN = 1 (inactive)
output VGA_VS,
input VGA_EN, // active low
@@ -227,6 +227,7 @@ always@(posedge clk_sys) begin
cfg_got <= 1;
end
if(cmd == 'h20) begin
cfg_got <= 0;
cnt <= cnt + 1'd1;
if(cnt<8) begin
case(cnt)
@@ -239,7 +240,7 @@ always@(posedge clk_sys) begin
6: VS <= io_din[11:0];
7: VBP <= io_din[11:0];
endcase
if(!cnt) begin
if(cnt == 1) begin
cfg_custom_p1 <= 0;
cfg_custom_p2 <= 0;
cfg_custom_t <= ~cfg_custom_t;
@@ -257,6 +258,7 @@ always@(posedge clk_sys) begin
end
if(cmd == 'h25) {led_overtake, led_state} <= io_din;
if(cmd == 'h26) vol_att <= io_din[4:0];
if(cmd == 'h27) VSET <= io_din[11:0];
end
end
end
@@ -295,6 +297,7 @@ vip vip
//Reset/Clock
.reset_reset_req(reset_req | ~cfg_ready),
.reset_reset(reset),
.reset_reset_vip(0),
//DE10-nano has no reset signal on GPIO, so core has to emulate cold reset button.
.reset_cold_req(~btn_reset),
@@ -365,6 +368,7 @@ vip_config vip_config
.ARX(ARX),
.ARY(ARY),
.CFG_SET(cfg_got),
.WIDTH(WIDTH),
.HFP(HFP),
@@ -374,6 +378,7 @@ vip_config vip_config
.VFP(VFP),
.VBP(VBP),
.VS(VS),
.VSET(VSET),
.address(ctl_address),
.write(ctl_write),
@@ -564,15 +569,16 @@ pll_hdmi pll_hdmi
.outclk_0(HDMI_TX_CLK)
);
//1280x720@60 PCLK=74.25MHz CEA
reg [11:0] WIDTH = 1280;
reg [11:0] HFP = 110;
reg [11:0] HS = 40;
reg [11:0] HBP = 220;
reg [11:0] HEIGHT = 720;
reg [11:0] VFP = 5;
//1920x1080@60 PCLK=148.5MHz CEA
reg [11:0] WIDTH = 1920;
reg [11:0] HFP = 88;
reg [11:0] HS = 48;
reg [11:0] HBP = 148;
reg [11:0] HEIGHT = 1080;
reg [11:0] VFP = 4;
reg [11:0] VS = 5;
reg [11:0] VBP = 20;
reg [11:0] VBP = 36;
reg [11:0] VSET = 0;
wire [63:0] reconfig_to_pll;
wire [63:0] reconfig_from_pll;
@@ -623,7 +629,6 @@ always @(posedge FPGA_CLK1_50) begin
old_wait <= cfg_waitrequest;
if(old_wait & ~cfg_waitrequest & gotd) cfg_ready <= 1;
if(~gotd) cfg_ready <= 0;
end
hdmi_config hdmi_config
@@ -833,7 +838,7 @@ emu emu
(
.CLK_50M(FPGA_CLK3_50),
.RESET(reset),
.HPS_BUS({clk_ctl, clk_vid, ce_pix, de, hs, vs, io_wait, clk_sys, io_fpga, io_uio, io_strobe, io_wide, io_din, io_dout}),
.HPS_BUS({HDMI_TX_VS, clk_ctl, clk_vid, ce_pix, de, hs, vs, io_wait, clk_sys, io_fpga, io_uio, io_strobe, io_wide, io_din, io_dout}),
.CLK_VIDEO(clk_vid),
.CE_PIXEL(ce_pix),

View File

@@ -92,6 +92,7 @@ reset_source reset_source (
.cold_req (reset_cold_req), // reset_ctl.cold_req
.reset (reset_reset), // .reset
.reset_req (reset_reset_req), // .reset_req
.reset_vip (0), // .reset_vip
.warm_req (reset_warm_req), // .warm_req
.reset_warm (reset_source_reset_warm_reset), // reset_warm.reset
.reset_cold (reset_source_reset_cold_reset) // reset_cold.reset

View File

@@ -983,7 +983,7 @@
<parameter name="H_FRONT_PORCH" value="88" />
<parameter name="H_SYNC_LENGTH" value="44" />
<parameter name="INTERLACED" value="0" />
<parameter name="LOW_LATENCY" value="0" />
<parameter name="LOW_LATENCY" value="1" />
<parameter name="NO_OF_CHANNELS" value="1" />
<parameter name="NO_OF_MODES" value="1" />
<parameter name="NUMBER_OF_COLOUR_PLANES" value="3" />

View File

@@ -6,6 +6,7 @@ module vip_config
input [7:0] ARX,
input [7:0] ARY,
input CFG_SET,
input [11:0] WIDTH,
input [11:0] HFP,
@@ -15,6 +16,8 @@ module vip_config
input [11:0] VFP,
input [11:0] VBP,
input [11:0] VS,
input [11:0] VSET,
output reg [8:0] address,
output reg write,
@@ -25,139 +28,96 @@ module vip_config
reg [31:0] wcalc;
reg [31:0] hcalc;
wire [31:0] videow = (wcalc > WIDTH) ? WIDTH : wcalc;
wire [31:0] videoh = (hcalc > HEIGHT) ? HEIGHT : hcalc;
wire [31:0] videow = (!VSET && (wcalc > WIDTH)) ? WIDTH : wcalc;
wire [31:0] videoh = VSET ? VSET : (hcalc > HEIGHT) ? HEIGHT : hcalc;
wire [31:0] posx = (WIDTH - videow)>>1;
wire [31:0] posy = (HEIGHT- videoh)>>1;
reg newres = 1;
wire [21:0] init[23] =
'{
//video mode
{newres, 2'd2, 7'd04, 12'd0 }, //Bank
{newres, 2'd2, 7'd30, 12'd0 }, //Valid
{newres, 2'd2, 7'd05, 12'd0 }, //Progressive/Interlaced
{newres, 2'd2, 7'd06, WIDTH }, //Active pixel count
{newres, 2'd2, 7'd07, HEIGHT }, //Active line count
{newres, 2'd2, 7'd09, HFP }, //Horizontal Front Porch
{newres, 2'd2, 7'd10, HS }, //Horizontal Sync Length
{newres, 2'd2, 7'd11, HFP+HBP+HS }, //Horizontal Blanking (HFP+HBP+HSync)
{newres, 2'd2, 7'd12, VFP }, //Vertical Front Porch
{newres, 2'd2, 7'd13, VS }, //Vertical Sync Length
{newres, 2'd2, 7'd14, VFP+VBP+VS }, //Vertical blanking (VFP+VBP+VSync)
{newres, 2'd2, 7'd30, 12'd1 }, //Valid
{newres, 2'd2, 7'd00, 12'd1 }, //Go
//mixer
{ 1'd1, 2'd1, 7'd03, WIDTH }, //Bkg Width
{ 1'd1, 2'd1, 7'd04, HEIGHT }, //Bkg Height
{ 1'd1, 2'd1, 7'd08, posx[11:0] }, //Pos X
{ 1'd1, 2'd1, 7'd09, posy[11:0] }, //Pos Y
{ 1'd1, 2'd1, 7'd10, 12'd1 }, //Enable Video 0
{ 1'd1, 2'd1, 7'd00, 12'd1 }, //Go
//scaler
{ 1'd1, 2'd0, 7'd03, videow[11:0] }, //Output Width
{ 1'd1, 2'd0, 7'd04, videoh[11:0] }, //Output Height
{ 1'd1, 2'd0, 7'd00, 12'd1 }, //Go
22'h3FFFFF
};
always @(posedge clk) begin
reg [7:0] state = 0;
reg [7:0] arx, ary;
reg [7:0] arxd, aryd;
integer timeout = 0;
reg [7:0] state = 0;
reg [7:0] arx, ary;
reg [7:0] arxd, aryd;
reg [11:0] vset, vsetd;
reg cfg, cfgd;
integer timeout = 0;
arxd <= ARX;
aryd <= ARY;
arxd <= ARX;
aryd <= ARY;
vsetd <= VSET;
cfg <= CFG_SET;
cfgd <= cfg;
write <= 0;
if(reset || (!state && ((arx != arxd) || (ary != aryd)))) begin
if(reset || (arx != arxd) || (ary != aryd) || (vset != vsetd) || (~cfgd && cfg)) begin
arx <= arxd;
ary <= aryd;
vset <= vsetd;
timeout <= 10000;
state <= 0;
if(reset || (~cfgd && cfg)) newres <= 1;
end
else
if(timeout > 0)
begin
timeout <= timeout - 1;
if(timeout == 1) begin
state <= 1;
wcalc <= (HEIGHT*arx)/ary;
hcalc <= (WIDTH*ary)/arx;
end
state <= 1;
end
else
if(~waitrequest && state)
begin
if(state == 1) begin
wcalc <= VSET ? (VSET*arx)/ary : (HEIGHT*arx)/ary;
hcalc <= (WIDTH*ary)/arx;
end
state <= state + 1'd1;
write <= 1;
if(state&3) write <= 0;
else
case(state>>2)
//scaler
30: begin
address <= 'h003; //Output Width
writedata <= videow;
end
31: begin
address <= 'h004; //Output Height
writedata <= videoh;
end
32: begin
address <= 'h000; //Go
writedata <= 1;
end
//mixer
20: begin
address <= 'h083; //Bkg Width
writedata <= WIDTH;
end
21: begin
address <= 'h084; //Bkg Height
writedata <= HEIGHT;
end
22: begin
address <= 'h088; //Pos X
writedata <= posx;
end
23: begin
address <= 'h089; //Pos Y
writedata <= posy;
end
24: begin
address <= 'h08A; //Enable Video 0
writedata <= 1;
end
25: begin
address <= 'h080; //Go
writedata <= 1;
end
//video mode
01: begin
address <= 'h104; //Bank
writedata <= 0;
end
02: begin
address <= 'h105; //Progressive/Interlaced
writedata <= 0;
end
03: begin
address <= 'h106; //Active pixel count
writedata <= WIDTH;
end
04: begin
address <= 'h107; //Active line count
writedata <= HEIGHT;
end
05: begin
address <= 'h109; //Horizontal Front Porch
writedata <= HFP;
end
06: begin
address <= 'h10A; //Horizontal Sync Length
writedata <= HS;
end
07: begin
address <= 'h10B; //Horizontal Blanking (HFP+HBP+HSync)
writedata <= HFP+HBP+HS;
end
08: begin
address <= 'h10C; //Vertical Front Porch
writedata <= VFP;
end
09: begin
address <= 'h10D; //Vertical Sync Length
writedata <= VS;
end
10: begin
address <= 'h10E; //Vertical blanking (VFP+VBP+VSync)
writedata <= VFP+VBP+VS;
end
11: begin
address <= 'h11E; //Valid
writedata <= 1;
end
12: begin
address <= 'h100; //Go
writedata <= 1;
end
default: write <= 0;
endcase
write <= 0;
if((state&3)==3) begin
if(init[state>>2] == 22'h3FFFFF) begin
state <= 0;
newres <= 0;
end
else begin
writedata <= 0;
{write, address, writedata[11:0]} <= init[state>>2];
end
end
end
end