mirror of
https://github.com/MiSTer-devel/Genesis_MiSTer.git
synced 2026-05-17 03:03:45 +00:00
Update scaler.
This commit is contained in:
1104
sys/ascal.vhd
1104
sys/ascal.vhd
File diff suppressed because it is too large
Load Diff
239
sys/pll_hdmi_adj.vhd
Normal file
239
sys/pll_hdmi_adj.vhd
Normal file
@@ -0,0 +1,239 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- HDMI PLL Adjust
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
-- Changes the HDMI PLL frequency according to the scaler suggestions.
|
||||
--------------------------------------------
|
||||
-- LLTUNE :
|
||||
-- 15 : Toggle
|
||||
-- 14 : Unused
|
||||
-- 13 : Sign phase difference
|
||||
-- 12:8 : Phase difference. Log (0=Large 31=Small)
|
||||
-- 7:6 : Unused
|
||||
-- 5 : Sign period difference.
|
||||
-- 4:0 : Period difference. Log (0=Large 31=Small)
|
||||
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
|
||||
ENTITY pll_hdmi_adj IS
|
||||
PORT (
|
||||
-- Scaler
|
||||
llena : IN std_logic; -- 0=Disabled 1=Enabled
|
||||
lltune : IN unsigned(15 DOWNTO 0); -- Outputs from scaler
|
||||
|
||||
-- Signals from reconfig commands
|
||||
i_waitrequest : OUT std_logic;
|
||||
i_write : IN std_logic;
|
||||
i_address : IN unsigned(5 DOWNTO 0);
|
||||
i_writedata : IN unsigned(31 DOWNTO 0);
|
||||
|
||||
-- Outputs to PLL_HDMI_CFG
|
||||
o_waitrequest : IN std_logic;
|
||||
o_write : OUT std_logic;
|
||||
o_address : OUT unsigned(5 DOWNTO 0);
|
||||
o_writedata : OUT unsigned(31 DOWNTO 0);
|
||||
|
||||
------------------------------------
|
||||
clk : IN std_logic;
|
||||
reset_na : IN std_logic
|
||||
);
|
||||
|
||||
BEGIN
|
||||
|
||||
|
||||
END ENTITY pll_hdmi_adj;
|
||||
|
||||
--##############################################################################
|
||||
|
||||
ARCHITECTURE rtl OF pll_hdmi_adj IS
|
||||
SIGNAL pwrite : std_logic;
|
||||
SIGNAL paddress : unsigned(5 DOWNTO 0);
|
||||
SIGNAL pdata : unsigned(31 DOWNTO 0);
|
||||
TYPE enum_state IS (sIDLE,sW1,sW2,sW3);
|
||||
SIGNAL state : enum_state;
|
||||
SIGNAL lltune_sync,lltune_sync2,lltune_sync3 : unsigned(15 DOWNTO 0);
|
||||
SIGNAL mfrac,mfrac_mem : unsigned(31 DOWNTO 0);
|
||||
SIGNAL sign,sign_pre : std_logic;
|
||||
SIGNAL up,modo,phm,dir : std_logic;
|
||||
SIGNAL fcpt : natural RANGE 0 TO 3;
|
||||
SIGNAL cptx : natural RANGE 0 TO 3;
|
||||
SIGNAL cpt : natural RANGE 0 TO 4095;
|
||||
SIGNAL phcor : natural RANGE 0 TO 3;
|
||||
SIGNAL diff : unsigned(31 DOWNTO 0);
|
||||
|
||||
TYPE enum_tstate IS (sWAIT,sADJ,sADJ2);
|
||||
SIGNAL tstate : enum_tstate;
|
||||
BEGIN
|
||||
----------------------------------------------------------------------------
|
||||
-- 000010 : Start reg "Write either 0 or 1 to start fractional PLL reconf.
|
||||
-- 000111 : M counter Fractional Value
|
||||
|
||||
Comb:PROCESS(i_write,i_address,
|
||||
i_writedata,pwrite,paddress,pdata) IS
|
||||
BEGIN
|
||||
IF i_write='1' THEN
|
||||
o_write <=i_write;
|
||||
o_address <=i_address;
|
||||
o_writedata <=i_writedata;
|
||||
ELSE
|
||||
o_write <=pwrite;
|
||||
o_address <=paddress;
|
||||
o_writedata<=pdata;
|
||||
END IF;
|
||||
END PROCESS Comb;
|
||||
|
||||
i_waitrequest<=o_waitrequest WHEN state=sIDLE ELSE '0';
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Schmurtz:PROCESS(clk,reset_na) IS
|
||||
VARIABLE off,ofp : natural RANGE 0 TO 63;
|
||||
VARIABLE dif : unsigned(31 DOWNTO 0);
|
||||
BEGIN
|
||||
IF reset_na='0' THEN
|
||||
modo<='0';
|
||||
state<=sIDLE;
|
||||
ELSIF rising_edge(clk) THEN
|
||||
IF i_address="000111" AND i_write='1' THEN
|
||||
mfrac<=i_writedata;
|
||||
mfrac_mem<=i_writedata;
|
||||
modo<='1';
|
||||
END IF;
|
||||
|
||||
lltune_sync<=lltune; -- <ASYNC>
|
||||
lltune_sync2<=lltune_sync;
|
||||
lltune_sync3<=lltune_sync2;
|
||||
|
||||
off:=to_integer('0' & lltune_sync(4 DOWNTO 0));
|
||||
ofp:=to_integer('0' & lltune_sync(12 DOWNTO 8));
|
||||
|
||||
IF lltune_sync(15)/=lltune_sync2(15) THEN
|
||||
fcpt<=fcpt+1;
|
||||
IF fcpt=2 THEN fcpt<=0; END IF;
|
||||
END IF;
|
||||
|
||||
CASE tstate IS
|
||||
WHEN sWAIT =>
|
||||
cpt<=0;
|
||||
IF lltune_sync3(15)/=lltune_sync2(15) AND llena='1' THEN
|
||||
|
||||
IF llena='0' THEN
|
||||
-- Recover original freq when disabling low lag mode
|
||||
phm<='0';
|
||||
IF modo='1' THEN
|
||||
mfrac<=mfrac_mem;
|
||||
up<='1';
|
||||
modo<='0';
|
||||
END IF;
|
||||
|
||||
ELSIF phm='0' AND fcpt=2 THEN
|
||||
-- Frequency adjust
|
||||
IF off<10 THEN off:=10; END IF;
|
||||
dif:=shift_right(mfrac,off + 1);
|
||||
diff<=dif;
|
||||
sign<=lltune_sync(5);
|
||||
IF off>=18 THEN
|
||||
phm<='1';
|
||||
ELSE
|
||||
tstate<=sADJ;
|
||||
END IF;
|
||||
cptx<=0;
|
||||
|
||||
ELSIF phm='1' THEN
|
||||
-- Phase adjust
|
||||
IF ofp<5 THEN ofp:=5; END IF;
|
||||
dif:=shift_right(mfrac,ofp + 3 + 1);
|
||||
IF (ofp>=18 OR off<16) AND fcpt=2 AND phcor=0 THEN
|
||||
phm<='0';
|
||||
END IF;
|
||||
IF phcor=0 THEN
|
||||
IF cptx=0 THEN
|
||||
sign<=NOT lltune_sync(13);
|
||||
sign_pre<=sign;
|
||||
diff<=dif;
|
||||
IF sign_pre/=NOT lltune_sync(13) THEN
|
||||
diff<='0' & dif(31 DOWNTO 1);
|
||||
END IF;
|
||||
END IF;
|
||||
cptx<=cptx+1;
|
||||
IF cptx=2 THEN
|
||||
cptx<=0;
|
||||
sign<=NOT sign;
|
||||
phcor<=1;
|
||||
END IF;
|
||||
tstate<=sADJ;
|
||||
ELSIF phcor=1 THEN
|
||||
cptx<=cptx+1;
|
||||
IF cptx=2 THEN
|
||||
cptx<=0;
|
||||
phcor<=2;
|
||||
tstate<=sADJ;
|
||||
END IF;
|
||||
ELSIF fcpt=2 THEN
|
||||
phcor<=0;
|
||||
cptx<=0;
|
||||
END IF;
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
WHEN sADJ =>
|
||||
IF sign='0' THEN
|
||||
mfrac<=mfrac + diff(31 DOWNTO 8);
|
||||
ELSE
|
||||
mfrac<=mfrac - diff(31 DOWNTO 8);
|
||||
END IF;
|
||||
IF up='0' THEN
|
||||
up<='1';
|
||||
tstate<=sADJ2;
|
||||
END IF;
|
||||
|
||||
WHEN sADJ2 =>
|
||||
cpt<=cpt+1;
|
||||
IF cpt=1023 THEN
|
||||
tstate<=sWAIT;
|
||||
ELSE
|
||||
tstate<=sADJ;
|
||||
END IF;
|
||||
|
||||
END CASE;
|
||||
|
||||
------------------------------------------------------
|
||||
CASE state IS
|
||||
WHEN sIDLE =>
|
||||
pwrite<='0';
|
||||
IF up='1' THEN
|
||||
up<='0';
|
||||
state<=sW1;
|
||||
pdata<=mfrac;
|
||||
paddress<="000111";
|
||||
pwrite<='1';
|
||||
END IF;
|
||||
|
||||
WHEN sW1 =>
|
||||
IF pwrite='1' AND o_waitrequest='0' THEN
|
||||
state<=sW2;
|
||||
pwrite<='0';
|
||||
END IF;
|
||||
|
||||
WHEN sW2 =>
|
||||
pdata<=x"0000_0001";
|
||||
paddress<="000010";
|
||||
pwrite<='1';
|
||||
state<=sW3;
|
||||
|
||||
WHEN sW3 =>
|
||||
IF pwrite='1' AND o_waitrequest='0' THEN
|
||||
pwrite<='0';
|
||||
state<=sIDLE;
|
||||
END IF;
|
||||
END CASE;
|
||||
|
||||
END IF;
|
||||
END PROCESS Schmurtz;
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
|
||||
END ARCHITECTURE rtl;
|
||||
|
||||
@@ -4,6 +4,7 @@ set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) p
|
||||
set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_hdmi.qip ]
|
||||
set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_hdmi_cfg.qip ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ascal.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) pll_hdmi_adj.vhd ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hq2x.sv ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scandoubler.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scanlines.v ]
|
||||
|
||||
@@ -8,6 +8,7 @@ set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) p
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll_hdmi_cfg/altera_pll_reconfig_core.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll_hdmi_cfg/altera_pll_reconfig_top.v ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ascal.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) pll_hdmi_adj.vhd ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hq2x.sv ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scandoubler.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scanlines.v ]
|
||||
|
||||
@@ -216,6 +216,7 @@ reg coef_set = 0;
|
||||
wire [7:0] ARX, ARY;
|
||||
reg [11:0] VSET = 0;
|
||||
reg [2:0] scaler_flt;
|
||||
reg lowlat = 0;
|
||||
|
||||
always@(posedge clk_sys) begin
|
||||
reg [7:0] cmd;
|
||||
@@ -273,8 +274,9 @@ always@(posedge clk_sys) begin
|
||||
if(cnt[1:0]==2) begin
|
||||
cfg_custom_p2[31:16] <= io_din;
|
||||
cfg_custom_t <= ~cfg_custom_t;
|
||||
cnt[1:0] <= 0;
|
||||
cnt[2:0] <= 3'b100;
|
||||
end
|
||||
if(cnt == 8) lowlat <= io_din[15];
|
||||
end
|
||||
end
|
||||
if(cmd == 'h25) {led_overtake, led_state} <= io_din;
|
||||
@@ -434,6 +436,12 @@ vip_config vip_config
|
||||
.writedata(ctl_writedata),
|
||||
.waitrequest(ctl_waitrequest)
|
||||
);
|
||||
|
||||
assign cfg_write = adj_write;
|
||||
assign cfg_address = adj_address;
|
||||
assign cfg_data = adj_data;
|
||||
assign adj_waitrequest = cfg_waitrequest;
|
||||
|
||||
`endif
|
||||
|
||||
|
||||
@@ -523,6 +531,7 @@ ascal
|
||||
(
|
||||
.reset_na (~reset_req),
|
||||
.run (1),
|
||||
.freeze (0),
|
||||
|
||||
.i_clk (clk_vid),
|
||||
.i_ce (ce_pix),
|
||||
@@ -560,7 +569,7 @@ ascal
|
||||
.vmin (vmin),
|
||||
.vmax (vmax),
|
||||
|
||||
.mode ({1'b1,scaler_flt ? 3'd6 : 3'd0}),
|
||||
.mode ({~lowlat,|scaler_flt,2'b00}),
|
||||
.poly_clk (clk_sys),
|
||||
.poly_a (coef_addr),
|
||||
.poly_dw (coef_data),
|
||||
@@ -609,6 +618,23 @@ always @(posedge clk_vid) begin
|
||||
endcase
|
||||
end
|
||||
|
||||
pll_hdmi_adj pll_hdmi_adj
|
||||
(
|
||||
.clk(FPGA_CLK1_50),
|
||||
.reset_na(~reset_req),
|
||||
|
||||
.llena(lowlat),
|
||||
.lltune(lltune),
|
||||
.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)
|
||||
);
|
||||
|
||||
`endif
|
||||
|
||||
|
||||
@@ -635,10 +661,10 @@ reg [11:0] VBP = 36;
|
||||
|
||||
wire [63:0] reconfig_to_pll;
|
||||
wire [63:0] reconfig_from_pll;
|
||||
wire cfg_waitrequest;
|
||||
reg cfg_write;
|
||||
reg [5:0] cfg_address;
|
||||
reg [31:0] cfg_data;
|
||||
wire cfg_waitrequest,adj_waitrequest;
|
||||
reg cfg_write,adj_write;
|
||||
reg [5:0] cfg_address,adj_address;
|
||||
reg [31:0] cfg_data,adj_data;
|
||||
|
||||
pll_hdmi_cfg pll_hdmi_cfg
|
||||
(
|
||||
@@ -664,24 +690,24 @@ always @(posedge FPGA_CLK1_50) begin
|
||||
gotd <= cfg_got;
|
||||
gotd2 <= gotd;
|
||||
|
||||
cfg_write <= 0;
|
||||
adj_write <= 0;
|
||||
|
||||
custd <= cfg_custom_t;
|
||||
custd2 <= custd;
|
||||
if(custd2 != custd & ~gotd) begin
|
||||
cfg_address <= cfg_custom_p1;
|
||||
cfg_data <= cfg_custom_p2;
|
||||
cfg_write <= 1;
|
||||
adj_address <= cfg_custom_p1;
|
||||
adj_data <= cfg_custom_p2;
|
||||
adj_write <= 1;
|
||||
end
|
||||
|
||||
if(~gotd2 & gotd) begin
|
||||
cfg_address <= 2;
|
||||
cfg_data <= 0;
|
||||
cfg_write <= 1;
|
||||
adj_address <= 2;
|
||||
adj_data <= 0;
|
||||
adj_write <= 1;
|
||||
end
|
||||
|
||||
old_wait <= cfg_waitrequest;
|
||||
if(old_wait & ~cfg_waitrequest & gotd) cfg_ready <= 1;
|
||||
old_wait <= adj_waitrequest;
|
||||
if(old_wait & ~adj_waitrequest & gotd) cfg_ready <= 1;
|
||||
end
|
||||
|
||||
hdmi_config hdmi_config
|
||||
@@ -883,6 +909,7 @@ wire [1:0] audio_mix;
|
||||
wire [7:0] r_out, g_out, b_out;
|
||||
wire vs, hs, de, f1;
|
||||
wire [1:0] scanlines;
|
||||
wire [15:0] lltune;
|
||||
wire clk_sys, clk_vid, ce_pix;
|
||||
|
||||
wire ram_clk;
|
||||
|
||||
Reference in New Issue
Block a user