2016-11-28 5 views
0

Я совершенно новый для программирования Verilog, и я не понимаю, где инициализировать переменные reg?Verilog reg assign?

Давайте посмотрим на следующие фрагменты: Edit: Warning at synthesize

module test (
     output LED0 
     ); 
reg led = 1'b1; 
assign LED0 = led; 
endmodule 

или

module test (
     output LED0 
     ); 

reg led; 
initial begin 
    reg led <= 1'b1; 
end 

assign LED0 = led; 
endmodule 

Дайте мне: Используя начальное значение привело, так как он никогда не назначается на линии: reg led = 1'b1;

Есть ли reg типы, которые назначаются всегда в блоке @?

Другой пример:

module fourBitCounter 
     (input clk, 
     output [3:0]counter 
     ); 

wire clk; 
initial begin 
reg[3:0] counter = 4'b1; 
end 

[email protected] (posedge clk) begin 

     if(counter > 15) 
       counter <= 0; 
     else 
       counter <= counter + 1; 
     end endmodule 

Здесь р имеет начальное значение 0, но я поставил перед 1 ... Что случилось? Спасибо!

+0

Вы, вероятно, не хотите использовать 'reg' ключевое слово внутри и' initial' блок. – toolic

+0

Вы правы. Но тот же результат, хотя ... –

ответ

1

Существуют ли типы регистров, назначенные всегда в блоке @?

Нет, reg типов могут быть назначены в always блоках и initial блоков (плюс task и function, но я пропущу их в рамках данного вопроса)

для вашего fourBitCounter, в reg[3:0] counter объявленный в Блок initial создает локальную переменную, также называемую counter, доступную только в пределах области, в которой он был создан. Вам нужно удалить reg[3:0] в начальном блоке, чтобы присвоение получило назначенный counter. Но это все равно не сработает, потому что вы объявили counter как предполагаемый тип провода, а блоки always/initial не могут назначать провода.

counter был объявлен как выход 4-битного проводника (output [3:0] counter является синонимом output wire [3:0] counter). Поскольку counter назначен в блоке always и initial, он должен быть reg. Поэтому он должен быть объявлен как output reg [3:0] counter.

Кроме того, вы указали clk как на входе, так и в качестве местного провода, это не может быть и то, и другое. Порты могут быть доступны локально, нет причин повторно объявлять их как локальные сети.

FYI: для 4-битного значения 15 + 1 равно 0, потому что ничего не хранить MSB.

module fourBitCounter (
    input clk, 
    output reg [3:0] counter // 'output reg', not 'output' 
); 

//wire clk; // do not do this, clk is an input 
initial begin 
    counter = 4'b1; // no 'reg' here 
end 

always @(posedge clk) begin 
    if(counter > 15) // this will never evaluate as true with counter declared as 4-bit 
    counter <= 0; 
    else 
    counter <= counter + 1; 
end 
endmodule

Для Verilog, assign заявления могут быть применены только в чистых типов (например wire). Это законно:

module test (output LED0); // LED0 is an inferred wire 
assign LED0 = 1'b1; 
endmodule 

Это незаконно:

module test (output reg LED0); // Explicit reg 
assign LED0 = 1'b1; // illegal, assign on a reg 
endmodule 
+0

Спасибо за ваш ответ! Это помогло мне исправить мои неправильные ошибки, но у меня есть еще один вопрос: почему вы использовали не-присвоение внутри процедурного блока? Почему нет: счетчик <= 4'b1. Постскриптум счетчик по-прежнему 0 в начале, возможно, исходный блок не синтезируется? –

+0

В начальном блоке я использовал назначение блокировки ('='). В всегда блоке я использовал неблокирующее присваивание ('<='), это должно было использоваться для назначения запланированных провалов/затворов во всех случаях. Я мог бы использовать неблокирование в исходном блоке, но я обычно не придерживаюсь своего стиля кодирования. Неблокирование откладывает обновление в планировщике, которое полезно для краев часов, но не в нулевое время – Greg

+0

Теперь все имеет смысл, кроме следующего: Можно ли назначить рег на провод, как в моем первом примере? Что там не так? Даже если бы я назначил светодиод внутри начального блока, я бы все равно получил: использование начального значения светодиода, так как он никогда не назначается –

0

С первого образца кода:

reg led;    // <-- This declares one register called "led" 
initial begin 
    reg led <= 1'b1; // <-- This declares a *separate* register called "led" 
end     //  which is only valid in the initial block 

Та же проблема существует в вашем втором образце; вы объявляете отдельный регистр в блоке initial. Не используйте ключевые слова reg или wire, если вы просто пытаетесь присвоить значение.

+0

Да, я действительно ошибся. Но даже без регистра или провода перед именем переменной это не делает работу. Как насчет моего первого примера? –

Смежные вопросы