[SOLVED] Synchronization error in UART

Status
Not open for further replies.

electrobuz

Member level 2
Joined
May 20, 2013
Messages
46
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Visit site
Activity points
1,638
Receive error in UART

Hi,
I want to make a function (in a package file) for Receive function of UART on fpga since I want to call it multiple times for receiving data at different times. The problem is that I will have to send the Clock and UART_RXD signals as attributes. My doubt is that can signals whose values will be change, be send as attributes. Also Is there anything else I can do instead making a function?
Thanks
 

I presume you are talking about Verilog (which I don't know), but I still don't quite understand your problem. For VHDL,for example, you would create a module with a clock input (usually something like a 16-times clock) and your data input. The rate of the clock matches your baud rate. Where is your confusion?
 

The problem is sending a changing signal as an attribute to the function. When I call the function, the value send to the function is the instantaneous value of the signal. But what happens when the signal changes (i.e sending the CLK as and attribute), is this reflected in the function or do I have to call the function again?
 


as far as i undersatnd you need to use vhdl procedures instead of function,
 

I am using VHDL. Yes by function I mean creating the function in the package file and using it.
 

Re: Receive error in UART

I want to call it multiple times for receiving data at different times.
Thanks

A UART Function should always be in polling mode(Asyn), so that you will not miss any data. If you want to call UART Read function at any different time, how will you make sure of the Start\stop transitions and how sure are you in capturing the right data?. I think there is some mis-understanding in your design requirements. Correct me if I am wrong

In case if this is your requirements, you can use procedures, but you cannot use Sequential statements inside a procedure. That being said, no clks can be passed inside. Instead, you can Pass the state transitions based on the clock into procedure. But you more or less trying to code it like a C program. Instead I would say, create a one process for UART Receive using baud clock. Then when ever you need to receive a data from UART, just enable a signal in the UART process from other process and take control.
 

Why not post the code. But if you're using a function in a package, you're probably doing it wrong. The main bulk of your design for a synthesisable design should be a process, not a function. A function should be nothing more than a nice way of presenting your code and be a utililty, not a fully functioning design.
 

It sounds like this is being made a LOT more complicated than it has to be.
1) UART is a PROCESS, with a CLOCK input, a DATA output, a DATA_AVAILABLE output, and maybe an ENABLE input.
2) You can enable or disable the UART with the ENABLE input. Not really sure why you'd do this, but you can
3) You can poll the DATA_AVAILABLE port, or use it to trigger another process to read data when it arrives.
4) Done.
 
Most designs are encapsulating an UART receive function inside a component that also contains the necessary state information like oversampling phase and bit counter.

I presume you'll find a lot of example designs to be used as a template.
 

As FvM correctly points out, UART would not be a process, it would be a component, contrary to what I said in post #9.
 

UART would not be a process, it would be a component
It will be included as a component but still there will be a receive 'process' which will control the signal to be send to UART_receive, i.e a process which will be invoked when new data is comming. (It can have something like UART_BUSY or UART_COMPLETE signals in its sensitivity list). Right?
Also how should I make this process?
This is what I have made, but it doesnt work properly. I want that whenever data is being sent it catches and stores it in a signal D, and I use this value in D wherever I want.


