Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

UART Transmit issue with CPLD

Status
Not open for further replies.

reservevoltage

Newbie level 4
Joined
Feb 27, 2020
Messages
6
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
63
Hello,
I have a demo card named cpld c-m240 epm240t100c5n.
I tried to send the data with uart and have a synchronous problem. (ı think)
According to my basic information in Uart communication, the duration of 1 or 0 for each bit (at 9600 baudrat and 50Mhz clok) is 104us.

I divided the 50Mhz to 9600 and created a counter according to the result.
Unfortunately ı could not figure out test bench logic. That is why the code is running without a simulation.
I had realized differences between sended byte and described byte at code when ı read the sended value from realterm.

My code is below. Does anyone hava a suggestion?
Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_SIGNED.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;

entity main is
    Generic ( 
        CLK_FREKANS : integer := 50000000;
        BAUDRATE : integer 	:= 9600
    );
    Port(
		in_clk : in std_logic;
        in_rst : in std_logic;
        in_tx_start : in std_logic;
        in_tx_data : in std_logic_vector(7 downto 0):="10101010";--sended data
        out_tx : out std_logic;
        out_tx_ok : out std_logic
    );
    
end main;

architecture Behavioral of main is

    constant CLK_BIT : integer := (CLK_FREKANS / BAUDRATE);--5208
    type t_UART_tx is (IDLE, START_B, SEND_D, STOP_D, Transmit_OK);
    signal r_UART_tx : t_UART_tx := IDLE;
    
    signal r_clk_counter : integer range 0 to CLK_BIT-1 := 0; -- 0 to 5207
    signal r_data_ind : integer range 0 to 7 := 0; 
    signal r_data   : std_logic_vector(7 downto 0) := (others => '0');
    signal r_tx : std_logic := '1';
    signal r_tx_ok : std_logic := '0';     
	 signal counter: integer range 0 to 96000:=0;

begin
		
    out_tx <= r_tx;
    out_tx_ok <= r_tx_ok;
process(in_clk, in_rst)
    begin
        if in_rst = '1' then
            r_UART_tx <= IDLE;
            r_clk_counter <= 0;
            r_data_ind <= 0;
            r_data <= (others => '0');
            r_tx <= '1';
            r_tx_ok <= '0';
            
        elsif rising_edge(in_clk) then
            r_tx_ok <= '0';
            case r_UART_tx is
			       --------------------------------------------------------------
                when IDLE =>
							--r_tx <= '1'; 
							r_clk_counter <= 0;
							r_data_ind <= 0;
						   if in_tx_start = '1' then
								r_data <= in_tx_data;
								r_UART_tx <= START_B;
							end if;  
                    
					 --------------------------------------------------------------	  
                when START_B =>
                     if r_clk_counter = CLK_BIT then --=5207
                        r_clk_counter <= 0;
								r_tx <= '0';
                        r_UART_tx <= SEND_D;                        
                     else
						       r_clk_counter <= r_clk_counter + 1;
                     end if;
					 
					 
					 --------------------------------------------------------------
					 when SEND_D =>      
                     if r_clk_counter = CLK_BIT then --=5207
								r_clk_counter <= 0;
								r_tx  <= r_data(r_data_ind);
                        if r_data_ind = 7 then
							    r_data_ind <= 0;
                                r_UART_tx <= STOP_D;   
                        else
									r_data_ind <= r_data_ind + 1;
                        end if;     
							else
							r_clk_counter <= r_clk_counter + 1;
							end if;
							
						
					  --------------------------------------------------------------
 					 when STOP_D =>
                      if r_clk_counter = CLK_BIT then --=5207--=5207
                         r_clk_counter <= 0;
								 r_tx  <= '1';
                         --r_UART_tx <= Transmit_OK;  
								 if counter=96000 then
								    r_UART_tx <= Transmit_OK; 
								 else 
								    counter<=counter+1;
								 end if;
                      else
						       r_clk_counter <= r_clk_counter + 1;
                      end if;
					  --------------------------------------------------------------
					  when Transmit_OK =>
				          r_tx  <= '1';
                      r_tx_ok <= '1';
                      r_UART_tx <= IDLE;
							 
					  when others => NULL;
				end case;
			end if;			
end process;
end Behavioral;
 

A first sight, you are defining

Code:
signal r_clk_counter : integer range 0 to CLK_BIT-1 := 0;

but comparing
Code:
if r_clk_counter = CLK_BIT then
which never occurs.

There may be more errors.

- - - Updated - - -

Also wrong sequence. Output is set to '0' after start bit but should be set to data LSB.

What do you mean with "could not figure out test bench logic"? Don't understand VHDL? Test bench for TX is really simple, just generate clock, reset and start, then watch internal states and output in wave viewer.
 

Hi FvM,

ı have changed some line at my code and wrote test bench code.

However still ı can not communicate with PC by using usb TTL. I have no ıdea what ı have to do.

