Re: Got UART Working!!! need syntax help with using ascii/buffer scheduling.
- From: rickman <gnuarm@xxxxxxxxx>
- Date: Mon, 26 Jan 2009 14:27:26 -0800 (PST)
In and email Jonathan Leslie said:
TX_DATA_IN( 7 DOWNTO 0 ) <= x"55";What is wrong with the way you have it written above?
JL:: - nothing if all I want is a single character on the outbound, but the idea is to get to a point where I can put message strings on the outbound uart. My app will need message packets sent out, and making long strings of hex code makes for a maintenance nightmare.
having a string of
TX_DATA_IN( 7 DOWNTO 0 ) <= x"55";
-- send char
TX_DATA_IN( 7 DOWNTO 0 ) <= x"45";
-- send char
TX_DATA_IN( 7 DOWNTO 0 ) <= x"62";
-- send char
is gonna get real annoying I'm building up to making a
communication package where I can send out on my uart
send_to_uart("UUT:init");
or
send_to_uart("UUT:shutdown");
1) Instead of using a test for the clock being 1 and an event, you
should use rising_edge(clock). This is a standard form and will make
the simulation match the synthesis better.
JL:: - check. thanks for semantic correction.
2) The above should be a single process and not combined with
anything else.
JL:: Quite right, I think I misspoke. I mean that the routine needs to be able to handle a "parameter" (using a c term) in
place of the x"55" where some other routine establishes what exactly is going to be sent on the TX line.
It will check for the trigger just as you have it
written. When found, it will use the character currently pointed to
by the index and increment the index. Remember that HDL describes
hardware and this is a description of the transmit holding register
and the logic controlling its timing. BTW, is this a holding
register or the transmitter data register (the one that shifts the
data out)? If the latter, you need to describe both the loading and
the shifting in one process.
JL:: not sure what your getting at here. I don't see anything to increment an index. Now as far as how the tx_data_in is used,
either as a register or transmitter data register, well that's a good question. I'm gonna have to dig a little on that one.
You need to *add* a counter. The only way you can access the
individual characters in the string is to use an index. Thinking of
this in hardware, there will be a tx shift register, a tx holding
register and a character source which does not need to be a register,
but can be.
The two registers need to define their controls and actions in the
same or different clocked processes. The character source is
controlled by a counter which also needs to be defined in a clocked
process. The character source can be defined in an unclocked process
or in a concurrent statement. In the process it would be a case
statement. In a concurrent statement it would be a selected
statement, IIRC (the one that uses "with").
I can tell that you are still trying to code in C. When you refer to
this as 'the routine needs to be able to handle a "parameter"' that
says to me that you are thinking of a subroutine that is called by a
higher routine. VHDL does not work like that really. A process is
*not* a subroutine. A process defines hardware that runs separately
from the other hardware in the design.
Here is a way to visualize the difference. When you program in C, you
would normally use a flowchart. That shows sequences of operations.
When you program in an HDL, you would instead use a data flow
diagram. That shows different operations on data that happen at the
same time. In a flowchart, blocks can be used that represent
subroutines that can be separately charted in levels. In a data flow
diagram, each block is a process that runs all the time and acts on
whatever data is presented to it.
The way I'm thinking is that I'm gonna need a fifo buffer where the transmit characters are placed and as long as that buffer is not empty the P7 process will take a character, load it into the tx_data_in register, and send it on its way. the fifo buffer handler will then move its pointer to the next character in the fifo.
You would only need a FIFO if you can't control the rate that
characters are sent to the Xmitter. Since you are producing the
characters, you can control that. Actually, the same is true for a Tx
Holding register. It is only there so that a CPU can have a full
character time to send the next character to the xmitter. The xmitter
has timing to control the character shifting. When it is complete,
the next data is loaded into the TxData register. A TxRdy signal is
asserted at this time and the counter is incremented so the next
character is presented.
Having a poor memory for detail, I always have to use templates or
look at existing code in order to write HDL. So I'll use pseudo code
here, meaning don't trust my details...
constant TstData : string(0 to 15) := "Testing 1, 2, 3!";
signal TxCntr : integer range 0 to 15;
TxNxtData <= TstData (TxCntr);
-- Data source control, provide string data to the UART, repeat every
16 chars
process SelectCntr ( clk, reset ) is
begin
if (reset = '1') then
TxCntr <= 0;
elsif ( rising_edge (clk) ) then
if ( TxRdy = '0' ) then
TxWrite <= '0';
else
if ( TxWrite = '0' ) then
TxWrite <= '1';
if ( TxCntr = 15 ) then
TxCntr <= 0;
else
TxCntr <= TxCntr + 1;
end if;
end if;
end if;
end if;
end process;
-- This code should be replaced with your UART code
process UART_Tx ( clk, reset ) is
begin
if (reset = '1') then
TxCntr <= 0;
elsif ( rising_edge (clk) ) then
if ( TxBitCnt = 9 ) then
if ( TxWrite = '1' ) then
TxData <= '0' & TxNxtData;
TxRdy <= '0';
TxBitCnt <= 0;
elsif ( TxBitTiming = '1' ) then
TxRdy <= '1';
end if;
elsif ( TxBitTiming = '1' ) then
TxData <= TxData ( TxData'high - 1 downto 0 ) & '1';
TxBitCnt <= TxBitCnt + 1;
end if;
end if;
end process;
Does this make sense? Do you see how this is different from writing C
code?
Rick
--- On Mon, 1/26/09, Rick Collins <gnuarm.2006@xxxxxxxxx> wrote:.
From: Rick Collins <gnuarm.2006@xxxxxxxxx>
Subject: Re: RS232 Uart is working!! now to get it cleaned up.
To: jon@xxxxxxxxxxxxxxxxxx
Date: Monday, January 26, 2009, 2:16 PM
At 01:34 PM 1/26/2009, you wrote:
Ok finally,
I've got a working UART. I initially had it monitor the receive line
and echo back out the character that it received.
I then changed it so that just sent the the letter 'U' by stuffing the
hex code in the TX_DATA_IN buffer:
TX_DATA_IN( 7 DOWNTO 0 ) <= x"55";
so
1) instead of manually converting 'U' to x'55', how do I use a
string literal to do the job.
for instance in C, I would simply write:
tx_data_in = 'U';
which is the same as the c code:
tx_data_in = 0x55;
my point is, I want to be able to use the ascii character instead of
the hexidecimal code.
What is wrong with the way you have it written above? Although the
above is a character literal and not a string. A string would be
"abcd". To send that you would need a loop that sends each character
in turn. You can either put a check for TxRdy explicity in the loop
code or you can make a function that waits for TxRdy and sends one
character. Then call this function in the loop.
Opps, I guess I was thinking of C code. You can do something
similiar in VHDL using an index to address the string.
2) I want a scheduler so that I can put out whole messages. I want to
be able to write on the uart, "I got it\n"
I can see a language element in VHDL called string:
constant char_sequence : string := "I got it";
but I'm not sure if that is the right way to do it. in addition, I
don't now how to send the characters of char_sequence out
sequentially.
here is my transmit process:
-------------------------------------------------------------------------------------------------
-- LATCHING NEW TRANSMIT DATA FROM RECEIVE UART ( TX_DATA_IN
[ 7-0 ] )
-------------------------------------------------------------------------------------------------
P7: PROCESS ( CLK_16_6MHZ, UART_RESET_BUFFER, RX_READ_BUFFER_STB,
RX_DATA_OUT( 7 DOWNTO 0 ) )
BEGIN
IF ( CLK_16_6MHZ = '1' AND CLK_16_6MHZ'EVENT ) THEN
IF ( UART_RESET_BUFFER = '0' ) THEN
IF ( RX_READ_BUFFER_STB = '1' ) THEN
TX_DATA_IN( 7 DOWNTO 0 ) <= x"55";
END IF;
END IF;
END IF;
END PROCESS P7;
now the x"55"; is gonna have to change, but I imagine that this
process will need
to be an entity in another process that is aware of the characters "I got
it" and schedule the
8 characters (I, ,g,o,t, ,i,t) to go out.
1) Instead of using a test for the clock being 1 and an event, you
should use rising_edge(clock). This is a standard form and will make
the simulation match the synthesis better.
2) The above should be a single process and not combined with
anything else. It will check for the trigger just as you have it
written. When found, it will use the character currently pointed to
by the index and increment the index. Remember that HDL describes
hardware and this is a description of the transmit holding register
and the logic controlling its timing. BTW, is this a holding
register or the transmitter data register (the one that shifts the
data out)? If the latter, you need to describe both the loading and
the shifting in one process.
Rick
- Follow-Ups:
- References:
- Got UART Working!!! need syntax help with using ascii/buffer scheduling.
- From: jleslie48
- Re: Got UART Working!!! need syntax help with using ascii/buffer scheduling.
- From: Jonathan Bromley
- Re: Got UART Working!!! need syntax help with using ascii/buffer scheduling.
- From: jleslie48
- Re: Got UART Working!!! need syntax help with using ascii/buffer scheduling.
- From: jleslie48
- Re: Got UART Working!!! need syntax help with using ascii/buffer scheduling.
- From: Jonathan Bromley
- Re: Got UART Working!!! need syntax help with using ascii/buffer scheduling.
- From: jleslie48
- Got UART Working!!! need syntax help with using ascii/buffer scheduling.
- Prev by Date: Re: Got UART Working!!! need syntax help with using ascii/buffer scheduling.
- Next by Date: Re: dual MIG controller on spartan 3A DSP
- Previous by thread: Re: Got UART Working!!! need syntax help with using ascii/buffer scheduling.
- Next by thread: Re: Got UART Working!!! need syntax help with using ascii/buffer scheduling.
- Index(es):
Relevant Pages
|