missing overloaded operator in numeric_std

C

Chuck Roth

Guest
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
 
Chuck Roth wrote:
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;
 
Chuck Roth wrote:

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
 

Welcome to EDABoard.com

Sponsor

Back
Top