Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > Recursive function to generate mux output

Reply
Thread Tools

Recursive function to generate mux output

 
 
Edward Watts
Guest
Posts: n/a
 
      01-24-2006
Hi all,

I posted a short while ago about using generate statements to select
out sections of a parallel signal or to combine sections into a
parallel signal (serial-ish to parallel and parallel to serial-ish
converters)
http://groups.google.com/group/comp....501029fa8041c6

The input serial to parallel works fine, and is synthesised and
general.
The output parallel to serial syntactically is fine, but won't
synthesis:
I'm using Xilinx 7.1i Foundation, and the code is the following

output_g : for i in 0 to NumberOfOutputOperands-1
generate
outputSlice_g : for j in 0 to NumberOfOutputBitGroups-1
generate
outputSliceLast_g : if (j = NumberOfOutputBitGroups-1) and (i =
NumberOutputOperands-1)
generate
process(clk)
if rising_edge(clk) then
if RSTIn = '1' then
...reset code.
else
result_internal <= result(i)( (j+1)*OutputWidth - 1 downto
j*OutputWidth );
-- other IO stuff.
end if;
end if;
end process;
end generate;
-- similar generate for all other output slices.
end generate;
end generate;

And the problem with this code is that a synthesis error occurs:
multi-source in Unit ... on signal result_internal<...>

VHDL requires that the process statement be inside the generate
statement, and not the other way around. Is there an option to use
perhaps a block statement to replicate the behaviour.

I've now tried to create a mux tree structure with a function, which
crashed the synthesis tool.
Here's the function, based off a reduction operator:

There were two errors raised, one at line 0 of this file of "Overflow
in constant operation", and the other is pointed out in the source
code.

