Перейти к содержанию
    

Первый проект на Verilog. Прошу помощи

3 hours ago, pinchemierda said:

Ну вообще.. Вы хотите сказать что без схемы что-то делаете??
Вот ваша схема, насколько я понимаю:
https://www.openimpulse.com/blog/products-page/product-category/max-ii-epm240-cpld-minimal-development-board/
https://www.openimpulse.com/blog/wp-content/uploads/wpsc/downloadables/EPM240MAINBOARD-Schematic-Diagram.pdf

R1, C1 - это импровизированный генератор сброса, сигнал PIN44. Если есть осциллограф, посмотрите  что на нем происходит. Должен быть короткий импульс "0", который становится "1".
Пин IO/DEV_CLRn в настройках возможно нужно объявить как "user IO".
Итак, в проекте появится вход i_rst 

Перепишите все ваши always блоки следующим образом:

always @(posedge i_core_clk or negedge i_rst)
begin
		if(~i_rst)
                 begin
                  counter[2:0] <= 3'd0;
		  clk_flag <= 1'd0;   // если он вообще здесь нужен будет 
                  sr_rx[7:0] <= 8'h0;
                  o_irq <= 1'd0;
                  rx_flag <= 1'd0;
                  o_rx_buf[7:0] <= 8'h0;
                 end

...............
// далее вся ваша логика
...............
end

always @(posedge i_core_clk or negedge i_rst)
begin 
  if(~i_rst)
  begin
    cs_flag <= 1'd0;
    tmp[2:0] <= 3'h0;
    sr_tx[7:0] <= 8'h0;
  end
..............
// опять же ваша логика
..............
end

Таким образом они все будут выглядеть единообразно 
always @(posedge i_core_clk or negedge i_rst)
begin

и как бонус вы просто не сможете создавать подобные конструкции

always @(posedge i_core_clk or posedge i_cs)


Да, конечно сигнал rst также должен появиться и тестбенче тоже.

Далее, в том же духе разберитесь с обработкой i_clk и i_cs.
i_clk нельзя просто так заводить в вашу схему! (также как и i_cs)
Как минимум, их нужно сначала один раз протактировать частотой i_core_clk

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

36 minutes ago, Джеймс said:

always @(posedge i_core_clk or posedge i_cs)

А чем Вам конструкция не угодила, я не могу понять? Ну ок, не совсем по феншую. Плюс нужно убедится, что пин i_cs имеет хороший pull-down. Иначе будет свистопляска)

А так вполне себе рабочее подключение входного пина на ресет флопа. Для уверенности можно i_cs пропустить через FF, чтобы избежать пульсаций.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

30 minutes ago, Nick_K said:

А чем Вам конструкция не угодила, я не могу понять? Ну ок, не совсем по феншую. Плюс нужно убедится, что пин i_cs имеет хороший pull-down. Иначе будет свистопляска)

А так вполне себе рабочее подключение входного пина на ресет флопа. Для уверенности можно i_cs пропустить через FF, чтобы избежать пульсаций.

Здесь  "не совсем по феншую" , там @ negedge CLK, а кончается всё свистопляской : )

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Имелось ввиду, что нет схемы в цифровом виде или на бумаге. В голове то она есть))). Генератор на pin12 да светодиод через джампер на pin77, вот и вся схема.

И у меня точно первый вариант схемы, pin44 без подтяжки и конденсатора. 

К pin44 подключил один из битов порта выхода o_rx_buf. В общем светодиод я на него повесил. Его можно как выход использовать? 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 minutes ago, pinchemierda said:

 

К pin44 подключил один из битов порта выхода o_rx_buf. В общем светодиод я на него повесил. Его можно как выход использовать? 

Ну если сконфигурировать как user IO то можно.
  Но вам в схеме не хватает reset-а. Значит его нужно сделать

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Почему тогда без этого reset-а другие проекты работают, в том числе вариант SPI SLAVE из того поста?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 minutes ago, pinchemierda said:

Почему тогда без этого reset-а другие проекты работают, в том числе вариант SPI SLAVE из того поста?

Ну я вообще-то хотел вам помочь, а не разбираться, почему в том посте проект работает.
К тому же главное - это подход.
Но в общем, у меня не так много времени.
Удачи! 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Насчет RESET'а вам правильно советуют - должен быть сигнал или способ приведения системы в известное состояние. Но это далеко не все, что можно сказать по коду из поста
 

Quote

ТЗ: 

1. После принятия посылки из 8 бит по линии i_mosi,

Не работает, потому что код еще пока неправильный, нуждается в доработке.

