Haz una pregunta
  Foros de Electrónica » Diseño digital » Circuitos lógicos combinacionales y secuenciales
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

04/07/2013 #1


conv_integer a tipo bit
Hola soy nuevo en este foro, tengo un problema quiza sea un poco de entendimiento en cuanto a la funcion conv_integer tengo que realizar un scanner de datos y quiero sustituir esta funcion, lo que pasa es que no debo de utilizar la funcion de la IEEE. Me podrian auxiliar para hacerlo sin dicha libreria. Es por eso que debo de utilizar los datos de tipo bit y no std_logic
De antemano muchas gracias un saludo
04/07/2013 #2

Avatar de chclau

Tendrias que explicar un poco mas lo que tenes que hacer, asi como esta planteado parece un problema del colegio o de la universidad, asi que lo mejor seria que pongas el enunciado entero.

Y para que el tema no vaya a moderacion, inclui tambien lo que hiciste hasta ahora. Si no hiciste nada... la pregunta va a caer en moderacion.
04/07/2013 #3


OK. eso es lo que quisiera realmente, usando tipos de dato bit poder hacer la conversion a entero sin utilizar la funcion conv_integer digamos que de entero a bit o viceversa. Espero ser un poco mas claro. Agradesco de antemano espero pronto tener el codigo y adjuntarlo. Gracias
04/07/2013 #4

Avatar de chclau

Las bibliotecas de la IEEE son de codigo abierto, anda a la Internet, busca la biblioteca std_logic_arith donde esta definida conv_integer y analiza como lo hace para los tipos signed o unsigned, y adaptalo para bit_vector.

Se puede preguntar por que necesitas hacer esto, si es un ejercicio o es por otra razon? Porque si es para implementarlo en un FPGA, no tiene sentido inventarse sus propias funciones. Ademas, las bibliotecas std_logic_arith estan un poco en desuso, hoy se prefiere la numeric_std.

Saludos
05/07/2013 #5


Ok gracias lo buscare. Es para un proyecto escolar y si efectivamente es para implementar en un FPGA mas concretamente Nexys 3, y precisamente digamos que no se pueden utilizar librerias de la IEEE lo mismo me paso con el operador '+' pero ese creo que ya esta resuelto. Gracias y espero me puedan seguir ayudando.
05/07/2013 #6

Avatar de chclau

Crearte tus propias bibliotecas es el ultimo recurso. Yo jamas lo hice.

Tendrias que explicarme un poco mas que problemas tuviste con el operador de suma. El tema de uso de enteros con y sin signo y bibliotecas puede ser un poco arido al comienzo pero tiene solucion... y la solucion NO pasa por inventarte bibliotecas... con eso vas a tener a la larga mas problemas durante la sintesis del FPGA.
05/07/2013 #7


Muy Bien, agradesco mucho tu ayuda este es mi codigo utilizando el tipo de dato std_logic digamos que solo lo tengo que cambiar tipo bit:

Código:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Scanner is
    Port ( Clk : in  STD_LOGIC; --Filo de subida
           Rst : in  STD_LOGIC; --Activo Alto
           S0 : in  STD_LOGIC; --Control del Barrido
           S1 : in  STD_LOGIC; --Control para read o write puntual
           S2 : in  STD_LOGIC; --Control de busqueda
           S3 : in  STD_LOGIC; --Lectura o escritura
           SW : in  STD_LOGIC_VECTOR (7 downto 0); --Entrada de datos y direcciones
           ADDRS_out : out  STD_LOGIC_VECTOR (4 downto 0); --Salidas
           Dout : out  STD_LOGIC_VECTOR (7 downto 0)); --Salida del dato buscado
end entity Scanner;

architecture arq_scanner of Scanner is
    type ram_type is array (0 to 31) of std_logic_vector (7 downto 0);
    signal ram_32x8 : ram_type := (others => (others => '0'));
    signal data_memread: std_logic_vector (7 downto 0);
    signal we: std_logic;
    type edos is (IDLE, BARRIDO, PUNTUAL, SCAN);
    signal ep: edos := IDLE;
    signal addrs: std_logic_vector (4 downto 0) := "00000";
