How to "or" a generic array of std_logic_vector ?

Guest
I have an array of std_logic_vector.

type array_of_std_logic_vector is array (0 to
number_of_rotors_array-1) of std_logic_vector(0 to
data_width_array-1);
signal data_out_array : array_of_std_logic_vector;

I want to "or" the "bits" of std_logic_vector for each element of the
vector like this.
data_out(i) shall be '1' if one of the elements of the vector has set
this bit to one.

data_out(0) <= '1' when unsigned(data_out_array(0)) /= 0;
data_out(1) <= '1' when unsigned(data_out_array(1)) /= 0;

The problem is that number_of_rotors and although data_width_array are
generic.

So, what is the solution ?

Thank´s for help
 
On Sat, 7 Jun 2008 12:17:08 -0700 (PDT), HansWernerMarschke@web.de
wrote:

type array_of_std_logic_vector is array (0 to
number_of_rotors_array-1) of std_logic_vector(0 to
data_width_array-1);
signal data_out_array : array_of_std_logic_vector;

I want to "or" the "bits" of std_logic_vector for each element of the
vector like this.
data_out(i) shall be '1' if one of the elements of the vector has set
this bit to one.

data_out(0) <= '1' when unsigned(data_out_array(0)) /= 0;
data_out(1) <= '1' when unsigned(data_out_array(1)) /= 0;

The problem is that number_of_rotors and although data_width_array are
generic.
That's not so much a problem as a solution waiting to happen...

for i in data_out_array'range loop
data_out(i) <= reduction_or(data_out_array(i));
end loop;

Oh, the function...

function reduction_or(v: in std_logic_vector) return std_logic is
variable r_or: std_logic;
begin
r_or := '0';
for i in v'range loop
r_or := r_or or v(i);
end loop;
return r;
end;

This is the sort of thing that VHDL does best.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
HansWernerMarschke@web.de wrote:

But there are still some latches.
Using a synchronous process would eliminate the latches.

-- Mike Treseler
 
On Sat, 7 Jun 2008 14:49:54 -0700 (PDT), HansWernerMarschke@web.de
wrote:

Thank´s for help

For a single std_logic_vector this is no problem.
I think you misunderstood the thrust of my post.
I threw in the reduction-OR function as an "easter egg",
but the real answer to your question was at the beginning:

for i in data_out_array'range loop
data_out(i) <= reduction_or(data_out_array(i));
end loop;

This is the COMPLETE answer to the question you posed:

- data_out_array is an array of SLVs
- data_out is an array, same range as data_out_array,
in which each bit is zero if the corresponding element
of data_out_array is exactly all zeros, but '1' if
there is any bit set in the corresponding element
of data_out_array.

What have I missed? If you don't like to implement my
reduction-OR, you can use the comparison style in your
original post:

for i in data_out_array'range loop
if unsigned(data_out_array(i)) = 0 then
data_out(i) <= '0';
else
data_out(i) <= '1';
end if;
end loop;


I´ve tried to solve the problem by using the following process:

process (data_out_array)
begin
for j in 0 to data_width_array - 1 loop
for i in 0 to number_of_rotors_array - 1 loop
if data_out_array(i)(j) = '1'
then
temp_data_out(j) <= '1';
else
null;
end if;
end loop;
data_out(j) <= temp_data_out(j);
end loop;
end process;

But there are still some latches.
Of course. Signal temp_data_out(j) is not in the
sensitivity list, and even if it were, it is not
completely assigned. Try this instead:

process (data_out_array)
--- don't put "temp_data_out" in sensitivity list,
--- because it's a variable
variable temp_data_out: std_logic; --- no need for vector
begin
--- for j in 0 to data_width_array - 1 loop
for j in data_out_array'range loop --- much nicer!!!
temp_data_out := '0'; --- this is the part you forgot
for i in 0 to number_of_rotors_array - 1 loop
if data_out_array(i)(j) = '1'
then
temp_data_out := '1';
else
null;
end if;
end loop;
data_out(j) <= temp_data_out;
end loop;
end process;


What about using a resolution function like this for example ?

-- function wired_or (inputs: bit_vector) return bit is
-- constant float_value: bit := '0';
-- begin
-- if inputs'length = 0 then
-- return float_value;
-- else
-- for i in inputs'range loop
-- if inputs(i) = '1' then
-- return '1';
-- end if;
-- end loop;
-- return '0';
-- end if;
-- end function wired_or;

-- subtype bus_bit is wired_or bit;
-- signal a : bus_bit;
Because synthesis would almost certainly not understand it;
synthesis tools' understanding of resolution functions is
generally restricted to the standard one for std_logic.
Your "unsigned(vec) /= 0" comparison is OK, but I dislike
using arithmetic operations when in truth I'm bit-bashing;
whatever was wrong with the reduction-OR function that
I offered?
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
Thank´s for help

For a single std_logic_vector this is no problem.

error <= '1' when unsigned(error_array) /= 0 else '0';
restart <= '1' when unsigned(restart_array) /= 0 else '0';

I´ve tried to solve the problem by using the following process:

