FPGA to SRAM port interface

I'm interfacing an FPGA to a multiplexed SRAM port (ALE, READ, WRITE, DATA/ADDR bus). I want to read from/write to the FPGA internal block RAM (SPARTAN 3E), using burst accesses.

This is a write access example. ____ ALE ___/ \__________________________________________________ _______________ __ __ __ ______ WRITE# \______/ \______/ \______/ \______/ ________ ________ ________ ________ ________ DTADD ____/ ADDR \/ DATA0 \/ DATA1 \/ DATA2 \/ DATA3 \______ \________/\________/\________/\________/\________/

For the address load and increment I combined ALE, READ and WRITE signals to generate one clock signal. CLOCK

Reply to
oen_br
Loading thread data ...

oen_br schrieb:

Use a clean clock (from a XO or so) to clock the FPGA logic. Not clock gating etc.! Build text book style FSMs to contol the BRAM and generate appropiate signals for your external SRAM. Than it will work fine.

Hint. Register at least WRITE# to the SRAM, so it will not glitch.

No, you have just one system clock, that generates all other signals. A clean 1 clock design. Just too easy ;-)

Regards Falk

Reply to
Falk Brunner

Hi Falk,

Yes, for the BRAM too. Why not? The ALE, READ# and WRITE# signals will never overlap!

I don't know what 'XO' means, but I think you mean a crystal (it reminded me Galactica Colonel Tigh :-) ). Anyway the tranfer rate is 60MHz (mega transfers per second), so, to sample ALE, etc, I will need a very high frequency clock signal (200MHz maybe?). Even if it is possible, it will spend a lot of power! Did I misunderstand you?

There is no external SRAM, just the internal BRAM used as a mail box! Two processors, each one using one BRAM port.

Thank's,

Luiz Carlos.

Reply to
oen_br

In order for the CLOCK signal to go high, ALE must be low, in your logic, since (not ALE) is AND'd with WRITE# and READ#. So that implies inside your 'if' the ALE='1' can never be true.

Perhaps changing your logic to falling_edge(CLOCK) might fix it within your approach. Or invert the CLOCK signal from what it is now.

-Dave

--
David Ashley                http://www.xdr.com/dash
Embedded linux, device drivers, system architecture
Reply to
David Ashley

Hi David,

The clock is right, I need to load the address at the falling edge of ALE. If you consider ALE falling edge generated the rising clock edge, ALE must be low at this point. So, ok, it should be "if (ALE = '0') then". But I'm not sure if the time taken by logic (inverting and anding ALE), and buffering this signal/clock will offer the sufficient setup time for the test. I mean, will it always work? Can I change the speed grade or the family of the FPGA ? Do I need to use some type of time constraint?

Luiz Carlos

Reply to
oen_br

oen_br schrieb:

You better learn about synchronous design. And glitching of clocks.

Yes.

Ahhhh, the FPGA is used to connect two processors, right? Hmm, in this xase why do you want to use a FPGA? There are dedicaded dual port memories, ready to use.

formatting link

Regards Falk

Reply to
Falk Brunner

The whole point is you want to write the first data at the address specified, the next data at the next address... what if when you load the first address you do a "-1" calculation right then? So when the first data is to get loaded, it does its "+1" and you're at the real address you wanted. So you are loading the address right at the start of each cycle, plenty of setup + hold time in all cases.

I just don't like your logic of testing ALE inside the clocked section -- when the clock itself depends on ALE. This is really questionable, get that out of the picture and things will get simpler.

-Dave

--
David Ashley                http://www.xdr.com/dash
Embedded linux, device drivers, system architecture
Reply to
David Ashley

I've been looking at this more...it seems easy on the face of it but it's somewhat complicated.

You want when ALE goes from high to low for the address latch to get the initial address you want to load. And when READ# or WRITE# go from low to high, you want the address latch to get its current value plus one. This implies 2 clocks...which is out of my experience but I suspect isn't synthesizable.