begin
    U_Control: process (Clk)
    begin
        if Clk'event and Clk = '1' then
            if Rst = '1' then ep <= IDLE;
            else
                case ep is when IDLE =>
                    if S0='1' then ep <= BARRIDO;
                    elsif S1='1' then ep <= PUNTUAL;
                    elsif S2='1' then ep <= SCAN; end if;
                              when BARRIDO =>
                    if S0='0' then ep <= IDLE; end if;
                              when PUNTUAL =>
                    if S1='0' then ep <= IDLE; end if;  
                              when SCAN =>
                    if S2='0' then ep <= IDLE; end if;
                end case;
         end if;                
        end if;    
    end process U_Control;

    rg_addrs: process(Clk)
    begin
        if Clk'event and Clk='1' then
        if Rst = '1' then addrs <= "00000";
        elsif (ep=IDLE and S0='1') then addrs <= "00000";
        elsif (ep=IDLE and S1='1') then addrs <= SW (4 downto 0);
        elsif (ep=IDLE and S2='0') then addrs <= "00000";
        elsif (ep=BARRIDO and S0='1') then addrs <= addrs + 1;        
        elsif (ep=SCAN and data_memread /= SW) then addrs <= addrs + 1;
        end if;
        end if;
    end process rg_addrs;

    data_memread <= ram_32x8 (conv_integer(addrs));
    sinc:process(Clk)
    begin
        if Clk'event and Clk='1' then
            if WE = '1' then
                ram_32x8 ( conv_integer(addrs)) <= SW;        
        end if;
        end if;
    end process sinc;
    ---------------------------------------------------------
    ------ Fin de la escritura de la RAM .....
    WE <= '1' when (ep = BARRIDO and S3 = '1') or
                   (ep = PUNTUAL and S3 = '1') else '0';
    --------------------------------------------------------
    ADDRS_out <= addrs;
    --------------------------------------------------------
    Dout <= data_memread;
end arq_scanner;
Para el operador '+' hago lo siguiente ha funcionado en otros programas:
function "+" (L: bit_vector; R: bit_vector) return bit_vector is
variable suma: bit_vector (L'range);
variable b: bit_vector (R'length - 1 downto 0);
variable c: bit;
begin
b := R;
c := '0';
for i in 0 to L'High loop
suma(i):= L(i) xor b(i) xor C;
c:= (L(i) and b(i)) or (L(i) and c) or (b(i) and C);
end loop;
return suma;
end function;
Alguna sugerencia para implementarlo en la FPGA con displays, etc.
Soy bastante inexperto en este lenguaje, quiza del tambien por eso de mis problemas. Gracias nuevamente, un Saludo
05/07/2013 #8

Avatar de chclau

Dos sugerencias:

1) La tarjeta que vas a usar tiene un FPGA de Xilinx. Busca una nota de aplicacion de ellos sobre como inferir memorias, que codigo VHDL utilizar.

2) Por lo que veo la funcion suma la usas para indexar la memoria. Nuevamente, siguiendo con las indicaciones de Xilinx veras ahi como realizarlo. Por empezar es factible realizar operaciones de suma con std_logic_vector, si te salta un error es porque estas usando la funcion o la biblioteca equivocada. Empeza por (1) y despues hablamos de la suma, si todavia tenes problemas.
05/07/2013 #9


Hola un saludo para decirte que he ingresado las funciones de suma y de integer con lo cual obtengo el siguiente codigo, pero con errores me podrias decir cual es los indico en el programa:

Código:
entity Scanner_bit is
    Port ( Clk : in  bit;
           Rst : in  bit;
           S0 : in  bit;
           S1 : in  bit;
           S2 : in  bit;
           S3 : in  bit;
           SW : in  bit_VECTOR (7 downto 0);
           ADDRS_out : out  bit_VECTOR (4 downto 0);
           Dout : out  bit_VECTOR (7 downto 0));
end entity Scanner_bit;


