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.

Help with UART vhdl code

Status
Not open for further replies.

PeterUK2009

Member level 4
Joined
Jun 21, 2009
Messages
72
Helped
2
Reputation
4
Reaction score
2
Trophy points
1,288
Activity points
2,117
Hi guy I need some help here!

I am trying to do something that suppose to be really simple but its taking me some time!

The goal is to produce a HDL code which send a letter to the PC by the serial port UART.

the communication is

19200 b. rate
8 bits data
1 bit start
1 bit stop
no party
no error

so 1 bit start by 8 bits of data and the 1 bit stop!

the stop tick rate at 16

I am try to send the letter A which is 41 hex which is 00100001 binary and I am getting in the PC the symbol "." which is 2e hex and "00101110" binary


The hardware is a Spartan 3 board at 50 M clock from xilinx

I would like to add that I have run the manufacture test which write spartan dev 3 kit ( or something like that) and it works fine. Therefore, the board, the max232, the cable, the PC, and the serial application is working fine!

I am attaching a link there my vhdl code and also the ucf code.

Thanks for reading looking forward to hear from you!

entity uart_sendOnly is
generic(
N: integer := 8; -- number of bits
M: integer := 163; -- mod-M
DBIT: integer:=8; -- # data bits
SB_TICK: integer:=16 -- #
);
port(

clk, reset: in std_logic;
tx_start: in std_logic;
-- s_tick: in std_logic;
din: in std_logic_vector(7 downto 0):= "01000001";
tx_done_tick: out std_logic;
tx: out std_logic
);
end uart_sendOnly;

architecture Behavioral of uart_sendOnly is
--mod m counter
signal tick: std_logic;
signal r_reg: unsigned(N-1 downto 0);
signal r_next: unsigned(N-1 downto 0);
signal s_delay: std_logic_vector(15 downto 0) := "0000000000000000";
------
type state_type is (idle, start, data, stop, delay_t);
signal state_reg, state_next: state_type;
signal s_reg, s_next: unsigned(3 downto 0);
signal n_reg, n_next: unsigned(2 downto 0);
signal b_reg : std_logic_vector(7 downto 0) := "01000001";--A --have the word to be sent
signal b_next: std_logic_vector(7 downto 0);
signal tx_reg, tx_next: std_logic;

