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.

[SOLVED] Problem with using UART on ML401 board

Status
Not open for further replies.

usamaaslam1

Newbie level 6
Joined
Aug 21, 2009
Messages
11
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,355
hi

i have written a vhdl code for the transmitter and reciver of UART. I am facing difficulties in getting the synchronization between my PC and ML401. the code is attached.

Anyone plz help me in correcting my code.

Secondly i want to know how can i send binary value using UART


Regards

Usama Bin Aslam
 

Attachments

  • Uart_test.rar
    2.5 KB · Views: 81

The main problem in your code is that you check at the actual baudrate.

The actual checking is best done on a multiple of the baudrate, typically a factor 16 higher.
When the start bit is detected we wait 8+16 cycles before we read the data (we should then be at exactly half the bit length of the first data bit). Then we wait 16 cycles before we read the next bit, etc.
Because we 'scan' at a higher rate, we can also do some additional checks. For example, we don't just wait for a single transition to detect the start bit, but we wait until we have detected it 4 times consecutively (for example). This way we don't risk on acting on a 'glitch' in the data. The same can apply to checking the state of a data bit. Instead of checking during a single cycle, we could just count how many times (during 16 cycles) the level is '1' or '0'. If we have more '1's than '0's then we have detected a '1', otherwise a '0'. We must make sure that this 'counting' starts at the point that we expect a data bit to begin.
In short, when scanning at a higher rate we can make sure that we are 'more in sync', and we can include some 'filtering'/'error checking' on the data we receive.
 

thanks for the reply Marcel.

so u need to say that actually if i am using a baud rate of 115200 then according to this my cycle counter value is 348. i need to check for the data at 348 + 16 cycle???? or it should be 348 + 174???? kindly clear me on this.

thanks
 

No, instead of a divider of 348, you use a divider of 348/16 = 21. So the clock becomes 16*115200 = 1843200 (40 MHz/183200 = 21).
Since this clock is 16 times higher than the actual baudrate we can now check the received data 16 times instead of just once.
If we now detect the start bit and then wait half a bit time (8 cycles) then we know that we are at half the start bit. After that we can check after 16 cycles (we are than at half of the first data bit), the next after again 16 cycles etc.
This way we check at the 'center' of each received data bit whcih is more reliable.
Like I said in an earlier post, we have the ability to scan the data and can add code that makes the detection more reliable, like 'filtering' (not acting on momentarily changed signals).
 

Hey Marcel,

i have done wat u said. for that my code is working alright wen i run my testbench. but wen i run it oon the ML401 i face problems. kindly check the code and please let me know abt my mistakes
 

Attachments

  • UART_Single.rar
    2.7 KB · Views: 87

First some 'generic' remarks.

Since the receiver state machine is a clocked process, you only need 'int_clk' in the sensitivity list if I am not mistaken.

Note that you use 'int_clk' as a derived clock, which is not always a good thing.
If you want to use the 'master' clock (clk) then simply combine the baudrate and receiver state.
Something like this:

process (Clk)
if rising_edge(Clk)
clk_count <= clk_count - 1;
if (clk_count = "00000")
clk_count <= "10101";
case State_RX_0 is
.....
end case;
end if;
end if;
end process;

Now the clocked state machine runs at the rising edge of the master clock.

I find your process for creating the baudrate a little difficult to
understand. If you want to toggle the 'int_clk' every 21 clk cycles
then the following will do too.

process (Clk)
if rising_edge(Clk)
clk_count <= clk_count - 1;
if (clk_count = "00000")
clk_count <= "10101";
int_clk <= not int_clk;
else
int_clk <= int_clk;
end if;
end if;
end process;

If you want the 'int_clk' just active for one 'clk' cycle then use.

process (Clk)
if rising_edge(Clk)
clk_count <= clk_count - 1;
if (clk_count = "00000")
clk_count <= "10101";
int_clk <= '1';
else
int_clk <= '0';
end if;
end if;
end process;

You don't always need a reset signal. Since 'clk_count', even if it has
an 'unknown' value, will always count down (or up) to the value we check,
we are always sure it will run correctly at some stage (and within a
reasonable time). Only when synchronization or a correct initialization
is of importance, you need
to use a reset. You then also have the option to use a synchronous
or asynchronous reset. If I remember correctly a synchronous reset
uses less resources.

Asynchronous reset:
process (Clk)
if (reset = '1')
..
else
if rising_edge(Clk)
..
end if;
end if;
end process;

Synchronous reset:
process (Clk)
if rising_edge(Clk)
if (reset = '1')
..
else
..
end if;
end if;
end process;


Note: All the code I present here is not checked in any way ....


I don't know about your test bench, but you can use a 'real' test bench
(you put i defined data and check the result), or you just create
a very basic one and check the signals 'manually'/'visibly'.
In general, if the test bench indicates that everything works properly
(and I assume then that the test bench is correctly setup), then
a real implementation should also be succesfull. If not, then either
the idea (what the code does) or the test bench is not correct.

It seems that the first data bit is checked 12 int_clk cycles after
detecting the start bit (10 * RX_0_IDLE + 1 * RX_0_START + 1 * RX_0_DATA).
This should, I think. be at least 16+8 = 24 int_clk cycles after
detecting the start bit. 24 int_cycle would be at halve the first data bit.


For an example on an UART sample from me, look here:

it also includes test benches.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top