1. У вас ничего не сделано для перевода входных сигналов в домен вашего основного тактового сигнала i_core_clk - перед тем, как их использовать, надо пропустить их через синхронизаторы. Иначе - метастабильность и неработоспособность.

 

2. Для общего порядка и приучения к хорошему стилю - в интерфейсе модуля обозначьте типы сигналов явным образом для ВСЕХ элементов, а не только для выходов. Не нужно полагаться на типы по умолчанию, все, что можно обозначить явным образом, д.б. так и обозначено. Это хорошая практика.

 

3. Не надо все в одну кучу смешивать. Пока вы начинающий, придерживайтесь правила: 1 регистровый объект (например, counter, clk_flag) - 1 always блок. Иногда можно ему в компанию добавить что-то очень близко связанное функционально, но у вас тут вроде не тот случай. Если вы надеялись что-то оптимизировать, собирая все под одной крышей - вы заблуждались. Синтезатор все равно рассматривает вначале все сущности по отдельности и лишь потом сопоставляет их функции и пытается что-то скомбинировать. Ваша первейшая задача - научиться писать ясный, незапутанный код, который работает понятным образом. Пусть он вначале и не будет влезать в 50 LE. Не надо преждевременной оптимизации - она, как известно, корень всех зол (premature optimization is a root of all evil).

 

4. И когда вы разделите все на понятные кусочки, будет легче и вам разбираться/улучшать свою конструкцию, и нам конструктивно критиковать и советовать.

 

5. Далее - после выполнения этих пунктов. Если что-то неясно по ним - спрашивайте.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да я в общем то и не отказывался ни от чьей помощи то, а очень даже благодарен за ваши попытки. Просто действительно не понятно как может влиять то, про что в большинстве обучающих роликов и статей даже не упоминают. И почему в одних случаях это критично, в плоть до полной неработоспособности модуля, а в других вообще не имеет значения. В общем не понял на что Вы,  Джеймс, обиделись)) 

Буду учиться писать в хорошем стиле. Просто я думаю, что в моём быдлокоде есть какая-то конкретная ошибка, которую я пока не способен увидеть. Эту конкретную ошибку хочется понять и не совершать в будущем. Буду сейчас пытаться найти информацию по reset-у, про который даже китайцы забыли, разводя плату)).

Цитата

перевода входных сигналов в домен вашего основного тактового сигнала i_core_clk

Не совсем понимаю смысла выражения "домен сигнала". Нужно входные сигналы сначала через триггеры пропускать, а дальше уже только с синхронизированными работать?   

типа такого:

always @(posedge i_core_clk)
begin
  sync_clk <= i_clk;
  sync_cs <= i_cs;
  sync_mosi <= i_mosi;
end

Тут ещё трудность в том, что у меня частота генератора 50 МГц, а частота spi 18 МГц. В общем каждый такт на счету.

Цитата

1 регистровый объект - 1 always блок

Разбить код на большее количество always блоков с одинаковыми списками чувствительности? Это только для лучшей читаемости кода или реально другая схема синтезируется?

Изменено пользователем pinchemierda
опечатка

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, pinchemierda said:

Буду учиться писать в хорошем стиле. Просто я думаю, что в моём быдлокоде есть какая-то конкретная ошибка, которую я пока не способен увидеть. Эту конкретную ошибку хочется понять и не совершать в будущем. Буду сейчас пытаться найти информацию по reset-у, про который даже китайцы забыли, разводя плату)).

Reset есть, китайцы про него не забыли: pin 44. Этот пин можно настроить как на работу в качестве глобального сигнала сброса (DEV_CLRn, и кажется, это настройка по умолчанию), либо на работу в качестве обычного IO. Если вы хотите все держать под контролем (и заодно узнать, в каком углу Квартуса настраиваются такие вещи) - выбирайте 2-й вариант. Кстати, какой у вас Квартус сейчас?

И этот входной сигнал уж точно нужно пропустить через синхронизатор (см. ниже). Особенно из-за его способа формирования на RC-цепочке.

Quote

Не совсем понимаю смысла выражения "домен сигнала". Нужно входные сигналы сначала через триггеры пропускать, а дальше уже только с синхронизированными работать?

Имеется в виду Clock Domain (это все триггеры, тактируемые данным тактовым сигналом). Тематика метастабильности, синхронизаторов и т.п. - искать по ключевым словам clock domain, clock domain crossing, metastability (метастабильность).

Эта тема немного затрагивается в топике на подобную вашей тему, на который указывалось где-то выше.

