Как «присвоить» значение выходному регистру в Verilog?

(вставьте здесь действительно простой отказ от ответственности)

В частности, у меня есть следующее объявление:

output reg icache_ram_rw

И в каком-то месте кода мне нужно поставить нулевое значение в этом рег. Вот что я пробовал и результаты:

assign icache_ram_rw = 1'b0;
( declarative lvalue or port sink reg icache_ram_rw must be a wire )

icache_ram_rw <= 1'b0;
( instance gate/name for type "icache_ram_rw" expected - <= read )

Как же мне это сделать?!


person Rafael Almeida    schedule 27.11.2009    source источник


Ответы (4)


Оператор assign используется для управления wires.

Если вы что-то объявили как reg, то вы должны дать ему значения внутри процедуры (блоки always или initial). Лучше всего устанавливать значения regs только в одном и том же блоке always. например:

always @( * ) begin // combo logic block
   if( some_condition ) begin
      icache_ram_rw = 1'b0;
   end else begin
      icache_ram_rw = something_else;
 end

Существуют важные различия между regs и wires, о которых вы должны прочитать.

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

// some parameter definitions to make logic 'read' clearer.
localparam READ = 1'b0; 
localparam WRITE = 1'b1;

// standard clocked logic 'template' that synthesis tools recognise.
always @( posedge clk or negedge resetb )
  if( !resetb ) begin  // asynchronous active low reset
     icache_ram_rw <= READ;
  end else if( some_enable_condition ) begin
     icache_ram_rw <= WRITE;
  end else begin
     icache_ram_rw <= READ;
  end
person Marty    schedule 27.11.2009
comment
Спасибо за полный ответ! Тактовая логика действительно присутствует в задании, просто я ее здесь для простоты опустил (может быть, лучше было бы добавить) =D - person Rafael Almeida; 08.12.2009

Удалите «reg» из объявления вывода, и код должен работать (по умолчанию используется проводной тип вывода).

Есть две вещи, которые большинству инженеров-самоучек или плохо обученных инженеров трудно понять в Verilog: (1) блокирующие -vs- неблокирующие присваивания (см. мою статью на эту тему: http://www.sunburst).-design.com/papers/CummingsSNUG2000SJ_NBA.pdf) и (2) reg -vs-wire. Давайте проясним последнюю тему прямо сейчас.

Все, что находится слева (LHS), или процедурное назначение (всегда, начальное, задача, функция) должно быть объявлено как тип переменной (обычно это reg). Все остальное в языке — это сеть (обычно провод). Без исключений. Это действительно так просто. Я не знаю ни одной книги Verilog, в которой бы это было сказано так просто.

Как это произошло? Я спросил Фила Мурби, хорошего друга и изобретателя языка Verilog: «Почему reg??» Фил сказал мне, что когда он изобретал Verilog, не было инструментов синтеза, и он думал, что все, что выходит из блока always, будет регистром. Он был неправ, и теперь мы застряли с этим ключевым словом «reg».

Я пытался изменить это в комитетах Veirlog и SystemVerilog более десяти лет. Я хотел бы объявить все как провод, и первое использование будет определять, ведет ли себя «провод» как reg (первое назначение из процедурного блока и последнее назначение выигрывает) или ведет себя как провод (первое назначение из управляющего источника, такого как выход модуля или непрерывное назначение и несколько драйверов разрешаются, как сегодня в Verilog), и было бы незаконным выполнять как процедурные назначения, так и назначения драйвера для одного и того же сигнала. Увы, мне не хватило голосов в комитете, чтобы принять это предложение.

Это ошибка, которую я чаще всего совершаю в своем собственном коде. Просто привыкните к таким сообщениям об ошибках, как «недопустимое назначение LHS» или «недопустимое назначение провода». Они оба означают одно и то же, вы забыли объявить свои регистры.

С уважением - Клифф Каммингс - Verilog & SystemVerilog Guru

person Cliff Cummings    schedule 27.06.2012

Обратите внимание, что вы также можете присвоить регистру начальное значение при его объявлении, например:

output reg icache_ram_rw = 1'b0;

Это обеспечит запуск с нулевым значением в моделировании. Для синтеза ваши результаты будут зависеть от инструмента синтеза и целевой технологии (для FPGA вы обычно можете назначить начальное значение для оборудования; для ASIC это не так).

person Russ Nelson    schedule 03.12.2009

  1. проблема в том, что оператор assign при синтезе создаст порт/вывод, поэтому ему нужен провод в качестве вывода.
  2. вы создали регистр с именем icache_ram_rw, теперь регистр не совпадает с пин-кодом ....
  3. поэтому для назначения регистра вам нужно использовать правильный формат verilog
  4. verilog позволяет сделать то же самое, используя оператор always, создается DFF, и входным контактом этого DFF будет ваш icache_ram_rw, формат уже предоставлен другими.
person Rahul Jain    schedule 30.09.2014