SystemVerilog generate statement scope

Hi,
up until a minute ago I thought I understood the generate construct of SystemVerilog. I have used it plenty of times in the past with success.
However, looking through some code from Xilinx I found this:

module xpm_fifo_rst # (
  parameter integer   COMMON_CLOCK     = 1,
  parameter integer   CDC_DEST_SYNC_FF = 2,
  parameter integer   SIM_ASSERT_CHK = 0

) (
  input  wire         rst,
  input  wire         wr_clk,
  input  wire         rd_clk,
  output wire         wr_rst,
  output wire         rd_rst,
  output wire         wr_rst_busy,
  output wire         rd_rst_busy
);
  reg  [1:0] power_on_rst  = 2'h3;
  wire rst_i;

  // -------------------------------------------------------------------------------------------------------------------
  // Reset Logic
  // -------------------------------------------------------------------------------------------------------------------
  //Keeping the power on reset to work even when the input reset(to xpm_fifo) is not applied or not using
   always @ (posedge wr_clk) begin
     power_on_rst <= {power_on_rst[0], 1'b0};
   end
   assign rst_i = power_on_rst[1] | rst;

  // Write and read reset generation for common clock FIFO
   if (COMMON_CLOCK == 1) begin : gen_rst_cc
    reg [2:0] fifo_wr_rst_cc = 3'b00;
    assign wr_rst        = fifo_wr_rst_cc[2];
    assign rd_rst        = fifo_wr_rst_cc[2];
    assign rd_rst_busy   = fifo_wr_rst_cc[2];
    assign wr_rst_busy   = fifo_wr_rst_cc[2];

  // synthesis translate_off
    `ifndef DISABLE_XPM_ASSERTIONS  
    if (SIM_ASSERT_CHK == 1) begin: assert_rst
      always @ (posedge wr_clk) begin
        assert (!$isunknown(rst)) else $warning ("Input port 'rst' has unknown value 'X' or 'Z' at %0t. This may cause the outputs of FIFO to be 'X' or 'Z' in simulation. Ensure 'rst' has a valid value ('0' or '1')",$time);
      end
    end : assert_rst
  `endif
  // synthesis translate_on

    always @ (posedge wr_clk) begin
      if (rst_i) begin
        fifo_wr_rst_cc    <= 3'h7;
      end else begin
  	fifo_wr_rst_cc   <= {fifo_wr_rst_cc[1:0],1'b0};
      end
    end
  end : gen_rst_cc

  // Write and read reset generation for independent clock FIFO
  if (COMMON_CLOCK == 0) begin : gen_rst_ic
    wire fifo_wr_rst_rd;
    wire fifo_rd_rst_wr_i;
    reg  fifo_wr_rst_i       = 1'b0;
    reg  wr_rst_busy_i       = 1'b0;
    reg  fifo_rd_rst_i       = 1'b0;
    reg  fifo_rd_rst_ic      = 1'b0;
    reg  fifo_wr_rst_ic      = 1'b0;
    reg  wr_rst_busy_ic      = 1'b0;
    reg  rst_seq_reentered   = 1'b0;

    assign wr_rst          = fifo_wr_rst_ic | wr_rst_busy_ic;
    assign rd_rst          = fifo_rd_rst_ic;
    assign rd_rst_busy     = fifo_rd_rst_ic;
    assign wr_rst_busy     = wr_rst_busy_ic;

    (* fsm_safe_state = "default_state" *) enum logic [2:0] {WRST_IDLE    = 3'b000,
                      WRST_IN      = 3'b010,
                      WRST_OUT     = 3'b111,
                      WRST_EXIT    = 3'b110,
                      WRST_GO2IDLE = 3'b100} curr_wrst_state = WRST_IDLE, next_wrst_state = WRST_IDLE;

    (* fsm_safe_state = "default_state" *) enum logic [1:0] {RRST_IDLE = 2'b00,
                      RRST_IN   = 2'b10,
                      RRST_OUT  = 2'b11,
                      RRST_EXIT = 2'b01} curr_rrst_state = RRST_IDLE, next_rrst_state = RRST_IDLE;

   // synthesis translate_off
    `ifndef DISABLE_XPM_ASSERTIONS   
   if (SIM_ASSERT_CHK == 1) begin: assert_rst
     always @ (posedge wr_clk) begin
       assert (!$isunknown(rst)) else $warning ("Input port 'rst' has unknown value 'X' or 'Z' at %0t. This may cause the outputs of FIFO to be 'X' or 'Z' in simulation. Ensure 'rst' has a valid value ('0' or '1')",$time);
      end
   end : assert_rst
  `endif

   // synthesis translate_on

   always @ (posedge wr_clk) begin
     if (rst_i) begin
       rst_seq_reentered  <= 1'b0;
     end else begin
       if (curr_wrst_state == WRST_GO2IDLE) begin
	 rst_seq_reentered  <= 1'b1;
       end
     end
   end

   always @* begin
      case (curr_wrst_state)
         WRST_IDLE: begin
            if (rst_i)
               next_wrst_state     <= WRST_IN;
            else
               next_wrst_state     <= WRST_IDLE;
            end
         WRST_IN: begin
            if (rst_i)
               next_wrst_state     <= WRST_IN;
            else if (fifo_rd_rst_wr_i)
               next_wrst_state     <= WRST_OUT;
            else
               next_wrst_state     <= WRST_IN;
            end
         WRST_OUT: begin
            if (rst_i)
               next_wrst_state     <= WRST_IN;
            else if (~fifo_rd_rst_wr_i)
               next_wrst_state     <= WRST_EXIT;
            else
               next_wrst_state     <= WRST_OUT;
            end
         WRST_EXIT: begin
            if (rst_i)
               next_wrst_state     <= WRST_IN;
            else if (~rst & ~rst_seq_reentered)
               next_wrst_state     <= WRST_GO2IDLE;
            else if (rst_seq_reentered)
               next_wrst_state     <= WRST_IDLE;
            else
               next_wrst_state     <= WRST_EXIT;
            end
         WRST_GO2IDLE: begin
	      next_wrst_state     <= WRST_IN;
            end
         default: next_wrst_state  <= WRST_IDLE;
      endcase
   end

   always @ (posedge wr_clk) begin
     curr_wrst_state     <= next_wrst_state;
     fifo_wr_rst_ic      <= fifo_wr_rst_i;
     wr_rst_busy_ic      <= wr_rst_busy_i;
   end

   always @* begin
      case (curr_wrst_state)
         WRST_IDLE     : fifo_wr_rst_i = rst_i;
         WRST_IN       : fifo_wr_rst_i = 1'b1;
         WRST_OUT      : fifo_wr_rst_i = 1'b0;
         WRST_EXIT     : fifo_wr_rst_i = 1'b0;
         WRST_GO2IDLE  : fifo_wr_rst_i = 1'b1;
         default:   fifo_wr_rst_i = fifo_wr_rst_ic;
      endcase
   end

   always @* begin
      case (curr_wrst_state)
         WRST_IDLE: wr_rst_busy_i = rst_i;
         WRST_IN  : wr_rst_busy_i = 1'b1;
         WRST_OUT : wr_rst_busy_i = 1'b1;
         WRST_EXIT: wr_rst_busy_i = 1'b1;
         default:   wr_rst_busy_i = wr_rst_busy_ic;
      endcase
   end

    always @* begin
      case (curr_rrst_state)
         RRST_IDLE: begin
            if (fifo_wr_rst_rd)
               next_rrst_state      <= RRST_IN;
            else
               next_rrst_state      <= RRST_IDLE;
            end
         RRST_IN  : next_rrst_state <= RRST_OUT;
         RRST_OUT : begin
            if (~fifo_wr_rst_rd)
               next_rrst_state      <= RRST_EXIT;
            else
               next_rrst_state      <= RRST_OUT;
            end
         RRST_EXIT: next_rrst_state <= RRST_IDLE;
         default: next_rrst_state   <= RRST_IDLE;
      endcase
   end

   always @ (posedge rd_clk) begin
     curr_rrst_state  <= next_rrst_state;
     fifo_rd_rst_ic   <= fifo_rd_rst_i;
   end

   always @* begin
      case (curr_rrst_state)
         RRST_IDLE: fifo_rd_rst_i <= fifo_wr_rst_rd;
         RRST_IN  : fifo_rd_rst_i <= 1'b1;
         RRST_OUT : fifo_rd_rst_i <= 1'b1;
         RRST_EXIT: fifo_rd_rst_i <= 1'b0;
         default:   fifo_rd_rst_i <= 1'b0;
      endcase
   end

    // Synchronize the wr_rst (fifo_wr_rst_ic) in read clock domain
    xpm_cdc_sync_rst #(
      .DEST_SYNC_FF      (CDC_DEST_SYNC_FF),
      .INIT              (0),
      .INIT_SYNC_FF      (1),
      .SIM_ASSERT_CHK    (0),
      .VERSION           (0))
      wrst_rd_inst (
        .src_rst         (fifo_wr_rst_ic),
        .dest_clk        (rd_clk),
        .dest_rst        (fifo_wr_rst_rd));

    // Synchronize the rd_rst (fifo_rd_rst_ic) in write clock domain
    xpm_cdc_sync_rst #(
      .DEST_SYNC_FF      (CDC_DEST_SYNC_FF),
      .INIT              (0),
      .INIT_SYNC_FF      (1),
      .SIM_ASSERT_CHK    (0),
      .VERSION           (0))
      rrst_wr_inst (
        .src_rst         (fifo_rd_rst_ic),
        .dest_clk        (wr_clk),
        .dest_rst        (fifo_rd_rst_wr_i));
  end : gen_rst_ic
endmodule : xpm_fifo_rst

This is just a module that comes with the current Vivado installation and which is used to handle reset signals in a fifo, I pasted the entire thing in case it is relevant.

Just a few lines into the module there a line which reads


   if (COMMON_CLOCK == 1) begin : gen_rst_cc

that if statement is not inside of any always, function or task, it is just standing on it’s own. Inside the if code there are register definitions, assign statements, etc.

My confusion comes from the fact that I always thought that in order to have conditional instantiations, declarations and assignments one always needed a generate block.
Can somebody clarify that for me please? I have searched everywhere and I have not found any examples of code where the generate or if statements are used as the case above…

In reply to arquer:

The generate/endgenerate keywords were made optional in Verilog IEEE Std 1364-2005. The compiler can tell from the context whether for, if, and case statements are procedural or represent a generate block.

What’s really amusing/annoying are the assertions that follow the code you posted wrapped in three layers of guards: 1) a pragma comment, 2) a conditional compiler directive, and 3) a generate-if

 // synthesis translate_off
    `ifndef DISABLE_XPM_ASSERTIONS  
    if (SIM_ASSERT_CHK == 1) begin: assert_rst
      always @ (posedge wr_clk) begin
        assert (!$isunknown(rst)) else $warning ("Input port 'rst' has unknown value 'X' or 'Z' at %0t. This may cause the outputs of FIFO to be 'X' or 'Z' in simulation. Ensure 'rst' has a valid value ('0' or '1')",$time);
      end
    end : assert_rst
  `endif
  // synthesis translate_on

I don’t understand why people use pragma synthesis on/off comments when conditional compiler directives are so much easier for tools to work with (comments get stripped away by many pre-processors. Even easier is to write the assertion by itself and there are control constructs to turn on/off assertions without needed any guards.

assert property (@(posedge clk) !$isunknown(rst)) else $warning ("Input port 'rst' has unknown value 'X' or 'Z' at %0t. This may cause the outputs of FIFO to be 'X' or 'Z' in simulation. Ensure 'rst' has a valid value ('0' or '1')",$time);

In reply to dave_59:

Thanks Dave! that makes a lot of sense! :)