Jump to content
    

Непрерывное присвоение на Verilog

Ага. Об этом помнишь, допустим, первые пятнадцать часов, после того, как всю схему продумал в общем. А потом, когда дело доходит до описания этого места, просто ошибаешься, по забывчивости, и делаешь не то, или просто путаешь с другим участком схемы. Поэтому я сначала описываю все необходимые в схеме основные сигналы, как wire и как reg, а потом это упрощает жизнь.

Ну, у меня как-то другой опыт: ничего, кроме неудобств от переобъявления reg/wire, не испытывал. Сейчас почти везде bit, забыл о проблемах.

 

Чего наоборот то? У меня тоже в ассигнах что попроще. А сложная, тяжелая логика, описанная в always, это редкое исключение, такая логика без регистра на выходе - большая редкость.

Не вижу противоречий. Триггеры на выходе логики - обычное дело, но кто обязывает их лепить в этом же блоке? Пример про fsm уже привели.

Share this post


Link to post
Share on other sites

см. two process fsm coding

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

 

ничего, кроме неудобств от переобъявления reg/wire, не испытывал.

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

 

но кто обязывает их лепить в этом же блоке?

Никто не обязывает. Собственный опыт подсказывает, что, если не хочешь возиться сутками в поисках багов, или в вычислении, откуда вечно нехватающие 100 пикосекунд вытащить, то надо делать именно так. За редким исключением.

 

ЗЫ

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

Share this post


Link to post
Share on other sites

Отвратный стиль

 

интересно, а Вы как тогда описываете автоматы ? В одном always блоке ?

 

Share this post


Link to post
Share on other sites

В одном always блоке ?

Да. Тем более, что разницы нет почти никакой с описанием в двух блоках, кроме убийства второго (регистрового) блока целиком и замены в первом "always @*" на "always @(posedge clk)". Вот, как-то типа такого (половину комментариев убил, ибо нечего им тут делать):

 

always @(posedge clk or posedge reset)
if (reset)
	ddr_fsm <= DDR_WAIT_INIT;
else if (fsm_error) // from bad state detector
	ddr_fsm <= DDR_WAIT_INIT;
else
	case (ddr_fsm)
		// wait for INIT fsm complete
		DDR_WAIT_INIT:       if (ddr_ini_fsm == DDR_INI_COMPLETE) ddr_fsm <= DDR_WAIT_Toit_1;
		// Wait for Toit
		DDR_WAIT_Toit_1:     if (dly_end) ddr_fsm <= DDR_STOP;
		// STOP phase
		DDR_STOP:            	if (reinit) ddr_fsm <= DDR_WAIT_INIT;
							 else if (refi_req) ddr_fsm <= bank_active_any ? (pch_ok ? DDR_PRE_REF : DDR_PRE_PRE_REF) : DDR_DO_REF;
							 else if (read_rq || write_rq)
                                  			if (open_bank) ddr_fsm <= DDR_OPEN_BANK;
							   else if (reopen_bank) ddr_fsm <= pch_ok ? DDR_REOPEN_BANK : DDR_PRE_REOPEN_BANK;
							   else ddr_fsm <= read_rq ? (rw_ok_a ? DDR_READ : DDR_PRE_READ) : (rw_ok_a ? DDR_WRITE : DDR_PRE_WRITE);

           		// Precharge selected bank if reopen needed
		DDR_PRE_REOPEN_BANK: if (pch_ok) ddr_fsm <= DDR_REOPEN_BANK;
		DDR_REOPEN_BANK:     ddr_fsm <= DDR_WAIT_Trp_3;
		DDR_WAIT_Trp_3:      if (dly_end) ddr_fsm <= DDR_OPEN_BANK;
		// Open selected bank
		DDR_OPEN_BANK:       ddr_fsm <= DDR_WAIT_Trcd;
		DDR_WAIT_Trcd:       if (dly_end) ddr_fsm <= reading ? (rw_ok_b ? DDR_READ : DDR_PRE_READ) : (rw_ok_b ? DDR_WRITE : DDR_PRE_WRITE);

		DDR_PRE_READ:        if (rw_ok) ddr_fsm <= DDR_READ;
           		DDR_READ:            ddr_fsm <= DDR_STOP;

		DDR_PRE_WRITE:        if (rw_ok) ddr_fsm <= DDR_WRITE;
           		DDR_WRITE:           ddr_fsm <= DDR_STOP;

		// Wait if was incomplete wait
		DDR_PRE_PRE_REF:     if (pch_ok) ddr_fsm <= DDR_PRE_REF;
		// Precharge if opened
		DDR_PRE_REF:         ddr_fsm <= DDR_WAIT_Trp_2;
		DDR_WAIT_Trp_2:      if (dly_end) ddr_fsm <= DDR_DO_REF;
		// Refresh
		DDR_DO_REF:          ddr_fsm <= DDR_WAIT_Toit_1;

	endcase

