subtractor

Hi,

if I synthese the followng code (substract using two's-complement and adder) using xst and then have a look to the RTL schematic, the co output is on ground and a 16bit adder is infered. The carry out (co) is the interesting signal for me. Did I wrote wrong code (TB not yet)? How to correct it? BTW, is there a way to 'tune' this entities especially to avoid such castings and conversations?

Thanks Olaf

---8

Reply to
Olaf Petzold
Loading thread data ...

there seems to be some problems on this line:

if b is zero, I got the warning: NUMERIC_STD.TO_UNSIGNED: vector truncated. Well, it's ok, since complement of 0x00 is 0xFF and +1 got overflow. The interesting part is, that the testbench with zero fails. Are there some thing to care about?

Thanks Olaf

Reply to
Olaf Petzold

somethings is wrong here. The adder TB success. The TB for this entity fails:

# ** Note: Verify Test #0: 27 - 9 = 18; co = '0' vs. got = '1' # ** Note: got wrong carry = '1' # ** Note: Verify Test #1: 39 - 0 = 39; co = '0' vs. got = '0' # ** Note: Verify Test #2: 0 - 0 = 0; co = '0' vs. got = '0' # ** Note: Verify Test #3: 255 - 0 = 255; co = '0' vs. got = '0' # ** Note: Verify Test #4: 10 - 20 = 246; co = '1' vs. got = '0' # ** Note: got wrong carry = '0' # ** Note: Verify Test #5: 0 - 255 = 1; co = '1' vs. got = '0' # ** Note: got wrong carry = '0'

Does someone say what gone wrong? Only the carry flag fails.

Thanks Olaf

Reply to
Olaf Petzold

a simplification doesn't help:

constant ONE : unsigned(WIDTH-1 downto 0) := to_unsigned(1, WIDTH);

-- two's-complement signal b2c : std_logic_vector(WIDTH-1 downto 0);

... b2c

Reply to
Olaf Petzold

Olaf Petzold schrieb:

Hi Olaf, think about the results numeric range. Can it be larger than the biggest number when you do a subtraction in a signed range (remember, you are doing two's complement!) because the result will be two's complement too.

In fact there is no other result for co than '0'.

Also you are not using a ci. (which is not really important for a subtractor)

a more compact code would look like this:

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity simple_sub is Port ( a : in std_logic_vector(15 downto 0); b : in std_logic_vector(15 downto 0); diff : out std_logic_vector(15 downto 0); co : out std_logic); end simple_sub;

architecture Behavioral of simple_sub is signal total_sum : std_logic_vector(16 downto 0); begin

total_sum

Reply to
backhus

8 bit only (for convenience)

10 = 8 + 2 = 00001010

20 = 16 + 4= 00010100 inverted: 11101011 add one : 11101100

Do the addition : 00001010 + 11101100 = 11110110

No carry needed!

-1*2^7+1*2^6+1*2^5+1*2^4+1*2^2+1*2^1 = -128+64+32+16+4+2 = -10

calculation correct!

So what's your TB expecting???

Probably you are searching for the (here) ninth bit of the result which should be '1' if the result is negative. But don't confuse this with a carry signal! That's two totally different things!

Reply to
backhus

# ** Error: D:/electronic/projects/la/la/source/vhdl/sub.vhd(33): Length of expected is 17; length of actual is 16. # ** Error: D:/electronic/projects/la/la/source/vhdl/sub.vhd(40): Length of expected is 17; length of actual is 16.

The same error I get on using unsigned of ieee.numeric_std. Here the complete file:

---8

Reply to
Olaf Petzold

OK, so BIT_WIDTH is 16.

lower_bound and upper_bound are (15 downto 0), or 16 bits wide.

x is also (15 downto 0), 16 bits wide.

diff is (16 downto 0) or 17 bits wide.

Here's the problem, and the error message is quite explicit. upper_bound and x are both 16 bits wide, and you're assigning them to a

17-bit vector.

Same here: x and lower_bound are 16-bit values assigned to a 17-bit value. Can't do that.

You simply need to extend x, upper_bound and lower_bound to be the same width as your result. In other words, something like (using numeric_std and appropriate types, either unsigned or signed):

diff := resize(x, diff'length) - resize(lower_bound, diff'length);

oughta work.

-a

Reply to
Andy Peters

Hi Olaf, shame on me. I have synthesized, but not simulated my source.

A simple change of my code like this:

total_sum

Reply to
backhus

Yes there is:

first note that numeric_std "signed" type is conveniently defined to be

2's complement, so it's a better choice than "unsigned" for your application; then note that if ports a, b, diff were signed, then diff
Reply to
Brian Drummond

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.