[SOLVED] vhdl output from division operation

Status
Not open for further replies.

rakeshk.r

Member level 2
Joined
Nov 12, 2013
Messages
47
Helped
1
Reputation
2
Reaction score
1
Trophy points
8
Visit site
Activity points
421
Hi,
The code below should perform 5.25/3 = 1.75 But i am not getting 1.75 (in signed binary "000111000000000000") instead i am getting "000000000000000001"and I don't why I am getting a wrong output. Also I am aware this code is not for synthesis. Any help to get the correct output is greatly appreciated. Thank you.
Code:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;

ENTITY test_hdl1 IS
port  ( clk : IN std_logic;
        rst : IN std_logic; 
        output : OUT signed (17 downto 0)
      );  
  
END ENTITY test_hdl1;

--
ARCHITECTURE logic OF test_hdl1 IS

BEGIN
testing :process (clk)
variable reg10: signed (17 downto 0);
variable reg8 : signed (17 downto 0);
variable reg9 : signed (17 downto 0);
begin
if (rising_edge(clk)) then
    
    if (rst='0') then 
        
        reg10 := reg8/reg9;  -- (4Int,14Fract)
       
    else 
               
        reg8  := "010101000000000000";-- 5.25 (4Int,14Fract)
        reg9  := "001100000000000000";-- 3    (4Int,14Fract)
        reg10 := (others=>'0');
    end if;
    output <= reg10;
end if;
end process;  
END ARCHITECTURE logic;

---------- my testbench ----------
Code:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;

LIBRARY project_lib;

ENTITY tb_test_hdl1 IS
END ENTITY tb_test_hdl1;

--
ARCHITECTURE logic OF tb_test_hdl1 IS
-- internal signal --
signal clk_tb   : std_logic := '0'; 
signal rst_tb   : std_logic := '1';
signal out_tb   : signed(17 downto 0); 
constant clk_period : time := 10 ns;  

-- component instantiation --
component test_hdl1
   port(
      clk   : IN     std_logic;
      rst   : IN   std_logic;
      output: OUT   signed(17 downto 0)
      );
end component;

For all : test_hdl1 use entity project_lib.test_hdl1; 

BEGIN

   uut:test_hdl1 port map(
        clk => clk_tb,
        rst => rst_tb,
        output => out_tb
      );

clk_toggle:process
begin
  clk_tb <= '1';
  wait for clk_period/2;  
  clk_tb <= '0';
  wait for clk_period/2;  
end process;

sim_tb: process
begin
  rst_tb <= '1';
  wait for 10 ns;
  rst_tb <= '0';

wait;
end process;    
END ARCHITECTURE logic;
 

The division function only returns the quotient, not the remainder of a division. Your division is 5.25/3 (scaled appropriatly). The answer to this is 1 (as given - the remainder would be 2.25).

Do fix this, you need to scale the divisor appropriatly. eg:
reg8 := 01010100000000000
reg9 := 00000000000000011

answer = 000111000000000000
 
generally, if we scale the divisor, should that be enough ? I was checking for another example: 5.25/3.5 = 1.5 , so i scaled 3.5 (001110000000000000) like this "000000000000000111" and i got the result like this "000011000000000000" instead i was expecting like this "000110000000000000". so my question is how scaling is done ?
 

the scaling is done such that A.B / C.D gives values in the range A.B. So the size of the numerator is the resulting size of the quotient.
 

sorry, A and B are the sizes of the integer and fraction part. A.B being A bits integer, B bits fraction.

For the numeric_std division operations, the return value has the same number of bits (A.B) as the numerator.
 
Read a fixed point notation like A.B as N_integer_bits.N_fractional_bits.

As you are using regular integer division, you get quotient_fractional_bits = dividend_fractional_bits - divisor_fractional_bits. For > 0 fractional result bits, you can add bits to the right of the dividend.

Or use the IEEE fixed point package, which cares for correct scaling.
 
@FvM I haven't used this fixed point package before. I have 2 questions regarding this. 1. I would like to know if both 'numeric_std' and 'fixed point' packages can be used in the same file. 2. Will there be a problem, when I interface a component1 output of 18-bit(10I,8F) like this, data_o : OUT sfixed(9 downto -8); to another component2 input like this, data_i : IN signed (17 downto 0);
 

1. Yes. THey are separate packages and the fixed point package has type conversion functions to convert to numeric_std types. Modelsim is fully 2008 compliant so already has the packages in the ieee library, but you will need to download the '93 compatible version for your FPGA vendor from www.vhdl.org/fphdl

2. You just need a type conversion, but the fixed package includes the conversion functions. (but why not convert component 2)
 
@TrickyDicky component2 (apparently a big design) is already designed using numeric_std types, it would be an arduous task for me to change the entire design to fixed_pkg. component1 is not a part of my synthesizable hardware, but component1 involves division operation. Now i need a help, You mentioned "fixed point package has type conversion functions to convert to numeric_std types. " could you give me the syntax for that. I want to to convert sfixed type to signed type ?
 

There's no need to change anything to fixed point package. It's just a kind of wrapper around integer arithmetic making your life comfortable. But you can do anything manually as well. As a first step, you need to figure out the right scaling, preferably using pencil and paper.
 

After my trial and error method to find right scaling, finally I understood what TrickyDicky meant in #4 and FvM said in #7. It helped a lot. Thanks to both of you.
 

hi.. anyone help me..
what is the suitable input and output that should i write? because i got unwanted input and output in waveform simulation like in the 4th pic..

 
Last edited:

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…