Interfacing FPGA to lpc2294 external bus

Started by itsjustimpossible January 10, 2006
Hi
I need to interface an FPGA to the external bus of the LPC2294 so
that I can directly read and write to the BlockRam internal to the
FPGA (Arranged as a dual-port RAM).

I just wondered if someone has already achieved this or knows of
some example VHDL they can point me at. We are very new to this,
just attended a VHDL course, and am wondering about the correct way
to go about it.

The XCLK seems to be the key to this, but I am currently trying to
sort out how to handle the control lines and the tri-state buffers.

The statement in the data sheet that is causing me a problem is
the "CS and OE lines may become low one XCLK earlier than is shown".
I assume then that I cannot use these lines directly as the address
bus may not be stable at that point.

I know this is probably blindingly obvious, but if anyone has some
pointers for a novice I would be very grateful.

If it makes any difference I am using an Altera Stratix.

Many thanks
Simon



An Engineer's Guide to the LPC2100 Series


> -----Original Message-----
> From: lpc2000@lpc2... [mailto:lpc2000@lpc2...] On Behalf
> Of itsjustimpossible
> Sent: Tuesday, January 10, 2006 6:33 AM
> To: lpc2000@lpc2...
> Subject: [lpc2000] Interfacing FPGA to lpc2294 external bus
>
> Hi
> I need to interface an FPGA to the external bus of the LPC2294 so
> that I can directly read and write to the BlockRam internal to the
> FPGA (Arranged as a dual-port RAM).
>
> I just wondered if someone has already achieved this or knows of
> some example VHDL they can point me at. We are very new to this,
> just attended a VHDL course, and am wondering about the correct way
> to go about it.
>
> The XCLK seems to be the key to this, but I am currently trying to
> sort out how to handle the control lines and the tri-state buffers.
>
> The statement in the data sheet that is causing me a problem is
> the "CS and OE lines may become low one XCLK earlier than is shown".
> I assume then that I cannot use these lines directly as the address
> bus may not be stable at that point.
>
> I know this is probably blindingly obvious, but if anyone has some
> pointers for a novice I would be very grateful.
>
> If it makes any difference I am using an Altera Stratix.

The LPC2294's external bus is async, so the XCLK is not absolutely needed.
I use a 4X XCLK (use FPGA PLL for this) to register the address and data in
the FPGA. The address bus will be stable when CS & OE return high, which is
when you latch/register write data or your read data should be stable.

Good luck!!!

Greg Deuerling
Fermi National Accelerator Laboratory



itsjustimpossible wrote:
> Hi
> I need to interface an FPGA to the external bus of the LPC2294 so
> that I can directly read and write to the BlockRam internal to the
> FPGA (Arranged as a dual-port RAM).
>
> I just wondered if someone has already achieved this or knows of
> some example VHDL they can point me at. We are very new to this,
> just attended a VHDL course, and am wondering about the correct way
> to go about it.
>
> The XCLK seems to be the key to this, but I am currently trying to
> sort out how to handle the control lines and the tri-state buffers.
>
> The statement in the data sheet that is causing me a problem is
> the "CS and OE lines may become low one XCLK earlier than is shown".
> I assume then that I cannot use these lines directly as the address
> bus may not be stable at that point.
>
> I know this is probably blindingly obvious, but if anyone has some
> pointers for a novice I would be very grateful.
>
> If it makes any difference I am using an Altera Stratix.

Hey Simon,

I have planned to interface an FPGA to an LPC part, but haven't had
time (I just tinker with the parts). If you want some help with the
interface, take a shot at it and let me know. I have the Altera tools
setup here and Mentor's ModelSim etc. The first thing you should try
and do is build a bus-functional-model (BFM) of the LPC external bus.
Basically you use non-synthesisable VHDL constructs (like time delays)
to implement the bus signal timing for a read, and then for a write.
Then you write your Stratix interface and write a test bench
to use the BFM to write and read to your Stratix i/f. If that works,
then it'll (usually) work on the real hardware (sometimes you
need to iterate to get a valid BFM).

