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

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

наверняка нагляднее "тайных знаний" о возможности "монтажного ИЛИ" у синтезатора )))

Причем тут синтезатор? В моделировщике все тоже самое. Это никакое не тайное знание. Это просто возможность языка как такового. Если пользуетесь оператором "assign", то должны знать, как он работает, и что делает. Если не знаете - то, значит, надо учить матчасть (3.7.1 и 3.7.2 в IEEE Std 1364-2001) :)

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


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

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

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


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

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

Ровно на столько же, сколько надо, чтобы понять, откуда берутся все составляющие явно записанной логической функции. (подразумевая, что в обоих случаях нет комментария, откуда что взялось). Кстати, в случае wired logic, даже проще - поиск по переменной покажет сразу все места, куда она подключена. А так искать отдельно куда каждая из переменных прицеплена.

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


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

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

 

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


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

А чем описание

 

wire [...]BUS = 0;
for( i =0;i ....)
  assign BUS  = BUS | EXT_BUS[i];

 

отличается от

 

wire [...]BUS;
assign BUS = EXT_BUS[0] | EXT_BUS[1] | EXT_BUS[2] ...;

 

с точки зрения понимания конкретного куска кода?

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


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

Непонятен вопрос.

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

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


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

ну так вот 1 кусок возможен только потому что можно сделать начальное присвоение ваера 0.

не об этом ли мы говорим?

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


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

ну так вот 1 кусок возможен только потому что можно сделать начальное присвоение ваера 0.

 

первый кусок, по идее, возможен только для типов wor или wand для синтеза. А для wire - это "Error - can not resolve multiple drivers on wire". Потому, что... Читаем 3.7.1 в стандарте V-2001...

 

Logical conflicts from multiple sources of the same strength on a wire or a tri net result in x (unknown) values.

 

То есть:

 

wire net = 1'b0;

 

это синоним

 

wire net;

assign net = 1'b0;

 

а потом второй

 

assign net = net | net1;

 

даст конфликт с результатом "x", как только net1 станет=1 - так как net уже подсоединен к жесткому источнику нуля, а еще и подсоединен к "net | net1". Более того, как только net1 станет единицей, даже если разрулить конфликт типом wor, такой "net" защелкнется в жесткой 1, так как "net = 1'b0 | net | ..." всегда станет равен 1. Если тип будет wand - то такая конструкция (получится net = 1'b0 & ( net | ...)) всегда будет в нуле. Потому, что у типов "wire/wand/wor" нет понятия инициализации, это провода, которые куда то подключаются к одному или нескольким источникам сигналов. Это не reg, им нельзя присвоить сначала одно, потом другое. Тут, как бы, все присвоения делаются одновременно, порождая или не порождая конфликт, который разруливается согласно 3.7.1 и 3.7.2 стандарта. Но для понимания сути работы wire/wand/wor терминология подключения провода к разным типам выходов куда понятнее и нагляднее.

 

дополнительно читаем 6.1 - 6.1.1 и 6.1.2 - которые говорят, что присвоение при объявлении и в assign это одно и тоже, и работают одинаково.

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


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

да я тоже проверил, правда вся шина либо Х, либо улетает в 1 либо улетает в 0... если вы это поняли только глядя в стандарт без тестов, снимаю шляпу:) у меня так не получилось понять:)

 

тогда остается один способ, все тоже самое только через reg, и always @(*).

 

 

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


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

у меня так не получилось понять:)

Это Ваша программерская религия понять не позволяет, как это так, провода и драйверы... Из-за нее, опять, конструкции с детскими ошибками тут предлагаете... А вот если бы хоть раз закоротили два выхода логики и ткнулись осциллографом, тогда бы поняли и без стандарта, что такое два assign-а одной wire разных значений. Там, натурально, полная "Х" получается...

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


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

ладно вам меня гнобить то.

через reg то правильно написано... ну через wire тоже синтезатор не жалуется, результат - отстойный, факт, но error не дает...

 

при том можно же писать

 

wire a;

wire b;

wire c;

assign c = a | b;

 

вот assign c = c | b; тоже можно, только работать не будет;) и не в драйверах дело...

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


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

и не в драйверах дело...

именно в драйверах. Опять, учим матчасть:

 

3.2.1 Net declarations

The net data types shall represent physical connections between structural entities, such as gates. A net shall not store a value (except for the trireg net). Instead, its value shall be determined by the values of its drivers, such as a continuous assignment or a gate.

 

Если один из них имеет силу (strong0, strong1), а второй - (weak0, weak1) - то конфликта не будет.

Опять же, отошлю в стандарт языка - 7.9 Logic strength modeling, 7.10 Strengths and values of combined signals

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


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

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

 

wire b = b | a.

один драйвер на конце а, а другой драйвер на конце b - и чему драйвер на конце b равен если он b | a?

 

это косяк скорее от того что wire не может сохранять значения и потому конструкция b=b|a не верна... этим он отличается от reg для которого

 

reg b = 0;

always @(*) b = b | a;

 

в целом допустимо.

 

так что если очень широко взять вопрос не в драйверах дело... логика нарушена...

ну а теперь давайте прижимайте меня стандартом....

 

 

 

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


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

wire b = b | a.

один драйвер на конце а, а другой драйвер на конце b - и чему драйвер на конце b равен если он b | a?

 

Элементарно, Ватсон! Берем, и представляем себе логический элемент "2ИЛИ" (К155ЛЛ1) - на один из входов которого заведен его же выход (он и есть драйвер), а на другой - некоторый сигнал "а" с другого драйвера. Дальше сами догадаетесь, как это работает? Это не косяк! Что описали, так оно и работает, и никакая логика не нарушена ни на йоту. Это описание "одноразовой"защелки, которая выдает на выходе 1 всегда, после того, как на ее вход "a" подали 1, но с неопределенным начальным состоянием - то есть, по сути, элемент, который не применим в реальных схемах.

 

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

 

Правильно - сделать

assign b = (b | a) & ~reset;

тогда появляется физическая возможность сброса этой защелки, то есть, получается RS-триггер

 

А драйверы нужны, когда несколько assign одной wire делаются, а не один, как в Вашем примере. Когда у "провода" всего один драйвер (один assign == один драйвер), то и конфликтов быть не может.

 

 

UPD:

Кстати, Ваш пример с reg и assign - крайне неудачный. Так как в симуляторе он, конечно, будет работать, а в железе - нет (50/50), так как начальное значение будет непредсказуемое, несмотря на, как бы, явную инициализацию в языке.

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


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

С вами трудно спорить, вы все время меняете текст и что-то дописываете:)...

 

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

 

правильнее так

reg b = 0;
always @(*)
begin 
reg b = 0;
b = b | a;
end

 

на вопрос зачем оно так, потому что вместо 1 присвоения может быть цикл...

 

 

 

UPD:

Кстати, Ваш пример с reg и assign - крайне неудачный.

Ну вот опять:)... вы что-то дописали:)

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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