begin
-- register for mod m
process(clk,reset)
begin
if (reset='1') then
r_reg <= (others=>'0');
elsif (clk'event and clk='1') then
r_reg <= r_next;
end if;
end process;
-- next-state logic
r_next <= (others=>'0') when r_reg=(M-1) else
r_reg + 1;
-- output logic
-- q <= std_logic_vector(r_reg);
tick <= '1' when r_reg=(M-1) else '0';
process(tick)
begin
if (tick = '1') then
-- s_delay <= s_dealy +1;
end if;
end process;
------------------finish mod m
-- FSMD state & data registers
process(clk,reset)
begin
if reset='1' then
state_reg <= idle;
s_reg <= (others=>'0');
n_reg <= (others=>'0');
b_reg <= (others=>'0');
tx_reg <= '1';
elsif (clk'event and clk='1') then
state_reg <= state_next;
s_reg <= s_next;
n_reg <= n_next;
b_reg <= b_next;
tx_reg <= tx_next;
end if;
end process;
-- next-state logic & data path functional units/routing
process(state_reg,s_reg,n_reg,b_reg,tick,
tx_reg,tx_start,din)
begin
state_next <= state_reg;
s_next <= s_reg;
n_next <= n_reg;
b_next <= b_reg;
tx_next <= tx_reg ;
tx_done_tick <= '0';
case state_reg is
when idle =>
tx_next <= '1';
if tx_start='1' then
state_next <= start;
s_next <= (others=>'0');
b_next <= din;
end if;
when start =>
tx_next <= '0';
-- if (s_tick = '1') then
if (tick = '1') then
if s_reg=15 then
state_next <= data;
s_next <= (others=>'0');
n_next <= (others=>'0');
else
s_next <= s_reg + 1;
end if;
end if;
when data =>
tx_next <= b_reg(0);
-- if (s_tick = '1') then
if (tick = '1') then
if s_reg=15 then
s_next <= (others=>'0');
b_next <= '0' & b_reg(7 downto 1) ;
if n_reg=(DBIT-1) then
state_next <= stop ;
else
n_next <= n_reg + 1;
end if;
else
s_next <= s_reg + 1;
end if;
end if;
when stop =>
tx_next <= '1';
-- if (s_tick = '1') then
if (tick = '1') then
if s_reg=(SB_TICK-1) then
state_next <= idle;
tx_done_tick <= '1';
else
s_next <= s_reg + 1;
end if;
end if;
when delay_t =>
tx_next <= '1';
if (s_delay = "1111111111111111") then
state_next <= idle;
else
state_next <= delay_t;
end if;
end case;
end process;


tx <= tx_reg;


end Behavioral;

NET "clk" TNM_NET = "clk";
TIMESPEC "TS_clk" = PERIOD "clk" 20 ns HIGH 50 %;
Net "tx" LOC="R13";
NET "clk" LOC = "T9" ;
NET "reset" LOC = "L14";
NET "tx_done_tick" LOC = "K12"; #led 0
 

This is where a good testbench, modelsim (or similar) and plenty of time to debug comes in handy. (PS. I noticed you're missing s_delay from the state machine sensitivity list).

What are you connecting this bit of code to?
 

I would like to post a update, work today and last night on this code. There is lot of modification done here!

Unfortunately after all work more putting into it still not working

now I have removed s_delay from the stage machine and go through the simulation step by step it look good on the simulation tool but it does not work on the hardware getting different asII symbol.

Any Ideals?

Here is a print screen on the simulation

P.D. notice I add some extra bits at the end so the idle stay longer, just I though maybe the PC need more time to synch but its a waste of code for sure.

2.png
 
P.D. notice I add some extra bits at the end so the idle stay longer, just I though maybe the PC need more time to synch but its a waste of code for sure.
In a fact, a receiving UART would be never able to sync on the start bit, if it connects to the bit stream at an arbitrary moment. You can make the test much more clear by sending a single character after an idle period. The baudrate measured in the simulation is correct for a 9600 Baud 10 bit frame.
 

In a fact, a receiving UART would be never able to sync on the start bit, if it connects to the bit stream at an arbitrary moment. You can make the test much more clear by sending a single character after an idle period. The baudrate measured in the simulation is correct for a 9600 Baud 10 bit frame.

I understand your point of view. about sync, but to be honest is not what I meant I was more thinking the ability of the PC receiving circuit to be ready for the next start bit. But this HDL is giving a long idle so I dont thing its needed any more delay to start the next start bit. I read somewhere that some computer need more than one stop bit, thanks *** no my PC :).

Now I have completed this Thread and tested on my hardware and working I even changed to work at 115200 and all works fine!

I need to get back to this code because I had some problems on the way I was implementing delay! I still cannot switch to think as RT code designer.
 

But this HDL is giving a long idle.
I was referring to the simulation waveform. There's no idle time at all. In this case, synchronization is impossible.

Regarding the "more than one stop bit" question, there are two points involved.
- frame synchronization, as discussed before. It requires at least a full character length idle time.
- in a continuous data stream (after succesful synchronization), a single stop bit is sufficient, if the receiver ends character receiving in the middle of the stop bit. Otherwise, there's a problem, if the transmitter clock is slightly faster. Industry standard UARTs (e.g. in a PC chip set) should comply to this requirement, but if I remember right, some µP UARTs don't consider it.
 
Last edited:

I was referring to the simulation waveform. There's no idle time at all. In this case, synchronization is impossible.

Regarding the "more than one stop bit" question, there are two points involved.
- frame synchronization, as discussed before. It requires at least a full character length idle time.
- in a continuous data stream (after succesful synchronization), a single stop bit is sufficient, if the receiver ends character receiving in the middle of the stop bit. Otherwise, there's a problem, if the transmitter clock is slightly faster. Industry standard UARTs (e.g. in a PC chip set) should comply to this requirement, but if I remember right, some µP UARTs don't consider it.

One question can you post external URL here, Planning to create a tutorial about this but I will host it out side, is that ok? I am getting to many penalties LOL
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top