Estoy tratando de implementar un transmisor UART simple, donde la tarjeta DDR Nexys4 está enviando caracteres ASCII a mi PC, que puedo ver usando Tera Term. El problema que tengo es que cuando presiono uno de los botones para enviar los datos de UART, sigo obteniendo mucho del mismo carácter a la vez, y el número no es exacto (por ejemplo, si intento enviar 0x66, obtengo el carácter 'f' a veces 102 veces, a veces 97 veces, etc). Pensé que necesitaba rebotar el botón, así que busqué un módulo para él. Pero parece que esto no tiene efecto. Me gustaría recibir ayuda sobre lo que está mal con la forma en que lo he hecho.
Aquí está el código para el UART: (basado en este ejemplo enlace )
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity uart_deb is
Port ( I_CLK, I_RST, I_TXSIG : in STD_LOGIC;
I_TXDATA : in STD_LOGIC_VECTOR(7 downto 0);
O_TXRDY, O_TX : out STD_LOGIC );
end uart_deb;
architecture STRUCTURE of uart_deb is
component uart_tx
Port (
I_CLK : in STD_LOGIC;
I_RST : in STD_LOGIC;
I_TXSIG : in STD_LOGIC;
I_TXDATA : in STD_LOGIC_VECTOR(7 downto 0);
O_TXRDY : out STD_LOGIC;
O_TX : out STD_LOGIC
);
end component;
component debounce
GENERIC(
counter_size : INTEGER := 19); --counter size (19 bits gives 10.5ms with 50MHz clock)
PORT(
I_CLK : IN STD_LOGIC; --input clock
button : IN STD_LOGIC; --input signal to be debounced
result : OUT STD_LOGIC); --debounced signal
END component;
signal RES : STD_LOGIC;
begin
G1: debounce port map (I_CLK, I_TXSIG, RES);
G2: uart_tx port map (I_CLK, I_RST, RES, I_TXDATA, O_TXRDY, O_TX);
end;
la fuente uart_tx:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity uart_tx is
Generic ( baud : integer := 9600);
Port (
I_CLK : in STD_LOGIC;
I_RST : in STD_LOGIC;
I_TXSIG : in STD_LOGIC;
I_TXDATA : in STD_LOGIC_VECTOR(7 downto 0);
O_TXRDY : out STD_LOGIC;
O_TX : out STD_LOGIC
);
end uart_tx;
architecture Behavioral of uart_tx is
signal tx_data : STD_LOGIC_VECTOR(7 downto 0) := (others => '0');
signal tx_state : integer := 0;
signal tx_rdy : STD_LOGIC := '1';
signal tx : STD_LOGIC := '1';
constant BIT_PD : integer := integer(50000000 / baud); -- 100MHz clock limit
signal tx_clk_counter : integer := BIT_PD;
signal tx_clk : STD_LOGIC := '0';
begin
clk_gen: process (I_CLK)
begin
if rising_edge(I_CLK) then
if tx_clk_counter = 0 then
tx_clk_counter <= BIT_PD;
tx_clk <= not tx_clk;
else
tx_clk_counter <= tx_clk_counter - 1;
end if;
end if;
end process;
O_TX <= tx;
O_TXRDY <= tx_rdy;
tx_proc: process (tx_clk, I_RST, I_TXSIG, tx_state)
begin
if rising_edge(tx_clk) then
if I_RST = '1' then
tx_state <= 0;
tx_data <= X"00";
tx_rdy <= '1';
tx <= '1';
else
if tx_state = 0 and I_TXSIG = '1' then
tx_state <= 1;
tx_data <= I_TXDATA;
tx_rdy <= '0';
tx <= '0';
elsif tx_state < 9 and tx_rdy = '0' then
tx <= tx_data(0);
tx_data <= '0' & tx_data(7 downto 1);
tx_state <= tx_state + 1;
elsif tx_state = 9 and tx_rdy = '0' then
tx <= '1';
tx_rdy <= '1';
tx_state <= 0;
end if;
end if;
end if;
end process;
end Behavioral;
y la fuente de debouncer:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
ENTITY debounce IS
GENERIC(
counter_size : INTEGER := 19); --counter size (19 bits gives 10.5ms with 50MHz clock)
PORT(
I_CLK : IN STD_LOGIC; --input clock
button : IN STD_LOGIC; --input signal to be debounced
result : OUT STD_LOGIC); --debounced signal
END debounce;
ARCHITECTURE logic OF debounce IS
SIGNAL flipflops : STD_LOGIC_VECTOR(1 DOWNTO 0); --input flip flops
SIGNAL counter_set : STD_LOGIC; --sync reset to zero
SIGNAL counter_out : STD_LOGIC_VECTOR(counter_size DOWNTO 0) := (OTHERS => '0'); --counter output
BEGIN
counter_set <= flipflops(0) xor flipflops(1); --determine when to start/reset counter
PROCESS(I_CLK)
BEGIN
IF(I_CLK'EVENT and I_CLK = '1') THEN
flipflops(0) <= button;
flipflops(1) <= flipflops(0);
If(counter_set = '1') THEN --reset counter because input is changing
counter_out <= (OTHERS => '0');
ELSIF(counter_out(counter_size) = '0') THEN --stable input time is not yet met
counter_out <= counter_out + 1;
ELSE --stable input time is met
result <= flipflops(1);
END IF;
END IF;
END PROCESS;
END logic;
el archivo de restricciones:
## Clock signal
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { I_CLK }]; #IO_L12P_T1_MRCC_35 Sch=clk100mhz
create_clock -add -name sys_clk_pin -period 20.00 -waveform {0 5} [get_ports {I_CLK}];
##Switches
set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { I_TXDATA[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { I_TXDATA[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { I_TXDATA[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { I_TXDATA[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]
set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { I_TXDATA[4] }]; #IO_L12N_T1_MRCC_14 Sch=sw[4]
set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { I_TXDATA[5] }]; #IO_L7N_T1_D10_14 Sch=sw[5]
set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { I_TXDATA[6] }]; #IO_L17N_T2_A13_D29_14 Sch=sw[6]
set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { I_TXDATA[7] }]; #IO_L5N_T0_D07_14 Sch=sw[7]
## LEDs
set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { O_TXRDY }]; #IO_L18P_T2_A24_15 Sch=led[0]
##Buttons
set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { I_RST }]; #IO_L9P_T1_DQS_14 Sch=btnc
set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { I_TXSIG }]; #IO_L4N_T0_D05_14 Sch=btnu
##USB-RS232 Interface
#set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { UART_TXD_IN }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in
set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { O_TX }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out
#set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { UART_CTS }]; #IO_L12N_T1_MRCC_35 Sch=uart_cts
#set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { UART_RTS }]; #IO_L5N_T0_AD13N_35 Sch=uart_rts