FPGARelated.com
Forums

rs232 uart: testbench vs real world, and the missing first letter.

Started by jleslie48 February 3, 2009
From previous thread:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
My first cleanup was to at least reduce the strings to something that
I could actually read.
The side effect being that the first character of the string got
clobbered and that answer will
reside in the spagetti code that you pointed out.  Meantime its not
immediately obvious to
me from the testbench:

http://jleslie48.com/fpga_uartjl_01/11jlmod/ccuart01/screencap/screen...

I see the "T" getting in, to the datastream, but I haven't found where
it got clobbered.  I do know the
code is a complete mess.

The source code is here if anyone is interested:

http://jleslie48.com/fpga_uartjl_01/11jlmod/ccuart01/source/LOKI_Top.vhd

http://jleslie48.com/fpga_uartjl_01/11jlmod/ccuart01/source/


++++++++++++++++++++++++++++++++++++++++++++++++++++


Ok, so I've been working with the testbench and the actual development
board on why my
dumb terminal program doesn't get the first character of the message:
"Testing 1,2,3..."

Here is a good screen capture of the dumb terminal as well as a
separate screen showing the
testbench run:


http://jleslie48.com/fpga_uartjl_01/11jlmod/ccuart01/screencap/screencap11_missingfirstletter.png

After a lot of mucking about, I zeroed in on the actual pin/wire that
the message is going out on,
and sure enough, there is the first letter "supposedly" going out in
Testbench, "T" followed by "e" followed
by "s".  all exactly as it should be: start bit, 8 bits of data, and a
stop bit, timed exactly at 115200 baud.

Meantime, the real world is missing the first letter.

What am I missing here?  Why is the sim and the real world out of
sync?


On Tue, 3 Feb 2009 07:31:46 -0800 (PST), jleslie48 wrote:

>After a lot of mucking about, I zeroed in on the actual pin/wire that >the message is going out on, >and sure enough, there is the first letter "supposedly" going out in >Testbench, "T" followed by "e" followed >by "s". all exactly as it should be: start bit, 8 bits of data, and a >stop bit, timed exactly at 115200 baud. > >Meantime, the real world is missing the first letter. > >What am I missing here? Why is the sim and the real world out of >sync?
I don't have time to look in detail right now, but my first port of call would be to check that you aren't overrunning the transmitter. I can easily imagine a situation in which you write the first character, note that the Tx claims to be ready for a second, so write the second character too soon - and it then overwrites the first character in one of the Tx's internal buffers. A good sanity check for this would be to add a dead-reckoning delay between characters and see if that works. Or just try sending a 1-character message. -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK jonathan.bromley@MYCOMPANY.com http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated.
On Feb 3, 10:37 am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
> On Tue, 3 Feb 2009 07:31:46 -0800 (PST), jleslie48 wrote: > >After a lot of mucking about, I zeroed in on the actual pin/wire that > >the message is going out on, > >and sure enough, there is the first letter "supposedly" going out in > >Testbench, "T" followed by "e" followed > >by "s". all exactly as it should be: start bit, 8 bits of data, and a > >stop bit, timed exactly at 115200 baud. > > >Meantime, the real world is missing the first letter. > > >What am I missing here? Why is the sim and the real world out of > >sync? > > I don't have time to look in detail right now, but my first > port of call would be to check that you aren't overrunning > the transmitter. I can easily imagine a situation in which > you write the first character, note that the Tx claims to > be ready for a second, so write the second character too > soon - and it then overwrites the first character in one > of the Tx's internal buffers. > > A good sanity check for this would be to add a dead-reckoning > delay between characters and see if that works. Or just try > sending a 1-character message. > -- > Jonathan Bromley, Consultant > > DOULOS - Developing Design Know-how > VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services > > Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK > jonathan.brom...@MYCOMPANY.comhttp://www.MYCOMPANY.com > > The contents of this message may contain personal views which > are not the views of Doulos Ltd., unless specifically stated.
Jonathan, Thanks again for your insight. I like that 1 character test I will do that in two minutes. Meantime, my associate doesn't like the fact that the tx_write_buffer_stb occurs on the same boundary as the update to tx_data_in: http://jleslie48.com/fpga_uartjl_01/11jlmod/ccuart01/screencap/screencap12_missingfirstletter.png does this sound right?
> A good sanity check for this would be to add a dead-reckoning > delay between characters and see if that works.
I love this idea but don't know how to implement it. Earlier in this project we agreed to black-box the nasties of the workings of the RS232. This sounds like I have to open that [pandora's] box again.
jleslie48 wrote:

> http://jleslie48.com/fpga_uartjl_01/11jlmod/ccuart01/screencap/screen... > > I see the "T" getting in, to the datastream, but I haven't found where > it got clobbered.
Is the reset pulse lined up ok?
On Tue, 3 Feb 2009 07:50:10 -0800 (PST), jleslie48 wrote:

>> >After a lot of mucking about, I zeroed in on the actual pin/wire that >> >the message is going out on, >> >and sure enough, there is the first letter "supposedly" going out in >> >Testbench, "T" followed by "e" followed >> >by "s". all exactly as it should be: start bit, 8 bits of data, and a >> >stop bit, timed exactly at 115200 baud. >> >> >Meantime, the real world is missing the first letter.
Sorry, I didn't read that carefully enough the first time. Do I understand correctly that you have examined the serial line output from the UART, and you are seeing the 'T' character - with its start, stop etc - actually going out on the line? If so, then my suggestion about buffer overrun is irrelevant and instead you need to ask why you are not seeing that character. Here are some possibilities: 1) It's going out so soon after you powered-up the FPGA that the real, physical receiver (which, I assume, is a COM port on your PC) has not had time to establish an idle-line level. 2) Ditto, but you have some issue with the modem handshake signals (DSR, RTS etc) so that the COM receiver doesn't think the line is active at that time. 3) Look carefully at the serial line output again: is it REALLY following the protocol? At least 11 bit times of "mark" followed by the transition to "space" at the beginning of the start bit? I don't know if you are using parity, but if so... perhaps there's some initialisation issue and the parity is wrong on the first character? A storage 'scope on the serial line, triggered by the FPGA's configuration DONE signal going true, might yield some insights. Many an experiment has foundered on the reefs of power-up initialisation trouble. -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK jonathan.bromley@MYCOMPANY.com http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated.
On Tue, 3 Feb 2009 07:50:10 -0800 (PST), jleslie48 wrote:

>Meantime, my associate doesn't like the fact that the >tx_write_buffer_stb >occurs on the same boundary as the update to tx_data_in:
If there is, in the UART code or anywhere else, a process that is clocked by rising_edge(tx_write_buffer_stb) (or the equivalent with 'event) then you are screwed. If, however, this is a synchronous enable signal and all the UART's activity is clocked by the clk_16_6_MHz signal as it should be, then all is well and you have nothing to worry about on that score. -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK jonathan.bromley@MYCOMPANY.com http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated.
On Feb 3, 11:01 am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
> On Tue, 3 Feb 2009 07:50:10 -0800 (PST), jleslie48 wrote: > >> >After a lot of mucking about, I zeroed in on the actual pin/wire that > >> >the message is going out on, > >> >and sure enough, there is the first letter "supposedly" going out in > >> >Testbench, "T" followed by "e" followed > >> >by "s". all exactly as it should be: start bit, 8 bits of data, and a > >> >stop bit, timed exactly at 115200 baud. > > >> >Meantime, the real world is missing the first letter. > > Sorry, I didn't read that carefully enough the first time. > Do I understand correctly that you have examined the > serial line output from the UART, and you are seeing > the 'T' character - with its start, stop etc - actually > going out on the line? If so, then my suggestion about > buffer overrun is irrelevant and instead you need to ask > why you are not seeing that character. Here are some > possibilities: > > 1) It's going out so soon after you powered-up the FPGA > that the real, physical receiver (which, I assume, is > a COM port on your PC) has not had time to establish > an idle-line level. > > 2) Ditto, but you have some issue with the modem > handshake signals (DSR, RTS etc) so that the COM > receiver doesn't think the line is active at that time. > > 3) Look carefully at the serial line output again: is > it REALLY following the protocol? At least 11 bit > times of "mark" followed by the transition to "space" > at the beginning of the start bit? I don't know if you > are using parity, but if so... perhaps there's some > initialisation issue and the parity is wrong on the > first character? > > A storage 'scope on the serial line, triggered by the > FPGA's configuration DONE signal going true, might > yield some insights. > > Many an experiment has foundered on the reefs of > power-up initialisation trouble. > -- > Jonathan Bromley, Consultant > > DOULOS - Developing Design Know-how > VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services > > Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK > jonathan.brom...@MYCOMPANY.comhttp://www.MYCOMPANY.com > > The contents of this message may contain personal views which > are not the views of Doulos Ltd., unless specifically stated.
+++++++++++++++
> Do I understand correctly that you have examined the > serial line output from the UART, and you are seeing > the 'T' character - with its start, stop etc - actually > going out on the line? If so, then my suggestion about
NO!!! I haven't put the output on a oscilliscope yet. I only meant that I "saw the 'T' character on the TESTBENCH output line.
> > 1) It's going out so soon after you powered-up the FPGA > that the real, physical receiver (which, I assume, is > a COM port on your PC) has not had time to establish > an idle-line level. > > 2) Ditto, but you have some issue with the modem > handshake signals (DSR, RTS etc) so that the COM > receiver doesn't think the line is active at that time. > > 3) Look carefully at the serial line output again: is > it REALLY following the protocol? At least 11 bit > times of "mark" followed by the transition to "space" > at the beginning of the start bit? I don't know if you > are using parity, but if so... perhaps there's some > initialisation issue and the parity is wrong on the > first character?
I don't think this is the case. The detail I left out is that if I leave my associates code alone, viz, If leave in the message definition as standard logic vector: ------------------------------------------------ SUBTYPE REG IS STD_LOGIC_VECTOR( 7 DOWNTO 0 ); TYPE LOKI_PROJECT IS ARRAY ( INTEGER RANGE <> ) OF REG; SIGNAL LOKI_MESS_TRAN : STD_LOGIC := '0'; CONSTANT LOKI_MESS_MAX : INTEGER := 26; SIGNAL LOKI_MESS_CNT : INTEGER RANGE 0 TO LOKI_MESS_MAX; SIGNAL PROJECT_NAME : LOKI_PROJECT( 0 TO LOKI_MESS_MAX ) := ( CR, AL, AO, AK, AI, SP, AP, AR, AO, AJ, AE, AC, AT, CR, AR, AE, AV, AI, AS, AI, AO, AN, SP, N0, N0, N1, CR ); IF ( CLK_16_6MHZ = '1' AND CLK_16_6MHZ'EVENT ) THEN IF ( UART_RESET_BUFFER = '0' ) THEN IF ( ( LOKI_MESS_TRAN = '1' ) AND ( TX_BUFFER_FULL = '0' ) AND ( TX_WRITE_BUFFER_STB = '0' ) ) THEN TX_DATA_IN( 7 DOWNTO 0 ) <= PROJECT_NAME ( LOKI_MESS_CNT ); -------------------------------------------------------- all works perfectly fine. its only when I introduce: -------------------------------------------- function to_slv(c: character) return std_logic_vector is begin return std_logic_vector(to_unsigned(character'pos(c), 8)); end; constant project_name_stg : string := "Testing 1,2,3,"; SIGNAL project_name_cnt : INTEGER RANGE 1 to project_name_stg'high; SIGNAL lprj_MESS_TRAN : STD_LOGIC := '0'; IF ( CLK_16_6MHZ = '1' AND CLK_16_6MHZ'EVENT ) THEN IF ( UART_RESET_BUFFER = '0' ) THEN IF ( ( lprj_MESS_TRAN = '1' ) AND ( TX_BUFFER_FULL = '0' ) AND ( TX_WRITE_BUFFER_STB = '0' ) ) THEN --TX_DATA_IN( 7 DOWNTO 0 ) <= PROJECT_NAME ( lprj_MESS_CNT ); TX_DATA_IN <= to_slv(project_name_stg ( project_name_cnt )); ---------------------------------------------------- That I see the first character missing problem. I don't know why the 'string' version skips the first character, but the "standard logic vector' version is fine. And yes I still know I have to bubble up the redundant checks and get these walks through the strings straightened out, but I these issues are mutatis mutandis with both sets of code, and the Testbench waveforms "look" identical, so I'm at a loss as to why they behave differently. Before I streamline code I want the missing first character for strings issue resolved.
On Feb 3, 10:52 am, Mike Treseler <mtrese...@gmail.com> wrote:
> jleslie48 wrote: > >http://jleslie48.com/fpga_uartjl_01/11jlmod/ccuart01/screencap/screen... > > > I see the "T" getting in, to the datastream, but I haven't found where > > it got clobbered. > > Is the reset pulse lined up ok?
Mike, Not sure what you mean here, and Jonathan, Bingo! I reduce the startup message to ----------------------------------------------------- constant project_name_stg : string := "1"; SIGNAL project_name_cnt : INTEGER RANGE 1 to project_name_stg'high; SIGNAL lprj_MESS_TRAN : STD_LOGIC := '0'; ------------------------------------------------------------ just the one character, and it's there. (good it would of taken me hours to figure out the oscilliscope!) so that would imply that the stop bit (aka, the dead-reckoning delay) is the issue yes? or is Mike onto the solution? And why does the standard logic vector not suffer from the same issue? Inquiring minds want to know...
jleslie48 wrote:
> -------------------------------------------- > function to_slv(c: character) return std_logic_vector is > begin > return std_logic_vector(to_unsigned(character'pos(c), 8)); > end; > > constant project_name_stg : string := "Testing 1,2,3,"; > SIGNAL project_name_cnt : INTEGER RANGE 1 to > project_name_stg'high; > SIGNAL lprj_MESS_TRAN : STD_LOGIC := '0'; > > IF ( CLK_16_6MHZ = '1' AND CLK_16_6MHZ'EVENT ) THEN > IF ( UART_RESET_BUFFER = '0' ) THEN > IF ( ( lprj_MESS_TRAN = '1' ) AND > ( TX_BUFFER_FULL = '0' ) AND > ( TX_WRITE_BUFFER_STB = '0' ) ) THEN > --TX_DATA_IN( 7 DOWNTO 0 ) <= PROJECT_NAME > ( lprj_MESS_CNT ); > TX_DATA_IN <= to_slv(project_name_stg > ( project_name_cnt )); > ---------------------------------------------------- > > That I see the first character missing problem. I don't know why the > 'string' version skips the > first character, but the "standard logic vector' version is fine.
Do you initialize project_name_cnt somewhere? -- Thomas
On Feb 3, 1:40 pm, "Thomas J. Gritzan" <phygon_antis...@gmx.de> wrote:
> jleslie48 wrote: > > -------------------------------------------- > > function to_slv(c: character) return std_logic_vector is > > begin > > return std_logic_vector(to_unsigned(character'pos(c), 8)); > > end; > > > constant project_name_stg : string := "Testing 1,2,3,"; > > SIGNAL project_name_cnt : INTEGER RANGE 1 to > > project_name_stg'high; > > SIGNAL lprj_MESS_TRAN : STD_LOGIC := '0'; > > > IF ( CLK_16_6MHZ = '1' AND CLK_16_6MHZ'EVENT ) THEN > > IF ( UART_RESET_BUFFER = '0' ) THEN > > IF ( ( lprj_MESS_TRAN = '1' ) AND > > ( TX_BUFFER_FULL = '0' ) AND > > ( TX_WRITE_BUFFER_STB = '0' ) ) THEN > > --TX_DATA_IN( 7 DOWNTO 0 ) <= PROJECT_NAME > > ( lprj_MESS_CNT ); > > TX_DATA_IN <= to_slv(project_name_stg > > ( project_name_cnt )); > > ---------------------------------------------------- > > > That I see the first character missing problem. I don't know why the > > 'string' version skips the > > first character, but the "standard logic vector' version is fine. > > Do you initialize project_name_cnt somewhere? > > -- > Thomas
good thought but here: ---------------------------------------- ------------------------------------------------------------------------------------------------- -- INITIALIZING lprj PROJECT MESSAGE COUNT ( project_name_cnt ) ------------------------------------------------------------------------------------------------- P10: PROCESS ( CLK_16_6MHZ, UART_RESET_BUFFER, UART_RESET_NEXT, lprj_MESS_TRAN, TX_WRITE_BUFFER_STB ) BEGIN IF ( CLK_16_6MHZ = '1' AND CLK_16_6MHZ'EVENT ) THEN IF ( ( UART_RESET_BUFFER = '0' ) AND ( UART_RESET_NEXT = '1' ) ) THEN project_name_cnt <= 1; --project_name_cnt'low; ELSIF ( ( lprj_MESS_TRAN = '1' ) AND ( TX_WRITE_BUFFER_STB = '1' ) AND ( project_name_cnt /= project_name_stg'high ) ) THEN project_name_cnt <= ( project_name_cnt + 1 ); END IF; END IF; END PROCESS P10; ------------------------------------------------------ here's the entire source code file: http://jleslie48.com/fpga_uartjl_01/11jlmod/ccuart01/source/LOKI_Top.vhd