function mux_build ( arg: std_logic_vector, a : std_logic_vector )
return std_logic_vector is
variable Result, Upper, Lower : std_logic_vector( SizeOfOutputBus-1
downto 0 );
variable Half : integer;
variable internal : std_logic_vector( arg'length-1 downto 0 );
begin
internal := arg;
if ( internal'length = SizeOfOutputBus ) then
Result := internal;
else
Half := 2**(internal'length-1);
Upper := mux_build( internal( internal'left downto Half ), a );
--gives "Use of null array slice on signal <internal> is not supported"
Lower := mux_build( internal( Half-1 downto internal'right), a );
if ( a( internal'length-SizeOfOutputBus-1) = '1' ) then
Result := Upper;
else
Result := Lower;
end if;
end if;
return Result;
end function;

Can someone help me with the nitty gritty of the language? I haven't
had too much experience with functions and synthesis.

Thanks,
ed.

 
Reply With Quote
 
 
 
 
Kai Harrekilde-Petersen
Guest
Posts: n/a
 
      01-24-2006
"Edward Watts" <(E-Mail Removed)> writes:

> I've now tried to create a mux tree structure with a function, which
> crashed the synthesis tool.
> Here's the function, based off a reduction operator:
>
> There were two errors raised, one at line 0 of this file of "Overflow
> in constant operation", and the other is pointed out in the source
> code.
>
> function mux_build ( arg: std_logic_vector, a : std_logic_vector )
> return std_logic_vector is
> variable Result, Upper, Lower : std_logic_vector( SizeOfOutputBus-1
> downto 0 );
> variable Half : integer;
> variable internal : std_logic_vector( arg'length-1 downto 0 );
> begin
> internal := arg;
> if ( internal'length = SizeOfOutputBus ) then
> Result := internal;
> else
> Half := 2**(internal'length-1);
> Upper := mux_build( internal( internal'left downto Half ), a );
> --gives "Use of null array slice on signal <internal> is not supported"
> Lower := mux_build( internal( Half-1 downto internal'right), a );
> if ( a( internal'length-SizeOfOutputBus-1) = '1' ) then
> Result := Upper;
> else
> Result := Lower;
> end if;
> end if;
> return Result;
> end function;
>
> Can someone help me with the nitty gritty of the language? I haven't
> had too much experience with functions and synthesis.


You have left out what widths you are testing with, but my best guess,
is that the function barfs when you get down to 1 bit wide vectors (0
downto 0).

Say your input isn't a multiple of SizeOfOutputBus, then the
internal'length = SizeOfOutputBus test will never succeed, and you end
up trying to split a 1-bit bus in one of the halfs.

Regards,


Kai
--
Kai Harrekilde-Petersen <khp(at)harrekilde(dot)dk>
 
Reply With Quote
 
 
 
 
Mike Treseler
Guest
Posts: n/a
 
      01-24-2006
Edward Watts wrote:

> And the problem with this code is that a synthesis error occurs:
> multi-source in Unit ... on signal result_internal<...>


Generate loops tend to have problems at the edges.
Sometimes you need a process or two outside the loop.

I find vhdl simulation a very quick way to
debug problems like this.

I find that a single process design
style is a good way to *eliminate*
problems like this.


-- Mike Treseler
 
Reply With Quote
 
Edward Watts
Guest
Posts: n/a
 
      01-26-2006
Replying to both posts.

Mike Treseler helped out with:

> I find that a single process design
> style is a good way to *eliminate*
> problems like this.


The issue is we don't want to retype out all the different multiples of
OutputBusWidth each time we change the size of the internal
representation (possibly up to 1024 bits). I'm not sure of a VHDL
pattern that deals with this problem, but i'm working on another
generate option. If I get it working, I'll post both the input and
output solutions for critique or dust-collecting

Kai Harrekilde-Petersen chipped in with:
> Say your input isn't a multiple of SizeOfOutputBus, then the
> internal'length = SizeOfOutputBus test will never succeed, and you end
> up trying to split a 1-bit bus in one of the halfs.

So a guard condition on the 1-bit wide bus should help...
However the function assign will barf on the usage, since it should
always return a value of

 
Reply With Quote
 
Edward Watts
Guest
Posts: n/a
 
      01-26-2006
Replying to both posts.

Mike Treseler helped out with:

> I find that a single process design
> style is a good way to *eliminate*
> problems like this.


The issue is we don't want to retype out all the different multiples of
OutputBusWidth each time we change the size of the internal
representation (possibly up to 1024 bits). I'm not sure of a VHDL
pattern that deals with this problem, but i'm working on another
generate option. If I get it working, I'll post both the input and
output solutions for critique or dust-collecting

Kai Harrekilde-Petersen chipped in with:
> Say your input isn't a multiple of SizeOfOutputBus, then the
> internal'length = SizeOfOutputBus test will never succeed, and you end
> up trying to split a 1-bit bus in one of the halfs.


So a guard condition on the 1-bit wide bus should help the synthesis
tool.
The input to the function is always some multiple of SizeOfOutputBus,
but not necessarily 2^n * SizeOfOutputBus.
However the function assign will barf on the usage, if it returns a
1-bit wide answer, since it should always return a value of
SizeOfOutputBus wide. Is there a method of constraining the input sizes
using some sort of assertion or precondition (I know it's not Eiffel)
whereby I can indicate to the compiler what it can assume?

cheers,
ed.

PS sorry if this is a double post. I may have tapped the post button
accidentally

 
Reply With Quote
 
Mike Treseler
Guest
Posts: n/a
 
      01-27-2006
Edward Watts wrote:

> Mike Treseler helped out with:
>
>>I find that a single process design
>>style is a good way to *eliminate*
>>problems like this.

>
> The issue is we don't want to retype out all the different multiples of
> OutputBusWidth each time we change the size of the internal
> representation (possibly up to 1024 bits).


Understood. My point was that I would
apply the generic dimensions to a some complex data type
to cover the same design in a single process.
I would find this easier to sim and debug.

-- Mike Treseler

 
Reply With Quote
 
Edward Watts
Guest
Posts: n/a
 
      01-30-2006
Here's the solution to all my problems.
I was attempting to convert a std_logic_vector signal to an integer to
use as an index into the output signal. Xilinx told me that I couldn't
use to_integer (error was "to_integer cannot have such operands in this
context."). However using conv_integer worked fine.

So here it is:
OutputBitGroupCounter is std_logic_vector(OutputBitGroupCounterBits-1
downto 0)
resultIn is std_logic_vector(N_Bits-1 downto 0);
result_internal is std_logic_vector(SizeOfOutputBus-1 downto 0);
out_internal is array(OutputBitGroupCounter_MAX downto 0) of
std_logic_vector(SizeOfOutputBus-1 downto 0);
outputCounting is a flag that is set when outputs are being read

-- use a generate signal to clock the N bit wide internal signal into a
2D array
outputSelect_g : for i in OutputBitGroupCounter_MAX downto 0 generate
process(CLK)
begin
--clock inputs into each part of the array slice.
if rising_edge(CLK) then
if RST = '1' then
out_internal(i) <= (others => '0');
elsif expFinished = '1' then
out_internal(i) <= resultIn( (i+1)*SizeOfOutputBus-1 downto
i*SizeOfOutputBus);
end if;
end if;
end process;
end generate;

-- followed with the almost trivial:
process(CLK)
begin
if rising_edge(CLK) then
if RST = '1' then
result_internal <= (others => '0');
elsif outputCounting = '1' then
result_internal <= out_internal( conv_integer(
outputBitGroupCounter ) );
end if;
end if;
end process;

ed.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
MUX with generate statement RADNOR VHDL 3 07-20-2011 09:25 PM
Two recursive calls inside of a recursive function n00m C++ 12 03-13-2008 03:18 PM
[how to make?] mux 1x1 128 bits + for generate conradojr VHDL 5 04-26-2007 05:58 PM
Want recursive SQL query function to generate breadcrumb navigation ASP General 2 03-30-2005 02:25 PM
operation on mux output valentin tihomirov VHDL 5 09-23-2004 08:51 PM



Advertisments