Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > This code works in simulation but not in reality, please help

Reply
Thread Tools

This code works in simulation but not in reality, please help

 
 
FranzH
Guest
Posts: n/a
 
      08-19-2007
Hello,

I have difficulies with the following code. It translates, I can make
a programing file, download it to the chip but the result is not as it
is in simulation and I don't understand why:

The following process sends out bytes by using the PicoBlaze UART
sender macro. The plan is to wait until "SEND_A_BYTE_NOW" gets '1'
and then send out the byte in "BYTE_TO_SEND_NOW". PBCLK is a 50 MHz
clock.

SERIALSENDER: process (PBCLK)
begin
if (rising_edge(PBCLK)) then
if (UART_STATE = B"00") then
write_to_uart <= '0';
if (SEND_A_BYTE_NOW = '1') then
UART_STATE <= B"01";
end if;
elsif (UART_STATE = B"01") then
out_port <= BYTE_TO_SEND_NOW;
write_to_uart <= '0';
UART_STATE <= B"10";
elsif (UART_STATE = B"10") then
write_to_uart <= '1';
UART_STATE <= B"00";
end if;
end if;
end process;

The sending itself work fine, but the wrong data seems to get sent.
The following process controls what is sent:

SEND: process (write_to_uart, BUSVAL)
begin
if (BUSVAL /= BUFBUS) then
if (tx_half_full = '0' AND SEND_A_BYTE_NOW = '0') then
SEND_A_BYTE_NOW <= '1';
BYTE_TO_SEND_NOW <= BYTE_TO_SEND_NOW + '1';
end if;
BUFBUS <= BUSVAL;
elsif (rising_edge(write_to_uart)) then
SEND_A_BYTE_NOW <= '0';
end if;
end process;

I want it to work like this: Each time "write_to_uart" gets '1', I
know that a byte was written to the UART send buffer. So I reset
"SEND_A_BYTE_NOW" to '0' such that the next byte only gets
sent if this goes back to '1'.

I want to send out a byte under the following conditions:
1. BUSVAL has changed
2. tx_half_full = '0'
3. SEND_A_BYTE_NOW is not already '1'

Then I want to send out a value that is the last value sent + 1

It simulates fine, but when I listen to the serial port of the real
device, the bytes don't come out in consecutive order. I would
expect:

1,2,3,4,5,6,7 and what I really get is 30, 45, 96, AE, B4 etc ....

I have a few questions:

* It this code above bad design ?
* Why does it work fine in simulation, but not on the real device ?
* Why does BYTE_TO_SEND_NOW get increased multiple times on the real
device and only once in simulation ?

Please help me. I am a VHDL beginner and don't know where to start
searching.

Thanks !
F.













 
Reply With Quote
 
 
 
 
Russell
Guest
Posts: n/a
 
      08-19-2007
On Aug 19, 1:26 pm, FranzH <(E-Mail Removed)> wrote:
> Hello,
>
> I have difficulies with the following code. It translates, I can make
> a programing file, download it to the chip but the result is not as it
> is in simulation and I don't understand why:
>
> The following process sends out bytes by using the PicoBlaze UART
> sender macro. The plan is to wait until "SEND_A_BYTE_NOW" gets '1'
> and then send out the byte in "BYTE_TO_SEND_NOW". PBCLK is a 50 MHz
> clock.
>
> SERIALSENDER: process (PBCLK)
> begin
> if (rising_edge(PBCLK)) then
> if (UART_STATE = B"00") then
> write_to_uart <= '0';
> if (SEND_A_BYTE_NOW = '1') then
> UART_STATE <= B"01";
> end if;
> elsif (UART_STATE = B"01") then
> out_port <= BYTE_TO_SEND_NOW;
> write_to_uart <= '0';
> UART_STATE <= B"10";
> elsif (UART_STATE = B"10") then
> write_to_uart <= '1';
> UART_STATE <= B"00";
> end if;
> end if;
> end process;
>
> The sending itself work fine, but the wrong data seems to get sent.
> The following process controls what is sent:
>
> SEND: process (write_to_uart, BUSVAL)
> begin
> if (BUSVAL /= BUFBUS) then
> if (tx_half_full = '0' AND SEND_A_BYTE_NOW = '0') then
> SEND_A_BYTE_NOW <= '1';
> BYTE_TO_SEND_NOW <= BYTE_TO_SEND_NOW + '1';
> end if;
> BUFBUS <= BUSVAL;
> elsif (rising_edge(write_to_uart)) then
> SEND_A_BYTE_NOW <= '0';
> end if;
> end process;
>
> I want it to work like this: Each time "write_to_uart" gets '1', I
> know that a byte was written to the UART send buffer. So I reset
> "SEND_A_BYTE_NOW" to '0' such that the next byte only gets
> sent if this goes back to '1'.
>
> I want to send out a byte under the following conditions:
> 1. BUSVAL has changed
> 2. tx_half_full = '0'
> 3. SEND_A_BYTE_NOW is not already '1'
>
> Then I want to send out a value that is the last value sent + 1
>
> It simulates fine, but when I listen to the serial port of the real
> device, the bytes don't come out in consecutive order. I would
> expect:
>
> 1,2,3,4,5,6,7 and what I really get is 30, 45, 96, AE, B4 etc ....
>
> I have a few questions:
>
> * It this code above bad design ?
> * Why does it work fine in simulation, but not on the real device ?
> * Why does BYTE_TO_SEND_NOW get increased multiple times on the real
> device and only once in simulation ?
>
> Please help me. I am a VHDL beginner and don't know where to start
> searching.
>
> Thanks !
> F.