process (data_out_array)
begin
for j in 0 to data_width_array - 1 loop
for i in 0 to number_of_rotors_array - 1 loop
if data_out_array(i)(j) = '1'
then
temp_data_out(j) <= '1';
else
null;
end if;
end loop;
data_out(j) <= temp_data_out(j);
end loop;
end process;

But there are still some latches.
Now I have a component named LDP in the design.
The synthesis says that some signals are missed in the sensitivity
list.
What about using a resolution function like this for example ?

-- function wired_or (inputs: bit_vector) return bit is
-- constant float_value: bit := '0';
-- begin
-- if inputs'length = 0 then
-- return float_value;
-- else
-- for i in inputs'range loop
-- if inputs(i) = '1' then
-- return '1';
-- end if;
-- end loop;
-- return '0';
-- end if;
-- end function wired_or;

-- subtype bus_bit is wired_or bit;
-- signal a : bus_bit;
 
On Sat, 7 Jun 2008 14:49:54 -0700 (PDT), HansWernerMarschke@web.de
wrote:

I´ve tried to solve the problem by using the following process:

process (data_out_array)
begin
for j in 0 to data_width_array - 1 loop
for i in 0 to number_of_rotors_array - 1 loop
if data_out_array(i)(j) = '1'
then
temp_data_out(j) <= '1';
else
null;
end if;
end loop;
data_out(j) <= temp_data_out(j);
end loop;
end process;

But there are still some latches.
The latches arise because there are paths through this process which do
NOT assign to temp_data_out; therefore if you are not assigning '1' to
it you must hold its old value ... in a latch. Or as Mike T says, in a
synch process, although I'm guessing that isn't what you want.

for j in 0 to data_width_array - 1 loop
temp_data_out(j) <= '0';
for i in 0 to number_of_rotors_array - 1 loop
would be one possible solution

- Brian
 
Thank´s for your help

I know now that using something like this:

error <= '1' when unsigned(error_array) /= 0 else '0';
restart <= '1' when unsigned(restart_array) /= 0 else '0';

... is not a good idea.
Instead you have to use a process like this:

process (error_array)
variable temp_error : std_logic;
begin
temp_error := '0';
for i in error_array'range loop
temp_error := temp_error or error_array(i);
end loop;
error <= temp_error;
end process;

... then a OR is generated.
For the OR of the bits of the array of std_logic_vector I use this;
although I don´t understand that not an OR gate is generated. Instead
of this I get a sequence of OR´s and AND´s where one input is negated.
It´s a pitty that I can´t show the scheme that is generated.

process (data_out_array)
variable temp_data_out : std_logic_vector(0 to data_width_array -
1);
begin
for i in 0 to data_width_array - 1 loop
temp_data_out(i) := '0';
for j in 0 to number_of_rotors_array - 1 loop
if data_out_array(j)(i) = '1'
then
temp_data_out(i) := '1';
else
null;
end if;
end loop;
data_out(i) <= temp_data_out(i);
end loop;
end process;
 
On Jun 8, 6:52 pm, "KJ" <kkjenni...@sbcglobal.net> wrote:
HansWernerMarsc...@web.de> wrote in message

news:1fdcc58c-906c-4ec7-ad33-c9de3f635e34@m36g2000hse.googlegroups.com...

I want to "or" the "bits" of std_logic_vector for each element of the
vector like this.
data_out(i) shall be '1' if one of the elements of the vector has set
this bit to one.

Somewhat similar to the process approach already covered in this thread is
to use a generate statement...basically the same amount of typing and debug

Gen_This : for i in data_out'range generate
data_out(i) <= '1' when unsigned(data_out_array(i)) /= 0;
end generate Gen_This;

KJ
The problem (latches) with this solution as well as that in the OP is
that there is no assignment to data_out when the row is 0.

Try:

data_out(i) <= '1' when unsigned(data_out_array(i)) /= 0 else '0';

Other than my personal preference to avoid combinatorial processes
(either explicit or implied by concurrent assignments), I see nothing
wrong with using the generate statement, so long as the concurrent
statements within it do not create latches. In fact, I prefer a
concurrent assignment statement over a combinatorial process that has
only one output.

Andy
 
On Jun 9, 2:07 pm, Andy <jonesa...@comcast.net> wrote:
On Jun 8, 6:52 pm, "KJ" <kkjenni...@sbcglobal.net> wrote:





HansWernerMarsc...@web.de> wrote in message

news:1fdcc58c-906c-4ec7-ad33-c9de3f635e34@m36g2000hse.googlegroups.com...

I want to "or" the "bits" of std_logic_vector for each element of the
vector like this.
data_out(i) shall be '1' if one of the elements of the vector has set
this bit to one.

Somewhat similar to the process approach already covered in this thread is
to use a generate statement...basically the same amount of typing and debug

Gen_This : for i in data_out'range generate
    data_out(i) <= '1' when unsigned(data_out_array(i)) /= 0;
end generate Gen_This;

KJ

The problem (latches) with this solution as well as that in the OP is
that there is no assignment to data_out when the row is 0.

Try:

  data_out(i) <= '1' when unsigned(data_out_array(i)) /= 0 else '0';
That's what I had intended to type...good catch.

KJ
 

Welcome to EDABoard.com

Sponsor

Back
Top