RS232 post-route simulation issues

J

jonasmaes

Hi, i'm having quite a few problems with writing/simulating a RS232
send module. For example this code:

process(baud_tick)
variable state, nextstate : integer := 0;
begin
case state is
when 0 => if TxD_start = '1' and baud_tick = '1' then nextstate := 1;
busy <= '1'; end if;
when 1 => if baud_tick = '1' then nextstate := 2; TxD <= '0'; end if;
--start
when 2 => if baud_tick = '1' then nextstate := 3; TxD <= TxD_data(0);
end if; --bit0
when 3 => if baud_tick = '1' then nextstate := 4; TxD <= TxD_data(1);
end if; --bit1
when 4 => if baud_tick = '1' then nextstate := 5; TxD <= TxD_data(2);
end if; --bit2
when 5 => if baud_tick = '1' then nextstate := 6; TxD <= TxD_data(3);
end if; --bit3
when 6 => if baud_tick = '1' then nextstate := 7; TxD <= TxD_data(4);
end if; --bit4
when 7 => if baud_tick = '1' then nextstate := 8; TxD <= TxD_data(5);
end if; --bit5
when 8 => if baud_tick = '1' then nextstate := 9; TxD <= TxD_data(6);
end if; --bit6
when 9 => if baud_tick = '1' then nextstate := 10; TxD <= TxD_data(7);
end if; --bit7
when 10 => if baud_tick = '1' then nextstate := 11; TxD <= '1'; end
if; --stopbit1
when 11 => if baud_tick = '1' then nextstate := 12; TxD <= '1'; end
if; --busy <= '0'; end if; --stopbit2
when 12 => if baud_tick = '1' then nextstate := 0; busy <= '0'; end
if;
when others => if baud_tick = '1' then nextstate := 0; TxD <= '0'; end
if; --(***)
end case;
if baud_tick = '0' then
state := nextstate;
end if;
end process;

The baudticks are small pulses that operate at a 115200 Hz frequency.
The behaverioul simulation works fine, but post-route doesnt. I mean
even when you change the TxD to <= '1' at (***), then the simulation
result changes. But it is made that you never get to 'when others'. So
is there something wrong with my declarations of nextstate or so?

I also tried a different approach:

process
begin
wait until rising_edge(TxD_start); busy <= '1;
wait until rising_edge(baud_tick); TxD <= '0'; --start
wait until rising_edge(baud_tick); TxD <= TxD_data(0); --bit0
wait until rising_edge(baud_tick); TxD <= TxD_data(1); --bit1
wait until rising_edge(baud_tick); TxD <= TxD_data(2); --bit2
wait until rising_edge(baud_tick); TxD <= TxD_data(3); --bit3
wait until rising_edge(baud_tick); TxD <= TxD_data(4); --bit4
wait until rising_edge(baud_tick); TxD <= TxD_data(5); --bit5
wait until rising_edge(baud_tick); TxD <= TxD_data(6); --bit6
wait until rising_edge(baud_tick); TxD <= TxD_data(7); --bit7
wait until rising_edge(baud_tick); TxD <= '1'; --stopbit1
wait until rising_edge(baud_tick); TxD <= '1'; --stopbit2
wait until rising_edge(clk_fpga); busy <= '0';
end process;


But it gives the error: line 63: Same wait conditions expected in all
Multiple Waits.
Is that normal? I find it weird that there would be such a restriction.
 
K

KJ

Hi, i'm having quite a few problems with writing/simulating a RS232
send module. For example this code:

process(baud_tick)
variable state, nextstate : integer := 0;
begin
case state is
when 0 => if TxD_start = '1' and baud_tick = '1' then nextstate := 1;
busy <= '1'; end if;
when 1 => if baud_tick = '1' then nextstate := 2; TxD <= '0'; end if;
--start
when 2 => if baud_tick = '1' then nextstate := 3; TxD <= TxD_data(0);
end if; --bit0
when 3 => if baud_tick = '1' then nextstate := 4; TxD <= TxD_data(1);
end if; --bit1
when 4 => if baud_tick = '1' then nextstate := 5; TxD <= TxD_data(2);
end if; --bit2
when 5 => if baud_tick = '1' then nextstate := 6; TxD <= TxD_data(3);
end if; --bit3
when 6 => if baud_tick = '1' then nextstate := 7; TxD <= TxD_data(4);
end if; --bit4
when 7 => if baud_tick = '1' then nextstate := 8; TxD <= TxD_data(5);
end if; --bit5
when 8 => if baud_tick = '1' then nextstate := 9; TxD <= TxD_data(6);
end if; --bit6
when 9 => if baud_tick = '1' then nextstate := 10; TxD <= TxD_data(7);
end if; --bit7
when 10 => if baud_tick = '1' then nextstate := 11; TxD <= '1'; end
if; --stopbit1
when 11 => if baud_tick = '1' then nextstate := 12; TxD <= '1'; end
if; --busy <= '0'; end if; --stopbit2
when 12 => if baud_tick = '1' then nextstate := 0; busy <= '0'; end
if;
when others => if baud_tick = '1' then nextstate := 0; TxD <= '0'; end
if; --(***)
end case;
if baud_tick = '0' then
state := nextstate;
end if;
end process;