Now, if you could have a set-reset latch in the picture that would make everything easy. When ALE is high, the SR goes to 1. When READ# or WRITE# go low, the SR goes to 0. Your original post had the LOAD_ADDR signal getting set when there was a rising_edge of ALE, and an async clear when READ# or WRITE# go low, which is the 2 clock problem in the first place. When would do it is an async set instead of the clocked set. You don't need any clocking on this.

I suppose you could describe the logic as 2 nand gates. I looked at xst.pdf and couldn't find a simple set/reset flip flop.

Unisim has an entity FDCP which is: D Flip-Flop with Asynchronous Clear and Preset

architecture FDCP_V of FDCP is begin VITALBehavior : process(C, CLR, PRE) variable FIRST_TIME : boolean := true ; begin

if (FIRST_TIME = true) then Q

Reply to
David Ashley

CLK _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-

No, you want the continuous clock that generated ALE. In a synchronous system, ALE is an input, not a clock.

-- Mike Treseler

Reply to
Mike Treseler

Falk, I'm aware of the danger of gererated clocks, but in this case I couldn't see any problem (at least until now). The signals are clean and have some nano-seconds between their activation.

Not really. The FPGA, besides other functions, connects 4 DSPs, a shared external SRAM and a PCI controller, everybody talking to everybody.

I thought this kind of problem was very common (combinatorial clocks using it's source signals as clock enables)!

Thanks,

Luiz Carlos

Reply to
oen_br

Mike, I don't have access to this clock.

Luiz Carlos.

Reply to
oen_br

Hi Dave,

Yes, that's the point. I also don't like it, but if possible and safe, it would be the easier way. Can it be made in a safe way? This is what I'm trying to learn!

Luiz Carlos.

Reply to
oen_br

oen_br schrieb:

In this case, a SYNCHRONOUS bus is strongly suggested. AFAIK many DSPs output the bus clock along with all other signals.

This is bad bad hack an shounld be avoided as much as possible. Maybe sometimes even more ;-)

Regards Falk

Reply to
Falk Brunner

Yes, but not the parallel port of ADSP-21363!

I would like to have the DSP peripheral clock, but I have to work with what is available.

Luiz Carlos.

Reply to
oen_br

In that case, I would use a PLL or add an oscillator to resynchronize everything to one clock.

-- Mike Treseler

Reply to
Mike Treseler

Few years ago I had this asynchronous interface running at ~25Mhz, not sure for 60Mhz. You may try to load the address asynchronous. No reason why it doesn't work if you take care setup/hold time

process(ALE, WRITE#) if (ALE = '1') then addr

Reply to
Marlboro

For the love of god, would the original poster please post a follow up on what finally makes the thing work? Too many people post questions, get answers, then vanish.

Note the WRITE# isn't enough, there's also the READ#. But this code seems perfect, if it works.

-Dave

--
David Ashley                http://www.xdr.com/dash
Embedded linux, device drivers, system architecture
Reply to
David Ashley

David,

I don't have the hardware yet, so, I'm just doing simulations. It will take more 3 to 4 months for the prototype board, but I'm trying to catch early designs faults. (Actually I'm doing everything, hardware, software and pre-layout, and a lot of times I have to stop and do other things!) At simulations, it worked (using auxiliary signals as that LOAD_ADDR), but I want a robust, clear and as simple as possible design. So I asked for some guide lines/ideias. I'll share the results when I have them.

Luiz Carlos

Reply to
oen_br

Marlboro,

This means that the CLB storage must have flip-flop and latch behavior at the same time, and I think it's not possible. When it's a flip-flop you can have preset/clear input, but it is preset or clear. Well, looking at the datasheet I found that "rev" input, I need to read more about it.

Luiz Carlos

Reply to
oen_br

Good point, I guess the synthesizer will "decode" the combine logic of dtadd & ALE and feed outputs to async R/P of the flipflops...

For example R(0) = ALE and not(dtadd(0)), P(0) = ALE and dtadd(0)...

Reply to
Marlboro

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.