Could you examine the code and please tell me where is my mistake

test code
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
use ieee.std_logic_arith.all;

entity test is
end test;

architecture modul of test is

---------------------------------------------------------------------------------
--COMPONENT definition
---------------------------------------------------------------------------------
component TX_MODUL
port
	  (clk: 		in std_logic;
		reset:  	in std_logic;
		data: 		in std_logic_vector( 7 downto 0);
		flag: 		out std_logic;
		transmit:	out std_logic);
end component TX_MODUL;
---------------------------------------------------------------------------------
--SIGNAL definition
---------------------------------------------------------------------------------
signal clk		: std_logic:='0';
signal reset		: std_logic:='0';
signal data		: std_logic_vector( 7 downto 0):= (others => '0');
signal flag		: std_logic:='0';
signal transmit	: std_logic:='1';
---------------------------------------------------------------------------------
--time definition
---------------------------------------------------------------------------------
signal board_osc_period : time := 20 ns;


begin
---------------------------------------------------------------------------------
--COMPONENT equalization
---------------------------------------------------------------------------------
C1: TX_MODUL   port map (
					clk		=> clk,
					reset		=> reset,
			   	data		=> data,
					flag		=> flag,
					transmit	=> transmit					
				   );
				 
zamanlama: process
			  begin
			  clk<='0';
			  wait for board_osc_period/2;
			  clk<='1';
			  wait for board_osc_period/2;
			  end process;
	
transmint: process
			  begin
			  wait for 10 us;
			  flag<='0';
			  data<="11110000";
			  wait for 1 us;
			  flag<='1';  
			  wait for 1 us;
			  end process;
			  

end modul;


TX code
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
use ieee.std_logic_arith.all;

entity TX_MODUL is
port
	(
		clk: 			in std_logic;
		reset:  		in std_logic;
		data: 		in std_logic_vector( 7 downto 0);
		flag: 		out std_logic;
		transmit:	out std_logic);
end TX_MODUL;

architecture modul of TX_MODUL is		

signal idle_counter: integer range 0 to 52085:=0;
															
signal counter: integer range 0 to 5209:=0;
signal index  : integer range 0 to 7:=0;
signal b_data : std_logic_vector( 7 downto 0):="00000000";
signal b_transmit: std_logic:='1';
signal b_flag: std_logic:='0';

type state_m is(IDLE, START, SEND, STOP);
signal state_new: state_m :=IDLE;
begin
transmit <= b_transmit;
flag	 <= b_flag;

process(clk,reset)
	begin
		if (reset='1') then
			counter<=0;
			index<=0;
			b_transmit<='1';
			b_flag<='0';
			b_data<="00000000";
			state_new<=IDLE;
		
		elsif rising_edge(clk) then
			case state_new is
				--------------------------------------
				when IDLE=>
					if counter=5208 then    --added
						index<=0;				
						counter<=0;
						b_transmit<='1';
						if (b_flag='0') then
							b_data<=data;
							b_flag<='1';
							state_new<=START;
						end if;
					else counter<=counter+1;
					end if;--eklendi
				--------------------------------------
				when START=>
				b_transmit<='0';                  --changed line
					if counter=5208 then
						
						counter<=0;
						state_new<=SEND;
					else counter<= counter+1;
					end if;
				--------------------------------------
				when SEND=>
				b_transmit<=b_data(index);        --changed line
					if counter=5208 then   
						if index=7 then
						   index<=0;
						   state_new<=STOP;
						else index<= index+1;
						end if;
						counter<=0;
					else counter<= counter+1;
					end if;
				--------------------------------------
				when STOP=>
					if counter=5208 then
						b_transmit<='1';
						counter<=0;
						b_flag<='0';
						state_new<=IDLE;
					else counter<=counter+1;
					end if;
			end case;		
		end if;
end process;
end modul;

- - - Updated - - -

Hi,
Code was previous version. Accidentally posted.
New version is a below.

Transmit
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
use ieee.std_logic_arith.all;

entity tx is
port
	(
		clk: 		in std_logic;
		reset:  	in std_logic;
		data: 		in std_logic_vector( 7 downto 0);
		flag: 		out std_logic;
		transmit:	out std_logic);
end tx;

architecture modul of tx is		

															
signal counter: integer range 0 to 5209:=0;
signal index  : integer range 0 to 7:=0;
signal b_data : std_logic_vector( 7 downto 0):="00000000";
signal b_transmit: std_logic:='1';
signal b_flag: std_logic:='0';

type state_m is(IDLE, START, D0,D1,D2,D3,D4,D5,D6,D7, STOP1,STOP2,SecureDelay);
signal state_new: state_m :=IDLE;
begin
transmit <= b_transmit;
flag	 <= b_flag;

