mirror of
https://github.com/MiSTer-devel/ColecoVision_MiSTer.git
synced 2026-05-17 03:03:31 +00:00
Update sys. Support for dynamic HDMI resolution.
This commit is contained in:
@@ -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,
|
||||
|
||||
22
sys/hps_io.v
22
sys/hps_io.v
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
#
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user