chack that:
1)you haven't reversed your bits - does your simulation send the same
orderthat the serial port sends (I made this mistake before ) -- I
think it is LSB first
2) do you translate the character sent to ascii first? wow is it
defined -- if you send me your code maybe I can look further - Russell

 
Reply With Quote
 
 
 
 
FranzH
Guest
Posts: n/a
 
      08-19-2007
>chack that:
>1)you haven't reversed your bits - does your simulation send the same
>orderthat the serial port sends (I made this mistake before ) -- I
>think it is LSB first


Hm ... I use the PicoBlaze Macro. It receives the input parallel so I
thought I don't need to worry about bit order. In addition, if I just
send bytes, then it works normally. Only if I put it together in the
way I posted, then things start to get strange. I am sure the sender
part of PicoBlaze should work fine. There must be something I am
missing in the interaction of the two processes that I posted.


>2) do you translate the character sent to ascii first? wow is it
>defined


I do not send ASCII, I just send out binary values. They should start
from 0 and get higher each time the bus changes.

Thanks
F.



 
Reply With Quote
 
Pieter Hulshoff
Guest
Posts: n/a
 
      08-20-2007
FranzH wrote:
> SEND: process (write_to_uart, BUSVAL)
> begin
> if (BUSVAL /= BUFBUS) then
> if (tx_half_full = '0' AND SEND_A_BYTE_NOW = '0') then
> SEND_A_BYTE_NOW <= '1';
> BYTE_TO_SEND_NOW <= BYTE_TO_SEND_NOW + '1';
> end if;
> BUFBUS <= BUSVAL;
> elsif (rising_edge(write_to_uart)) then
> SEND_A_BYTE_NOW <= '0';
> end if;
> end process;


This can never work. You are using a combinatorial process to change the value
of BUFBUS while using that same BUFBUS to check on what to do in the process.
Within the simulator, this will cause a 1 delta cycle time during which your
BYTE_TO_SEND_NOW counter is incremented and SEND_A_BYTE_NOW is set to 1. Now try
to think of what this should look like in hardware...

Kind regards,

Pieter Hulshoff
 
Reply With Quote
 
FranzH
Guest
Posts: n/a
 
      08-20-2007
On Mon, 20 Aug 2007 11:28:38 +0200, Pieter Hulshoff
<(E-Mail Removed)> wrote:

>FranzH wrote:
>> SEND: process (write_to_uart, BUSVAL)
>> begin
>> if (BUSVAL /= BUFBUS) then
>> if (tx_half_full = '0' AND SEND_A_BYTE_NOW = '0') then
>> SEND_A_BYTE_NOW <= '1';
>> BYTE_TO_SEND_NOW <= BYTE_TO_SEND_NOW + '1';
>> end if;
>> BUFBUS <= BUSVAL;
>> elsif (rising_edge(write_to_uart)) then
>> SEND_A_BYTE_NOW <= '0';
>> end if;
>> end process;

