Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers

uart transmitter

Altera_Forum
Honored Contributor II
1,113 Views

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;
0 Kudos
4 Replies
Altera_Forum
Honored Contributor II
399 Views

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 

--------------------------------------------------------------------------
0 Kudos
Altera_Forum
Honored Contributor II
399 Views

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).
0 Kudos
Altera_Forum
Honored Contributor II
399 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
399 Views

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;
0 Kudos
Reply