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;
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?
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
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
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.
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
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
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
Log in with Google account
No account? Register here.