¿Cómo usar el valor presente y anterior de una señal para este código VHDL?

1

Necesitamos el valor presente y anterior de la señal noisysignal1 para calcular ciertas ecuaciones. Una de las ecuaciones es y[i] = noisysignal1[i]*w1 + noisysignal1[i-1]*w2; . ¿Cómo podemos usar el valor presente y anterior de noisysignal1 al mismo tiempo en nuestro código VHDL?

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.math_real.all;
use IEEE.STD_LOGIC_Unsigned.ALL;

use IEEE.NUMERIC_STD.ALL;
entity random is
  generic (
    width : integer :=  32; 
    nn : natural := 1; -- power of the binomial distribution <16
    m : REAL := 0.0    -- mean output value
  ); 
  port (
    clk : in std_logic;
    random_num : out std_logic_vector (width-1 downto 0);   --output vector
    RST : in STD_LOGIC;
    DATA_OUT : out REAL := 0.0            
  );
end random;

architecture Behavioral of random is
  type arri is array (0 to 15) of integer;
  type arrr is array (0 to 15) of real;
  signal noisysignal1 : real;
begin
  process(clk,rst)
    variable rand_temp : std_logic_vector(width-1 downto 0) := (width-1 => '1',others => '0');
    variable temp : std_logic := '0';

    variable s1 : arri := (3,33,333,3,4,5,6,7,8,9,11,22,33,others=>55);
    variable s2 : arri := (5,55,555,50,6,7,8,9,5,6,7,21,33,others=>22);
    variable r : arrr := (others=>0.0);
    variable s : real := 0.0;

    variable noisysignal : real; 
    begin
      if rst='1' then
        DATA_OUT <= 0.0;
      elsif rising_edge(clk) then
        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;

        s := 0.0;
        for i in 0 to nn-1 loop    -- nn noise generators
          UNIFORM (s1(i),s2(i),r(i));
          s := s+r(i);
        end loop;
        DATA_OUT <= 2.0*(s/real(nn)-0.5) + m;
        noisysignal := real(to_integer(signed(rand_temp))) + ( 2.0 * (s/real(nn)-0.5) + m);
        noisysignal1 <= noisysignal;
      end if;
    random_num <= rand_temp;
  end process;
end Behavioral;
    
pregunta Anwesa Roy

4 respuestas

1

Tienes que registrar noisysignal1 una vez. Aquí está el código resultante. El registro es noisysignal1_r . Luego puedes usar y = noisysignal1*w1 + noisysignal1_r*w2 .

Espero haber entendido lo que quieres.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.math_real.all;
use IEEE.STD_LOGIC_Unsigned.ALL;

use IEEE.NUMERIC_STD.ALL;
entity random is
  generic
  (
    width : integer :=  32; 
    nn : natural := 1; --power of the binomial distribution <16
    m : REAL:=0.0     -- mean output value
  ); 
  port
  (
    clk : in std_logic;
    random_num : out std_logic_vector (width-1 downto 0);   --output vector
    RST : in STD_LOGIC;
    DATA_OUT : out REAL := 0.0            
  );
end random;

architecture Behavioral of random is
  type arri is array (0 to 15) of integer;
  type arrr is array (0 to 15) of real;
  signal noisysignal1, noisysignal1_r : real;
begin
  process(clk,rst)
    variable rand_temp : std_logic_vector(width-1 downto 0) := (width-1 => '1', others => '0');
    variable temp : std_logic := '0';

    variable s1 : arri := (3,33,333,3,4,5,6,7,8,9,11,22,33,others=>55);
    variable s2 : arri := (5,55,555,50,6,7,8,9,5,6,7,21,33,others=>22);
    variable r : arrr := (others=>0.0);
    variable s : real := 0.0;

    variable noisysignal : real;

  begin
    if rst='1' then
      DATA_OUT <= 0.0;
    elsif rising_edge(clk) then
      noisysignal1_r <= noisysignal1;
      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;

      s := 0.0;
      for i in 0 to nn-1 loop    -- nn noise generators
        UNIFORM (s1(i),s2(i),r(i));
        s := s+r(i);
      end loop;
      DATA_OUT <= 2.0*(s/real(nn) - 0.5) + m;
      noisysignal :=real (to_integer(signed(rand_temp))) + ( 2.0*(s/real(nn) - 0.5) + m);
      noisysignal1 <= noisysignal;
    end if;
    random_num <= rand_temp;
  end process;
end Behavioral;
    
respondido por el Renato
0

Más allá de simplemente crear una variable temporal, la forma más sencilla sería utilizar el atributo last_value, que proporciona el último valor asignado a esa señal. Ej:

y[i] = noisysignal1[i]*w1 + noisysignal1[i]'last_value * w2;

Puede leer más aquí , aunque es posible que algunas herramientas de síntesis no lo reconozcan. Simula y sintetiza en Vivado 2014.2.

    
respondido por el Drew
0

Solo necesitas registrar las señales.

Un registro almacenará los datos de un ciclo a otro (activado mediante una declaración de borde ascendente @). Cada registro en una cadena empujará los datos un ciclo más atrás.

La salida de un registro en el ciclo actual será el valor ingresado en el ciclo anterior.

Si necesita recuperar los datos de dos ciclos, puede poner otro registro en la salida del primer [registro], empujando su salida un ciclo más.

    
respondido por el jbord39
0

¿No podría agregar una señal noisysignal1_old además de su señal noisysignal1, y luego al final de su bucle for asigna noisysignal1 a noisysignal1_old? De esta manera, el bucle podría calcular la ecuación con el valor presente y el valor anterior de noisysignal.

    
respondido por el Asct20

Lea otras preguntas en las etiquetas