OpenCores
URL https://opencores.org/ocsvn/modbus/modbus/trunk

Subversion Repositories modbus

[/] [modbus/] [trunk/] [enlace/] [gen_trama_top.vhd] - Rev 3

Compare with Previous | Blame | View Log

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
entity gen_trama_top is
	generic(
		addr_bits 	 : integer := 8 -- 2^addr_bits = numero bits de direccionamiento
	);
	port(
		clk			:in std_logic;
		reset		:in std_logic;
		end_gen		:out std_logic;
-- PicoBlaze
		cant_datos_picoB	:in std_logic_vector(7 downto 0);  -- cantidad de datos cargados en ram 
		picoB_ok		:in std_logic;	-- arrancar transmision (tomando datos desde ram)
-- ram
    	data_out_ram	:in  std_logic_vector(7 downto 0);  --dato leido desde ram
    	addr_ram		:out std_logic_vector(addr_bits-1 downto 0);  --dato leido desde ram
		E_ram		:out std_logic;  	-- habilitador de ram
		WE_ram		:out std_logic;  	-- habilitador de escritura ram: 0-lectura 1-escritura
-- uart
		send_done_uart	:in  std_logic;		-- aviso de dato enviado (por uart), seal habilitadora para obtener nuevo dato de ram
		data_in_uart	:out std_logic_vector(7 downto 0);  --dato leido desde ram
		send_data_uart	:out std_logic
	);
end gen_trama_top;
 
architecture Behavioral of gen_trama_top is
 
-- ********************* DECLARACION DE SEALES Y ESTADOS *****************************
   type state_type is (st1_espera, st2_dos_puntos, st3_lectura_ram, st4_ascii_H, st4_ascii_H_conver, st5_ascii_L, st5_ascii_L_conver, st6_fin_datos,st7_LRC_H, st7_LRC_H_conver, st8_LRC_L, st8_LRC_L_conver, st9_CR, st10_LF); 
	signal state, next_state : state_type; 
	signal Saddr 			:std_logic_vector (addr_bits-1 downto 0):=(others =>'0');  
	signal SE_ram 			:std_logic:='0';
	signal SWE_ram 		:std_logic:='0';
--	signal Sdata_in_uart	:std_logic_vector (7 downto 0):=(others =>'0');
	signal Ssend_data_uart	:std_logic:='0';
	signal Sst4_cont		:std_logic_vector(1 downto 0):="00";
	signal Sst5_cont		:std_logic_vector(1 downto 0):="00";
	signal Sst7_cont		:std_logic_vector(1 downto 0):="00";
	signal Sst8_cont		:std_logic_vector(1 downto 0):="00";
 
-- Seales CONVERSOR
	signal Sbin  		:std_logic_vector (7 downto 0):=(others =>'0');
   signal Sascii_H	:std_logic_vector (7 downto 0):=(others =>'0');
   signal Sascii_L 	:std_logic_vector (7 downto 0):=(others =>'0');
-- Seales LRC
	signal Slrc_bin	: std_logic_vector (7 downto 0):=(others =>'0');
	signal Strama		: std_logic:='0';	
	signal Q1, Q2, Q3, Q4, Q5	: std_logic:='0'; 	   -- seales auxiliares para obtener Snew_data e funcion de send_done (cadena Flip Flops)
	signal Snew_data_pre	: std_logic:='0';
	signal Snew_data	: std_logic:='0';
 
 
-- ***************** DECLARACION COMPONENTE GENERADOR LRC  ****************************
component gen_lrc
	port(
		clk		:in std_logic;	 				--clk
		reset	:in std_logic;					--reset
		new_data	:in std_logic;					--nuevo valor a leer
		trama	:in std_logic;					--suma vlida
		dato_trama:in std_logic_vector(7 downto 0);	--dato desde la ram
		lrc_bin	:out std_logic_vector(7 downto 0)	--valor del lrc calculado
	);
end component;
-- ***************** DECLARACION COMPONENTE CONVERSOR BIN A ASCII  ****************************
component bin_ascii
	port(
		clk		:in std_logic;
		reset	:in std_logic;
		bin		:in std_logic_vector(7 downto 0);
		ascii_h	:out std_logic_vector(7 downto 0);
		ascii_l	:out std_logic_vector(7 downto 0)
	);
end component;
 
 
begin
-- ***************** INSTANCIACION COMPONENTE GEN_LRC  ****************************
generador_lrc: gen_lrc
	port map(
		clk		=> clk,
		reset	=> reset,
		new_data	=> Snew_data,
		trama	=> Strama, 			--suma vlida (trama = '1')
		dato_trama => data_out_ram,		--dato desde la ram
		lrc_bin	=> Slrc_bin			--valor del lrc calculado
	);
