Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Lms(least mean square) algorithm design using vhdl.

Status
Not open for further replies.

Anwesa Roy

Member level 2
Joined
Feb 24, 2014
Messages
49
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
532
We are designing LMS algorithm using vhdl.
pic.png

We want to know how each value of X(n) comes. We have been told that X(n) is a complex number, which is the input to equalizer which comes AFTER TRAVELLING THROUGH the CHANNEL suffering from noise, pathloss etc.So the question is , will we get the value of X(1) after first delay, X(2) after 2nd delay and so on.

But, in design through vhdl how can we design a channel that will contain noise,delay, pathloss etc (example a Rayleigh fading channel).

Our senior has designed the LMS algorithm through hardware cosimulation where she has modelled the channel using Rayleigh fading channel. But we are unsure if such a design could be done in vhdl.So we cant find a value of X(n) [input signal] and d(n) [desired signal] with which we can simulate our vhdl program.


We have designed an algorithm, but we dont know what value should we take for x(0), x(1),.....x(n) or d(n)...

We have taken four values of x(n), and used these values iteratively..Is the process correct(Since the calculations involes complex numbers, we have broken the complex and real parts and have computed those individually)...Another question is that, d(n) is just one signal, however x(n) is so many...why is that?...


Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.std_logic_signed.all;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity lms2 is
    Port (wr9,wi9,xr,xi : in STD_LOGIC_VECTOR (12 downto 0);
           --u : in integer;
         
           yr,yi,er,ei,wr8,wi8,zzz,sum1 : out STD_LOGIC_VECTOR (12 downto 0));
end lms2;

architecture Behavioral of lms2 is
signal a,b :real;
signal yr11, yi11, yr22, yi22 : real;

--variable r,s : real range 0.0 to 15.0;

begin

process(wr9,wi9,xr,xi)--process also runs without the parameters,but it gives problems during simulation
--process(u,xr,xi)
variable wr : std_logic_vector(12 downto 0);
variable wi : std_logic_vector(12 downto 0);

--variable wr : std_logic_vector(4 downto 0) :="00010";
--variable wi : std_logic_vector(4 downto 0) :="00011";
--variable wr : std_logic_vector(4 downto 0) :=wr9;
--variable wi : std_logic_vector(4 downto 0) :=wi9;
variable xr1_1 : real :=0.707;
variable xi1_1 : real :=0.701;

variable xr1_2 : real :=0.707;
variable xi1_2 : real :=0.701;

variable xr_0 : real :=0.707;
variable xi_0 : real :=0.701;

variable xr_1 : real :=0.707;
variable xi_1 : real :=0.701;

variable xr_2 : real :=0.707;
variable xi_2 : real :=0.701;

variable xr_3 : real :=0.707;
variable xi_3 : real :=0.701;

variable dr1 : real :=0.807;
variable di1 : real :=0.801;
variable yr1_1: real;
variable yi1_1 : real;
variable yr1_2 : real;
variable yi1_2 : real;

variable er1_1 : real;
variable ei1_1 : real;
variable er1_2 : real;
variable ei1_2 : real;

variable wr1_1 : real := 0.0;
variable wi1_1 : real := 0.0;

variable wr1_2 : real := 0.0;
variable wi1_2 : real := 0.0;

variable u   : real :=0.2;
variable k : integer :=0;

--variable f : real := 3.2;
--variable g : real := 2.6;
--variable h : real;
--variable hh : real;


begin

--h := f+g;
--hh := f*g;
--a <= h;
--b <=hh;

--process(xr,xi,u)
--bi <= to_integer(unsigned(k)) ;
--bj <= to_integer(unsigned(l)) ;
--bk <= bi*bj;





for z in 1 to 170 loop
if (k=0)then
xr1_1 := xr_0;
xi1_1 := xi_0;
xr1_2 := xr_3;
xr1_2 := xi_3;

elsif (k=1) then
xr1_1 := xr_1;
xi1_1 := xi_1;
xr1_2 := xr_0;
xr1_2 := xi_0;

elsif (k=2) then
xr1_1 := xr_2;
xi1_1 := xi_2;
xr1_2 := xr_1;
xr1_2 := xi_1;

