Джеймс 4 1 июля, 2020 Опубликовано 1 июля, 2020 · Жалоба 3 minutes ago, pinchemierda said: К мастеру вопросов точно нет. В синхронном варианте связка МК <-> ПЛИС работает, только частота не максимальная, а 9МГц. Этот рабочий код можете выложить? ("В синхронном варианте ... только частота не максимальная, а 9МГц.") Вместе с тестбенчем, естественно Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bmv89 0 1 июля, 2020 Опубликовано 1 июля, 2020 (изменено) · Жалоба module spi_slave( input i_core_clk, //FPGA clock input wire i_cs, input wire i_clk, input wire i_mosi, output reg o_miso, output reg o_irq, output reg [7:0]o_rx_buf, input wire [7:0]i_tx_buf ); reg [2:0]counter; //счётчик битов //детектор CLK reg clk_1, clk_2; wire clk_pos, clk_neg; assign clk_pos = clk_1 & ~clk_2; assign clk_neg = ~clk_1 & clk_2; //детектор CS reg cs_1, cs_2; wire cs_neg; assign cs_neg = ~cs_1 & cs_2; always @(posedge i_core_clk) begin clk_1 <= i_clk; clk_2 <= clk_1; cs_1 <= i_cs; cs_2 <= cs_1; if(clk_pos && !cs_2) counter <= counter + 1'd1; if(cs_neg) counter <= 3'd0; end //----------------------- MOSI ----------------------------- reg [7:0]sr_rx; //сдвиговый приёмный регистр reg rx_flag; always @(posedge i_core_clk) begin if(clk_pos && !cs_2) begin sr_rx <= {sr_rx[6:0], i_mosi}; if(counter == 3'd7) rx_flag <= 1'd1; end if(rx_flag) begin rx_flag <= 1'd0; o_irq <= 1'd1; o_rx_buf <= sr_rx; end if(o_irq) o_irq <= 1'd0; end //-------------------------- MISO --------------------------------- reg [7:0]sr_tx; //сдвиговый регистр отправки always @(*) begin if(cs_2) o_miso = 1'dZ; else o_miso = sr_tx[7]; end always @(negedge i_core_clk) begin if(o_irq || cs_neg) begin sr_tx <= i_tx_buf; end if(clk_neg && !cs_2 && counter) begin sr_tx <= sr_tx << 1'd1; end end endmodule Симулирую пока внутри квартуса, написание тестбенчей пока не освоил до конца. Знаю, сейчас ругаться будете, но модуль простой и логику работы можно вполне проверить встроенным функциональным симулятором. Только что, nice_vladi сказал: https://gitlab.com/vborchsh/spi-core/-/blob/master/spi_slave.sv Сдаётся мне, это тоже будет работать только при соотношении клоков iclk/isclk = 10/1 (минимум). Изменено 1 июля, 2020 пользователем pinchemierda Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nice_vladi 2 1 июля, 2020 Опубликовано 1 июля, 2020 · Жалоба 19 minutes ago, pinchemierda said: Сдаётся мне, это тоже будет работать только при соотношении клоков iclk/isclk = 10/1 (минимум). Так можно отсимулить. Там есть ТБ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 1 1 июля, 2020 Опубликовано 1 июля, 2020 (изменено) · Жалоба 1 hour ago, pinchemierda said: К мастеру вопросов точно нет. В синхронном варианте связка МК <-> ПЛИС работает, только частота не максимальная, а 9МГц. Использование o_irq может скрывать логические ошибки. В синхронном варианте клоком является хороший сигнал от генератора 50МГц на той-же плате. В асинхронном варианте клоком является сигнал с другой платы, надо гарантировать качество этого сигнала - нормальные фронты, отсутствие звона, и тд. Изменено 1 июля, 2020 пользователем Leka Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bmv89 0 1 июля, 2020 Опубликовано 1 июля, 2020 · Жалоба Только что, Leka сказал: В асинхронном варианте клоком является сигнал с другой платы, надо гарантировать качество этого сигнала - нормальные фронты, отсутствие звона, и тд. Если убрать из кода всё связанное с отправкой по MISO (оставить только приём по MOSI) приём начинает работать правильно и очень стабильно (и на любой скорости). Является ли это подтверждением того, что spi клок подходящего качества? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 1 1 июля, 2020 Опубликовано 1 июля, 2020 · Жалоба 9 minutes ago, pinchemierda said: Является ли это подтверждением того, что spi клок подходящего качества? Да, наверно. 10 minutes ago, pinchemierda said: убрать из кода всё связанное с отправкой по MISO Непонятно, как это может повлиять на прием. 12 minutes ago, pinchemierda said: Если убрать из кода всё связанное с отправкой по MISO (оставить только приём по MOSI) приём начинает работать правильно и очень стабильно (и на любой скорости). К моему коду это тоже относится? (кстати, немного поправил свой код) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bmv89 0 1 июля, 2020 Опубликовано 1 июля, 2020 · Жалоба Только что, Leka сказал: К моему коду это тоже относится? Это вообще к любому варианту относится. И к синхронному и к асинхронному (в том числе вашему). Даже к самому начальному, на который все очень сильно ругались. Я это с самого начала отметил. Причём даже удалять не обязательно, достаточно просто не производить никаких действий с входным буфером и не выводить его на внешние пины в топ модуле. Не знаю, стоит ли на этом заострять внимание, потому что решением проблемы в синхронном варианте было применение детекторов фронтов по spi_clk и spi_cs. И для меня совсем не понятно, почему без них приём работал отлично (если только приём!), а с отправкой не работало. Хотя, как уже писали, когда в синхронном дизайне вылезают проблемы связанные с асинхронщиной, возникает метастабильность и всё такое... И там уже логического объяснения происходящего быть не может (бесовщина полная может твориться). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 1 1 июля, 2020 Опубликовано 1 июля, 2020 · Жалоба 17 minutes ago, pinchemierda said: Не знаю, стоит ли на этом заострять внимание Стоит, spi-slave должен работать от клока мастера, без каких-либо дополнительных клоков. Зачем лишние сущности? Еще момент, если используется z-состояние выхода, пин надо объявить так: inout MISO Но если других устройств нет, лучше не делать с z-состоянием. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bmv89 0 1 июля, 2020 Опубликовано 1 июля, 2020 · Жалоба 1 час назад, nice_vladi сказал: https://gitlab.com/vborchsh/spi-core/-/blob/master/spi_slave.sv Это ещё и систем верилог, что ли? Не могу перевести эту строку в верилог: omiso <= tx_shift_reg[$high(tx_shift_reg)]; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 1 1 июля, 2020 Опубликовано 1 июля, 2020 · Жалоба http://www.asic-world.com/systemverilog/system_task_function2.html Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Plain 220 1 июля, 2020 Опубликовано 1 июля, 2020 · Жалоба 4 часа назад, pinchemierda сказал: изредка нормализуется приём на пару секунд (особенно если свободные контакты руками полапать) Покажите нам фото этой экспериментальной установки, потому что в общем случае передача таких частот даже на 10 мм требует соответствующий конструктив, включая монтаж и линии связи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bmv89 0 1 июля, 2020 Опубликовано 1 июля, 2020 · Жалоба Только что, Plain сказал: Покажите нам фото этой экспериментальной установки Не работает на любой частоте, даже на 1 МГц. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Джеймс 4 1 июля, 2020 Опубликовано 1 июля, 2020 · Жалоба 4 hours ago, pinchemierda said: Симулирую пока внутри квартуса, написание тестбенчей пока не освоил до конца. Знаю, сейчас ругаться будете, но модуль простой и логику работы можно вполне проверить встроенным функциональным симулятором. Ладно, в целом нормально. Хотя reset-а все равно нет, но я уже понял, что вас не додавить. Кстати, вы уже наверное почувствовали разницу между "стабильно работает" и "работает, если полапать незанятые пины". Вот то-то и оно. Теперь по стилю.. Знаете, - можно писать стихи без глаголов, а у вас в коде совсем нет ELSE-ов. Может они и правда здесь не нужны, но мне кажется причина в чем-то другом. Взять например этот фрагмент: always @(posedge i_core_clk) begin if(clk_pos && !cs_2) counter <= counter + 1'd1; if(cs_neg) counter <= 3'd0; end Очевидно же, что приоритет обнуления счетчика должен быть выше, - то есть код должен выглядеть вот так: always @(posedge i_core_clk) begin if(cs_neg) counter[2:0] <= 3'd0; else if (clk_pos && !cs_2) counter[2:0] <= counter[2:0] + 3'd1; end Это как минимум улучшает понимание, даже если эти события во времени и не пересекаются никогда. Далее, снова эта ваша привычка, зачем засунули sr_rx и rx_flag под один always ?? always @(posedge i_core_clk) begin if(clk_pos && !cs_2) sr_rx[7:0] <= {sr_rx[6:0], i_mosi}; end Всё! Дальше пошел другой always. always @(posedge i_core_clk) begin здесь только формирование rx_flag !!! end и так далее Теперь по вашей проблеме. Сейчас нет времени разбираться хватит ли 50MHz чтобы принимать на частоте SPI 18MHz. Но я так понял, вы в это уперлись. Была бы PLL - поставили бы PLL. Но её нет. Сделать-то на самом деле можно - собирайте 4 бита в одном регистре (по нечетным значениям счетчика counter) и 4 бита в другом регистре по четным значениям счетчика counter. Соответствующие стробики будут наезжать на следующий такт SCLK, но это не страшно - в параллель будут работать два "плеча". Но если так делать не хотите, предлагаю довольно некрасивый hack. Сделать удвоитель частоты на логике. Тогда получите 100 MHz тактовую частоту (не меандр, короткие импульсы). Как сделать - по ссылке (см. Удвоитель частоты). Автор удвоителя - Peter Alfkehttps://tqfp.org/fpga/shest-prostyh-asinhronnyh-histrostey.html Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 1 1 июля, 2020 Опубликовано 1 июля, 2020 (изменено) · Жалоба 1 hour ago, pinchemierda said: Не работает на любой частоте, даже на 1 МГц. Надписи хорошо-бы сделать, где какие провода. Очень м/б, что проблема именно тут. 15 minutes ago, Джеймс said: Это как минимум улучшает понимание, даже если эти события во времени и не пересекаются никогда. Варианты кода равнозначны, независимо от "пересечения событий во времени". Изменено 1 июля, 2020 пользователем Leka Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Plain 220 1 июля, 2020 Опубликовано 1 июля, 2020 · Жалоба 58 минут назад, pinchemierda сказал: Не работает на любой частоте Уменьшите длину общего провода до нуля — соедините демоплату и плату с дисплеем не проводом, а перемычкой, подключённой к контакту общего провода, расположенному в том же месте, что и контакты данных. Длины проводов кабеля данных соответственно тоже уменьшите насколько возможно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться