Recursive instantiation?

P

pallav

Guest
I'm trying to create a library of parametrizable components. I'm
looking at a priority encoder. I found some code on the web that shows
how to do this in a recursive way (I didn't know Verilog-2001 allows
recursive instantiation). The code is shown below. It seems to look OK
by recursively breaking down the decoder into smaller powers of 2
decoder. Alternatively, see http://damdevil.org/paste/?ODBlNm

I'm trying to compile this using Synopsys VCS to see if it supports
this feature but I'm getting some errors I'm not sure how to fix:

vlogan +warn=all +v2k -l comp.logan x.v
vcs priencr -l comp.log


Chronologic VCS (TM)
Version C-2009.06 -- Thu Aug 13 03:44:19 2009
Copyright (c) 1991-2008 by Synopsys Inc.
ALL RIGHTS RESERVED

This program is proprietary and confidential information of Synopsys
Inc.
and may be used and disclosed only as authorized in a license
agreement
controlling such use and disclosure.

Parsing design file 'x.v'
CPU time: .032 seconds to compile
Doing common elaboration
..
Error-[V2KTDMI] Too deep module instantiation
x.v, 1
"priencr"
Module 'priencr' may be involved in infinite recursive
instantiation.
Instance stack trace:
priencr x.v, 24
priencr x.v, 24
priencr x.v, 24
priencr x.v, 24
priencr x.v, 24
priencr x.v, 24
priencr x.v, 24
priencr x.v, 24
priencr x.v, 24
priencr x.v, 24
priencr x.v, 24
priencr x.v, 24
priencr x.v, 24
priencr x.v, 24
priencr x.v, 24
...

Any ideas on what I'm doing wrong? Thanks.
Kind regards.



module priencr #(parameter width = 64)
(
input [width-1:0] decode,
output [log2(width)-1:0] encode,
output valid
);

function [31:0] log2;
input reg [31:0] value;
begin
value = value-1;
for (log2=0; value>0; log2=log2+1)
value = value>>1;
end
endfunction

generate
if (width == 2)
begin
assign valid = |decode;
assign encode = decode[1];
end
else if (width & (width-1))
priencr #(1<<log2(width)) priencr ({1<<log2(width) {1'b0}} |
decode,
encode,valid);
else
begin
wire [log2(width)-2:0] encode_low;
wire [log2(width)-2:0] encode_high;
wire valid_low, valid_high;
priencr #(width>>1) low(decode[(width>>1)-1:0],encode_low,valid_low);
priencr #(width>>1) high(decode
[width-1:width>>1],encode_high,valid_high);
assign valid = valid_low | valid_high;
assign encode = valid_high ? {1'b1,encode_high} : {1'b0,encode_low};
end
endgenerate
endmodule
 
On Aug 13, 3:48 am, pallav <pallavgu...@gmail.com> wrote:
I'm trying to create a library of parametrizable components. I'm
looking at a priority encoder. I found some code on the web that shows
how to do this in a recursive way (I didn't know Verilog-2001 allows
recursive instantiation). The code is shown below. It seems to look OK
by recursively breaking down the decoder into smaller powers of 2
decoder. Alternatively, seehttp://damdevil.org/paste/?ODBlNm

I'm trying to compile this using Synopsys VCS to see if it supports
this feature but I'm getting some errors I'm not sure how to fix:

vlogan +warn=all +v2k -l comp.logan x.v
vcs priencr -l comp.log

  Chronologic VCS (TM)
            Version C-2009.06 -- Thu Aug 13 03:44:19 2009
               Copyright (c) 1991-2008 by Synopsys Inc.
                         ALL RIGHTS RESERVED

This program is proprietary and confidential information of Synopsys
Inc.
and may be used and disclosed only as authorized in a license
agreement
controlling such use and disclosure.

Parsing design file 'x.v'
CPU time: .032 seconds to compile
Doing common elaboration
.
Error-[V2KTDMI] Too deep module instantiation
x.v, 1
"priencr"
  Module 'priencr' may be involved in infinite recursive
instantiation.
  Instance stack trace:
      priencr  x.v, 24
      priencr  x.v, 24
      priencr  x.v, 24
      priencr  x.v, 24
      priencr  x.v, 24
      priencr  x.v, 24
      priencr  x.v, 24
      priencr  x.v, 24
      priencr  x.v, 24
      priencr  x.v, 24
      priencr  x.v, 24
      priencr  x.v, 24
      priencr  x.v, 24
      priencr  x.v, 24
      priencr  x.v, 24
      ...

Any ideas on what I'm doing wrong? Thanks.
Kind regards.

module priencr #(parameter width = 64)
  (
   input [width-1:0] decode,
   output [log2(width)-1:0] encode,
   output valid
   );

  function [31:0] log2;
    input reg [31:0] value;
    begin
      value = value-1;
      for (log2=0; value>0; log2=log2+1)
        value = value>>1;
    end
  endfunction

  generate
    if (width == 2)
      begin
        assign valid = |decode;
        assign encode = decode[1];
      end
    else if (width & (width-1))
      priencr #(1<<log2(width)) priencr ({1<<log2(width) {1'b0}} |
