[verilog] Assign a synthesizable initial value to a reg in Verilog

I'm an FPGA noob trying to learn Verilog. How can I "assign" a value to a reg in an always block, either as an initial value, or as a constant. I'm trying to do something like this in the code below. I get an error because the 8 bit constant doesn't count as input. I also don't want to trigger the always off of a clock. I just want to assign a register to a specific value. As I want it to be synthesisable I can't use an initial block. Thanks a lot.

module top
(
    input wire clk,
    output wire [7:0] led   
 );


reg [7:0] data_reg ; 
always @*
begin
    data_reg = 8'b10101011;
end

assign led = data_reg;

endmodule

This question is related to verilog

The answer is


You can combine the register declaration with initialization.

reg [7:0] data_reg = 8'b10101011;

Or you can use an initial block

reg [7:0] data_reg;
initial data_reg = 8'b10101011;

The other answers are all good. For Xilinx FPGA designs, it is best not to use global reset lines, and use initial blocks for reset conditions for most logic. Here is the white paper from Ken Chapman (Xilinx FPGA guru)

http://japan.xilinx.com/support/documentation/white_papers/wp272.pdf


When a chip gets power all of it's registers contain random values. It's not possible to have an an initial value. It will always be random.

This is why we have reset signals, to reset registers to a known value. The reset is controlled by something off chip, and we write our code to use it.

always @(posedge clk) begin
    if (reset == 1) begin // For an active high reset
        data_reg = 8'b10101011;
    end else begin
        data_reg = next_data_reg;
    end
end

You should use what your FPGA documentation recommends. There is no portable way to initialize register values other than using a reset net. This has a hardware cost associated with it on most synthesis targets.


The always @* would never trigger as no Right hand arguments change. Why not use a wire with assign?

module top (
    input wire clk,
    output wire [7:0] led   
);

wire [7:0] data_reg ; 
assign data_reg   = 8'b10101011;
assign led        = data_reg;

endmodule

If you actually want a flop where you can change the value, the default would be in the reset clause.

module top
(
    input        clk,
    input        rst_n,
    input  [7:0] data,
    output [7:0] led   
 );

reg [7:0] data_reg ; 
always @(posedge clk or negedge rst_n) begin
  if (!rst_n)
    data_reg <= 8'b10101011;
  else
    data_reg <= data ; 
end

assign led = data_reg;

endmodule

Hope this helps