elsif (k=3) then
xr1_1 := xr_3;
xi1_1 := xi_3;
xr1_2 := xr_2;
xr1_2 := xi_2;
end if;
k := k+1;
if(k=4) then
k := 0;
end if;
yr1_1 := wr1_1*xr1_1-wi1_1*xi1_1;
yi1_1 := wr1_1*xi1_1+wi1_1*xr1_1;
yr1_2 := wr1_2*xr1_2-wi1_2*xi1_2;
yi1_2 := wr1_2*xi1_2+wi1_2*xr1_2;

er1_1 := (wr1_1*xr1_1)-(wi1_1*xi1_1)-dr1;
ei1_1 := (wr1_1*xi1_1)+(wi1_1*xr1_1)-di1;
er1_2 := (wr1_2*xr1_2)-(wi1_2*xi1_2)-dr1;
ei1_2 := (wr1_2*xi1_2)+(wi1_2*xr1_2)-di1;

wr1_1 := u*(xr1_1*er1_1-xi1_1*ei1_1)+wr1_1;
wi1_1 := u*(xr1_1*ei1_1+xi1_1*er1_1)+wi1_1;
wr1_2 := u*(xr1_2*er1_2-xi1_2*ei1_2)+wr1_2;
wi1_2 := u*(xr1_2*ei1_2+xi1_2*er1_2)+wi1_2;



end loop;

yr11 <= yr1_1;
yi11 <= yi1_1;
yr22 <= yr1_2;
yi22 <= yi1_2;

end process;


end Behavioral;
 
Last edited:

Only you can really comment on the quality of your algorithm.
But in terms of your code - what are you trying to do with this VHDL? you cannot put it in a chip as it is full of real types, so why bother with VHDL? why not do it in C or matlab, as it appears you've written it like software anyway.

This code is not good VHDL if you intend to put it in hardware or at least try and simulate a design that might behave like hardware.
 

Only you can really comment on the quality of your algorithm.
But in terms of your code - what are you trying to do with this VHDL? you cannot put it in a chip as it is full of real types, so why bother with VHDL? why not do it in C or matlab, as it appears you've written it like software anyway.

This code is not good VHDL if you intend to put it in hardware or at least try and simulate a design that might behave like hardware.



We can put it in fpga boards after we use floating point libraries(For now we are not accustomed with using floating point libraries hence using real variables and are just simulating the results). We are using vhdl because we need to compute the resources(DSP slices) used for the vhdl program against the same algorithm implemented using hardware co simulation.

The question is we are not geting what values of x(n) and d(n) should we use for simulation.
 

Only you can comment on the algorithm. I assume you have a model of it somewhere other than VHDL - so you should know what values of X(n) and d(n) to use - we cannot tell you.

You current VHDL implementation is nothing like a hardware implementation - so it is no use to you in its current state. I highly suggest starting again after reading a VHDL tutorial.
 

why bother with VHDL? why not do it in C or matlab, as it appears you've written it like software anyway.
It doesn't appear to be written like software it is written exactly like software.

The use of the term "VHDL program", the extensive use of variables (storage in software), a for loop to iterate over some block of "software", real types...These are all things that say I know how to write software in C, etc. VHDL is written in a text editor, so I can use my software knowledge to write VHDL software.

Draw a schematic then translate it to VHDL with the standard templates for all the hardware blocks, e.g. multiplexers, flip-flops, comparisons, counters, etc.

