library IEEE; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity fsm_uart_tx is Generic ( BIT_LENGTH : integer := 2000; PARITY : string := "none"; --! Can be either "even", "odd", or "none" STOP_BITS : integer := 1 --! Can be either 1 or 2 ); Port ( clk : in STD_LOGIC; rst : in STD_LOGIC; data : in STD_LOGIC_VECTOR (7 downto 0); empty : in STD_LOGIC; rd_en : out STD_LOGIC; TX : out STD_LOGIC ); end fsm_uart_tx; architecture Behavioral of fsm_uart_tx is type tipoestado is (reposo, sampledata, testdata, b_start, B_0, B_1, B_2, B_3, B_4, B_5, B_6, B_7, B_paridad, B_stop, b_stop2); signal estado, p_estado: tipoestado; -- This integer must go up to BIT_LENGTH instead of BIT_LENGTH-1 because when -- cont = BIT_LENGTH-1, p_cont will reach BIT_LENGTH signal cont, p_cont: integer range 0 to BIT_LENGTH; signal datai, p_datai: std_logic_vector (7 downto 0); begin -- PARITY must be one of the three supported values assert PARITY = "even" or PARITY = "odd" or PARITY = "none" report "uart_emu: PARITY must be either even, odd or none" severity failure; -- STOP_BITS must be one of the two supported values assert STOP_BITS = 1 or STOP_BITS = 2 report "uart_emu: STOP_BITS must be either 1 or 2" severity failure; sinc: process(clk, rst) begin if(rst='1')then estado<=reposo; cont<=0; datai<=(others=>'0'); elsif(clk='1' and clk'event) then estado<=p_estado; cont<=p_cont; datai<=p_datai; end if; end process; comb: process(estado, cont, data, datai, empty) begin p_estado<=estado; p_cont<=cont; p_datai<=datai; rd_en <= '0'; case estado is when reposo=> TX<='1'; p_cont <= 0; if(empty='0')then rd_en <= '1'; p_estado<=sampledata; end if; when sampledata=> TX<='1'; p_datai<=data; --muestrear dato a la entrada p_estado<=b_start; when testdata=> TX<='1'; p_estado<=b_start; p_cont<= 0; when b_start=> TX<='0'; p_cont<=cont+1; if(cont=BIT_LENGTH-1)then p_cont<= 0; p_estado<=b_0; end if; when b_0=> TX<=datai(0); p_cont<=cont+1; if(cont=BIT_LENGTH-1)then p_cont<= 0; p_estado<=b_1; end if; when b_1=> TX<=datai(1); p_cont<=cont+1; if(cont=BIT_LENGTH-1)then p_cont<= 0; p_estado<=b_2; end if; when b_2=> TX<=datai(2); p_cont<=cont+1; if(cont=BIT_LENGTH-1)then p_cont<= 0; p_estado<=b_3; end if; when b_3=> TX<=datai(3); p_cont<=cont+1; if(cont=BIT_LENGTH-1)then p_cont<= 0; p_estado<=b_4; end if; when b_4=> TX<=datai(4); p_cont<=cont+1; if(cont=BIT_LENGTH-1)then p_cont<= 0; p_estado<=b_5; end if; when b_5=> TX<=datai(5); p_cont<=cont+1; if(cont=BIT_LENGTH-1)then p_cont<= 0; p_estado<=b_6; end if; when b_6=> TX<=datai(6); p_cont<=cont+1; if(cont=BIT_LENGTH-1)then p_cont<=0; p_estado<=b_7; end if; when b_7=> TX<=datai(7); p_cont<=cont+1; if(cont=BIT_LENGTH-1)then p_cont<=0; if PARITY /= "none" then p_estado<=b_paridad; else p_estado<=b_stop; end if; end if; when b_paridad=> if PARITY = "even" then TX <= datai(0) xor datai(1) xor datai(2) xor datai(3) xor datai(4) xor datai(5) xor datai(6) xor datai(7); elsif PARITY = "odd" then TX <= not (datai(0) xor datai(1) xor datai(2) xor datai(3) xor datai(4) xor datai(5) xor datai(6) xor datai(7)); end if; p_cont<=cont+1; if(cont=BIT_LENGTH-1)then p_cont<=0; p_estado<=b_stop; end if; when b_stop=> TX<='1'; p_cont<=cont+1; if(cont=BIT_LENGTH-1)then p_cont<=0; if STOP_BITS = 1 then p_estado <= reposo; else p_estado <= b_stop2; end if; end if; when b_stop2=> TX<='1'; p_cont<=cont+1; if(cont=BIT_LENGTH-1)then p_cont<=0; p_estado<=reposo; end if; end case; end process; end Behavioral;