3
votes

I'm totally new to Verilog programming and I do not understand where to initialize reg variables?

Let's have a look at the following snippets: Edit: Warning at synthesize

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

or

module test (
       output LED0 
       );   

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

assign LED0 = led;
endmodule

Give me: Using initial value of led since it is never assigned at the line: reg led = 1'b1;

Are reg types only assigned in always@ block?

Another example:

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

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

always@ (posedge clk) begin

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

Here the reg has an initial value of 0 but I've set it before to 1... What's wrong? Thank you!

2

2 Answers

7
votes

Are reg types only assigned in always@ block?

No, reg types can be assigned in always blocks and initial blocks (plus task and function but I'll skip them in the scope of this question)

For your fourBitCounter, the reg[3:0] counter declared in the initial block creates a local variable also called counter that is only accessible within the scope of the block it was created in. You need to remove the reg[3:0] in the initial block so that the assignment get applied the the intended counter. But it will still not work because you declared counter as an inferred wire type and always/initial blocks cannot assign wires.

counter was declared as an output of a 4-bit inferred wire (output [3:0] counter is synonyms to output wire [3:0] counter). Since counter is assigned in an always block and initial block it needs to be a reg type. Therefore it should be declared as output reg [3:0] counter.

Also, you declared clk as in input and as a local wire, it cannot be both. Ports can be accessed locally, there is no reason to re-declare them as local nets.

FYI: for a 4-bit value, 15+1 equals 0 because there is nothing to store the 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

For Verilog, assign statements can only be applied on net types (e.g. wire). This is legal:

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

This is illegal:

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

From your first code sample:

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

The same issue exists in your second sample; you're declaring a separate register in the initial block. Don't use the keywords reg or wire if you're just trying to assign a value.