EmbDev.net

Forum: FPGA, VHDL & Verilog UART + FIFO transmission problems


von Alessandro (Guest)


Rate this post
useful
not useful
Hi Everyone,

I am struggling to make this design work. UART alone is ok but when I 
add FIFO to accumulate data I receive missreads on the PC.

Design:

-- UART Transmitter
-- Baud: 7200
-- Clock: 27MHz


library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;

entity uart_tx is

  port
  (
    reset    : in std_logic;
    stop    : in std_logic;
    clk    : in std_logic;
    rx      : in std_logic;
    tx      : buffer std_logic;

    tx_rdy   : buffer std_logic
  );

end entity;

architecture rtl of uart_tx is
  --signal data : std_logic_vector( 7 downto 0) := "01000001"; --ASCII 
value of alphabet 'A' in hex
  --signal data : std_logic_vector(7 downto 0) := "01011111"; --ASCII 
value of alphabet '_' in hex
  signal data : std_logic_vector(7 downto 0) := "00000000";
  signal next_data : std_logic_vector(2 downto 0) := "000"; --ASCII 
value of alphabet '_' in hex

  --variable to count the clock pulse
  signal count : integer range 0 to 3749 := 3749; --7200 baud generator 
variable (27MHz/7200)
   signal bit_number : integer range 0 to 1200 :=0; --start bit+8 data 
bits+stop bit+10 buffer bits

  signal write_enable : std_logic:='0';
  signal read_enable : std_logic:='0';
  signal fifo_prog_empty : std_logic:='0';
  signal fifo_empty : std_logic:='0';
  signal fifo_prog_full : std_logic:='0';
  signal fifo_full : std_logic:='0';


  signal counter : std_logic_vector(24 downto 0):=(OTHERS => '0');
  signal data_gen : std_logic_vector(7 downto 0):=(OTHERS => '0');

  signal second_stop : std_logic:='0';

  COMPONENT FIFO_memory
  PORT (
    clk : IN STD_LOGIC;
    rst : IN STD_LOGIC;
    din : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
    wr_en : IN STD_LOGIC;
    rd_en : IN STD_LOGIC;
    dout : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
    full : OUT STD_LOGIC;
    empty : OUT STD_LOGIC;
    prog_full : OUT STD_LOGIC;
    prog_empty : OUT STD_LOGIC
  );
END COMPONENT;


begin
  process (reset,clk)

    begin

    if reset = '1' then

    tx <= '1';
    tx_rdy <= '0';
    count <= 0;
    --next_data <= "000";
    bit_number <= 0;


    elsif (rising_edge(clk)) then
        if (count = 3749) then
          if (bit_number = 0 and rx = '1' and tx_rdy = '1') then
            tx <= '0'; --start bit
            tx_rdy <= '0';
          elsif(bit_number = 9) then
            tx <= '1'; -- stop bit
          elsif((bit_number > 0) and (bit_number < 9))  then
            tx <= data(bit_number-1); --8 data bits
            tx_rdy <= '0';
          elsif(bit_number > 9) then
            tx <= '1'; --10 logic high bits as a buffer before the next 
transmission
            tx_rdy <= '1';

          end if;

          -- make sure transmission stops only after last bit was 
transmitted

          if ((second_stop = '1') and (bit_number > 9)) then
            bit_number <= bit_number;
          else
            bit_number <= bit_number+1;
          end if;

          if(bit_number = 13) then --resetting the bit number
            bit_number <=0;
          end if;

        end if;
        count <= count+1;
        if (count = 3750) then --resetting the baud generator counter
          count <=0;
        end if;
      end if;

  end process;

  read_enable <= '1' when (count = 3750 and bit_number = 0 and 
second_stop = '0') else '0';


  process(clk) begin

  if rising_edge(clk) then

  if fifo_prog_full = '1' then

    second_stop <= '0';

  elsif ((fifo_prog_empty = '1') and (fifo_prog_full = '0')) then

    second_stop <= '1';

  end if;

  end if;

  end process;


 -- input data for FIFO

--  process(clk,reset) begin
--
--    if reset = '1' then
--
--        data_gen <= (OTHERS => '0');
--
--    elsif rising_edge(clk) then
--
--        data_gen <= data_gen + '1';
--
--    end if;
--
--   end process;





  -- write enable for FIFO

    process(clk,reset) begin

    if reset = '1' then

      counter <= (OTHERS => '0');
      data_gen <= (OTHERS => '0');

    elsif rising_edge(clk) then

      if counter = "1111110111110111" then --"1100110111111110011000000" 
then

        counter <= (OTHERS => '0');
        data_gen <= data_gen + '1';

      else

        counter <= counter + '1';

      end if;

    end if;

  end process;


write_enable <= '1' WHEN counter = "1111110111110111" else '0';

FIFO : FIFO_memory
  PORT MAP (
    clk => clk,
    rst => reset,
    din => data_gen,
    wr_en => write_enable,
    rd_en => read_enable,
    dout => data,
    full => fifo_full,
    empty => fifo_empty,
    prog_full => fifo_prog_full,
    prog_empty => fifo_prog_empty
  );


