|
Передача данных UART => SDRAM память, Как правильно передать данные между UART и SDRAM контроллером |
|
|
|
Nov 6 2016, 16:14
|

В поисках себя...
   
Группа: Свой
Сообщений: 729
Регистрация: 11-06-13
Из: Санкт-Петербург
Пользователь №: 77 140

|
Добрый вечер уважаемые форумчане. Хочу попросить вашего совета по правильной организации передачи данных между UART и SDRAM контроллером. Хочу записать изображение в SDRAM память, и вывести его на LVDS матрицу. Изображение представляет собой набор пикселей, где каждый пиксель состоит из 3 байтов данных. Каждый байт передает данные о базовой составляющей цвета (RGB). Передача изображения из компьютера в SDRAM память будет через UART (9600/8-N-1). Мой UART приемник работает по классической схеме: через частоту в 16 раз больше бодовой и выборкой трех значений с середины битового интервала, с последующим мажорированием. После принятия байта приемником он поступает на модуль, который после принятия трех байт, отбрасывает ненужные мне разряды цвета, и объединяет их в одно слово, являющееся цветом пикселя, которое будет записываться в SDRAM память. Таким образом каждые 3 байта я должен передавать данные SDRAM контроллеру (который может работать на частоте до 133 МГц) для их записи в память. Соответственно мы в итоге должны передать данные между 2 клоковыми доменами UART => SDRAM контроллер. У меня есть 2 варианта по организации передачи данных: использовать протокол Handshake (рукопожатие) или FIFO буфер. Первый вариант кажется предпочтительным, поскольку применение FIFO буфера неоправданно из-за того, что скорость записи данных в него будет несопоставимо ниже, чем я могу этот буфер читать, и буфер будет всегда пустой. Можно накопить данные в буфере, и периодически его считывать по мере заполнения. Но не вижу рациональных причин так делать. Вот и хотелось бы услышать Ваше мнение, как правильнее организовать передачу данных. Естественно UART приемник и SDRAM контроллер реализованы в ПЛИС.
Сообщение отредактировал Flip-fl0p - Nov 6 2016, 16:31
|
|
|
|
|
 |
Ответов
|
Nov 6 2016, 22:29
|

В поисках себя...
   
Группа: Свой
Сообщений: 729
Регистрация: 11-06-13
Из: Санкт-Петербург
Пользователь №: 77 140