Share this post


Link to post
Share on other sites

Ясно.

Вся grlib таким вот "отвратным стилем" написана.

 

Отвратный стиль

 

Тем более, что разницы нет почти никакой

Share this post


Link to post
Share on other sites

Ясно.

 

Судя по приведенным цитатам, ничего не ясно. Поясню.

 

Практически нет разницы во внешнем виде описания тела автомата.

 

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

 

Вся grlib таким вот "отвратным стилем" написана.

Ну это сугубо их проблема. Повторюсь, это мое личное мнение. А о вкусе и цвете можете вести спор, если он Вам интересен. Я привел тот аргумент, почему, пройдя по граблям, я отказался от таких описаний. Некоторые, возможно, еще по ним не ходили. У них все еще впереди. Либо, эти проблемы они решают применением более быстрого/большого кристалла, а не оптимизацией описания, что, тоже, вполне хороший путь, если денег лишних много. А решать это (на примере grlib) приходится пользователям, а не авторам.

Share this post


Link to post
Share on other sites

Нахожусь в ступоре :) Когда возник вопрос "а как собственно описывать автомат правильно" , то на просторах интернета нашел "Synthesizable Finite State Machine Design Techniques Using the New SystemVerilog 3.0 Enhancements" от Sunburst Design. Там много всяких техник описано, но про один always блок было упомянуто как о технике которую надо избегать.

 

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

 

Да к вроде бы следующее состояние (NEXT) и используется исключительно для определении текущего (STATE), согласно "two always block coding style".

post-74507-1423653716_thumb.png

Share this post


Link to post
Share on other sites

Да к вроде бы следующее состояние (NEXT) и используется исключительно для определении текущего (STATE), согласно "two always block coding style".

 

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

Share this post


Link to post
Share on other sites

в описании автомата в одном always вижу только проблемы со смешение переходов и работы автомата. Чисто описательной. То есть если автомат в каждом состоянии делает много работы, то его становиться трудно читать, состояния разрастаются и переходы зрительно теряются. Я эту проблему для себя решил taskами, то есть в самом описании автомата у меня переходы и внутри состоянии вызовы тасков. Описание сокращается, зрительный анализ не теряется. ИМХО...

 

Share this post


Link to post
Share on other sites

Я эту проблему для себя решил taskами,

Это не эта проблема, не мешайте мух с котлетами. От этого не зависит, выносить регистр, хранящий состояние автомата в отдельный блок, состоящий из одной строчки "fsm <= fsm_next_state", или сделать это сразу в одном блоке.

Share this post


Link to post
Share on other sites

SM, Вы же пишете про бритву Оккама, радеете за Verilog вместо VHDL, но тут же говорите, что различие wire и reg - это полезно, чтобы не наделать ошибок по невнимательности, т.к. синтезатор всё подскажет. Тогда уж надо перейти к строгой типизации VHDL, там уж точно синтезатор ошибки будет находить.

Моё мнение: если уж мы отказались от строгостей VHDL, сказав, что мы будем за свои ошибки отвечать сами, имея преимущество в удобстве написания, то тогда надо за ошибки отвечать самому до конца.