The baudticks are small pulses that operate at a 115200 Hz frequency.
The behaverioul simulation works fine, but post-route doesnt. I mean
even when you change the TxD to <= '1' at (***), then the simulation
result changes. But it is made that you never get to 'when others'.
How would it get there? 'nextstate' is an integer that appears to start at
0 and counts up to 12 and then resets back to 0. Your current case
statement covers all 13 of those cases so the 'others' path will never be
hit.
So
is there something wrong with my declarations of nextstate or so?
If the simulation of the original code works and the post-route simulation
does not it is usually indicative of a timing problem. Perform some static
timing analysis, make sure that your testbench inputs do not violate that
timing are the general guidelines to success.
I also tried a different approach:

process
begin
wait until rising_edge(TxD_start); busy <= '1;
wait until rising_edge(baud_tick); TxD <= '0'; --start
wait until rising_edge(baud_tick); TxD <= TxD_data(0); --bit0
wait until rising_edge(baud_tick); TxD <= TxD_data(1); --bit1
wait until rising_edge(baud_tick); TxD <= TxD_data(2); --bit2
wait until rising_edge(baud_tick); TxD <= TxD_data(3); --bit3
wait until rising_edge(baud_tick); TxD <= TxD_data(4); --bit4
wait until rising_edge(baud_tick); TxD <= TxD_data(5); --bit5
wait until rising_edge(baud_tick); TxD <= TxD_data(6); --bit6
wait until rising_edge(baud_tick); TxD <= TxD_data(7); --bit7
wait until rising_edge(baud_tick); TxD <= '1'; --stopbit1
wait until rising_edge(baud_tick); TxD <= '1'; --stopbit2
wait until rising_edge(clk_fpga); busy <= '0';
end process;


But it gives the error: line 63: Same wait conditions expected in all
Multiple Waits.
Is that normal? I find it weird that there would be such a restriction.
What is 'it'? (i.e. what tool is giving the error?). I'm suspecting that
this is a synthesis tool that can not synthesize the code as written (as
opposed to a simulation tool that probably has no trouble with it at all).
If so, you need to review how to write synthesizable code. The problem that
the synthesizer is having is because you're waiting for rising edges of
three different signals at different points in the process and it is having
difficulty figuring out how to implement this.

The general flavor of your first approach with the case statement is closer
but even there the code is kind of clumsy. A somewhat simpler form is shown
below that is 'synthesizer friendly'. Synthesis tools generally choke on
code in the form that you re-wrote it to, sometimes on the first form along
where you look for baud_tick to be 0 at the end of the process.

process(baud_tick)
variable state, nextstate : integer := 0;
begin
if rising_edge(baud_tick) then -- KJ added
case state is
when 0 => if TxD_start = '1' then nextstate := 1;busy <= '1'; end if;
when 1 => nextstate := 2; TxD <= '0'; --start
when 2 => nextstate := 3; TxD <= TxD_data(0); --bit0
when 3 => nextstate := 4; TxD <= TxD_data(1); --bit1
when 4 => nextstate := 5; TxD <= TxD_data(2); --bit2
when 5 => nextstate := 6; TxD <= TxD_data(3); --bit3
when 6 => nextstate := 7; TxD <= TxD_data(4); --bit4
when 7 => nextstate := 8; TxD <= TxD_data(5); --bit5
when 8 => nextstate := 9; TxD <= TxD_data(6); --bit6
when 9 => nextstate := 10; TxD <= TxD_data(7); --bit7
when 10 => nextstate := 11; TxD <= '1'; --stopbit1
when 11 => nextstate := 12; TxD <= '1'; --busy <= '0'; --stopbit2
when 12 => nextstate := 0; busy <= '0';
when others => nextstate := 0; TxD <= '0';
end case;
state <= nextstate;
end if; -- KJ added
end process;

Good luck

KJ
 
J

jonasmaes

What is 'it'? (i.e. what tool is giving the error?). I'm suspecting that
this is a synthesis tool that can not synthesize the code as written (as
opposed to a simulation tool that probably has no trouble with it at all).
If so, you need to review how to write synthesizable code. The problem that
the synthesizer is having is because you're waiting for rising edges of
three different signals at different points in the process and it is having
difficulty figuring out how to implement this.

Yes, you're right, it is the synthesis tool of ISE 9.1i. You say it's
having difficulties to implement this. But is it even possible (2 or
more rising_edges of different signals?) Can you 'help' the synthesis
tool :) Sorry if this is a noobisch question but i'm a newb in terms
of VHDL :)

process(baud_tick)
variable state, nextstate : integer := 0;
begin
if rising_edge(baud_tick) then -- KJ added
case state is
when 0 => if TxD_start = '1' then nextstate := 1;busy <= '1'; end if;
when 1 => nextstate := 2; TxD <= '0'; --start
when 2 => nextstate := 3; TxD <= TxD_data(0); --bit0
when 3 => nextstate := 4; TxD <= TxD_data(1); --bit1
when 4 => nextstate := 5; TxD <= TxD_data(2); --bit2
when 5 => nextstate := 6; TxD <= TxD_data(3); --bit3
when 6 => nextstate := 7; TxD <= TxD_data(4); --bit4
when 7 => nextstate := 8; TxD <= TxD_data(5); --bit5
when 8 => nextstate := 9; TxD <= TxD_data(6); --bit6
when 9 => nextstate := 10; TxD <= TxD_data(7); --bit7
when 10 => nextstate := 11; TxD <= '1'; --stopbit1
when 11 => nextstate := 12; TxD <= '1'; --busy <= '0'; --stopbit2
when 12 => nextstate := 0; busy <= '0';
when others => nextstate := 0; TxD <= '0';
end case;
state <= nextstate;
end if; -- KJ added
end process;


Cool this works!! Thanks a bunch. I'll try to work more with the
static timing analysis.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top