Cheers
Dave


On 10 Jan 2006 at 12:33, itsjustimpossible wrote:

> Hi
> I need to interface an FPGA to the external bus of the LPC2294 so that
> I can directly read and write to the BlockRam internal to the FPGA
> (Arranged as a dual-port RAM).
>
> I just wondered if someone has already achieved this or knows of some
> example VHDL they can point me at. We are very new to this, just
> attended a VHDL course, and am wondering about the correct way to go
> about it.
>
> The XCLK seems to be the key to this, but I am currently trying to
> sort out how to handle the control lines and the tri-state buffers.
>
> The statement in the data sheet that is causing me a problem is
> the "CS and OE lines may become low one XCLK earlier than is shown". I
> assume then that I cannot use these lines directly as the address bus
> may not be stable at that point.
>
> I know this is probably blindingly obvious, but if anyone has some
> pointers for a novice I would be very grateful.
>
> If it makes any difference I am using an Altera Stratix.


The external bus is an async bus. When writing use the write strobes as the
"clock" signal that clocks the data into the specific RAM location.
Use the external CS signal to qualify the internal CS signal based on the address
bus. i.e. the output of the comparator block goes through a 2 to 1 mux using the
external CS signal as the select signal.
Do you want to be able to handle various bus-width accesses, mis-aligned
access etc. ? The easiest is to allow only one size access (aligned), whether it is
8, 16 or 32 bit. If you want to be able to handle all possible bus transactions,
then the complexity increases dramatically. Another problem if you are
accessing dual port RAM is that the LPC2294 does not have a "wait" signal
where you can stretch the access cycle if the other side is trying to access the
same address at the same time. You will need to implement some sort of
semaphore in the FPGA with which you can grant access to the dual port RAM
to either the one bus or the other bus. If you have simultaneous access from both
sides you WILL have problems.

Regards
Anton Erasmus
--
A J Erasmus


--- In lpc2000@lpc2..., "Anton Erasmus" <antone@s...> wrote:
>
> On 10 Jan 2006 at 12:33, itsjustimpossible wrote:
>
> > Hi
> > I need to interface an FPGA to the external bus of the LPC2294
so that
> > I can directly read and write to the BlockRam internal to the
FPGA
> > (Arranged as a dual-port RAM).
<snip>
> The external bus is an async bus. When writing use the write
strobes as the
> "clock" signal that clocks the data into the specific RAM
location.
> Use the external CS signal to qualify the internal CS signal based
on the address
<snip>

Hi
Thanks to all of you who replied, and thanks for the suggestions. I
am plugging away at the moment to get a test bench working to
incorporate them. I did try the quick-stab approach which failed
miserably so I am now doing it properly.

To answer the last questions, all I need is simple read/write access
over an 8-bit bus. No multi-master or different bus widths to
contend with, so I was hoping that it would be straightforward.

It should all make a bit more sense once I have it running in the
simulator.

cheers
Simon





> Hi
> Thanks to all of you who replied, and thanks for the suggestions. I
> am plugging away at the moment to get a test bench working to
> incorporate them. I did try the quick-stab approach which failed
> miserably so I am now doing it properly.
>
> To answer the last questions, all I need is simple read/write access
> over an 8-bit bus. No multi-master or different bus widths to
> contend with, so I was hoping that it would be straightforward.
>
> It should all make a bit more sense once I have it running in the
> simulator.
>

Hey Simon,

> so I am now doing it properly.

Good for you!

I took a quick look at the data sheet, and it really doesn't
look too hard. The FPGA either needs to look like SRAM, which the
dual-ported SRAM in the FPGA can do quite nicely, or a
clocked register could be made to work as well. You might
just have to setup the LPC wait-states.