For loop are completely unrolled in HDLs and the resulting logic exists in parallel. As a software oriented developer never use for loops until you fully understand they are not temporal, but spatial. Also never use variables until you fully understand that they are immediately evaluated in a process (also don't use them until you understand what this last statement means).

As Tricky said you need to go read a VHDL tutorial or book and start over.
 

@Anwesa, don't use floating point. Instead, do a fixed point simulation in a language you are comfortable with. Floating point numbers are one way to represent numbers less than one, but there are other ways as well. Floating point makes sense for CPU/GPU designs as the hardware is already there. But for FPGA/ASIC, you should determine if it is actually needed as it requires a very significant increase in resources.

The result of your attempt will likely tell you that it is infeasible to put the design onto any device. Each multiply uses multiple dsp slices, and you have at least 24*170 of them -- 4080*N, where N is probably 4+.
 
@Anwesa, don't use floating point. Instead, do a fixed point simulation in a language you are comfortable with. Floating point numbers are one way to represent numbers less than one, but there are other ways as well. Floating point makes sense for CPU/GPU designs as the hardware is already there. But for FPGA/ASIC, you should determine if it is actually needed as it requires a very significant increase in resources.

The result of your attempt will likely tell you that it is infeasible to put the design onto any device. Each multiply uses multiple dsp slices, and you have at least 24*170 of them -- 4080*N, where N is probably 4+.

We are doing calculations with numbers less than 1 hence we have to use real variables/floating point numbers.

So you are telling that since the resources used by this program is very high, we have to stick to simulation, it cant be implemented in fpgas...
 

We are doing calculations with numbers less than 1 hence we have to use real variables/floating point numbers.

So you are telling that since the resources used by this program is very high, we have to stick to simulation, it cant be implemented in fpgas...

It can be implemented in an FPGA. But it will use a lot of resources. Fixed point can also represent less than 1 and will use few resources.
But you are going about implementing your design completly the wrong way.
 
How to implement LMS algorithm in vhdl?

We are trying to implement LMS algorithm using VHDL .
1)What values should we take for x(n) and d(n)?
2) Since x(n) is the value of the signal that is obtained after passing through the channel, do we need to model a channel to generate x(n)?If so how to do that?
 

Re: How to implement LMS algorithm in vhdl?

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

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:
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:
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;

I am using vivado 2016.2
 

An essential feature of the fixed point package is that it does rounding/truncation and if desired saturation of arithmetic results automatically. And adjust the decimal point during multiply. Your range example suggests that you don't yet understand the concept. I believe it's already explained in the package user's guide.

What you need to find out is the required range (number of integer bits) and resolution (number of fractional bits) for all signals involved in your code. Determine if range overflow can occur under circumstances and implement saturation logic if necessary. (An option of the fixed package that consumes additional logic resources). Then leave the number conversion and scaling of results to the package.

Another point, the coefficients used in your code are real constants, not floating point (a synthesizable number format). Real constants are converted to fixed point numbers by the respective conversion function.
 

It's pretty obvious from the code in #11 that the OP still has no clue about hardware design. They are still writing their VHDL as if it was a software programming language. Tons of variables, relying on multiplication and addition priority rules to ensure correctly calculated values (I don't trust VHDL or Verilog to interpret that correctly, e.g. in Verilog the calculation is done left to right with no rules.

e.g.
Code:
what you wrote
  y = x1*w1+x2*w2
what verilog would do...
  y = (((x1*w1)+x2)*w2)
don't know if this also applies to VHDL

You code also doesn't seem to account for how slow it will be.
Code:
y := x1*w1+x2*w2;  -- two multiplies and an add, or possibly interpreted as
                   -- a multiply followed by an add, followed by a multiply, maybe slow
e := y-x;          -- now take that first calculation and subtract something., definitely slow
w1 := u*x1*e+w1;   -- now multiply it with another multiply, extremely slow
As all of this stuff needs to be done in 1 clock cycle don't expect high performance and a high clock rate, good luck getting it to run at 50 MHz.
 

This thread has been going on since June. OP, you are not using your time efficiently by trying to implement without knowing hardware design. Take some time off from the implementation task, and start learning.
 

what verilog would do...
y = (((x1*w1)+x2)*w2)
I'm only occasionally writing Verilog, but according to the LRM operator precedence rules are as below (quite similar to C language)

Verilog operator precedence.png

VHDL is similar in a first order, some differences with operators that are dual use, both logical and bitwise.
 

We have found a code for implementing LMS algorithm. However we cannot find any of the components of LMS algorithm in the simulation results viz input signal x(n), desired signal d(n),error signal e(n),output signal y(n).Only signal result is there.What value is result representing?Also after simulation using test bench, result is holding one single value. Please explain what this code is doing?
Also in the test bench mu2(mu) is 0.15. How have they calculated that?

Code:
----------------------------------------------------------------Mainfile.vhd-----------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity adaptivfilter is
port (
afi: in std_logic_vector(31 downto 0);
bfi: in std_logic_vector(31 downto 0);
mu2: in std_logic_vector(31 downto 0);
ndfi: in std_logic;
rfdfi: out std_logic;
clk: in std_logic;
resultfi: out std_logic_vector(31 downto 0);
rdyfi: out std_logic);
end adaptivfilter;

