Update sys.
This commit is contained in:
parent
8dd279eef3
commit
98b7a395ce
|
@ -52,13 +52,14 @@ module emu
|
|||
output VGA_F1,
|
||||
output [1:0] VGA_SL,
|
||||
output VGA_SCALER, // Force VGA scaler
|
||||
output VGA_DISABLE, // analog out is off
|
||||
|
||||
input [11:0] HDMI_WIDTH,
|
||||
input [11:0] HDMI_HEIGHT,
|
||||
output HDMI_FREEZE,
|
||||
|
||||
`ifdef MISTER_FB
|
||||
// Use framebuffer in DDRAM (USE_FB=1 in qsf)
|
||||
// Use framebuffer in DDRAM
|
||||
// FB_FORMAT:
|
||||
// [2:0] : 011=8bpp(palette) 100=16bpp 101=24bpp 110=32bpp
|
||||
// [3] : 0=16bits 565 1=16bits 1555
|
||||
|
@ -185,6 +186,7 @@ assign LED_POWER = 0;
|
|||
assign BUTTONS = 0;
|
||||
assign VGA_SCALER= 0;
|
||||
assign HDMI_FREEZE = 0;
|
||||
assign VGA_DISABLE = 0;
|
||||
|
||||
wire [1:0] ar = status[8:7];
|
||||
video_freak video_freak
|
||||
|
|
277
sys/ascal.vhd
277
sys/ascal.vhd
|
@ -220,6 +220,8 @@ ENTITY ascal IS
|
|||
vdisp : IN natural RANGE 0 TO 4095;
|
||||
vmin : IN natural RANGE 0 TO 4095;
|
||||
vmax : IN natural RANGE 0 TO 4095; -- 0 <= vmin < vmax < vdisp
|
||||
vrr : IN std_logic := '0';
|
||||
vrrmax : IN natural RANGE 0 TO 4095 := 0;
|
||||
|
||||
-- Scaler format. 00=16bpp 565, 01=24bpp 10=32bpp
|
||||
format : IN unsigned(1 DOWNTO 0) :="01";
|
||||
|
@ -423,6 +425,12 @@ ARCHITECTURE rtl OF ascal IS
|
|||
SIGNAL o_hmin,o_hmax,o_hdisp,o_v_hmin_adj : uint12;
|
||||
SIGNAL o_hsize,o_vsize : uint12;
|
||||
SIGNAL o_vtotal,o_vsstart,o_vsend : uint12;
|
||||
SIGNAL o_vrr,o_isync,o_isync2 : std_logic;
|
||||
SIGNAL o_vrr_sync,o_vrr_sync2 : boolean;
|
||||
SIGNAL o_vrr_min,o_vrr_min2 : boolean;
|
||||
SIGNAL o_vrr_max,o_vrr_max2 : boolean;
|
||||
SIGNAL o_vcpt_sync,o_vcpt_sync2, o_vrrmax : uint12;
|
||||
SIGNAL o_sync, o_sync_max : boolean;
|
||||
SIGNAL o_vmin,o_vmax,o_vdisp : uint12;
|
||||
SIGNAL o_divcpt : natural RANGE 0 TO 36;
|
||||
SIGNAL o_iendframe0,o_iendframe02,o_iendframe1,o_iendframe12 : std_logic;
|
||||
|
@ -435,7 +443,7 @@ ARCHITECTURE rtl OF ascal IS
|
|||
SIGNAL o_pshift : natural RANGE 0 TO 15;
|
||||
SIGNAL o_readack,o_readack_sync,o_readack_sync2 : std_logic;
|
||||
SIGNAL o_readdataack,o_readdataack_sync,o_readdataack_sync2 : std_logic;
|
||||
SIGNAL o_copyv : unsigned(0 TO 12);
|
||||
SIGNAL o_copyv : unsigned(0 TO 14);
|
||||
SIGNAL o_adrs : unsigned(31 DOWNTO 0); -- Avalon address
|
||||
SIGNAL o_adrs_pre : natural RANGE 0 TO 2**24-1;
|
||||
SIGNAL o_stride : unsigned(13 DOWNTO 0);
|
||||
|
@ -456,16 +464,16 @@ ARCHITECTURE rtl OF ascal IS
|
|||
SIGNAL o_wadl,o_radl0,o_radl1,o_radl2,o_radl3 : natural RANGE 0 TO OHRES-1;
|
||||
SIGNAL o_ldw,o_ldr0,o_ldr1,o_ldr2,o_ldr3 : type_pix;
|
||||
SIGNAL o_wr : unsigned(3 DOWNTO 0);
|
||||
SIGNAL o_hcpt,o_vcpt,o_vcpt_pre,o_vcpt_pre2,o_vcpt_pre3 : uint12;
|
||||
SIGNAL o_hcpt,o_vcpt,o_vcpt_pre,o_vcpt_pre2,o_vcpt_pre3,o_vcpt2 : uint12;
|
||||
SIGNAL o_ihsize,o_ihsizem,o_ivsize : uint12;
|
||||
SIGNAL o_ihsize_temp, o_ihsize_temp2 : natural RANGE 0 TO 32767;
|
||||
|
||||
SIGNAL o_vfrac : unsigned(11 DOWNTO 0);
|
||||
SIGNAL o_hfrac : arr_frac(0 TO 8);
|
||||
SIGNAL o_hfrac : arr_frac(0 TO 9);
|
||||
ATTRIBUTE ramstyle OF o_hfrac : SIGNAL IS "logic"; -- avoid blockram shift register
|
||||
|
||||
SIGNAL o_hacc,o_hacc_ini,o_hacc_next,o_vacc,o_vacc_next,o_vacc_ini : natural RANGE 0 TO 4*OHRES-1;
|
||||
SIGNAL o_hsv,o_vsv,o_dev,o_pev,o_end : unsigned(0 TO 9);
|
||||
SIGNAL o_hsv,o_vsv,o_dev,o_pev,o_end : unsigned(0 TO 11);
|
||||
SIGNAL o_hsp,o_vss : std_logic;
|
||||
SIGNAL o_vcarrym,o_prim : boolean;
|
||||
SIGNAL o_read,o_read_pre : std_logic;
|
||||
|
@ -482,16 +490,14 @@ ARCHITECTURE rtl OF ascal IS
|
|||
TYPE arr_uint4 IS ARRAY (natural RANGE <>) OF natural RANGE 0 TO 15;
|
||||
SIGNAL o_off : arr_uint4(0 TO 2);
|
||||
SIGNAL o_bibu : std_logic :='0';
|
||||
SIGNAL o_dcptv : arr_uint12(1 TO 12);
|
||||
SIGNAL o_dcptv : arr_uint12(1 TO 14);
|
||||
SIGNAL o_dcpt : uint12;
|
||||
SIGNAL o_hpixs,o_hpix0,o_hpix1,o_hpix2,o_hpix3 : type_pix;
|
||||
SIGNAL o_hpixq : arr_pixq(2 TO 6);
|
||||
SIGNAL o_hpixq : arr_pixq(2 TO 8);
|
||||
ATTRIBUTE ramstyle OF o_hpixq : SIGNAL IS "logic"; -- avoid blockram shift register
|
||||
SIGNAL o_vpixq : arr_pix(0 TO 3);
|
||||
SIGNAL o_vpixq, o_vpixq_pre : arr_pix(0 TO 3);
|
||||
SIGNAL o_vpix_outer : arr_pix(0 TO 2);
|
||||
SIGNAL o_vpix_inner : arr_pix(0 TO 5);
|
||||
|
||||
-- ATTRIBUTE ramstyle OF o_hpixq : SIGNAL IS "logic";
|
||||
SIGNAL o_vpix_inner : arr_pix(0 TO 6);
|
||||
|
||||
|
||||
SIGNAL o_vpe : std_logic;
|
||||
|
@ -522,7 +528,7 @@ ARCHITECTURE rtl OF ascal IS
|
|||
END CASE;
|
||||
END FUNCTION;
|
||||
|
||||
FUNCTION shift_ipack(i_dw : unsigned(N_DW-1 DOWNTO 0);
|
||||
FUNCTION shift_ipack( i_dw : unsigned(N_DW-1 DOWNTO 0);
|
||||
acpt : natural RANGE 0 TO 15;
|
||||
shift : unsigned(0 TO 119);
|
||||
pix : type_pix;
|
||||
|
@ -867,7 +873,7 @@ ARCHITECTURE rtl OF ascal IS
|
|||
FUNCTION bic_calc0(f : unsigned(11 DOWNTO 0);
|
||||
p : arr_pix(0 TO 3)) RETURN type_bic_pix_abcd IS
|
||||
BEGIN
|
||||
RETURN type_bic_pix_abcd'(r=>bic_calc0(f,p(0).r,p(1).r,p(2).r,p(3).r),
|
||||
RETURN type_bic_pix_abcd'( r=>bic_calc0(f,p(0).r,p(1).r,p(2).r,p(3).r),
|
||||
g=>bic_calc0(f,p(0).g,p(1).g,p(2).g,p(3).g),
|
||||
b=>bic_calc0(f,p(0).b,p(1).b,p(2).b,p(3).b));
|
||||
END FUNCTION;
|
||||
|
@ -964,22 +970,21 @@ ARCHITECTURE rtl OF ascal IS
|
|||
r0,r1,b0,b1,g0,g1 : signed(26 DOWNTO 0);
|
||||
END RECORD;
|
||||
|
||||
|
||||
SIGNAL o_h_poly_mem : arr_uv40(0 TO 2**FRAC-1);
|
||||
SIGNAL o_v_poly_mem : arr_uv40(0 TO 2**FRAC-1);
|
||||
SIGNAL o_a_poly_mem : arr_uv40(0 TO 2**FRAC-1);
|
||||
ATTRIBUTE ramstyle OF o_h_poly_mem : SIGNAL IS "no_rw_check";
|
||||
ATTRIBUTE ramstyle OF o_v_poly_mem : SIGNAL IS "no_rw_check";
|
||||
ATTRIBUTE ramstyle OF o_a_poly_mem : SIGNAL IS "no_rw_check";
|
||||
SIGNAL o_a_poly_addr, o_v_poly_addr, o_h_poly_addr : integer RANGE 0 TO 2**FRAC-1;
|
||||
SIGNAL o_h_poly_phase_a,o_h_poly_phase_a2,o_h_poly_phase_a3 : poly_phase_t;
|
||||
SIGNAL o_v_poly_phase_a,o_v_poly_phase_a2,o_v_poly_phase_a3 : poly_phase_t;
|
||||
SIGNAL o_a_poly_addr, o_v_poly_addr : integer RANGE 0 TO 2**FRAC-1;
|
||||
SIGNAL o_h_poly_phase_a,o_h_poly_phase_a2,o_h_poly_phase_a3, o_h_poly_phase_a4, o_h_poly_phase_a5 : poly_phase_t;
|
||||
SIGNAL o_v_poly_phase_a,o_v_poly_phase_a2,o_v_poly_phase_a3, o_v_poly_phase_a4, o_v_poly_phase_a5 : poly_phase_t;
|
||||
SIGNAL o_poly_phase_a, o_poly_phase_a2, o_poly_phase_a3 : poly_phase_t;
|
||||
SIGNAL o_poly_phase_b,o_poly_phase_b2,o_poly_phase_b3 : poly_phase_t;
|
||||
SIGNAL o_v_poly_phase, o_v_poly_phase2, o_h_poly_phase, o_poly_phase : poly_phase_interp_t;
|
||||
SIGNAL o_v_poly_pix, o_h_poly_pix : type_pix;
|
||||
SIGNAL o_v_poly_lum, o_h_poly_lum, o_poly_lum : unsigned(7 DOWNTO 0);
|
||||
SIGNAL o_poly_lerp_ta, o_poly_lerp_tb, o_poly_lerp_tb3 : signed(9 DOWNTO 0);
|
||||
SIGNAL o_v_poly_phase, o_v_poly_phase2, o_h_poly_phase, o_poly_phase, o_poly_phase1 : poly_phase_interp_t;
|
||||
SIGNAL o_v_poly_pix, o_h_poly_pix, o_h_lum_pix, o_v_lum_pix : type_pix;
|
||||
SIGNAL o_poly_lum, o_poly_lum1 : unsigned(7 DOWNTO 0);
|
||||
SIGNAL o_poly_lerp_ta, o_poly_lerp_tb : signed(9 DOWNTO 0);
|
||||
SIGNAL o_h_poly_t,o_h_poly_t2,o_v_poly_t : type_poly_t;
|
||||
|
||||
SIGNAL o_v_poly_adaptive, o_h_poly_adaptive, o_v_poly_use_adaptive, o_h_poly_use_adaptive : std_logic;
|
||||
|
@ -987,7 +992,6 @@ ARCHITECTURE rtl OF ascal IS
|
|||
SIGNAL poly_tdw : unsigned(39 DOWNTO 0);
|
||||
SIGNAL poly_a2 : unsigned(FRAC-1 DOWNTO 0);
|
||||
|
||||
|
||||
FUNCTION poly_unpack(a : unsigned(39 DOWNTO 0)) RETURN poly_phase_t IS
|
||||
VARIABLE v : poly_phase_t;
|
||||
BEGIN
|
||||
|
@ -995,7 +999,6 @@ ARCHITECTURE rtl OF ascal IS
|
|||
v.t1 := signed(a(29 DOWNTO 20));
|
||||
v.t2 := signed(a(19 DOWNTO 10));
|
||||
v.t3 := signed(a( 9 DOWNTO 0));
|
||||
|
||||
RETURN v;
|
||||
END FUNCTION;
|
||||
|
||||
|
@ -1144,8 +1147,7 @@ BEGIN
|
|||
i_head(87 DOWNTO 85)<=i_count;
|
||||
i_head(79 DOWNTO 64)<="0000" & to_unsigned(i_hrsize,12); -- Image width
|
||||
i_head(63 DOWNTO 48)<="0000" & to_unsigned(i_vrsize,12); -- Image height
|
||||
i_head(47 DOWNTO 32)<=
|
||||
to_unsigned(N_BURST * i_hburst,16); -- Line Length. Bytes
|
||||
i_head(47 DOWNTO 32)<= to_unsigned(N_BURST * i_hburst,16); -- Line Length. Bytes
|
||||
i_head(31 DOWNTO 16)<="0000" & to_unsigned(i_ohsize,12);
|
||||
i_head(15 DOWNTO 0) <="0000" & to_unsigned(i_ovsize,12);
|
||||
|
||||
|
@ -1850,10 +1852,15 @@ BEGIN
|
|||
o_hsize <=o_hmax - o_hmin + 1;
|
||||
o_vsize <=o_vmax - o_vmin + 1;
|
||||
|
||||
o_vrr <=vrr;
|
||||
o_vrrmax <= vrrmax;
|
||||
|
||||
--------------------------------------------
|
||||
-- Triple buffering.
|
||||
-- For intelaced video, half frames are updated independently
|
||||
-- Input : Toggle buffer at end of input frame
|
||||
o_isync <= '0';
|
||||
o_isync2 <= o_isync;
|
||||
o_freeze <= freeze;
|
||||
o_inter <=i_inter; -- <ASYNC>
|
||||
o_iendframe0<=i_endframe0; -- <ASYNC>
|
||||
|
@ -1861,12 +1868,14 @@ BEGIN
|
|||
IF o_iendframe0='1' AND o_iendframe02='0' THEN
|
||||
o_ibuf0<=buf_next(o_ibuf0,o_obuf0,o_freeze);
|
||||
o_bufup0<='1';
|
||||
o_isync <= '1';
|
||||
END IF;
|
||||
o_iendframe1<=i_endframe1; -- <ASYNC>
|
||||
o_iendframe12<=o_iendframe1;
|
||||
IF o_iendframe1='1' AND o_iendframe12='0' THEN
|
||||
o_ibuf1<=buf_next(o_ibuf1,o_obuf1,o_freeze);
|
||||
o_bufup1<='1';
|
||||
o_isync <= '1';
|
||||
END IF;
|
||||
|
||||
-- Output : Change framebuffer, and image properties, at VS falling edge
|
||||
|
@ -2277,25 +2286,15 @@ BEGIN
|
|||
|
||||
-- Fetch polyphase coefficients
|
||||
PolyFetch:PROCESS (o_clk) IS
|
||||
VARIABLE hfrac2_v, hfrac3_v, vfrac_v : unsigned(FRAC-1 DOWNTO 0);
|
||||
VARIABLE o_poly_phase_v : poly_phase_interp_t;
|
||||
VARIABLE hfrac3_v, vfrac_v : unsigned(FRAC-1 DOWNTO 0);
|
||||
BEGIN
|
||||
IF rising_edge(o_clk) THEN
|
||||
hfrac2_v:=o_hfrac(2)(11 DOWNTO 12-FRAC);
|
||||
hfrac3_v:=o_hfrac(3)(11 DOWNTO 12-FRAC);
|
||||
vfrac_v:=o_vfrac(11 DOWNTO 12-FRAC);
|
||||
|
||||
o_v_poly_use_adaptive <= to_std_logic((o_vmode(2 DOWNTO 0)/="000") AND (o_v_poly_adaptive = '1'));
|
||||
o_h_poly_use_adaptive <= to_std_logic((o_hmode(2 DOWNTO 0)/="000") AND (o_h_poly_adaptive = '1'));
|
||||
|
||||
-- C2 / HC2 / VC3
|
||||
o_v_poly_addr<=to_integer(vfrac_v);
|
||||
o_h_poly_addr<=to_integer(hfrac2_v);
|
||||
IF o_v_poly_use_adaptive = '1' THEN
|
||||
o_a_poly_addr<=to_integer(vfrac_v);
|
||||
ELSIF o_h_poly_use_adaptive = '1' THEN
|
||||
o_a_poly_addr<=to_integer(hfrac2_v);
|
||||
END IF;
|
||||
o_v_poly_addr<=to_integer(o_vfrac(11 DOWNTO 12-FRAC));
|
||||
|
||||
-- C3 / HC3 / VC4
|
||||
IF o_vmode(2 DOWNTO 0)/="000" THEN
|
||||
|
@ -2305,22 +2304,21 @@ BEGIN
|
|||
END IF;
|
||||
|
||||
IF o_hmode(2 DOWNTO 0)/="000" THEN
|
||||
o_h_poly_phase_a<=poly_unpack(o_h_poly_mem(o_h_poly_addr));
|
||||
o_h_poly_phase_a<=poly_unpack(o_h_poly_mem(to_integer(hfrac3_v)));
|
||||
ELSE
|
||||
o_h_poly_phase_a<=poly_nn(hfrac3_v);
|
||||
END IF;
|
||||
|
||||
IF o_v_poly_use_adaptive='1' THEN
|
||||
o_poly_lum<=o_v_poly_lum;
|
||||
o_poly_lum<=poly_lum(o_v_lum_pix);
|
||||
o_a_poly_addr<=o_v_poly_addr;
|
||||
ELSIF o_h_poly_use_adaptive='1' THEN
|
||||
o_poly_lum<=o_h_poly_lum;
|
||||
o_poly_lum<=poly_lum(o_h_lum_pix);
|
||||
o_a_poly_addr<=to_integer(hfrac3_v);
|
||||
END IF;
|
||||
|
||||
o_poly_phase_b<=poly_unpack(o_a_poly_mem(o_a_poly_addr));
|
||||
|
||||
-- C4 / HC4 / VC5
|
||||
o_poly_lerp_ta<=signed(to_unsigned(256,10) - resize(o_poly_lum,10));
|
||||
o_poly_lerp_tb<=signed(resize(o_poly_lum,10));
|
||||
o_poly_phase_b<=poly_unpack(o_a_poly_mem(o_a_poly_addr));
|
||||
|
||||
IF o_v_poly_use_adaptive='1' THEN
|
||||
o_poly_phase_a<=o_v_poly_phase_a;
|
||||
|
@ -2330,21 +2328,36 @@ BEGIN
|
|||
|
||||
o_h_poly_phase_a2<=o_h_poly_phase_a;
|
||||
o_v_poly_phase_a2<=o_v_poly_phase_a;
|
||||
o_poly_phase_b2<=o_poly_phase_b;
|
||||
o_poly_lum1<=o_poly_lum;
|
||||
|
||||
-- C5 / HC5 / VC6
|
||||
o_poly_phase<=poly_lerp(o_poly_phase_a, o_poly_phase_b2, o_poly_lerp_ta, o_poly_lerp_tb);
|
||||
o_poly_lerp_ta<=signed(to_unsigned(256,10) - resize(o_poly_lum1,10));
|
||||
o_poly_lerp_tb<=signed(resize(o_poly_lum1,10));
|
||||
|
||||
o_poly_phase_b2<=o_poly_phase_b;
|
||||
o_poly_phase_a2<=o_poly_phase_a;
|
||||
|
||||
o_h_poly_phase_a3<=o_h_poly_phase_a2;
|
||||
o_v_poly_phase_a3<=o_v_poly_phase_a2;
|
||||
|
||||
-- C6 / HC6 / VC7
|
||||
o_v_poly_phase<=poly_cvt(o_v_poly_phase_a3);
|
||||
o_h_poly_phase<=poly_cvt(o_h_poly_phase_a3);
|
||||
o_poly_phase<=poly_lerp(o_poly_phase_a2, o_poly_phase_b2, o_poly_lerp_ta, o_poly_lerp_tb);
|
||||
o_h_poly_phase_a4<=o_h_poly_phase_a3;
|
||||
o_v_poly_phase_a4<=o_v_poly_phase_a3;
|
||||
|
||||
-- C7 / HC7 / VC8
|
||||
o_h_poly_phase_a5<=o_h_poly_phase_a4;
|
||||
o_v_poly_phase_a5<=o_v_poly_phase_a4;
|
||||
o_poly_phase1<=o_poly_phase;
|
||||
|
||||
-- C8 / HC8 / VC9
|
||||
o_v_poly_phase<=poly_cvt(o_v_poly_phase_a5);
|
||||
o_h_poly_phase<=poly_cvt(o_h_poly_phase_a5);
|
||||
|
||||
IF o_v_poly_use_adaptive = '1' THEN
|
||||
o_v_poly_phase<=o_poly_phase;
|
||||
o_v_poly_phase<=o_poly_phase1;
|
||||
ELSIF o_h_poly_use_adaptive = '1' THEN
|
||||
o_h_poly_phase<=o_poly_phase;
|
||||
o_h_poly_phase<=o_poly_phase1;
|
||||
END IF;
|
||||
|
||||
END IF;
|
||||
|
@ -2510,77 +2523,78 @@ BEGIN
|
|||
|
||||
-----------------------------------
|
||||
o_hfrac(1)<=dir_v;
|
||||
o_hfrac(2 TO 6) <= o_hfrac(1 TO 5);
|
||||
o_hfrac(2 TO 9) <= o_hfrac(1 TO 8);
|
||||
|
||||
o_copyv(1 TO 12)<=o_copyv(0 TO 11);
|
||||
o_copyv(1 TO 14)<=o_copyv(0 TO 13);
|
||||
|
||||
o_dcptv(1)<=o_dcpt;
|
||||
IF o_dcptv(1)>=o_hsize THEN
|
||||
o_copyv(2)<='0';
|
||||
END IF;
|
||||
o_dcptv(2)<=o_dcptv(1) MOD OHRES;
|
||||
o_dcptv(3 TO 12)<=o_dcptv(2 TO 11);
|
||||
o_dcptv(3 TO 14)<=o_dcptv(2 TO 13);
|
||||
|
||||
-- C2
|
||||
o_hpixq(2)<=(o_hpix3,o_hpix2,o_hpix1,o_hpix0);
|
||||
o_hpixq(3 TO 6)<=o_hpixq(2 TO 5);
|
||||
o_hpixq(3 TO 8)<=o_hpixq(2 TO 7);
|
||||
|
||||
-- BILINEAR / SHARP BILINEAR ---------------
|
||||
-- C4 : Pre-calc Sharp Bilinear
|
||||
o_h_sbil_t<=sbil_frac1(o_hfrac(3));
|
||||
-- C7 : Pre-calc Sharp Bilinear
|
||||
o_h_sbil_t<=sbil_frac1(o_hfrac(6));
|
||||
|
||||
-- C5 : Select
|
||||
-- C8 : Select
|
||||
o_h_bil_frac<=(OTHERS =>'0');
|
||||
IF o_hmode(0)='1' THEN -- Bilinear
|
||||
IF MASK(MASK_BILINEAR)='1' THEN
|
||||
o_h_bil_frac<=bil_frac(o_hfrac(4));
|
||||
o_h_bil_frac<=bil_frac(o_hfrac(7));
|
||||
END IF;
|
||||
ELSE -- Sharp Bilinear
|
||||
IF MASK(MASK_SHARP_BILINEAR)='1' THEN
|
||||
o_h_bil_frac<=sbil_frac2(o_hfrac(4),o_h_sbil_t);
|
||||
o_h_bil_frac<=sbil_frac2(o_hfrac(7),o_h_sbil_t);
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
-- C6 : Opposite frac
|
||||
o_h_bil_t<=bil_calc(o_h_bil_frac,o_hpixq(5));
|
||||
-- C9 : Opposite frac
|
||||
o_h_bil_t<=bil_calc(o_h_bil_frac,o_hpixq(8));
|
||||
|
||||
-- C7 : Bilinear / Sharp Bilinear
|
||||
-- C10 : Bilinear / Sharp Bilinear
|
||||
o_h_bil_pix.r<=bound(o_h_bil_t.r,8+FRAC);
|
||||
o_h_bil_pix.g<=bound(o_h_bil_t.g,8+FRAC);
|
||||
o_h_bil_pix.b<=bound(o_h_bil_t.b,8+FRAC);
|
||||
|
||||
-- BICUBIC -------------------------------------------
|
||||
-- C5 : Bicubic coefficients A,B,C,D
|
||||
-- C5 : Bicubic calc T1 = X.D + C
|
||||
o_h_bic_abcd1<=bic_calc0(o_hfrac(4),o_hpixq(4));
|
||||
o_h_bic_tt1<=bic_calc1(o_hfrac(4),
|
||||
bic_calc0(o_hfrac(4),o_hpixq(4)));
|
||||
-- C8 : Bicubic coefficients A,B,C,D
|
||||
-- C8 : Bicubic calc T1 = X.D + C
|
||||
o_h_bic_abcd1<=bic_calc0(o_hfrac(7),o_hpixq(6));
|
||||
o_h_bic_tt1<=bic_calc1(o_hfrac(7),
|
||||
bic_calc0(o_hfrac(7),o_hpixq(6)));
|
||||
|
||||
-- C6 : Bicubic calc T2 = X.T1 + B
|
||||
-- C9 : Bicubic calc T2 = X.T1 + B
|
||||
o_h_bic_abcd2<=o_h_bic_abcd1;
|
||||
o_h_bic_tt2<=bic_calc2(o_hfrac(5),o_h_bic_tt1,o_h_bic_abcd1);
|
||||
o_h_bic_tt2<=bic_calc2(o_hfrac(8),o_h_bic_tt1,o_h_bic_abcd1);
|
||||
|
||||
-- C7 : Bicubic final Y = X.T2 + A
|
||||
o_h_bic_pix<=bic_calc3(o_hfrac(6),o_h_bic_tt2,o_h_bic_abcd2);
|
||||
-- C10 : Bicubic final Y = X.T2 + A
|
||||
o_h_bic_pix<=bic_calc3(o_hfrac(9),o_h_bic_tt2,o_h_bic_abcd2);
|
||||
|
||||
-- POLYPHASE -----------------------------------------
|
||||
-- C2
|
||||
IF o_hfrac(2)(o_hfrac(2)'left)='0' THEN
|
||||
o_h_poly_lum<=poly_lum(o_hpix2);
|
||||
o_h_lum_pix<=o_hpix2;
|
||||
ELSE
|
||||
o_h_poly_lum<=poly_lum(o_hpix1);
|
||||
o_h_lum_pix<=o_hpix1;
|
||||
END IF;
|
||||
-- C3-C6 in PolyFetch
|
||||
|
||||
-- C7 : Apply Polyphase
|
||||
o_h_poly_t<=poly_calc(o_h_poly_phase,o_hpixq(6));
|
||||
-- C3-C8 in PolyFetch
|
||||
|
||||
-- C8 : Sum and bound
|
||||
-- C9 : Apply Polyphase
|
||||
o_h_poly_t<=poly_calc(o_h_poly_phase,o_hpixq(8));
|
||||
|
||||
-- C10 : Sum and bound
|
||||
o_h_poly_pix<=poly_final(o_h_poly_t);
|
||||
|
||||
-- C9 : Select interpoler ----------------------------
|
||||
o_wadl<=o_dcptv(12);
|
||||
o_wr<=o_altx AND (o_copyv(12) & o_copyv(12) & o_copyv(12) & o_copyv(12));
|
||||
-- C11 : Select interpoler ----------------------------
|
||||
o_wadl<=o_dcptv(14);
|
||||
o_wr<=o_altx AND (o_copyv(14) & o_copyv(14) & o_copyv(14) & o_copyv(14));
|
||||
o_ldw<=(x"00",x"00",x"00");
|
||||
|
||||
CASE o_hmode(2 DOWNTO 0) IS
|
||||
|
@ -2630,17 +2644,27 @@ BEGIN
|
|||
OSWEEP:PROCESS(o_clk) IS
|
||||
BEGIN
|
||||
IF rising_edge(o_clk) THEN
|
||||
|
||||
IF o_ce='1' THEN
|
||||
-- Output pixels count
|
||||
IF o_hcpt+1<o_htotal THEN
|
||||
o_hcpt<=(o_hcpt+1) MOD 4096;
|
||||
ELSE
|
||||
o_hcpt<=0;
|
||||
|
||||
IF o_vcpt_sync /= 4095 THEN
|
||||
o_vcpt_sync <= o_vcpt_sync+1;
|
||||
END IF;
|
||||
|
||||
IF o_vcpt_pre3+1>=o_vtotal THEN
|
||||
o_vcpt_pre3<=0;
|
||||
ELSIF o_vrr_sync2 THEN
|
||||
o_vcpt_pre3<=o_vsstart;
|
||||
o_sync<=false;
|
||||
ELSE
|
||||
o_vcpt_pre3<=(o_vcpt_pre3+1) MOD 4096;
|
||||
END IF;
|
||||
|
||||
o_vcpt_pre2<=o_vcpt_pre3;
|
||||
o_vcpt_pre<=o_vcpt_pre2;
|
||||
o_vcpt<=o_vcpt_pre;
|
||||
|
@ -2656,11 +2680,11 @@ BEGIN
|
|||
(o_vcpt=o_vsend AND o_hcpt<o_hsstart));
|
||||
|
||||
o_vss<=to_std_logic(o_vcpt_pre2>=o_vmin AND o_vcpt_pre2<=o_vmax);
|
||||
o_hsv(1 TO 9)<=o_hsv(0 TO 8);
|
||||
o_vsv(1 TO 9)<=o_vsv(0 TO 8);
|
||||
o_dev(1 TO 9)<=o_dev(0 TO 8);
|
||||
o_pev(1 TO 9)<=o_pev(0 TO 8);
|
||||
o_end(1 TO 9)<=o_end(0 TO 8);
|
||||
o_hsv(1 TO 11)<=o_hsv(0 TO 10);
|
||||
o_vsv(1 TO 11)<=o_vsv(0 TO 10);
|
||||
o_dev(1 TO 11)<=o_dev(0 TO 10);
|
||||
o_pev(1 TO 11)<=o_pev(0 TO 10);
|
||||
o_end(1 TO 11)<=o_end(0 TO 10);
|
||||
|
||||
IF o_run='0' THEN
|
||||
o_hsv(2)<='0';
|
||||
|
@ -2669,10 +2693,27 @@ BEGIN
|
|||
o_pev(2)<='0';
|
||||
o_end(2)<='0';
|
||||
END IF;
|
||||
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
o_vcpt_sync2<=o_vcpt_sync;
|
||||
o_vrr_min<=(o_vcpt_sync2<o_vtotal);
|
||||
o_vrr_min2<=o_vrr_min;
|
||||
o_vrr_max<=(o_vcpt_sync2<o_vrrmax);
|
||||
o_vrr_max2<=o_vrr_max;
|
||||
|
||||
IF o_isync2='1' THEN
|
||||
o_vcpt_sync<=0;
|
||||
o_sync_max<=o_vrr_max2;
|
||||
IF o_vrr_min2 THEN
|
||||
o_sync<=true;
|
||||
END iF;
|
||||
END IF;
|
||||
|
||||
o_vcpt2<=o_vcpt_pre3;
|
||||
o_vrr_sync<=(o_vrr='1' AND (o_sync OR o_sync_max) AND o_vcpt2>=o_vdisp AND o_vcpt2<o_vsstart);
|
||||
o_vrr_sync2<=o_vrr_sync;
|
||||
|
||||
END IF;
|
||||
END PROCESS OSWEEP;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
@ -2685,7 +2726,7 @@ BEGIN
|
|||
BEGIN
|
||||
IF rising_edge(o_clk) THEN
|
||||
IF o_ce='1' THEN
|
||||
o_v_hmin_adj<=o_hmin + 4;
|
||||
o_v_hmin_adj<=o_hmin + 5;
|
||||
|
||||
fracnn_v := o_vfrac(o_vfrac'left);
|
||||
r1_v := (o_hcpt - o_v_hmin_adj + OHRES) MOD OHRES;
|
||||
|
@ -2731,35 +2772,38 @@ BEGIN
|
|||
o_vpix_inner(0)<=pixq_v(2);
|
||||
END IF;
|
||||
|
||||
-- CYCLE 3-6
|
||||
o_vpix_inner(1 TO 4)<=o_vpix_inner(0 TO 3);
|
||||
-- CYCLE 3-7
|
||||
o_vpix_inner(1 TO 5)<=o_vpix_inner(0 TO 4);
|
||||
|
||||
-- CYCLE 7
|
||||
-- CYCLE 8
|
||||
IF to_integer(o_vacpt)>o_ivsize THEN
|
||||
IF fracnn_v = '0' THEN
|
||||
o_vpixq<=(o_vpix_outer(0), o_vpix_inner(4), o_vpix_inner(4), o_vpix_inner(4));
|
||||
o_vpixq_pre<=(o_vpix_outer(0), o_vpix_inner(5), o_vpix_inner(5), o_vpix_inner(5));
|
||||
ELSE
|
||||
o_vpixq<=(o_vpix_outer(0), o_vpix_outer(1), o_vpix_outer(1), o_vpix_outer(1));
|
||||
o_vpixq_pre<=(o_vpix_outer(0), o_vpix_outer(1), o_vpix_outer(1), o_vpix_outer(1));
|
||||
END IF;
|
||||
ELSIF to_integer(o_vacpt)=o_ivsize THEN
|
||||
IF fracnn_v = '0' THEN
|
||||
o_vpixq<=(o_vpix_outer(0), o_vpix_inner(4), o_vpix_outer(1), o_vpix_outer(1));
|
||||
o_vpixq_pre<=(o_vpix_outer(0), o_vpix_inner(5), o_vpix_outer(1), o_vpix_outer(1));
|
||||
ELSE
|
||||
o_vpixq<=(o_vpix_outer(0), o_vpix_outer(1), o_vpix_inner(4), o_vpix_inner(4));
|
||||
o_vpixq_pre<=(o_vpix_outer(0), o_vpix_outer(1), o_vpix_inner(5), o_vpix_inner(5));
|
||||
END IF;
|
||||
ELSE
|
||||
IF fracnn_v = '0' THEN
|
||||
o_vpixq<=(o_vpix_outer(0), o_vpix_inner(4), o_vpix_outer(1), o_vpix_outer(2));
|
||||
o_vpixq_pre<=(o_vpix_outer(0), o_vpix_inner(5), o_vpix_outer(1), o_vpix_outer(2));
|
||||
ELSE
|
||||
o_vpixq<=(o_vpix_outer(0), o_vpix_outer(1), o_vpix_inner(4), o_vpix_outer(2));
|
||||
o_vpixq_pre<=(o_vpix_outer(0), o_vpix_outer(1), o_vpix_inner(5), o_vpix_outer(2));
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
-- CYCLE 9
|
||||
o_vpixq<=o_vpixq_pre;
|
||||
|
||||
-- BILINEAR / SHARP BILINEAR -----------------------
|
||||
-- C6 : Pre-calc Sharp Bilinear
|
||||
-- C8 : Pre-calc Sharp Bilinear
|
||||
o_v_sbil_t<=sbil_frac1(o_vfrac);
|
||||
|
||||
-- C7 : Select
|
||||
-- C9 : Select
|
||||
o_v_bil_frac<=(OTHERS =>'0');
|
||||
IF o_vmode(0)='1' THEN -- Bilinear
|
||||
IF MASK(MASK_BILINEAR)='1' THEN
|
||||
|
@ -2771,48 +2815,48 @@ BEGIN
|
|||
END IF;
|
||||
END IF;
|
||||
|
||||
-- C8 :
|
||||
-- C10 :
|
||||
o_v_bil_t<=bil_calc(o_v_bil_frac,o_vpixq);
|
||||
|
||||
-- C9 : Nearest / Bilinear / Sharp Bilinear
|
||||
-- C11 : Nearest / Bilinear / Sharp Bilinear
|
||||
o_v_bil_pix.r<=bound(o_v_bil_t.r,8+FRAC);
|
||||
o_v_bil_pix.g<=bound(o_v_bil_t.g,8+FRAC);
|
||||
o_v_bil_pix.b<=bound(o_v_bil_t.b,8+FRAC);
|
||||
|
||||
-- BICUBIC -----------------------------------------
|
||||
-- C7 : Bicubic coefficients A,B,C,D
|
||||
-- C7 : Bicubic calc T1 = X.D + C
|
||||
-- C9 : Bicubic coefficients A,B,C,D
|
||||
-- C9 : Bicubic calc T1 = X.D + C
|
||||
o_v_bic_abcd1<=bic_calc0(o_vfrac,o_vpixq);
|
||||
o_v_bic_tt1<=bic_calc1(o_vfrac,bic_calc0(o_vfrac,o_vpixq));
|
||||
|
||||
-- C8 : Bicubic calc T2 = X.T1 + B
|
||||
-- C10 : Bicubic calc T2 = X.T1 + B
|
||||
o_v_bic_abcd2<=o_v_bic_abcd1;
|
||||
o_v_bic_tt2<=bic_calc2(o_vfrac,o_v_bic_tt1,o_v_bic_abcd1);
|
||||
|
||||
-- C9 : Bicubic final Y = X.T2 + A
|
||||
-- C11 : Bicubic final Y = X.T2 + A
|
||||
o_v_bic_pix<=bic_calc3(o_vfrac,o_v_bic_tt2,o_v_bic_abcd2);
|
||||
|
||||
-- POLYPHASE ---------------------------------------
|
||||
-- C3 : Calculate Luminance
|
||||
o_v_poly_lum<=poly_lum(o_vpix_inner(0));
|
||||
-- C3 : Setup luminance
|
||||
o_v_lum_pix<=o_vpix_inner(0);
|
||||
|
||||
-- C4-C7 in PolyFetch
|
||||
-- C4-C9 in PolyFetch
|
||||
|
||||
-- C8 : Apply polyphase
|
||||
-- C10 : Apply polyphase
|
||||
o_v_poly_t<=poly_calc(o_v_poly_phase,o_vpixq);
|
||||
|
||||
-- C9 : Bound
|
||||
-- C11 : Bound
|
||||
o_v_poly_pix<=poly_final(o_v_poly_t);
|
||||
|
||||
-- CYCLE 10 -----------------------------------------
|
||||
o_hs<=o_hsv(9);
|
||||
o_vs<=o_vsv(9);
|
||||
o_de<=o_dev(9);
|
||||
o_vbl<=o_end(9);
|
||||
-- CYCLE 12 -----------------------------------------
|
||||
o_hs<=o_hsv(11);
|
||||
o_vs<=o_vsv(11);
|
||||
o_de<=o_dev(11);
|
||||
o_vbl<=o_end(11);
|
||||
o_r<=x"00";
|
||||
o_g<=x"00";
|
||||
o_b<=x"00";
|
||||
o_brd<= not o_pev(9);
|
||||
o_brd<= not o_pev(11);
|
||||
|
||||
CASE o_vmode(2 DOWNTO 0) IS
|
||||
WHEN "000" => -- Nearest
|
||||
|
@ -2843,7 +2887,7 @@ BEGIN
|
|||
END IF;
|
||||
END CASE;
|
||||
|
||||
IF o_pev(9)='0' THEN
|
||||
IF o_pev(11)='0' THEN
|
||||
o_r<=o_border(23 DOWNTO 16); -- Copy border colour
|
||||
o_g<=o_border(15 DOWNTO 8);
|
||||
o_b<=o_border(7 DOWNTO 0);
|
||||
|
@ -2852,7 +2896,6 @@ BEGIN
|
|||
----------------------------------------------------
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
END PROCESS VSCAL;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
|
|
@ -1,239 +0,0 @@
|
|||
|
||||
module hdmi_config
|
||||
(
|
||||
// Host Side
|
||||
input iCLK,
|
||||
input iRST_N,
|
||||
|
||||
input dvi_mode,
|
||||
input audio_96k,
|
||||
input [1:0] limited,
|
||||
input ypbpr,
|
||||
|
||||
output reg done,
|
||||
|
||||
// I2C Side
|
||||
output I2C_SCL,
|
||||
inout I2C_SDA
|
||||
);
|
||||
|
||||
// Internal Registers/Wires
|
||||
reg mI2C_GO = 0;
|
||||
wire mI2C_END;
|
||||
wire mI2C_ACK;
|
||||
reg [15:0] LUT_DATA;
|
||||
reg [7:0] LUT_INDEX = 0;
|
||||
|
||||
i2c #(50_000_000, 20_000) i2c_av
|
||||
(
|
||||
.CLK(iCLK),
|
||||
|
||||
.I2C_SCL(I2C_SCL), // I2C CLOCK
|
||||
.I2C_SDA(I2C_SDA), // I2C DATA
|
||||
|
||||
.I2C_ADDR('h39), // 0x39 is the Slave Address of the ADV7513 chip!
|
||||
.I2C_WLEN(1),
|
||||
.I2C_WDATA1(init_data[LUT_INDEX][15:8]), // SUB_ADDR
|
||||
.I2C_WDATA2(init_data[LUT_INDEX][7:0]), // DATA
|
||||
.START(mI2C_GO), // START transfer
|
||||
.READ(0),
|
||||
.END(mI2C_END), // END transfer
|
||||
.ACK(mI2C_ACK) // ACK
|
||||
);
|
||||
|
||||
////////////////////// Config Control ////////////////////////////
|
||||
always@(posedge iCLK or negedge iRST_N) begin
|
||||
reg [1:0] mSetup_ST = 0;
|
||||
|
||||
if(!iRST_N) begin
|
||||
LUT_INDEX <= 0;
|
||||
mSetup_ST <= 0;
|
||||
mI2C_GO <= 0;
|
||||
done <= 0;
|
||||
end else begin
|
||||
if(init_data[LUT_INDEX] != 16'hFFFF) begin
|
||||
case(mSetup_ST)
|
||||
0: begin
|
||||
mI2C_GO <= 1;
|
||||
mSetup_ST <= 1;
|
||||
end
|
||||
1: if(~mI2C_END) mSetup_ST <= 2;
|
||||
2: begin
|
||||
mI2C_GO <= 0;
|
||||
if(mI2C_END) begin
|
||||
mSetup_ST <= 0;
|
||||
if(!mI2C_ACK) LUT_INDEX <= LUT_INDEX + 8'd1;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
else done <= 1;
|
||||
end
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
///////////////////// Config Data LUT //////////////////////////
|
||||
|
||||
wire [15:0] init_data[82] =
|
||||
'{
|
||||
16'h9803, // ADI required Write.
|
||||
|
||||
{8'hD6, 8'b1100_0000}, // [7:6] HPD Control...
|
||||
// 00 = HPD is from both HPD pin or CDC HPD
|
||||
// 01 = HPD is from CDC HPD
|
||||
// 10 = HPD is from HPD pin
|
||||
// 11 = HPD is always high
|
||||
|
||||
16'h4110, // Power Down control
|
||||
16'h9A70, // ADI required Write.
|
||||
16'h9C30, // ADI required Write.
|
||||
{8'h9D, 8'b0110_0001}, // [7:4] must be b0110!.
|
||||
// [3:2] b00 = Input clock not divided. b01 = Clk divided by 2. b10 = Clk divided by 4. b11 = invalid!
|
||||
// [1:0] must be b01!
|
||||
16'hA2A4, // ADI required Write.
|
||||
16'hA3A4, // ADI required Write.
|
||||
16'hE0D0, // ADI required Write.
|
||||
|
||||
|
||||
16'h35_40,
|
||||
16'h36_D9,
|
||||
16'h37_0A,
|
||||
16'h38_00,
|
||||
16'h39_2D,
|
||||
16'h3A_00,
|
||||
|
||||
{8'h16, 8'b0011_1000}, // Output Format 444 [7]=0.
|
||||
// [6] must be 0!
|
||||
// Colour Depth for Input Video data [5:4] b11 = 8-bit.
|
||||
// Input Style [3:2] b10 = Style 1 (ignored when using 444 input).
|
||||
// DDR Input Edge falling [1]=0 (not using DDR atm).
|
||||
// Output Colour Space RGB [0]=0.
|
||||
|
||||
{8'h17, 8'b01100010}, // Aspect ratio 16:9 [1]=1, 4:3 [1]=0
|
||||
|
||||
{8'h18, ypbpr ? 8'h86 : limited[0] ? 8'h8D : limited[1] ? 8'h8E : 8'h00}, // CSC Scaling Factors and Coefficients for RGB Full->Limited.
|
||||
{8'h19, ypbpr ? 8'hDF : limited[0] ? 8'hBC : 8'hFE}, // Taken from table in ADV7513 Programming Guide.
|
||||
{8'h1A, ypbpr ? 8'h1A : 8'h00}, // CSC Channel A.
|
||||
{8'h1B, ypbpr ? 8'h3F : 8'h00},
|
||||
{8'h1C, ypbpr ? 8'h1E : 8'h00},
|
||||
{8'h1D, ypbpr ? 8'hE2 : 8'h00},
|
||||
{8'h1E, ypbpr ? 8'h07 : 8'h01},
|
||||
{8'h1F, ypbpr ? 8'hE7 : 8'h00},
|
||||
|
||||
{8'h20, ypbpr ? 8'h04 : 8'h00}, // CSC Channel B.
|
||||
{8'h21, ypbpr ? 8'h1C : 8'h00},
|
||||
{8'h22, ypbpr ? 8'h08 : limited[0] ? 8'h0D : 8'h0E},
|
||||
{8'h23, ypbpr ? 8'h11 : limited[0] ? 8'hBC : 8'hFE},
|
||||
{8'h24, ypbpr ? 8'h01 : 8'h00},
|
||||
{8'h25, ypbpr ? 8'h91 : 8'h00},
|
||||
{8'h26, ypbpr ? 8'h01 : 8'h01},
|
||||
{8'h27, 8'h00},
|
||||
|
||||
{8'h28, ypbpr ? 8'h1D : 8'h00}, // CSC Channel C.
|
||||
{8'h29, ypbpr ? 8'hAE : 8'h00},
|
||||
{8'h2A, ypbpr ? 8'h1B : 8'h00},
|
||||
{8'h2B, ypbpr ? 8'h73 : 8'h00},
|
||||
{8'h2C, ypbpr ? 8'h06 : limited[0] ? 8'h0D : 8'h0E},
|
||||
{8'h2D, ypbpr ? 8'hDF : limited[0] ? 8'hBC : 8'hFE},
|
||||
{8'h2E, ypbpr ? 8'h07 : 8'h01},
|
||||
{8'h2F, ypbpr ? 8'hE7 : 8'h00},
|
||||
|
||||
{8'h3B, 8'b0000_0000}, // Pixel repetition [6:5] b00 AUTO. [4:3] b00 x1 mult of input clock. [2:1] b00 x1 pixel rep to send to HDMI Rx.
|
||||
|
||||
16'h4000, // General Control Packet Enable
|
||||
|
||||
{8'h48, 8'b0000_1000}, // [6]=0 Normal bus order!
|
||||
// [5] DDR Alignment.
|
||||
// [4:3] b01 Data right justified (for YCbCr 422 input modes).
|
||||
|
||||
16'h49A8, // ADI required Write.
|
||||
16'h4C00, // ADI required Write.
|
||||
|
||||
{8'h55, 8'b0001_0000}, // [7] must be 0!. Set RGB444 in AVinfo Frame [6:5], Set active format [4].
|
||||
// AVI InfoFrame Valid [4].
|
||||
// Bar Info [3:2] b00 Bars invalid. b01 Bars vertical. b10 Bars horizontal. b11 Bars both.
|
||||
// Scan Info [1:0] b00 (No data). b01 TV. b10 PC. b11 None.
|
||||
|
||||
{8'h57, 1'b0, // [7] IT Content. 0 - No. 1 - Yes (type set in register h59).
|
||||
3'b000, // [6:4] Color space (ignored for RGB)
|
||||
(ypbpr | limited) ? 2'b01 : 2'b10, // [3:2] RGB Quantization range
|
||||
2'b00}, // [1:0] Non-Uniform Scaled: 00 - None. 01 - Horiz. 10 - Vert. 11 - Both.
|
||||
|
||||
16'h7301,
|
||||
|
||||
{8'h94, 8'b1000_0000}, // [7]=1 HPD Interrupt ENabled.
|
||||
|
||||
16'h9902, // ADI required Write.
|
||||
16'h9B18, // ADI required Write.
|
||||
|
||||
16'h9F00, // ADI required Write.
|
||||
|
||||
{8'hA1, 8'b0000_0000}, // [6]=1 Monitor Sense Power Down DISabled.
|
||||
|
||||
16'hA408, // ADI required Write.
|
||||
16'hA504, // ADI required Write.
|
||||
16'hA600, // ADI required Write.
|
||||
16'hA700, // ADI required Write.
|
||||
16'hA800, // ADI required Write.
|
||||
16'hA900, // ADI required Write.
|
||||
16'hAA00, // ADI required Write.
|
||||
16'hAB40, // ADI required Write.
|
||||
|
||||
{8'hAF, 6'b0000_01,~dvi_mode,1'b0}, // [7]=0 HDCP Disabled.
|
||||
// [6:5] must be b00!
|
||||
// [4]=0 Current frame is unencrypted
|
||||
// [3:2] must be b01!
|
||||
// [1]=1 HDMI Mode.
|
||||
// [0] must be b0!
|
||||
|
||||
16'hB900, // ADI required Write.
|
||||
|
||||
{8'hBA, 8'b0110_0000}, // [7:5] Input Clock delay...
|
||||
// b000 = -1.2ns.
|
||||
// b001 = -0.8ns.
|
||||
// b010 = -0.4ns.
|
||||
// b011 = No delay.
|
||||
// b100 = 0.4ns.
|
||||
// b101 = 0.8ns.
|
||||
// b110 = 1.2ns.
|
||||
// b111 = 1.6ns.
|
||||
|
||||
16'hBB00, // ADI required Write.
|
||||
|
||||
16'hDE9C, // ADI required Write.
|
||||
16'hE460, // ADI required Write.
|
||||
16'hFA7D, // Nbr of times to search for good phase
|
||||
|
||||
|
||||
// (Audio stuff on Programming Guide, Page 66)...
|
||||
|
||||
{8'h0A, 8'b0000_0000}, // [6:4] Audio Select. b000 = I2S.
|
||||
// [3:2] Audio Mode. (HBR stuff, leave at 00!).
|
||||
|
||||
{8'h0B, 8'b0000_1110}, //
|
||||
|
||||
{8'h0C, 8'b0000_0100}, // [7] 0 = Use sampling rate from I2S stream. 1 = Use samp rate from I2C Register.
|
||||
// [6] 0 = Use Channel Status bits from stream. 1 = Use Channel Status bits from I2C register.
|
||||
// [2] 1 = I2S0 Enable.
|
||||
// [1:0] I2S Format: 00 = Standard. 01 = Right Justified. 10 = Left Justified. 11 = AES.
|
||||
|
||||
{8'h0D, 8'b0001_0000}, // [4:0] I2S Bit (Word) Width for Right-Justified.
|
||||
{8'h14, 8'b0000_0010}, // [3:0] Audio Word Length. b0010 = 16 bits.
|
||||
{8'h15, audio_96k, 7'b010_0000}, // I2S Sampling Rate [7:4]. b0000 = (44.1KHz). b0010 = 48KHz.
|
||||
// Input ID [3:1] b000 (0) = 24-bit RGB 444 or YCrCb 444 with Separate Syncs.
|
||||
|
||||
// Audio Clock Config
|
||||
16'h0100, //
|
||||
audio_96k ? 16'h0230 : 16'h0218, // Set N Value 12288/6144
|
||||
16'h0300, //
|
||||
|
||||
16'h0701, //
|
||||
16'h0822, // Set CTS Value 74250
|
||||
16'h090A, //
|
||||
|
||||
16'hFFFF // END
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
endmodule
|
|
@ -55,6 +55,13 @@ module hps_io #(parameter CONF_STR, CONF_STR_BRAM=1, PS2DIV=0, WIDE=0, VDNUM=1,
|
|||
output reg [15:0] joystick_r_analog_4,
|
||||
output reg [15:0] joystick_r_analog_5,
|
||||
|
||||
input [15:0] joystick_0_rumble, // 15:8 - 'large' rumble motor magnitude, 7:0 'small' rumble motor magnitude
|
||||
input [15:0] joystick_1_rumble,
|
||||
input [15:0] joystick_2_rumble,
|
||||
input [15:0] joystick_3_rumble,
|
||||
input [15:0] joystick_4_rumble,
|
||||
input [15:0] joystick_5_rumble,
|
||||
|
||||
// paddle 0..255
|
||||
output reg [7:0] paddle_0,
|
||||
output reg [7:0] paddle_1,
|
||||
|
@ -71,6 +78,29 @@ module hps_io #(parameter CONF_STR, CONF_STR_BRAM=1, PS2DIV=0, WIDE=0, VDNUM=1,
|
|||
output reg [8:0] spinner_4,
|
||||
output reg [8:0] spinner_5,
|
||||
|
||||
// ps2 keyboard emulation
|
||||
output ps2_kbd_clk_out,
|
||||
output ps2_kbd_data_out,
|
||||
input ps2_kbd_clk_in,
|
||||
input ps2_kbd_data_in,
|
||||
|
||||
input [2:0] ps2_kbd_led_status,
|
||||
input [2:0] ps2_kbd_led_use,
|
||||
|
||||
output ps2_mouse_clk_out,
|
||||
output ps2_mouse_data_out,
|
||||
input ps2_mouse_clk_in,
|
||||
input ps2_mouse_data_in,
|
||||
|
||||
// ps2 alternative interface.
|
||||
|
||||
// [8] - extended, [9] - pressed, [10] - toggles with every press/release
|
||||
output reg [10:0] ps2_key = 0,
|
||||
|
||||
// [24] - toggles with every event
|
||||
output reg [24:0] ps2_mouse = 0,
|
||||
output reg [15:0] ps2_mouse_ext = 0, // 15:8 - reserved(additional buttons), 7:0 - wheel movements
|
||||
|
||||
output [1:0] buttons,
|
||||
output forced_scandoubler,
|
||||
output direct_video,
|
||||
|
@ -79,8 +109,10 @@ module hps_io #(parameter CONF_STR, CONF_STR_BRAM=1, PS2DIV=0, WIDE=0, VDNUM=1,
|
|||
//toggle to force notify of video mode change
|
||||
input new_vmode,
|
||||
|
||||
output reg [63:0] status,
|
||||
input [63:0] status_in,
|
||||
inout [21:0] gamma_bus,
|
||||
|
||||
output reg [127:0] status,
|
||||
input [127:0] status_in,
|
||||
input status_set,
|
||||
input [15:0] status_menumask,
|
||||
|
||||
|
@ -133,31 +165,6 @@ module hps_io #(parameter CONF_STR, CONF_STR_BRAM=1, PS2DIV=0, WIDE=0, VDNUM=1,
|
|||
output reg [7:0] uart_mode,
|
||||
output reg [31:0] uart_speed,
|
||||
|
||||
// ps2 keyboard emulation
|
||||
output ps2_kbd_clk_out,
|
||||
output ps2_kbd_data_out,
|
||||
input ps2_kbd_clk_in,
|
||||
input ps2_kbd_data_in,
|
||||
|
||||
input [2:0] ps2_kbd_led_status,
|
||||
input [2:0] ps2_kbd_led_use,
|
||||
|
||||
output ps2_mouse_clk_out,
|
||||
output ps2_mouse_data_out,
|
||||
input ps2_mouse_clk_in,
|
||||
input ps2_mouse_data_in,
|
||||
|
||||
// ps2 alternative interface.
|
||||
|
||||
// [8] - extended, [9] - pressed, [10] - toggles with every press/release
|
||||
output reg [10:0] ps2_key = 0,
|
||||
|
||||
// [24] - toggles with every event
|
||||
output reg [24:0] ps2_mouse = 0,
|
||||
output reg [15:0] ps2_mouse_ext = 0, // 15:8 - reserved(additional buttons), 7:0 - wheel movements
|
||||
|
||||
inout [21:0] gamma_bus,
|
||||
|
||||
// for core-specific extensions
|
||||
inout [35:0] EXT_BUS
|
||||
);
|
||||
|
@ -259,7 +266,7 @@ always@(posedge clk_sys) begin : uio_block
|
|||
reg [3:0] pdsp_idx;
|
||||
reg ps2skip = 0;
|
||||
reg [3:0] stflg = 0;
|
||||
reg [63:0] status_req;
|
||||
reg[127:0] status_req;
|
||||
reg old_status_set = 0;
|
||||
reg old_upload_req = 0;
|
||||
reg upload_req = 0;
|
||||
|
@ -330,6 +337,12 @@ always@(posedge clk_sys) begin : uio_block
|
|||
'h39: io_dout <= 1;
|
||||
'h3C: if(upload_req) begin io_dout <= {ioctl_upload_index, 8'd1}; upload_req <= 0; end
|
||||
'h3E: io_dout <= 1; // shadow mask
|
||||
'h003F: io_dout <= joystick_0_rumble;
|
||||
'h013F: io_dout <= joystick_1_rumble;
|
||||
'h023F: io_dout <= joystick_2_rumble;
|
||||
'h033F: io_dout <= joystick_3_rumble;
|
||||
'h043F: io_dout <= joystick_4_rumble;
|
||||
'h053F: io_dout <= joystick_5_rumble;
|
||||
endcase
|
||||
|
||||
sd_buff_addr <= 0;
|
||||
|
@ -455,13 +468,17 @@ always@(posedge clk_sys) begin : uio_block
|
|||
// send image info
|
||||
'h1d: if(byte_cnt<5) img_size[{byte_cnt-1'b1, 4'b0000} +:16] <= io_din;
|
||||
|
||||
// status, 64bit version
|
||||
'h1e: if(!byte_cnt[MAX_W:3]) begin
|
||||
case(byte_cnt[2:0])
|
||||
// status, 128bit version
|
||||
'h1e: if(!byte_cnt[MAX_W:4]) begin
|
||||
case(byte_cnt[3:0])
|
||||
1: status[15:00] <= io_din;
|
||||
2: status[31:16] <= io_din;
|
||||
3: status[47:32] <= io_din;
|
||||
4: status[63:48] <= io_din;
|
||||
5: status[79:64] <= io_din;
|
||||
6: status[95:80] <= io_din;
|
||||
7: status[111:96] <= io_din;
|
||||
8: status[127:112] <= io_din;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
@ -491,12 +508,16 @@ always@(posedge clk_sys) begin : uio_block
|
|||
'h24: TIMESTAMP[(byte_cnt-6'd1)<<4 +:16] <= io_din;
|
||||
|
||||
//status set
|
||||
'h29: if(!byte_cnt[MAX_W:3]) begin
|
||||
case(byte_cnt[2:0])
|
||||
'h29: if(!byte_cnt[MAX_W:4]) begin
|
||||
case(byte_cnt[3:0])
|
||||
1: io_dout <= status_req[15:00];
|
||||
2: io_dout <= status_req[31:16];
|
||||
3: io_dout <= status_req[47:32];
|
||||
4: io_dout <= status_req[63:48];
|
||||
5: io_dout <= status_req[79:64];
|
||||
6: io_dout <= status_req[95:80];
|
||||
7: io_dout <= status_req[111:96];
|
||||
8: io_dout <= status_req[127:112];
|
||||
endcase
|
||||
end
|
||||
|
||||
|
@ -870,22 +891,28 @@ always @(posedge clk_sys) begin
|
|||
11: dout <= vid_pix[31:16];
|
||||
12: dout <= vid_vtime_hdmi[15:0];
|
||||
13: dout <= vid_vtime_hdmi[31:16];
|
||||
14: dout <= vid_ccnt[15:0];
|
||||
15: dout <= vid_ccnt[31:16];
|
||||
default dout <= 0;
|
||||
endcase
|
||||
end
|
||||
|
||||
reg [31:0] vid_hcnt = 0;
|
||||
reg [31:0] vid_vcnt = 0;
|
||||
reg [31:0] vid_ccnt = 0;
|
||||
reg [7:0] vid_nres = 0;
|
||||
reg [1:0] vid_int = 0;
|
||||
|
||||
always @(posedge clk_vid) begin
|
||||
integer hcnt;
|
||||
integer vcnt;
|
||||
integer ccnt;
|
||||
reg old_vs= 0, old_de = 0, old_vmode = 0;
|
||||
reg [3:0] resto = 0;
|
||||
reg calch = 0;
|
||||
|
||||
if(calch & de) ccnt <= ccnt + 1;
|
||||
|
||||
if(ce_pix) begin
|
||||
old_vs <= vs;
|
||||
old_de <= de;
|
||||
|
@ -906,9 +933,11 @@ always @(posedge clk_vid) begin
|
|||
if(&resto) vid_nres <= vid_nres + 1'd1;
|
||||
vid_hcnt <= hcnt;
|
||||
vid_vcnt <= vcnt;
|
||||
vid_ccnt <= ccnt;
|
||||
end
|
||||
vcnt <= 0;
|
||||
hcnt <= 0;
|
||||
ccnt <= 0;
|
||||
calch <= 1;
|
||||
end
|
||||
end
|
||||
|
|
|
@ -102,19 +102,19 @@ end
|
|||
|
||||
endmodule
|
||||
|
||||
module ltc2308_tape #(parameter HIST_LOW = 16, HIST_HIGH = 64, ADC_RATE = 48000, CLK_RATE = 50000000)
|
||||
module ltc2308_tape #(parameter HIST_LOW = 16, HIST_HIGH = 64, ADC_RATE = 48000, CLK_RATE = 50000000, NUM_CH = 1)
|
||||
(
|
||||
input reset,
|
||||
input clk,
|
||||
|
||||
inout [3:0] ADC_BUS,
|
||||
output reg dout,
|
||||
output active
|
||||
output active,
|
||||
output adc_sync,
|
||||
output [(NUM_CH*12)-1:0] adc_data
|
||||
);
|
||||
|
||||
wire [11:0] adc_data;
|
||||
wire adc_sync;
|
||||
ltc2308 #(1, ADC_RATE, CLK_RATE) adc
|
||||
ltc2308 #(NUM_CH, ADC_RATE, CLK_RATE) adc
|
||||
(
|
||||
.reset(reset),
|
||||
.clk(clk),
|
||||
|
@ -133,7 +133,7 @@ always @(posedge clk) begin
|
|||
data1 <= data2;
|
||||
data2 <= data3;
|
||||
data3 <= data4;
|
||||
data4 <= adc_data;
|
||||
data4 <= adc_data[11:0];
|
||||
|
||||
sum <= data1+data2+data3+data4;
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ wire [21:0] osd_h_hdr = (info || rot) ? osd_h : (osd_h + OSD_HDR);
|
|||
|
||||
// pipeline the comparisons a bit
|
||||
always @(posedge clk_video) if(ce_pix) begin
|
||||
v_cnt_h <= v_cnt < osd_t;
|
||||
v_cnt_h <= v_cnt <= osd_t;
|
||||
v_cnt_1 <= v_cnt < 320;
|
||||
v_cnt_2 <= v_cnt < 640;
|
||||
v_cnt_3 <= v_cnt < 960;
|
||||
|
|
|
@ -16,6 +16,7 @@ set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) v
|
|||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) arcade_video.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) osd.v ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) vga_out.sv ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) yc_out.sv ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) i2c.v ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) alsa.sv ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) i2s.v ]
|
||||
|
@ -25,7 +26,6 @@ set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) i
|
|||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ltc2308.sv ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sigma_delta_dac.v ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) mt32pi.sv ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hdmi_config.sv ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) mcp23009.sv ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) f2sdram_safe_terminator.sv ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ddr_svc.sv ]
|
||||
|
|
|
@ -45,6 +45,7 @@ set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM2_
|
|||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM2_*
|
||||
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM2_DQ[*]
|
||||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM2_DQ[*]
|
||||
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to SDRAM2_DQ[*]
|
||||
set_instance_assignment -name ALLOW_SYNCH_CTRL_USAGE OFF -to *|SDRAM2_*
|
||||
|
||||
set_global_assignment -name VERILOG_MACRO "MISTER_DUAL_SDRAM=1"
|
||||
|
|
|
@ -28,6 +28,7 @@ set_false_path -to [get_ports {VGA_*}]
|
|||
set_false_path -to [get_ports {AUDIO_SPDIF}]
|
||||
set_false_path -to [get_ports {AUDIO_L}]
|
||||
set_false_path -to [get_ports {AUDIO_R}]
|
||||
set_false_path -from {get_ports {SW[*]}}
|
||||
set_false_path -to {cfg[*]}
|
||||
set_false_path -from {cfg[*]}
|
||||
set_false_path -from {VSET[*]}
|
||||
|
@ -55,6 +56,7 @@ set_false_path -from {FB_BASE[*] FB_BASE[*] FB_WIDTH[*] FB_HEIGHT[*] LFB_HMIN[*]
|
|||
set_false_path -to {vol_att[*] scaler_flt[*] led_overtake[*] led_state[*]}
|
||||
set_false_path -from {vol_att[*] scaler_flt[*] led_overtake[*] led_state[*]}
|
||||
set_false_path -from {aflt_* acx* acy* areset* arc*}
|
||||
set_false_path -from {arx* ary*}
|
||||
set_false_path -from {vs_line*}
|
||||
|
||||
set_false_path -from {ascal|o_ihsize*}
|
||||
|
@ -62,7 +64,7 @@ set_false_path -from {ascal|o_ivsize*}
|
|||
set_false_path -from {ascal|o_format*}
|
||||
set_false_path -from {ascal|o_hdown}
|
||||
set_false_path -from {ascal|o_vdown}
|
||||
set_false_path -from {ascal|o_hmin* ascal|o_hmax* ascal|o_vmin* ascal|o_vmax*}
|
||||
set_false_path -from {ascal|o_hmin* ascal|o_hmax* ascal|o_vmin* ascal|o_vmax* ascal|o_vrrmax* ascal|o_vrr}
|
||||
set_false_path -from {ascal|o_hdisp* ascal|o_vdisp*}
|
||||
set_false_path -from {ascal|o_htotal* ascal|o_vtotal*}
|
||||
set_false_path -from {ascal|o_hsstart* ascal|o_vsstart* ascal|o_hsend* ascal|o_vsend*}
|
||||
|
|
229
sys/sys_top.v
229
sys/sys_top.v
|
@ -168,7 +168,7 @@ assign LED = (led_overtake & led_state) | (~led_overtake & {1'b0,led_locked,1'b0
|
|||
|
||||
wire btn_r, btn_o, btn_u;
|
||||
`ifdef MISTER_DUAL_SDRAM
|
||||
assign {btn_r,btn_o,btn_u} = {mcp_btn[1],mcp_btn[2],mcp_btn[0]};
|
||||
assign {btn_r,btn_o,btn_u} = SW[3] ? {mcp_btn[1],mcp_btn[2],mcp_btn[0]} : ~{SDRAM2_DQ[9],SDRAM2_DQ[13],SDRAM2_DQ[11]};
|
||||
`else
|
||||
assign {btn_r,btn_o,btn_u} = ~{BTN_RESET,BTN_OSD,BTN_USER} | {mcp_btn[1],mcp_btn[2],mcp_btn[0]};
|
||||
`endif
|
||||
|
@ -212,7 +212,7 @@ end
|
|||
|
||||
// gp_in[31] = 0 - quick flag that FPGA is initialized (HPS reads 1 when FPGA is not in user mode)
|
||||
// used to avoid lockups while JTAG loading
|
||||
wire [31:0] gp_in = {1'b0, btn_user | btn[1], btn_osd | btn[0], SW[3], 8'd0, io_ver, io_ack, io_wide, io_dout};
|
||||
wire [31:0] gp_in = {1'b0, btn_user | btn[1], btn_osd | btn[0], SW[3], 8'd0, io_ver, io_ack, io_wide, io_dout | io_dout_sys};
|
||||
wire [31:0] gp_out;
|
||||
|
||||
wire [1:0] io_ver = 1; // 0 - obsolete. 1 - optimized HPS I/O. 2,3 - reserved for future.
|
||||
|
@ -270,7 +270,6 @@ reg [15:0] cfg;
|
|||
|
||||
reg cfg_set = 0;
|
||||
wire vga_fb = cfg[12] | vga_force_scaler;
|
||||
wire [1:0] hdmi_limited = {cfg[11],cfg[8]};
|
||||
|
||||
`ifdef MISTER_DEBUG_NOHDMI
|
||||
wire direct_video = 1;
|
||||
|
@ -278,12 +277,11 @@ wire direct_video = 1;
|
|||
wire direct_video = cfg[10];
|
||||
`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 MISTER_DUAL_SDRAM
|
||||
wire ypbpr_en = cfg[5];
|
||||
wire sog = cfg[9];
|
||||
wire vga_scaler = cfg[2] | vga_force_scaler;
|
||||
`endif
|
||||
|
@ -304,12 +302,13 @@ reg [11:0] VSET = 0, HSET = 0;
|
|||
reg FREESCALE = 0;
|
||||
reg [2:0] scaler_flt;
|
||||
reg lowlat = 0;
|
||||
reg cfg_dis = 0;
|
||||
reg cfg_done = 0;
|
||||
|
||||
reg vs_wait = 0;
|
||||
reg [11:0] vs_line = 0;
|
||||
|
||||
reg scaler_out = 0;
|
||||
reg vrr_mode = 0;
|
||||
|
||||
reg [31:0] aflt_rate = 7056000;
|
||||
reg [39:0] acx = 4258969;
|
||||
|
@ -324,16 +323,16 @@ reg [12:0] arc1x = 0;
|
|||
reg [12:0] arc1y = 0;
|
||||
reg [12:0] arc2x = 0;
|
||||
reg [12:0] arc2y = 0;
|
||||
reg [15:0] io_dout_sys;
|
||||
|
||||
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;
|
||||
reg [4:0] acx_att;
|
||||
reg [7:0] fb_crc;
|
||||
|
||||
old_strobe <= io_strobe;
|
||||
coef_wr <= 0;
|
||||
|
||||
`ifndef MISTER_DEBUG_NOHDMI
|
||||
|
@ -346,9 +345,11 @@ always@(posedge clk_sys) begin
|
|||
areset <= 0;
|
||||
acx_att <= 0;
|
||||
acx <= acx >> acx_att;
|
||||
io_dout_sys <= 0;
|
||||
end
|
||||
else
|
||||
if(~old_strobe & io_strobe) begin
|
||||
if(io_strobe) begin
|
||||
io_dout_sys <= 0;
|
||||
if(!has_cmd) begin
|
||||
has_cmd <= 1;
|
||||
cmd <= io_din[7:0];
|
||||
|
@ -365,6 +366,10 @@ always@(posedge clk_sys) begin
|
|||
acy2 <= -24'd2023767;
|
||||
areset <= 1;
|
||||
end
|
||||
if(io_din[7:0] == 'h20) io_dout_sys <= 'b11;
|
||||
`ifndef MISTER_DEBUG_NOHDMI
|
||||
if(io_din[7:0] == 'h40) io_dout_sys <= fb_crc;
|
||||
`endif
|
||||
end
|
||||
else begin
|
||||
cnt <= cnt + 1'd1;
|
||||
|
@ -377,7 +382,7 @@ always@(posedge clk_sys) begin
|
|||
cfg_set <= 0;
|
||||
if(cnt<8) begin
|
||||
case(cnt[2:0])
|
||||
0: WIDTH <= io_din[11:0];
|
||||
0: {HDMI_PR,vrr_mode,WIDTH} <= {io_din[15:14], io_din[11:0]};
|
||||
1: HFP <= io_din[11:0];
|
||||
2: HS <= {io_din[15], io_din[11:0]};
|
||||
3: HBP <= io_din[11:0];
|
||||
|
@ -401,7 +406,7 @@ always@(posedge clk_sys) begin
|
|||
cfg_custom_t <= ~cfg_custom_t;
|
||||
cnt[2:0] <= 3'b100;
|
||||
end
|
||||
if(cnt == 8) {lowlat,cfg_dis} <= io_din[15:14];
|
||||
if(cnt == 8) {lowlat,cfg_done} <= {io_din[15],1'b1};
|
||||
`endif
|
||||
end
|
||||
end
|
||||
|
@ -458,10 +463,42 @@ always@(posedge clk_sys) begin
|
|||
end
|
||||
`ifndef MISTER_DEBUG_NOHDMI
|
||||
if(cmd == 'h3E) {shadowmask_wr,shadowmask_data} <= {1'b1, io_din};
|
||||
if(cmd == 'h40) begin
|
||||
case(cnt[3:0])
|
||||
0: io_dout_sys <= {arxy, arx};
|
||||
1: io_dout_sys <= {arxy, ary};
|
||||
2: io_dout_sys <= {LFB_EN, FB_EN, FB_FMT};
|
||||
3: io_dout_sys <= FB_WIDTH;
|
||||
4: io_dout_sys <= FB_HEIGHT;
|
||||
5: io_dout_sys <= FB_BASE[15:0];
|
||||
6: io_dout_sys <= FB_BASE[31:16];
|
||||
7: io_dout_sys <= FB_STRIDE;
|
||||
endcase
|
||||
end
|
||||
`endif
|
||||
`ifndef MISTER_DISABLE_YC
|
||||
if(cmd == 'h41) begin
|
||||
case(cnt[3:0])
|
||||
0: {pal_en,cvbs,yc_en} <= io_din[2:0];
|
||||
1: PhaseInc[15:0] <= io_din;
|
||||
2: PhaseInc[31:16] <= io_din;
|
||||
3: PhaseInc[39:32] <= io_din[7:0];
|
||||
4: ColorBurst_Range[15:0] <= io_din;
|
||||
5: ColorBurst_Range[16] <= io_din[0];
|
||||
endcase
|
||||
end
|
||||
`endif
|
||||
end
|
||||
end
|
||||
|
||||
`ifndef MISTER_DEBUG_NOHDMI
|
||||
fb_crc <= {LFB_EN, FB_EN, FB_FMT}
|
||||
^ FB_WIDTH[7:0] ^ FB_WIDTH[11:8]
|
||||
^ FB_HEIGHT[7:0] ^ FB_HEIGHT[11:8]
|
||||
^ arx[7:0] ^ arx[11:8] ^ arxy
|
||||
^ ary[7:0] ^ ary[11:8];
|
||||
`endif
|
||||
|
||||
vs_d0 <= HDMI_TX_VS;
|
||||
if(vs_d0 == HDMI_TX_VS) vs_d1 <= vs_d0;
|
||||
|
||||
|
@ -482,17 +519,6 @@ cyclonev_hps_interface_peripheral_uart uart
|
|||
.txd(uart_txd)
|
||||
);
|
||||
|
||||
wire aspi_sck,aspi_mosi,aspi_ss,aspi_miso;
|
||||
cyclonev_hps_interface_peripheral_spi_master spi
|
||||
(
|
||||
.sclk_out(aspi_sck),
|
||||
.txd(aspi_mosi), // mosi
|
||||
.rxd(aspi_miso), // miso
|
||||
|
||||
.ss_0_n(aspi_ss),
|
||||
.ss_in_n(1)
|
||||
);
|
||||
|
||||
wire [63:0] f2h_irq = {video_sync,HDMI_TX_VS};
|
||||
cyclonev_hps_interface_interrupts interrupts
|
||||
(
|
||||
|
@ -598,11 +624,13 @@ ddr_svc ddr_svc
|
|||
.ram_write(ram2_write),
|
||||
.ram_bcnt(ram2_bcnt),
|
||||
|
||||
`ifndef MISTER_DISABLE_ALSA
|
||||
.ch0_addr(alsa_address),
|
||||
.ch0_burst(1),
|
||||
.ch0_data(alsa_readdata),
|
||||
.ch0_req(alsa_req),
|
||||
.ch0_ready(alsa_ready),
|
||||
`endif
|
||||
|
||||
.ch1_addr(pal_addr),
|
||||
.ch1_burst(128),
|
||||
|
@ -634,6 +662,11 @@ wire clk_hdmi = hdmi_clk_out;
|
|||
ascal
|
||||
#(
|
||||
.RAMBASE(32'h20000000),
|
||||
`ifdef MISTER_SMALL_VBUF
|
||||
.RAMSIZE(32'h00200000),
|
||||
`else
|
||||
.RAMSIZE(32'h00800000),
|
||||
`endif
|
||||
`ifndef MISTER_FB
|
||||
.PALETTE2("false"),
|
||||
`else
|
||||
|
@ -695,6 +728,8 @@ ascal
|
|||
.vdisp (HEIGHT),
|
||||
.vmin (vmin),
|
||||
.vmax (vmax),
|
||||
.vrr (vrr_mode),
|
||||
.vrrmax (HEIGHT + VBP + VS[11:0] + 12'd1),
|
||||
|
||||
.mode ({~lowlat,LFB_EN ? LFB_FLT : |scaler_flt,2'b00}),
|
||||
.poly_clk (clk_sys),
|
||||
|
@ -804,37 +839,40 @@ reg [11:0] vmax;
|
|||
reg [11:0] hdmi_height;
|
||||
reg [11:0] hdmi_width;
|
||||
|
||||
reg [11:0] arx;
|
||||
reg [11:0] ary;
|
||||
reg arxy;
|
||||
|
||||
always @(posedge clk_vid) begin
|
||||
reg [11:0] hmini,hmaxi,vmini,vmaxi;
|
||||
reg [11:0] wcalc,videow,arx;
|
||||
reg [11:0] hcalc,videoh,ary;
|
||||
reg [11:0] wcalc,videow;
|
||||
reg [11:0] hcalc,videoh;
|
||||
reg [2:0] state;
|
||||
reg xy;
|
||||
|
||||
hdmi_height <= (VSET && (VSET < HEIGHT)) ? VSET : HEIGHT;
|
||||
hdmi_width <= (HSET && (HSET < WIDTH)) ? HSET : WIDTH;
|
||||
hdmi_width <= (HSET && (HSET < WIDTH)) ? HSET << HDMI_PR : WIDTH << HDMI_PR;
|
||||
|
||||
if(!ARY) begin
|
||||
if(ARX == 1) begin
|
||||
arx <= arc1x[11:0];
|
||||
ary <= arc1y[11:0];
|
||||
xy <= arc1x[12] | arc1y[12];
|
||||
arxy <= arc1x[12] | arc1y[12];
|
||||
end
|
||||
else if(ARX == 2) begin
|
||||
arx <= arc2x[11:0];
|
||||
ary <= arc2y[11:0];
|
||||
xy <= arc2x[12] | arc2y[12];
|
||||
arxy <= arc2x[12] | arc2y[12];
|
||||
end
|
||||
else begin
|
||||
arx <= 0;
|
||||
ary <= 0;
|
||||
xy <= 0;
|
||||
arxy <= 0;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
arx <= ARX[11:0];
|
||||
ary <= ARY[11:0];
|
||||
xy <= ARX[12] | ARY[12];
|
||||
arxy <= ARX[12] | ARY[12];
|
||||
end
|
||||
|
||||
ar_md_start <= 0;
|
||||
|
@ -852,7 +890,7 @@ always @(posedge clk_vid) begin
|
|||
hcalc <= hdmi_height;
|
||||
state <= 6;
|
||||
end
|
||||
else if(xy) begin
|
||||
else if(arxy) begin
|
||||
wcalc <= arx;
|
||||
hcalc <= ary;
|
||||
state <= 6;
|
||||
|
@ -881,7 +919,7 @@ always @(posedge clk_vid) begin
|
|||
end
|
||||
|
||||
6: begin
|
||||
videow <= (wcalc > hdmi_width) ? hdmi_width : wcalc[11:0];
|
||||
videow <= (wcalc > hdmi_width) ? (hdmi_width >> HDMI_PR) : (wcalc[11:0] >> HDMI_PR);
|
||||
videoh <= (hcalc > hdmi_height) ? hdmi_height : hcalc[11:0];
|
||||
end
|
||||
|
||||
|
@ -907,7 +945,7 @@ pll_hdmi_adj pll_hdmi_adj
|
|||
.reset_na(~reset_req),
|
||||
|
||||
.llena(lowlat),
|
||||
.lltune({16{hdmi_config_done | cfg_dis}} & lltune),
|
||||
.lltune({16{cfg_done}} & lltune),
|
||||
.locked(led_locked),
|
||||
.i_waitrequest(adj_waitrequest),
|
||||
.i_write(adj_write),
|
||||
|
@ -963,6 +1001,7 @@ reg [11:0] HEIGHT = 1080;
|
|||
reg [11:0] VFP = 4;
|
||||
reg [12:0] VS = 5;
|
||||
reg [11:0] VBP = 36;
|
||||
reg HDMI_PR = 0;
|
||||
|
||||
wire [63:0] reconfig_to_pll;
|
||||
wire [63:0] reconfig_from_pll;
|
||||
|
@ -1035,22 +1074,6 @@ 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)
|
||||
);
|
||||
|
||||
assign HDMI_I2C_SCL = hdmi_scl_en ? 1'b0 : 1'bZ;
|
||||
assign HDMI_I2C_SDA = hdmi_sda_en ? 1'b0 : 1'bZ;
|
||||
|
||||
|
@ -1132,34 +1155,41 @@ csync csync_hdmi(clk_hdmi, hdmi_hs_osd, hdmi_vs_osd, hdmi_cs_osd);
|
|||
|
||||
reg [23:0] dv_data;
|
||||
reg dv_hs, dv_vs, dv_de;
|
||||
wire [23:0] dv_data_osd;
|
||||
wire dv_hs_osd, dv_vs_osd, dv_cs_osd;
|
||||
|
||||
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 [12:0] vsz, vcnt, vcnt_l, vcnt_ll;
|
||||
reg old_hs, old_vs;
|
||||
reg vde;
|
||||
reg [3:0] hss;
|
||||
|
||||
if(ce_pix) begin
|
||||
hss <= (hss << 1) | vga_hs_osd;
|
||||
hss <= (hss << 1) | dv_hs_osd;
|
||||
|
||||
old_hs <= vga_hs_osd;
|
||||
if(~old_hs && vga_hs_osd) begin
|
||||
old_vs <= vga_vs_osd;
|
||||
old_hs <= dv_hs_osd;
|
||||
if(~old_hs && dv_hs_osd) begin
|
||||
old_vs <= dv_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(~old_vs & dv_vs_osd) begin
|
||||
if (vcnt != vcnt_ll || vcnt < vcnt_l) vsz <= vcnt;
|
||||
vcnt_l <= vcnt;
|
||||
vcnt_ll <= vcnt_l;
|
||||
end
|
||||
if(old_vs & ~dv_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;
|
||||
dv_de1 <= !{hss,dv_hs_osd} && vde;
|
||||
dv_hs1 <= csync_en ? dv_cs_osd : dv_hs_osd;
|
||||
dv_vs1 <= dv_vs_osd;
|
||||
end
|
||||
|
||||
dv_d1 <= vga_data_osd;
|
||||
dv_d1 <= dv_data_osd;
|
||||
dv_d2 <= dv_d1;
|
||||
dv_de2 <= dv_de1;
|
||||
dv_hs2 <= dv_hs1;
|
||||
|
@ -1171,6 +1201,12 @@ always @(posedge clk_vid) begin
|
|||
dv_vs <= dv_vs2;
|
||||
end
|
||||
|
||||
`ifndef MISTER_DISABLE_YC
|
||||
assign {dv_data_osd, dv_hs_osd, dv_vs_osd, dv_cs_osd } = ~yc_en ? {vga_data_osd, vga_hs_osd, vga_vs_osd, vga_cs_osd } : {yc_o, yc_hs, yc_vs, yc_cs };
|
||||
`else
|
||||
assign {dv_data_osd, dv_hs_osd, dv_vs_osd, dv_cs_osd } = {vga_data_osd, vga_hs_osd, vga_vs_osd, vga_cs_osd };
|
||||
`endif
|
||||
|
||||
wire hdmi_tx_clk;
|
||||
`ifndef MISTER_DEBUG_NOHDMI
|
||||
cyclonev_clkselect hdmi_clk_sw
|
||||
|
@ -1289,6 +1325,7 @@ wire vga_cs_osd;
|
|||
csync csync_vga(clk_vid, vga_hs_osd, vga_vs_osd, vga_cs_osd);
|
||||
|
||||
`ifndef MISTER_DUAL_SDRAM
|
||||
wire VGA_DISABLE;
|
||||
wire [23:0] vgas_o;
|
||||
wire vgas_hs, vgas_vs, vgas_cs;
|
||||
vga_out vga_scaler_out
|
||||
|
@ -1305,8 +1342,8 @@ csync csync_vga(clk_vid, vga_hs_osd, vga_vs_osd, vga_cs_osd);
|
|||
.csync_o(vgas_cs)
|
||||
);
|
||||
|
||||
wire [23:0] vga_o;
|
||||
wire vga_hs, vga_vs, vga_cs;
|
||||
wire [23:0] vga_o, vga_o_t;
|
||||
wire vga_hs, vga_vs, vga_cs, vga_hs_t, vga_vs_t, vga_cs_t;
|
||||
vga_out vga_out
|
||||
(
|
||||
.clk(clk_vid),
|
||||
|
@ -1314,20 +1351,51 @@ csync csync_vga(clk_vid, vga_hs_osd, vga_vs_osd, vga_cs_osd);
|
|||
.hsync(vga_hs_osd),
|
||||
.vsync(vga_vs_osd),
|
||||
.csync(vga_cs_osd),
|
||||
.dout(vga_o),
|
||||
.dout(vga_o_t),
|
||||
.din(vga_data_osd),
|
||||
.hsync_o(vga_hs),
|
||||
.vsync_o(vga_vs),
|
||||
.csync_o(vga_cs)
|
||||
.hsync_o(vga_hs_t),
|
||||
.vsync_o(vga_vs_t),
|
||||
.csync_o(vga_cs_t)
|
||||
);
|
||||
|
||||
`ifndef MISTER_DISABLE_YC
|
||||
reg pal_en;
|
||||
reg yc_en;
|
||||
reg cvbs;
|
||||
reg [16:0] ColorBurst_Range;
|
||||
reg [39:0] PhaseInc;
|
||||
wire [23:0] yc_o;
|
||||
wire yc_hs, yc_vs, yc_cs;
|
||||
|
||||
yc_out yc_out
|
||||
(
|
||||
.clk(clk_vid),
|
||||
.PAL_EN(pal_en),
|
||||
.CVBS(cvbs),
|
||||
.PHASE_INC(PhaseInc),
|
||||
.COLORBURST_RANGE(ColorBurst_Range),
|
||||
.hsync(vga_hs_osd),
|
||||
.vsync(vga_vs_osd),
|
||||
.csync(vga_cs_osd),
|
||||
.dout(yc_o),
|
||||
.din(vga_data_osd),
|
||||
.hsync_o(yc_hs),
|
||||
.vsync_o(yc_vs),
|
||||
.csync_o(yc_cs)
|
||||
);
|
||||
|
||||
assign {vga_o, vga_hs, vga_vs, vga_cs } = ~yc_en ? {vga_o_t, vga_hs_t, vga_vs_t, vga_cs_t } : {yc_o, yc_hs, yc_vs, yc_cs };
|
||||
`else
|
||||
assign {vga_o, vga_hs, vga_vs, vga_cs } = {vga_o_t, vga_hs_t, vga_vs_t, vga_cs_t } ;
|
||||
`endif
|
||||
|
||||
wire cs1 = (vga_fb | vga_scaler) ? vgas_cs : vga_cs;
|
||||
|
||||
assign VGA_VS = (VGA_EN | SW[3]) ? 1'bZ :((((vga_fb | vga_scaler) ? ~vgas_vs : ~vga_vs) | csync_en) ^ VS[12]);
|
||||
assign VGA_HS = (VGA_EN | SW[3]) ? 1'bZ : (((vga_fb | vga_scaler) ? (csync_en ? ~vgas_cs : ~vgas_hs) : (csync_en ? ~vga_cs : ~vga_hs)) ^ HS[12]);
|
||||
assign VGA_R = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[23:18] : vga_o[23:18];
|
||||
assign VGA_G = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[15:10] : vga_o[15:10];
|
||||
assign VGA_B = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[7:2] : vga_o[7:2] ;
|
||||
assign VGA_VS = (VGA_EN | SW[3]) ? 1'bZ : (((vga_fb | vga_scaler) ? (~vgas_vs ^ VS[12]) : VGA_DISABLE ? 1'd1 : ~vga_vs) | csync_en);
|
||||
assign VGA_HS = (VGA_EN | SW[3]) ? 1'bZ : ((vga_fb | vga_scaler) ? ((csync_en ? ~vgas_cs : ~vgas_hs) ^ HS[12]) : VGA_DISABLE ? 1'd1 : (csync_en ? ~vga_cs : ~vga_hs));
|
||||
assign VGA_R = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[23:18] : VGA_DISABLE ? 6'd0 : vga_o[23:18];
|
||||
assign VGA_G = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[15:10] : VGA_DISABLE ? 6'd0 : vga_o[15:10];
|
||||
assign VGA_B = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[7:2] : VGA_DISABLE ? 6'd0 : vga_o[7:2] ;
|
||||
`endif
|
||||
|
||||
reg video_sync = 0;
|
||||
|
@ -1400,8 +1468,10 @@ audio_out audio_out
|
|||
.core_l(audio_l),
|
||||
.core_r(audio_r),
|
||||
|
||||
`ifndef MISTER_DISABLE_ALSA
|
||||
.alsa_l(alsa_l),
|
||||
.alsa_r(alsa_r),
|
||||
`endif
|
||||
|
||||
.i2s_bclk(HDMI_SCLK),
|
||||
.i2s_lrclk(HDMI_LRCLK),
|
||||
|
@ -1414,6 +1484,18 @@ audio_out audio_out
|
|||
);
|
||||
|
||||
|
||||
`ifndef MISTER_DISABLE_ALSA
|
||||
wire aspi_sck,aspi_mosi,aspi_ss,aspi_miso;
|
||||
cyclonev_hps_interface_peripheral_spi_master spi
|
||||
(
|
||||
.sclk_out(aspi_sck),
|
||||
.txd(aspi_mosi), // mosi
|
||||
.rxd(aspi_miso), // miso
|
||||
|
||||
.ss_0_n(aspi_ss),
|
||||
.ss_in_n(1)
|
||||
);
|
||||
|
||||
wire [28:0] alsa_address;
|
||||
wire [63:0] alsa_readdata;
|
||||
wire alsa_ready;
|
||||
|
@ -1440,6 +1522,7 @@ alsa alsa
|
|||
.pcm_l(alsa_l),
|
||||
.pcm_r(alsa_r)
|
||||
);
|
||||
`endif
|
||||
|
||||
//////////////// User I/O (USB 3.0 connector) /////////////////////////
|
||||
|
||||
|
@ -1560,6 +1643,10 @@ emu emu
|
|||
.VGA_F1(f1),
|
||||
.VGA_SCALER(vga_force_scaler),
|
||||
|
||||
`ifndef MISTER_DUAL_SDRAM
|
||||
.VGA_DISABLE(VGA_DISABLE),
|
||||
`endif
|
||||
|
||||
.HDMI_WIDTH(direct_video ? 12'd0 : hdmi_width),
|
||||
.HDMI_HEIGHT(direct_video ? 12'd0 : hdmi_height),
|
||||
.HDMI_FREEZE(freeze),
|
||||
|
|
|
@ -0,0 +1,230 @@
|
|||
//============================================================================
|
||||
// YC - Luma / Chroma Generation
|
||||
// Copyright (C) 2022 Mike Simone
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation; either version 2 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
// more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
//============================================================================
|
||||
/*
|
||||
Colorspace
|
||||
Y 0.299R' + 0.587G' + 0.114B'
|
||||
U 0.492(B' - Y) = 504 (X 1024)
|
||||
V 0.877(R' - Y) = 898 (X 1024)
|
||||
*/
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
module yc_out
|
||||
(
|
||||
input clk,
|
||||
input [39:0] PHASE_INC,
|
||||
input PAL_EN,
|
||||
input CVBS,
|
||||
input [16:0] COLORBURST_RANGE,
|
||||
|
||||
input hsync,
|
||||
input vsync,
|
||||
input csync,
|
||||
|
||||
input [23:0] din,
|
||||
output [23:0] dout,
|
||||
|
||||
output reg hsync_o,
|
||||
output reg vsync_o,
|
||||
output reg csync_o
|
||||
);
|
||||
|
||||
wire [7:0] red = din[23:16];
|
||||
wire [7:0] green = din[15:8];
|
||||
wire [7:0] blue = din[7:0];
|
||||
|
||||
logic [9:0] red_1, blue_1, green_1, red_2, blue_2, green_2;
|
||||
|
||||
logic signed [20:0] yr = 0, yb = 0, yg = 0;
|
||||
|
||||
typedef struct {
|
||||
logic signed [20:0] y;
|
||||
logic signed [20:0] c;
|
||||
logic signed [20:0] u;
|
||||
logic signed [20:0] v;
|
||||
logic hsync;
|
||||
logic vsync;
|
||||
logic csync;
|
||||
} phase_t;
|
||||
|
||||
localparam MAX_PHASES = 7'd8;
|
||||
|
||||
phase_t phase[MAX_PHASES];
|
||||
reg unsigned [7:0] Y, C, c, U, V;
|
||||
|
||||
|
||||
reg [10:0] cburst_phase; // colorburst counter
|
||||
reg unsigned [7:0] vref = 'd128; // Voltage reference point (Used for Chroma)
|
||||
logic [7:0] chroma_LUT_COS; // Chroma cos LUT reference
|
||||
logic [7:0] chroma_LUT_SIN; // Chroma sin LUT reference
|
||||
logic [7:0] chroma_LUT_BURST; // Chroma colorburst LUT reference
|
||||
logic [7:0] chroma_LUT = 8'd0;
|
||||
|
||||
/*
|
||||
THe following LUT table was calculated by Sin(2*pi*t/2^8) where t: 0 - 255
|
||||
*/
|
||||
|
||||
/*************************************
|
||||
8 bit Sine look up Table
|
||||
**************************************/
|
||||
wire signed [10:0] chroma_SIN_LUT[256] = '{
|
||||
11'h000, 11'h006, 11'h00C, 11'h012, 11'h018, 11'h01F, 11'h025, 11'h02B, 11'h031, 11'h037, 11'h03D, 11'h044, 11'h04A, 11'h04F,
|
||||
11'h055, 11'h05B, 11'h061, 11'h067, 11'h06D, 11'h072, 11'h078, 11'h07D, 11'h083, 11'h088, 11'h08D, 11'h092, 11'h097, 11'h09C,
|
||||
11'h0A1, 11'h0A6, 11'h0AB, 11'h0AF, 11'h0B4, 11'h0B8, 11'h0BC, 11'h0C1, 11'h0C5, 11'h0C9, 11'h0CC, 11'h0D0, 11'h0D4, 11'h0D7,
|
||||
11'h0DA, 11'h0DD, 11'h0E0, 11'h0E3, 11'h0E6, 11'h0E9, 11'h0EB, 11'h0ED, 11'h0F0, 11'h0F2, 11'h0F4, 11'h0F5, 11'h0F7, 11'h0F8,
|
||||
11'h0FA, 11'h0FB, 11'h0FC, 11'h0FD, 11'h0FD, 11'h0FE, 11'h0FE, 11'h0FE, 11'h0FF, 11'h0FE, 11'h0FE, 11'h0FE, 11'h0FD, 11'h0FD,
|
||||
11'h0FC, 11'h0FB, 11'h0FA, 11'h0F8, 11'h0F7, 11'h0F5, 11'h0F4, 11'h0F2, 11'h0F0, 11'h0ED, 11'h0EB, 11'h0E9, 11'h0E6, 11'h0E3,
|
||||
11'h0E0, 11'h0DD, 11'h0DA, 11'h0D7, 11'h0D4, 11'h0D0, 11'h0CC, 11'h0C9, 11'h0C5, 11'h0C1, 11'h0BC, 11'h0B8, 11'h0B4, 11'h0AF,
|
||||
11'h0AB, 11'h0A6, 11'h0A1, 11'h09C, 11'h097, 11'h092, 11'h08D, 11'h088, 11'h083, 11'h07D, 11'h078, 11'h072, 11'h06D, 11'h067,
|
||||
11'h061, 11'h05B, 11'h055, 11'h04F, 11'h04A, 11'h044, 11'h03D, 11'h037, 11'h031, 11'h02B, 11'h025, 11'h01F, 11'h018, 11'h012,
|
||||
11'h00C, 11'h006, 11'h000, 11'h7F9, 11'h7F3, 11'h7ED, 11'h7E7, 11'h7E0, 11'h7DA, 11'h7D4, 11'h7CE, 11'h7C8, 11'h7C2, 11'h7BB,
|
||||
11'h7B5, 11'h7B0, 11'h7AA, 11'h7A4, 11'h79E, 11'h798, 11'h792, 11'h78D, 11'h787, 11'h782, 11'h77C, 11'h777, 11'h772, 11'h76D,
|
||||
11'h768, 11'h763, 11'h75E, 11'h759, 11'h754, 11'h750, 11'h74B, 11'h747, 11'h743, 11'h73E, 11'h73A, 11'h736, 11'h733, 11'h72F,
|
||||
11'h72B, 11'h728, 11'h725, 11'h722, 11'h71F, 11'h71C, 11'h719, 11'h716, 11'h714, 11'h712, 11'h70F, 11'h70D, 11'h70B, 11'h70A,
|
||||
11'h708, 11'h707, 11'h705, 11'h704, 11'h703, 11'h702, 11'h702, 11'h701, 11'h701, 11'h701, 11'h701, 11'h701, 11'h701, 11'h701,
|
||||
11'h702, 11'h702, 11'h703, 11'h704, 11'h705, 11'h707, 11'h708, 11'h70A, 11'h70B, 11'h70D, 11'h70F, 11'h712, 11'h714, 11'h716,
|
||||
11'h719, 11'h71C, 11'h71F, 11'h722, 11'h725, 11'h728, 11'h72B, 11'h72F, 11'h733, 11'h736, 11'h73A, 11'h73E, 11'h743, 11'h747,
|
||||
11'h74B, 11'h750, 11'h754, 11'h759, 11'h75E, 11'h763, 11'h768, 11'h76D, 11'h772, 11'h777, 11'h77C, 11'h782, 11'h787, 11'h78D,
|
||||
11'h792, 11'h798, 11'h79E, 11'h7A4, 11'h7AA, 11'h7B0, 11'h7B5, 11'h7BB, 11'h7C2, 11'h7C8, 11'h7CE, 11'h7D4, 11'h7DA, 11'h7E0,
|
||||
11'h7E7, 11'h7ED, 11'h7F3, 11'h7F9
|
||||
};
|
||||
|
||||
logic [39:0] phase_accum;
|
||||
logic PAL_FLIP = 1'd0;
|
||||
logic PAL_line_count = 1'd0;
|
||||
|
||||
/**************************************
|
||||
Generate Luma and Chroma Signals
|
||||
***************************************/
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
for (logic [3:0] x = 0; x < (MAX_PHASES - 1'd1); x = x + 1'd1) begin
|
||||
phase[x + 1] <= phase[x];
|
||||
end
|
||||
|
||||
// delay red / blue signals to align luma with U/V calculation (Fixes colorbleeding)
|
||||
red_1 <= red;
|
||||
blue_1 <= blue;
|
||||
red_2 <= red_1;
|
||||
blue_2 <= blue_1;
|
||||
|
||||
// Calculate Luma signal
|
||||
yr <= {red, 8'd0} + {red, 5'd0}+ {red, 4'd0} + {red, 1'd0};
|
||||
yg <= {green, 9'd0} + {green, 6'd0} + {green, 4'd0} + {green, 3'd0} + green;
|
||||
yb <= {blue, 6'd0} + {blue, 5'd0} + {blue, 4'd0} + {blue, 2'd0} + blue;
|
||||
phase[0].y <= yr + yg + yb;
|
||||
|
||||
// Generate the LUT values using the phase accumulator reference.
|
||||
phase_accum <= phase_accum + PHASE_INC;
|
||||
chroma_LUT <= phase_accum[39:32];
|
||||
|
||||
// Adjust SINE carrier reference for PAL (Also adjust for PAL Switch)
|
||||
if (PAL_EN) begin
|
||||
if (PAL_FLIP)
|
||||
chroma_LUT_BURST <= chroma_LUT + 8'd160;
|
||||
else
|
||||
chroma_LUT_BURST <= chroma_LUT + 8'd96;
|
||||
end else // Adjust SINE carrier reference for NTSC
|
||||
chroma_LUT_BURST <= chroma_LUT + 8'd128;
|
||||
|
||||
// Prepare LUT values for sin / cos (+90 degress)
|
||||
chroma_LUT_SIN <= chroma_LUT;
|
||||
chroma_LUT_COS <= chroma_LUT + 8'd64;
|
||||
|
||||
// Calculate for U, V - Bit Shift Multiple by u = by * 1024 x 0.492 = 504, v = ry * 1024 x 0.877 = 898
|
||||
phase[0].u <= $signed({2'b0 ,(blue_2)}) - $signed({2'b0 ,phase[0].y[17:10]});
|
||||
phase[0].v <= $signed({2'b0 , (red_2)}) - $signed({2'b0 ,phase[0].y[17:10]});
|
||||
phase[1].u <= 21'($signed({phase[0].u, 8'd0}) + $signed({phase[0].u, 7'd0}) + $signed({phase[0].u, 6'd0}) + $signed({phase[0].u, 5'd0}) + $signed({phase[0].u, 4'd0}) + $signed({phase[0].u, 3'd0}));
|
||||
phase[1].v <= 21'($signed({phase[0].v, 9'd0}) + $signed({phase[0].v, 8'd0}) + $signed({phase[0].v, 7'd0}) + $signed({phase[0].v, 1'd0}));
|
||||
|
||||
phase[0].c <= vref;
|
||||
phase[1].c <= phase[0].c;
|
||||
phase[2].c <= phase[1].c;
|
||||
phase[3].c <= phase[2].c;
|
||||
|
||||
if (hsync) begin // Reset colorburst counter, as well as the calculated cos / sin values.
|
||||
cburst_phase <= 'd0;
|
||||
phase[2].u <= 21'b0;
|
||||
phase[2].v <= 21'b0;
|
||||
phase[4].c <= phase[3].c;
|
||||
|
||||
if (PAL_line_count) begin
|
||||
PAL_FLIP <= ~PAL_FLIP;
|
||||
PAL_line_count <= ~PAL_line_count;
|
||||
end
|
||||
end
|
||||
else begin // Generate Colorburst for 9 cycles
|
||||
if (cburst_phase >= COLORBURST_RANGE[16:10] && cburst_phase <= COLORBURST_RANGE[9:0]) begin // Start the color burst signal at 40 samples or 0.9 us
|
||||
// COLORBURST SIGNAL GENERATION (9 CYCLES ONLY or between count 40 - 240)
|
||||
phase[2].u <= $signed({chroma_SIN_LUT[chroma_LUT_BURST],5'd0});
|
||||
phase[2].v <= 21'b0;
|
||||
|
||||
// Division to scale down the results to fit 8 bit.
|
||||
if (PAL_EN)
|
||||
phase[3].u <= $signed(phase[2].u[20:8]) + $signed(phase[2].u[20:10]) + $signed(phase[2].u[20:14]);
|
||||
else
|
||||
phase[3].u <= $signed(phase[2].u[20:8]) + $signed(phase[2].u[20:11]) + $signed(phase[2].u[20:12]) + $signed(phase[2].u[20:13]);
|
||||
|
||||
phase[3].v <= phase[2].v;
|
||||
end else begin // MODULATE U, V for chroma
|
||||
/*
|
||||
U,V are both multiplied by 1024 earlier to scale for the decimals in the YUV colorspace conversion.
|
||||
U and V are both divided by 2^10 which introduce chroma subsampling of 4:1:1 (25% or from 8 bit to 6 bit)
|
||||
*/
|
||||
phase[2].u <= $signed((phase[1].u)>>>10) * $signed(chroma_SIN_LUT[chroma_LUT_SIN]);
|
||||
phase[2].v <= $signed((phase[1].v)>>>10) * $signed(chroma_SIN_LUT[chroma_LUT_COS]);
|
||||
|
||||
// Divide U*sin(wt) and V*cos(wt) to fit results to 8 bit
|
||||
phase[3].u <= $signed(phase[2].u[20:9]) + $signed(phase[2].u[20:10]) + $signed(phase[2].u[20:14]);
|
||||
phase[3].v <= $signed(phase[2].v[20:9]) + $signed(phase[2].v[20:10]) + $signed(phase[2].u[20:14]);
|
||||
end
|
||||
|
||||
// Stop the colorburst timer as its only needed for the initial pulse
|
||||
if (cburst_phase <= COLORBURST_RANGE[9:0])
|
||||
cburst_phase <= cburst_phase + 9'd1;
|
||||
|
||||
// Calculate for chroma (Note: "PAL SWITCH" routine flips V * COS(Wt) every other line)
|
||||
if (PAL_EN) begin
|
||||
if (PAL_FLIP)
|
||||
phase[4].c <= vref + phase[3].u - phase[3].v;
|
||||
else
|
||||
phase[4].c <= vref + phase[3].u + phase[3].v;
|
||||
PAL_line_count <= 1'd1;
|
||||
end else
|
||||
phase[4].c <= vref + phase[3].u + phase[3].v;
|
||||
end
|
||||
|
||||
// Adjust sync timing correctly
|
||||
phase[1].hsync <= hsync; phase[1].vsync <= vsync; phase[1].csync <= csync;
|
||||
phase[2].hsync <= phase[1].hsync; phase[2].vsync <= phase[1].vsync; phase[2].csync <= phase[1].csync;
|
||||
phase[3].hsync <= phase[2].hsync; phase[3].vsync <= phase[2].vsync; phase[3].csync <= phase[2].csync;
|
||||
phase[4].hsync <= phase[3].hsync; phase[4].vsync <= phase[3].vsync; phase[4].csync <= phase[3].csync;
|
||||
hsync_o <= phase[4].hsync; vsync_o <= phase[4].vsync; csync_o <= phase[4].csync;
|
||||
|
||||
phase[1].y <= phase[0].y; phase[2].y <= phase[1].y; phase[3].y <= phase[2].y; phase[4].y <= phase[3].y; phase[5].y <= phase[4].y;
|
||||
|
||||
// Set Chroma / Luma output
|
||||
C <= CVBS ? 8'd0 : phase[4].c[7:0];
|
||||
Y <= CVBS ? ({1'b0, phase[5].y[17:11]} + {1'b0, phase[4].c[7:1]}) : phase[5].y[17:10];
|
||||
end
|
||||
|
||||
assign dout = {C, Y, 8'd0};
|
||||
|
||||
endmodule
|
||||
|
Loading…
Reference in New Issue