decode,
                                         encode,valid);
    else
      begin
        wire [log2(width)-2:0] encode_low;
        wire [log2(width)-2:0] encode_high;
        wire valid_low, valid_high;
        priencr #(width>>1) low(decode[(width>>1)-1:0],encode_low,valid_low);
        priencr #(width>>1) high(decode
[width-1:width>>1],encode_high,valid_high);
        assign valid = valid_low | valid_high;
        assign encode = valid_high ? {1'b1,encode_high} : {1'b0,encode_low};
      end
  endgenerate
endmodule
XST was perfectly happy with the recursive instantiation, but
it puked on your log2 function:

8: function [31:0] log2;
9: input reg [31:0] value;
10: begin
11: value = value-1;
12: for (log2=0; value>0; log2=log2+1)
13: value = value>>1;
14: end
15: endfunction

line 11: Invalid use of input signal <log2/1/value> as target.
line 12: For loop stop condition should depend on loop variable or be
static.

Is it possible that VCS is also having trouble with log2, but
not reporting it? This could cause the recursion to fail due
to incorrect values returned by log2 being used as the new width.

Regards,
Gabor
 
On Aug 13, 8:45 am, gabor <ga...@alacron.com> wrote:
On Aug 13, 3:48 am, pallav <pallavgu...@gmail.com> wrote:
snip

XST was perfectly happy with the recursive instantiation, but
it puked on your log2 function:

 8:  function [31:0] log2;
 9:    input reg [31:0] value;
10:    begin
11:      value = value-1;
12:      for (log2=0; value>0; log2=log2+1)
13:        value = value>>1;
14:    end
15:  endfunction

line 11: Invalid use of input signal <log2/1/value> as target.
line 12: For loop stop condition should depend on loop variable or be
static.

Is it possible that VCS is also having trouble with log2, but
not reporting it?  This could cause the recursion to fail due
to incorrect values returned by log2 being used as the new width.

Regards,
Gabor
Hi Gabor,

Thanks for responding. I also though log2 could have been problematic.
So I tried the following. Rewrote it so the for loop is dependent on
one variable:

log2.v:
function [31:0] log2;
input reg [31:0] value;
begin
log2 = 0;
for (value = value - 1; value > 0; value = value >> 1)
log2 = log2 + 1;
end
endfunction


Then I tried a small test to see if it is working OK:

y.v:
module test ();

`include "log2.v"

initial
begin
$display("10 = %d", log2(10));
$display("32 = %d", log2(32));
$display("64 = %d", log2(64));
$display("4 = %d", log2(4));
end
endmodule

Upon compiling this in VCS and running, I get the right results:
Compiler version C-2009.06; Runtime version C-2009.06; Aug 13 15:22
2009
10 = 4
32 = 5
64 = 6
4 = 2
V C S S i m u l a t i o n R e p o r t

So then I updated the original priority encoder code as follows:

x.v:
module priencr #(parameter width = 4)
(
input [width-1:0] decode,
output [log2(width)-1:0] encode,
output valid
);

`include "log2.v"

generate
if (width == 2)
begin
assign valid = |decode;
assign encode = decode[1];
end
else if (width & (width-1))
priencr #(1<<log2(width)) priencr ({1<<log2(width) {1'b0}} |
decode,
encode,valid);
else
begin: p
wire [log2(width)-2:0] encode_low;
wire [log2(width)-2:0] encode_high;
wire valid_low, valid_high;
priencr #(width>>1) low(decode[(width>>1)-1:0],encode_low,valid_low);
priencr #(width>>1) high(decode
[width-1:width>>1],encode_high,valid_high);
assign valid = valid_low | valid_high;
assign encode = valid_high ? {1'b1,encode_high} : {1'b0,encode_low};
end
endgenerate
endmodule

Note that it has a default width of 4 so there should be only 1 level
of recursion during compilation. I tried compiling it on VCS but I
still get the same error:

Parsing design file 'x.v'
Parsing included file 'log2.v'.
Back to file 'x.v'.
CPU time: .031 seconds to compile
Doing common elaboration
..
Error-[V2KTDMI] Too deep module instantiation
x.v, 20
"p"
Module 'p' may be involved in infinite recursive instantiation.
Instance
stack trace:
p x.v, 20
priencr x.v, 24
p x.v, 20
priencr x.v, 24
p x.v, 20
priencr x.v, 24
p x.v, 20
priencr x.v, 24
p x.v, 20
priencr x.v, 24
p x.v, 20
priencr x.v, 24
p x.v, 20
priencr x.v, 24
p x.v, 20
...

I will check Synopsys Solvnet for any articles on recursion or their
manual to see if they have anything about this problem.

Thanks for your time.

Kind regards.
 
On Aug 13, 3:32 pm, pallav <pallavgu...@gmail.com> wrote:
On Aug 13, 8:45 am, gabor <ga...@alacron.com> wrote:



On Aug 13, 3:48 am, pallav <pallavgu...@gmail.com> wrote:
snip