architecture Behavioral of adaptivfilter is
 
signal xin0 : std_logic_vector(31 downto 0):= "11000000000000000000000000000000";
    signal xin1 : std_logic_vector(31 downto 0):= "11000000000000000000000000000000";
    signal wt0 : std_logic_vector(31 downto 0):= "11000000000000000000000000000000";
    signal wt1 : std_logic_vector(31 downto 0):= "11000000000000000000000000000000";
    signal rfdmul0,rfdmul1,rfdmul2,rfdmul3,rfdmul4,rfdad0,rfdad1,rfdad2,rfdsub0:std_logic:='1';
    signal resultad0,resultad1,resultad2,resultmul0,resultmul1,resultmul2,resultmul3,resultmul4,resultsub0 : std_logic_vector(31 downto 0):= "11000000000000000000000000000000";
    signal ndfi2,ndad,ndsub0,rdymul0,rdymul1,rdymul2,rdymul3,rdymul4,rdyad0,rdyad1,rdyad2,rdysub0:std_logic:='0';
    
    component fadder
    port (
    a: in std_logic_vector(31 downto 0);
    b: in std_logic_vector(31 downto 0);
    operation: in std_logic_vector(5 downto 0);
    operation_nd: in std_logic;
    operation_rfd: out std_logic;
    clk: in std_logic;
    result: out std_logic_vector(31 downto 0);

 
rdy: out std_logic);
end component;
component fmultiplier
port (
a: in std_logic_vector(31 downto 0);
b: in std_logic_vector(31 downto 0);
operation_nd: in std_logic;
operation_rfd: out std_logic;
clk: in std_logic;
result: out std_logic_vector(31 downto 0);
rdy: out std_logic);
end component;
begin
mul0: fmultiplier port map(xin0,wt0,ndfi2,rfdmul0,clk,resultmul0,rdymul0);
mul1: fmultiplier port map(xin1,wt1,ndfi2,rfdmul1,clk,resultmul1,rdymul1);
ndad<=rdymul0;
add0: fadder port map (resultmul0,resultmul1,"000000",ndad,rfdad0,clk,resultad0,rdyad0);
sub: fadder port map (bfi,resultad0,"000001",rdyad0,rfdsub0,clk,resultsub0,rdysub0);

 
mul2: fmultiplier port map(mu2,resultsub0,rdysub0,rfdmul2,clk,resultmul2,rdymul2);
mul3: fmultiplier port map(resultmul2,xin0,rdymul2,rfdmul3,clk,resultmul3,rdymul3);
mul4: fmultiplier port map(resultmul2,xin1,rdymul2,rfdmul4,clk,resultmul4,rdymul4);
add1: fadder port map (wt0,resultmul3,"000000",rdymul4,rfdad1,clk,resultad1,rdyad1);
add2: fadder port map (wt1,resultmul4,"000000",rdymul4,rfdad2,clk,resultad2,rdyad2);
resultfi<=resultad0;
rdyfi<=rdyad2;--last ready output
rfdfi<=rdyad0;--last ready for data;not giving;
process( ndfi)
begin
ndfi2<=ndfi;
end process;

READ_NET: process

begin

 
wait until ndfi = '1';--+
xin1<=xin0;
xin0<=afi;
end process READ_NET;

READ_wt: process
begin
wait until rdyad2 = '1';
wt0<=resultad1;
wt1<=resultad2;
end process READ_wt;
end Behavioral;

Test Bench:

Code:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values