PROCESS(RX_BUSY)
BEGIN
IF(RX_BUSY'EVENT AND RX_BUSY='0')THEN
D <= RX_DATA;
END IF;
END PROCESS;
 

Several points: You should use a clock, not your RX_BUSY signal, for your synchronous process; you also probably want a state machine, something like this (inside a synchronous process):

Code:
case comm_state is
     when idle=>
           if DATA_RCVD then
              comm_state<=s1;
          end if;
     when s1 =>
        --latch the data here
        -- clear the DATA_RCVD flag by reading the data or some other mechanism
   ...
 
Reactions: FvM

    FvM

    Points: 2
    Helpful Answer Positive Rating
I did the following:
Code:
PROCESS(CLOCK_50,State)
BEGIN
case State is
when 0 =>     --idle
	if DATA_RCVD = '1' then
	State <= 1;
	end if;
when 1 =>
	D1 <= RX_DATA;
	State <= 2;
when 2 =>
	D2 <= RX_DATA;
when others => NULL;
end case;
END PROCESS;

Here what I am trying to do is get the first value being sent in D1, then the next value being sent in D2. Then making another process where I am using these D1 and D2.
But I get the following warning and the code does not work when put on the FPGA (Spartan 3E Nexys2)

"WARNINGhysDesignRules:372 - Gated clock. Clock net State_not0001 is sourced by
a combinatorial pin. This is not good design practice. Use the CE pin to
control the loading of data into the flip-flop"
 

The code snippet in your post neither uses a primary clock nor a gated clock. But the warning suggests that a clock is involved in the actual compiled code. So the warning apparently belongs to a different code.

As barry said, the code assigning the state variable and other registered values must be inside a synchronous process, in other words enclosed by a clock edge sensitive condition. And the clock should be a primary design clock, not a gated or divided clock.
 

I will look for the reason for the warning. But, my major concerning is catching values that are being sent. This method of making an FSM and catching them in different signals doesnt seem to be working.
 

instead of posting code snippets that dont match the errors your report, how about posting the whole code so we can have a look?
 

instead of posting code snippets that dont match the errors your report, how about posting the whole code so we can have a look?

Main Code:
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
ENTITY UART IS
PORT(
CLOCK_50: IN STD_LOGIC;
--D: INOUT STD_LOGIC_VECTOR(7 downto 0);
--KEY: IN STD_LOGIC;  --pressed for transmission
LED:OUT STD_LOGIC_VECTOR(7 downto 0);
--UART_TXD:OUT STD_LOGIC;

UART_RXD:IN STD_LOGIC
);
END UART;
 
 
 
ARCHITECTURE MAIN OF UART IS

--SIGNAL TX_DATA: STD_LOGIC_VECTOR(7  downto 0);
--SIGNAL TX_START: STD_LOGIC:='0';
--SIGNAL TX_BUSY: STD_LOGIC;
SIGNAL RX_DATA: STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL RX_BUSY: STD_LOGIC;
SIGNAL DATA_RCVD: std_logic;
SIGNAL D,D1,D2,D3: std_logic_vector(7 downto 0);
SIGNAL Flag1: std_logic:='0';
SIGNAL State: integer:=0;
COMPONENT RX
PORT(
CLK:IN STD_LOGIC;
RX_LINE:IN STD_LOGIC;
DATA:OUT STD_LOGIC_VECTOR(7 downto 0);
BUSY:OUT STD_LOGIC;
DATA_RCVD: out std_logic
);
END COMPONENT RX;
------------------------------------------------------
BEGIN
--C1: TX PORT MAP (CLOCK_50,TX_START,TX_BUSY,TX_DATA,UART_TXD);
C1: RX PORT MAP (CLOCK_50,UART_RXD,RX_DATA,RX_BUSY,DATA_RCVD);
 
 
PROCESS(CLOCK_50,State)
BEGIN
case State is
when 0 =>     --idle
	if DATA_RCVD = '1' then
	State <= 1;
	end if;
when 1 =>
	--if DATA_RCVD = '1' then
	D1 <= RX_DATA;
	State <= 2;
	--else
	--State <= 0;
	--end if;
when 2 =>
--	if DATA_RCVD = '1' then
	D2 <= RX_DATA;
--	end if;
when others => NULL;
end case;
END PROCESS;
 
PROCESS
BEGIN
D3 <= D1 or D2;
LED <= D3;

end process ;
END MAIN;


The RX component is working, I have tested it
 

The shown code is pure combinational, inferring latches rather than registers. A combinational state machine usually won't work in FPGA hardware. The state sequence is also inplausible, because it's stuck at state 2.

The "gate clock" warning can't be related to the shown code.
 

I'm not sure how this is working. As shown, it's just going to hang in state 2. Further, it's going to assign RX_DATA to D1 and D2 every time you receive one data. And you STILL don't have a clocked process.
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…