How to use ufixed when it involves multiplication a number of times?(VHDL question)

Discussion in 'VHDL' started by Anwesa Roy, Aug 22, 2016.

  1. Anwesa Roy

    Anwesa Roy

    Joined:
    Aug 22, 2016
    Messages:
    1
    Likes Received:
    0
    We have to implement the following LMS equations in vhdl in a loop. y=x1w1+x2w2; w1=u*x1*e+w1; w2=u*x2*e+w2; e=y-x; However u is a floating point number and have to make the code synthesizable. Hence we have to use fixed point implementation and have to use ufixed. However when we are multiplying the numbers ,the range of the number to hold the multiplied number increases with each iteration, that is the range of the number that holds multiplication value has to be increased with each iteration. For example for eq 2:

    u is ufixed(3 downto -5) x1 is ufixed(6 downto -5) e is ufixed(15 downto -10) w1 is ufixed(6 downto -5)

    which makes w1 (26 downto -20) which contradicts the previous range of w1.How to resolve this issue?

    Code (Text):
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    --use IEEE.STD_LOGIC_Arith.ALL;
    use IEEE.STD_LOGIC_Unsigned.ALL;

    use IEEE.NUMERIC_STD.ALL;
    library ieee_proposed;
    use ieee_proposed.fixed_pkg.all;


    Library UNISIM;
    use UNISIM.vcomponents.all;


    entity freq_div is

         generic ( width : integer :=  4 );
        Port (clk_p, clk_n : in  STD_LOGIC;

              LED : out  STD_LOGIC:='0';

             seconds : out std_logic_vector(5 downto 0);
             minutes : out std_logic_vector(5 downto 0);
             hours : out std_logic_vector(4 downto 0);

            random_num : out std_logic_vector (width-1 downto 0);
            data_outa,data_outb,data_outc,data_outd,output : out STD_LOGIC_VECTOR(7 downto 0);

               count : out  STD_LOGIC_vector(3 downto 0));
    end freq_div;

    architecture Behavioral of freq_div is

    signal sec,min,hour : integer range 0 to 60 :=0;
    signal counta : integer :=1;
    signal clka : std_logic :='0';

    signal clk2: std_logic;
    signal cnt : std_logic_vector(3 downto 0):=(others=>'0');
    signal clk: std_logic_vector(28 downto 0):=(others=>'0');

    signal data_out1,rand_temp1,noisy_signal,data_outb1,data_outc1,data_outd1, summation_signal : integer;
    signal noisy_signal1,s1,s2,s3,s4,s : STD_LOGIC_VECTOR(7 downto 0);
    signal summation_signal1 : STD_LOGIC_VECTOR(11 downto 0);
    signal i : integer :=1;
    signal j : integer :=120;
    signal k : integer :=40;
    signal l : integer :=80;
    signal ii,iii: integer :=0 ;
    signal jj: integer :=30 ;
    signal kk: integer :=60 ;
    signal ll: integer :=90 ;
    signal ii_gate: std_logic := '0';
    signal a : integer := 0;

    --signal n1,n2 : ufixed(127 downto -128);
    --signal n3 : ufixed(255 downto -256);

    signal n1,n2 : ufixed(6 downto -5);
    --signal n3 : ufixed(13 downto -10);
    signal n3 : ufixed(25 downto -10);




    signal LED1 :STD_LOGIC := '0';

    type memory_type is array (0 to 359) of std_logic_vector(7 downto 0);
    signal sine2,sineo : memory_type;
    --ROM for storing the sine values generated by MATLAB.
    signal sine : memory_type :=(x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"01",x"01",
    x"01",x"01",x"01",x"01",x"02",x"02",x"02",x"02",x"03",x"03",
    x"03",x"04",x"04",x"04",x"04",x"05",x"05",x"05",x"05",x"06",
    x"06",x"07",x"07",x"08",x"08",x"09",x"09",x"0a",x"0a",x"0b",
    x"0b",x"0c",x"0c",x"0d",x"0d",x"0e",x"0e",x"0f",x"0f",x"10",
    x"11",x"11",x"12",x"13",x"13",x"14",x"15",x"15",x"16",x"17",
    x"18",x"18",x"19",x"1a",x"1b",x"1b",x"1c",x"1d",x"1e",x"1e",
    x"1f",x"20",x"21",x"22",x"23",x"23",x"24",x"25",x"26",x"27",
    x"28",x"29",x"2a",x"2b",x"2c",x"2d",x"2f",x"2f",x"30",x"31",
    x"32",x"34",x"35",x"35",x"36",x"37",x"38",x"39",x"3a",x"3b",
    x"3c",x"3c",x"3e",x"3f",x"40",x"41",x"42",x"43",x"44",x"45",
    x"46",x"46",x"47",x"48",x"49",x"49",x"4a",x"4b",x"4c",x"4c",
    x"4e",x"4f",x"4f",x"50",x"51",x"51",x"52",x"53",x"53",x"54",
    x"55",x"55",x"56",x"57",x"57",x"58",x"58",x"59",x"59",x"5a",
    x"5a",x"5b",x"5b",x"5c",x"5c",x"5d",x"5d",x"5e",x"5e",x"5f",
    x"5f",x"5f",x"60",x"60",x"60",x"61",x"61",x"61",x"61",x"62",
    x"62",x"62",x"62",x"63",x"63",x"63",x"63",x"63",x"63",x"64",
    x"64",x"64",x"64",x"64",x"64",x"64",x"64",x"64",x"64",x"64",
    x"64",x"64",x"64",x"64",x"64",x"64",x"63",x"63",x"63",x"63",
    x"63",x"63",x"62",x"62",x"62",x"62",x"61",x"61",x"61",x"60",
    x"60",x"60",x"5f",x"5f",x"5f",x"5e",x"5e",x"5d",x"5d",x"5c",
    x"5c",x"5b",x"5b",x"5a",x"5a",x"59",x"59",x"58",x"58",x"57",
    x"57",x"56",x"55",x"55",x"54",x"54",x"53",x"53",x"52",x"51",
    x"51",x"50",x"4f",x"4f",x"4e",x"4d",x"4c",x"4c",x"4b",x"4a",
    x"49",x"49",x"48",x"47",x"46",x"46",x"45",x"44",x"44",x"43",
    x"42",x"41",x"41",x"40",x"3f",x"3e",x"3d",x"3c",x"3c",x"3b",
    x"3a",x"39",x"38",x"37",x"36",x"35",x"35",x"34",x"33",x"32",
    x"31",x"30",x"2f",x"2f",x"2e",x"2d",x"2c",x"2b",x"2a",x"29",
    x"28",x"28",x"27",x"26",x"25",x"24",x"23",x"23",x"22",x"21",
    x"20",x"1f",x"1e",x"1e",x"1d",x"1c",x"1b",x"1b",x"1a",x"19",
    x"18",x"18",x"17",x"16",x"15",x"15",x"14",x"13",x"13",x"12",
    x"11",x"11",x"10",x"0f",x"0f",x"0e",x"0d",x"0d",x"0c",x"0c",
    x"0b",x"0b",x"0a",x"0a",x"09",x"09",x"08",x"08",x"07",x"07",
    x"06",x"06",x"05",x"05",x"05",x"04",x"04",x"04",x"03",x"03",
    x"03",x"02",x"02",x"02",x"02",x"01",x"01",x"01",x"01",x"01",
    x"01",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00");


    COMPONENT ila_1

    PORT (  clk : IN STD_LOGIC;
        probe0 : IN STD_LOGIC_VECTOR(3 DOWNTO 0));
    END COMPONENT  ;

    begin

    --seconds <= conv_std_logic_vector(sec,6);
    --minutes <= conv_std_logic_vector(min,6);
    --hours <= conv_std_logic_vector(hour,5);

    seconds <= std_logic_vector(to_signed(sec,6));
    minutes <= std_logic_vector(to_signed(min,6));
    hours <= std_logic_vector(to_signed(hour,5));

       IBUFDS_inst : IBUFDS
      generic map (
         DIFF_TERM => FALSE, -- Differential Termination
         IBUF_LOW_PWR => TRUE, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
         IOSTANDARD => "DEFAULT")
      port map (
         O => clk2,  -- Buffer output
         I => clk_p,  -- Diff_p buffer input (connect directly to top-level port)
         IB => clk_n -- Diff_n buffer input (connect directly to top-level port)
      );

    process(clk2)
      begin
      if(clk2'event and clk2='1') then
      counta <=counta+1;
      if(counta = 5) then
      clka <= not clka;
      counta <=1;
      end if;
      end if;
      end process;

      process(clka)   --period of clk is 1 second.
      variable rand_temp : std_logic_vector(width-1 downto 0):=(width-1 => '1',others => '0');
      variable temp : std_logic := '0';

      variable w1,w2 : ufixed(6 downto -5);
      --variable w1,w2 : ufixed(42 downto -5);
      variable x1,x2 : ufixed(6 downto -5);
      variable u : ufixed(3 downto -5);
      variable x : ufixed(14 downto -10);
      variable y : ufixed(14 downto -10);
      variable e : ufixed(15 downto -10);

      begin
      w1 :=  to_ufixed (0.0,w1);
      w2 :=  to_ufixed (0.0,w2);
      u :=  to_ufixed (0.05,u);

      if(clka'event and clka='1') then

      n1 <=  to_ufixed (51.9999,n1);         -- n1 = "00101110" = 5.75
      n2 <=  to_ufixed (6.5,n2);          -- n2 = "00110100" = 6.5
      n3 <= 0.2*n2*n1;

      LED1 <= not LED1;
      LED <= LED1;
      temp := rand_temp(width-1) xor rand_temp(width-2);
      rand_temp(width-1 downto 1) := rand_temp(width-2 downto 0);
      rand_temp(0) := temp;

      i <= i+ 1;
      if(i = 359) then
      i <= 0;
      end if;

      j <= j+ 1;
      if(j = 359) then
      j <= 0;
      end if;

      k <= k+ 1;
      if(k = 359) then
      k <= 0;
      end if;

      l <= l+ 1;
      if(l = 359) then
      l <= 0;
      end if;

      data_outa <= sine(i);

      data_outb <= sine(j);
      data_outc <= sine(k);
      data_outd <= sine(l);

      data_out1<=to_integer(unsigned(sine(i)));
      random_num <= rand_temp;
      rand_temp1<=to_integer(unsigned(rand_temp));
      noisy_signal<=data_out1+rand_temp1;
      noisy_signal1<= std_logic_vector(to_signed(noisy_signal,8));

      sine2(ii)<=noisy_signal1;
      sineo(ii)<=sine(i);
           ii <= ii+ 1;
               if(ii = 359) then
               ii <=0;
               ii_gate <= '1';
               end if;

           if ii_gate = '1' then    
           s1 <= sine2(iii);
           s<= sineo(iii);
           output <=s1;
           iii <= iii+ 1;
           if(iii = 359) then
           iii <= 0;
           end if;

           x1 :=  to_ufixed (to_integer(signed(s1)),x1);
           x :=  to_ufixed (to_integer(signed(s)),x);

          s2 <= sine2(jj);
          jj <= jj+ 1;
          if(jj = 359) then
          jj <= 0;
          end if;
          x2 :=  to_ufixed (to_integer(signed(s2)),x2);

           s3 <= sine2(kk);
           kk <= kk+ 1;
           if(kk = 359) then
           kk <= 0;
           end if;
           s4 <= sine2(ll);
           ll <= ll+ 1;
           if(ll = 359) then
           ll <= 0;
           end if;

            if(a<1000) then
                --write your code here..
                  y := x1*w1+x2*w2;
                  e := y-x;
                  w1 := u*x1*e+w1;
                  w2 :=u*x2*e+w2;
                  a<=a+1;  --increment the pointer 'j'.

            end if;

           end if;

      sec <= sec+ 1;
      if(sec = 59) then
      sec<=0;
      min <= min + 1;
      if(min = 59) then
      hour <= hour + 1;
      min <= 0;
      if(hour = 23) then
      hour <= 0;
      end if;
      end if;
      end if;
      end if;

      end process;


    --    process(clk2, rst)
    --        begin
    --            if (rst = '1')then
    --                clk <= (others=>'0');
    --            elsif (clk2'event and clk2 = '1')then
    --                clk <= clk + 1;
    --            end if;
    --    end process;


    --  process(clk(25), rst,up,pause)
    --      begin
    --      if (rst = '1') then
    --          cnt <= (others=>'0');
    --      elsif (clk(25) = '1' and clk(25)'event) then
    --          if (up = '1' and pause = '0')then
    --              cnt <= cnt + '1';
    --          elsif (up = '0' and pause = '0') then
    --              cnt <= cnt - '1';
    --          elsif( pause ='1')then
    --              cnt <= cnt;
    --          end if;
    --      end if;
    --  end process;

    --  count <= cnt;






    end Behavioral;
     
    Please focus on this part as the equations have been iplemented here:


    Code (Text):
    if(a<1000) then
                --write your code here..
                  y := x1*w1+x2*w2;
                  e := y-x;
                  w1 := u*x1*e+w1;
                  w2 :=u*x2*e+w2;
                  a<=a+1;  --increment the pointer 'j'.

            end if;
     
    Anwesa Roy, Aug 22, 2016
    #1
    1. Advertisements

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Bernd Fuhrmann
    Replies:
    8
    Views:
    540
    Rob Williscroft
    Dec 28, 2003
  2. metaperl
    Replies:
    2
    Views:
    373
    bayerj
    Dec 14, 2006
  3. Michael Hines
    Replies:
    1
    Views:
    327
    Arnaud Delobelle
    May 24, 2008
  4. William Hughes
    Replies:
    13
    Views:
    1,649
    Ben Bacarisse
    Mar 15, 2010
  5. Moh

    I need a VHDL code

    Moh, Jun 8, 2016, in forum: VHDL
    Replies:
    0
    Views:
    501
  6. ivan gagula

    VHDL sequence of a machine

    ivan gagula, Jun 22, 2016, in forum: Introductions
    Replies:
    0
    Views:
    394
    ivan gagula
    Jun 22, 2016
  7. ivan gagula

    RTL to VHDL

    ivan gagula, Jun 22, 2016, in forum: Introductions
    Replies:
    0
    Views:
    470
    ivan gagula
    Jun 22, 2016
  8. Razn_957
    Replies:
    0
    Views:
    384
    Razn_957
    Aug 19, 2016
Loading...