Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

uart transmitter

Hi there!

I need to decode comands and data sended by device.

On the one side I have device with clk, dc, cs and data ports, on the other there is cable uart -> usb.

I wrote module to grab data from device and send to the PC. In simulation it works fine, but on the fpga - doesn't.

Device sends signals, module grabs them (i think so), but there is no communication on PC (Terminal doesn't print anything).

I tried to communicate in the simpliest way - one stop bit, and one start bit.

Code is listed below. Does anyone have any suggestion?

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity transmiter is
port(
	clk			: in std_logic;
	dc				: in std_logic;
	serial_in	: in std_logic;
	cs				: in std_logic;
	
	uart_tx: out std_logic;
	
	lampka_fifo_0	: out std_logic;
	lampka_fifo_1	: out std_logic;
	lampka_fifo_2	: out std_logic;
	lampka_fifo_3	: out std_logic;
	lampka_fifo_4	: out std_logic;
	lampka_fifo_5	: out std_logic;
	lampka_fifo_6	: out std_logic;
	lampka_fifo_7	: out std_logic;
	
	data_out : out std_logic_vector (7 downto 0);
	cmd_out	: out std_logic_vector (7 downto 0);
	
	lampka_dc_indicator : out std_logic;
	lampka_clk	: out std_logic;
	lampka_dc	: out std_logic;
	lampka_data	: out std_logic;
	lampka_cs	: out std_logic;
	lampka_txd	: out std_logic
	
	);
end transmiter;
architecture transmiter_arch of transmiter is
	signal data_bus		: std_logic_vector (7 downto 0);
	signal counter_reg 	: integer range 0 to 7 := 0;
	type fifo is array (0 to 7) of std_logic_vector (7 downto 0);
	signal fifo_buf		: fifo;
	signal data_to_be_send	:	std_logic_vector (7 downto 0) := "00000000";
	
	signal fifo_deep	:	integer range 0 to 10 := 0;
	signal ready_to_send : std_logic;
	signal dc_indicator : std_logic;
	signal dc_indicator_reg : std_logic := '0';
begin 
	
	process (clk)
	begin
		if rising_edge(clk) then
			if (counter_reg = 7) then
				counter_reg <= 0;
			else 
				counter_reg <= counter_reg + 1;
			end if;
			
		end if;
	end process;
	
	process (clk)
	begin 
		if (rising_edge(clk)) then
			for i in 0 to 6 loop
				data_bus(i+1) <= data_bus(i);
			end loop;						 
			data_bus(0) <= serial_in;		
		end if;
		
			
	end process;
	
	write_to_fifo: process (clk)
	begin
		if (clk = '1') then
			if (counter_reg = 0) then
				fifo_buf(fifo_deep) <= data_bus;
				fifo_deep <= fifo_deep + 1;	
			end if;
			if (dc = '1') then
				data_out <= data_bus;
			else
				cmd_out <= data_bus;
			end if;
		else
			if (fifo_deep > 0 and ready_to_send = '1') then
				data_to_be_send <= fifo_buf(0);
				for i in 0 to 6 loop
					fifo_buf(i) <= fifo_buf(i+1);
				end loop;
				fifo_deep <= fifo_deep - 1;
				data_to_be_send <= fifo_buf(0);
			end if;
		end if;
	end process;
	
	
	
	send : process (clk)
	variable send_cnt	: integer range 0 to 10 := 0;
	begin
		if (rising_edge(clk)) then
			if (send_cnt = 0) then
				uart_tx <= '0';
				lampka_txd <= '0'; -- !!!!!!!!!!!!!!!!!!!!!!!!
				send_cnt := send_cnt + 1;
				ready_to_send <= '0';
			elsif (send_cnt > 0 and send_cnt <9) then
				uart_tx <= data_to_be_send (send_cnt - 1);
				lampka_txd <= data_to_be_send (send_cnt - 1);
				send_cnt := send_cnt + 1;
				ready_to_send <= '0';
			elsif (send_cnt = 9) then
				uart_tx <= '1';
				lampka_txd <= '1';
				send_cnt :=0;
				ready_to_send <= '1';
			end if;
		end if;	
	end process;
	
	process (cs)
	begin
		if (rising_edge(cs)) then
			dc_indicator_reg <= not dc_indicator;
		end if;
	end process;
	
	dc_indicator <= dc_indicator_reg;
	
	lampka_cs <= cs;
	lampka_data <= serial_in;
	lampka_clk <= clk;
	lampka_dc <= dc;
	
	lampka_dc_indicator <= dc_indicator;
	
	lampka_fifo_0	<=	fifo_buf(0)(0);
	lampka_fifo_1	<= fifo_buf(0)(1);
	lampka_fifo_2	<= fifo_buf(0)(2);
	lampka_fifo_3	<= fifo_buf(0)(3);
	lampka_fifo_4	<= fifo_buf(0)(4);
	lampka_fifo_5	<= fifo_buf(0)(5);
	lampka_fifo_6	<= fifo_buf(0)(6);
	lampka_fifo_7	<= fifo_buf(0)(7);
	
end transmiter_arch;

4 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    A long time ago I wrote in my Coding Style book the model and verification of a UART.

    You can download the code at systemverilog dot us/Ch12_dir.tar

    I hope that this helps.

    --------------------------------------------------------------------------

    Ben Cohen (831) 345-1759

    systemverilog dot us ben at systemverilog dot us

    * SystemVerilog Assertions Handbook, 2nd Edition, 2010 ISBN 878-0-9705394-8-7

    * A Pragmatic Approach to VMM Adoption 2006 ISBN 0-9705394-9-5

    * Using PSL/SUGAR for Formal and Dynamic Verification 2nd Edition, 2004, ISBN 0-9705394-6-0

    * Real Chip Design and Verification Using Verilog and VHDL, 2002 isbn 0-9705394-2-8

    * Component Design by Example, 2001 ISBN 0-9705394-0-1

    * VHDL Coding Styles and Methodologies, 2nd Edition, 1999 ISBN 0-7923-8474-1

    * VHDL Answers to Frequently Asked Questions, 2nd Edition ISBN 0-7923-8115

    --------------------------------------------------------------------------
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks a lot for your answer! :)

    As I suppose, data grabing process should be synchronized by clk from device, while data sending should be synchronized by clk form FPGA (proper to get specified baud rate).

    Am I right? If so, how i can get specified baud rate?

    Terminal program, which I use at the moment shows only data in sended in packets. Is there any software which show me exactly what's getting from FPGA to PC (i mean bit after bit).
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    It was many years since I used that model. I suggest that you run the testbench and understand the clocking scheme. As I quickly remember, the 16x clk and system clk are different. You may need some sync (e.g. 2 stage reclock) if needed.

    Ben Cohen Ben at systemverilog dot us
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Still stucked.

    I've even try to get the simpliest connection. (code below)

    But still get nothing.

    :-(

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    entity simpleuart is
    port(
    	clk	: in std_logic; --freq = 27 MHz
    	lampka_txd : out std_logic;
    	uart_tx	: out std_logic);
    end simpleuart;
    architecture simpleuart_arch of simpleuart is
    	signal send_clock	: std_logic := '1';
    	constant N	: natural := 5625; -- clock divider to get baud rate = 4800.
    	signal cntT : integer range 0 to 2812;
    	
    begin
    	send_clock_generator : process (clk)
    	begin
    		if(rising_edge(clk)) then
    			if (cntT = 2812) then
    				send_clock <= not (send_clock);
    				cntT <= 0;
    			else
    				cntT <= cntT + 1;
    			end if;
    		end if;
    		
    	end process;
    	
    	
    	lampka_txd <= send_clock;
    	
    	send : process (send_clock)
    	variable send_cnt	: integer range 0 to 10 := 0;
    	begin
    		if (rising_edge(send_clock)) then
    			if (send_cnt = 0) then
    				uart_tx <= '0';
    				--lampka_txd <= '0'; -- !!!!!!!!!!!!!!!!!!!!!!!!
    				send_cnt := send_cnt + 1;
    				--lampki(send_cnt) <= '0';
    				--ready_to_send <= '0';
    			elsif (send_cnt > 0 and send_cnt <4) then
    				uart_tx <= '1';
    				--lampka_txd <= '1';
    				send_cnt := send_cnt + 1;
    				--lampki(send_cnt) <= '1';
    				--ready_to_send <= '0';
    			elsif (send_cnt < 9) then
    				uart_tx <= '0';
    				--lampka_txd <= '0';
    				send_cnt := send_cnt + 1;
    				--lampki(send_cnt) <= '0';
    			elsif (send_cnt = 9) then
    				uart_tx <= '1';
    				--lampka_txd <= '1';
    				--lampki(send_cnt) <= '1';
    				send_cnt :=0;
    				--ready_to_send <= '1';
    			end if;
    		end if;	
    	end process;
    end simpleuart_arch;