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