flammmable 0 5 мая, 2021 Опубликовано 5 мая, 2021 (изменено) · Жалоба Я написал в Quartus код для приема байтов по UART: module uart_rx #( parameter CLK_FREQUENCY, parameter UART_BAUDRATE, parameter BITS_NUMBER )( input clock, output reg stop_rx, output test,//--------------------------------- output reg [BITS_NUMBER-1:0]data_rx, input rx_in ); parameter CLK_PERIOD = 1000/CLK_FREQUENCY; parameter UART_PERIOD = 1000_000_000/UART_BAUDRATE; parameter CLK_DIVIDER = UART_PERIOD/CLK_PERIOD; enum {IDLE, START_WAIT, START_GET, BIT_WAIT, BIT_GET, STOP_WAIT, STOP_GET, END} fsm; reg [17:0]delay_cnt; reg [7:0]data_store; reg [3:0]bit_cnt; assign test = ~rx_in && stop_rx;//------------------- always @(posedge clock) begin case(fsm) IDLE:begin if(~rx_in) begin stop_rx <= LOW; delay_cnt<= CLK_DIVIDER/2; fsm <= START_WAIT; end end START_WAIT:begin delay_cnt <= delay_cnt - 1; if(delay_cnt == 0) begin bit_cnt <= 0; fsm <= START_GET; end end START_GET:begin delay_cnt<= CLK_DIVIDER; bit_cnt <= 0; fsm <= BIT_WAIT; end BIT_WAIT:begin delay_cnt <= delay_cnt - 1; if(delay_cnt == 0) begin fsm <= BIT_GET; end end BIT_GET:begin data_store[bit_cnt] <= rx_in; bit_cnt <= bit_cnt + 1; delay_cnt<= CLK_DIVIDER; if(bit_cnt == BITS_NUMBER-1) begin fsm <= STOP_WAIT; end else begin fsm <= BIT_WAIT; end end STOP_WAIT:begin delay_cnt <= delay_cnt - 1; if(delay_cnt == 0) begin fsm <= STOP_GET; end end STOP_GET:begin data_rx <= data_store; fsm <= END; end END:begin stop_rx <= HIGH; fsm <= IDLE; end endcase end endmodule На симуляторе всё (разумеется) отлично. В железе (DE0-Nano и ПЛИСом EP4CE22F17C6N) всё отлично. Почти. Код срабатывает где-то 9 из 10 раз. CLK_FREQUENCY устанавливал в 50 и в 25. UART_BAUDRATE - в 57600 и 9600. Данные одни и те же - два ASCII-кода символов "A" и "B" подряд. Пробовал менять их местами, частота ошибки вроде не поменялась. Судя по осциллографу иногда конечный автомат не выходит из состояния IDLE, несмотря на нисходящий фронт старт-бита: always @(posedge clock) begin case(fsm) IDLE:begin if(~rx_in) begin stop_rx <= LOW; delay_cnt<= CLK_DIVIDER/2; fsm <= START_WAIT; end end ... Хотя, как видно по линии "test", сам стартовый бит вполне осознается ПЛИСом. Осциллограмма снималась с дополнительных пинов ПЛИСа, которым были назначены (при помощи assign): 1) rx от UARTа 2) stop_rx от модуля 3) test от модуля Сама ошибка возникает как в первом, так и во втором байте всей передачи, причем независимо от того передается ли "AB", или "BA". Вопрос: в чем может быть причина и как отлавливать подобные ошибки? Изменено 5 мая, 2021 пользователем flammmable Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
R6L-025 1 5 мая, 2021 Опубликовано 5 мая, 2021 · Жалоба А на осциллограмме что есть что? Как организовывается передача, между чем и чем? Я к тому что если между FPGA и внешним устройством, то может попробовать loop-test, все передавать и принимать внутри FPGA? Что в этом случае будет Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flammmable 0 5 мая, 2021 Опубликовано 5 мая, 2021 (изменено) · Жалоба 27 minutes ago, R6L-025 said: А на осциллограмме что есть что? Осциллограмма снималась с дополнительных пинов ПЛИСа, которым были назначены (при помощи assign): 1) (синий) rx от UARTа 2) (желтый) stop_rx от модуля 3) (зеленый) test от модуля 27 minutes ago, R6L-025 said: Как организовывается передача, между чем и чем? За ПЛИС - DE0-Nano (EP4CE22F17C6N). За UART - FT232 от Waveshare (FT232RL), txd/rxd которого соединены проводами с пинами демоплаты. 27 minutes ago, R6L-025 said: Я к тому что если между FPGA и внешним устройством, то может попробовать loop-test, все передавать и принимать внутри FPGA? Учитывая, что осциллограмма снималась с дополнительных пинов ПЛИСа, одному из которых был назначен (при помощи assign) rx от UARTа (для FT232RL это, разумеется txd) и то, что биты, получаемые с rx видны на осциллограмме можно заключить, что сигнал вполне заходит внутрь ПЛИСа. Т.е. в верхнем модуле есть input rx и output output_test_2. И rx подключен И к модулю uart_rx И выходному пину output_test_2. С которого снята синяя осциллограмма. Изменено 5 мая, 2021 пользователем flammmable Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
R6L-025 1 5 мая, 2021 Опубликовано 5 мая, 2021 · Жалоба В SignalTap смотрел что происходит внутри? Может там что-то странное получится увидеть. Посмотреть на состояние fsm, stop_rx, delay_cnt. Ну и еще яб добавил системе reset. Иначе нельзя гарантировать что система будет в известном состоянии на момент начала работы. Еще - можно добавить default ветку в switch-case, чтоб отлавливать ошибочные состояния (на всякий случай). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mixa7109 0 5 мая, 2021 Опубликовано 5 мая, 2021 · Жалоба Я бы тебе посоветовал шину rx_in завести на триггер в отдельном процессе и уже его анализировать. А ещё можно было бы поставить простенький фильтр из 3 регистров. Для этого надо провести входной сигнал по трем регистрам. И создать 4 сигнал, который будет отображать в себе следующее (reg1 and reg2) or (reg2 and reg 3) or (reg1 and 3). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nieve 0 5 мая, 2021 Опубликовано 5 мая, 2021 · Жалоба Изначально "fsm" в каком состоянии? Теоретически на симуляторе все триггера автомата могут быть в "0", а в ПЛИС в "1" и наоборот. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 5 мая, 2021 Опубликовано 5 мая, 2021 · Жалоба Приветствую! 7 minutes ago, mixa7109 said: Я бы тебе посоветовал шину rx_in завести на триггер Это должен быть не совет а требование! Уже много раз говорилось - внешние входные сигналы нужно синхронизировать перед использованием. Это как два триггера (подряд) об асфальт Удачи! Rob Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexadmin 0 5 мая, 2021 Опубликовано 5 мая, 2021 · Жалоба 1) Поставить по всем входам по два последователньых триггера. 2) Пока компилируется читать про метастабильность. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 5 мая, 2021 Опубликовано 5 мая, 2021 · Жалоба Синхронизация с доменом входного сигнала + мажоритарный фильтр + выборка для фильтра в центре бита. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flammmable 0 5 мая, 2021 Опубликовано 5 мая, 2021 (изменено) · Жалоба Творчески переосмыслив советы, добавил reg rx_inner; и в том же always прямо перед case добавил rx_inner <= rx_in; . А все дальнейшие операции с rx_in заменил на операции с rx_inner. Ошибка больше не появляется. Всем спасибо! Изменено 5 мая, 2021 пользователем flammmable Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 5 мая, 2021 Опубликовано 5 мая, 2021 · Жалоба 10 часов назад, flammmable сказал: Творчески переосмыслив советы, добавил reg rx_inner; и в том же always прямо перед case добавил rx_inner <= rx_in; . А все дальнейшие операции с rx_in заменил на операции с rx_inner. Ошибка больше не появляется. Всем спасибо! Для надежного uart - этого мало. Неплохо было бы поставить некий фильтр, который сглаживает всплески\проседания\пологие фронты. Неплохо было бы выборку данных бита, делать в середине битового интервала Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flammmable 0 6 мая, 2021 Опубликовано 6 мая, 2021 (изменено) · Жалоба 9 hours ago, Flip-fl0p said: Неплохо было бы выборку данных бита, делать в середине битового интервала Она и так делается в середине интервала. При переходе автомата в состояние START_WAIT задержка устанавливается в delay_cnt<= CLK_DIVIDER/2; Далее при переходе в состояние BIT_WAIT задержка устанавливается в delay_cnt<= CLK_DIVIDER; 9 hours ago, Flip-fl0p said: Неплохо было бы поставить некий фильтр, который сглаживает всплески\проседания\пологие фронты. А вот это - вопрос дискуссионный. Можно сделать мажоритарный фильтр, можно включить в UART бит паритета, можно добавить handshake, можно прикрутить CRC16 и т.д. Но все эти вещи не решают проблемы, а маскируют их. Возможна ситуация, что необходима безошибочная работа устройства в течение 1 часа, а некая ошибка происходит раз в 6 часов. Вроде неплохо. Но и не хорошо. Прикручиваем CRC, к примеру, и ошибка возникает раз в 1 неделю (когда неизбежно случается коллизия контрольной суммы). Отлично! А теперь предположим, что необходима безошибочная работа устройства в течение 1 часа, а некая ошибка происходит раз в 10 минут. Прикручиваем CRC и ошибка начинает повторяться раз в 6 часов. Затем устройство передается из производства в эксплуатацию, а там оказываются какие-либо специфические условия, не покрытые тестами. И - оп! Ошибка начинает появляться именно раз в 1 час. Но теперь её сложнее локализовать. Представляется что у всех этих фильтров и контрольных сумм важной функцией является возможность разом их отключить для проведения диагностики. Изменено 6 мая, 2021 пользователем flammmable Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 6 мая, 2021 Опубликовано 6 мая, 2021 · Жалоба 7 минут назад, flammmable сказал: А вот это - вопрос дискуссионный. Можно сделать мажоритарный фильтр, можно включить в UART бит паритета, можно добавить handshake, можно прикрутить CRC16 и т.д. Но все эти вещи не решают проблемы, а маскируют их. Мажоритарный фильтр (МЖФ)- решает проблемы одноразовых всплесков\провалов в линии. Конечно если физическая среда - подвержена влиянию помех, и от каждого чиха в ней появляются проблемы, то МЖФ мало поможет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flammmable 0 6 мая, 2021 Опубликовано 6 мая, 2021 · Жалоба 8 minutes ago, Flip-fl0p said: Мажоритарный фильтр (МЖФ)- решает проблемы одноразовых всплесков\провалов в линии. Конечно если физическая среда - подвержена влиянию помех, и от каждого чиха в ней появляются проблемы, то МЖФ мало поможет. Одноразовых в пределах периода дискретизации. Если иглы толще двух периодов, то МЖФ из трех триггеров начнет распознавать их не как иглы, а как сигнал. Если иглы сильно тоньше одного периода, то они и так не повлияют на передачу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 6 мая, 2021 Опубликовано 6 мая, 2021 · Жалоба 45 минут назад, flammmable сказал: Одноразовых в пределах периода дискретизации. Если иглы толще двух периодов, то МЖФ из трех триггеров начнет распознавать их не как иглы, а как сигнал. Если иглы сильно тоньше одного периода, то они и так не повлияют на передачу. Так МЖФ можно делать не на 3 отсчета, а на 5 например, или 7. Если у Вас столько игл - в сигнале, значит проблема на физическом уровне. Тут ничего не спасет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться