Codice vhdl per uart RS232
 Posted: 21 Nov 2012, 10:32
Posted: 21 Nov 2012, 10:32Ciao a tutti, mi sto impelagando nella simulazione di una porta uart RS232 che prenda 8 bit in ingresso , e me li restituisca in uscita ( in seguito vorrei mandare i dati ad un display ma questo in una fase successiva).
Ho implementato il codice dopo avere cercato di capire a fondo il suo funzionamento su internet, ma non riesco in modelsim a settare i parametri giusti per potere ottenere i bit esatti in uscita. Io forzo ad 1 i parametri Rx,Tx, DSR ( segnala che la periferica è pronta ad operare) e CTS( il canale dati è pronto per la trasmissione), il resto a zero ed il clock a 50 Mhz(con un divisore). Il reset funziona perfettamente invece (l'ho predisposto come suggerito da flz ).
).
Spero in un vostro aiuto e allego il codice qui di seguito.
			Ho implementato il codice dopo avere cercato di capire a fondo il suo funzionamento su internet, ma non riesco in modelsim a settare i parametri giusti per potere ottenere i bit esatti in uscita. Io forzo ad 1 i parametri Rx,Tx, DSR ( segnala che la periferica è pronta ad operare) e CTS( il canale dati è pronto per la trasmissione), il resto a zero ed il clock a 50 Mhz(con un divisore). Il reset funziona perfettamente invece (l'ho predisposto come suggerito da flz
 ).
).Spero in un vostro aiuto e allego il codice qui di seguito.
- Code: Select all
- --RS232
 library IEEE;
 use IEEE.STD_LOGIC_1164.ALL;
 use IEEE.STD_LOGIC_ARITH.ALL;
 use IEEE.STD_LOGIC_UNSIGNED.ALL;
 entity rs_232 is
 port ( Rx : in std_logic;
 Clock : in std_logic;
 Reset : in std_logic;
 CTS : in std_logic;
 DTR_in : in std_logic;
 Data_in : in std_logic_vector (7 downto 0);
 DSR : in std_logic;
 RTS_in : in std_logic;
 RTS_out : out std_logic;
 DTR_out : out std_logic;
 Tx : out std_logic;
 Data_out: out std_logic_vector (7 downto 0)
 );
 end rs_232;
 
 architecture behavioral of rs_232 is
 
 component Div_clk
 port(
 clk_in : in std_logic;
 reset : in std_logic; -- reset asincrono
 clk_out : out std_logic
 );
 
 end component;
 component uart
 port (
 
 clk_div :in std_logic;
 reset :in std_logic;
 ld_tx_data :in std_logic;
 tx_data :in std_logic_vector (7 downto 0);
 tx_enable :in std_logic;
 rx_enable :in std_logic;
 uld_rx_data :in std_logic;
 rx_in :in std_logic;
 tx_out :out std_logic;
 rx_data :out std_logic_vector (7 downto 0)
 
 );
 
 end component;
 signal div_clk_1 : std_logic;
 signal DTR_1 : std_logic;
 signal RTS_1 : std_logic;
 
 begin
 
 uart_component : uart port map ( reset => reset,
 clk_div => div_clk_1,
 ld_tx_data => DTR_in,
 tx_data => Data_in,
 tx_enable => RTS_in,
 tx_out => Tx,
 uld_rx_data => DSR,
 rx_data => Data_out,
 rx_enable => CTS,
 rx_in => Rx
 );
 
 clock_component : Div_clk port map ( clk_in => Clock,
 reset => reset,
 clk_out => div_clk_1
 );
 
 DTR_1 <= DTR_in;
 RTS_1 <= RTS_in;
 DTR_out <= DTR_1;
 RTS_out <= RTS_1;
 
 end architecture;
 
