Consultas relacionadas con la implementación del cambio de fase de la onda sinusoidal después de algún tiempo de retraso

0

Estamos escribiendo un código vhdl en el que estamos generando dos ondas sinusoidales, donde tenemos que dar un cambio de fase particular (por ejemplo, 170 grados) a cada una de las ondas después de cierto tiempo y este proceso ocurrirá repetitivamente (es decir, después de cada 50 segundos habrá cambios de fase de 170 grados de las ondas sinusoidales.)

Hemos intentado hacer el programa. Se ejecuta hasta cierto punto. Sin embargo, cuando el valor de i es mayor que 359 (hay 360 valores en la matriz), la simulación se detiene y muestra un error de fuera de límites del índice de la matriz a pesar del hecho de que i se reinicializó a 0 si el valor de i se convierte en > = 359.

Estamos incluyendo el diagrama de simulación hasta el que se produjo la simulación (después de que se detiene la simulación). Y la flecha en el segundo diagrama muestra el punto donde el puntero marca en el programa cuando finaliza la simulación.

libraryieee;useieee.std_logic_1164.all;useieee.std_logic_arith.all;useieee.std_logic_unsigned.all;entitydigi_clkisport(clk1:instd_logic;seconds:outstd_logic_vector(5downto0);minutes:outstd_logic_vector(5downto0);hours:outstd_logic_vector(4downto0);data_out3:outSTD_LOGIC_VECTOR(4downto0);data_out1:outSTD_LOGIC_VECTOR(7downto0);data_out2:outSTD_LOGIC_VECTOR(7downto0));enddigi_clk;architectureBehavioralofdigi_clkissignalsec,min,hour:integerrange0to60:=0;signalcount:integer:=1;signalclk:std_logic:='0';signali:integer:=0;signalj:integer:=155;typememory_typeisarray(0to359)ofstd_logic_vector(7downto0);--ROMforstoringthesinevaluesgeneratedbyMATLAB.signalsine: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");


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

 --clk generation.



process(clk1)
begin
if(clk1'event and clk1='1') then
count <=count+1;
if(count = 5) then --This is originally 50000000(for ease of viewing simulation results we have taken this a small no.).For 100 MHz clock this generates 1 Hz clock
clk <= not clk;
count <=1;
end if;
end if;
end process;

process(clk)   --period of clk is 1 second.
begin

if(clk'event and clk='1') then
sec <= sec+ 1;

--if(i >=359 or j>= 359) then
--i <=0;
--j <=0;
--end if;

data_out1 <= sine(i);-- after 20 us ;
data_out2 <= sine(j);

i <= i+ 1;
j <= j+ 1;

if(sec=50)then
i <= i+170;
if(i>=359)then
i<=0;
end if;
end if;

if(sec=100)then
i <= i+170;
if(i>=359)then
i<=0;
end if;
end if;

--if(sec=40)then
--i<= i+170;
--if(i>=359)then
--i<=0;
--end if;
--end if;

if(i >= 359) then
i <= 0;
end if;

if (j >= 359) then
j <= 0;
end if;


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

end Behavioral;
    
pregunta Anwesa Roy

2 respuestas

1

En lugar de

if(sec=50)then
    i <= i+170;
    if(i>=359)then
        i<=0;
    end if;
end if;

Deberías hacer algo como:

if(sec=50)then
    i <= i+170;
    if(i+170>359)then
        i<=i+170-360;
    end if;
end if;

Esto ajustará 360 de nuevo a 0 correctamente.

Otra opción es usar 'grados binarios' en su lugar, de modo que el rango completo de un valor de potencia de 2 corresponda a una rotación completa. Si utiliza un contador grande, puede obtener una alta resolución. El valor del recuento se ajustará naturalmente al desbordamiento, todo lo que necesita hacer es convertir sus pasos de fase en los valores binarios correspondientes. Esta técnica es muy común en la síntesis digital directa / osciladores controlados numéricamente, que es básicamente lo que estás implementando.

    
respondido por el alex.forencich
0

El problema es que "i" es una señal y no una variable, por lo que su nuevo valor no está disponible de inmediato. Por lo tanto, cuando tienes algo como

if(sec=50)then
    i <= i+170;
    if(i>=359)then
        i<=0;
    end if;
end if;

...

if(i >= 359) then
        i <= 0;
end if;

"i" se puede establecer más allá del rango de 359 si "i > 189" y no se leerá como tal hasta el siguiente ciclo de reloj, por lo tanto, las verificaciones no hacen lo que usted espera.

Querrá cambiar "> = 359" a "< 359" y, cuando realice los cambios de fase, compare con el valor mínimo que causará una reinversión DESPUÉS de la adición. Por lo tanto, en sec = 50 y sec = 100 use i > = 189 como condición.

    
respondido por el ks0ze

Lea otras preguntas en las etiquetas