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

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

3 minutes ago, pinchemierda said:

К мастеру вопросов точно нет. В синхронном варианте связка МК <-> ПЛИС работает, только частота не максимальная, а 9МГц.

Этот рабочий код можете выложить? ("В синхронном варианте ... только частота не максимальная, а 9МГц.")
Вместе с тестбенчем, естественно

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


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

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 сказал:

Сдаётся мне, это тоже будет работать только при соотношении клоков iclk/isclk = 10/1 (минимум). 

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

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


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

19 minutes ago, pinchemierda said:

Сдаётся мне, это тоже будет работать только при соотношении клоков iclk/isclk = 10/1 (минимум). 

Так можно отсимулить. Там есть ТБ

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


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

1 hour ago, pinchemierda said:

К мастеру вопросов точно нет. В синхронном варианте связка МК <-> ПЛИС работает, только частота не максимальная, а 9МГц.

Использование o_irq может скрывать логические ошибки.

 

В синхронном варианте клоком является хороший сигнал от генератора 50МГц на той-же плате.

В асинхронном варианте клоком является сигнал с другой платы, надо гарантировать качество этого сигнала - нормальные фронты, отсутствие звона, и тд.

Изменено пользователем Leka

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


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

Только что, Leka сказал:

В асинхронном варианте клоком является сигнал с другой платы, надо гарантировать качество этого сигнала - нормальные фронты, отсутствие звона, и тд.

Если убрать из кода всё связанное с отправкой по MISO (оставить только приём по MOSI) приём начинает работать правильно и очень стабильно (и на любой скорости). Является ли это подтверждением того, что spi клок подходящего качества?   

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


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

9 minutes ago, pinchemierda said:

Является ли это подтверждением того, что spi клок подходящего качества?   

Да, наверно. 

 

10 minutes ago, pinchemierda said:

убрать из кода всё связанное с отправкой по MISO

Непонятно, как это может повлиять на прием. 

12 minutes ago, pinchemierda said:

Если убрать из кода всё связанное с отправкой по MISO (оставить только приём по MOSI) приём начинает работать правильно и очень стабильно (и на любой скорости).

К моему коду это тоже относится?

(кстати, немного поправил свой код)

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


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

Только что, Leka сказал:

К моему коду это тоже относится?

Это вообще к любому варианту относится. И к синхронному и к асинхронному (в том числе вашему). Даже к самому начальному, на который все очень сильно ругались. Я это с самого начала отметил. 

Причём даже удалять не обязательно, достаточно просто не производить никаких действий с входным буфером и не выводить его на внешние пины в топ модуле.

Не знаю, стоит ли на этом заострять внимание, потому что решением проблемы в синхронном варианте было применение детекторов фронтов по spi_clk и spi_cs. И для меня совсем не понятно, почему без них приём работал отлично (если только приём!), а с отправкой не работало.

Хотя, как уже писали, когда в синхронном дизайне вылезают проблемы связанные с асинхронщиной, возникает метастабильность и всё такое... И там уже логического объяснения происходящего быть не может (бесовщина полная может твориться).

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


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

17 minutes ago, pinchemierda said:

Не знаю, стоит ли на этом заострять внимание

Стоит, spi-slave должен работать от клока мастера, без каких-либо дополнительных клоков. Зачем лишние сущности? 

Еще момент, если используется z-состояние выхода, пин надо объявить так:

inout MISO

Но если других устройств нет, лучше не делать с z-состоянием.

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


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

1 час назад, nice_vladi сказал:

Это ещё и систем верилог, что ли? Не могу перевести эту строку в верилог:

omiso <= tx_shift_reg[$high(tx_shift_reg)]; 

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


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

4 часа назад, pinchemierda сказал:

изредка нормализуется приём на пару секунд (особенно если свободные контакты руками полапать)

Покажите нам фото этой экспериментальной установки, потому что в общем случае передача таких частот даже на 10 мм требует соответствующий конструктив, включая монтаж и линии связи.

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


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

Только что, Plain сказал:

Покажите нам фото этой экспериментальной установки

Не работает на любой частоте, даже на 1 МГц.

фото.jpg

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


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

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 Alfke

https://tqfp.org/fpga/shest-prostyh-asinhronnyh-histrostey.html

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


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

1 hour ago, pinchemierda said:

Не работает на любой частоте, даже на 1 МГц.

Надписи хорошо-бы сделать, где какие провода. Очень м/б, что проблема именно тут.

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

Это как минимум улучшает понимание, даже если эти события во времени и не пересекаются никогда.

Варианты кода равнозначны, независимо от "пересечения событий во времени".

Изменено пользователем Leka

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


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

58 минут назад, pinchemierda сказал:

Не работает на любой частоте

Уменьшите длину общего провода до нуля — соедините демоплату и плату с дисплеем не проводом, а перемычкой, подключённой к контакту общего провода, расположенному в том же месте, что и контакты данных. Длины проводов кабеля данных соответственно тоже уменьшите насколько возможно.

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


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

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

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

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

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

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

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

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

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

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