USE ieee.numeric_std.ALL;
ENTITY tb IS
END tb;
ARCHITECTURE behavior OF tb IS-- Component Declaration for the Unit Under Test (UUT)

 
COMPONENT adaptivfilter
PORT(
afi : IN std_logic_vector(31 downto 0);
bfi : IN std_logic_vector(31 downto 0);
mu2 : IN std_logic_vector(31 downto 0);
ndfi : IN std_logic;rfdfi : OUT std_logic;
clk : IN std_logic;
resultfi : OUT std_logic_vector(31 downto 0);
rdyfi : OUT std_logic);
END COMPONENT;
signal afi : std_logic_vector(31 downto 0) := (others => '0');
signal bfi : std_logic_vector(31 downto 0) := (others => '0');
signal mu2 : std_logic_vector(31 downto 0):= "00111110000110011001100110011010"; --(0.15)
signal ndfi : std_logic := '0';
signal clk: std_logic := '0';
signal rfdfi : std_logic;
signal resultfi : std_logic_vector(31 downto 0);
signal rdyfi : std_logic;-- Clock period definitions
constant clk_period: time := 2000 ns;
constant nd_period: time := 0.2 ms;
BEGIN

 
-- Instantiate the Unit Under Test (UUT)
uut: adaptivfilter PORT MAP (
afi => afi,
bfi => bfi,
mu2 => mu2,
ndfi => ndfi,
rfdfi => rfdfi,
clk => clk,
resultfi => resultfi,
rdyfi => rdyfi);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
ndfi_process :process
begin
ndfi <= '0';
wait for 500 ns ;
ndfi <= '1';
wait for clk_period;
ndfi <= '0';
wait for 0.175 ms ;
end process;

 
REA_NET: process
begin
afi <="00111111100000000000000000000000";
bfi <="00111110100111100011011101111010";
wait for nd_period;
afi <="00111110100111100011011101111010";
bfi <="00111111100000000000000000000000";
wait for nd_period;
afi <="10111111010011110001101110111101";
bfi <="00111110100111100011011101111010" ;
wait for nd_period;
afi <="10111111010011110001101110111101";
bfi <="10111111010011110001101110111101";
wait for nd_period;
afi <="00111110100111100011011101111010";
bfi <="10111111010011110001101110111101";
wait for nd_period;
end process REA_NET;
END behavior;
 

If we give you a response, will you actually read and listen to it?
Where did you "find" this code? It also looks pretty poor.
Why dont you ask the authors of this code what it all means?
 

How to write testbench for this code if we want to implement it in vivado HLS?

We are new to vivado HLS. It seems that it is mandatory to write testbench for a c code in vivado hls. How to write a testbench for this code?

We have come to know that we have to omit the printf statements. What are the other necessary changes that should be incorporated in our source code.

Any other necessary suggestions are welcome.Thank you

Code:
#include <stdio.h>
/*#include <conio.h>*/

int main()
{
    printf("Hello, World!\n");
    int i,j;
    float w1,w2,u,e[1000],y[1000];
    u=0.002;
    w1=0.0;
    w2=0.0;
    j=0;
    float x[]={1,0,1,0,0,1,1,0,1,1,0,1,0,0,1,1};
    //printf("Enter the values of x:");

    float d[]={0,0,1,0,1,0,1,0,0,1,1,1,0,0,0,1};
    for(i=1;i<=1000;i++)
    {
     y[i]=x[j+1]*w1+x[j]*w2;
     printf("%d\n",i);
     printf("x:%f\n",x[j]);
     printf("y(n):%f\n",y[i]);
     e[i]=y[i]-d[j+1];
     if(e[i]<0)
     {
      e[i]=-e[i];   
     }
     printf("er:%f\n",e[i]);
     w1=u*x[j+1]*e[i]+w1;
     w2=u*x[j]*e[i]+w2;

     j=j+1;
     if(j==16)
     {
         j=0;
     }
    }
    /*printf("Values of y:");
    for(i=0;i<25;i++)
    {
     printf("%f\n",y[i]);   
    }
    printf("Values of error:");
     for(i=0;i<2;i++)
    {
     printf("%f\n",e[i]);   
    }
    */
    return 0;
}
 

1> You have deviated from the original topic. So please start a new thread.

2> I have never worked with Vivado HLS, but if I were you I would start with the following-
https://www.xilinx.com/video/hardware/getting-started-vivado-high-level-synthesis.html
https://www.xilinx.com/support/docu...x2014_1/ug902-vivado-high-level-synthesis.pdf

How to write testbench for this code if we want to implement it in vivado HLS?
In HLS you get an RTL as an output product, right? This can be your DUT.
Then it should be possible to write a normal TB in VHDL/Verilog that will be driving your DUT (HLS generated RTL).

I don't know for HLS, if one can also write a TB in C and after translation, whether it would be perfect to testing the DUT. You ned to find it out from <2>.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top