BUS
INTERFACE
Now, lets design an on-chip bus peripheral interface
to enable robust and easy reuse of peripheral cores
and to prepare for an ecology of interoperable cores
to come.
It
helps to distinguish between core users and core designers.
The former are more numerous, while the latter are
more experienced. Therefore, I make ease-of-use tradeoffs
in favor of core users.
Because
FPGAs are malleable and FPGA SoC design is so new,
I wanted an interface that can evolve to address new
requirements without invalidating existing designs.
With
these two considerations in mind, I borrowed a few
ideas from the software world and defined an abstract
control signal bus with all of the common control
signals collected into an opaque bus CTRL15:0.
MEMCTRL
drives CTRL and also does I/O address decoding, driving
the eight I/O selects SEL7:0.
Now,
you need only instantiate the core, attach CLK, CTRL,
D, some SELi, any core-specific inputs and
outputs, and youre done!
Contrast
this with interfacing to a traditional peripheral
IC. Each IC has its own idiosyncratic set of control
signals, I/O register addresses, chip selects, byte
read and write strobes, ready, interrupt request,
and such. They dont call it glue logic for nothing.
Of
course, we cant just sweep all the complexity
under the rug. Each core must decode CTRL and recover
the relevant control signals. This is done with the
DCTRL (CTRL decoder) macro (see Figure 5). DCTRL inputs
SELi, CTRL15:0, and CLK and outputs local I/O
register address, upper and lower byte output enables
(read strobes), and clock enables (write strobes).
Within
each DCTRL instance, you do final address decoding
for the specific peripheral, combining its SELi
signal with the I/O select within CTRL15:0. Here XIN8
only uses LDT (the LSB output enable). The other DCTRL
outputs are unloaded and automatically eliminated
by the FPGA implementation tools.
Using
DCTRL and the on-chip tri-state bus, the typical overhead
per peripheral is only one or two CLBs, and perhaps
a column of TBUFs.
Control
signal abstraction can also make bus interface evolution
easy. If you revise MEMCTRL and DCTRL together, arbitrary
changes to CTRL15:0 can be made without invalidating
any existing designs. And, to add new bus features,
simply design a new decoder DCTRL_v2, causing no changes
to existing DCTRL clients.