Поддерживаю dxp в том, что неудобно лезть в объявление переменных и менять wire на reg. Да, Вы говорите что поменять объявление всего несколько секунд. Но тут всплывают те же тезисы, что и в холиваре между тоннами писанины на VHDL и краткостью Verilog: не сама писанина страшна, это действительно всего несколько лишних нажатий на клавиатуре. Пугает чисто психологический момент (возвращаемся обратно к wire и reg): вот, надо из текущего положения исходника куда-то лезть в его начало, выискивать там этот злополучный сигнал и менять его объявление. А затем возвращаться обратно и искать то положение в тексте, над которым я работал, которое было на экране. В результате даже мысль можно потерять из-за таких переключений внимания. И тогда можно наделать ещё больше неочевидных системных ошибок (которые тоже не обнаруживаются синтезатором как ошибки), чем ошибка в наличии/отсутствии задержки сигнала на такт.

 

По причине неудобства лезть в объявление, чтобы поменять wire на reg у меня одно время был такой стиль написания, что я все сигналы объявлял как reg, а затем комбинаторику описывал в блоках always @*. Затем немножко изменил мнение: мне понравилось, что при использовании wire и assign можно кратко и наглядно выполнить простые мультиплексоры через ? и :, в одну строчку, чтобы не загромождать код блоками олвэйзов. Пришлось ради этого мириться с необходимостью лезть в объявления в случае изменений способа обработки сигнала...

 

У некоторых есть ещё привычка ставить перед сигналом префикс его объявления типа w_my_signal или r_my_signal. Я вот тоже против таких префиксов, т.к. потом при необходимости изменения объявления придётся все сигналы заменять. Пусть и автозаменой. Но я ей не доверяю на 100%, боюсь, что что-то лишнее в общем случае может попасть под паттерн, поэтому стараюсь автозамены не делать либо делать их с подтверждением вручную по каждой замене, анализируя, что же предлагается заменить. А это уже небыстро...

К тому же, у некоторых при таком использовании префиксов появляется соблазн использовать их не совсем по назначению. Допустим, есть 2 почти одинаковых по функциям сигнала, пусть называются они одинаково data_valid, но по типу объявлен один как wire, другой как reg, идут они с разных мест: один с комбинационной схемы, другой с триггера. Разработчику нужно их как-то отличать, и он решает отличать их только по префикску, не меняя имени согласно более узкому назначению каждого из сигналов. Затем по прошествии времени возникает (зачастую уже не у автора кода, а у другого, кто этот код поддерживает после увольнения автора и т.п.) желание что-то улучшить, и тот сигнал, который был объявлен как reg, сделать wire-ом. И тут начинается...

Share this post


Link to post
Share on other sites

но тут же говорите, что различие wire и reg - это полезно, чтобы не наделать ошибок по невнимательности, т.к. синтезатор всё подскажет. Тогда уж надо перейти к строгой типизации VHDL, там уж точно синтезатор ошибки будет находить.

 

Я, конкретно, за типизацию по электрической сущности объектов. Причем, за такую, которая не требует преобразований типов при их использовании. То есть, не строгую. Но против лишней типизации по арифметическо-логическим признакам, требующим лишних явных преобразований для использования в качестве аргументов в выражениях (пусть бы была хоть сотня типов по этим признакам, но чтобы корректно преобразовывались один к другому автоматически при использовании). Тут необходимый минимум - signed/unsigned, и, пожалуй, все.

 

Да, в верилоге она, типизация по электрической сущности, сделана слегка кривовато. Но что имеем, то имеем... На мой взгляд, как раз, некая минимально необходимая, почти достаточная... Не хватает разделения объектов на, как бы, "latch" и "pure wire". В остальном - нужный минимум.

Share this post


Link to post
Share on other sites

позволю себе вмешаться в дискуссию. М.б. стоит объявлять локальные переменные в том месте, где они используются? По счастью верилог это позволяет. Тогда не придется далеко ходить и переключать внимание для изменения типа. А то есть такая секта людей, которые все сущности объявляют в начале описания модуля, как на VHDL)))

Share this post


Link to post
Share on other sites

М.б. стоит объявлять локальные переменные в том месте, где они используются?

Ну да, почему бы и нет... особенно "сугубо местные" wire xxxx = expression, без слова assign.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...