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.