-- ***************** INSTANCIACION COMPONENTE CONVERSOR  ****************************
conv_bin2ascii: bin_ascii
	port map(
		clk		=> clk,		
		reset	=> reset,
		bin		=> Sbin,	   	-- entrada del conversor
		ascii_h	=> Sascii_H,	
		ascii_l	=> Sascii_L
	);
--************ MAQUINA ESTADO: DESCRIPCION SINCRONIZAR CAMBIOS DE ESTADO **************	    
SYNC_PROC: process (clk,reset)
   begin
      if (reset='1') then
         state <= st1_espera;
      elsif (clk'event and clk = '1') then
         state <= next_state;
	    E_ram <= SE_ram;
	    WE_ram <= SWE_ram;
--    data_in_uart <= Sdata_in_uart;
--	    send_data_uart <= Ssend_data_uart;
      end if;
   end process;
 
 
--  data_in_uart <= Sdata_in_uart;
--************ MAQUINA ESTADO: DESCRIPCION EJECUCION EN LOS ESTADOS (SALIDAS) ***********
-- En los distintos estados se envian los caracteres de comienzo y fin de trama, lrc, y datos obtenidos de la RAM.
-- En el estos estados se usa send_done_uart solo para poder resetar las seales de "enviar dato" (send_data_uart) y las de RAM,
-- siempre que se cambia de estado es porque el dato anterior ya termino de enviarse.
OUTPUT_DECODE: process (state,send_done_uart) --send_done_uart = 1 == "envio realizado"
   begin
     if state = st2_dos_puntos then
		if send_done_uart = '0' then	   
			data_in_uart 	<= "00111010";	-- carga en la entrada de uart el dato a enviar: ':'	
		end if;
	end if;
 
	if state = st3_lectura_ram then	 --no se envian datos, se direcciona el elemento de la RAM
		if send_done_uart = '0' then	
			addr_ram 	<= Saddr;		-- direccion del elemento a enviar
			SE_ram 	<= '1';		-- hablita la RAM
			SWE_ram	<= '0';		-- habilita la Lectura
			Saddr <= Saddr + 1;           -- se incrementa el contador para luego acceder al proximo elemeto de RAM
		end if;
		Strama <= '1';
     end if;
 
	if state = st4_ascii_H then
		if send_done_uart = '0' then
			data_in_uart 	<= Sascii_H;	-- parte alta del dato covertido
			Snew_data_pre <= '1';
		end if;
	end if;
 
	if state = st5_ascii_L then
		if send_done_uart = '0' then
			data_in_uart 	<= Sascii_L;	-- parte alta del dato covertido
			Snew_data_pre <= '0';
     	end if;
	end if;
 
	if state = st6_fin_datos then
		Strama <= '0';
		SE_ram 	<= '0';		-- deshabilita la RAM
		SWE_ram	<= '0';		-- (se mantiene siempre habilitada la lectura de la RAM)
	end if;
 
	if state = st7_LRC_H then
	    	data_in_uart 	<= Sascii_H;	-- parte alta del dato covertido	
	end if;
 
	if state = st8_LRC_L then
	    		data_in_uart 	<= Sascii_L;	-- parte alta del dato covertido
	end if;
 
   if state = st9_CR then
  		data_in_uart 	<= "01000010";--"00001101";	-- carga en la entrada de uart el dato a enviar: CR
   end if;
   if state = st10_LF then
    	data_in_uart 	<= "01000001";--"00001010";
		end_gen	<= '1';
	else
		end_gen <= '0';
   end if;
 
 
end process;
 
send_232:process(clk,state,send_done_uart)
begin
	if clk'event and clk = '1' then
		if (state=st2_dos_puntos or state = st4_ascii_H or state = st5_ascii_L or state = st7_LRC_H or	state = st8_LRC_L or state = st9_CR or state = st10_LF) then
			if send_done_uart = '0' then
	 			Ssend_data_uart	<= '1';        -- seal que da la orden a la uart para enviar el dato
	 		else
				Ssend_data_uart	<= '0';
	 		end if;
     	end if;
	end if;
end process;
 
send_data_uart <= Ssend_data_uart;
 
--************ MAQUINA ESTADO: DESCRIPCION ESTADO SIGUIENTE ***********************
NEXT_STATE_DECODE: process (Saddr, Sst4_cont,Sst5_cont, state, send_done_uart, picoB_ok)
begin
      next_state <= state;  					--default is to stay in current state
      case (state) is
			when st1_espera =>					--estado de espera, comienza la secuencia de estados cuado
				if picoB_ok = '1' then 			-- el pico blaze termina de cargar RAM
					next_state <= st2_dos_puntos;	-- se pasa a los estados que envan la trama
            end if;
         when st2_dos_puntos =>
	    		if send_done_uart = '1' then		--cuando se termina de enviar ":" se pasa al estado 3
					next_state <= st3_lectura_ram;
				end if;
         when st3_lectura_ram =>				-- se pasa a otro estado independientemente de send_done_uart ya que st3 no se envia ningn dato
				if Saddr < cant_datos_picoB then	-- se recorre la RAM hasta el ltimo elemento dispuesto por pico blaze 
					next_state <= st4_ascii_H_conver;	-- se va a enviar la parte alta del correspondiente elemento de RAM
				else 			
					next_state <= st6_fin_datos;-- cuando se termina de recorrer los elementos de la RAM se envia el LRC
				end if;
			when st4_ascii_H_conver =>
				if Sst4_cont > "10" then
					next_state <= st4_ascii_H;
				end if;
			when st4_ascii_H =>
				if send_done_uart = '1' then		-- cuando se termina de enviar la parte alta del correspondiente elemento, pasa a enviar la parte baja
					next_state <= st5_ascii_L_conver;	
				end if;
			when st5_ascii_L_conver =>
				if Sst5_cont > "10" then
					next_state <= st5_ascii_L;
				end if;
			when st5_ascii_L =>					
				if send_done_uart = '1' then		-- cuando se envi la parte baja volvemos al st3 a buscar otro elemento a enviar
					next_state <= st3_lectura_ram;	
				end if;
			when st6_fin_datos =>
				next_state <= st7_LRC_H_conver;
			when st7_LRC_H_conver =>
				next_state <= st7_LRC_H;
			when st7_LRC_H =>	
				if send_done_uart = '1' then	
					next_state <= st8_LRC_L_conver;
				end if;
			when st8_LRC_L_conver =>
				next_state <= st8_LRC_L;
			when st8_LRC_L =>	
				if send_done_uart = '1' then	
					next_state <= st9_CR;		-- cuando se termina de enviar el LRC se envia caracteres de fin de trama
				end if;
			when st9_CR =>
				if send_done_uart = '1' then
					next_state <= st10_LF;
				end if;
			when st10_LF =>
				if send_done_uart = '1' then		-- cuando se termina de enviar trama se vuelve a st1_espera
					next_state <= st1_espera;
				end if;
         when others =>
            next_state <= st1_espera;
			end case;      
end process;
 
 
 
process(clk)
begin
	if clk'event and clk = '1' then
		if state = st4_ascii_H_conver then
			Sst4_cont <= Sst4_cont + 1;
		else
			Sst4_cont <= "00";
		end if;
	end if;
end process;
 
 
process(clk)
begin
	if clk'event and clk = '1' then
		if state = st5_ascii_L_conver then
			Sst5_cont <= Sst5_cont + 1;
		else
			Sst5_cont <= "00";
		end if;
	end if;
end process;
 
process(clk)
begin
	if clk'event and clk = '1' then
		if state = st7_LRC_H_conver then
			Sst7_cont <= Sst7_cont + 1;
		else
			Sst7_cont <= "00";
		end if;
	end if;
end process;
 
process(clk)
begin
	if clk'event and clk = '1' then
		if state = st8_LRC_L_conver then
			Sst8_cont <= Sst8_cont + 1;
		else
			Sst8_cont <= "00";
		end if;
	end if;
end process;
 
 
-- ************** FLIP FLOPS PARA GENERAR Snew_data *******************
-- Snew_data es la seal que le idica al componente "generar LRC", que tome y sume un 
-- nuevo dato que tiene presente en la entrada.  Sigue a Send_done pero retrasado 
-- tres pulsos de clock, tiempo suficiente para que aparezca el dato a la entrada del
-- componente gen_LRC.
 
process(clk, reset)
begin
  if (reset = '1') then
    Q1 <= '0';
    Q2 <= '0';
    Q3 <= '0';
    Q4 <= '0';
    Q5 <= '0';
  elsif (clk'event and clk = '1') then
    Q1 <= Snew_data_pre;
    Q2 <= Q1;
    Q3 <= Q2;
    Q4 <= Q3;
    Q5 <= Q4;
  end if;
end process;
 
Snew_data <= Q1 and Q2 and Q3 and Q4 and (not Q5);
 
--******************************************************************
 
--************ MUX *************************
Sbin <= data_out_ram when Strama = '1' else 
		Slrc_bin; 
--******************************************
 
end Behavioral;

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.