Velocity Reviews > VHDL > algorithm problem

# algorithm problem

Guest
Posts: n/a

 11-03-2003
Hello,

I'm trying to code a module to do the following algorithm:

If Input is even, divide by 2 and do two's complement(invert bits and add 1)
If Input is odd, increment by 1 and then divide by 2.

No matter what types I use, I can't seem to use any operators( /, srl, not).
I usually get 'can not have such operands in this context' errors. Input is
defined as std_logic_vector(7 downto 0) and SignNum is unsigned(7 downto 0).
Both are signals. I can get around not using the shift/divide operators,
but not the negation. What data type should I use to be able to use 'not'?

SignedCalc : process(Input)
variable EvenShift : unsigned(7 downto 0);
variable OddShift : unsigned(7 downto 0);
variable OddInc : unsigned(7 downto 0);
variable uInput : unsigned(7 downto 0);
begin
uInput := unsigned(Input);
if(Input(0) = '0') then --Even number
EvenShift := "0" & uInput(7 downto 1);
SignedNum <= (not EvenShift) + 1;
else --Odd Number
OddInc := uInput + 1;
OddShift := "0" & OddInc(7 downto 1);
SignedNum <= OddShift;
end if;
end process;

Ralf Hildebrandt
Guest
Posts: n/a

 11-03-2003

> I'm trying to code a module to do the following algorithm:
>
> If Input is even, divide by 2 and do two's complement(invert bits and add 1)
> If Input is odd, increment by 1 and then divide by 2.

process(input)
variable dummy : std_ulogic_vector(7 downto 0);
begin
if (input(0)='0') then -- even

dummy:='0' & input(7 downto 1); -- divide by 2
output<=std_ulogic_vector( to_unsigned(0, - signed(dummy) );
-- negative (2th compl. and +1)

else -- odd

dummy:=std_ulogic_vector( unsigned(input) + 1 );
output<='0' & dummy(7 downto 1);

end if;
end process;

Ralf

Egbert Molenkamp
Guest
Posts: n/a

 11-03-2003

"Adam" <(E-Mail Removed)> wrote in message
news:lbkpb.3423\$(E-Mail Removed)...
> Hello,
>
> I'm trying to code a module to do the following algorithm:
>
> If Input is even, divide by 2 and do two's complement(invert bits and add

1)
> If Input is odd, increment by 1 and then divide by 2.
>
> No matter what types I use, I can't seem to use any operators( /, srl,

not).
> I usually get 'can not have such operands in this context' errors. Input

is
> defined as std_logic_vector(7 downto 0) and SignNum is unsigned(7 downto

0).
> Both are signals. I can get around not using the shift/divide operators,
> but not the negation. What data type should I use to be able to use

'not'?

'/' is not defined for std_logic_vector in the LRM-VHDL
'srl' is defined from 1993 in the LRM-VHDL, maybe you have to set a switch
for it (1987 may be the default)
'not' this should work.

'/' can be used with type UNSIGNED (package numeric_std).
See solution beneath.
You suggested to use use type UNSIGNED. In that case I can NOT write
- (uInput/2)
to replace :
(NOT(uInput/2)) + 1 )
since the unary minus is only delcared for type SIGNED (also in package
numeric_std).

Egbert Molenkamp

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity demo is
port (Input : std_logic_vector(7 downto 0);
Output : out std_logic_vector(7 downto 0));
end demo ;

architecture behavior of demo is
begin
process(input)
variable uInput : unsigned(7 downto 0);
begin
uInput := unsigned(Input);
if uInput(0)='0' then
Output<= std_logic_vector ( (NOT(uInput/2)) + 1);
else
Output<= std_logic_vector ( uInput/2 );
end if;
end process;
end behavior;

Guest
Posts: n/a

 11-03-2003
Thank you, that worked. I guess I can't do any operations on
std_vector_logic and must convert to unsigned/signed first..

Egbert Molenkamp
Guest
Posts: n/a

 11-03-2003
"Adam" <(E-Mail Removed)> schreef in bericht
news:Nzwpb.8167\$(E-Mail Removed)...
> Thank you, that worked. I guess I can't do any operations on
> std_vector_logic and must convert to unsigned/signed first..

This is a little bit to pessimistic. You can not do arithmetic operations
with std_logic_vector (since the interpretation is not defined in the VHDL
standard: unsigned, sign-magnitude,...).
The solution I presented used an IEEE approved package. However there are
also non IEEE packages that can do arithmetic operations on a
std_logic_vector.
http://members.aol.com/vhdlcohen/vhdl/Models.html
Also Synopsys has a package std_logic_unsigned (often located in the IEEE
library) that can operate on std_logic_vector. But this package can surprise
you with respect to explicit and implicit declarations.

Currently also for the VHDL-200X interpretation of a vector as an unsigned
is investigated, see
http://www.eda.org/vhdl-200x/vhdl-20...proposals.html

Egbert Molenkamp

A123b456c
Guest
Posts: n/a

 11-08-2003
>Subject: algorithm problem
>Date: 11/2/03 8:45 PM US
>Message-id: <lbkpb.3423\$(E-Mail Removed)>
>
>Hello,
>
> I'm trying to code a module to do the >following algorithm:
>
>If Input is even, divide by 2 and do two's >complement(invert bits and add 1)
>If Input is odd, increment by 1 and then >divide by 2.

You might want to look at the following code.

library ieee;
use ieee.std_logic_1164.all;
---
---
---
---
entity mystery is
generic
(
length: integer := 4
);
port --- bit zero is lsb, dividing means shifting right
(
inputs: in std_logic_vector(length-1 downto 0);
outputs: out std_logic_vector(length-1 downto 0)
);
end entity mystery;
---
---
---
---
architecture mystery of mystery is
---
function increment(vektor: std_logic_vector)
return std_logic_vector is
variable result: std_logic_vector(vektor'range);
variable carry: std_logic;
begin
carry := '1';
for count in vektor'low to vektor'high loop
result(count) := vektor(count) xor carry;
carry := vektor(count) and carry;
end loop;
return (result);
end function increment;
---
begin
mysterious: process(inputs)
variable zwischen_even: std_logic_vector(length-1 downto 0);
variable zwischen_odd: std_logic_vector(length-1 downto 0);
begin
if (inputs(0) = '0') then
zwischen_even := not ('0' & inputs(length-1 downto 1));
outputs <= increment(zwischen_even);
else
zwischen_odd := increment(inputs);
outputs <= '0' & zwischen_odd(length-1 downto 1);
end if;
end process mysterious;
end architecture mystery;