data/full_repos/permissive/217290850/sys/sys_top.v
 line:183: before: "integer"
1: b'%Warning-WIDTH: data/full_repos/permissive/217290850/sys/sys_top.v:1320: Operator SUB expects 17 bits on the RHS, but RHS\'s SIGNED generates 14 bits.\n                                                                       : ... In instance sys_top.audmix_r\n  1: a3 <= $signed(a2) - $signed(a2[16:3]) + $signed(pre_in[15:2]);\n                       ^\n                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.\n%Warning-WIDTH: data/full_repos/permissive/217290850/sys/sys_top.v:1320: Operator ADD expects 17 bits on the RHS, but RHS\'s SIGNED generates 14 bits.\n                                                                       : ... In instance sys_top.audmix_r\n  1: a3 <= $signed(a2) - $signed(a2[16:3]) + $signed(pre_in[15:2]);\n                                           ^\n%Warning-WIDTH: data/full_repos/permissive/217290850/sys/sys_top.v:1321: Operator SUB expects 17 bits on the RHS, but RHS\'s SIGNED generates 15 bits.\n                                                                       : ... In instance sys_top.audmix_r\n  2: a3 <= $signed(a2) - $signed(a2[16:2]) + $signed(pre_in[15:1]);\n                       ^\n%Warning-WIDTH: data/full_repos/permissive/217290850/sys/sys_top.v:1321: Operator ADD expects 17 bits on the RHS, but RHS\'s SIGNED generates 15 bits.\n                                                                       : ... In instance sys_top.audmix_r\n  2: a3 <= $signed(a2) - $signed(a2[16:2]) + $signed(pre_in[15:1]);\n                                           ^\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:168: Cannot find file containing module: \'mcp23009\'\nmcp23009 mcp23009\n^~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/217290850/sys,data/full_repos/permissive/217290850/mcp23009\n             data/full_repos/permissive/217290850/sys,data/full_repos/permissive/217290850/mcp23009.v\n             data/full_repos/permissive/217290850/sys,data/full_repos/permissive/217290850/mcp23009.sv\n             mcp23009\n             mcp23009.v\n             mcp23009.sv\n             obj_dir/mcp23009\n             obj_dir/mcp23009.v\n             obj_dir/mcp23009.sv\n%Warning-WIDTH: data/full_repos/permissive/217290850/sys/sys_top.v:193: Logical Operator LOGNOT expects 1 bit on the LHS, but LHS\'s VARREF \'deb_user\' generates 8 bits.\n                                                                      : ... In instance sys_top\n  if(!deb_user) btn_user <= 0;\n     ^\n%Warning-WIDTH: data/full_repos/permissive/217290850/sys/sys_top.v:197: Logical Operator LOGNOT expects 1 bit on the LHS, but LHS\'s VARREF \'deb_osd\' generates 8 bits.\n                                                                      : ... In instance sys_top\n  if(!deb_osd) btn_osd <= 0;\n     ^\n%Warning-WIDTH: data/full_repos/permissive/217290850/sys/sys_top.v:190: Logical Operator LOGNOT expects 1 bit on the LHS, but LHS\'s VARREF \'div\' generates 32 bits.\n                                                                      : ... In instance sys_top\n if(!div) begin\n    ^\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:254: Cannot find file containing module: \'cyclonev_hps_interface_mpu_general_purpose\'\ncyclonev_hps_interface_mpu_general_purpose h2f_gp\n^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:398: Cannot find file containing module: \'cyclonev_hps_interface_peripheral_uart\'\ncyclonev_hps_interface_peripheral_uart uart\n^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:404: Cannot find file containing module: \'cyclonev_hps_interface_peripheral_spi_master\'\ncyclonev_hps_interface_peripheral_spi_master spi\n^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n%Warning-WIDTH: data/full_repos/permissive/217290850/sys/sys_top.v:414: Operator ASSIGNW expects 64 bits on the Assign RHS, but Assign RHS\'s REPLICATE generates 1 bits.\n                                                                      : ... In instance sys_top\nwire [63:0] f2h_irq = {HDMI_TX_VS};\n                    ^\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:415: Cannot find file containing module: \'cyclonev_hps_interface_interrupts\'\ncyclonev_hps_interface_interrupts interrupts\n^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:448: Cannot find file containing module: \'sysmem_lite\'\nsysmem_lite sysmem\n^~~~~~~~~~~\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:511: Cannot find file containing module: \'ascal\'\nascal\n^~~~~\n%Warning-WIDTH: data/full_repos/permissive/217290850/sys/sys_top.v:622: Logical Operator COND expects 1 bit on the Conditional Test, but Conditional Test\'s VARREF \'VSET\' generates 12 bits.\n                                                                      : ... In instance sys_top\n    wcalc <= VSET ? (VSET*ARX)/ARY : (HEIGHT*ARX)/ARY;\n                  ^\n%Warning-WIDTH: data/full_repos/permissive/217290850/sys/sys_top.v:622: Operator DIV expects 32 bits on the RHS, but RHS\'s VARREF \'ARY\' generates 8 bits.\n                                                                      : ... In instance sys_top\n    wcalc <= VSET ? (VSET*ARX)/ARY : (HEIGHT*ARX)/ARY;\n                              ^\n%Warning-WIDTH: data/full_repos/permissive/217290850/sys/sys_top.v:622: Operator DIV expects 32 bits on the RHS, but RHS\'s VARREF \'ARY\' generates 8 bits.\n                                                                      : ... In instance sys_top\n    wcalc <= VSET ? (VSET*ARX)/ARY : (HEIGHT*ARX)/ARY;\n                                                 ^\n%Warning-WIDTH: data/full_repos/permissive/217290850/sys/sys_top.v:623: Operator DIV expects 32 bits on the RHS, but RHS\'s VARREF \'ARX\' generates 8 bits.\n                                                                      : ... In instance sys_top\n    hcalc <= (WIDTH*ARY)/ARX;\n                        ^\n%Warning-WIDTH: data/full_repos/permissive/217290850/sys/sys_top.v:630: Operator ASSIGNDLY expects 32 bits on the Assign RHS, but Assign RHS\'s VARREF \'WIDTH\' generates 12 bits.\n                                                                      : ... In instance sys_top\n    wcalc<= WIDTH;\n         ^~\n%Warning-WIDTH: data/full_repos/permissive/217290850/sys/sys_top.v:631: Operator ASSIGNDLY expects 32 bits on the Assign RHS, but Assign RHS\'s VARREF \'HEIGHT\' generates 12 bits.\n                                                                      : ... In instance sys_top\n    hcalc<= HEIGHT;\n         ^~\n%Warning-WIDTH: data/full_repos/permissive/217290850/sys/sys_top.v:621: Logical Operator LOGAND expects 1 bit on the LHS, but LHS\'s VARREF \'ARX\' generates 8 bits.\n                                                                      : ... In instance sys_top\n   else if(ARX && ARY) begin\n               ^~\n%Warning-WIDTH: data/full_repos/permissive/217290850/sys/sys_top.v:621: Logical Operator LOGAND expects 1 bit on the RHS, but RHS\'s VARREF \'ARY\' generates 8 bits.\n                                                                      : ... In instance sys_top\n   else if(ARX && ARY) begin\n               ^~\n%Warning-WIDTH: data/full_repos/permissive/217290850/sys/sys_top.v:635: Logical Operator LOGNOT expects 1 bit on the LHS, but LHS\'s VARREF \'VSET\' generates 12 bits.\n                                                                      : ... In instance sys_top\n    videow <= (!VSET && (wcalc > WIDTH))     ? WIDTH  : wcalc[11:0];\n               ^\n%Warning-WIDTH: data/full_repos/permissive/217290850/sys/sys_top.v:636: Logical Operator COND expects 1 bit on the Conditional Test, but Conditional Test\'s VARREF \'VSET\' generates 12 bits.\n                                                                      : ... In instance sys_top\n    videoh <= VSET ? VSET : (hcalc > HEIGHT) ? HEIGHT : hcalc[11:0];\n                   ^\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:650: Cannot find file containing module: \'pll_hdmi_adj\'\npll_hdmi_adj pll_hdmi_adj\n^~~~~~~~~~~~\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:681: Cannot find file containing module: \'fbpal\'\nfbpal fbpal\n^~~~~\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:707: Cannot find file containing module: \'pll_hdmi\'\npll_hdmi pll_hdmi\n^~~~~~~~\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:738: Cannot find file containing module: \'pll_cfg\'\npll_cfg pll_cfg\n^~~~~~~\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:786: Cannot find file containing module: \'hdmi_config\'\nhdmi_config hdmi_config\n^~~~~~~~~~~\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:804: Cannot find file containing module: \'scanlines\'\nscanlines #(1) HDMI_scanlines\n^~~~~~~~~\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:822: Cannot find file containing module: \'osd\'\nosd hdmi_osd\n^~~\n%Warning-WIDTH: data/full_repos/permissive/217290850/sys/sys_top.v:854: Operator OR expects 4 bits on the RHS, but RHS\'s VARREF \'vga_hs_osd\' generates 1 bits.\n                                                                      : ... In instance sys_top\n  hss <= (hss << 1) | vga_hs_osd;\n                    ^\n%Warning-WIDTH: data/full_repos/permissive/217290850/sys/sys_top.v:867: Logical Operator LOGNOT expects 1 bit on the LHS, but LHS\'s REPLICATE generates 5 bits.\n                                                                      : ... In instance sys_top\n  dv_de1 <= !{hss,vga_hs_osd} && vde;\n            ^\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:886: Cannot find file containing module: \'cyclonev_clkselect\'\ncyclonev_clkselect hdmi_clk_sw\n^~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:896: Cannot find file containing module: \'altddio_out\'\naltddio_out\n^~~~~~~~~~~\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:950: Cannot find file containing module: \'scanlines\'\nscanlines #(0) VGA_scanlines\n^~~~~~~~~\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:968: Cannot find file containing module: \'osd\'\nosd vga_osd\n^~~\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:992: Cannot find file containing module: \'vga_out\'\n vga_out vga_out\n ^~~~~~~\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:1061: Cannot find file containing module: \'audio_out\'\naudio_out audio_out\n^~~~~~~~~\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:1087: Cannot find file containing module: \'alsa\'\nalsa alsa\n^~~~\n%Error: data/full_repos/permissive/217290850/sys/sys_top.v:1172: Cannot find file containing module: \'emu\'\nemu emu\n^~~\n%Error: Exiting due to 22 error(s), 20 warning(s)\n'
module sys_top
(

	input         FPGA_CLK1_50,
	input         FPGA_CLK2_50,
	input         FPGA_CLK3_50,


	output        HDMI_I2C_SCL,
	inout         HDMI_I2C_SDA,

	output        HDMI_MCLK,
	output        HDMI_SCLK,
	output        HDMI_LRCLK,
	output        HDMI_I2S,

	output        HDMI_TX_CLK,
	output        HDMI_TX_DE,
	output [23:0] HDMI_TX_D,
	output        HDMI_TX_HS,
	output        HDMI_TX_VS,

	input         HDMI_TX_INT,


	output [12:0] SDRAM_A,
	inout  [15:0] SDRAM_DQ,
	output        SDRAM_DQML,
	output        SDRAM_DQMH,
	output        SDRAM_nWE,
	output        SDRAM_nCAS,
	output        SDRAM_nRAS,
	output        SDRAM_nCS,
	output  [1:0] SDRAM_BA,
	output        SDRAM_CLK,
	output        SDRAM_CKE,

`ifdef DUAL_SDRAM

	output [12:0] SDRAM2_A,
	inout  [15:0] SDRAM2_DQ,
	output        SDRAM2_nWE,
	output        SDRAM2_nCAS,
	output        SDRAM2_nRAS,
	output        SDRAM2_nCS,
	output  [1:0] SDRAM2_BA,
	output        SDRAM2_CLK,

`else

	output  [5:0] VGA_R,
	output  [5:0] VGA_G,
	output  [5:0] VGA_B,
	inout         VGA_HS,
	output		  VGA_VS,
	input         VGA_EN,


	output		  AUDIO_L,
	output		  AUDIO_R,
	output		  AUDIO_SPDIF,


	inout   [3:0] SDIO_DAT,
	inout         SDIO_CMD,
	output        SDIO_CLK,


	output        LED_USER,
	output        LED_HDD,
	output        LED_POWER,
	input         BTN_USER,
	input         BTN_OSD,
	input         BTN_RESET,
`endif


	output        SD_SPI_CS,
	input         SD_SPI_MISO,
	output        SD_SPI_CLK,
	output        SD_SPI_MOSI,

	inout         SDCD_SPDIF,
	output        IO_SCL,
	inout         IO_SDA,


	output        ADC_SCK,
	input         ADC_SDO,
	output        ADC_SDI,
	output        ADC_CONVST,


	input   [1:0] KEY,


	input   [3:0] SW,


	output  [7:0] LED,


	inout   [6:0] USER_IO
);



`ifndef DUAL_SDRAM
	assign SDIO_DAT  = 4'bZZZZ;
	assign SDIO_CLK  = 1'bZ;
	assign SDIO_CMD  = 1'bZ;
	assign SD_SPI_CS = mcp_sdcd ? ((~VGA_EN & sog & ~cs1) ? 1'b1 : 1'bZ) : 1'bZ;
`else
	assign SD_SPI_CS = 1'bZ;
`endif
assign SD_SPI_CLK  = 1'bZ;
assign SD_SPI_MOSI = 1'bZ;



reg [7:0] led_overtake = 0;
reg [7:0] led_state    = 0;

wire led_p =  led_power[1] ? ~led_power[0] : 1'b0;
wire led_d =  led_disk[1]  ? ~led_disk[0]  : ~(led_disk[0] | gp_out[29]);
wire led_u = ~led_user;
wire led_locked;

`ifndef DUAL_SDRAM
	assign LED_POWER = (SW[3] | led_p) ? 1'bZ : 1'b0;
	assign LED_HDD   = (SW[3] | led_d) ? 1'bZ : 1'b0;
	assign LED_USER  = (SW[3] | led_u) ? 1'bZ : 1'b0;
`endif


assign LED = (led_overtake & led_state) | (~led_overtake & {1'b0,led_locked,1'b0, ~led_p, 1'b0, ~led_d, 1'b0, ~led_u});

wire btn_r, btn_o, btn_u;
`ifdef DUAL_SDRAM
	assign {btn_r,btn_o,btn_u} = {mcp_btn[1],mcp_btn[2],mcp_btn[0]};
`else
	assign {btn_r,btn_o,btn_u} = ~{BTN_RESET,BTN_OSD,BTN_USER} | {mcp_btn[1],mcp_btn[2],mcp_btn[0]};
`endif

wire [2:0] mcp_btn;
wire       mcp_sdcd;
mcp23009 mcp23009
(
	.clk(FPGA_CLK2_50),

	.btn(mcp_btn),
	.led({led_p, led_d, led_u}),
	.sd_cd(mcp_sdcd),

	.scl(IO_SCL),
	.sda(IO_SDA)
);


reg btn_user, btn_osd;
always @(posedge FPGA_CLK2_50) begin
	integer div;
	reg [7:0] deb_user;
	reg [7:0] deb_osd;

	div <= div + 1'b1;
	if(div > 100000) div <= 0;

	if(!div) begin
		deb_user <= {deb_user[6:0], btn_u | ~KEY[1]};
		if(&deb_user) btn_user <= 1;
		if(!deb_user) btn_user <= 0;

		deb_osd <= {deb_osd[6:0], btn_o | ~KEY[0]};
		if(&deb_osd) btn_osd <= 1;
		if(!deb_osd) btn_osd <= 0;
	end
end






wire [31:0] gp_in = {1'b0, btn_user, btn_osd, SW[3], 8'd0, io_ver, io_ack, io_wide, io_dout};
wire [31:0] gp_out;

wire  [1:0] io_ver    = 1;
wire        io_wait;
wire        io_wide;
wire [15:0] io_dout;
wire [15:0] io_din    = gp_outr[15:0];
wire        io_clk    = gp_outr[17];
wire        io_ss0 = gp_outr[18];
wire        io_ss1 = gp_outr[19];
wire        io_ss2 = gp_outr[20];


`ifndef DEBUG_NOHDMI
wire io_osd_hdmi = io_ss1 & ~io_ss0;
`endif

wire io_fpga     = ~io_ss1 & io_ss0;
wire io_uio      = ~io_ss1 & io_ss2;

reg  io_ack;
reg  rack;
wire io_strobe = ~rack & io_clk;

always @(posedge clk_sys) begin
	if(~(io_wait | vs_wait) | io_strobe) begin
		rack <= io_clk;
		io_ack <= rack;
	end
end

reg [31:0] gp_outr;
always @(posedge clk_sys) begin
	reg [31:0] gp_outd;
	gp_outr <= gp_outd;
	gp_outd <= gp_out;
end

`ifdef DUAL_SDRAM
	wire  [7:0] core_type  = 'hA8;
`else
	wire  [7:0] core_type  = 'hA4;
`endif


wire [31:0] core_magic = {24'h5CA623, core_type};

cyclonev_hps_interface_mpu_general_purpose h2f_gp
(
	.gp_in({~gp_out[31] ? core_magic : gp_in}),
	.gp_out(gp_out)
);


reg [15:0] cfg;

reg        cfg_got      = 0;
reg        cfg_set      = 0;
wire [1:0] hdmi_limited = {cfg[11],cfg[8]};
`ifndef DEBUG_NOHDMI
wire       direct_video = cfg[10];
`else
wire       direct_video = 1;
`endif
wire       dvi_mode     = cfg[7];
wire       audio_96k    = cfg[6];
wire       csync_en     = cfg[3];
wire       ypbpr_en     = cfg[5];
wire       io_osd_vga   = io_ss1 & ~io_ss2;
`ifndef DUAL_SDRAM
	wire    sog          = cfg[9];
	wire    vga_scaler   = cfg[2];
`endif

reg        cfg_custom_t = 0;
reg  [5:0] cfg_custom_p1;
reg [31:0] cfg_custom_p2;

reg  [4:0] vol_att = 0;

reg  [6:0] coef_addr;
reg  [8:0] coef_data;
reg        coef_wr = 0;

wire [7:0] ARX, ARY;
reg [11:0] VSET = 0;
reg  [2:0] scaler_flt;
reg        lowlat = 0;
reg        cfg_dis = 0;

reg        vs_wait = 0;

always@(posedge clk_sys) begin
	reg  [7:0] cmd;
	reg        has_cmd;
	reg        old_strobe;
	reg  [7:0] cnt = 0;
	reg        vs_d0,vs_d1,vs_d2;

	old_strobe <= io_strobe;
	coef_wr <= 0;

	if(~io_uio) begin
		has_cmd <= 0;
		cmd <= 0;
	end
	else
	if(~old_strobe & io_strobe) begin
		if(!has_cmd) begin
			has_cmd <= 1;
			cmd <= io_din[7:0];
			cnt <= 0;
			if(io_din[7:0] == 'h30) vs_wait <= 1;
		end
		else begin
			if(cmd == 1) begin
				cfg <= io_din;
				cfg_set <= 1;
			end
			if(cmd == 'h20) begin
				cfg_set <= 0;
				cnt <= cnt + 1'd1;
				if(cnt<8) begin
					case(cnt[2:0])
						0: if(WIDTH  != io_din[11:0]) WIDTH  <= io_din[11:0];
						1: if(HFP    != io_din[11:0]) HFP    <= io_din[11:0];
						2: if(HS     != io_din[11:0]) HS     <= io_din[11:0];
						3: if(HBP    != io_din[11:0]) HBP    <= io_din[11:0];
						4: if(HEIGHT != io_din[11:0]) HEIGHT <= io_din[11:0];
						5: if(VFP    != io_din[11:0]) VFP    <= io_din[11:0];
						6: if(VS     != io_din[11:0]) VS     <= io_din[11:0];
						7: if(VBP    != io_din[11:0]) VBP    <= io_din[11:0];
					endcase
`ifndef DEBUG_NOHDMI
					if(cnt == 1) begin
						cfg_custom_p1 <= 0;
						cfg_custom_p2 <= 0;
						cfg_custom_t <= ~cfg_custom_t;
					end
				end
				else begin
					if(cnt[1:0]==0) cfg_custom_p1 <= io_din[5:0];
					if(cnt[1:0]==1) cfg_custom_p2[15:0]  <= io_din;
					if(cnt[1:0]==2) begin
						cfg_custom_p2[31:16] <= io_din;
						cfg_custom_t <= ~cfg_custom_t;
						cnt[2:0] <= 3'b100;
					end
					if(cnt == 8) {lowlat,cfg_dis} <= io_din[15:14];
`endif
				end
			end
			if(cmd == 'h2F) begin
				cnt <= cnt + 1'd1;
				case(cnt[3:0])
					0: {FB_EN,FB_FLT,FB_FMT} <= {io_din[15], io_din[14], io_din[5:0]};
					1: FB_BASE[15:0]  <= io_din[15:0];
					2: FB_BASE[31:16] <= io_din[15:0];
					3: FB_WIDTH       <= io_din[11:0];
					4: FB_HEIGHT      <= io_din[11:0];
					5: FB_HMIN        <= io_din[11:0];
					6: FB_HMAX        <= io_din[11:0];
					7: FB_VMIN        <= io_din[11:0];
					8: FB_VMAX        <= io_din[11:0];
				endcase
			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];
			if(cmd == 'h2A) {coef_wr,coef_addr,coef_data} <= {1'b1,io_din};
			if(cmd == 'h2B) scaler_flt <= io_din[2:0];
		end
	end

	vs_d0 <= HDMI_TX_VS;
	if(vs_d0 == HDMI_TX_VS) vs_d1 <= vs_d0;

	vs_d2 <= vs_d1;
	if(~vs_d2 & vs_d1) vs_wait <= 0;
end

always @(posedge clk_sys) begin
	reg vsd, vsd2;
	if(~cfg_ready || ~cfg_set) cfg_got <= cfg_set;
	else begin
		vsd  <= HDMI_TX_VS;
		vsd2 <= vsd;
		if(~vsd2 & vsd) cfg_got <= cfg_set;
	end
end

cyclonev_hps_interface_peripheral_uart uart
(
	.ri(0)
);

wire aspi_sck,aspi_mosi,aspi_ss;
cyclonev_hps_interface_peripheral_spi_master spi
(
	.sclk_out(aspi_sck),
	.txd(aspi_mosi),
	.rxd(1),

	.ss_0_n(aspi_ss),
	.ss_in_n(1)
);

wire [63:0] f2h_irq = {HDMI_TX_VS};
cyclonev_hps_interface_interrupts interrupts
(
	.irq(f2h_irq)
);



reg reset_req = 0;
always @(posedge FPGA_CLK2_50) begin
	reg [1:0] resetd, resetd2;
	reg       old_reset;


	old_reset <= reset;
	if(~old_reset & reset) reset_req <= 1;



	if(resetd==1) reset_req <= 1;
	if(resetd==2 && resetd2==0) reset_req <= 0;

	resetd  <= gp_out[31:30];
	resetd2 <= resetd;
end

wire clk_100m;
wire clk_hdmi  = hdmi_clk_out;
wire clk_audio = FPGA_CLK3_50;
wire clk_pal   = FPGA_CLK3_50;



wire reset;
sysmem_lite sysmem
(

	.reset_core_req(reset_req),
	.reset_out(reset),
	.clock(clk_100m),


	.reset_hps_cold_req(btn_r),

`ifdef USE_DDRAM

	.ram1_clk(ram_clk),
	.ram1_address(ram_address),
	.ram1_burstcount(ram_burstcount),
	.ram1_waitrequest(ram_waitrequest),
	.ram1_readdata(ram_readdata),
	.ram1_readdatavalid(ram_readdatavalid),
	.ram1_read(ram_read),
	.ram1_writedata(ram_writedata),
	.ram1_byteenable(ram_byteenable),
	.ram1_write(ram_write),
`endif


	.ram2_clk(clk_audio),
	.ram2_address((ap_en1 == ap_en2) ? aram_address : pram_address),
	.ram2_burstcount((ap_en1 == ap_en2) ? aram_burstcount : pram_burstcount),
	.ram2_waitrequest(aram_waitrequest),
	.ram2_readdata(aram_readdata),
	.ram2_readdatavalid(aram_readdatavalid),
	.ram2_read((ap_en1 == ap_en2) ? aram_read : pram_read),
	.ram2_writedata(0),
	.ram2_byteenable(8'hFF),
	.ram2_write(0),



	.vbuf_clk(clk_100m),
	.vbuf_address(vbuf_address),
	.vbuf_burstcount(vbuf_burstcount),
	.vbuf_waitrequest(vbuf_waitrequest),
	.vbuf_writedata(vbuf_writedata),
	.vbuf_byteenable(vbuf_byteenable),
	.vbuf_write(vbuf_write),
	.vbuf_readdata(vbuf_readdata),
	.vbuf_readdatavalid(vbuf_readdatavalid),
	.vbuf_read(vbuf_read)
);

wire  [27:0] vbuf_address;
wire   [7:0] vbuf_burstcount;
wire         vbuf_waitrequest;
wire [127:0] vbuf_readdata;
wire         vbuf_readdatavalid;
wire         vbuf_read;
wire [127:0] vbuf_writedata;
wire  [15:0] vbuf_byteenable;
wire         vbuf_write;

wire  [23:0] hdmi_data;
wire         hdmi_vs, hdmi_hs, hdmi_de;

ascal
#(
	.RAMBASE(32'h20000000),
	.N_DW(128),
	.N_AW(28)
)
ascal
(
	.reset_na (~reset_req),
	.run      (1),
	.freeze   (0),

	.i_clk    (clk_ihdmi),
	.i_ce     (ce_hpix),
	.i_r      (hr_out),
	.i_g      (hg_out),
	.i_b      (hb_out),
	.i_hs     (hhs_fix),
	.i_vs     (hvs_fix),
	.i_fl     (f1),
	.i_de     (hde_emu),
	.iauto    (1),
	.himin    (0),
	.himax    (0),
	.vimin    (0),
	.vimax    (0),

	.o_clk    (clk_hdmi),
	.o_ce     (1),
	.o_r      (hdmi_data[23:16]),
	.o_g      (hdmi_data[15:8]),
	.o_b      (hdmi_data[7:0]),
	.o_hs     (hdmi_hs),
	.o_vs     (hdmi_vs),
	.o_de     (hdmi_de),
	.o_lltune (lltune),
	.htotal   (WIDTH + HFP + HBP + HS),
	.hsstart  (WIDTH + HFP),
	.hsend    (WIDTH + HFP + HS),
	.hdisp    (WIDTH),
	.hmin     (hmin),
	.hmax     (hmax),
	.vtotal   (HEIGHT + VFP + VBP + VS),
	.vsstart  (HEIGHT + VFP),
	.vsend    (HEIGHT + VFP + VS),
	.vdisp    (HEIGHT),
	.vmin     (vmin),
	.vmax     (vmax),

	.mode     ({~lowlat,FB_EN ? FB_FLT : |scaler_flt,2'b00}),
	.poly_clk (clk_sys),
	.poly_a   (coef_addr),
	.poly_dw  (coef_data),
	.poly_wr  (coef_wr),

	.pal_clk  (clk_pal),
	.pal_dw   (pal_d),
	.pal_a    (pal_a),
	.pal_wr   (pal_wr),

	.o_fb_ena         (FB_EN),
	.o_fb_hsize       (FB_WIDTH),
	.o_fb_vsize       (FB_HEIGHT),
	.o_fb_format      (FB_FMT),
	.o_fb_base        (FB_BASE),

	.avl_clk          (clk_100m),
	.avl_waitrequest  (vbuf_waitrequest),
	.avl_readdata     (vbuf_readdata),
	.avl_readdatavalid(vbuf_readdatavalid),
	.avl_burstcount   (vbuf_burstcount),
	.avl_writedata    (vbuf_writedata),
	.avl_address      (vbuf_address),
	.avl_write        (vbuf_write),
	.avl_read         (vbuf_read),
	.avl_byteenable   (vbuf_byteenable)
);

reg        FB_EN     = 0;
reg        FB_FLT    = 0;
reg  [5:0] FB_FMT    = 0;
reg [11:0] FB_WIDTH  = 0;
reg [11:0] FB_HEIGHT = 0;
reg [11:0] FB_HMIN   = 0;
reg [11:0] FB_HMAX   = 0;
reg [11:0] FB_VMIN   = 0;
reg [11:0] FB_VMAX   = 0;
reg [31:0] FB_BASE   = 0;

reg [11:0] hmin;
reg [11:0] hmax;
reg [11:0] vmin;
reg [11:0] vmax;

always @(posedge clk_vid) begin
	reg [31:0] wcalc;
	reg [31:0] hcalc;
	reg  [2:0] state;
	reg [11:0] videow;
	reg [11:0] videoh;

	state <= state + 1'd1;
	case(state)
		0: if(FB_EN) begin
				hmin <= FB_HMIN;
				vmin <= FB_VMIN;
				hmax <= FB_HMAX;
				vmax <= FB_VMAX;
				state<= 0;
			end
			else if(ARX && ARY) begin
				wcalc <= VSET ? (VSET*ARX)/ARY : (HEIGHT*ARX)/ARY;
				hcalc <= (WIDTH*ARY)/ARX;
			end
			else begin
				hmin <= 0;
				hmax <= WIDTH - 1'd1;
				vmin <= 0;
				vmax <= HEIGHT - 1'd1;
				wcalc<= WIDTH;
				hcalc<= HEIGHT;
				state<= 0;
			end
		6: begin
				videow <= (!VSET && (wcalc > WIDTH))     ? WIDTH  : wcalc[11:0];
				videoh <= VSET ? VSET : (hcalc > HEIGHT) ? HEIGHT : hcalc[11:0];
			end
		7: begin
				hmin <= ((WIDTH  - videow)>>1);
				hmax <= ((WIDTH  - videow)>>1) + videow - 1'd1;
				vmin <= ((HEIGHT - videoh)>>1);
				vmax <= ((HEIGHT - videoh)>>1) + videoh - 1'd1;
			end
	endcase
end

`ifndef DEBUG_NOHDMI
wire [15:0] lltune;

pll_hdmi_adj pll_hdmi_adj
(
   .clk(FPGA_CLK1_50),
	.reset_na(~reset_req),

	.llena(lowlat),
	.lltune({16{hdmi_config_done | cfg_dis}} & lltune),
	.locked(led_locked),
	.i_waitrequest(adj_waitrequest),
	.i_write(adj_write),
	.i_address(adj_address),
	.i_writedata(adj_data),
	.o_waitrequest(cfg_waitrequest),
	.o_write(cfg_write),
	.o_address(cfg_address),
	.o_writedata(cfg_data)
);
`else
assign led_locked=0;
`endif

wire [23:0] pal_d;
wire  [7:0] pal_a;
wire        pal_wr;

wire ap_en1, ap_en2;

wire [28:0] pram_address;
wire  [7:0] pram_burstcount;
wire        pram_read;

fbpal fbpal
(
	.reset(reset),
	.en_in(ap_en2),
	.en_out(ap_en1),

	.ram_clk(clk_pal),
	.ram_address(pram_address),
	.ram_burstcount(pram_burstcount),
	.ram_waitrequest(aram_waitrequest),
	.ram_readdata(aram_readdata),
	.ram_readdatavalid(aram_readdatavalid),
	.ram_read(pram_read),

	.fb_address(FB_BASE),

	.pal_en(~FB_FMT[2] & FB_FMT[1] & FB_FMT[0] & FB_EN),
	.pal_a(pal_a),
	.pal_d(pal_d),
	.pal_wr(pal_wr)
);



`ifndef DEBUG_NOHDMI
wire hdmi_clk_out;
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_clk_out)
);
`else
assign hdmi_clk_out=0;
`endif

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    = 36;

wire [63:0] reconfig_to_pll;
wire [63:0] reconfig_from_pll;
wire        cfg_waitrequest,adj_waitrequest;
wire        cfg_write;
wire  [5:0] cfg_address;
wire [31:0] cfg_data;
reg         adj_write;
reg   [5:0] adj_address;
reg  [31:0] adj_data;
`ifndef DEBUG_NOHDMI
pll_cfg pll_cfg
(
	.mgmt_clk(FPGA_CLK1_50),
	.mgmt_reset(reset_req),
	.mgmt_waitrequest(cfg_waitrequest),
	.mgmt_read(0),
	.mgmt_readdata(),
	.mgmt_write(cfg_write),
	.mgmt_address(cfg_address),
	.mgmt_writedata(cfg_data),
	.reconfig_to_pll(reconfig_to_pll),
	.reconfig_from_pll(reconfig_from_pll)
);

reg cfg_ready = 0;

always @(posedge FPGA_CLK1_50) begin
	reg gotd = 0, gotd2 = 0;
	reg custd = 0, custd2 = 0;
	reg old_wait = 0;

	gotd  <= cfg_got;
	gotd2 <= gotd;

	adj_write <= 0;

	custd <= cfg_custom_t;
	custd2 <= custd;
	if(custd2 != custd & ~gotd) begin
		adj_address <= cfg_custom_p1;
		adj_data <= cfg_custom_p2;
		adj_write <= 1;
	end

	if(~gotd2 & gotd) begin
		adj_address <= 2;
		adj_data <= 0;
		adj_write <= 1;
	end

	old_wait <= adj_waitrequest;
	if(old_wait & ~adj_waitrequest & gotd) cfg_ready <= 1;
end
`else
wire cfg_ready=1;
`endif

wire hdmi_config_done;
hdmi_config hdmi_config
(
	.iCLK(FPGA_CLK1_50),
	.iRST_N(cfg_ready & ~HDMI_TX_INT & ~cfg_dis),
	.done(hdmi_config_done),

	.I2C_SCL(HDMI_I2C_SCL),
	.I2C_SDA(HDMI_I2C_SDA),

	.dvi_mode(dvi_mode),
	.audio_96k(audio_96k),
	.limited(hdmi_limited),
	.ypbpr(ypbpr_en & direct_video)
);

`ifndef DEBUG_NOHDMI
wire [23:0] hdmi_data_sl;
wire        hdmi_de_sl, hdmi_vs_sl, hdmi_hs_sl;
scanlines #(1) HDMI_scanlines
(
	.clk(clk_hdmi),

	.scanlines(scanlines),
	.din(hdmi_data),
	.hs_in(hdmi_hs),
	.vs_in(hdmi_vs),
	.de_in(hdmi_de),

	.dout(hdmi_data_sl),
	.hs_out(hdmi_hs_sl),
	.vs_out(hdmi_vs_sl),
	.de_out(hdmi_de_sl)
);

wire [23:0] hdmi_data_osd;
wire        hdmi_de_osd, hdmi_vs_osd, hdmi_hs_osd;
osd hdmi_osd
(
	.clk_sys(clk_sys),

	.io_osd(io_osd_hdmi),
	.io_strobe(io_strobe),
	.io_din(io_din),

	.clk_video(clk_hdmi),
	.din(hdmi_data_sl),
	.hs_in(hdmi_hs_sl),
	.vs_in(hdmi_vs_sl),
	.de_in(hdmi_de_sl),

	.dout(hdmi_data_osd),
	.hs_out(hdmi_hs_osd),
	.vs_out(hdmi_vs_osd),
	.de_out(hdmi_de_osd)
);
`endif

reg [23:0] dv_data;
reg        dv_hs, dv_vs, dv_de;
always @(posedge 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) | vga_hs_osd;

		old_hs <= vga_hs_osd;
		if(~old_hs && vga_hs_osd) begin
			old_vs <= vga_vs_osd;
			if(~&vcnt) vcnt <= vcnt + 1'd1;
			if(~old_vs & vga_vs_osd & ~f1) vsz <= vcnt;
			if(old_vs & ~vga_vs_osd) vcnt <= 0;

			if(vcnt == 1) vde <= 1;
			if(vcnt == vsz - 3) vde <= 0;
		end

		dv_de1 <= !{hss,vga_hs_osd} && vde;
		dv_hs1 <= csync_en ? vga_cs_osd : vga_hs_osd;
		dv_vs1 <= vga_vs_osd;
	end

	dv_d1  <= vga_data_osd;
	dv_d2  <= dv_d1;
	dv_de2 <= dv_de1;
	dv_hs2 <= dv_hs1;
	dv_vs2 <= dv_vs1;

	dv_data<= dv_d2;
	dv_de  <= dv_de2;
	dv_hs  <= dv_hs2;
	dv_vs  <= dv_vs2;
end

wire hdmi_tx_clk;
`ifndef DEBUG_NOHDMI
cyclonev_clkselect hdmi_clk_sw
(
	.clkselect({1'b1, direct_video}),
	.inclk({clk_vid, hdmi_clk_out, 2'b00}),
	.outclk(hdmi_tx_clk)
);
`else
assign hdmi_tx_clk = clk_vid;
`endif

altddio_out
#(
	.extend_oe_disable("OFF"),
	.intended_device_family("Cyclone V"),
	.invert_output("OFF"),
	.lpm_hint("UNUSED"),
	.lpm_type("altddio_out"),
	.oe_reg("UNREGISTERED"),
	.power_up_high("OFF"),
	.width(1)
)
hdmiclk_ddr
(
	.datain_h(1'b0),
	.datain_l(1'b1),
	.outclock(hdmi_tx_clk),
	.dataout(HDMI_TX_CLK),
	.aclr(1'b0),
	.aset(1'b0),
	.oe(1'b1),
	.outclocken(1'b1),
	.sclr(1'b0),
	.sset(1'b0)
);

reg hdmi_out_hs;
reg hdmi_out_vs;
reg hdmi_out_de;
reg [23:0] hdmi_out_d;

always @(posedge hdmi_tx_clk) begin
	reg hs,vs,de;
	reg [23:0] d;

	hs <= direct_video ? dv_hs   : hdmi_hs_osd;
	vs <= direct_video ? dv_vs   : hdmi_vs_osd;
	de <= direct_video ? dv_de   : hdmi_de_osd;
	d  <= direct_video ? dv_data : hdmi_data_osd;

	hdmi_out_hs <= hs;
	hdmi_out_vs <= vs;
	hdmi_out_de <= de;
	hdmi_out_d  <= d;
end

assign HDMI_TX_HS = hdmi_out_hs;
assign HDMI_TX_VS = hdmi_out_vs;
assign HDMI_TX_DE = hdmi_out_de;
assign HDMI_TX_D  = hdmi_out_d;



wire [23:0] vga_data_sl;
wire        vga_de_sl, vga_vs_sl, vga_hs_sl;
scanlines #(0) VGA_scanlines
(
	.clk(clk_vid),

	.scanlines(scanlines),
	.din(de_emu ? {r_out, g_out, b_out} : 24'd0),
	.hs_in(hs_fix),
	.vs_in(vs_fix),
	.de_in(de_emu),

	.dout(vga_data_sl),
	.hs_out(vga_hs_sl),
	.vs_out(vga_vs_sl),
	.de_out(vga_de_sl)
);

wire [23:0] vga_data_osd;
wire        vga_vs_osd, vga_hs_osd;
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),
	.hs_in(vga_hs_sl),
	.vs_in(vga_vs_sl),
	.de_in(vga_de_sl),

	.dout(vga_data_osd),
	.hs_out(vga_hs_osd),
	.vs_out(vga_vs_osd)
);

wire vga_cs_osd;
csync csync_vga(clk_vid, vga_hs_osd, vga_vs_osd, vga_cs_osd);

`ifndef DUAL_SDRAM
	wire [23:0] vga_o;
	vga_out vga_out
	(
		.ypbpr_full(0),
		.ypbpr_en(ypbpr_en),
		.dout(vga_o),
		.din(vga_scaler ? {24{hdmi_de_osd}} & hdmi_data_osd : vga_data_osd)
	);

	wire hdmi_cs_osd;
	csync csync_hdmi(clk_hdmi, hdmi_hs_osd, hdmi_vs_osd, hdmi_cs_osd);

	wire vs1 = vga_scaler ? hdmi_vs_osd : vga_vs_osd;
	wire hs1 = vga_scaler ? hdmi_hs_osd : vga_hs_osd;
	wire cs1 = vga_scaler ? hdmi_cs_osd : vga_cs_osd;

	assign VGA_VS = (VGA_EN | SW[3]) ? 1'bZ      : csync_en ? 1'b1 : ~vs1;
	assign VGA_HS = (VGA_EN | SW[3]) ? 1'bZ      : csync_en ? ~cs1 : ~hs1;
	assign VGA_R  = (VGA_EN | SW[3]) ? 6'bZZZZZZ : vga_o[23:18];
	assign VGA_G  = (VGA_EN | SW[3]) ? 6'bZZZZZZ : vga_o[15:10];
	assign VGA_B  = (VGA_EN | SW[3]) ? 6'bZZZZZZ : vga_o[7:2];
`endif



assign SDCD_SPDIF =(SW[3] & ~spdif) ? 1'b0 : 1'bZ;

`ifndef DUAL_SDRAM
	wire anl,anr;

	assign AUDIO_SPDIF = SW[3] ? 1'bZ : SW[0] ? HDMI_LRCLK : spdif;
	assign AUDIO_R     = SW[3] ? 1'bZ : SW[0] ? HDMI_I2S   : anr;
	assign AUDIO_L     = SW[3] ? 1'bZ : SW[0] ? HDMI_SCLK  : anl;
`endif

assign HDMI_MCLK = 0;

wire [15:0] audio_l, audio_l_pre;
aud_mix_top audmix_l
(
	.clk(clk_audio),
	.att(vol_att),
	.mix(audio_mix),
	.is_signed(audio_s),

	.core_audio(audio_ls),
	.pre_in(audio_r_pre),
	.linux_audio(alsa_l),

	.pre_out(audio_l_pre),
	.out(audio_l)
);

wire [15:0] audio_r, audio_r_pre;
aud_mix_top audmix_r
(
	.clk(clk_audio),
	.att(vol_att),
	.mix(audio_mix),
	.is_signed(audio_s),

	.core_audio(audio_rs),
	.pre_in(audio_l_pre),
	.linux_audio(alsa_r),

	.pre_out(audio_r_pre),
	.out(audio_r)
);

wire spdif;
audio_out audio_out
(
	.reset(reset),
	.clk(clk_audio),
	.sample_rate(audio_96k),
	.left_in(audio_l),
	.right_in(audio_r),
	.i2s_bclk(HDMI_SCLK),
	.i2s_lrclk(HDMI_LRCLK),
	.i2s_data(HDMI_I2S),
`ifndef DUAL_SDRAM
	.dac_l(anl),
	.dac_r(anr),
`endif
	.spdif(spdif)
);

wire [28:0] aram_address;
wire  [7:0] aram_burstcount;
wire        aram_waitrequest;
wire [63:0] aram_readdata;
wire        aram_readdatavalid;
wire        aram_read;

wire [15:0] alsa_l, alsa_r;

alsa alsa
(
	.reset(reset),
	.en_in(ap_en1),
	.en_out(ap_en2),

	.ram_clk(clk_audio),
	.ram_address(aram_address),
	.ram_burstcount(aram_burstcount),
	.ram_waitrequest(aram_waitrequest),
	.ram_readdata(aram_readdata),
	.ram_readdatavalid(aram_readdatavalid),
	.ram_read(aram_read),

	.spi_ss(aspi_ss),
	.spi_sck(aspi_sck),
	.spi_mosi(aspi_mosi),

	.pcm_l(alsa_l),
	.pcm_r(alsa_r)
);




assign USER_IO[0] =                       !user_out[0]  ? 1'b0 : 1'bZ;
assign USER_IO[1] =                       !user_out[1]  ? 1'b0 : 1'bZ;
assign USER_IO[2] = !(SW[1] ? HDMI_I2S   : user_out[2]) ? 1'b0 : 1'bZ;
assign USER_IO[3] =                       !user_out[3]  ? 1'b0 : 1'bZ;
assign USER_IO[4] = !(SW[1] ? HDMI_SCLK  : user_out[4]) ? 1'b0 : 1'bZ;
assign USER_IO[5] = !(SW[1] ? HDMI_LRCLK : user_out[5]) ? 1'b0 : 1'bZ;
assign USER_IO[6] =                       !user_out[6]  ? 1'b0 : 1'bZ;

assign user_in[0] =         USER_IO[0];
assign user_in[1] =         USER_IO[1];
assign user_in[2] = SW[1] | USER_IO[2];
assign user_in[3] =         USER_IO[3];
assign user_in[4] = SW[1] | USER_IO[4];
assign user_in[5] = SW[1] | USER_IO[5];
assign user_in[6] =         USER_IO[6];




wire [15:0] audio_ls, audio_rs;
wire        audio_s;
wire  [1:0] audio_mix;
wire  [7:0] r_out, g_out, b_out;
wire        vs_fix, hs_fix, de_emu, vs_emu, hs_emu, f1;
wire  [1:0] scanlines;
wire        clk_sys, clk_vid, ce_pix;
wire  [7:0] hr_out, hg_out, hb_out;
wire        hvs_fix, hhs_fix, hde_emu, hvs_emu, hhs_emu;
wire        clk_ihdmi, ce_hpix;

`ifdef USE_DDRAM
wire        ram_clk;
wire [28:0] ram_address;
wire [7:0]  ram_burstcount;
wire        ram_waitrequest;
wire [63:0] ram_readdata;
wire        ram_readdatavalid;
wire        ram_read;
wire [63:0] ram_writedata;
wire [7:0]  ram_byteenable;
wire        ram_write;
`endif

wire        led_user;
wire  [1:0] led_power;
wire  [1:0] led_disk;

sync_fix hdmi_sync_v(clk_ihdmi, hvs_emu, hvs_fix);
sync_fix hdmi_sync_h(clk_ihdmi, hhs_emu, hhs_fix);
sync_fix sync_v(clk_vid, vs_emu, vs_fix);
sync_fix sync_h(clk_vid, hs_emu, hs_fix);

assign audio_mix = 0;
assign {ADC_SCK, ADC_SDI, ADC_CONVST} = 0;
wire  [6:0] user_out, user_in;

`ifndef USE_SDRAM
assign {SDRAM_DQ, SDRAM_A, SDRAM_BA, SDRAM_CLK, SDRAM_CKE, SDRAM_DQML, SDRAM_DQMH, SDRAM_nWE, SDRAM_nCAS, SDRAM_nRAS, SDRAM_nCS} = {39'bZ};
`endif

emu emu
(
	.CLK_50M(FPGA_CLK2_50),
	.RESET(reset),
	.HPS_BUS({f1, HDMI_TX_VS, clk_100m, clk_ihdmi, ce_hpix, hde_emu, hhs_fix, hvs_fix, io_wait, clk_sys, io_fpga, io_uio, io_strobe, io_wide, io_din, io_dout}),

	.VGA_CLK(clk_vid),
	.VGA_CE(ce_pix),
	.VGA_R(r_out),
	.VGA_G(g_out),
	.VGA_B(b_out),
	.VGA_HS(hs_emu),
	.VGA_VS(vs_emu),
	.VGA_DE(de_emu),
	.VGA_F1(f1),

	.HDMI_CLK(clk_ihdmi),
	.HDMI_CE(ce_hpix),
	.HDMI_R(hr_out),
	.HDMI_G(hg_out),
	.HDMI_B(hb_out),
	.HDMI_HS(hhs_emu),
	.HDMI_VS(hvs_emu),
	.HDMI_DE(hde_emu),
	.HDMI_SL(scanlines),
	.HDMI_ARX(ARX),
	.HDMI_ARY(ARY),

	.LED_USER(led_user),
	.LED_POWER(led_power),
	.LED_DISK(led_disk),

	.AUDIO_L(audio_ls),
	.AUDIO_R(audio_rs),
	.AUDIO_S(audio_s),

`ifdef USE_DDRAM
	.DDRAM_CLK(ram_clk),
	.DDRAM_ADDR(ram_address),
	.DDRAM_BURSTCNT(ram_burstcount),
	.DDRAM_BUSY(ram_waitrequest),
	.DDRAM_DOUT(ram_readdata),
	.DDRAM_DOUT_READY(ram_readdatavalid),
	.DDRAM_RD(ram_read),
	.DDRAM_DIN(ram_writedata),
	.DDRAM_BE(ram_byteenable),
	.DDRAM_WE(ram_write),
`endif

`ifdef USE_SDRAM
	.SDRAM_DQ(SDRAM_DQ),
	.SDRAM_A(SDRAM_A),
	.SDRAM_DQML(SDRAM_DQML),
	.SDRAM_DQMH(SDRAM_DQMH),
	.SDRAM_BA(SDRAM_BA),
	.SDRAM_nCS(SDRAM_nCS),
	.SDRAM_nWE(SDRAM_nWE),
	.SDRAM_nRAS(SDRAM_nRAS),
	.SDRAM_nCAS(SDRAM_nCAS),
	.SDRAM_CLK(SDRAM_CLK),
	.SDRAM_CKE(SDRAM_CKE),
`endif

`ifdef DUAL_SDRAM
	.SDRAM2_DQ(SDRAM2_DQ),
	.SDRAM2_A(SDRAM2_A),
	.SDRAM2_BA(SDRAM2_BA),
	.SDRAM2_nCS(SDRAM2_nCS),
	.SDRAM2_nWE(SDRAM2_nWE),
	.SDRAM2_nRAS(SDRAM2_nRAS),
	.SDRAM2_nCAS(SDRAM2_nCAS),
	.SDRAM2_CLK(SDRAM2_CLK),
	.SDRAM2_EN(SW[3]),
`endif

	.USER_OUT(user_out),
	.USER_IN(user_in)
);

endmodule
module sys_top
(

	input         FPGA_CLK1_50,
	input         FPGA_CLK2_50,
	input         FPGA_CLK3_50,


	output        HDMI_I2C_SCL,
	inout         HDMI_I2C_SDA,

	output        HDMI_MCLK,
	output        HDMI_SCLK,
	output        HDMI_LRCLK,
	output        HDMI_I2S,

	output        HDMI_TX_CLK,
	output        HDMI_TX_DE,
	output [23:0] HDMI_TX_D,
	output        HDMI_TX_HS,
	output        HDMI_TX_VS,

	input         HDMI_TX_INT,


	output [12:0] SDRAM_A,
	inout  [15:0] SDRAM_DQ,
	output        SDRAM_DQML,
	output        SDRAM_DQMH,
	output        SDRAM_nWE,
	output        SDRAM_nCAS,
	output        SDRAM_nRAS,
	output        SDRAM_nCS,
	output  [1:0] SDRAM_BA,
	output        SDRAM_CLK,
	output        SDRAM_CKE,

`ifdef DUAL_SDRAM

	output [12:0] SDRAM2_A,
	inout  [15:0] SDRAM2_DQ,
	output        SDRAM2_nWE,
	output        SDRAM2_nCAS,
	output        SDRAM2_nRAS,
	output        SDRAM2_nCS,
	output  [1:0] SDRAM2_BA,
	output        SDRAM2_CLK,

`else

	output  [5:0] VGA_R,
	output  [5:0] VGA_G,
	output  [5:0] VGA_B,
	inout         VGA_HS,
	output		  VGA_VS,
	input         VGA_EN,


	output		  AUDIO_L,
	output		  AUDIO_R,
	output		  AUDIO_SPDIF,


	inout   [3:0] SDIO_DAT,
	inout         SDIO_CMD,
	output        SDIO_CLK,


	output        LED_USER,
	output        LED_HDD,
	output        LED_POWER,
	input         BTN_USER,
	input         BTN_OSD,
	input         BTN_RESET,
`endif


	output        SD_SPI_CS,
	input         SD_SPI_MISO,
	output        SD_SPI_CLK,
	output        SD_SPI_MOSI,

	inout         SDCD_SPDIF,
	output        IO_SCL,
	inout         IO_SDA,


	output        ADC_SCK,
	input         ADC_SDO,
	output        ADC_SDI,
	output        ADC_CONVST,


	input   [1:0] KEY,


	input   [3:0] SW,


	output  [7:0] LED,


	inout   [6:0] USER_IO
);




`ifndef DUAL_SDRAM
	assign SDIO_DAT  = 4'bZZZZ;
	assign SDIO_CLK  = 1'bZ;
	assign SDIO_CMD  = 1'bZ;
	assign SD_SPI_CS = mcp_sdcd ? ((~VGA_EN & sog & ~cs1) ? 1'b1 : 1'bZ) : 1'bZ;
`else
	assign SD_SPI_CS = 1'bZ;
`endif
assign SD_SPI_CLK  = 1'bZ;
assign SD_SPI_MOSI = 1'bZ;



reg [7:0] led_overtake = 0;
reg [7:0] led_state    = 0;

wire led_p =  led_power[1] ? ~led_power[0] : 1'b0;
wire led_d =  led_disk[1]  ? ~led_disk[0]  : ~(led_disk[0] | gp_out[29]);
wire led_u = ~led_user;
wire led_locked;

`ifndef DUAL_SDRAM
	assign LED_POWER = (SW[3] | led_p) ? 1'bZ : 1'b0;
	assign LED_HDD   = (SW[3] | led_d) ? 1'bZ : 1'b0;
	assign LED_USER  = (SW[3] | led_u) ? 1'bZ : 1'b0;
`endif


assign LED = (led_overtake & led_state) | (~led_overtake & {1'b0,led_locked,1'b0, ~led_p, 1'b0, ~led_d, 1'b0, ~led_u});

wire btn_r, btn_o, btn_u;
`ifdef DUAL_SDRAM
	assign {btn_r,btn_o,btn_u} = {mcp_btn[1],mcp_btn[2],mcp_btn[0]};
`else
	assign {btn_r,btn_o,btn_u} = ~{BTN_RESET,BTN_OSD,BTN_USER} | {mcp_btn[1],mcp_btn[2],mcp_btn[0]};
`endif

wire [2:0] mcp_btn;
wire       mcp_sdcd;
mcp23009 mcp23009
(
	.clk(FPGA_CLK2_50),

	.btn(mcp_btn),
	.led({led_p, led_d, led_u}),
	.sd_cd(mcp_sdcd),

	.scl(IO_SCL),
	.sda(IO_SDA)
);


reg btn_user, btn_osd;
always @(posedge FPGA_CLK2_50) begin
	integer div;
	reg [7:0] deb_user;
	reg [7:0] deb_osd;

	div <= div + 1'b1;
	if(div > 100000) div <= 0;

	if(!div) begin
		deb_user <= {deb_user[6:0], btn_u | ~KEY[1]};
		if(&deb_user) btn_user <= 1;
		if(!deb_user) btn_user <= 0;

		deb_osd <= {deb_osd[6:0], btn_o | ~KEY[0]};
		if(&deb_osd) btn_osd <= 1;
		if(!deb_osd) btn_osd <= 0;
	end
end






wire [31:0] gp_in = {1'b0, btn_user, btn_osd, SW[3], 8'd0, io_ver, io_ack, io_wide, io_dout};
wire [31:0] gp_out;

wire  [1:0] io_ver    = 1;
wire        io_wait;
wire        io_wide;
wire [15:0] io_dout;
wire [15:0] io_din    = gp_outr[15:0];
wire        io_clk    = gp_outr[17];
wire        io_ss0 = gp_outr[18];
wire        io_ss1 = gp_outr[19];
wire        io_ss2 = gp_outr[20];


`ifndef DEBUG_NOHDMI
wire io_osd_hdmi = io_ss1 & ~io_ss0;
`endif

wire io_fpga     = ~io_ss1 & io_ss0;
wire io_uio      = ~io_ss1 & io_ss2;

reg  io_ack;
reg  rack;
wire io_strobe = ~rack & io_clk;

always @(posedge clk_sys) begin
	if(~(io_wait | vs_wait) | io_strobe) begin
		rack <= io_clk;
		io_ack <= rack;
	end
end

reg [31:0] gp_outr;
always @(posedge clk_sys) begin
	reg [31:0] gp_outd;
	gp_outr <= gp_outd;
	gp_outd <= gp_out;
end

`ifdef DUAL_SDRAM
	wire  [7:0] core_type  = 'hA8;
`else
	wire  [7:0] core_type  = 'hA4;
`endif


wire [31:0] core_magic = {24'h5CA623, core_type};

cyclonev_hps_interface_mpu_general_purpose h2f_gp
(
	.gp_in({~gp_out[31] ? core_magic : gp_in}),
	.gp_out(gp_out)
);


reg [15:0] cfg;

reg        cfg_got      = 0;
reg        cfg_set      = 0;
wire [1:0] hdmi_limited = {cfg[11],cfg[8]};
`ifndef DEBUG_NOHDMI
wire       direct_video = cfg[10];
`else
wire       direct_video = 1;
`endif
wire       dvi_mode     = cfg[7];
wire       audio_96k    = cfg[6];
wire       csync_en     = cfg[3];
wire       ypbpr_en     = cfg[5];
wire       io_osd_vga   = io_ss1 & ~io_ss2;
`ifndef DUAL_SDRAM
	wire    sog          = cfg[9];
	wire    vga_scaler   = cfg[2];
`endif

reg        cfg_custom_t = 0;
reg  [5:0] cfg_custom_p1;
reg [31:0] cfg_custom_p2;

reg  [4:0] vol_att = 0;

reg  [6:0] coef_addr;
reg  [8:0] coef_data;
reg        coef_wr = 0;

wire [7:0] ARX, ARY;
reg [11:0] VSET = 0;
reg  [2:0] scaler_flt;
reg        lowlat = 0;
reg        cfg_dis = 0;

reg        vs_wait = 0;

always@(posedge clk_sys) begin
	reg  [7:0] cmd;
	reg        has_cmd;
	reg        old_strobe;
	reg  [7:0] cnt = 0;
	reg        vs_d0,vs_d1,vs_d2;

	old_strobe <= io_strobe;
	coef_wr <= 0;

	if(~io_uio) begin
		has_cmd <= 0;
		cmd <= 0;
	end
	else
	if(~old_strobe & io_strobe) begin
		if(!has_cmd) begin
			has_cmd <= 1;
			cmd <= io_din[7:0];
			cnt <= 0;
			if(io_din[7:0] == 'h30) vs_wait <= 1;
		end
		else begin
			if(cmd == 1) begin
				cfg <= io_din;
				cfg_set <= 1;
			end
			if(cmd == 'h20) begin
				cfg_set <= 0;
				cnt <= cnt + 1'd1;
				if(cnt<8) begin
					case(cnt[2:0])
						0: if(WIDTH  != io_din[11:0]) WIDTH  <= io_din[11:0];
						1: if(HFP    != io_din[11:0]) HFP    <= io_din[11:0];
						2: if(HS     != io_din[11:0]) HS     <= io_din[11:0];
						3: if(HBP    != io_din[11:0]) HBP    <= io_din[11:0];
						4: if(HEIGHT != io_din[11:0]) HEIGHT <= io_din[11:0];
						5: if(VFP    != io_din[11:0]) VFP    <= io_din[11:0];
						6: if(VS     != io_din[11:0]) VS     <= io_din[11:0];
						7: if(VBP    != io_din[11:0]) VBP    <= io_din[11:0];
					endcase
`ifndef DEBUG_NOHDMI
					if(cnt == 1) begin
						cfg_custom_p1 <= 0;
						cfg_custom_p2 <= 0;
						cfg_custom_t <= ~cfg_custom_t;
					end
				end
				else begin
					if(cnt[1:0]==0) cfg_custom_p1 <= io_din[5:0];
					if(cnt[1:0]==1) cfg_custom_p2[15:0]  <= io_din;
					if(cnt[1:0]==2) begin
						cfg_custom_p2[31:16] <= io_din;
						cfg_custom_t <= ~cfg_custom_t;
						cnt[2:0] <= 3'b100;
					end
					if(cnt == 8) {lowlat,cfg_dis} <= io_din[15:14];
`endif
				end
			end
			if(cmd == 'h2F) begin
				cnt <= cnt + 1'd1;
				case(cnt[3:0])
					0: {FB_EN,FB_FLT,FB_FMT} <= {io_din[15], io_din[14], io_din[5:0]};
					1: FB_BASE[15:0]  <= io_din[15:0];
					2: FB_BASE[31:16] <= io_din[15:0];
					3: FB_WIDTH       <= io_din[11:0];
					4: FB_HEIGHT      <= io_din[11:0];
					5: FB_HMIN        <= io_din[11:0];
					6: FB_HMAX        <= io_din[11:0];
					7: FB_VMIN        <= io_din[11:0];
					8: FB_VMAX        <= io_din[11:0];
				endcase
			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];
			if(cmd == 'h2A) {coef_wr,coef_addr,coef_data} <= {1'b1,io_din};
			if(cmd == 'h2B) scaler_flt <= io_din[2:0];
		end
	end

	vs_d0 <= HDMI_TX_VS;
	if(vs_d0 == HDMI_TX_VS) vs_d1 <= vs_d0;

	vs_d2 <= vs_d1;
	if(~vs_d2 & vs_d1) vs_wait <= 0;
end

always @(posedge clk_sys) begin
	reg vsd, vsd2;
	if(~cfg_ready || ~cfg_set) cfg_got <= cfg_set;
	else begin
		vsd  <= HDMI_TX_VS;
		vsd2 <= vsd;
		if(~vsd2 & vsd) cfg_got <= cfg_set;
	end
end

cyclonev_hps_interface_peripheral_uart uart
(
	.ri(0)
);

wire aspi_sck,aspi_mosi,aspi_ss;
cyclonev_hps_interface_peripheral_spi_master spi
(
	.sclk_out(aspi_sck),
	.txd(aspi_mosi),
	.rxd(1),

	.ss_0_n(aspi_ss),
	.ss_in_n(1)
);

wire [63:0] f2h_irq = {HDMI_TX_VS};
cyclonev_hps_interface_interrupts interrupts
(
	.irq(f2h_irq)
);



reg reset_req = 0;
always @(posedge FPGA_CLK2_50) begin
	reg [1:0] resetd, resetd2;
	reg       old_reset;


	old_reset <= reset;
	if(~old_reset & reset) reset_req <= 1;



	if(resetd==1) reset_req <= 1;
	if(resetd==2 && resetd2==0) reset_req <= 0;

	resetd  <= gp_out[31:30];
	resetd2 <= resetd;
end

wire clk_100m;
wire clk_hdmi  = hdmi_clk_out;
wire clk_audio = FPGA_CLK3_50;
wire clk_pal   = FPGA_CLK3_50;



wire reset;
sysmem_lite sysmem
(

	.reset_core_req(reset_req),
	.reset_out(reset),
	.clock(clk_100m),


	.reset_hps_cold_req(btn_r),

`ifdef USE_DDRAM

	.ram1_clk(ram_clk),
	.ram1_address(ram_address),
	.ram1_burstcount(ram_burstcount),
	.ram1_waitrequest(ram_waitrequest),
	.ram1_readdata(ram_readdata),
	.ram1_readdatavalid(ram_readdatavalid),
	.ram1_read(ram_read),
	.ram1_writedata(ram_writedata),
	.ram1_byteenable(ram_byteenable),
	.ram1_write(ram_write),
`endif


	.ram2_clk(clk_audio),
	.ram2_address((ap_en1 == ap_en2) ? aram_address : pram_address),
	.ram2_burstcount((ap_en1 == ap_en2) ? aram_burstcount : pram_burstcount),
	.ram2_waitrequest(aram_waitrequest),
	.ram2_readdata(aram_readdata),
	.ram2_readdatavalid(aram_readdatavalid),
	.ram2_read((ap_en1 == ap_en2) ? aram_read : pram_read),
	.ram2_writedata(0),
	.ram2_byteenable(8'hFF),
	.ram2_write(0),



	.vbuf_clk(clk_100m),
	.vbuf_address(vbuf_address),
	.vbuf_burstcount(vbuf_burstcount),
	.vbuf_waitrequest(vbuf_waitrequest),
	.vbuf_writedata(vbuf_writedata),
	.vbuf_byteenable(vbuf_byteenable),
	.vbuf_write(vbuf_write),
	.vbuf_readdata(vbuf_readdata),
	.vbuf_readdatavalid(vbuf_readdatavalid),
	.vbuf_read(vbuf_read)
);

wire  [27:0] vbuf_address;
wire   [7:0] vbuf_burstcount;
wire         vbuf_waitrequest;
wire [127:0] vbuf_readdata;
wire         vbuf_readdatavalid;
wire         vbuf_read;
wire [127:0] vbuf_writedata;
wire  [15:0] vbuf_byteenable;
wire         vbuf_write;

wire  [23:0] hdmi_data;
wire         hdmi_vs, hdmi_hs, hdmi_de;

ascal
#(
	.RAMBASE(32'h20000000),
	.N_DW(128),
	.N_AW(28)
)
ascal
(
	.reset_na (~reset_req),
	.run      (1),
	.freeze   (0),

	.i_clk    (clk_ihdmi),
	.i_ce     (ce_hpix),
	.i_r      (hr_out),
	.i_g      (hg_out),
	.i_b      (hb_out),
	.i_hs     (hhs_fix),
	.i_vs     (hvs_fix),
	.i_fl     (f1),
	.i_de     (hde_emu),
	.iauto    (1),
	.himin    (0),
	.himax    (0),
	.vimin    (0),
	.vimax    (0),

	.o_clk    (clk_hdmi),
	.o_ce     (1),
	.o_r      (hdmi_data[23:16]),
	.o_g      (hdmi_data[15:8]),
	.o_b      (hdmi_data[7:0]),
	.o_hs     (hdmi_hs),
	.o_vs     (hdmi_vs),
	.o_de     (hdmi_de),
	.o_lltune (lltune),
	.htotal   (WIDTH + HFP + HBP + HS),
	.hsstart  (WIDTH + HFP),
	.hsend    (WIDTH + HFP + HS),
	.hdisp    (WIDTH),
	.hmin     (hmin),
	.hmax     (hmax),
	.vtotal   (HEIGHT + VFP + VBP + VS),
	.vsstart  (HEIGHT + VFP),
	.vsend    (HEIGHT + VFP + VS),
	.vdisp    (HEIGHT),
	.vmin     (vmin),
	.vmax     (vmax),

	.mode     ({~lowlat,FB_EN ? FB_FLT : |scaler_flt,2'b00}),
	.poly_clk (clk_sys),
	.poly_a   (coef_addr),
	.poly_dw  (coef_data),
	.poly_wr  (coef_wr),

	.pal_clk  (clk_pal),
	.pal_dw   (pal_d),
	.pal_a    (pal_a),
	.pal_wr   (pal_wr),

	.o_fb_ena         (FB_EN),
	.o_fb_hsize       (FB_WIDTH),
	.o_fb_vsize       (FB_HEIGHT),
	.o_fb_format      (FB_FMT),
	.o_fb_base        (FB_BASE),

	.avl_clk          (clk_100m),
	.avl_waitrequest  (vbuf_waitrequest),
	.avl_readdata     (vbuf_readdata),
	.avl_readdatavalid(vbuf_readdatavalid),
	.avl_burstcount   (vbuf_burstcount),
	.avl_writedata    (vbuf_writedata),
	.avl_address      (vbuf_address),
	.avl_write        (vbuf_write),
	.avl_read         (vbuf_read),
	.avl_byteenable   (vbuf_byteenable)
);

reg        FB_EN     = 0;
reg        FB_FLT    = 0;
reg  [5:0] FB_FMT    = 0;
reg [11:0] FB_WIDTH  = 0;
reg [11:0] FB_HEIGHT = 0;
reg [11:0] FB_HMIN   = 0;
reg [11:0] FB_HMAX   = 0;
reg [11:0] FB_VMIN   = 0;
reg [11:0] FB_VMAX   = 0;
reg [31:0] FB_BASE   = 0;

reg [11:0] hmin;
reg [11:0] hmax;
reg [11:0] vmin;
reg [11:0] vmax;

always @(posedge clk_vid) begin
	reg [31:0] wcalc;
	reg [31:0] hcalc;
	reg  [2:0] state;
	reg [11:0] videow;
	reg [11:0] videoh;

	state <= state + 1'd1;
	case(state)
		0: if(FB_EN) begin
				hmin <= FB_HMIN;
				vmin <= FB_VMIN;
				hmax <= FB_HMAX;
				vmax <= FB_VMAX;
				state<= 0;
			end
			else if(ARX && ARY) begin
				wcalc <= VSET ? (VSET*ARX)/ARY : (HEIGHT*ARX)/ARY;
				hcalc <= (WIDTH*ARY)/ARX;
			end
			else begin
				hmin <= 0;
				hmax <= WIDTH - 1'd1;
				vmin <= 0;
				vmax <= HEIGHT - 1'd1;
				wcalc<= WIDTH;
				hcalc<= HEIGHT;
				state<= 0;
			end
		6: begin
				videow <= (!VSET && (wcalc > WIDTH))     ? WIDTH  : wcalc[11:0];
				videoh <= VSET ? VSET : (hcalc > HEIGHT) ? HEIGHT : hcalc[11:0];
			end
		7: begin
				hmin <= ((WIDTH  - videow)>>1);
				hmax <= ((WIDTH  - videow)>>1) + videow - 1'd1;
				vmin <= ((HEIGHT - videoh)>>1);
				vmax <= ((HEIGHT - videoh)>>1) + videoh - 1'd1;
			end
	endcase
end

`ifndef DEBUG_NOHDMI
wire [15:0] lltune;

pll_hdmi_adj pll_hdmi_adj
(
   .clk(FPGA_CLK1_50),
	.reset_na(~reset_req),

	.llena(lowlat),
	.lltune({16{hdmi_config_done | cfg_dis}} & lltune),
	.locked(led_locked),
	.i_waitrequest(adj_waitrequest),
	.i_write(adj_write),
	.i_address(adj_address),
	.i_writedata(adj_data),
	.o_waitrequest(cfg_waitrequest),
	.o_write(cfg_write),
	.o_address(cfg_address),
	.o_writedata(cfg_data)
);
`else
assign led_locked=0;
`endif

wire [23:0] pal_d;
wire  [7:0] pal_a;
wire        pal_wr;

wire ap_en1, ap_en2;

wire [28:0] pram_address;
wire  [7:0] pram_burstcount;
wire        pram_read;

fbpal fbpal
(
	.reset(reset),
	.en_in(ap_en2),
	.en_out(ap_en1),

	.ram_clk(clk_pal),
	.ram_address(pram_address),
	.ram_burstcount(pram_burstcount),
	.ram_waitrequest(aram_waitrequest),
	.ram_readdata(aram_readdata),
	.ram_readdatavalid(aram_readdatavalid),
	.ram_read(pram_read),

	.fb_address(FB_BASE),

	.pal_en(~FB_FMT[2] & FB_FMT[1] & FB_FMT[0] & FB_EN),
	.pal_a(pal_a),
	.pal_d(pal_d),
	.pal_wr(pal_wr)
);



`ifndef DEBUG_NOHDMI
wire hdmi_clk_out;
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_clk_out)
);
`else
assign hdmi_clk_out=0;
`endif

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    = 36;

wire [63:0] reconfig_to_pll;
wire [63:0] reconfig_from_pll;
wire        cfg_waitrequest,adj_waitrequest;
wire        cfg_write;
wire  [5:0] cfg_address;
wire [31:0] cfg_data;
reg         adj_write;
reg   [5:0] adj_address;
reg  [31:0] adj_data;
`ifndef DEBUG_NOHDMI
pll_cfg pll_cfg
(
	.mgmt_clk(FPGA_CLK1_50),
	.mgmt_reset(reset_req),
	.mgmt_waitrequest(cfg_waitrequest),
	.mgmt_read(0),
	.mgmt_readdata(),
	.mgmt_write(cfg_write),
	.mgmt_address(cfg_address),
	.mgmt_writedata(cfg_data),
	.reconfig_to_pll(reconfig_to_pll),
	.reconfig_from_pll(reconfig_from_pll)
);

reg cfg_ready = 0;

always @(posedge FPGA_CLK1_50) begin
	reg gotd = 0, gotd2 = 0;
	reg custd = 0, custd2 = 0;
	reg old_wait = 0;

	gotd  <= cfg_got;
	gotd2 <= gotd;

	adj_write <= 0;

	custd <= cfg_custom_t;
	custd2 <= custd;
	if(custd2 != custd & ~gotd) begin
		adj_address <= cfg_custom_p1;
		adj_data <= cfg_custom_p2;
		adj_write <= 1;
	end

	if(~gotd2 & gotd) begin
		adj_address <= 2;
		adj_data <= 0;
		adj_write <= 1;
	end

	old_wait <= adj_waitrequest;
	if(old_wait & ~adj_waitrequest & gotd) cfg_ready <= 1;
end
`else
wire cfg_ready=1;
`endif

wire hdmi_config_done;
hdmi_config hdmi_config
(
	.iCLK(FPGA_CLK1_50),
	.iRST_N(cfg_ready & ~HDMI_TX_INT & ~cfg_dis),
	.done(hdmi_config_done),

	.I2C_SCL(HDMI_I2C_SCL),
	.I2C_SDA(HDMI_I2C_SDA),

	.dvi_mode(dvi_mode),
	.audio_96k(audio_96k),
	.limited(hdmi_limited),
	.ypbpr(ypbpr_en & direct_video)
);

`ifndef DEBUG_NOHDMI
wire [23:0] hdmi_data_sl;
wire        hdmi_de_sl, hdmi_vs_sl, hdmi_hs_sl;
scanlines #(1) HDMI_scanlines
(
	.clk(clk_hdmi),

	.scanlines(scanlines),
	.din(hdmi_data),
	.hs_in(hdmi_hs),
	.vs_in(hdmi_vs),
	.de_in(hdmi_de),

	.dout(hdmi_data_sl),
	.hs_out(hdmi_hs_sl),
	.vs_out(hdmi_vs_sl),
	.de_out(hdmi_de_sl)
);

wire [23:0] hdmi_data_osd;
wire        hdmi_de_osd, hdmi_vs_osd, hdmi_hs_osd;
osd hdmi_osd
(
	.clk_sys(clk_sys),

	.io_osd(io_osd_hdmi),
	.io_strobe(io_strobe),
	.io_din(io_din),

	.clk_video(clk_hdmi),
	.din(hdmi_data_sl),
	.hs_in(hdmi_hs_sl),
	.vs_in(hdmi_vs_sl),
	.de_in(hdmi_de_sl),

	.dout(hdmi_data_osd),
	.hs_out(hdmi_hs_osd),
	.vs_out(hdmi_vs_osd),
	.de_out(hdmi_de_osd)
);
`endif

reg [23:0] dv_data;
reg        dv_hs, dv_vs, dv_de;
always @(posedge 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) | vga_hs_osd;

		old_hs <= vga_hs_osd;
		if(~old_hs && vga_hs_osd) begin
			old_vs <= vga_vs_osd;
			if(~&vcnt) vcnt <= vcnt + 1'd1;
			if(~old_vs & vga_vs_osd & ~f1) vsz <= vcnt;
			if(old_vs & ~vga_vs_osd) vcnt <= 0;

			if(vcnt == 1) vde <= 1;
			if(vcnt == vsz - 3) vde <= 0;
		end

		dv_de1 <= !{hss,vga_hs_osd} && vde;
		dv_hs1 <= csync_en ? vga_cs_osd : vga_hs_osd;
		dv_vs1 <= vga_vs_osd;
	end

	dv_d1  <= vga_data_osd;
	dv_d2  <= dv_d1;
	dv_de2 <= dv_de1;
	dv_hs2 <= dv_hs1;
	dv_vs2 <= dv_vs1;

	dv_data<= dv_d2;
	dv_de  <= dv_de2;
	dv_hs  <= dv_hs2;
	dv_vs  <= dv_vs2;
end

wire hdmi_tx_clk;
`ifndef DEBUG_NOHDMI
cyclonev_clkselect hdmi_clk_sw
(
	.clkselect({1'b1, direct_video}),
	.inclk({clk_vid, hdmi_clk_out, 2'b00}),
	.outclk(hdmi_tx_clk)
);
`else
assign hdmi_tx_clk = clk_vid;
`endif

altddio_out
#(
	.extend_oe_disable("OFF"),
	.intended_device_family("Cyclone V"),
	.invert_output("OFF"),
	.lpm_hint("UNUSED"),
	.lpm_type("altddio_out"),
	.oe_reg("UNREGISTERED"),
	.power_up_high("OFF"),
	.width(1)
)
hdmiclk_ddr
(
	.datain_h(1'b0),
	.datain_l(1'b1),
	.outclock(hdmi_tx_clk),
	.dataout(HDMI_TX_CLK),
	.aclr(1'b0),
	.aset(1'b0),
	.oe(1'b1),
	.outclocken(1'b1),
	.sclr(1'b0),
	.sset(1'b0)
);

reg hdmi_out_hs;
reg hdmi_out_vs;
reg hdmi_out_de;
reg [23:0] hdmi_out_d;

always @(posedge hdmi_tx_clk) begin
	reg hs,vs,de;
	reg [23:0] d;

	hs <= direct_video ? dv_hs   : hdmi_hs_osd;
	vs <= direct_video ? dv_vs   : hdmi_vs_osd;
	de <= direct_video ? dv_de   : hdmi_de_osd;
	d  <= direct_video ? dv_data : hdmi_data_osd;

	hdmi_out_hs <= hs;
	hdmi_out_vs <= vs;
	hdmi_out_de <= de;
	hdmi_out_d  <= d;
end

assign HDMI_TX_HS = hdmi_out_hs;
assign HDMI_TX_VS = hdmi_out_vs;
assign HDMI_TX_DE = hdmi_out_de;
assign HDMI_TX_D  = hdmi_out_d;



wire [23:0] vga_data_sl;
wire        vga_de_sl, vga_vs_sl, vga_hs_sl;
scanlines #(0) VGA_scanlines
(
	.clk(clk_vid),

	.scanlines(scanlines),
	.din(de_emu ? {r_out, g_out, b_out} : 24'd0),
	.hs_in(hs_fix),
	.vs_in(vs_fix),
	.de_in(de_emu),

	.dout(vga_data_sl),
	.hs_out(vga_hs_sl),
	.vs_out(vga_vs_sl),
	.de_out(vga_de_sl)
);

wire [23:0] vga_data_osd;
wire        vga_vs_osd, vga_hs_osd;
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),
	.hs_in(vga_hs_sl),
	.vs_in(vga_vs_sl),
	.de_in(vga_de_sl),

	.dout(vga_data_osd),
	.hs_out(vga_hs_osd),
	.vs_out(vga_vs_osd)
);

wire vga_cs_osd;
csync csync_vga(clk_vid, vga_hs_osd, vga_vs_osd, vga_cs_osd);

`ifndef DUAL_SDRAM
	wire [23:0] vga_o;
	vga_out vga_out
	(
		.ypbpr_full(0),
		.ypbpr_en(ypbpr_en),
		.dout(vga_o),
		.din(vga_scaler ? {24{hdmi_de_osd}} & hdmi_data_osd : vga_data_osd)
	);

	wire hdmi_cs_osd;
	csync csync_hdmi(clk_hdmi, hdmi_hs_osd, hdmi_vs_osd, hdmi_cs_osd);

	wire vs1 = vga_scaler ? hdmi_vs_osd : vga_vs_osd;
	wire hs1 = vga_scaler ? hdmi_hs_osd : vga_hs_osd;
	wire cs1 = vga_scaler ? hdmi_cs_osd : vga_cs_osd;

	assign VGA_VS = (VGA_EN | SW[3]) ? 1'bZ      : csync_en ? 1'b1 : ~vs1;
	assign VGA_HS = (VGA_EN | SW[3]) ? 1'bZ      : csync_en ? ~cs1 : ~hs1;
	assign VGA_R  = (VGA_EN | SW[3]) ? 6'bZZZZZZ : vga_o[23:18];
	assign VGA_G  = (VGA_EN | SW[3]) ? 6'bZZZZZZ : vga_o[15:10];
	assign VGA_B  = (VGA_EN | SW[3]) ? 6'bZZZZZZ : vga_o[7:2];
`endif



assign SDCD_SPDIF =(SW[3] & ~spdif) ? 1'b0 : 1'bZ;

`ifndef DUAL_SDRAM
	wire anl,anr;

	assign AUDIO_SPDIF = SW[3] ? 1'bZ : SW[0] ? HDMI_LRCLK : spdif;
	assign AUDIO_R     = SW[3] ? 1'bZ : SW[0] ? HDMI_I2S   : anr;
	assign AUDIO_L     = SW[3] ? 1'bZ : SW[0] ? HDMI_SCLK  : anl;
`endif

assign HDMI_MCLK = 0;

wire [15:0] audio_l, audio_l_pre;
aud_mix_top audmix_l
(
	.clk(clk_audio),
	.att(vol_att),
	.mix(audio_mix),
	.is_signed(audio_s),

	.core_audio(audio_ls),
	.pre_in(audio_r_pre),
	.linux_audio(alsa_l),

	.pre_out(audio_l_pre),
	.out(audio_l)
);

wire [15:0] audio_r, audio_r_pre;
aud_mix_top audmix_r
(
	.clk(clk_audio),
	.att(vol_att),
	.mix(audio_mix),
	.is_signed(audio_s),

	.core_audio(audio_rs),
	.pre_in(audio_l_pre),
	.linux_audio(alsa_r),

	.pre_out(audio_r_pre),
	.out(audio_r)
);

wire spdif;
audio_out audio_out
(
	.reset(reset),
	.clk(clk_audio),
	.sample_rate(audio_96k),
	.left_in(audio_l),
	.right_in(audio_r),
	.i2s_bclk(HDMI_SCLK),
	.i2s_lrclk(HDMI_LRCLK),
	.i2s_data(HDMI_I2S),
`ifndef DUAL_SDRAM
	.dac_l(anl),
	.dac_r(anr),
`endif
	.spdif(spdif)
);

wire [28:0] aram_address;
wire  [7:0] aram_burstcount;
wire        aram_waitrequest;
wire [63:0] aram_readdata;
wire        aram_readdatavalid;
wire        aram_read;

wire [15:0] alsa_l, alsa_r;

alsa alsa
(
	.reset(reset),
	.en_in(ap_en1),
	.en_out(ap_en2),

	.ram_clk(clk_audio),
	.ram_address(aram_address),
	.ram_burstcount(aram_burstcount),
	.ram_waitrequest(aram_waitrequest),
	.ram_readdata(aram_readdata),
	.ram_readdatavalid(aram_readdatavalid),
	.ram_read(aram_read),

	.spi_ss(aspi_ss),
	.spi_sck(aspi_sck),
	.spi_mosi(aspi_mosi),

	.pcm_l(alsa_l),
	.pcm_r(alsa_r)
);




assign USER_IO[0] =                       !user_out[0]  ? 1'b0 : 1'bZ;
assign USER_IO[1] =                       !user_out[1]  ? 1'b0 : 1'bZ;
assign USER_IO[2] = !(SW[1] ? HDMI_I2S   : user_out[2]) ? 1'b0 : 1'bZ;
assign USER_IO[3] =                       !user_out[3]  ? 1'b0 : 1'bZ;
assign USER_IO[4] = !(SW[1] ? HDMI_SCLK  : user_out[4]) ? 1'b0 : 1'bZ;
assign USER_IO[5] = !(SW[1] ? HDMI_LRCLK : user_out[5]) ? 1'b0 : 1'bZ;
assign USER_IO[6] =                       !user_out[6]  ? 1'b0 : 1'bZ;

assign user_in[0] =         USER_IO[0];
assign user_in[1] =         USER_IO[1];
assign user_in[2] = SW[1] | USER_IO[2];
assign user_in[3] =         USER_IO[3];
assign user_in[4] = SW[1] | USER_IO[4];
assign user_in[5] = SW[1] | USER_IO[5];
assign user_in[6] =         USER_IO[6];




wire [15:0] audio_ls, audio_rs;
wire        audio_s;
wire  [1:0] audio_mix;
wire  [7:0] r_out, g_out, b_out;
wire        vs_fix, hs_fix, de_emu, vs_emu, hs_emu, f1;
wire  [1:0] scanlines;
wire        clk_sys, clk_vid, ce_pix;
wire  [7:0] hr_out, hg_out, hb_out;
wire        hvs_fix, hhs_fix, hde_emu, hvs_emu, hhs_emu;
wire        clk_ihdmi, ce_hpix;

`ifdef USE_DDRAM
wire        ram_clk;
wire [28:0] ram_address;
wire [7:0]  ram_burstcount;
wire        ram_waitrequest;
wire [63:0] ram_readdata;
wire        ram_readdatavalid;
wire        ram_read;
wire [63:0] ram_writedata;
wire [7:0]  ram_byteenable;
wire        ram_write;
`endif

wire        led_user;
wire  [1:0] led_power;
wire  [1:0] led_disk;

sync_fix hdmi_sync_v(clk_ihdmi, hvs_emu, hvs_fix);
sync_fix hdmi_sync_h(clk_ihdmi, hhs_emu, hhs_fix);
sync_fix sync_v(clk_vid, vs_emu, vs_fix);
sync_fix sync_h(clk_vid, hs_emu, hs_fix);

assign audio_mix = 0;
assign {ADC_SCK, ADC_SDI, ADC_CONVST} = 0;
wire  [6:0] user_out, user_in;

`ifndef USE_SDRAM
assign {SDRAM_DQ, SDRAM_A, SDRAM_BA, SDRAM_CLK, SDRAM_CKE, SDRAM_DQML, SDRAM_DQMH, SDRAM_nWE, SDRAM_nCAS, SDRAM_nRAS, SDRAM_nCS} = {39'bZ};
`endif

emu emu
(
	.CLK_50M(FPGA_CLK2_50),
	.RESET(reset),
	.HPS_BUS({f1, HDMI_TX_VS, clk_100m, clk_ihdmi, ce_hpix, hde_emu, hhs_fix, hvs_fix, io_wait, clk_sys, io_fpga, io_uio, io_strobe, io_wide, io_din, io_dout}),

	.VGA_CLK(clk_vid),
	.VGA_CE(ce_pix),
	.VGA_R(r_out),
	.VGA_G(g_out),
	.VGA_B(b_out),
	.VGA_HS(hs_emu),
	.VGA_VS(vs_emu),
	.VGA_DE(de_emu),
	.VGA_F1(f1),

	.HDMI_CLK(clk_ihdmi),
	.HDMI_CE(ce_hpix),
	.HDMI_R(hr_out),
	.HDMI_G(hg_out),
	.HDMI_B(hb_out),
	.HDMI_HS(hhs_emu),
	.HDMI_VS(hvs_emu),
	.HDMI_DE(hde_emu),
	.HDMI_SL(scanlines),
	.HDMI_ARX(ARX),
	.HDMI_ARY(ARY),

	.LED_USER(led_user),
	.LED_POWER(led_power),
	.LED_DISK(led_disk),

	.AUDIO_L(audio_ls),
	.AUDIO_R(audio_rs),
	.AUDIO_S(audio_s),

`ifdef USE_DDRAM
	.DDRAM_CLK(ram_clk),
	.DDRAM_ADDR(ram_address),
	.DDRAM_BURSTCNT(ram_burstcount),
	.DDRAM_BUSY(ram_waitrequest),
	.DDRAM_DOUT(ram_readdata),
	.DDRAM_DOUT_READY(ram_readdatavalid),
	.DDRAM_RD(ram_read),
	.DDRAM_DIN(ram_writedata),
	.DDRAM_BE(ram_byteenable),
	.DDRAM_WE(ram_write),
`endif

`ifdef USE_SDRAM
	.SDRAM_DQ(SDRAM_DQ),
	.SDRAM_A(SDRAM_A),
	.SDRAM_DQML(SDRAM_DQML),
	.SDRAM_DQMH(SDRAM_DQMH),
	.SDRAM_BA(SDRAM_BA),
	.SDRAM_nCS(SDRAM_nCS),
	.SDRAM_nWE(SDRAM_nWE),
	.SDRAM_nRAS(SDRAM_nRAS),
	.SDRAM_nCAS(SDRAM_nCAS),
	.SDRAM_CLK(SDRAM_CLK),
	.SDRAM_CKE(SDRAM_CKE),
`endif

`ifdef DUAL_SDRAM
	.SDRAM2_DQ(SDRAM2_DQ),
	.SDRAM2_A(SDRAM2_A),
	.SDRAM2_BA(SDRAM2_BA),
	.SDRAM2_nCS(SDRAM2_nCS),
	.SDRAM2_nWE(SDRAM2_nWE),
	.SDRAM2_nRAS(SDRAM2_nRAS),
	.SDRAM2_nCAS(SDRAM2_nCAS),
	.SDRAM2_CLK(SDRAM2_CLK),
	.SDRAM2_EN(SW[3]),
`endif

	.USER_OUT(user_out),
	.USER_IN(user_in)
);

endmodule