architecture arq_scanner_bit of Scanner_bit is

    function "+" (L: bit_vector; R: bit_vector) return bit_vector is
      variable suma: bit_vector (L'range);
      variable b: bit_vector (R'length - 1 downto 0);
      variable c: bit;
    begin
      b := R;
      c := '0';
      for i in 0 to L'High loop
       suma(i):= L(i) xor b(i) xor C;
       c:= (L(i) and b(i)) or (L(i) and c) or (b(i) and C);
      end loop;
      return suma;
    end function;
    
    function conver_integer (BV: bit_vector) return integer is
        variable numint: integer;
        variable bvector: bit_vector (BV'range);
    begin
        bvector := BV;
        numint := 0;
        for i in 0 to bvector'high loop
            if bvector (i) = '1' then
                numint := numint + 2**i;
            end if;
        end loop;
    return numint;
    end function conver_integer;
    
    type ram_type is array (0 to 31) of bit_vector (7 downto 0);
    signal ram_32x8 : ram_type := (others => (others => '0'));
    signal data_memread: bit_vector (7 downto 0);
    signal we: bit;
    
    type edos is (IDLE, BARRIDO, PUNTUAL, SCAN);
    signal ep: edos := IDLE;
    signal addrs: bit_vector (4 downto 0) := "00000";
    
begin
    U_Control: process (Clk)
    begin
        if Clk'event and Clk = '1' then
            if Rst = '1' then ep <= IDLE;
            else
                case ep is when IDLE =>
                    if S0='1' then ep <= BARRIDO;
                    elsif S1='1' then ep <= PUNTUAL;
                    elsif S2='1' then ep <= SCAN; end if;
                              when BARRIDO =>
                    if S0='0' then ep <= IDLE; end if;
                              when PUNTUAL =>
                    if S1='0' then ep <= IDLE; end if;  
                              when SCAN =>
                    if S2='0' then ep <= IDLE; end if;
                end case;
         end if;                
        end if;    
    end process U_Control;
    
    
    rg_addrs: process(Clk)
    begin
        if Clk'event and Clk='1' then
            if Rst = '1' then addrs <= "00000";
            elsif (ep=IDLE and S0='1') then addrs <= "00000";
            elsif (ep=IDLE and S1='1') then addrs <= SW (4 downto 0);
            elsif (ep=IDLE and S2='0') then addrs <= "00000";
            
            -------------------------------------------------------------------
            elsif (ep=BARRIDO and S0='1') then addrs <= addrs + 1;              --ERROR
            elsif (ep=SCAN and data_memread /= SW) then addrs <= addrs + 1;  --ERROR
            -------------------------------------------------------------------
            
            end if;
        end if;
    end process rg_addrs;
    
    data_memread <= ram_32x8 (conver_integer(addrs));

    sinc:process(Clk)
    begin
        if Clk'event and Clk='1' then
            if WE = '1' then
                ram_32x8 ( conver_integer(addrs)) <= SW;        
        end if;
        end if;
    end process sinc;
    WE <= '1' when (ep = BARRIDO and S3 = '1') or
                   (ep = PUNTUAL and S3 = '1') else '0';
                        
    ADDRS_out <= addrs;
    Dout <= data_memread;
end arq_scanner_bit;

Te indico los errores en comentarios arriba y a l hora de checar la sintaxis me indica lo siguiente:
Line 82: Type bit_vector does not match with the integer literal
Line 83: Type bit_vector does not match with the integer literal
De antemano muchas gracias un saludo
05/07/2013 #10

Avatar de chclau

Te recomiendo que pases tu diseño a std_logic y std_logic_vector y te recuerdo lo que te puse en el mensaje anterior, busca una nota de aplicacion de Xilinx sobre como se infieren memorias.

Suerte!
05/07/2013 #11


Me gustaría pasar el diseño a std_logic pero es parte del trabajo no usar la librería de la IEEE, porque el código ya lo tengo. Un ultimo favor espero me pudieras ayudar a hacer un barrido para mostrar las salidas en los displays en el ultimo process como te mencione de una nexys 3, y es que me cuesta trabajo hacerlo

Código:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL; --Por la funcion +

entity Scanner is
    Port ( Clk : in  STD_LOGIC;
           Rst : in  STD_LOGIC;
           S0 : in  STD_LOGIC;
           S1 : in  STD_LOGIC;
           S2 : in  STD_LOGIC;
           S3 : in  STD_LOGIC;
           SW : in  STD_LOGIC_VECTOR (7 downto 0);
              
              LED1, LED2 : out STD_LOGIC_VECTOR (6 downto 0);
              AN : out STD_LOGIC_VECTOR (3 downto 0);
              
           ADDRS_out : out  STD_LOGIC_VECTOR (4 downto 0));
end entity Scanner;
architecture arq_scanner of Scanner is

    type ram_type is array (0 to 31) of std_logic_vector (7 downto 0);
    signal ram_32x8 : ram_type := (others => (others => '0'));
    signal data_memread: std_logic_vector (7 downto 0);
    signal we: std_logic;

    type edos is (IDLE, BARRIDO, PUNTUAL, SCAN);
    signal ep: edos := IDLE;

    signal addrs: std_logic_vector (4 downto 0) := "00000";

    signal Dout : std_logic_vector (7 downto 0);
begin
    U_Control: process (Clk)
    begin
        if Clk'event and Clk = '1' then
            if Rst = '1' then ep <= IDLE;
            else
                case ep is when IDLE =>
                    if S0='1' then ep <= BARRIDO;
                    elsif S1='1' then ep <= PUNTUAL;
                    elsif S2='1' then ep <= SCAN; end if;
                              when BARRIDO =>
                    if S0='0' then ep <= IDLE; end if;
                              when PUNTUAL =>
                    if S1='0' then ep <= IDLE; end if;  
                              when SCAN =>
                    if S2='0' then ep <= IDLE; end if;
                end case;
         end if;                

        end if;    
    end process U_Control;

    rg_addrs: process(Clk)
    begin
        if Clk'event and Clk='1' then
        if Rst = '1' then addrs <= "00000";
        elsif (ep=IDLE and S0='1') then addrs <= "00000";
        elsif (ep=IDLE and S1='1') then addrs <= SW (4 downto 0);
        elsif (ep=IDLE and S2='0') then addrs <= "00000";
        elsif (ep=BARRIDO and S0='1') then addrs <= addrs + 1;        
        elsif (ep=SCAN and data_memread /= SW) then addrs <= addrs + 1;
        end if;
        end if;
    end process rg_addrs;
    data_memread <= ram_32x8 (conv_integer(addrs));

    sinc:process(Clk)
    begin
        if Clk'event and Clk='1' then
            if WE = '1' then
                ram_32x8 ( conv_integer(addrs)) <= SW;        
        end if;
        end if;
    end process sinc;

    WE <= '1' when (ep = BARRIDO and S3 = '1') or
                   (ep = PUNTUAL and S3 = '1') else '0';

    ADDRS_out <= addrs;

    Dout <= data_memread;
    
    with Dout (3 downto 0) SELect
   LED1<= "1111001" when "0001",   --1
         "0100100" when "0010",   --2
         "0110000" when "0011",   --3
         "0011001" when "0100",   --4
         "0010010" when "0101",   --5
         "0000010" when "0110",   --6
         "1111000" when "0111",   --7
         "0000000" when "1000",   --8
         "0010000" when "1001",   --9
         "0001000" when "1010",   --A
         "0000011" when "1011",   --b
         "1000110" when "1100",   --C
         "0100001" when "1101",   --d
         "0000110" when "1110",   --E
         "0001110" when "1111",   --F
         "1000000" when others;   --0
            
    with Dout (7 downto 4) SELect
   LED2<= "1111001" when "0001",   --1
         "0100100" when "0010",   --2
         "0110000" when "0011",   --3
         "0011001" when "0100",   --4
         "0010010" when "0101",   --5
         "0000010" when "0110",   --6
         "1111000" when "0111",   --7
         "0000000" when "1000",   --8
         "0010000" when "1001",   --9
         "0001000" when "1010",   --A
         "0000011" when "1011",   --b
         "1000110" when "1100",   --C
         "0100001" when "1101",   --d
         "0000110" when "1110",   --E
         "0001110" when "1111",   --F
         "1000000" when others;   --0
    process(Clk)
    begin
    if Clk'event and Clk='1' then
        

    end if;
    end process;

end arq_scanner;
Muchas gracias por tu ayuda
05/07/2013 #12

Avatar de chclau

Compile tu proyecto y al parecer esta todo bien. Disculpa, por lo que veo tambien sacas la salida a dos displays de siete segmentos, entonces, no entiendo bien que es lo que te estaria faltando, a que barrido te refieres?
05/07/2013 #13


Precisamente el barrido para los displays o cres que asi funcione correctamente??.
Me parece que habria que hacer un barrido o divisor de frecuencias para que no haya problema al implememtarlo a la FPGA. Ya que en ocasiones me ha pasado que los displays no funcionana correctamente???
Gracias nuevamente un saludo.
06/07/2013 #14

Avatar de chclau

Si, tenes razon, que tonto. Ya te ayudo, mientras paseaba con el perro me di cuenta de que tonta fue mi respuesta. Ahora preparo algo y te lo mando.


---------- Actualizado después de 24 minutos ----------

Aca te pongo un proceso que hace el display. Incluilo en tu codigo o usalo como componente.

Código:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL; 

entity display_mux is
    Port 
    ( 
	Clk : in  STD_LOGIC;
        Rst : in  STD_LOGIC;
        din : in STD_LOGIC_VECTOR(7 downto 0);
              
        leds : out STD_LOGIC_VECTOR(6 downto 0);
        sel  : out STD_LOGIC_VECTOR(1 downto 0)           
    );
end entity display_mux;

architecture rtl of display_mux is

	signal decode : STD_LOGIC_VECTOR(3 downto 0);
	signal sel_i  : STD_LOGIC;
	
begin
    disp: process (Clk)
    begin
        if Clk'event and Clk = '1' then
            if Rst = '1' then 
		sel_i 	<= '0';
	    end if;	
        else
		sel_i <= not sel_i;
        end if;    
    end process disp;
    
	decode <= din(3 downto 0) when sel_i ='0' else
			 din(7 downto 4);
	sel    <= "10" when sel_i = '0' else
		      "01";
	
   with decode(3 downto 0) SELect
   leds <= 
	"1111001" when "0001",   --1
        "0100100" when "0010",   --2
        "0110000" when "0011",   --3
        "0011001" when "0100",   --4
        "0010010" when "0101",   --5
        "0000010" when "0110",   --6
        "1111000" when "0111",   --7
        "0000000" when "1000",   --8
        "0010000" when "1001",   --9
        "0001000" when "1010",   --A
        "0000011" when "1011",   --b
        "1000110" when "1100",   --C
        "0100001" when "1101",   --d
        "0000110" when "1110",   --E
        "0001110" when "1111",   --F
        "1000000" when others;   --0            

end rtl;
06/07/2013 #15


OK. muchas gracias nuevamente por tu ayuda lo intentare agregar al diseño. Espero poder hacerlo bien y te contare como va. Gracias, nuevamente un saludo
06/07/2013 #16


Disculpa dentro de la expresion del flanco del process disp no tendria que depender del Reloj (Clk) y no del Reset(Rst)???
Gracias un saludo
06/07/2013 #17

Avatar de chclau

Eso es un reset síncrono, que utilicé porque vi que vos habías hecho lo mismo para otros procesos.

Lo que yo hago en mis proyectos es utilizar reset asíncrono, pero sincronizar la subida del reset al reloj. Es algo muy común, tiene la ventaja de que hay reset aunque no haya clock, pero el reset es también síncrono al reloj.
06/07/2013 #18


Ok gracias entonces es el mismo rst que he utilizado en los otros procesos, bueno lo implementara un poco mas tarde y te dire como va para poder implementarlo en el FPGA.
Saludos!!!!
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Buscar más temas sobre:
Lupa Circuitos lógicos combinacionales y secuenciales

Compuertas, flips flops, registros, PLDs, codificadores, contadores, multiplexores, ...

Cerrar
Foros de Electrónica » Diseño digital » Circuitos lógicos combinacionales y secuenciales

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.