diff --git a/ColecoVision.sv b/ColecoVision.sv
index 112772b..13ca586 100644
--- a/ColecoVision.sv
+++ b/ColecoVision.sv
@@ -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,
diff --git a/sys/hps_io.v b/sys/hps_io.v
index a9ef4c9..e26ef16 100644
--- a/sys/hps_io.v
+++ b/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
diff --git a/sys/ip/reset_source.v b/sys/ip/reset_source.v
index e9f0435..569eb9c 100644
--- a/sys/ip/reset_source.v
+++ b/sys/ip/reset_source.v
@@ -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
diff --git a/sys/ip/reset_source_hw.tcl b/sys/ip/reset_source_hw.tcl
index defa277..cba39f7 100644
--- a/sys/ip/reset_source_hw.tcl
+++ b/sys/ip/reset_source_hw.tcl
@@ -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
#
diff --git a/sys/sys_top.v b/sys/sys_top.v
index decde57..4f737d5 100644
--- a/sys/sys_top.v
+++ b/sys/sys_top.v
@@ -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),
diff --git a/sys/sysmem.sv b/sys/sysmem.sv
index 04b485b..0f60f65 100644
--- a/sys/sysmem.sv
+++ b/sys/sysmem.sv
@@ -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
diff --git a/sys/vip.qsys b/sys/vip.qsys
index eeb9226..47306be 100644
--- a/sys/vip.qsys
+++ b/sys/vip.qsys
@@ -983,7 +983,7 @@
-
+
diff --git a/sys/vip_config.sv b/sys/vip_config.sv
index d6754c4..68057d7 100644
--- a/sys/vip_config.sv
+++ b/sys/vip_config.sv
@@ -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