hardware - Xillinx UART Rx on Spartan-3E -


so brain scrambled after battling this, trying implement simple rs232 receiver (baud 19200) spartan3e (50mhz clock). in simulation works, when upload design (i've used leds output byte received) receiving garbage. i'm using pyserial transmit simple 8bit sequences:

ser.write(chr(0x00)) 

even simple message seem receiving 11111111. head scrambled, i've used textbook examples, own designs , nothing working! below vhdl rx , baud rate (the baud rate tick linked s_tick signal in rx), , running 16 times oversampling of baud.

    library ieee; use ieee.std_logic_1164.all;  -- uncomment following library declaration if using -- arithmetic functions signed or unsigned values use ieee.numeric_std.all;  -- uncomment following library declaration if instantiating -- xilinx primitives in code. --library unisim; --use unisim.vcomponents.all;  entity receiver     generic (         dbit : integer:=8;         sb_tick: integer:=16);     port ( clk : in  std_logic;            reset : in  std_logic;            rx : in  std_logic;            s_tick : in  std_logic;            rx_done_tick : out  std_logic;            dout : out  std_logic_vector(7 downto 0)); end receiver;  architecture behavioral of receiver     type state_type is(idle, start, data, stop);     signal state_reg , state_next: state_type;     signal s_reg , s_next: unsigned(3 downto 0); --number of sample ticks, 7 in start, 15 in data, sb_tick in stop     signal n_reg , n_next: unsigned(2 downto 0); -- number of data bits recieved     signal b_reg , b_next: std_logic_vector(7 downto 0);     signal baud : integer := 163;     signal count, count_next : integer :=0;     signal tick : std_logic; begin  process(clk,reset) begin     if reset='1'         state_reg <=idle;         s_reg <= (others =>'0');         n_reg <= (others =>'0');         b_reg <= (others =>'0');     elsif (clk'event , clk='1')         count <= count_next;         state_reg <= state_next;         s_reg <= s_next;         n_reg <= n_next;         b_reg <= b_next;     end if ; end process;    tick <='1' when count = (baud-1) else '0';   process(state_reg,s_reg,n_reg,b_reg,s_tick,rx, count) begin     state_next <= state_reg ;     s_next <= s_reg;     n_next <= n_reg;     b_next <= b_reg;      if(count = (baud-1))         count_next <= 0;     else          count_next <= count+1;     end if;      rx_done_tick <='0';      case state_reg     when idle =>         if rx='0'             count_next <= 0;             state_next <= start;             s_next <= (others => '0');         end if;     when start =>         if (s_tick = '1')             if s_reg = 7              state_next <= data;             s_next <= (others => '0');             n_next <= (others => '0');             else             s_next <= s_reg+1;             end if ;         end if;     when data =>         if (s_tick ='1')             if s_reg = 15                 s_next <= (others => '0');                 b_next <= rx & b_reg(7 downto 1);                 if n_reg=(dbit-1)                     state_next <= stop;                 else                     n_next <= n_reg+1;                 end if;             else                  s_next <= s_reg+1;             end if;         end if;     when stop =>         if (s_tick ='1')             if s_reg=(sb_tick-1)                 if(rx = '1')                     state_next <= idle;                 else                     state_next <= start;                 end if;                 rx_done_tick <='1';             else                 s_next <= s_reg+1;             end if;         end if; end case; end process;  dout <= b_reg;    end behavioral; 

baud:

    library ieee; use ieee.std_logic_1164.all;  -- uncomment following library declaration if using -- arithmetic functions signed or unsigned values --use ieee.numeric_std.all;  -- uncomment following library declaration if instantiating -- xilinx primitives in code. --library unisim; --use unisim.vcomponents.all;  entity baudrate     generic (     n: integer := 163);     port ( clk : in  std_logic;            rst : in  std_logic;               tick : out std_logic); end baudrate;  architecture behavioral of baudrate  signal count, count_next : integer := 0; signal div : integer := n;   begin  process(clk,rst) begin     if rst='1'         count <= 0;         --tick <= '0';     elsif (clk'event , clk ='1')         count <= count_next;     --  if(count = (n-1))         --  tick <= '1';         --else             --tick <='0';     --  end if;     end if; end process;  count_next <= 0 when count = (n-1) else count+1;  tick <='1' when count = (n-1) else '0';  end behavioral; 

i've tried embedding baud counter in rx , nothing working. know there better ways rs232 (and using picoblaze) understand why not working in synthesis.

some reasons simulation , real-life not matching given here:

https://stackoverflow.com/a/15204291/106092

also, check warnings, related removed logic. might see in there.

have checked .pad file make sure signals coming out right pins?

another potential gotcha using leds feedback results wired such "on" when signal low. dates olden-days when drivers pull low better drive high, not necessary more (certainly fpga io drive pins)... see done on pcb!


Comments