Menu

#955 Problem of index in a generate block

v0.9
closed-fixed
nobody
None
5
2015-02-20
2014-07-07
Matthieu
No

I would like to report a bug in Icarus Verilog version 0.9.7 (v0_9_7).
The code is rejected at the compilation.
This is the code of a generic multiplexer for N inputs, 1 output.
The code compile perfectly with quartus and with Xilinx also.

You can see below my shell output :

iverilog -Wall ro_puf_mux_n_to_1.v -o tb_mux_n_to_1.v
ro_puf_mux_n_to_1.v:80: error: Index of inter_w[(((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)] needs to be constant in this context.
ro_puf_mux_n_to_1.v:80: : Index expression is: (((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)
ro_puf_mux_n_to_1.v:80: : Context scope is: ro_puf_mux_n_to_1.genblk2.SELECT_STAGE[1].genblk6.INTERMEDIARY_STAGE[0]
ro_puf_mux_n_to_1.v:80: error: Output port expression must support continuous assignment.
ro_puf_mux_n_to_1.v:80: : Port dat_o of ro_puf_mux_2_to_1 is connected to inter_w[(((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)]
ro_puf_mux_n_to_1.v:80: error: Index of inter_w[(((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)] needs to be constant in this context.
ro_puf_mux_n_to_1.v:80: : Index expression is: (((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)
ro_puf_mux_n_to_1.v:80: : Context scope is: ro_puf_mux_n_to_1.genblk2.SELECT_STAGE[1].genblk6.INTERMEDIARY_STAGE[1]
ro_puf_mux_n_to_1.v:80: error: Output port expression must support continuous assignment.
ro_puf_mux_n_to_1.v:80: : Port dat_o of ro_puf_mux_2_to_1 is connected to inter_w[(((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)]
ro_puf_mux_n_to_1.v:80: error: Index of inter_w[(((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)] needs to be constant in this context.
ro_puf_mux_n_to_1.v:80: : Index expression is: (((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)
ro_puf_mux_n_to_1.v:80: : Context scope is: ro_puf_mux_n_to_1.genblk2.SELECT_STAGE[1].genblk6.INTERMEDIARY_STAGE[2]
ro_puf_mux_n_to_1.v:80: error: Output port expression must support continuous assignment.
ro_puf_mux_n_to_1.v:80: : Port dat_o of ro_puf_mux_2_to_1 is connected to inter_w[(((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)]
ro_puf_mux_n_to_1.v:80: error: Index of inter_w[(((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)] needs to be constant in this context.
ro_puf_mux_n_to_1.v:80: : Index expression is: (((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)
ro_puf_mux_n_to_1.v:80: : Context scope is: ro_puf_mux_n_to_1.genblk2.SELECT_STAGE[1].genblk6.INTERMEDIARY_STAGE[3]
ro_puf_mux_n_to_1.v:80: error: Output port expression must support continuous assignment.
ro_puf_mux_n_to_1.v:80: : Port dat_o of ro_puf_mux_2_to_1 is connected to inter_w[(((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)]
ro_puf_mux_n_to_1.v:80: error: Index of inter_w[(((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)] needs to be constant in this context.
ro_puf_mux_n_to_1.v:80: : Index expression is: (((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)
ro_puf_mux_n_to_1.v:80: : Context scope is: ro_puf_mux_n_to_1.genblk2.SELECT_STAGE[2].genblk6.INTERMEDIARY_STAGE[0]
ro_puf_mux_n_to_1.v:80: error: Output port expression must support continuous assignment.
ro_puf_mux_n_to_1.v:80: : Port dat_o of ro_puf_mux_2_to_1 is connected to inter_w[(((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)]
ro_puf_mux_n_to_1.v:80: error: Index of inter_w[(((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)] needs to be constant in this context.
ro_puf_mux_n_to_1.v:80: : Index expression is: (((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)
ro_puf_mux_n_to_1.v:80: : Context scope is: ro_puf_mux_n_to_1.genblk2.SELECT_STAGE[2].genblk6.INTERMEDIARY_STAGE[1]
ro_puf_mux_n_to_1.v:80: error: Output port expression must support continuous assignment.
ro_puf_mux_n_to_1.v:80: : Port dat_o of ro_puf_mux_2_to_1 is connected to inter_w[(((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)]
ro_puf_mux_n_to_1.v:80: error: Index of inter_w[(((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)] needs to be constant in this context.
ro_puf_mux_n_to_1.v:80: : Index expression is: (((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)
ro_puf_mux_n_to_1.v:80: : Context scope is: ro_puf_mux_n_to_1.genblk2.SELECT_STAGE[3].genblk6.INTERMEDIARY_STAGE[0]
ro_puf_mux_n_to_1.v:80: error: Output port expression must support continuous assignment.
ro_puf_mux_n_to_1.v:80: : Port dat_o of ro_puf_mux_2_to_1 is connected to inter_w[(((n_inputs)/(('sd2)(i)))*((('sd2)(i))-('sd1)))+(j)]
14 error(s) during elaboration.


-- CODE --------------------------------------

// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on

//`define ALTERA

module ro_puf_mux_2_to_1
(
input sel_i,
input [1:0] dat_i,
output dat_o
);

assign dat_o = sel_i && dat_i[1] || sel_i && dat_i[0];

endmodule

module ro_puf_mux_n_to_1
#(
parameter sel_w = 4,
parameter n_inputs = 2**sel_w
)
(
input [n_inputs-1:0] inputs_i,
input [sel_w-1:0] sel_i,
output output_o
);

`ifdef ALTERA

lpm_mux
#(
.lpm_size(n_inputs),
.lpm_type("LPM_MUX"),
.lpm_width(1),
.lpm_widths(sel_w)
)
LPM_MUX_component
(
.data(inputs_i),
.sel(sel_i),
.result(output_o)
);

`else // Generic

genvar i,j;
generate
if(sel_w == 1) begin
ro_puf_mux_2_to_1 mux_simple
(
.sel_i(sel_i),
.dat_i(inputs_i),
.dat_o(output_o)
);
end else begin

 wire [n_inputs-2:0] inter_w;

 for(i=0; i<sel_w; i=i+1) begin : SELECT_STAGE

    if(i==0) begin

       for(j=0; j<n_inputs/2; j=j+1) begin : FIRST_STAGE
      ro_puf_mux_2_to_1 mux_first_stage
         (
          .sel_i(sel_i[i]),
          .dat_i(inputs_i[2*j+1:2*j]),
          .dat_o(inter_w[j])
          );
       end

    end else begin

       for(j=0; j<(n_inputs/(2**(i+1))); j=j+1) begin : INTERMEDIARY_STAGE
      ro_puf_mux_2_to_1 mux_intermediary_stages
         (
          .sel_i(sel_i[i]),
          .dat_i(inter_w[ (n_inputs/(2**(i-1)))*((2**(i-1))-1) + 2*j + 1 : (n_inputs/(2**(i-1)))*((2**(i-1))-1) + 2*j ]),
          .dat_o(inter_w[ (n_inputs/(2**i))*((2**i)-1) + j ])
          );
       end

    end
 end

 assign output_o = inter_w[ (n_inputs/(2**(sel_w-1)))*((2**(sel_w-1))-1) ];

  end

endgenerate

`endif

endmodule

1 Attachments

Related

Bugs: #955

Discussion

  • Cary R.

    Cary R. - 2014-07-07

    I can confirm that this is still failing with the latest V0.9 from git. It does compile correctly using the latest development from git.

     
  • Cary R.

    Cary R. - 2014-07-07

    Just as a note, there is an error in the code for the 2 to 1 mux module. The term that selects the zero input should be ~sel not sel. With this change the V0.9 branch is still broken, but the development branch generates a mux that functions correctly.

     
  • Cary R.

    Cary R. - 2014-07-07

    The issue here is that V0.9 uses eval_const() when calculating the constant for a net bit select and eval_const() does not have code to support the power operator. This causes the compiler to mistakenly think the expression is not constant when it really is. One of the enhancements in development is that it uses the eval_tree() infrastructure to calculate the constant. You can work around this problem by replacing 2**i in the .dat_o assignment with 1<<i which switches to the supported shift operator. I will discuss this issue with Steve and get his opinion regarding the best way to fix this issue.

     
  • Cary R.

    Cary R. - 2014-07-08

    I have pushed a fix for this to git and it will be available in V0.9.8 whenever it is released.

     
  • Cary R.

    Cary R. - 2014-07-08
    • status: open --> closed-fixed
     
    • Matthieu

      Matthieu - 2014-07-08

      I use now the master branch version. Thank you for your help.

      On 07/08/2014 03:26 AM, Cary R. wrote:

      • status: open --> closed-fixed
      • Comment:

      I have pushed a fix for this to git and it will be available in V0.9.8
      whenever it is released.


      [bugs:#955] http://sourceforge.net/p/iverilog/bugs/955/ Problem of
      index in a generate block

      Status: closed-fixed
      Group: v0.9
      Created: Mon Jul 07, 2014 12:42 PM UTC by Matthieu
      Last Updated: Mon Jul 07, 2014 11:25 PM UTC
      Owner: nobody

      I would like to report a bug in Icarus Verilog version 0.9.7 (v0_9_7).
      The code is rejected at the compilation.
      This is the code of a generic multiplexer for N inputs, 1 output.
      The code compile perfectly with quartus and with Xilinx also.

      You can see below my shell output :

      iverilog -Wall ro_puf_mux_n_to_1.v -o tb_mux_n_to_1.v
      ro_puf_mux_n_to_1.v:80: error: Index of
      inter_w[(((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)]
      needs to be constant in this context.
      ro_puf_mux_n_to_1.v:80: : Index expression is:
      (((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)
      ro_puf_mux_n_to_1.v:80: : Context scope is:
      ro_puf_mux_n_to_1.genblk2.SELECT_STAGE[1].genblk6.INTERMEDIARY_STAGE[0]
      ro_puf_mux_n_to_1.v:80: error: Output port expression must support
      continuous assignment.
      ro_puf_mux_n_to_1.v:80: : Port dat_o of ro_puf_mux_2_to_1 is
      connected to
      inter_w[(((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)]
      ro_puf_mux_n_to_1.v:80: error: Index of
      inter_w[(((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)]
      needs to be constant in this context.
      ro_puf_mux_n_to_1.v:80: : Index expression is:
      (((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)
      ro_puf_mux_n_to_1.v:80: : Context scope is:
      ro_puf_mux_n_to_1.genblk2.SELECT_STAGE[1].genblk6.INTERMEDIARY_STAGE[1]
      ro_puf_mux_n_to_1.v:80: error: Output port expression must support
      continuous assignment.
      ro_puf_mux_n_to_1.v:80: : Port dat_o of ro_puf_mux_2_to_1 is
      connected to
      inter_w[(((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)]
      ro_puf_mux_n_to_1.v:80: error: Index of
      inter_w[(((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)]
      needs to be constant in this context.
      ro_puf_mux_n_to_1.v:80: : Index expression is:
      (((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)
      ro_puf_mux_n_to_1.v:80: : Context scope is:
      ro_puf_mux_n_to_1.genblk2.SELECT_STAGE[1].genblk6.INTERMEDIARY_STAGE[2]
      ro_puf_mux_n_to_1.v:80: error: Output port expression must support
      continuous assignment.
      ro_puf_mux_n_to_1.v:80: : Port dat_o of ro_puf_mux_2_to_1 is
      connected to
      inter_w[(((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)]
      ro_puf_mux_n_to_1.v:80: error: Index of
      inter_w[(((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)]
      needs to be constant in this context.
      ro_puf_mux_n_to_1.v:80: : Index expression is:
      (((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)
      ro_puf_mux_n_to_1.v:80: : Context scope is:
      ro_puf_mux_n_to_1.genblk2.SELECT_STAGE[1].genblk6.INTERMEDIARY_STAGE[3]
      ro_puf_mux_n_to_1.v:80: error: Output port expression must support
      continuous assignment.
      ro_puf_mux_n_to_1.v:80: : Port dat_o of ro_puf_mux_2_to_1 is
      connected to
      inter_w[(((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)]
      ro_puf_mux_n_to_1.v:80: error: Index of
      inter_w[(((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)]
      needs to be constant in this context.
      ro_puf_mux_n_to_1.v:80: : Index expression is:
      (((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)
      ro_puf_mux_n_to_1.v:80: : Context scope is:
      ro_puf_mux_n_to_1.genblk2.SELECT_STAGE[2].genblk6.INTERMEDIARY_STAGE[0]
      ro_puf_mux_n_to_1.v:80: error: Output port expression must support
      continuous assignment.
      ro_puf_mux_n_to_1.v:80: : Port dat_o of ro_puf_mux_2_to_1 is
      connected to
      inter_w[(((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)]
      ro_puf_mux_n_to_1.v:80: error: Index of
      inter_w[(((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)]
      needs to be constant in this context.
      ro_puf_mux_n_to_1.v:80: : Index expression is:
      (((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)
      ro_puf_mux_n_to_1.v:80: : Context scope is:
      ro_puf_mux_n_to_1.genblk2.SELECT_STAGE[2].genblk6.INTERMEDIARY_STAGE[1]
      ro_puf_mux_n_to_1.v:80: error: Output port expression must support
      continuous assignment.
      ro_puf_mux_n_to_1.v:80: : Port dat_o of ro_puf_mux_2_to_1 is
      connected to
      inter_w[(((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)]
      ro_puf_mux_n_to_1.v:80: error: Index of
      inter_w[(((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)]
      needs to be constant in this context.
      ro_puf_mux_n_to_1.v:80: : Index expression is:
      (((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)
      ro_puf_mux_n_to_1.v:80: : Context scope is:
      ro_puf_mux_n_to_1.genblk2.SELECT_STAGE[3].genblk6.INTERMEDIARY_STAGE[0]
      ro_puf_mux_n_to_1.v:80: error: Output port expression must support
      continuous assignment.
      ro_puf_mux_n_to_1.v:80: : Port dat_o of ro_puf_mux_2_to_1 is
      connected to
      inter_w[(((n_inputs)/(('sd2)*(i)))*((('sd2)*(i))-('sd1)))+(j)]
      14 error(s) during elaboration.
      

      -- CODE --------------------------------------
      

      // synopsys translate_off
      `timescale 1 ps / 1 ps
      // synopsys translate_on

      //`define ALTERA

      module ro_puf_mux_2_to_1
      (
      input sel_i,
      input [1:0] dat_i,
      output dat_o
      );

      assign dat_o = sel_i && dat_i[1] || sel_i && dat_i[0];

      endmodule

      module ro_puf_mux_n_to_1

      (

      parameter sel_w = 4,
      parameter n_inputs = 2**sel_w
      )
      (
      input [n_inputs-1:0] inputs_i,
      input [sel_w-1:0] sel_i,
      output output_o
      );

      `ifdef ALTERA

      lpm_mux

      (

      .lpm_size(n_inputs),
      .lpm_type("LPM_MUX"),
      .lpm_width(1),
      .lpm_widths(sel_w)
      )
      LPM_MUX_component
      (
      .data(inputs_i),
      .sel(sel_i),
      .result(output_o)
      );

      `else // Generic

      genvar i,j;
      generate
      if(sel_w == 1) begin
      ro_puf_mux_2_to_1 mux_simple
      (
      .sel_i(sel_i),
      .dat_i(inputs_i),
      .dat_o(output_o)
      );
      end else begin

      wire [n_inputs-2:0] inter_w;

      for(i=0; i<sel_w; i=i+1) begin : SELECT_STAGE

       if(i==0)  begin
      
          for(j=0;  j<n_inputs/2;  j=j+1)  begin  :  FIRST_STAGE
         ro_puf_mux_2_to_1  mux_first_stage
            (
             .sel_i(sel_i[i]),
             .dat_i(inputs_i[2*j+1:2*j]),
             .dat_o(inter_w[j])
             );
          end
      
       end  else  begin
      
          for(j=0;  j<(n_inputs/(2**(i+1)));  j=j+1)  begin  :  INTERMEDIARY_STAGE
         ro_puf_mux_2_to_1  mux_intermediary_stages
            (
             .sel_i(sel_i[i]),
             .dat_i(inter_w[  (n_inputs/(2**(i-1)))*((2**(i-1))-1)  +  2*j  +  1  :  (n_inputs/(2**(i-1)))*((2**(i-1))-1)  +  2*j  ]),
             .dat_o(inter_w[  (n_inputs/(2**i))*((2**i)-1)  +  j  ])
             );
          end
      
       end
      

      end

      assign output_o = inter_w[ (n_inputs/(2(sel_w-1)))*((2(sel_w-1))-1) ];

      end

      endgenerate

      `endif

      endmodule


      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/iverilog/bugs/955/
      https://sourceforge.net/p/iverilog/bugs/955

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/
      https://sourceforge.net/auth/subscriptions

       

      Related

      Bugs: #955


Log in to post a comment.