- Code: Select all
- --Divisore Clock
 library IEEE;
 use IEEE.STD_LOGIC_1164.ALL;
 use IEEE.STD_LOGIC_ARITH.ALL;
 use IEEE.STD_LOGIC_UNSIGNED.ALL;
 entity Div_clk is
 
 port(
 clk_in : in std_logic; -- Input Clock
 reset : in std_logic; -- reset asincrono
 clk_out : out std_logic -- uscita
 );
 
 end Div_clk;
 architecture Behavioral of Div_clk is
 signal clk_flag : std_logic := '0';
 begin
 process (clk_in, reset)
 variable count : integer :=1;
 begin
 if (clk_in 'event ) and (clk_in ='1') then
 if (reset = '1') then
 count := 0;
 end if;
 
 if (count mod 10)= 0 then
 clk_flag <= not clk_flag;
 end if;
 
 if (count = 10) then
 count :=1;
 
 else
 count := count + 1;
 end if;
 end if;
 end process;
 clk_out <= clk_flag;
 end Behavioral;
- Code: Select all
- --uart
 library IEEE;
 use IEEE.STD_LOGIC_1164.ALL;
 use IEEE.STD_LOGIC_ARITH.ALL;
 use IEEE.STD_LOGIC_UNSIGNED.ALL;
 entity uart is
 port (
 
 clk_div :in std_logic;
 reset :in std_logic;
 ld_tx_data :in std_logic;
 tx_data :in std_logic_vector (7 downto 0);
 tx_enable :in std_logic;
 rx_enable :in std_logic;
 uld_rx_data :in std_logic;
 rx_in :in std_logic;
 tx_out :out std_logic;
 rx_data :out std_logic_vector (7 downto 0)
 
 );
 
 end entity;
 architecture rtl of uart is
 signal tx_reg : std_logic_vector (7 downto 0);
 signal tx_cnt : std_logic_vector (3 downto 0);
 signal rx_reg : std_logic_vector (7 downto 0);
 signal rx_sample_cnt : std_logic_vector (3 downto 0);
 signal rx_cnt : std_logic_vector (3 downto 0);
 signal rx_s1 : std_logic;
 signal rx_s2 : std_logic;
 
 begin
 -- TRASMISSIONE
 process (clk_div, reset)
 begin
 if (reset = '1') then
 tx_reg <= (others=>'0');
 tx_out <= '1';
 tx_cnt <= (others=>'0');
 
 elsif (rising_edge(clk_div)) then
 if (ld_tx_data ='1') then
 tx_reg <= tx_data;
 end if;
 end if;
 
 if (tx_enable ='1') then
 tx_cnt <= tx_cnt +1;
 if (tx_cnt = 0) then
 tx_out <= '0';
 end if;
 if (tx_cnt > 0 and tx_cnt < 9) then
 tx_out <= tx_reg(conv_integer(tx_cnt) - 1);
 end if;
 if (tx_cnt = 9) then
 tx_out <= '1';
 tx_cnt <= "0000";
 end if;
 end if;
 if (tx_enable = '0') then
 tx_cnt <= X"0";
 end if;
 
 
 end process;
 -- RICEZIONE
 process (clk_div, reset) begin
 if (reset = '1') then
 rx_reg <= (others=>'0');
 rx_data <= (others=>'0');
 rx_sample_cnt <= (others=>'0');
 rx_cnt <= (others=>'0');
 rx_s1 <= '1';
 rx_s2 <= '1';
 
 elsif (rising_edge(clk_div)) then
 -- sincronizzazione del segnale di ingresso
 rx_s1 <= rx_in;
 rx_s2 <= rx_s1;
 
 if (uld_rx_data = '1') then
 rx_data <= rx_reg;
 
 end if;
 if (rx_enable = '1') then
 
 rx_sample_cnt <= rx_sample_cnt + 1;
 if (rx_sample_cnt = 9) then
 rx_cnt <= rx_cnt + 1;
 -- carico dati sul registro parallelo
 if (rx_cnt < 8) then
 rx_reg(conv_integer(rx_cnt)) <= rx_s2;
 
 end if;
 end if;
 end if;
 end if;
 
 end process;
 end architecture;