XST was perfectly happy with the recursive instantiation, but
it puked on your log2 function:

 8:  function [31:0] log2;
 9:    input reg [31:0] value;
10:    begin
11:      value = value-1;
12:      for (log2=0; value>0; log2=log2+1)
13:        value = value>>1;
14:    end
15:  endfunction

line 11: Invalid use of input signal <log2/1/value> as target.
line 12: For loop stop condition should depend on loop variable or be
static.

Is it possible that VCS is also having trouble with log2, but
not reporting it?  This could cause the recursion to fail due
to incorrect values returned by log2 being used as the new width.

Regards,
Gabor

Hi Gabor,

Thanks for responding. I also though log2 could have been problematic.
So I tried the following. Rewrote it so the for loop is dependent on
one variable:

log2.v:
function [31:0] log2;
   input reg [31:0] value;
   begin
      log2 = 0;
      for (value = value - 1; value > 0; value = value >> 1)
        log2 = log2 + 1;
   end
endfunction

Then I tried a small test to see if it is working OK:

y.v:
module test ();

`include "log2.v"

initial
 begin
  $display("10 = %d", log2(10));
  $display("32 = %d", log2(32));
  $display("64 = %d", log2(64));
  $display("4 = %d", log2(4));
 end
endmodule

Upon compiling this in VCS and running, I get the right results:
Compiler version C-2009.06; Runtime version C-2009.06;  Aug 13 15:22
2009
10 =           4
32 =           5
64 =           6
4 =           2
           V C S   S i m u l a t i o n   R e p o r t

So then I updated the original priority encoder code as follows:

x.v:
module priencr #(parameter width = 4)
  (
   input [width-1:0] decode,
   output [log2(width)-1:0] encode,
   output valid
   );

`include "log2.v"

  generate
    if (width == 2)
      begin
        assign valid = |decode;
        assign encode = decode[1];
      end
    else if (width & (width-1))
      priencr #(1<<log2(width)) priencr ({1<<log2(width) {1'b0}} |
decode,
                                         encode,valid);
    else
      begin: p
        wire [log2(width)-2:0] encode_low;
        wire [log2(width)-2:0] encode_high;
        wire valid_low, valid_high;
        priencr #(width>>1) low(decode[(width>>1)-1:0],encode_low,valid_low);
        priencr #(width>>1) high(decode
[width-1:width>>1],encode_high,valid_high);
        assign valid = valid_low | valid_high;
        assign encode = valid_high ? {1'b1,encode_high} : {1'b0,encode_low};
      end
  endgenerate
endmodule

Note that it has a default width of 4 so there should be only 1 level
of recursion during compilation. I tried compiling it on VCS but I
still get the same error:

Parsing design file 'x.v'
Parsing included file 'log2.v'.
Back to file 'x.v'.
CPU time: .031 seconds to compile
Doing common elaboration
.
Error-[V2KTDMI] Too deep module instantiation
x.v, 20
"p"
  Module 'p' may be involved in infinite recursive instantiation.
Instance
  stack trace:
      p  x.v, 20
      priencr  x.v, 24
      p  x.v, 20
      priencr  x.v, 24
      p  x.v, 20
      priencr  x.v, 24
      p  x.v, 20
      priencr  x.v, 24
      p  x.v, 20
      priencr  x.v, 24
      p  x.v, 20
      priencr  x.v, 24
      p  x.v, 20
      priencr  x.v, 24
      p  x.v, 20
      ...

I will check Synopsys Solvnet for any articles on recursion or their
manual to see if they have anything about this problem.

Thanks for your time.

Kind regards.
XST doesn't like your new version either. It will take:

function [31:0] log2;
input [31:0] value;
integer j;
reg [31:0] i;
begin
j = value - 1;
log2 = 0;
for (i = 0; i < 31; i = i + 1)
if (j) log2 = i+1;
end
endfunction

Apparently XST has limited for loop capabilities...

In any case with this log2 function implemented, XST could
compile the priencr just fine.

Regards,
Gabor
 
On Aug 13, 5:42 pm, gabor <ga...@alacron.com> wrote:
<snip>
XST doesn't like your new version either.  It will take:

function [31:0] log2;
   input [31:0] value;
   integer j;
   reg [31:0] i;
   begin
      j = value - 1;
      log2 = 0;
      for (i = 0; i < 31; i = i + 1)
        if (j) log2 = i+1;
   end
endfunction

Apparently XST has limited for loop capabilities...

In any case with this log2 function implemented, XST could
compile the priencr just fine.

Regards,
Gabor

I tried your function. VCS doesn't like it and gives the same errors.
Look like it has even more limited capabilities than XST for this.
I'll just go back and code up the different size priority encoders. No
big deal.

Thanks.

Kind regards.
 
pallav <pallavgupta@gmail.com> wrote:

I tried your function. VCS doesn't like it and gives the same errors.
Look like it has even more limited capabilities than XST for this.
I'll just go back and code up the different size priority encoders. No
big deal.
How about a look up table for the log2()?

It isn't that big, and doesn't generate anything.

-- glen
 

Welcome to EDABoard.com

Sponsor

Back
Top