Синхронизатор - это несколько (обычно 2-3) D-триггеров, подключенных стык-в-стык (как можно меньшая задержка распространения сигнала от выхода одного ко входу другого должна быть). Последнее - немаловажная особенность борьбы с метастабильностью (для чего они, собственно, и предназначены).

Для RESET он будет что-то вроде такого:
 

reg   reset_n_sync_reg_0;

reg   reset_n_sync_reg_1;

wire rst_n;

always @(posedge clk) begin

    reset_n_sync_reg_0 <= PAD_44;

    reset_n_sync_reg_1 <= reset_n_sync_reg_0;

end

assign rst_n = reset_n_sync_reg_1;

А для остальных сигналов синхронизаторы уже должны использовать системный rst_n:
 

reg [1:0] i_cs_sync;

wire cs_sys;

reg [1:0] i_clk_sync;

wire clk_sys;

reg [1:0] i_mosi_sync;

wire mosi_sys;

always @(posedge clk, negedge rst_n) begin

    if (~rst_n) begin

        i_cs_sync <= 2'b0;

        i_clk_sync <= 2'b0;

        i_mosi_sync <= 2'b0;

    end else begin

        i_cs_sync[0] <= i_cs;

        i_cs_sync[1] <= i_cs_sync[0];

        i_clk_sync[0] <= i_clk;

        i_clk_sync[1] <= i_clk_sync[0];

        i_mosi_sync[0] <= i_mosi;

        i_mosi_sync[1] <= i_mosi_sync[0];

    end

end

assign cs_sys = i_cs_sync[1];

assign clk_sys = i_clk_sync[1];

assign mosi_sys = i_mosi_sync[1];

И дальше в дизайне пользуйтесь сигналами cs_sys, clk_sys, mosi_sys - они синхронизированы с системным клоком. Последний пример - это как раз тот случай, когда логично собирать несколько триггерных объектов под одной "крышей" - они работают в едином порыве и могут быть объединены в блок под названием "синхронизатор входных сигналов" (т.е., объединены по функциональному признаку).

Quote

Тут ещё трудность в том, что у меня частота генератора 50 МГц, а частота spi 18 МГц. В общем каждый такт на счету.

А что определяет эти 18 МГц? Вам пока нужно научиться работать в парадигме синхронных цифровых дизайнов, а натягивание на 18 МГц при клоке 50 - тут без асинхронщины не обойтись. Не все сразу. Вот если бы вы догадались приобрести платку не с CPLD, а с маленькими FPGA (какой-нибудь Циклон с 3-6 тыс. LE) - то было бы вам счастье, т.к. у них на борту есть PLL, и можно было бы получить вполне нормальные для такого дизайна, как у вас, 100-150 МГц частоты тактового сигнала. А по цене такая платка ненамного дороже. А так - давайте пока работать с частотой SPI, скажем, 4-5 МГц.

Quote

Разбить код на большее количество always блоков с одинаковыми списками чувствительности? Это только для лучшей читаемости кода или реально другая схема синтезируется?

А читаемость кода - думаете, оно того не стоит? Отсюда и лучшее понимание принципа работы вашей конструкции будет, и меньшее число ошибок, и.... Так что - таки да, в вашем случае "другая схема" реализуется. Надеюсь, в случае предлагаемого подхода она будет отличаться как раз тем, что работает :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 часов назад, pinchemierda сказал:

у меня частота генератора 50 МГц, а частота spi 18 МГц

Я стесняюсь спросить, а соответствующие констрейны написаны?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

11 часов назад, Raven сказал:

У вас ничего не сделано для перевода входных сигналов в домен вашего основного тактового сигнала

Нет в ТЗ никаких ни сбросов, ни доменов — там описан преобразователь параллельного интерфейса в некий последовательный интерфейс, схожий с SPI названиями сигналов, но не соответствующий стандарту SPI. Оба интерфейса внешние, даже приёмного регистра нет, а единственное упоминание о внутреннем тактовом генераторе — создание сигнала прерывания.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 minutes ago, Plain said:

Нет в ТЗ никаких ни сбросов, ни доменов — там описан преобразователь параллельного интерфейса в некий последовательный интерфейс, схожий с SPI названиями сигналов, но не соответствующий стандарту SPI. Оба интерфейса внешние, даже приёмного регистра нет, а единственное упоминание о внутреннем тактовом генераторе — создание сигнала прерывания.

Что ж, замечание справедливое. Надеюсь, ТС учтет его и будет дополнять свое ТЗ необходимым по мере погружения в тему. Начиная с этого момента.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

11 часов назад, pinchemierda сказал:

Да я в общем то и не отказывался ни от чьей помощи ....

А я вот услышал совсем другое... Типа "буду сам по-себе"...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...