EmbDev.net

Forum: FPGA, VHDL & Verilog UART transmitter


Author: Hareesh M. (Company: Mindteck) (hareeshp)
Posted on:
Attached files:

Rate this post
0 useful
not useful
Hi all,
I have written code for UART transmitter with 9600 baud rate. The thing 
is when i simulate the code using modelsim the UART signals are find but 
when i try to use terminal for transmission there is no output.
Library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity uart_tx is

  generic (
          baud_rate_divisor : integer:=520
        );
  
  port (
        i_inclk         : in std_logic; --Clock input 50Mhz
        i_reset          : in std_logic; --Reset for UART transmission
        i_tx_data_bits    : in std_logic_vector(0 to 7); --8 bits of data to be send
        i_tx_start      : in std_logic; --
        o_tx_done      : out std_logic; --Bit to indicate transmission done
        o_tx_line_busy    : out std_logic; --Bit to indicate busy
        led_testing      : out std_logic;
        test_led        : out std_logic;
        o_serial_data    : out std_logic --Data to be send serially
        
      );
      
end uart_tx;

architecture behav of uart_tx is

  type transmitter_state is(tx_idle,tx_start,tx_data,tx_stop);
  signal tx_state:transmitter_state:=tx_idle;

  signal baud_rate_clk    : std_logic:='0';
  signal clk_divider     : integer range 0 to 530:= 0;
  signal tx_data_byte    : std_logic_vector(0 to 7);
  signal tx_done_bit    : std_logic;
  signal out_clk         : std_logic:='0';
  signal index_counter    : integer range 0 to 7;

  
  
  
begin
  process(i_reset,i_inclk)
  begin
    if(i_reset='0')then
      clk_divider<=0;
    elsif(rising_edge(i_inclk))then
      if(clk_divider<baud_rate_divisor)then
        clk_divider <= clk_divider+1;        
      else
        clk_divider <= 0;
        baud_rate_clk <= not(baud_rate_clk);
      end if;
    end if;
  end process;
  
  led_testing <= baud_rate_clk;

  process(baud_rate_clk)
  begin
    if(rising_edge(baud_rate_clk))then
    
      case tx_state is
        when tx_idle =>
          o_tx_done      <= '0';
          o_tx_line_busy <= '0';
          index_counter  <=  0;
          
          if(i_tx_start='0')then
            tx_data_byte <= i_tx_data_bits;
            tx_state <= tx_start;
          else
            tx_state <= tx_idle;
          end if;
          
        when tx_start =>
          o_tx_line_busy <= '1';
          o_serial_data <= '0';
          tx_state <= tx_data;
          
        when tx_data =>
          o_serial_data <= tx_data_byte(index_counter);
          
          if(index_counter<7)then            
            index_counter <= index_counter+1;
            tx_state <= tx_data;
          else
            tx_state <= tx_stop;
          end if;
          
        when tx_stop =>
          o_serial_data <= '1';
          o_tx_done <= '1';
          tx_state <= tx_idle;
        
        when others =>
          tx_state <= tx_idle;
      end case;
    end if;
  end process;
  
  test_led <= i_tx_start;

end behav; 


and the test bench for above code is give
LIBRARY ieee  ; 
LIBRARY std  ; 
USE ieee.NUMERIC_STD.all  ; 
USE ieee.std_logic_1164.all  ; 
USE ieee.std_logic_textio.all  ; 
USE ieee.std_logic_unsigned.all  ; 
USE std.textio.all  ; 
ENTITY tx_test_bench  IS 
  GENERIC (
    baud_rate_divisor  : INTEGER   := 520 ); 
END ; 
 
ARCHITECTURE tx_test_bench_arch OF tx_test_bench IS
  SIGNAL i_inclk   :  STD_LOGIC  ; 
  SIGNAL led_testing : STD_LOGIC;
  SIGNAL i_tx_start   :  STD_LOGIC  ; 
  SIGNAL o_tx_line_busy   :  STD_LOGIC  ;
  SIGNAL i_tx_data_bits   :  STD_LOGIC_VECTOR (0 to 7)  ; 
  SIGNAL o_serial_data   :  STD_LOGIC  ; 
  SIGNAL o_tx_done   :  STD_LOGIC  ; 
  SIGNAL i_reset   :  STD_LOGIC  ; 

  COMPONENT uart_tx  
    GENERIC ( 
      baud_rate_divisor  : INTEGER  );  
    PORT ( 
      i_inclk  : in STD_LOGIC ;
    led_testing : out STD_LOGIC;  
      i_tx_start  : in STD_LOGIC ; 
      o_tx_line_busy  : out STD_LOGIC ; 
      i_tx_data_bits  : in STD_LOGIC_VECTOR (0 to 7); 
      o_serial_data  : out STD_LOGIC ; 
      o_tx_done  : out STD_LOGIC ; 
      i_reset  : in STD_LOGIC ); 
  END COMPONENT ; 