|
Цитата(iosifk @ Nov 6 2016, 22:10)  Все красиво, кроме одного... Откуда Вы узнаете, где в потоке данных будет 1-й байт, а где 2-й и т.д. Достаточно одного сбоя и канал перестанет работать правильно... Поскольку у меня приемник UART самописный - то я добавил сигнал валидности. Когда байт принят - формируется короткий импульс, что данные приняты и их можно использовать. Считая эти импульсы я и делаю вывод о том, какой номер байта у меня принят. Вот модуль которым я это делаю. Я правда в железе его не отлаживал, поскольку макетная плата на работе. Но симуляцию вроде прошел успешно. CODE --=============================== PIXEL_CREATING ========================================= -- Данный модуль предназначен для приема 3 байт данных по UART и пребразования их -- В одно слово, содержащее данные о цвете пикселя.
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL;
ENTITY PIXEL_CREATING IS GENERIC ( COLOR_DEPTH : INTEGER := 12 --COLOR_DEPTH/3 Для одного цвета ); PORT ( CLK : IN STD_LOGIC; -- Частота UART ресивера UART_DATA : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- Данные, выдавемые UART DATA_VALID : IN STD_LOGIC; -- Сигнал подтверждения валидных данных рессивером ASY_RESET : IN STD_LOGIC; -- Асинхронный сброс Синхронизирован в топ модуле. PIXEL_COLOR : OUT STD_LOGIC_VECTOR(COLOR_DEPTH-1 DOWNTO 0); -- Выходной сигнал который является цветом пикселя PIXEL_VALID : OUT STD_LOGIC ); END ENTITY;
ARCHITECTURE PIXEL_CREATING_arc OF PIXEL_CREATING IS SIGNAL BYTE_CNT : INTEGER RANGE 0 TO 2 := 0; -- Счетчик принятых байт SIGNAL RED_COLOR_REG : STD_LOGIC_VECTOR(COLOR_DEPTH/3-1 DOWNTO 0) := (OTHERS => '0'); -- Регистр куда записывается красная составляющая пикселя SIGNAL GREEN_COLOR_REG : STD_LOGIC_VECTOR(COLOR_DEPTH/3-1 DOWNTO 0) := (OTHERS => '0'); -- Регистр куда записывается зеленая составляющая пикселя SIGNAL BLUE_COLOR_REG : STD_LOGIC_VECTOR(COLOR_DEPTH/3-1 DOWNTO 0) := (OTHERS => '0'); -- Регистр куда записывается синяя составляющая пикселя SIGNAL LOAD_DATA : STD_LOGIC := '0'; -- Сигнал разрешения объедениения данных BEGIN BYTE_COUNTER : PROCESS ( CLK, ASY_RESET ) BEGIN IF (ASY_RESET = '1') THEN BYTE_CNT <= 0 ; LOAD_DATA <= '0'; PIXEL_VALID <= '0'; RED_COLOR_REG <= (OTHERS => '0'); GREEN_COLOR_REG <= (OTHERS => '0'); BLUE_COLOR_REG <= (OTHERS => '0'); PIXEL_COLOR <= (OTHERS => '0'); ELSIF (CLK'EVENT AND CLK = '1') THEN LOAD_DATA <= '0'; -- Постоянно держим сигнал разрешения в нуле PIXEL_VALID <= '0'; -- Постоянно держим сигнал валидности пикселя в нуле IF (DATA_VALID = '1') THEN -- Как только поступил сигнал валидности данных CASE BYTE_CNT IS -- Начинаем анализировать состояние счётчика WHEN 0 => -- Есть сигнал валидности и счтчик равен 0 RED_COLOR_REG <= UART_DATA(COLOR_DEPTH/3-1 DOWNTO 0); -- Значит это были данные о красном цвете пикселя BYTE_CNT <= BYTE_CNT + 1; -- Инкрементируем счетчик на 1 WHEN 1 => -- Есть сигнал валидности и счтчик равен 1 GREEN_COLOR_REG <= UART_DATA(COLOR_DEPTH/3-1 DOWNTO 0); -- Значит это были данные о зеленом цвете пикселя BYTE_CNT <= BYTE_CNT + 1; -- Инкрементируем счетчик на 1 WHEN 2 => -- Есть сигнал валидности и счтчик равен 2 BLUE_COLOR_REG <= UART_DATA(COLOR_DEPTH/3-1 DOWNTO 0); -- Значит это были данные о синем цвете пикселя LOAD_DATA <= '1'; -- Разрешам следующим тактом "собрать пиксель" BYTE_CNT <= 0 ; -- Обнулим счетчик WHEN OTHERS => BYTE_CNT <= 0 ; -- Обнуляем счётчик если он вышел за диапазон счета END CASE; END IF; IF (LOAD_DATA = '1') THEN -- Как только наступило разрешение сбора пикселя PIXEL_VALID <= '1'; -- Значит следующим тактом у нас будет валидный пиксель PIXEL_COLOR <= BLUE_COLOR_REG&GREEN_COLOR_REG&RED_COLOR_REG; -- Соберем его END IF; END IF; END PROCESS; END ARCHITECTURE; Я тоже думал про то, что если будет сбой, то счетчик байтов может сбиться. Но к сожалению у меня нет ответа на вопрос, что будет при сбое. Остаётся надежда только на то, что сбоя не будет, поскольку кроме UART у меня нет других способов связи между макетной платой и ПК. Связь осуществляется через микросхему FTDI FT2232H. В системе у меня 2 виртуальных COM порта, один из которых применяется для конфигурации ПЛИС, а через другой буду передавать данные. Надежность данного решения под вопросом. Но приходиться работать с тем, что имею. Как вариант найти какой-нибудь из протоколов на основе UART и передавать информацию посредством этого протокола. Но хочется обойтись "малой кровью"
Сообщение отредактировал Flip-fl0p - Nov 6 2016, 22:42
|
|
|
|
Сообщений в этой теме
Flip-fl0p Передача данных UART => SDRAM память Nov 6 2016, 16:14  Александр77 Цитата(Flip-fl0p @ Nov 7 2016, 01:29... Nov 7 2016, 04:16   Flip-fl0p Цитата(Александр77 @ Nov 7 2016, 07:16) С... Nov 7 2016, 05:06    Bad0512 Вижу 2 проблемы в вашем дизайне :
1. Вы не придума... Nov 7 2016, 05:13     Flip-fl0p Цитата(Bad0512 @ Nov 7 2016, 08:13) Вижу ... Nov 7 2016, 05:24      Bad0512 Цитата(Flip-fl0p @ Nov 7 2016, 12:24... Nov 7 2016, 06:59       Flip-fl0p Цитата(Bad0512 @ Nov 7 2016, 09:59) Ну хо... Nov 7 2016, 07:29        Bad0512 Цитата(Flip-fl0p @ Nov 7 2016, 14:29... Nov 7 2016, 09:12    iosifk Цитата(Flip-fl0p @ Nov 7 2016, 08:06... Nov 7 2016, 08:24    iosifk Цитата(Flip-fl0p @ Nov 7 2016, 08:06... Nov 7 2016, 09:39 ViKo Сделать счетчик таймаута приема. Если он сработал,... Nov 7 2016, 03:24 ViKo Что мешает ускорить скорость передачи до 250 кбит/... Nov 7 2016, 06:31 tvcam Я могу ошибиться, но не две минуты, 9600/8 = 1200 ... Nov 7 2016, 06:46 warrior-2001 Реализуйте что-то типа Манчестера и будет вам счас... Nov 7 2016, 09:15 Flip-fl0p Реализовал я передачу данных между UART => ПЛИС... Nov 8 2016, 11:11
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|