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

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

2 часа назад, Джеймс сказал:

Ну и в каком случае вы говорили то, что соответствует действительности?

В обоих. С чего взяли, что одно другое исключает? Пробовал делать со сбросом от 44 пина в синхронном варианте (медленном), когда он был ещё не работоспособен. Затем методом тыка подобрал вариант (увидел на ютуб канале Jack0v) детектора фронтов с которым заработало. В конечном варианте асинхронный сброс уже не использовал, потому что и без него норм.  

Сейчас пытаюсь сделать асинхронный (быстрый) SPI, вообще не зависящий от i_core_clk, тактируемый spi клоком.

6 часов назад, Nick_K сказал:

Зачем всё лепить в одном процессе? Сложно вынести txsw и counter в один процесс, а spirx и txbuf в другой

Каюсь, с первого раза не усвоил дельный совет)) Действительно разные схемы в итоге синтезируются! Спасибо, что ткнули носом, куда надо))

Приём стал на много лучше, но всё ещё периодически проскакивают артефакты.

	
module spi_slave(
							input wire SS,
							input wire SCLK,
							output wire MISO,
							input wire MOSI,
							
							output reg [7:0]spirx,
							input wire [7:0]spitx
);

	reg [7:0]txbuf; 
	reg [7:0]spireg; 
	reg txsw;    
	reg [2:0]counter;

	always @(negedge SCLK or posedge SS) 
	begin
		if(SS) 
		begin
			txsw <= 1'b0;
			counter <= 3'd0;
		end
		else 
		begin
			txsw <= 1'b1;
			counter <= counter + 1'd1;
		end
	end
	
	always @(negedge SCLK) 
	begin
		if(counter == 3'd7) spirx <= spireg;
		if(counter == 3'd7 || ~txsw) txbuf <= spitx;
	end

	always @(posedge SCLK) 
	begin
	  spireg <= {spireg[6:0], MOSI};
	end
	
	assign miso_mux = (txsw) ? txbuf[3'd7-counter] : spitx[3'd7-counter];
	assign MISO = (~SS) ? miso_mux : 1'bz;

endmodule

  

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


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

15 hours ago, Nick_K said:

Логично выглядит?

Сейчас посмотрел, во что синтезируется подобный код(см. ниже), и погладил себя по головке - сам _никогда_ не использую асинхронный сброс.

top(
input clk, nclr, d,
output reg q
);
always@(posedge clk or negedge nclr)
	if(! nclr);
	else q<=d;
endmodule

 

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

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


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

И что же такого страшного вы там могли увидеть? Триггер с асинхронным сбросом - это он вас так напугал? Хотя постойте, именно приведенный вами код действительно будет превращаться во что-то пострашнее - это же какой-то регистр-защелка, и он совсем без сброса де-факто! По nclr синтезатору нужно придумать, как сохранить предыдущее состояние. Поэтому и результат синтеза впечатляет. Только причем здесь асинхронный сброс?

А вообще - это не должно быть догмой. В разных ситуациях по-разному: где-то лучше придерживаться синхронных сбросов, а в других - асинхронные имеют явные преимущества.

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


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

Триггер с асинхронным сбросом составляет основу типовой ячейки ПЛИС, т.е. он в готовом виде уже имеется безо всяких синтезирований.

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


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

module top(
input clk, nclr, d,
output reg q
);
always@(posedge clk or negedge nclr)
        q<=d;
endmodule

Очевидно?

11 minutes ago, Raven said:

именно приведенный вами код

Поправил, имел в виду обычное описание асинхронного сброса "if(! nclr)".

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


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

1 minute ago, Raven said:

Поправьте до конца тогда уж.

Код для случая, когда какой-либо регистр пропущен в ветке "if(! nclr)", по ошибке или незнанию.

 

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


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

1 minute ago, Leka said:

Код для случая, когда какой-либо регистр пропущен в ветке "if(! nclr)", по ошибке или незнанию.

Для борьбы с ошибками или незнанием существуют штуки под названиями верификация, LINT check и даже более страшный equivalence check. Это не значит, что нужно только из-за этого лишать себя асинхронных сбросов.

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


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

 Асинхронный сброс - это костыль. Противоречит здравой идее синхронного дизайна. Служит источником трудноуловимых ошибок. Замусоривает код. И тд и тп. 

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

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


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

1 hour ago, Leka said:

Сейчас посмотрел, во что синтезируется подобный код(см. ниже),
и погладил себя по головке - сам _никогда_ не использую асинхронный сброс.

 

@Leka Извините, вопрос совсем не по теме.  А Вы "в команде" занимаетесь FPGA-разработкой или один?

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


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

Не хочу вестись на очередной holywar. Отмечу только, что любая идея, доведенная до абсолюта, приводит, как правило, к плохим результатам.

P.S. Немного не удержался все-таки: попробуйте задать начальные состояния своей логики в отсутствие тактового сигнала.

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


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

6 hours ago, Leka said:

 Асинхронный сброс - это костыль. Противоречит здравой идее синхронного дизайна. Служит источником трудноуловимых ошибок. Замусоривает код. И тд и тп. 

По секрету расскажу, в ПЛИС не бывает FF с синхронным сбросом в виде чистого примитива. В общем то как и в ASIC. Любое понятие "FF с синхронным сбросом" достигается путём дополнительной логики, которая делает оной (сброс) синхронным.

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

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


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

2 hours ago, Nick_K said:

Тогда в чём проблема?

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

8 hours ago, Raven said:

задать начальные состояния своей логики в отсутствие тактового сигнала.

Тактовый сигнал отсутствует при включении питания, тогда куча процессов происходит - перевод GPIO в режим загрузки, загрузка прошивки, сброс всех регистров в начальное состояние (инициализация), ожидание захвата PLL, перевод GPIO в пользовательский режим, и только потом поведение соответствует коду. Так что в синхронном дизайне клок есть всегда, а начальное состояние регистров задается строками вида "reg [7:0] q = 8'd123" (и тп).

9 hours ago, Leka said:

 


module top(
input clk, nclr, d,
output reg q
);
always@(posedge clk or negedge nclr)
        q<=d;
endmodule

 

Попробуйте объяснить результат синтеза.

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


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

1 hour ago, Leka said:

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

Вы несёте какой-то бред.

Ещё раз, сигнал для управления асинхронным сбросом формируется в синхронном домене (рассмотрим случай одного домена, без переходов). Timing Analysis в конце делает проверку, что все пути внутри этого синхронного домена соответствуют временным констрейнам, а это значит, что все формируемые сигналы (не важно установка или снятие сигнала) придёт от точки формирования до точки получения своевременно (без слэков). Ну или выдаст, что есть превышение RAT над AT, что в результате даст Slack. Единственная поправка для сигналлов асинхронного сброса - это значения setup и hold могут значительно отличаться от таковых в FF, о чём IDE прекрасно знает и учитывает.

Таким образом, если в проекте нет отрицательных значений Slack, то как установка, так и снятие сигналлов, включительно сигналлы сброса и установки (синхронные и асинхронные - неважно), соответствуют заданным временным параметрам констрейнов и Violation'ов не будет.

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


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

Блин, все умными словами разговаривают такими))) Я с вашего разрешения напомню о своей проблеме? 

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

always @(posedge i_core_clk or negedge rst), i_core_clk здесь частота от генератора 50МГц. 

И ещё вопрос, есть разница от какого пина тактировать модуль? Если нет, то для чего у микросхемы есть специальные пины для подключения внешнего генератора (у EPM240T100C5 это PIN12, 14, 64, 62)? Если делать асинхронный SPI может имеет смысл подключать SPI CLK на один из этих выводов?      

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


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

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

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

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

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

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

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

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

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

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