BEGIN
  DUT  : uart_tx  
    GENERIC MAP ( 
      baud_rate_divisor  => baud_rate_divisor   )
    PORT MAP ( 
      i_tx_start   => i_tx_start  ,
      i_inclk   => i_inclk  ,
      i_tx_data_bits   => i_tx_data_bits  ,
      o_serial_data   => o_serial_data  ,
      o_tx_line_busy   => o_tx_line_busy  ,
      o_tx_done   => o_tx_done  ,
    led_testing => led_testing,
      i_reset   => i_reset   ) ; 



-- "Clock Pattern" : dutyCycle = 50
-- Start Time = 0 ps, End Time = 100 ms, Period = 20 ns
  Process
  Begin
   i_inclk  <= '0'  ;
  wait for 10 ns ;
   i_inclk  <= '1'  ;
  wait for 10 ns ;
-- dumped values till 100 ps

 End Process;


-- "Constant Pattern"
-- Start Time = 0 ps, End Time = 10 ps, Period = 0 ps
  Process
  Begin
  wait until rising_edge(led_testing);
  i_tx_start  <= '1'  ;
  i_tx_data_bits  <= "10101010"  ;
  wait until rising_edge(led_testing);
  i_tx_start <= '0';
  wait until o_tx_done<='1';
---- dumped values till 10 ps
  wait;
 End Process;

end;


iam also attaching the simulated output

