ARM Interface Block Data Sheet


The ARM IF block is the Xilinx side of the "virtual port" abstraction for communication between the ARM and the Xilinx.  It's the object through which all ARM <--> Xilinx communication passes.  The ARM Interface symbol (see below) represents the ARM processor from the viewpoint of the Xilinx design i.e. inputs to the ARM on the left, outputs from the ARM on the right.

The mechanisms of that communication should generally not be of concern to the application designer.  The features of the ARM IF block that most designers will use are the 15 32-bit read ports, the 15 32-bit write ports, the three master clock lines, and the FIQ and IRQ interrupt inputs.

Connection between this block and library or custom blocks is via Viewdraw buses for connections with multiple signals (e.g. ports) and nets for connections with one signal (e.g. read).  The cleanest way to make these is to connect a bus or net stub to the ARM IF block where appropriate and assign a label to it, then connect another bus or net stub to the custom or library block and give it the SAME label.  Careful to make sure the labels are identical.

To make a bus, hit the B key, press the left mouse button at a pin (the blue lines in the picture below), draw out a stub, then press the right mouse button to end the bus.  Hit escape to end the command.  Double-click on the bus and a dialog box will appear.  Type a string into the LABEL field and hit return.  You can move the label independent of the bus by left clicking and dragging.

To make a net, do the same thing as for a bus except hit the N key.

There are many examples in \\hitz\designs\picoradio\TestBed\Applications.  Check them out.

The ARM Interface Block also contains the following services:

 

 

The simplest way to add your design to the Xilinx is to generate VHDL for it, then instantiate the VHDL in the workspace at the top level.  Single-bit ports are mapped to signals on a Xilinx symbol, and multi-bit ports are mapped to busses. 

When your VHDL port definition is ready, run vhdl2sym <your VHDL file name> in a tcsh window within your Xilinx project directory (where sym and sch subdirectories are located).  This will generate a symbol with all necessary attributes.  Then, open the project workspace schematic in Viewdraw, hit the C key, and use the dialog to instantiate your new symbol in the schematic.  Connect the new symbol where appropriate using the methods described above.

Convention is to put VHDL source files in the behv subdirectory of your Xilinx workspace.

 


ARM Interface Pins:

This interface provides six functions: 

1) 15 independent bidirectional 32-bit wide ports, 
2)
port activity flags, 
3)
master clock source, 
4)
interrupt lines, 
5)
digital board LED interface, and  
6)
raw processor bus interface.

ports:

RD_n_[31:0]
WR_n_[31:0]

All ports are equivalent, so choice of port number for any given Xilinx block is arbitrary.  However, IF you instantiate any PRTB library block that uses a port, then you MUST tell the kernel which port you have assigned to that block.  For instance, the Bluetooth interface block takes two ports: one write port for control and one read port for status.  If  you use the Bluetooth block, in app_Init() you must insert two calls to the ARM library function xilinx_SetPortAssignment(): xilinx_SetPortAssignment(PA_RADIO_CNTL, n); and xilinx_SetPortAssignment(PA_RADIO_STATUS, m); where n and m are port numbers.

The ARM library function xilinx_ReadPort(n) returns the integer value present on Xilinx read port n (RD_n_[31:0]).  The ARM library function xilinx_WritePort(n,m) places the integer n on Xilinx write port m (WR_m_[31:0]).

An ARM integer is 32 bits wide, so bitwise operations on the read or written integers have the corresponding effect on the port signals.  For example, the instruction xilinx_WritePort(3, 5 & 0x4); will set bit 2 on port WR_3_[31:0], since 0x4 (2 ^ 2) masks bit 2 (the third most significant bit after bits 0 and 1).  Of course, this is a stupid instruction, but hopefully you get the idea.

The concept of bit masking on a port is key for manipulating designer-defined control blocks in the Xilinx.  With bit masking, you can treat a single port as 32 independent signals.  One very useful tactic that I use a lot in library blocks is to pick an adjacent pair of bits as "on" and "off" switches for a single control signal.  For example, let's say I want to control a Tx/Rx signal for a radio where Tx = 1 and Rx = 0.  I'll assign, say, port 6 for the radio controller and bits 0 and 1 in that port for control of the Tx/Rx signal; 0 for on and 1 for off.  In the controller, I'll put a JK flip-flop (or equivalent) with the J  input connected to port 6 bit 0 and the K input connected to port 6 bit 1.  When software wants to transmit, it makes two function calls: xilinx_WritePort(6,0x1) followed by xilinx_WritePort(6,0).  Conversely, to receive, it calls xilinx_WritePort(6, 0x2) also followed by xilinx_WritePort(6,0).  There are two advantages to this method:

  1. When multiple control signals in the same block are manipulated by the ARM, code in the ARM does not need to store the previous value written to the port; in other words, the port is "stateless" from the viewpoint of the ARM.  State is maintained only in the Xilinx.  Occasionally, Xilinx block state is needed by the ARM code.  Best way to deal with this is to assign an ARM IF read port to a status port on the Xilinx block in question and query that port from the ARM using xilinx_ReadPort().

  2. A Xilinx block does not need to use the port activity flags for control since a control action is always a single bit transitioning from low to high.

port activity flags:

READ
WRITE
SEL[14:0]

The READ signal goes high for one master clock cycle when any read port is accessed.  The WRITE signal goes high for one master clock cycle when any write port is accessed.  A bit in SEL[14:0] goes high for one master clock cycle when a read or write on the corresponding port occurs e.g. if SEL10 pulses then there is activity on either RD_A_[31:0] or WR_A_[31:0].  Combining the port activity flags allows you to discriminate between read and write activity on any given port number.

These signals are useful primarily for data flow where the value on a port is atomic, that is, individual bits have no special significance to the Xilinx block that sources or sinks the port.

master clock source:

MCLK[2:0]

The three signals in this bus are independent 20MHz master clocks.  Each clock is driven by its own global driver (bufgs).  You can derive slower clocks from these.  Make sure to take fanout into consideration when assigning clocks.  If your block has a lot of regular state or logic (wide registers, big muxes, etc) use multiple master clocks distributed evenly.

interrupt lines:

FIQ
IRQ

These two signals are the means by which a Xilinx block requests service from the ARM.  A positive transition on the FIQ line initiates the system-wide FIQ handler, while a positive transition on the IRQ line initiates the Xilinx IRQ handler.  These signals are edge-sensitive i.e. in order to request a second interrupt, the lines must be taken low and then high again.  See ... for an in-depth discussion of the FIQ and IRQs.

digital board LED interface:

LEDS[7:0]

The eight bits in this bus are directly routed to the row of eight LEDs on the digital board.  It's sometimes useful to assign signals to the LEDs for debugging or status purposes.

raw processor bus interface:

CS/
RD/
WR/
ARM_ADDR[7:0]
ARM_DATA[31:0]

In very rare circumstances it may be useful to have direct access to the ARM address and data busses.  These can be used if a need arises that isn't addressed by the ARM IF block.  Operation of these signals conforms to typical bus transfer protocols.  For more info, see Fred.