>
>This can never work. You are using a combinatorial process to change the value
>of BUFBUS while using that same BUFBUS to check on what to do in the process.
>Within the simulator, this will cause a 1 delta cycle time during which your
>BYTE_TO_SEND_NOW counter is incremented and SEND_A_BYTE_NOW is set to 1. Now try
>to think of what this should look like in hardware...
>
>Kind regards,
>
>Pieter Hulshoff


Thanks very much Pieter. I am a complete newbie in VHDL. I have great
difficulty to see what can be synthesized and what can not be
synthesized. I also don't know much about what the synthesis tool will
make out of my code. Can you point me to some book or tutorial where I
can learn what VHDL constructs will be synthesizable and what will not
work ? Or is this all a question of experience and I have to learn it
the hard way ? It is very confusing for me that a synthesis tool does
not create an error if it can not synthesize something. I hope this
doesn't sound too stupid

F.


 
Reply With Quote
 
Pieter Hulshoff
Guest
Posts: n/a
 
      08-20-2007
FranzH wrote:
> On Mon, 20 Aug 2007 11:28:38 +0200, Pieter Hulshoff
> <(E-Mail Removed)> wrote:
>
>> FranzH wrote:
>>> SEND: process (write_to_uart, BUSVAL)
>>> begin
>>> if (BUSVAL /= BUFBUS) then
>>> if (tx_half_full = '0' AND SEND_A_BYTE_NOW = '0') then
>>> SEND_A_BYTE_NOW <= '1';
>>> BYTE_TO_SEND_NOW <= BYTE_TO_SEND_NOW + '1';
>>> end if;
>>> BUFBUS <= BUSVAL;
>>> elsif (rising_edge(write_to_uart)) then
>>> SEND_A_BYTE_NOW <= '0';
>>> end if;
>>> end process;

>> This can never work. You are using a combinatorial process to change the value
>> of BUFBUS while using that same BUFBUS to check on what to do in the process.
>> Within the simulator, this will cause a 1 delta cycle time during which your
>> BYTE_TO_SEND_NOW counter is incremented and SEND_A_BYTE_NOW is set to 1. Now try
>> to think of what this should look like in hardware...

>
> Thanks very much Pieter. I am a complete newbie in VHDL. I have great
> difficulty to see what can be synthesized and what can not be
> synthesized. I also don't know much about what the synthesis tool will
> make out of my code. Can you point me to some book or tutorial where I
> can learn what VHDL constructs will be synthesizable and what will not
> work ? Or is this all a question of experience and I have to learn it
> the hard way ? It is very confusing for me that a synthesis tool does
> not create an error if it can not synthesize something. I hope this
> doesn't sound too stupid


I can't think of a good book on that off the top of my head, but usually it
helps if you just draw a little hardware schematic of what you think you are
designing. If you see a combinatorial loopback anywhere (as you have created
here) you may want to think long and hard about if that's truly what you had in
mind.

Drawing things also helps prevent timing problems due to long paths. As a little
example, consider the schematic and timing implications of the two following
functionally identical processes:

cnt := cnt + 1;
IF cnt = 5 THEN
cnt := 0;
END IF;

cnt <= cnt + 1;
IF cnt = 4 THEN
cnt <= 0;
END IF;

The first process increments first, then uses the incremented result to clear
the counter. The second uses the counter value in the flip-flops to do the
check. The second process will therefore probably function at a higher clock
frequency than the first one.

Regards,

Pieter
 
Reply With Quote
 
Mike Treseler
Guest
Posts: n/a
 
      08-20-2007
FranzH wrote:
> Can you point me to some book or tutorial where I
> can learn what VHDL constructs will be synthesizable and what will not
> work ?


See the template example here
http://home.comcast.net/~mike_treseler/
for one way that works for me.

-- Mike Treseler
 
Reply With Quote
 
FranzH
Guest
Posts: n/a
 
      08-20-2007
On Mon, 20 Aug 2007 08:33:44 -0700, Mike Treseler
<(E-Mail Removed)> wrote:

>FranzH wrote:
>> Can you point me to some book or tutorial where I
>> can learn what VHDL constructs will be synthesizable and what will not
>> work ?

>
>See the template example here
> http://home.comcast.net/~mike_treseler/
>for one way that works for me.
>
> -- Mike Treseler


Thanks, I will have a look

 
Reply With Quote
 
Thomas Stanka
Guest
Posts: n/a
 
      08-21-2007