Author: Lothar M. (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Hareesh M. wrote:
> the test bench for above code is
Drive i_reset with a defined value.

> when i try to use terminal for transmission there is no output.
What terminal? Do you mean when you implement that design on real 
hardware? What does a scope or a logic analyzer show?

This is bad design practice:
    baud_rate_clk <= not(baud_rate_clk);
:
:
    if(rising_edge(baud_rate_clk))then
Don't use divided locally distributed clocks in a FPGA. Instead use 
clock enables and only one clock overall the FPGA!

: Edited by Moderator
Author: Hareesh M. (Company: Mindteck) (hareeshp)
Posted on:

Rate this post
0 useful
not useful
Lothar M. wrote:
> Hareesh M. wrote:
>> the test bench for above code is
> Drive i_reset with a defined value.

Ok i will do it. Thanks for the comment
>
>> when i try to use terminal for transmission there is no output.
> What terminal? Do you mean when you implement that design on real
> hardware? What does a scope or a logic analyzer show?

I have connected the
o_serial_data
 to a gpio in fpga dev board and used a rs232 to usb cable to see the 
output in pc
>
> This is bad design practice:
>
>     baud_rate_clk <= not(baud_rate_clk);
> :
> :
>     if(rising_edge(baud_rate_clk))then
> 
> Don't use divided locally distributed clocks in a FPGA. Instead use
> clock enables and only one clock overall the FPGA!

Thanks for your comment, but if i use a enable signal will i get a clock 
as output. Does 9600bps baud rate generation is fine?

Author: Lothar M. (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Hareesh M. wrote:
> I have connected the o_serial_data to a gpio in fpga dev board and used
> a rs232 to usb cable to see the output in pc
What cable?
You know, that RS232 has very different signal levels than your FPGA 
output pin?

> Does 9600bps baud rate generation is fine?
Not the way you do it.

> but if i use a enable signal will i get a clock as output.
???
You got lost somewhere. A clock enable is simply implemented in your 
code:
  signal baud_tic   : std_logic:='0'; -- the clock enable signal
:
:
  process(i_reset,i_inclk)
  begin
    if(i_reset='0')then
      clk_divider<=0;
    elsif(rising_edge(i_inclk))then   -- ONLY ONE AND THE SAME CLOCK in the whole design!
      if(clk_divider<1234)then        -- adapt this value
        clk_divider <= clk_divider+1; 
        baud_tic <= '0';
      else
        clk_divider <= 0;
        baud_tic <= '1';              -- clock enable active for one clock cycle
      end if;
    end if;
  end process;
  
  led_testing <= baud_rate_clk;

  process(i_inclk)
  begin
    if(rising_edge(i_inclk))then      -- ONLY ONE AND THE SAME CLOCK in the whole design!
    if baud_tic='1' then              -- this is the clock enable
      case tx_state is
        when tx_idle =>
          o_tx_done      <= '0';
          o_tx_line_busy <= '0';
          index_counter  <=  0;
:
:

: Edited by Moderator
Author: Hareesh M. (Company: Mindteck) (hareeshp)
Posted on:

Rate this post
0 useful
not useful
Lothar M. wrote:
> Hareesh M. wrote:
>> I have connected the o_serial_data to a gpio in fpga dev board and used
>> a rs232 to usb cable to see the output in pc
> What cable?
> You know, that RS232 has very different signal levels than your FPGA
> output pin?

The gpio which i have connected in fpga dev board is of 3.3V and the 
rs232 voltage level range between  +3 to +15 volts or the range −3 to 
−15

Author: Lothar M. (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Hareesh M. wrote:
> The gpio which i have connected in fpga dev board is of 3.3V and the
> rs232 voltage level range between  +3 to +15 volts or the range −3 to −15
And does this fit togeher? And does the polarity of a '1' and a '0' fit 
together?

A hint: look for a levelshifter like MAX3232

Or better: look for a "ttl 3V RS232-USB adapter"
https://www.google.com/search?q=ttl+3V+RS232-USB+adapter

: Edited by Moderator
Author: Hareesh M. (Company: Mindteck) (hareeshp)
Posted on:
Attached files:

Rate this post
0 useful
not useful
Lothar M. wrote:
> Hareesh M. wrote:
>> The gpio which i have connected in fpga dev board is of 3.3V and the
>> rs232 voltage level range between  +3 to +15 volts or the range −3 to −15
> And does this fit togeher? And does the polarity of a '1' and a '0' fit
> together?
>
> A hint: look for a levelshifter like MAX3232
>
> Or better: look for a "ttl 3V RS232-USB adapter"
> https://www.google.com/search?q=ttl+3V+RS232-USB+adapter

I have attached the cable picture.And i tried to probe the signal in CRO 
also, but nothing is coming.

Author: Lothar M. (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Hareesh M. wrote:
> I have attached the cable picture.
Ok, a 3V-RS232 levelshifter is necessary with that.

Author: Lothar M. (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Hareesh M. wrote:
> i tried to probe the signal in CRO also
CRO? Whtas the long meaning of that TLA?

Author: Hareesh M. (Company: Mindteck) (hareeshp)
Posted on:

Rate this post
0 useful
not useful
Lothar M. wrote:
> Hareesh M. wrote:
>> i tried to probe the signal in CRO also
> CRO? Whtas the long meaning of that TLA?

I meant the oscilloscope.

Author: Lothar M. (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Hareesh M. wrote:
> but nothing is coming.
So you must dig into that: why is there nothing?
Do you activate the i_tx_start signal in your hardware?

Can you see anything on your led_testing output?

Author: Hareesh M. (Company: Mindteck) (hareeshp)
Posted on:

Rate this post
0 useful
not useful
Lothar M. wrote:
> Hareesh M. wrote:
>> but nothing is coming.
> So you must dig into that: why is there nothing?
> Do you activate the i_tx_start signal in your hardware?
>
> Can you see anything on your led_testing output?

i have connected the signal i_tx_start to a push button.

clock out is coming at led_testing.

Author: Lothar M. (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Hareesh M. wrote:
> i have connected the signal i_tx_start to a push button.
Just a simple button? Without a additional pullup or a pulldown? And 
what signal level do you measure at that input?

What happens when you change your code in a way that the transmission 
always starts on its own in an endless loop? For debugging I would add 
thre additional LED and set one of them in each state of that FSM to 
see, where the thing stucks.

: Edited by Moderator
Author: Hareesh M. (Company: Mindteck) (hareeshp)
Posted on:

Rate this post
0 useful
not useful
Lothar M. wrote:
> Hareesh M. wrote:
>> i have connected the signal i_tx_start to a push button.
> Just a simple button? Without a additional pullup or a pulldown? And
> what signal level do you measure at that input?

A button with a pull down.

>
> What happens when you change your code in a way that the transmission
> always starts on its own in an endless loop? For debugging I would add
> thre additional LED and set one of them in each state of that FSM to
> see, where the thing stucks.

Actually i have tried this, and the led is set when code go into each 
state.

Author: Hareesh M. (Company: Mindteck) (hareeshp)
Posted on:

Rate this post
0 useful
not useful
Lothar M. wrote:
> Hareesh M. wrote:
>> I have connected the o_serial_data to a gpio in fpga dev board and used
>> a rs232 to usb cable to see the output in pc
> What cable?
> You know, that RS232 has very different signal levels than your FPGA
> output pin?
>
>> Does 9600bps baud rate generation is fine?
> Not the way you do it.

Could you please suggest the changes??

Author: Lothar M. (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Hareesh M. wrote:
> Could you please suggest the changes??
I did. With the "clock enable" the design is whats called "synchonous".

Hareesh M. wrote:
> Actually i have tried this, and the led is set when code go into each
> state.
So you see on the LED your design stepping throughout the 4 states? But 
you don't see any changes on o_serial_data although its set in 
tx_stop and it reset in tx_start?

Author: hareesh (Guest)
Posted on:

Rate this post
0 useful
not useful
Lothar M. wrote:
> Hareesh M. wrote:
>> Could you please suggest the changes??
> I did. With the "clock enable" the design is whats called "synchonous".
>
> Hareesh M. wrote:
>> Actually i have tried this, and the led is set when code go into each
>> state.
> So you see on the LED your design stepping throughout the 4 states? But
> you don't see any changes on o_serial_data although its set in
> tx_stop and it reset in tx_start?

Hi  Lothar ,
The signals are coming in o_serial_data. the issue was with the i_reset 
signal.
Thanks for your valuable comments. Now i need to use a usb to serial 
cable to see the signals in pc.

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