process(clk,reset)
	begin
		if (reset='1') then
			counter<=0;
			index<=0;
			b_transmit<='1';
			b_flag<='0';
			b_data<="00000000";
			state_new<=IDLE;
		
		elsif rising_edge(clk) then
			case state_new is
				--------------------------------------
				when IDLE=>
				b_transmit<='1';
				index<=0;
				counter<=0;
				if(b_flag<='0') then
				   b_data<=data;
				   b_flag<='1';
				   state_new<=START;
				end if;
				--------------------------------------
				when START=>
				b_transmit<='0';
				if counter=5208 then				   
				   counter<=0;
				   state_new<=D0;
				else counter<= counter+1;
				end if;
				--------------------------------------
				when D0=>
				b_transmit<=b_data(0);
				if counter=5208 then
				   counter<=0;  
				   state_new<=D1;
				else counter<= counter+1;
				end if;
				--------------------------------------
				when D1=>
				b_transmit<=b_data(1);
				if counter=5208 then
				   counter<=0;
				   state_new<=D2;
				else counter<= counter+1;
				end if;
				--------------------------------------
				when D2=>
				b_transmit<=b_data(2);
				if counter=5208 then
				   counter<=0;
				   state_new<=D3;
				else counter<= counter+1;
				end if;
				--------------------------------------
				when D3=>
				b_transmit<=b_data(3);
				if counter=5208 then
				   counter<=0;
				   state_new<=D4;
				else counter<= counter+1;
				end if;
				--------------------------------------
				when D4=>
				b_transmit<=b_data(4);
				if counter=5208 then
				   counter<=0;
				   state_new<=D5;
				else counter<= counter+1;
				end if;
				--------------------------------------
				when D5=>
				b_transmit<=b_data(5);
				if counter=5208 then
				   counter<=0;
				   state_new<=D6;
				else counter<= counter+1;
				end if;
				--------------------------------------
				when D6=>
				b_transmit<=b_data(6);
				if counter=5208 then
				   counter<=0;
				   state_new<=D7;
				else counter<= counter+1;
				end if;
				--------------------------------------
				when D7=>
				b_transmit<=b_data(7);
				if counter=5208 then
				   counter<=0;
				   state_new<=STOP1;
				else counter<= counter+1;
				end if;
				--------------------------------------
				when STOP1=>
				b_transmit<='1';
				if counter=5208 then
				   counter<=0;
				   state_new<=STOP2;
				else counter<= counter+1;
				end if;
				--------------------------------------
				when STOP2=>
				 b_transmit<='1';
				if counter=2604 then
				   counter<=0;
				   state_new<=SecureDelay;
				else counter<= counter+1;
				end if;
				--------------------------------------
				When SecureDelay=>
				b_transmit<='1';
				if counter=5208 then
				   counter<=0;
				   b_flag<='0';
				   state_new<=IDLE;
				 else counter<= counter+1;
				end if;	
			end case;		
		end if;
    end process;
end modul;

Test
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
use ieee.std_logic_arith.all;

entity test is
end test;

architecture modul of test is

---------------------------------------------------------------------------------
--COMPONENT definition
---------------------------------------------------------------------------------
component tx
port
	  (clk: 			in std_logic;
		reset:  		in std_logic;
		data: 		in std_logic_vector( 7 downto 0);
		flag: 		out std_logic;
		transmit:	out std_logic);
end component tx;
---------------------------------------------------------------------------------
--SIGNAL definition
---------------------------------------------------------------------------------
signal clk			: std_logic:='0';
signal reset		: std_logic:='0';
signal data			: std_logic_vector( 7 downto 0):= (others => '0');
signal flag			: std_logic:='0';
signal transmit	: std_logic:='1';
---------------------------------------------------------------------------------
--time definition
---------------------------------------------------------------------------------
signal board_osc_period : time := 20 ns;


begin
---------------------------------------------------------------------------------
--COMPONENT equalization
---------------------------------------------------------------------------------
C1: tx   port map (
					clk		=> clk,
					reset		=> reset,
			   	data		=> data,
					flag		=> flag,
					transmit	=> transmit					
				   );
				 
zamanlama: process
			  begin
			  clk<='0';
			  wait for board_osc_period/2;
			  clk<='1';
			  wait for board_osc_period/2;
			  end process;
	
transmint: process
			  begin
			  wait for 100 us;
			  flag<='0';
			  data<="11001100";
			  wait for 1040 us;
			  flag<='1';  
			  wait for 100 us;
			  end process;
			  

end modul;
 

However still ı can not communicate with PC by using usb TTL. I have no ıdea what ı have to do.
Run the code and the testbench in a simulator and observe in the waveform view what the design is doing and debug why it isn't doing what it was supposed to do. As you already have a testbench run it in the simulator and display the waveform starting with the data you are inputting and look at how it gets serialized and sent.

If the design works in simulation and not on hardware then look carefully at the timing constraints and make sure you don't have any unconstrained paths.

Could you examine the code and please tell me where is my mistake
That is your job. You will learn more if you make the effort to learn how to debug the code you've written in a simulator.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top