Я пытаюсь работать с пиксельными данными, которые выводятся на микросхему DVI. Используются различные тактовые частоты, потому что регистры микросхемы DVI программируются с использованием I2C (поэтому требуется тактовая частота <500 кГц) - от делителя тактовой частоты.
Микросхему DVI требуется дифференциальная тактовая частота пикселей 40 МГц, однако DVI отображает полбайта дважды за цикл, поэтому необходимы дополнительные тактовые импульсы 80 МГц, чтобы проталкивать каждую половину пикселя на линии данных с каждым полупериодом. из DCM.
Это привело к множеству проблем. Я попытался просто использовать двойную тактовую частоту пикселя, чтобы поменять местами каждую половину пикселя, но получил ошибку:
This design contains a global buffer instance, <out2_bufg>,
driving the net, <pxlclk_p_int>, that is driving the following (first 30)
non-clock load pins.
Поэтому я добавил элемент BUFG между выходом DCM и компонентами, использующими сигнал, но он ничего не изменил, вместо этого ошибка теперь выдается дважды как на входе, так и на выходе BUFG.
- Как я могу это исправить - учитывая, что я только что добавил BUFG, и он ему не нравится!
Мой код ниже; Я попытался вырезать несвязанные вещи, которые не имеют отношения к часам, но они все еще довольно длинные!
РЕДАКТИРОВАТЬ 1: Я добавил блок, который при добавлении в систему вызвал ошибку (которой раньше не было). Это во втором блоке кода! В настоящее время я работаю над другими предложениями, касающимися дифференциальной сигнализации, и буду редактировать снова, когда закончу!
Спасибо большое,
Дэйвид
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
library UNISIM;
use UNISIM.VComponents.all;
ENTITY I2CBus IS
PORT(
SYSCLK_N : IN STD_LOGIC; --system 200MHz differential clock
SYSCLK_P : IN STD_LOGIC;
BTN : IN STD_LOGIC; -- to manually change reset
LED : OUT STD_LOGIC_VECTOR(3 downto 0); --to observe reset value
SCL_DBG : OUT STD_LOGIC; -- copy of SCL to output pin
SDA_DBG : OUT STD_LOGIC; --copy of SDA to output pin
SCL : OUT STD_LOGIC; --Serial Clock Line
SDA : INOUT STD_LOGIC; --Serial Data Line
DVIRESET_N : OUT STD_LOGIC; --reset_n to dvi device
DVI_ENABLE : OUT STD_LOGIC; --enable DVI device inputs (active high)
PXLCLK_P : OUT STD_LOGIC; --pixel clock differential pair through buffers
PXLCLK_N : OUT STD_LOGIC;
DVI_DATA : OUT STD_LOGIC_VECTOR(11 downto 0); --12 bit multiplexed pixel to DVI
HSYNC : OUT STD_LOGIC; --Horizontal/Vertical sync timing pulses
VSYNC : OUT STD_LOGIC
);
END I2CBus;
ARCHITECTURE behavior OF I2CBus IS
COMPONENT IIC_MASTER --sends data to write out onto SDA bus line in I2C protocol
PORT(SCL : IN STD_LOGIC;
SCL2X : IN STD_LOGIC;
RESET_N : IN STD_LOGIC;
ENA : IN STD_LOGIC;
ADR : IN STD_LOGIC_VECTOR(6 DOWNTO 0);
REG : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
RW : IN STD_LOGIC;
DAT_WR : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
BUSY : OUT STD_LOGIC;
SDA : INOUT STD_LOGIC;
ACK_ERR : BUFFER STD_LOGIC);
END COMPONENT IIC_MASTER;
COMPONENT DCM --takes input system differential clocks, generates further clocks
PORT(
SYSCLK_P : IN STD_LOGIC; -- CLOCK IN PORTS 200MHZ DIFFERENTIAL
SYSCLK_N : IN STD_LOGIC;
-- CLOCK OUT PORTS
SYSCLK : OUT STD_LOGIC;
PXLCLK : OUT STD_LOGIC;
PXLCLK2X : OUT STD_LOGIC
);
END COMPONENT;
COMPONENT CLK_DIVIDER --divides system clock down for i2c bus clock line
GENERIC(INPUT_FREQ : INTEGER;
OUT1_FREQ : INTEGER;
OUT2_FREQ : INTEGER);
PORT(SYSCLK : IN STD_LOGIC;
RESET_N : IN STD_LOGIC;
RESET_N_OUT : OUT STD_LOGIC;
OUT1 : OUT STD_LOGIC;
OUT2 : OUT STD_LOGIC);
END COMPONENT CLK_DIVIDER;
COMPONENT DVI_INITIALISE --initialises CH7301c registers to necessary operation values
PORT(SYSCLK : IN STD_LOGIC;
ACK_ERR : IN STD_LOGIC;
BUSY : IN STD_LOGIC;
RESET_N : IN STD_LOGIC;
COUNT : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
DVI_WR : OUT STD_LOGIC := '0';
DVI_REGDATA : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
DVI_WDATA : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END COMPONENT DVI_INITIALISE;
COMPONENT DVI_INTERFACE --outputs sync pulses, controls enable and manages pixel addresses
PORT(PIXEL_CLK : IN STD_LOGIC;
RESET_N : IN STD_LOGIC;
PXL_ADDR : OUT STD_LOGIC_VECTOR(19 DOWNTO 0) := (OTHERS => '0');
HSYNC, VSYNC : OUT STD_LOGIC := '1';
ENABLE : OUT STD_LOGIC := '0');
END COMPONENT DVI_INTERFACE;
COMPONENT DVI_MUX
PORT(PXLCLK : IN STD_LOGIC;
PXLCLK2X : IN STD_LOGIC;
PXL_DAT : IN STD_LOGIC_VECTOR(23 DOWNTO 0); --pixel as RGB
DATA : OUT STD_LOGIC_VECTOR(11 DOWNTO 0); --multiplexed output
RESET_N : IN STD_LOGIC); --reset low signal
END COMPONENT DVI_MUX;
--Inputs
signal reset_n_input : std_logic; -- input reset from button
----Outputs ------
signal sda_internal : STD_LOGIC; -- Internal SDA
----Clocks-----
signal SCL_internal : std_logic; -- i2c clock
signal SCL2X_internal : std_logic; -- i2c x2 to load SDA data
signal sysclk : std_logic; --system clock
signal pxlclk_p_int : std_logic; --differential pixel clock pair
signal pxlclk_n_int : std_logic;
signal pxlclk : std_logic; --pxlclk after BUFG
signal pxlclk2x_int : STD_LOGIC; --2x pixel clock for loading pixel data
-----Internal Control Signals ---
signal reset_n : std_logic; --active high
signal busy : std_logic; --low when not i2c not busy
signal ack_err : std_logic; --high when i2c ackknowledge error occurs
----Internal Data-----
signal i2c_reg : STD_LOGIC_VECTOR(7 DOWNTO 0); --register data for I2C
signal i2c_rw : STD_LOGIC; --R/W* for I2C
signal i2c_data : STD_LOGIC_VECTOR(7 DOWNTO 0); --Data for I2C
BEGIN
master : IIC_Master
port map(
SCL => SCL_internal,
SCL2X => SCL2X_internal,
RESET_N => RESET_N,
ENA => '1',
ADR => "1110110",
REG => i2c_reg,
RW => i2c_rw,
DAT_WR => i2c_data,
BUSY => busy,
SDA => sda_internal,
ACK_ERR => ack_err
);
DCM_SYS : DCM
port map(
SYSCLK_P => SYSCLK_P, --take differential input clock
SYSCLK_N => SYSCLK_N,
SYSCLK => sysclk, --200 MHz system clock
PXLCLK => pxlclk, --and pixel clock
PXLCLK2X => pxlclk2x_int --pixel clock at double rate
);
Clk_Div : Clk_Divider
generic map(
INPUT_FREQ => 200000000, --200 MHz system input
OUT1_FREQ => 100000, --to work correctly, 200 must go into all frequencies (x2).
OUT2_FREQ => 200000 --i.e. from 200, cannot generate 40 as 200/40/2 = 2.5, which will be 2
)
port map(
SYSCLK => sysclk,
RESET_N => reset_n_input,
RESET_N_OUT => reset_n,
OUT1 => scl_internal,
OUT2 => scl2x_internal
);
data_load : component DVI_INITIALISE
port map(
SYSCLK => sysclk,
ACK_ERR => ack_err,
BUSY => busy,
RESET_N => reset_n,
COUNT => LED,
DVI_WR => i2c_rw,
DVI_REGDATA => i2c_reg,
DVI_WDATA => i2c_data
);
interface : DVI_INTERFACE
port map(
PIXEL_CLK => pxlclk_p_int,
RESET_N => reset_n,
PXL_ADDR => open,
HSYNC => HSYNC,
VSYNC => VSYNC,
ENABLE => DVI_ENABLE
);
pxl_mux : DVI_MUX
port map(
PXLCLK => pxlclk_p_int,
PXLCLK2X => pxlclk2x_int,
PXL_DAT => x"FF0000",
DATA => DVI_DATA,
RESET_N => reset_n
);
------------OUTPUT BUFFERS (CLOCK FORWARDING)------------
ODDR_pxlclk_p : ODDR2
generic map(
DDR_ALIGNMENT => "NONE",
INIT => '0',
SRTYPE => "SYNC")
port map(
Q => PXLCLK_P, --output to positive output
C0 => pxlclk_p_int, --differential input
C1 => pxlclk_n_int,
CE => '1', --chip enable tied high
D0 => '1',
D1 => '0',
R => '0',
S => '0'
);
ODDR_pxlclk_n : ODDR2
generic map(
DDR_ALIGNMENT => "NONE",
INIT => '0',
SRTYPE => "SYNC")
port map(
Q => PXLCLK_N, --output to negative output
C0 => pxlclk_n_int,
C1 => pxlclk_p_int,
CE => '1',
D0 => '1',
D1 => '0',
R => '0',
S => '0'
);
out2_bufg : BUFG port map(I => pxlclk, O => pxlclk_p_int); --ERROR THROWN ON I/O HERE
----------------Mappings---------------------------
reset_n_input <= not BTN; --when button pressed, reset
SCL <= 'Z' when scl_internal = '1' else scl_internal;
SCL_DBG <= 'Z' when scl_internal = '1' else scl_internal;
SDA <= sda_internal;
SDA_DBG <= SDA; --copy SDA to debug line
DVIRESET_N <= reset_n; --reset DVI device
pxlclk_n_int <= not pxlclk_p_int; --create differential pair
end behavior;
DVI_MUX Когда я добавил этот блок в систему, ошибка возникла там, где раньше не было
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
ENTITY DVI_MUX IS
PORT(
PXLCLK : IN STD_LOGIC; --pixel clock
PXLCLK2X : IN STD_LOGIC; --double freq. pixel clock
PXL_DAT : IN STD_LOGIC_VECTOR(23 downto 0); --pixel in RGB format
DATA : OUT STD_LOGIC_VECTOR(11 downto 0); --
RESET_N : IN STD_LOGIC
);
END ENTITY DVI_MUX;
architecture RTL of DVI_Mux is
begin
mux_proc : process(PXLCLK2X)
begin
if falling_edge(PXLCLK2X) then
if PXLCLK = '0' then -- if pxlclk low, load first half of pixel
DATA <= PXL_DAT(23 downto 16) & PXL_DAT(11 downto 8);
else --else load second half
DATA <= PXL_DAT(15 downto 12) & PXL_DAT(7 downto 0);
end if;
if RESET_N = '0' then --if reset active7
DATA <= (others => '1');
end if;
end if;
end process;
end architecture RTL;
DVI_INTERFACE
иDVI_MUX
. Метод ошибки указывает, что тактовый сигнал используется как не тактовый сигнал в комбинационной логике. - person Martin Zabel   schedule 11.12.2015