The downside of the LPC implementation of their external bus
interface is that you can't force the processor to wait for a
variable number of cycles (via a WAIT# input pin).
eg. lets say you wrote an SPI controller in the FPGA, if
you could extend the processor read cycle, then you can
force the read to take as a long as the SPI transaction.
However, the solution is to make sure you route an interrupt
line between the LPC and the FPGA, and then you start a
transaction by writing to a register, then poll for done,
or use an interrupt, then read the result. In each case,
access is to a register, so the timing on the bus is
identical.

Cheers
Dave


--- In lpc2000@lpc2..., David Hawkins <dwh@o...> wrote:
<snip>
> You might just have to setup the LPC wait-states.

I did have to set WST1=1 and WST2=1 in the LPC, this gives one more
clock cycle per access and seemed to help a lot.

>
> The downside of the LPC implementation of their external bus
> interface is that you can't force the processor to wait for a
> variable number of cycles (via a WAIT# input pin).
<snip>

Luckily the wait state part is not a problem in this case (well not
so far anyway).

>
> Cheers
> Dave
>

I now have it working and have tried to incorporate as many
suggestions as possible. Only problem is it looks a bit too
straightforward to be true (safe).

I am using an XCLK of 60MHz multiplied by 4 in the FPGA and fed to
the blockRam.
An option in the blockRam allows all inputs and outputs to be
registered so I have connected its address and data input busses
directly to the uP busses. After this it seems the only thing left
to do is generate a 'WriteNow' and 'ReadNow' signal to be fed to the
BlockRam and to tri-state the data output bus.

This is all there is...

P_uP_INTERFACE: process (tl_ReadNow, tl_RAM_DATA_OUT)
begin

if (tl_ReadNow = '1') then
tl_DataIn <= tl_RAM_DATA_OUT;
else
tl_DataIn <= (others => 'Z');
end if;

end process P_uP_INTERFACE;

---------------

tl_WriteNow <= (not tl_CSIn) and (not tl_BLSOIn);

tl_ReadNow <= (not tl_CSIn) and (not tl_OEIn); Simulates OK and seems to work in practice. Just seems a bit un-
complicated.

Thanks for the help so far, if you have any comments they would be
greatly appreciated.

Many thanks

Simon



> I now have it working and have tried to incorporate as many
> suggestions as possible. Only problem is it looks a bit too
> straightforward to be true (safe).

That's always the best solution!

> I am using an XCLK of 60MHz multiplied by 4 in the FPGA and fed to
> the blockRam.
> An option in the blockRam allows all inputs and outputs to be
> registered so I have connected its address and data input busses
> directly to the uP busses. After this it seems the only thing left
> to do is generate a 'WriteNow' and 'ReadNow' signal to be fed to the
> BlockRam and to tri-state the data output bus.
>
> This is all there is...
>
> P_uP_INTERFACE: process (tl_ReadNow, tl_RAM_DATA_OUT)
> begin
>
> if (tl_ReadNow = '1') then
> tl_DataIn <= tl_RAM_DATA_OUT;
> else
> tl_DataIn <= (others => 'Z');
> end if;
>
> end process P_uP_INTERFACE;

I believe:

tl_DataIn <= (others => 'Z') when (tl_ReadNow = '0')
else tl_RAM_DATA_OUT;

compiles more efficiently on Altera devices (there is an app
note somewhere for the FLEX devices). Probably makes no difference
on the Stratix devices.

> tl_WriteNow <= (not tl_CSIn) and (not tl_BLSOIn);
>
> tl_ReadNow <= (not tl_CSIn) and (not tl_OEIn); > Simulates OK and seems to work in practice. Just seems a bit un-
> complicated.

Just check the setup/hold times. However, since the FPGA is running
off the XCLK, you can tune things pretty nicely.

> Thanks for the help so far, if you have any comments they would be
> greatly appreciated.

Sounds like you're all set. Let us know how things go.

Dave


--- In lpc2000@lpc2..., David Hawkins <dwh@o...> wrote:
<snip>
> Sounds like you're all set. Let us know how things go.
>
> Dave
>

Thats great! Always good to have a bit of a second opinion.

Thanks for your help.

cheers
Simon