Tenemos que implementar las siguientes ecuaciones de LMS en vhdl en un bucle. y = x1w1 + x2w2; w1 = u * x1 * e + w1; w2 = u * x2 * e + w2; e = y-x; Sin embargo, u es un número de punto flotante y debe hacer que el código sea sintetizable. Por lo tanto, tenemos que usar la implementación de punto fijo y usar ufixed. Sin embargo, cuando estamos multiplicando los números, el rango del número para mantener el número multiplicado aumenta con cada iteración, es decir, el rango del número que contiene el valor de multiplicación debe aumentarse con cada iteración. Por ejemplo para la ecuación 2:
u es ufixed (3 abajo a -5) x1 es ufixed (6 abajo a -5) e es ufixed (15 downto -10) w1 es ufixed (6 downto -5)
que hace w1 (26 abajo a -20) que contradice el rango anterior de w1.¿Cómo resolver este problema?
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;
Por favor, enfóquese en esta parte ya que las ecuaciones se han multiplicado aquí:
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;
Estoy usando vivado 2016.2