EmbDev.net

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


Author: Alessandro (Guest)
Posted on:

Rate this post
0 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;

Author: lkmiller (Guest)
Posted on:

Rate this post
0 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?

Author: Alessandro (Guest)
Posted on:
Attached files:

Rate this post
0 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

Author: René D. (Company: www.dossmatik.de) (dose)
Posted on:

Rate this post
0 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

Author: duy tam (Guest)
Posted on:

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

Author: Mar. Wa. (elektrowagi78)
Posted on:

Rate this post
0 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.

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig