FPGARelated.com
Forums

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

Started by jleslie48 February 3, 2009
On Feb 3, 12:41 pm, jleslie48 <j...@jonathanleslie.com> wrote:
> 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...
Ok, the mystery gets deeper. I make the message string: constant project_name_stg : string := "123456789a12345"; aka, 15 characters, all is well. I make it 16 characters: constant project_name_stg : string := "123456789a123456"; my output becomes: 23456789a1234561 were the 1 at the end is indeed the first character not the last.
On Feb 3, 1:56 pm, jleslie48 <j...@jonathanleslie.com> wrote:
> 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 :=3D "Testing 1,2,3,"; > > > SIGNAL project_name_cnt : INTEGER RANGE 1 to > > > project_name_stg'high; > > > SIGNAL lprj_MESS_TRAN : STD_LOGIC :=3D '0'; > > > > IF ( CLK_16_6MHZ =3D '1' AND CLK_16_6MHZ'EVENT ) THEN > > > IF ( UART_RESET_BUFFER =3D '0' ) THEN > > > IF ( ( lprj_MESS_TRAN =3D '1' ) AND > > > ( TX_BUFFER_FULL =3D '0' ) AND > > > ( TX_WRITE_BUFFER_STB =3D '0' ) ) THEN > > > --TX_DATA_IN( 7 DOWNTO 0 ) <=3D PROJECT=
_NAME
> > > ( lprj_MESS_CNT ); > > > TX_DATA_IN <=3D 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 =3D '1' AND CLK_16_6MHZ'EVENT ) THEN > IF ( ( UART_RESET_BUFFER =3D '0' ) AND > ( UART_RESET_NEXT =3D '1' ) ) THEN > project_name_cnt <=3D 1; --project_name_cnt'low; > > ELSIF ( ( lprj_MESS_TRAN =3D '1' ) AND > ( TX_WRITE_BUFFER_STB =3D '1' ) AND > ( project_name_cnt /=3D > project_name_stg'high ) ) THEN > project_name_cnt <=3D ( 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
------------------------------??? ------------------------ One quick thing I noticed in process "P5": P5: PROCESS ( CLK_16_6MHZ ) BEGIN IF ( CLK_16_6MHZ =3D '1' AND CLK_16_6MHZ'EVENT ) THEN IF ( RESET_COUNT( 3 DOWNTO 0 ) =3D "1111" ) THEN RESET_COUNT( 3 DOWNTO 0 ) <=3D "1111"; UART_RESET_BUFFER <=3D '0'; ELSE RESET_COUNT( 3 DOWNTO 0 ) <=3D RESET_COUNT( 3 DOWNTO 0 ) + 1 ; UART_RESET_BUFFER <=3D '1'; END IF; END IF; END PROCESS P5; ------------------------------------???------------------------------=A2=BC The 2nd IF says that if RESET_COUNT is all 1's, then set it to all 1's. I think that you meant to set it to all 0's. BTW, you don't need "...(3 downto 0)..." because the signal is defined as (3 downto 0). so..... BEGIN IF ( rising_edge( CLK_16_6MHZ ) ) THEN IF ( RESET_COUNT =3D "1111" ) THEN RESET_COUNT <=3D (others =3D> '0'); -- ALL bits to '0' UART_RESET_BUFFER <=3D '0'; ELSE RESET_COUNT <=3D RESET_COUNT + 1 ; UART_RESET_BUFFER <=3D '1'; END IF; END IF; -------------------- HTH -Dave Pollum
On Feb 3, 2:19 pm, jleslie48 <j...@jonathanleslie.com> wrote:
> On Feb 3, 12:41 pm, jleslie48 <j...@jonathanleslie.com> wrote: > > > > > 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... > > Ok, > > the mystery gets deeper. > > I make the message string: > constant project_name_stg : string := "123456789a12345"; > > aka, 15 characters, all is well. > I make it 16 characters: > constant project_name_stg : string := "123456789a123456"; > > my output becomes: > 23456789a1234561 > > were the 1 at the end is indeed the first character not the last.
and the string: constant project_name_stg : string := "f23456789a1234567"; yields the output: 23456789a1234567 I imagine 17 or more is destructive to the first character.
On Feb 3, 2:21 pm, Dave Pollum <vze24...@verizon.net> wrote:
> On Feb 3, 1:56 pm, jleslie48 <j...@jonathanleslie.com> wrote: > > > 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 :=3D "Testing 1,2,3,"; > > > > SIGNAL project_name_cnt : INTEGER RANGE 1 to > > > > project_name_stg'high; > > > > SIGNAL lprj_MESS_TRAN : STD_LOGIC :=3D '0'; > > > > > IF ( CLK_16_6MHZ =3D '1' AND CLK_16_6MHZ'EVENT ) THEN > > > > IF ( UART_RESET_BUFFER =3D '0' ) THEN > > > > IF ( ( lprj_MESS_TRAN =3D '1' ) AND > > > > ( TX_BUFFER_FULL =3D '0' ) AND > > > > ( TX_WRITE_BUFFER_STB =3D '0' ) ) THEN > > > > --TX_DATA_IN( 7 DOWNTO 0 ) <=3D PROJE=
CT_NAME
> > > > ( lprj_MESS_CNT ); > > > > TX_DATA_IN <=3D to_slv(project_name_s=
tg
> > > > ( project_name_cnt )); > > > > ---------------------------------------------------- > > > > > That I see the first character missing problem. I don't know why th=
e
> > > > '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 =3D '1' AND CLK_16_6MHZ'EVENT ) THEN > > IF ( ( UART_RESET_BUFFER =3D '0' ) AND > > ( UART_RESET_NEXT =3D '1' ) ) THEN > > project_name_cnt <=3D 1; --project_name_cnt'low; > > > ELSIF ( ( lprj_MESS_TRAN =3D '1' ) AND > > ( TX_WRITE_BUFFER_STB =3D '1' ) AND > > ( project_name_cnt /=3D > > project_name_stg'high ) ) THEN > > project_name_cnt <=3D ( 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 > > ------------------------------??? ------------------------ > One quick thing I noticed in process "P5": > P5: PROCESS ( CLK_16_6MHZ ) > BEGIN > IF ( CLK_16_6MHZ =3D '1' AND CLK_16_6MHZ'EVENT ) THEN > IF ( RESET_COUNT( 3 DOWNTO 0 ) =3D "1111" ) THEN > RESET_COUNT( 3 DOWNTO 0 ) <=3D "1111"; > UART_RESET_BUFFER <=3D '0'; > ELSE > RESET_COUNT( 3 DOWNTO 0 ) <=3D RESET_COUNT( 3 DOWNTO 0 ) > + 1 ; > UART_RESET_BUFFER <=3D '1'; > END IF; > END IF; > END PROCESS P5; > ------------------------------------???------------------------------=A2=
=BC
> The 2nd IF says that if RESET_COUNT is all 1's, then set it to all > 1's. I think that you meant to set it to all 0's. BTW, you don't > need "...(3 downto 0)..." because the signal is defined as (3 downto > 0). > so..... > > BEGIN > IF ( rising_edge( CLK_16_6MHZ ) ) THEN > IF ( RESET_COUNT =3D "1111" ) THEN > RESET_COUNT <=3D (others =3D> '0'); -- ALL > bits to '0' > UART_RESET_BUFFER <=3D '0'; > ELSE > RESET_COUNT <=3D RESET_COUNT + 1 ; > UART_RESET_BUFFER <=3D '1'; > END IF; > END IF; > -------------------- > HTH > -Dave Pollum
well certainly: ~ IF ( RESET_COUNT( 3 DOWNTO 0 ) =3D "1111" ) THEN ~ RESET_COUNT( 3 DOWNTO 0 ) <=3D "1111"; makes no sense. and 'something' bad happens when the 16th character is in the buffer, so this is definitely a near hit at least. lets see how reset_count, uart_reset_buffer are used...
On Feb 3, 2:43 pm, jleslie48 <j...@jonathanleslie.com> wrote:
> On Feb 3, 2:21 pm, Dave Pollum <vze24...@verizon.net> wrote: > > > > > On Feb 3, 1:56 pm, jleslie48 <j...@jonathanleslie.com> wrote: > > > > 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 :=3D "Testing 1,2,3,"; > > > > > SIGNAL project_name_cnt : INTEGER RANGE 1 to > > > > > project_name_stg'high; > > > > > SIGNAL lprj_MESS_TRAN : STD_LOGIC :=3D '0'; > > > > > > IF ( CLK_16_6MHZ =3D '1' AND CLK_16_6MHZ'EVENT ) THEN > > > > > IF ( UART_RESET_BUFFER =3D '0' ) THEN > > > > > IF ( ( lprj_MESS_TRAN =3D '1' ) AND > > > > > ( TX_BUFFER_FULL =3D '0' ) AND > > > > > ( TX_WRITE_BUFFER_STB =3D '0' ) ) THEN > > > > > --TX_DATA_IN( 7 DOWNTO 0 ) <=3D PRO=
JECT_NAME
> > > > > ( lprj_MESS_CNT ); > > > > > TX_DATA_IN <=3D 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 =3D '1' AND CLK_16_6MHZ'EVENT ) THEN > > > IF ( ( UART_RESET_BUFFER =3D '0' ) AND > > > ( UART_RESET_NEXT =3D '1' ) ) THEN > > > project_name_cnt <=3D 1; --project_name_cnt'low=
;
> > > > ELSIF ( ( lprj_MESS_TRAN =3D '1' ) AND > > > ( TX_WRITE_BUFFER_STB =3D '1' ) AND > > > ( project_name_cnt /=3D > > > project_name_stg'high ) ) THEN > > > project_name_cnt <=3D ( 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.v=
hd
> > > ------------------------------??? ------------------------ > > One quick thing I noticed in process "P5": > > P5: PROCESS ( CLK_16_6MHZ ) > > BEGIN > > IF ( CLK_16_6MHZ =3D '1' AND CLK_16_6MHZ'EVENT ) THEN > > IF ( RESET_COUNT( 3 DOWNTO 0 ) =3D "1111" ) THEN > > RESET_COUNT( 3 DOWNTO 0 ) <=3D "1111"; > > UART_RESET_BUFFER <=3D '0'; > > ELSE > > RESET_COUNT( 3 DOWNTO 0 ) <=3D RESET_COUNT( 3 DOWNTO 0 ) > > + 1 ; > > UART_RESET_BUFFER <=3D '1'; > > END IF; > > END IF; > > END PROCESS P5; > > ------------------------------------???------------------------------=
=A2=BC
> > The 2nd IF says that if RESET_COUNT is all 1's, then set it to all > > 1's. I think that you meant to set it to all 0's. BTW, you don't > > need "...(3 downto 0)..." because the signal is defined as (3 downto > > 0). > > so..... > > > BEGIN > > IF ( rising_edge( CLK_16_6MHZ ) ) THEN > > IF ( RESET_COUNT =3D "1111" ) THEN > > RESET_COUNT <=3D (others =3D> '0'); -- A=
LL
> > bits to '0' > > UART_RESET_BUFFER <=3D '0'; > > ELSE > > RESET_COUNT <=3D RESET_COUNT + 1 ; > > UART_RESET_BUFFER <=3D '1'; > > END IF; > > END IF; > > -------------------- > > HTH > > -Dave Pollum > > well certainly: > > ~ IF ( RESET_COUNT( 3 DOWNTO 0 ) =3D "1111" ) THEN > ~ RESET_COUNT( 3 DOWNTO 0 ) <=3D "1111"; > > makes no sense. and 'something' bad happens when the 16th character > is in the buffer, so this is definitely a near hit at least. lets see > how > reset_count, uart_reset_buffer are used...
Ok this is a fking mess. what was done here was this, the "program" starts with uart_reset_buffer and uart_reset_next high, and the p5 process counts for 16 clock pulses to allow the system to startup. on the 16th pulse (=3D'1111') uart_reset_buffer goes low, and as a result of the D-FF that is made up on P6, uart_reset_next waits one clock pulse to go low. So for 1 and only 1 clock pulse, IF ( ( UART_RESET_BUFFER =3D '0' ) AND ( UART_RESET_NEXT =3D '1' ) ) THEN is true. This is the trigger for the "hello world" message. Now I imagine there *must* be a better way to do this, and Jonathan B. has already pointed out that his section of code is, in technical terms, higgley-piggley, but it is not causing my current flub.
On Feb 3, 3:08 pm, jleslie48 <j...@jonathanleslie.com> wrote:
> On Feb 3, 2:43 pm, jleslie48 <j...@jonathanleslie.com> wrote: > > > > > On Feb 3, 2:21 pm, Dave Pollum <vze24...@verizon.net> wrote: > > > > On Feb 3, 1:56 pm, jleslie48 <j...@jonathanleslie.com> wrote: > > > > > On Feb 3, 1:40 pm, "Thomas J. Gritzan" <phygon_antis...@gmx.de> wro=
te:
> > > > > > 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 :=3D "Testing 1,2,3,"=
;
> > > > > > SIGNAL project_name_cnt : INTEGER RANGE 1 to > > > > > > project_name_stg'high; > > > > > > SIGNAL lprj_MESS_TRAN : STD_LOGIC :=3D '0'; > > > > > > > IF ( CLK_16_6MHZ =3D '1' AND CLK_16_6MHZ'EVENT ) THEN > > > > > > IF ( UART_RESET_BUFFER =3D '0' ) THEN > > > > > > IF ( ( lprj_MESS_TRAN =3D '1' ) AND > > > > > > ( TX_BUFFER_FULL =3D '0' ) AND > > > > > > ( TX_WRITE_BUFFER_STB =3D '0' ) ) THEN > > > > > > --TX_DATA_IN( 7 DOWNTO 0 ) <=3D P=
ROJECT_NAME
> > > > > > ( lprj_MESS_CNT ); > > > > > > TX_DATA_IN <=3D to_slv(project_na=
me_stg
> > > > > > ( project_name_cnt )); > > > > > > ---------------------------------------------------- > > > > > > > That I see the first character missing problem. I don't know wh=
y the
> > > > > > 'string' version skips the > > > > > > first character, but the "standard logic vector' version is fin=
e.
> > > > > > 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 =3D '1' AND CLK_16_6MHZ'EVENT ) THEN > > > > IF ( ( UART_RESET_BUFFER =3D '0' ) AND > > > > ( UART_RESET_NEXT =3D '1' ) ) THEN > > > > project_name_cnt <=3D 1; --project_name_cnt'l=
ow;
> > > > > ELSIF ( ( lprj_MESS_TRAN =3D '1' ) AND > > > > ( TX_WRITE_BUFFER_STB =3D '1' ) AND > > > > ( project_name_cnt /=3D > > > > project_name_stg'high ) ) THEN > > > > project_name_cnt <=3D ( 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
> > > > ------------------------------??? ------------------------ > > > One quick thing I noticed in process "P5": > > > P5: PROCESS ( CLK_16_6MHZ ) > > > BEGIN > > > IF ( CLK_16_6MHZ =3D '1' AND CLK_16_6MHZ'EVENT ) THEN > > > IF ( RESET_COUNT( 3 DOWNTO 0 ) =3D "1111" ) THEN > > > RESET_COUNT( 3 DOWNTO 0 ) <=3D "1111"; > > > UART_RESET_BUFFER <=3D '0'; > > > ELSE > > > RESET_COUNT( 3 DOWNTO 0 ) <=3D RESET_COUNT( 3 DOWNTO 0=
)
> > > + 1 ; > > > UART_RESET_BUFFER <=3D '1'; > > > END IF; > > > END IF; > > > END PROCESS P5; > > > ------------------------------------???------------------------------=
=A2=BC
> > > The 2nd IF says that if RESET_COUNT is all 1's, then set it to all > > > 1's. I think that you meant to set it to all 0's. BTW, you don't > > > need "...(3 downto 0)..." because the signal is defined as (3 downto > > > 0). > > > so..... > > > > BEGIN > > > IF ( rising_edge( CLK_16_6MHZ ) ) THEN > > > IF ( RESET_COUNT =3D "1111" ) THEN > > > RESET_COUNT <=3D (others =3D> '0'); --=
ALL
> > > bits to '0' > > > UART_RESET_BUFFER <=3D '0'; > > > ELSE > > > RESET_COUNT <=3D RESET_COUNT + 1 ; > > > UART_RESET_BUFFER <=3D '1'; > > > END IF; > > > END IF; > > > -------------------- > > > HTH > > > -Dave Pollum > > > well certainly: > > > ~ IF ( RESET_COUNT( 3 DOWNTO 0 ) =3D "1111" ) THEN > > ~ RESET_COUNT( 3 DOWNTO 0 ) <=3D "1111"; > > > makes no sense. and 'something' bad happens when the 16th character > > is in the buffer, so this is definitely a near hit at least. lets see > > how > > reset_count, uart_reset_buffer are used... > > Ok this is a fking mess. > > what was done here was this, the "program" starts with > uart_reset_buffer > and uart_reset_next high, and the p5 process counts for 16 clock > pulses > to allow the system to startup. on the 16th pulse (=3D'1111') > uart_reset_buffer > goes low, and as a result of the D-FF that is made up on P6, > uart_reset_next > waits one clock pulse to go low. So for 1 and only 1 clock pulse, > > IF ( ( UART_RESET_BUFFER =3D '0' ) AND > ( UART_RESET_NEXT =3D '1' ) ) THEN > > is true. This is the trigger for the "hello world" message. > > Now I imagine there *must* be a better way to do this, and Jonathan B. > has > already pointed out that his section of code is, in technical terms, > higgley-piggley, > but it is not causing my current flub.
I still don't get it. Here's the simulation of the 16 character printout: http://jleslie48.com/fpga_uartjl_01/11jlmod/ccuart01/screencap/screencap13_= firstislast16.png everything looks to me ship-shape. I'm gonna have to compare this simulation to a 15 character one. anybody see anything?
Hi,

I would like to use a Spartan 3 100K FPGA to implement 16
serial ports.  The ports will be fairly simple: 1200 to
115200 baud, Tx, Rx, and two flow control lines per port.

I already have a working serial port and could make sixteen
instances of it.  This would chew up a lot of the FPGA.

Is there a better way to build sixteen serial ports?


Would it make sense to build one serial port and try to
time division multiplex it to the sixteen sets of inputs,
perhaps keeping all state information in RAM?  Is this a
feasible or reasonable approach?


thanks in advance
Bob Smith

Bob Smith <usenet@linuxtoys.org> wrote:
 
> I would like to use a Spartan 3 100K FPGA to implement 16 > serial ports. The ports will be fairly simple: 1200 to > 115200 baud, Tx, Rx, and two flow control lines per port.
> I already have a working serial port and could make sixteen > instances of it. This would chew up a lot of the FPGA.
> Is there a better way to build sixteen serial ports?
> Would it make sense to build one serial port and try to > time division multiplex it to the sixteen sets of inputs, > perhaps keeping all state information in RAM? Is this a > feasible or reasonable approach?
So only one data bus for all 16? My first thought is, assuming you have FIFOs on them, would be to multiplex the FIFOs (write the port and data into the FIFO) for the receiver, and then when you read it read the data and port. For the transmitter, that probably doesn't work, but you could use one RAM and 32 pointer registers. (top and bottom for each UART.) Can you use the SRL16 for the shift registers? Otherwise, a UART shouldn't be all that big. -- glen
On Feb 4, 7:32=A0pm, Bob Smith <use...@linuxtoys.org> wrote:
> Hi, > > I would like to use a Spartan 3 100K FPGA to implement 16 > serial ports. =A0The ports will be fairly simple: 1200 to > 115200 baud, Tx, Rx, and two flow control lines per port. > > I already have a working serial port and could make sixteen > instances of it. =A0This would chew up a lot of the FPGA. > > Is there a better way to build sixteen serial ports? > > Would it make sense to build one serial port and try to > time division multiplex it to the sixteen sets of inputs, > perhaps keeping all state information in RAM? =A0Is this a > feasible or reasonable approach?
What did your calculator say ? 115200 baud is 8.68us, at x8 or 16 sampling, that's ~2MHz. Split that 16 ways and you have ~32MHz - does not sound high..... 15-16 byte fifos would likely fit into a ~byte sized state variable.
On Tue, 3 Feb 2009 11:24:17 -0800 (PST), jleslie48 wrote:

>> I make the message string: >> constant project_name_stg : string := "123456789a12345"; >> >> aka, 15 characters, all is well. >> I make it 16 characters: >> constant project_name_stg : string := "123456789a123456"; >> >> my output becomes: >> 23456789a1234561 >> >> were the 1 at the end is indeed the first character not the last.
No conceivable way this could be correlated with the fact that your UART's FIFO buffer is 16 places deep, surely??? :-) -- 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.