missing overloaded operator in numeric_std

C

Chuck Roth

The only problem I have encountered with numeric_std is there is no
overloaded operator to add a std_logic bit to an unsigned (even though there
is an overloaded operator to add an integer to an unsigned). This means
that the very useful construction to infer an adder, A + B + carry
cannot be used if A and B are unsigned and carry is std_logic. One
work-around is to declare carry as an unsigned(0 downto 0), which works but
it is rather awkward. I have tried type conversion such as unsigned(carry)
and unsigned('0'&carry) but these fail. Does anyone have a suggestion for
a better work-around?

-- Chuck Roth
 
M

Mike Treseler

Chuck said:
The only problem I have encountered with numeric_std is there is no
overloaded operator to add a std_logic bit to an unsigned (even though there
is an overloaded operator to add an integer to an unsigned). This means
that the very useful construction to infer an adder, A + B + carry
cannot be used if A and B are unsigned and carry is std_logic.

See one way to do it below using unsigned'(0 => carry).
Note that synthesis usually handles the carry chain
pretty well without explicit description.

-- Mike Treseler
____________________________________________________
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity unsigned_carry is

generic (result_len : natural := 5;
add_len : natural := 4);
port(
clk : in std_logic;
A : in unsigned(add_len-1 downto 0);
B : in unsigned(add_len-1 downto 0);
ci : in std_ulogic; -- carry in
D : out unsigned(result_len-1 downto 0)
);
end entity unsigned_carry;

architecture behave of unsigned_carry is
begin
clked : process(clk) is
subtype vec_t is unsigned(add_len -1 downto 0);
subtype sum_t is unsigned(result_len -1 downto 0);
------------------------------------------------------------
function add_uns (arg_a, arg_b : vec_t;
arg_ci : std_ulogic)
return sum_t is
begin
return
resize(arg_a, result_len) +
resize(arg_b, result_len) +
unsigned'(0 => arg_ci);
end function add_uns;
------------------------------------------------------------
procedure test_add_uns is
begin -- procedure test_add_uns
assert add_uns("0011" , "1100", '0') = "01111"
report "add_uns 1: unexpected sum";
assert add_uns("0011" , "1100", '1') = "10000"
report "add_uns 2: unexpected sum";
end procedure test_add_uns;
------------ Mike Treseler Thu Sep 8 10:21:56 2005---------
begin
test_add_uns; -- asserts are ignored by synthesis
if rising_edge(clk) then
D <= add_uns(arg_a => A, arg_b => B, arg_ci => ci);
end if;
end process clked;
end behave;
 
M

Mike Treseler

Chuck said:
Thanks for your answers to my numeric_std questions.

You are welcome.
The fix you sent for my carry problem simulates
and synthesizes fine with the software I use.
But I don't understand the notation. unsigned'(0 => carry)
is obviously a type conversion,

No, a qualified expression. See:
http://groups.google.com/groups?q=vhdl+qualified+expression+conversion
but what does the
(0 => carry) part mean

It is an aggregate. Check out:
http://vhdl.org/comp.lang.vhdl/FAQ1.html#aggregates

and why is it an integer 0?

It means bit zero of the vector is identified as "carry"
Can you recommend a good reference on this sort of thing?

Just about any VHDL reference or text covers these subjects.
My favorite is The Designer's Guide to VHDL by Peter J. Ashenden
Is there any reason why you used std_ulogic instead of std_logic?

Because it maps to std_logic without conversion
and allows multiple drive problems to be found at
compile time rather than at run time.
One thing I stress in the course I teach is the relationship
between the VHDL code and the actual hardware.
In some exercises, I have students draw a block
diagram using registers, counters, adders. state machines,
etc. and then translate that into VHDL to check their designs.
That is why I am interested in details like how to add in a carry.

The actual hardware in an fpga is gates, clock-enable d-flops
and sometimes RAM. All else is abstraction.

A TTL style netlist is a valid mental model, but so is a vhdl
synchronous process. Counters, registers and adders can just as well
be understood as a statement or two in the
_elsif rising_edge(clock) then_ clause of a vhdl process.

-- Mike Treseler
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top