kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
vhdl_YUV: Extend offset to 7 bits and eliminate fixed delay (v8.0)
Change-Id: I84e26f1b968cb035c3371ca25812fb0d9bc54c4byuv80
rodzic
3109879451
commit
7ab3e15574
|
@ -71,6 +71,7 @@ static int supports_alt_r = 0; /* Supports R channel inversion on alternate line
|
|||
static int supports_edge = 0; /* Selection of leading rather than trailing edge */
|
||||
static int supports_clamptype = 0; /* Selection of back porch or sync tip clamping */
|
||||
static int supports_delay = 0; /* A 0-3 pixel delay */
|
||||
static int supports_extended_delay = 0; /* A 0-15 pixel delay */
|
||||
|
||||
// invert state (not part of config)
|
||||
static int invert = 0;
|
||||
|
@ -197,7 +198,7 @@ static void write_config(config_t *config) {
|
|||
// Use 4 bits of offset and 1 bit of delay
|
||||
sp |= (config->sp_offset & 15) << scan_len;
|
||||
scan_len += 4;
|
||||
sp |= ((~config->delay >> 1) & 1) << scan_len;
|
||||
sp |= ((~config->delay >> 1) & 1) << scan_len;
|
||||
scan_len += 1;
|
||||
} else {
|
||||
// Use 3 bits of offset and 2 bit of delay
|
||||
|
@ -211,6 +212,11 @@ static void write_config(config_t *config) {
|
|||
scan_len += 4;
|
||||
}
|
||||
|
||||
if (supports_extended_delay) {
|
||||
sp |= ((~config->delay >> 2) & 3) << scan_len;
|
||||
scan_len += 2;
|
||||
}
|
||||
|
||||
sp |= config->filter_c << scan_len;
|
||||
scan_len++;
|
||||
|
||||
|
@ -326,6 +332,9 @@ static void cpld_init(int version) {
|
|||
// CPLDv4 adds support for chroma subsampling
|
||||
// CPLDv5 adds support for inversion of R on alternative lines
|
||||
// CPLDv4 adds support for sync edge selection and 2-bit pixel delay
|
||||
if (major >= 8) {
|
||||
supports_extended_delay = 1;
|
||||
}
|
||||
if (major >= 7) {
|
||||
supports_clamptype = 1;
|
||||
}
|
||||
|
@ -624,7 +633,11 @@ static int cpld_get_divider() {
|
|||
}
|
||||
|
||||
static int cpld_get_delay() {
|
||||
return cpld_get_value(DELAY);
|
||||
if (supports_extended_delay) {
|
||||
return 0;
|
||||
} else {
|
||||
return cpld_get_value(DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
static int cpld_frontend_info() {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
sampling=7,1,1,0,1,1,2,8,0,108,65,176,125,255,230,0,150
|
||||
geometry=52,54,272,200,384,288,1,1,3,8,7000000,448,5000,312,5,0
|
||||
geometry=68,54,272,200,384,288,1,1,3,8,7000000,448,5000,312,5,0
|
||||
palette=Spectrum_48K_9_Col
|
||||
output_invert=2
|
||||
|
|
Plik binarny nie jest wyświetlany.
|
@ -49,31 +49,30 @@ architecture Behavorial of RGBtoHDMI is
|
|||
|
||||
-- Version number: Design_Major_Minor
|
||||
-- Design: 0 = Normal CPLD, 1 = Alternative CPLD, 2=Atom CPLD, 3=YUV6847 CPLD
|
||||
constant VERSION_NUM : std_logic_vector(11 downto 0) := x"375";
|
||||
constant VERSION_NUM : std_logic_vector(11 downto 0) := x"380";
|
||||
|
||||
-- NOTE: the difference between the leading and trailing offsets is
|
||||
-- 256 clks = 32 pixel clocks.
|
||||
|
||||
-- Default offset to start sampling at when using the leading edge of sync
|
||||
constant leading_offset : unsigned(9 downto 0) := to_unsigned(1024 - 512, 10);
|
||||
|
||||
-- Default offset to start sampling at when using the trailing edge of sync
|
||||
constant trailing_offset : unsigned(9 downto 0) := to_unsigned(1024 - 256, 10);
|
||||
|
||||
-- Sampling points
|
||||
constant INIT_SAMPLING_POINTS : std_logic_vector(12 downto 0) := "0000001100000";
|
||||
constant INIT_SAMPLING_POINTS : std_logic_vector(14 downto 0) := "000000110000000";
|
||||
|
||||
-- The sampling counter runs at 8x pixel clock
|
||||
signal counter : unsigned(9 downto 0);
|
||||
-- The counter runs at 8x pixel clock and controls all aspects of sampling
|
||||
signal counter : unsigned(6 downto 0);
|
||||
|
||||
signal clamp_counter : unsigned(1 downto 0);
|
||||
signal start_clamp : std_logic;
|
||||
-- This used to be the top bit of counter, but it's really logically seperate
|
||||
-- It controls when psync is active
|
||||
signal sampling : std_logic;
|
||||
|
||||
-- The misc counter (used for VSYNC detection and Clamp)
|
||||
signal misc_tick : std_logic;
|
||||
signal misc_counter : unsigned(2 downto 0);
|
||||
|
||||
-- Sample point register;
|
||||
signal sp_reg : std_logic_vector(12 downto 0) := INIT_SAMPLING_POINTS;
|
||||
signal sp_reg : std_logic_vector(14 downto 0) := INIT_SAMPLING_POINTS;
|
||||
|
||||
-- Break out of sp_reg
|
||||
signal offset : unsigned (4 downto 0);
|
||||
signal offset : unsigned (6 downto 0);
|
||||
signal filter_C : std_logic;
|
||||
signal filter_L : std_logic;
|
||||
signal invert : std_logic;
|
||||
|
@ -85,7 +84,6 @@ architecture Behavorial of RGBtoHDMI is
|
|||
-- State to determine whether to invert A
|
||||
signal inv_R : std_logic;
|
||||
|
||||
|
||||
-- R/PA/PB processing pipeline
|
||||
signal AL1 : std_logic;
|
||||
signal AH1 : std_logic;
|
||||
|
@ -118,6 +116,8 @@ architecture Behavorial of RGBtoHDMI is
|
|||
signal HS1 : std_logic;
|
||||
signal HS2 : std_logic;
|
||||
signal HS3 : std_logic;
|
||||
signal HS4 : std_logic;
|
||||
signal HS5 : std_logic;
|
||||
|
||||
signal LL_S : std_logic;
|
||||
signal LH_S : std_logic;
|
||||
|
@ -125,19 +125,20 @@ architecture Behavorial of RGBtoHDMI is
|
|||
|
||||
signal sample_L : std_logic;
|
||||
signal sample_AB : std_logic;
|
||||
signal sample_Q : std_logic;
|
||||
|
||||
signal HS_counter : unsigned(1 downto 0);
|
||||
|
||||
begin
|
||||
-- Offset is inverted as we count upwards to 0
|
||||
offset <= unsigned(sp_reg(4 downto 0) xor "11111");
|
||||
filter_C <= sp_reg(5);
|
||||
filter_L <= sp_reg(6);
|
||||
invert <= sp_reg(7);
|
||||
subsam_C <= sp_reg(8);
|
||||
alt_R <= sp_reg(9);
|
||||
edge <= sp_reg(10);
|
||||
clamp_size <= unsigned(sp_reg(12 downto 11));
|
||||
offset <= unsigned(sp_reg(6 downto 0) xor "1111111");
|
||||
filter_C <= sp_reg(7);
|
||||
filter_L <= sp_reg(8);
|
||||
invert <= sp_reg(9);
|
||||
subsam_C <= sp_reg(10);
|
||||
alt_R <= sp_reg(11);
|
||||
edge <= sp_reg(12);
|
||||
clamp_size <= unsigned(sp_reg(14 downto 13));
|
||||
|
||||
swap_bits <= FS_I when mux = '1' else '0';
|
||||
|
||||
|
@ -222,31 +223,22 @@ begin
|
|||
end if;
|
||||
|
||||
HS3 <= HS2;
|
||||
HS4 <= HS3;
|
||||
HS5 <= HS4;
|
||||
|
||||
-- Counter is used to find sampling point for first pixel
|
||||
if HS3 = '1' and HS2 = '0' then
|
||||
-- leading edge, reset the counter to measure the sync pulse
|
||||
counter <= leading_offset or offset;
|
||||
if alt_R = '1' then
|
||||
inv_R <= not inv_R;
|
||||
else
|
||||
inv_R <= '0';
|
||||
end if;
|
||||
elsif HS3 = '0' and HS2 = '1' and edge = '0' then
|
||||
-- trailing edge, if edge=0 (trailing) then reset the counter
|
||||
counter <= trailing_offset or offset;
|
||||
elsif counter(counter'left) = '1' then
|
||||
-- if HS remains low of 1FF cycles, we have the Spectrum FS
|
||||
-- (1FF cycles is 9.125 us)
|
||||
if HS2 = '0' and "000" & counter(8 downto 0) = x"1FF" then
|
||||
-- synchronise inv_R to frame sync pulse
|
||||
if alt_R = '1' then
|
||||
inv_R <= '1';
|
||||
end if;
|
||||
end if;
|
||||
counter <= counter + 1;
|
||||
if (HS3 = '1' and HS2 = '0' and edge = '1') or (HS3 = '0' and HS2 = '1' and edge = '0') then
|
||||
counter <= offset;
|
||||
else
|
||||
counter(6 downto 0) <= counter(6 downto 0) + 1;
|
||||
counter <= counter + 1;
|
||||
end if;
|
||||
|
||||
if HS3 = '0' and HS2 = '1' then
|
||||
-- Stop sampling on the trailing edge of HSYNC
|
||||
sampling <= '0';
|
||||
elsif HS2 = '1' and counter = "1111111" then
|
||||
-- Start sampling when the counter expires
|
||||
sampling <= '1';
|
||||
end if;
|
||||
|
||||
-- Registers for Chroma / Luma Filtering
|
||||
|
@ -283,6 +275,12 @@ begin
|
|||
sample_L <= '0';
|
||||
end if;
|
||||
|
||||
if counter(3 downto 0) = "1111" then
|
||||
sample_Q <= '1';
|
||||
else
|
||||
sample_Q <= '0';
|
||||
end if;
|
||||
|
||||
-- sample colour signal
|
||||
if sample_AB = '1' then
|
||||
AL <= AL_next;
|
||||
|
@ -320,8 +318,8 @@ begin
|
|||
if version = '0' then
|
||||
quad <= VERSION_NUM;
|
||||
psync <= FS_I;
|
||||
elsif counter(counter'left) = '0' then
|
||||
if counter(3 downto 0) = "0000" then
|
||||
elsif sampling = '1' then
|
||||
if sample_Q = '1' then
|
||||
quad(11 downto 6) <= BL_next & LL_next & AL_next & BH_next & LH_next & AH_next;
|
||||
quad( 5 downto 0) <= BL & LL & AL & BH & LH & AH;
|
||||
end if;
|
||||
|
@ -333,28 +331,54 @@ begin
|
|||
psync <= '0';
|
||||
end if;
|
||||
|
||||
if HS3 = '0' and HS2 = '1' then
|
||||
start_clamp <= '1';
|
||||
-- misc_counter has two uses:
|
||||
--
|
||||
-- 1. During HSYNC it measures the duration of HSYNC as a crude
|
||||
-- VSYNC detector, which is used for PAL inversion
|
||||
-- 2. After HSYNC it determines the duration of the clamp counter
|
||||
--
|
||||
-- Misc counter deccrements every 128 cycles
|
||||
--
|
||||
-- HSYNC is nominally 4.7us long (~32 pixels == 256 cycles)
|
||||
-- VSYNC is nominally 256 us long (1792 pixels == 14336 cycles)
|
||||
|
||||
if counter = offset then
|
||||
misc_tick <= '1';
|
||||
else
|
||||
start_clamp <= '0';
|
||||
misc_tick <= '0';
|
||||
end if;
|
||||
|
||||
if start_clamp = '1' then
|
||||
-- start at the trailing edge of HSYNC
|
||||
clamp_counter <= clamp_size;
|
||||
elsif clamp_counter /= "00" and counter(6 downto 0) = ("00" & offset) then
|
||||
clamp_counter <= clamp_counter - 1;
|
||||
if HS5 = '1' and HS4 = '0' then
|
||||
-- leading edge, load misc_counter to measure HSYNC duration
|
||||
misc_counter <= (others => '1');
|
||||
elsif HS5 = '0' and HS4 = '1' then
|
||||
-- trailing edge, load misc_counter to generate clamp
|
||||
misc_counter <= '0' & clamp_size;
|
||||
elsif misc_tick = '1' and misc_counter /= 0 then
|
||||
misc_counter <= misc_counter - 1;
|
||||
end if;
|
||||
|
||||
-- generate the clamp output
|
||||
if clamp_size = "00" then
|
||||
-- Generate the clamp output
|
||||
if clamp_size = 0 then
|
||||
clamp <= not(HS1 or HS2);
|
||||
elsif clamp_counter = "00" then
|
||||
elsif misc_counter = 0 then
|
||||
clamp <= '0';
|
||||
else
|
||||
elsif HS4 = '1' then
|
||||
clamp <= '1';
|
||||
end if;
|
||||
|
||||
-- PAL Inversion
|
||||
if alt_R <= '0' then
|
||||
inv_R <= '0';
|
||||
elsif HS5 = '1' and HS4 = '0' then
|
||||
-- leading edge, toggle PAL inversion if enabled
|
||||
inv_R <= not inv_R;
|
||||
elsif HS5 = '0' and misc_counter = 0 then
|
||||
-- if HSYNC remains low for >= 7 * 128 cycles we have VSYNC
|
||||
-- synchronise inv_R when VSYNC detected
|
||||
inv_R <= '1';
|
||||
end if;
|
||||
|
||||
-- generate the csync output
|
||||
csync <= HS2;
|
||||
|
||||
|
|
Plik binarny nie jest wyświetlany.
|
@ -118,3 +118,14 @@ FB3 14/18 37/54 88/90 9/ 9*
|
|||
FB4 17/18 36/54 82/90 6/ 7
|
||||
----- ----- ----- -----
|
||||
66/72 137/216 294/360 29/34
|
||||
|
||||
Extend offset to 7 bits and eliminate fixed delay (v8.0)
|
||||
|
||||
Function Mcells FB Inps Pterms IO
|
||||
Block Used/Tot Used/Tot Used/Tot Used/Tot
|
||||
FB1 18/18* 40/54 55/90 6/ 9
|
||||
FB2 18/18* 23/54 35/90 8/ 9
|
||||
FB3 17/18 34/54 90/90* 9/ 9*
|
||||
FB4 17/18 39/54 84/90 6/ 7
|
||||
----- ----- ----- -----
|
||||
70/72 136/216 264/360 29/34
|
||||
|
|
Ładowanie…
Reference in New Issue