end rtl;


Test Bench:

------------------------------------------------------------------------ 
--------
-- Company:
-- Engineer:
--
-- Create Date:   12:17:41 12/27/2016
-- Design Name:
-- Module Name: 
C:/Users/Alessandro/Desktop/UART_TX3/simple_uart/testbench.vhd
-- Project Name:  simple_uart
-- Target Device:
-- Tool versions:
-- Description:
--
-- VHDL Test Bench Created by ISE for module: uart_tx
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes:
-- This testbench has been automatically generated using types std_logic 
and
-- std_logic_vector for the ports of the unit under test.  Xilinx 
recommends
-- that these types always be used for the top-level I/O of a design in 
order
-- to guarantee that the testbench will bind correctly to the 
post-implementation
-- simulation model.
------------------------------------------------------------------------ 
--------
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;

ENTITY testbench IS
END testbench;

ARCHITECTURE behavior OF testbench IS

    -- Component Declaration for the Unit Under Test (UUT)

    COMPONENT uart_tx
    PORT(
      reset : IN  std_logic;
         stop : IN  std_logic;
      clk : IN  std_logic;
         rx : IN  std_logic;
         tx : BUFFER  std_logic;
      tx_rdy : BUFFER std_logic
        );
    END COMPONENT;


   --Inputs
   signal clk : std_logic := '0';
   signal rx : std_logic := '0';
  signal stop : std_logic := '0';
  signal reset : std_logic := '0';

   --Outputs
   signal tx : std_logic;
  signal tx_rdy : std_logic;

   -- Clock period definitions
   constant clk_period : time := 37 ns;

BEGIN

  -- Instantiate the Unit Under Test (UUT)
   uut: uart_tx PORT MAP (
       reset => reset,
       stop => stop,
          clk => clk,
          rx => rx,
          tx => tx,
       tx_rdy => tx_rdy
        );

   -- Clock process definitions
   clk_process :process
   begin
    clk <= '0';
    wait for clk_period/2;
    clk <= '1';
    wait for clk_period/2;
   end process;


   reset_proc :process
   begin
    reset <= '1';
    wait for 100 ns;
    reset <= '0';
    wait for 10000000 ms;
   end process;


   stop_proc :process
   begin
    stop <= '0';
    wait for 100000000 ms;
    stop <= '1';
    wait for 100 ns;
   end process;


   -- Stimulus process
   stim_proc: process
   begin

        rx <= '1';
        wait until tx_rdy = '0';
        rx <= '0';
        wait until tx_rdy = '1';


   end process;

END;

von lkmiller (Guest)


Rate this post
useful
not useful
Alessandro wrote:
> UART alone is ok but when I add FIFO to accumulate data I receive
> missreads on the PC.
You have that problem only on real hardware?
The simulation is fine?

von Alessandro (Guest)


Attached files:

Rate this post
useful
not useful
Dear lkmiller,

Thank you for your reply.

Yep! The problem is only on real hw. The simulation looks completely 
fine.

I've tried to use the code for UART in trasmission without the FIFO and 
I am actually able to see data on the PC (using putty.exe).

While if I put a FIFO before the UART module: simulation is ok while 
real data transmission does not work in the sense that my FPGA is 
transmitting something to the PC but data make no sense.

Alessandro Rossetta

PS - I attached vhd code

von René D. (Company: www.dossmatik.de) (dose)


Rate this post
useful
not useful
Alessandro

I have solved your problem. It works fine also in hardware and vendor 
independent.

 have a look inside the zipfile...

http://www.dossmatik.de/mais/MAIS_CPU_V1.zip

  ..rtl/device/UART_TX_8N1.vhd

von duy tam (Guest)


Rate this post
useful
not useful
DO you have this code by verilog ?

von Michael W. (Guest)


Rate this post
useful
not useful
Funny question. The CPU of Rene is right a large project. Hardware to 
believe he has done that twice to serve a minor programming laguage like 
Verilog.

VHDL ist the key. Verilog is out.

von Esakki Ponniah (Guest)


Rate this post
useful
not useful
I download the code from MAIS_CPU_V1.zip    I have error like below

Uart_8N1_TX\Uart_8N1_TX.vhd" Line 25: Formal <clk_freq> has no actual or 
default value.

Uart_8N1_TX\Uart_8N1_TX.vhd" Line 26: Formal <baudrate> has no actual or 
default value.


---------------------
@René D.

Alessandro

I have solved your problem. It works fine also in hardware and vendor
independent.

 have a look inside the zipfile...

http://www.dossmatik.de/mais/MAIS_CPU_V1.zip

  ..rtl/device/UART_TX_8N1.vhd

von Duke Scarring (Guest)


Rate this post
useful
not useful
Just add default values for clock frequency and baudrate.
Here is an example:
1
      clk_freq   : positive  := 50;      -- 50 MHz clock
2
      brate      : positive  := 115200;  -- RS232 baudrate

Duke

von p uma maheshwar (Guest)


Rate this post
useful
not useful
hi can you send varilog code for uart and fifo

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.