--- Quote Start ---
We are using a TS-7400 CPU board which basically has a 20 bit data IO bus that comes off of a CPLD on their board. They use a EP9302 processor chip which is running from the 14.7456 MHz crystal. However, I do not know about whats happening internal to that processor. The 9302 talks to their CPLD and manipulates the data IO bus. They also pass the 14 MHz clock signal through their CPLD (which ends up being the FPGA clk) and they can turn it off or on in the CPLD (which means there must be delays as it passes through their CPLD).
--- Quote End ---
I looked at the TS-7300 a while back. There was an
OpenCores.org design for the external bus interface. If Technologic Systems have used the same design for the TS-7400, you might get some nice tips in there. The code was written bu Jesse Off, one of TS's design engineers.
So your FPGA is attached to their board? Is this a PC104 module, or something like that?
--- Quote Start ---
We have decided to use 8 bits as a multiplexed addr/data bus and 3 other lines as ale, rd, and wr. Because of the number of IO lines we need from the FPGA its not practical to use more lines to interface to the TS7400.
So our code that runs on the TS7400 basically goes through this process:
Set the Data Direction Register (DDR) for DIO[7:0] to output.
Place the data on the data bus.
Set the ale (or wr) bit high.
Set the ale (or wr) bit low.
Read cycles would by like this:
Set the DDR for DIO[7:0] to input.
Set the rd bit high.
Read the DIO[7:0] data
Set the rd bit low.
--- Quote End ---
So you have essentially taken the external processor bus and turned it into a bit-banged I/O bus. This is not exactly the most efficient way you could have done this, but lets put that aside for now, and get you something that will work. We can 'optimize' later.
--- Quote Start ---
By scope measurements I have determined that the rate that we can go through this process takes about 1us for each steo (depending on what instructions we need to execute). That means when writing (addr or data) the data will be on the DIO bus about 1 us before the rising edge of ale or wr and will be held there until about 1 us after the falling edge of ale or wr. We would read data in about 1 us after asserting rd. Seems like plenty of setup and hold time to me though the ale, wr, and rd are not necessarily synchronous with the clk signal.
--- Quote End ---
Right, this is the second option I mentioned, and Nial expanded upon.
You are interfacing to an
asynchronous bus, and the timing of that bus is slow compared to your FPGA clock (which with the use of a PLL can be ~100MHz).
To interface to this type of bus, you need to:
1) Use synchronizers (a chain of at least two DFFs) to synchronize the control signals from the TS-7400 board (ALE, RD and WR, but not the 8-bit data bus) to the FPGA clock domain.
2) You create an edge detector to detect when ALE pulses, and use that to capture the address into a register clocked by your FPGA clock.
3) You create a state machine that is triggered by the ALE pulse (in the FPGA clock domain), and use that to sequence the read or write cycle from the FPGA.
If I was writing this code, I'd create a bus functional model (BFM), which is just a fancy way of saying a simulation for the read/write accesses. I'd then simulate the logic in Modelsim to make sure I could read and write from some registers in my FPGA. Then I'd run some hardware tests and capture some SignalTap II traces to confirm that my BFM signals matched the hardware. Because your signals are all asynchronous, your .SDC file will cut the timing along those signal paths.
If this all sounds completely foreign to you, let us know, and Nial or myself, or someone else will give you code examples.
Cheers,
Dave