(Publiqué misma pregunta en stackoverflow pero no obtener la respuesta correcta)
Soy novato en VHDL. Así que hoy, después de UART Tx, intenté leer los datos que provienen de la terminal de Realterm. Solo escribí códigos Rx para ver los datos. También usé la pantalla de 7 segmentos y 7 LED para ver qué datos recibí. Cuando miras los resultados de testbench, el problema es cuando el registro de 3 bits es "110" dos veces, el programa salta a rx_data_bit sin hacer rx_start_bit < = '1'
EDIT 1: Se actualizan los códigos y los resultados del banco de pruebas. Ahora el problema es que rx_data_bit nunca pasa a '0', por lo que rx_stop_bit nunca pasa a '1'
EDIT 2: Creo que el problema está aquí
if(rx_data_bit = '1') then
counter_del_half <= '0';
if(half_pulse = '1')then
rx_reg((rx_counter)) <= in_Data_rx;
if(rx_counter < 8 and baud_pulse = '1')then
rx_counter <= rx_counter + 1;
if(rx_counter = 8) then
rx_data_bit <= '0';
rx_stop_bit <= '1';
end if;
end if;
end if;
end if;
EDIT 3: Ahora, el contador cuenta correctamente pero tengo una pregunta aquí. ¿Debería el primer bit de rx_counter (1) durar medio bit largo o 1 bit largo? Además, rx_stop_bit debe ser '1', cuando rx_counter llega a 9.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.NUMERIC_STD.ALL;
entity UART_Rx is
port (
CLK: in std_logic;
nReset: in std_logic;
in_Data_Rx: in std_logic;
Segment7_1: out std_logic_vector (6 downto 0);
Segment7_2: out std_logic_vector (6 downto 0)
);
end UART_Rx;
architecture Behavioral of UART_Rx is
-- CLOCK AND BUTTON SIGNALS --
constant Baudrate: integer:= 9600;
constant CLK_Hiz: integer:= 50000000;
constant CLK_Bit: integer:= (CLK_Hiz / Baudrate) + 1;
signal counter_baud: integer range 0 to (CLK_Bit - 1):= 0;
signal counter_half: integer range 0 to ((CLK_Bit - 1)/2):= 0;
signal counter_del_baud: std_ulogic:= '0';
signal counter_del_half: std_ulogic:= '0';
signal baud_pulse: std_ulogic:= '0';
signal half_pulse: std_ulogic:= '0';
-- RX SIGNALS --
signal rx_reg: std_logic_vector (7 downto 0):= (others => '0');
signal rx_reg_counter: std_logic_vector (2 downto 0):= (others => '0');
signal rx_counter: integer range 0 to 9:= 0;
signal rx_first_bit: std_ulogic:= '1';
signal rx_start_bit: std_ulogic:= '0';
signal rx_data_bit: std_ulogic:= '0';
signal rx_stop_bit: std_ulogic:= '0';
signal rx_data_al: std_ulogic:= '0';
begin
-- CLOCK PROCESS --
clk_process: process(CLK,nReset)
begin
if(nReset = '0') then
baud_pulse <= '0';
counter_baud <= 0;
half_pulse <= '0';
counter_half <= 0;
elsif(rising_edge(CLK)) then
if(counter_baud < (CLK_Bit - 1)) then
counter_baud <= counter_baud + 1;
baud_pulse <= '0';
else
counter_baud <= 0;
baud_pulse <= '1';
end if;
if(counter_half < (CLK_Bit - 1)/2) then
counter_half <= counter_half + 1;
half_pulse <= '0';
else
counter_half <= 0;
half_pulse <= '1';
end if;
if(counter_del_baud = '1') then
counter_baud <= 0;
end if;
if(counter_del_half = '1') then
counter_half <= 0;
end if;
end if;
end process;
rx_process: process(CLK, nReset)
begin
if(rising_edge(CLK)) then
rx_reg_counter <= rx_reg_counter (1 downto 0) & in_Data_Rx;
if(rx_first_bit = '1' and rx_reg_counter (2 downto 0) = "110") then
counter_del_baud <= '1';
rx_start_bit <= '1';
rx_first_bit <= '0';
end if;
if(rx_start_bit = '1') then
counter_del_baud <= '0';
if(baud_pulse = '1') then
counter_del_baud <= '1';
rx_start_bit <= '0';
rx_data_bit <= '1';
counter_del_half <= '1';
end if;
end if;
if(rx_data_bit = '1') then
counter_del_half <= '0';
counter_del_baud <= '0';
if(half_pulse = '1')then
rx_data_bit <= '0';
rx_data_al <= '1';
rx_counter <= 1;
end if;
end if;
if(rx_data_al = '1') then
rx_reg(rx_counter - 1) <= in_Data_rx;
if(rx_counter > 0 and rx_counter < 9) then
if(baud_pulse = '1')then
rx_counter <= rx_counter + 1;
if(rx_counter = 9) then
rx_data_al <= '0';
rx_stop_bit <= '1';
end if;
end if;
end if;
end if;
if(rx_stop_bit = '1')then
rx_counter <= 0;
if(baud_pulse = '1') then
rx_stop_bit <= '0';
rx_reg_counter <= (others => '1');
rx_first_bit <= '1';
end if;
end if;
case rx_reg(3 downto 0) is --abcdefg--
when "0000" => segment7_1 <= "0000001"; -- '0'
when "0001" => segment7_1 <= "1001111"; -- '1'
when "0010" => segment7_1 <= "0010010"; -- '2'
when "0011" => segment7_1 <= "0000110"; -- '3'
when "0100" => segment7_1 <= "1001100"; -- '4'
when "0101" => segment7_1 <= "0100100"; -- '5'
when "0110" => segment7_1 <= "0100000"; -- '6'
when "0111" => segment7_1 <= "0001111"; -- '7'
when "1000" => segment7_1 <= "0000000"; -- '8'
when "1001" => segment7_1 <= "0000100"; -- '9'
when "1010" => segment7_1 <= "0001000"; -- 'A'
when "1011" => segment7_1 <= "1100000"; -- 'B'
when "1100" => segment7_1 <= "0110001"; -- 'C'
when "1101" => segment7_1 <= "1000010"; -- 'D'
when "1110" => segment7_1 <= "0110000"; -- 'E'
when "1111" => segment7_1 <= "0111000"; -- 'F'
when others => segment7_1 <= "1111111";
end case;
case rx_reg(7 downto 4) is
when "0000" => segment7_2 <= "0000001"; -- '0'
when "0001" => segment7_2 <= "1001111"; -- '1'
when "0010" => segment7_2 <= "0010010"; -- '2'
when "0011" => segment7_2 <= "0000110"; -- '3'
when "0100" => segment7_2 <= "1001100"; -- '4'
when "0101" => segment7_2 <= "0100100"; -- '5'
when "0110" => segment7_2 <= "0100000"; -- '6'
when "0111" => segment7_2 <= "0001111"; -- '7'
when "1000" => segment7_2 <= "0000000"; -- '8'
when "1001" => segment7_2 <= "0000100"; -- '9'
when "1010" => segment7_2 <= "0001000"; -- 'A'
when "1011" => segment7_2 <= "1100000"; -- 'B'
when "1100" => segment7_2 <= "0110001"; -- 'C'
when "1101" => segment7_2 <= "1000010"; -- 'D'
when "1110" => segment7_2 <= "0110000"; -- 'E'
when "1111" => segment7_2 <= "0111000"; -- 'F'
when others => segment7_2 <= "1111111";
end case;
rx_reg <= (others => '0');
end if;
end process;
end Behavioral;
Aquí está el código del banco de pruebas:
library ieee;
use ieee.std_logic_1164.all;
entity tb_UART_Rx is
end tb_UART_Rx;
architecture tb of tb_UART_Rx is
component UART_Rx
port (CLK : in std_logic;
nReset : std_logic:='1';
in_Data_Rx : std_logic:='1';
Segment7_1 : out std_logic_vector (6 downto 0):= (others => '0');
Segment7_2 : out std_logic_vector (6 downto 0):= (others => '0'));
end component;
signal CLK : std_logic;
signal nReset : std_logic:='1';
signal in_Data_Rx : std_logic:='1';
signal rx_reg_counter: std_logic_vector (2 downto 0):= (others => '1');
signal Segment7_1 : std_logic_vector (6 downto 0):= (others => '0');
signal Segment7_2 : std_logic_vector (6 downto 0):= (others => '0');
constant TbPeriod : time := 20 ns;
signal TbSimEnded : std_logic := '0';
begin
dut : UART_Rx
port map (CLK => CLK,
nReset => nReset,
in_Data_Rx => in_Data_Rx,
Segment7_1 => Segment7_1,
Segment7_2 => Segment7_2);
clk_process: process
begin
CLK <= '0';
wait for TbPeriod/2;
CLK <= '1';
wait for TbPeriod/2;
end process;
stimuli : process
begin
nReset <= '0';
wait for 100 ns;
nReset <= '1';
wait for 100 ns;
in_Data_Rx <= '1';
wait for 0.104 ms;
in_Data_Rx <= '0';
wait for 0.104 ms;
in_Data_Rx <= '0';
wait for 0.104 ms;
in_Data_Rx <= '1';
wait for 0.104 ms;
in_Data_Rx <= '1';
wait for 0.104 ms;
in_Data_Rx <= '1';
wait for 0.104 ms;
in_Data_Rx <= '0';
wait for 0.104 ms;
in_Data_Rx <= '0';
wait for 0.104 ms;
in_Data_Rx <= '0';
wait for 0.104 ms;
in_Data_Rx <= '0';
wait for 0.104 ms;
in_Data_Rx <= '1';
wait;
end process;
end tb;
configuration cfg_tb_UART_Rx of tb_UART_Rx is
for tb
end for;
end cfg_tb_UART_Rx;
Aquí están los resultados del banco de pruebas:
Gracias.