Kepsz
Member level 1
This is my UART code:
Xilinx ISE 13.4 constantly writes the excessive skew because message about the "BAUD_CLK". The code works, i mostly see the rigth values in laptop terminal. But if i try to start sending data bytes fast (putting high frequency to "start" input), the code makes mistakes with a big probability, showing constantly big numbers in the output.
In generaly, my imput is two 12 bit vector, and my output in the terminal is a decimal value 0 .. 4095. Input vectors are came from a latch, but this is not related to my problems.
Code:
library ieee ;
use ieee.std_logic_1164.all ;
use ieee.numeric_std.all;
entity txmit is
port (CLK_IN, START, CTS, RTS : in std_logic ;
DATA_INPUT_0, DATA_INPUT_1 : in std_logic_vector(11 downto 0);
UART_OUT : out std_logic ) ;
end txmit ;
architecture v1 of txmit is --For Digilent PmodUSBUart
signal TXD_TEMP_PUFFER: std_logic_vector (7 downto 0);
signal BAUD_CLK : std_logic;
signal state : unsigned (5 downto 0);
type states is (Idle, Transmit, Loaddata);
signal current_state : states;
signal next_state : states;
begin
tx_states: process (BAUD_CLK, current_state, state)
begin
if (rising_edge(BAUD_CLK) ) then
if (current_state = Transmit) then
state <= state + "000001" ;
else
state <= "000000" ;
end if;
end if;
end process;
BAUD_RATE: process (CLK_IN)
variable clk_div_counter : integer range 0 to 434;
begin
if (rising_edge(CLK_IN)) then
clk_div_counter := clk_div_counter + 1;
if (clk_div_counter <= 217) then --50MHz base CLK_IN / 9600baud = 5208,3 / 115200baud = 434,027
BAUD_CLK <= '1';
else
BAUD_CLK <= '0';
if (clk_div_counter = 434) then
clk_div_counter := 0; --ISE 13.4 sucks with ranged integer, had to limit it manualy
end if;
end if;
end if;
End Process;
NEXT_STATE_DECODE: process (CLK_IN, current_state, state, START)
begin
if (rising_edge(CLK_IN)) then
next_state <= current_state; --default is to stay in current state
case (current_state) is
when Idle =>
if (START = '1') then
next_state <= Loaddata;
end if;
when Loaddata =>
if (START = '0') then
next_state <= Transmit;
end if;
when Transmit =>
if (START = '0' and std_logic_vector(state) = "110001") then
next_state <= Idle;
end if;
when others =>
next_state <= Idle;
end case;
end if;
end process;
SYNC_PROC: process (CLK_IN)
begin
if (rising_edge(CLK_IN)) then
current_state <= next_state;
end if;
end process;
Transmit_process : process (BAUD_CLK, current_state, state, DATA_INPUT_0, DATA_INPUT_1, CTS, RTS) -- data format: 1 start bit, 8 data bits, 2 stop bits, no parity bit, LSB first
begin
if (rising_edge(BAUD_CLK) and current_state = Transmit and RTS = '0' and CTS = '1' ) then --RTS = '0' and CTS = '1' means the reciever is waiting for transmission
if (std_logic_vector(state) = "000001") then --start '0' bit, load input to puffer
UART_OUT <= '0' ;
TXD_TEMP_PUFFER <= DATA_INPUT_0(7 downto 0);
elsif (std_logic_vector(state) >= "000010" and std_logic_vector(state) <= "001000") then --shift out 8 bits data
UART_OUT <= TXD_TEMP_PUFFER(0);
TXD_TEMP_PUFFER <= "0" & TXD_TEMP_PUFFER(7 downto 1);
elsif (std_logic_vector(state) = "001001") then
UART_OUT <= TXD_TEMP_PUFFER(0) ;
elsif (std_logic_vector(state) = "001010") then -- number one stop '1' bit
UART_OUT <= '1';
elsif (std_logic_vector(state) = "001011") then -- number two stop '1' bit
UART_OUT <= '1';
-----------------------------------------------------------------------------------------------
elsif (std_logic_vector(state) = "001100") then --start '0' bit, load input to puffer
UART_OUT <= '0';
TXD_TEMP_PUFFER <= "0000" & DATA_INPUT_0(11 downto 8);
elsif (std_logic_vector(state) >= "001101" and std_logic_vector(state) <= "010011") then --shift out 8 bits data
UART_OUT <= TXD_TEMP_PUFFER(0);
TXD_TEMP_PUFFER <= "0" & TXD_TEMP_PUFFER(7 downto 1);
elsif (std_logic_vector(state) = "010100") then
UART_OUT <= TXD_TEMP_PUFFER(0);
elsif (std_logic_vector(state) = "010101") then -- number one stop '1' bit
UART_OUT <= '1';
elsif (std_logic_vector(state) = "010110") then -- number two stop '1' bit
UART_OUT <= '1';
-----------------------------------------------------------------------------------------------
elsif (std_logic_vector(state) = "010111") then --start '0' bit, load input to puffer
UART_OUT <= '0';
TXD_TEMP_PUFFER <= DATA_INPUT_1(7 downto 0);
elsif (std_logic_vector(state) >= "011000" and std_logic_vector(state) <= "011110") then --shift out 8 bits data
UART_OUT <= TXD_TEMP_PUFFER(0);
TXD_TEMP_PUFFER <= "0" & TXD_TEMP_PUFFER(7 downto 1);
elsif (std_logic_vector(state) = "011111") then
UART_OUT <= TXD_TEMP_PUFFER(0);
elsif (std_logic_vector(state) = "100000") then -- number one stop '1' bit
UART_OUT <= '1';
elsif (std_logic_vector(state) = "100001") then -- number two stop '1' bit
UART_OUT <= '1';
-----------------------------------------------------------------------------------------------
elsif (std_logic_vector(state) = "100010") then --start '0' bit, load input to puffer
UART_OUT <= '0' ;
TXD_TEMP_PUFFER <= "0000" & DATA_INPUT_1(11 downto 8);
elsif (std_logic_vector(state) >= "100011" and std_logic_vector(state) <= "101001") then --shift out 8 bits data
UART_OUT <= TXD_TEMP_PUFFER(0);
TXD_TEMP_PUFFER <= "0" & TXD_TEMP_PUFFER(7 downto 1);
elsif (std_logic_vector(state) = "101010") then
UART_OUT <= TXD_TEMP_PUFFER(0);
elsif (std_logic_vector(state) = "101011") then -- number one stop '1' bit
UART_OUT <= '1';
elsif (std_logic_vector(state) = "101100") then -- number two stop '1' bit
UART_OUT <= '1';
else
UART_OUT <= '1';
end if ;
end if ;
end process ;
end ;
Xilinx ISE 13.4 constantly writes the excessive skew because message about the "BAUD_CLK". The code works, i mostly see the rigth values in laptop terminal. But if i try to start sending data bytes fast (putting high frequency to "start" input), the code makes mistakes with a big probability, showing constantly big numbers in the output.
In generaly, my imput is two 12 bit vector, and my output in the terminal is a decimal value 0 .. 4095. Input vectors are came from a latch, but this is not related to my problems.