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;