On 20 Aug., 11:28, Pieter Hulshoff <(E-Mail Removed)> wrote:
> FranzH wrote:
> > SEND: process (write_to_uart, BUSVAL)
> > begin
> > if (BUSVAL /= BUFBUS) then
> > if (tx_half_full = '0' AND SEND_A_BYTE_NOW = '0') then
> > SEND_A_BYTE_NOW <= '1';
> > BYTE_TO_SEND_NOW <= BYTE_TO_SEND_NOW + '1';
> > end if;
> > BUFBUS <= BUSVAL;
> > elsif (rising_edge(write_to_uart)) then
> > SEND_A_BYTE_NOW <= '0';
> > end if;
> > end process;

>
> This can never work. You are using a combinatorial process to change the value
> of BUFBUS while using that same BUFBUS to check on what to do in the process.
> Within the simulator, this will cause a 1 delta cycle time during which your
> BYTE_TO_SEND_NOW counter is incremented and SEND_A_BYTE_NOW is set to 1. Now try
> to think of what this should look like in hardware...


Actually this is not the problem with this sensibility list (the
sensibility list prevents the 1 delta).
The problem arises due do the usage of a nonstandard clocked process
which can't be exactly synthesised.
A clocked process shall be:
process (clock, Reset) -- no signal else, naming doesn't matter, reset
optional (but recommended)
if reset = <static signal> then
all_registers <= <static value>
elsif rising_edge(clock) then
some_reg <= any_value
if (synch_reset|enable|whatever)....
other_reg <= any_value
end if
.......
end if
end process

Every other clocked process tends to fit in no real hardware.
Your HW can't re-wire your reset during runtime to set a register to a
nonstatic value during asynch reset (unless you do reconfiguration in
some fpgas). And whatever HW your tool generate when accepting the
code above, it won't be reliabel the HW you expected or you see in
simulation. It wouldn't even be the same functionality when changing
the synthesis tool.

bye Thomas

 
Reply With Quote
 
Pieter Hulshoff
Guest
Posts: n/a
 
      08-21-2007
Thomas Stanka wrote:
> On 20 Aug., 11:28, Pieter Hulshoff <(E-Mail Removed)> wrote:
>> FranzH wrote:
>>> SEND: process (write_to_uart, BUSVAL)
>>> begin
>>> if (BUSVAL /= BUFBUS) then
>>> if (tx_half_full = '0' AND SEND_A_BYTE_NOW = '0') then
>>> SEND_A_BYTE_NOW <= '1';
>>> BYTE_TO_SEND_NOW <= BYTE_TO_SEND_NOW + '1';
>>> end if;
>>> BUFBUS <= BUSVAL;
>>> elsif (rising_edge(write_to_uart)) then
>>> SEND_A_BYTE_NOW <= '0';
>>> end if;
>>> end process;

>> This can never work. You are using a combinatorial process to change the value
>> of BUFBUS while using that same BUFBUS to check on what to do in the process.
>> Within the simulator, this will cause a 1 delta cycle time during which your
>> BYTE_TO_SEND_NOW counter is incremented and SEND_A_BYTE_NOW is set to 1. Now try
>> to think of what this should look like in hardware...

>
> Actually this is not the problem with this sensibility list (the
> sensibility list prevents the 1 delta).


Even with BUSVAL added to the sensitivity list it would not have made a
difference, since the next time the process is called BUFBUS = BUSVAL. Most
synthesis tools would give at most a warning about forgetting BUSVAL in the
sensitivity list here.

Personally I prefer the following code style:

PROCESS
BEGIN
WAIT UNTIL clk = '1';
<code>
IF reset = '1' THEN
<resets>
END IF;
END PROCESS;

Regards,

Pieter
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem with post-route simulation / timing simulation jasperng VHDL 0 11-27-2008 06:23 AM
When I turn on my PC, it works, works, works. Problem! Fogar Computer Information 1 01-17-2006 12:57 AM
this code works in IE but not Firefox - please help Notgiven Javascript 5 01-11-2006 12:03 AM
[py2exe.i18n] English works, German works, but not French. What do I miss? F. GEIGER Python 3 08-06-2004 10:01 AM
After rebooting my PC works, works, works! Antivirus problem? Adriano Computer Information 1 12-15-2003 05:30 AM



Advertisments