I just had to do this for a client. I'm surprised the only reference designs I could find were ones that read and write to a FIFO rather than the Avalon switch fabric.
If you run the Avalon switch fabric using the EMIF clock, the design is much simpler since they are synchronized. If running at different clock speeds, it is more complex. For example, the avm_m0_read_n and avm_m0_write_n signals must be synchronous to the Avalon switch fabric, as indicated in the specs.
Be advised that the above example will read or write multiple times as it directly ties avm_m0_read_n, and avm_m0_write_n to the EMIF signals, as these signals are active for at least 3 clocks. Not a problem for most peripherials, but a problem if trying to access a FIFO.
Also, there is no checking for the dataready signal from Avalon. If you have a NIOS II processor connected to peripherials shared by the EMIF avalon master, the data may not be ready in time if the arbitrator is allowing the NIOS II access at the same time you want an EMIF master access. It is also a problem if you have a component that has a long, multi-cycle, or variable read duration. A provision for setting EMA_WAIT is necessary for this to be bullet-proof.
In the end, I managed to work out a solution that incorporated some asyncronous logic for latching write data from the EMIF (deferring the write cycle to operate after the chip-select was inactive), made the Avalon master syncronous to the switch fabric, transfered the EMIF chipselect into the Avalon clock domain, and made the EMIF data bus tri-stated (when necessary, i.e. EMA_OEn), and the high/low 16 bits of output data control logic output asyncronously through a wire assignment, in Verilog. I also ended up pre-setting the EMA_WAIT pin making the EMIF bus always wait until data is available from the read (and releasing it when a EMIF write cycle was in progress), rather than have it only happen within an active chip-select. This was because the EMIF strobe period needed to be set to at least 5 clocks for it to properly see and extend the wait cycle.
These methods all combined to allow the EMIF and Avalon to be operated at any speed independently, and at the fastest possible EMIF settings. I also wrote a simple interrupt controller to route the interrupts from the peripherials attached to the EMIF Avalon master back out to a common TI DSP interrupt input, and another avalon slave interface so the DSP could interrogate which peripherial is causing the interrupt.
I wish I could give the code away, but gave anyone with the know-how the essential details to do it properly. Actually, I wish Altera would have had a component I could have used. Surely, using an Altera FPGA and the SOPC builder tool for peripherial expansion for TI DSPs is a common thing to do. Isn't it?????
As a side note, it is nice to add a NIOS processor to your design, even if you aren't going to use it (you can remove it later), attach it to all the peripherial your DSP chip is going to use, and generate a BSP in the NIOS II IDE. You get a nicely generated system.h file you can use for your TI program to reference the base addresses and IRQs of your peripherials.....You still need to port the drivers to the TI side, but this gets you a head start in that direction. If you modify io.h to add the base EMIF address and modify IORD and IOWR macros, some of the simpler drivers, such as SYSID/TIMESTAMP don't even need any modifications at all for use on the TI DSP side.
Edit: Also, you should copy over alt_types.h to your TI project, and modify alt_u16, alt_u32, etc to apprioriate types, as TI's compiler's definition of long, for example, is 64 bits, and not 32 bits...This caused me some problems.