Project The AXI and APB busses

Creating peripherals and bridging between different AMBA busses

3416

Project 3 (APB Version)

The Advanced Microcontroller Bus Architecture (AMBA) standard defines a number of open bus standards for on-chip interconnects. AMBA was created by ARM and as open-standards the interfaces can be implemented without licensing fees.

The current AMBA specification includes many different bus standards. Of these the three most commonly used are Advanced Extensible Interface (AXI), Advanced High-performance Bus (AHB), and Advanced Peripheral Bus (APB). AXI and AHB are high-speed system buses which can connect one or more processing units to memory and other high-speed on-chip resources (such asb external memory controllers or high speed communication interfaces). The main system bus is often bridged to a slower ‘peripheral bus’ which is used to connect the processor to low-bandwidth peripherals (UARTs, SPI, GPIO, etc).

Many microcontrollers (often ARM cortex-M based systems) use AHB or AHB-lite as the main system bus. Higher performance cores (such as the Cortex-A series) have AXI-based interfaces.

AHB is a simpler interface and while still being high-performance, doesn’t need as many on-chip resources to implement. This reduces the power consumption, making it ideal for low power microcontrollers.

AXI has higher throughput, as its highly pipelined design allows for higher utilization of the bus when shared between multiple CPU cores and DMA masters. AXI can support complex bus topologies, sharing slave endpoints between multiple bus masters with multiple transactions in flight at the same time.

APB is a much simpler interface than both AHB and AXI. It does not support burst transactions, nor pipelined accesses. At the cost of performance, APB has far fewer signals and more forgiving timing. This relieves the burden on the designers of peripherals; With APB a set of memory-mapped registers can be implemented with a simple decoder for bus writes and a mux for reads. A majority of Microcontrollers connect most of their memory-mapped peripherals using an APB interface. Not only does it make designing peripherals easier, by placing low-bandwidth peripherals on their own bus, the main system bus’ connections can be optimized for speed

Often, multiple buses are mixed on a system. For example the PS portion of the Zynq uses all three of AXI, AHB, and APB: The main system interconnect is AXI-based which connects the processor core to the on-chip SRAM, the DDR external memory controller, and to the FPGA. The FPGA AXI ports include both slave interfaces and master interfaces. Slave ports allow the processor to access FPGA resources and Master ports allow FPGA logic to access PS resources. The hardware peripherals of Zynq are connected to an APB which is bridged to the main AXI interconnect. The USB and Ethernet controllers in the Zynq PS have AHB Master interfaces, but these are bridged to AXI so they can access the processor’s memory, this is known as Direct Memory Access(DMA).

The Zynq illustrates that in system integration many interfaces can be used and connected through bridges. Bridges, or glue-logic, take up chip resources and might hamper bandwidth but these downsides are weighed against other factors; Having to redesign IP for a specific interface might take too long or cost too much. Often being able to reuse existing IP presets a quicker path to deployment, or lower overall cost than a custom design.

In the previous project you modified the template code to make use of the provided memory mapped registers. If you looked through the generated code, you may have noticed there is a lot of logic involved in interfacing the AXI bus to the slave registers. The template provided is a quick solution if you need write and read access to the contents of the registers and all of your custom logic can be derived from the read data of the registers (Unidirectional control). However if you need a higher degree of control over your logic, you may have to implement your own custom axi logic, or design an APB peripheral instead. For example, you may want a register bit to clear itself automatically (as is often used in peripheral resets), modifying the Xilinx template code to do this may prove difficult.

In this project you will analyze and simulate both AXI and APB protocols. You will also design a couple of APB-based IPs to attach to the Zynq PS through an AXI to APB bridge interface. In future projects you will use both AXI and APB peripherals, use this project to gain a feel for appropriate situations for each.

Requirement 1 (Use the ILA Debugger to scope AXI read and write transactions).

Hook the integrated logic analyzer to the AXI slave port of the LED controller you designed for project 1. Instead of marking wires for debug in HDL or in the synthesized design, you can mark wires for debug in the block design view. After you have generated a bitstream of your block design along with the ILA, you can probe the AXI bus connection while your program is running. Setup triggers to capture both read and write transactions on the bus. When stepping through your program show your TA the how the program being executed, the signals on the ILA and the data output on the LEDs are related.

Requirement 2 (Simulate the AXI bus)

Simulating Synchronous logic:

https://www.realdigital.org/doc/8961f0f5102b1f72844b91b5c1217a2c

Create a simulation for your AXI LED controller. Create tasks to simulate write and read transactions on the AXI bus. If you make the tasks generic, they can be used to simulate any AXI4-lite IP core with a slave port. Create additional tasks for sequences specific to the LED controller:

  • Enable_LED_CTL : enables the controller’s outputs
  • Write_LED_CTL : Sets the output data of the module, based on a given parameter
  • Read_LED_CTL : Reads the output of the LED As an AXI bus transaction

Create a simulation sequence, then use breakpoints and stepping to show your TA that you can effectively simulate the AXI bus to control your IP Core’s LED outputs.

Requirement 3 Design an APB bus slave IP

Document: Signals and timing of APB bus:

https://www.realdigital.org/doc/9a5587c92d9aa24fbc355f4d3e1a9d83

Tutorial: creating an APB IP and connecting it to zynq using AXI-APB Bridge:

https://www.realdigital.org/doc/78e6f9b1a03ba4ca131ff3ba2e4dff3f

(follow tutorial basically) (Add fourth register with a reset flag (must clear automatically) )

Design and package an APB slave IP. You can follow this tutorial to get a start.

Put your IP in a block design and test it with a simple c program and verify you can control the green LEDs as well as the RGB LEDs on the blackboard using software

Add a fourth register, accessed at address offset 0xC from the slave’s base address (this address is left unused in the tutorial). Use the register to add a software controlled reset for the other 3 registers. This register should have 3 bits (one for each output register). When a 1 is written to a bit from the processor, the corresponding LED register resets to zero. The next clock cycle the bit should clear.

To implement this functionality, your IP will need to modify its registers when it is not being addressed for a write. You will need to create logic that both decodes writes and handles other cases of changing values. These should to be placed in the same always block (In general you should only modify values for a synchronous element in a single always block.)

An example of write logic for a register that modifies itself is shown below


//logic for the register val (accessed at address 2)
always @(posedge clk)
begin
	if(rst) //system rest
		val<=16'd0;
	else if( (addr==2) & write_en) //if this register is addressed for a write
		val<=write_data;
	else
	begin
		//behavior for register when not being addressed for a write (or being reset)
		//in this case register always sets itself to a constant value
		reg <= 16'hABCD;
	end
end

Modify your project 2 functions to work with your APB IP, including new reset functionality. If you don’t add global enable functionality, you do not need to create c code for enabling your module. From a software programmer’s perspective, accessing the APB bus through an AXI bridge is the same as accessing an AXI peripheral: both are just processor bus memory accesses.

Requirement 4 Simulate your APB IP

Simulating the APB bus:

https://www.realdigital.org/doc/b00d897d0ed9081202c420294e2739c0

In a simulation emulate an APB Bus Master to control your APB-connected LED controller. Write tasks for general APB write and read transactions and use those to create functions to simulate writing, reading, and resetting your led controller.

Requirement 5 Create an APB IP that can read input value from devices.

Create a memory mapped APB slave that allows the processor to read the values of the switches and buttons on the blackboard. During an APB read, you could mux the output of the switches or buttons (depending on the requested address) directly onto the APB read data bus, however driving a synchronous bus from asynchronous signals could result in metastability. A better solution would be to synchronize any asynchronous inputs to the clock domain of the APB it is connected to. This can be accomplished by feeding the signal through one or multiple flip flops.

Simulate your APB slave (make sure the value simulated by your switches/buttons are read properly), then package it into a system that has the Zynq processing system connected to both your APB led controller and APB input controller. Write a program where the green LED’s are controlled by slide switches and RGB LED’s are controlled by pushbuttons. For each RGB led use 2 pushbuttons to cycle through all the possible combinations of the color channels, one to cycle forward through the patterns, and the other to cycle through the patterns in reverse.

Challenge 1 (Set register flags to detect rising edge (clear with a write) )

Modify your input controller with 2 additional registers. Use one register to detect rising edges from the switches and the other to detect rising edges from the buttons.

A rising edge can be detected by registering a signal through a flip-flop then comparing the register’s output to it’s input; The input to the flip-flop can be though of as the ‘current’ value, and the output as the ‘previous’ value. The rising edge should only be detected for one clock cycle. However this represents a problem when trying to read this over a bus. Unless the address is being constantly read, it is unlikely the processor will be reading this address when the rising-edge event occurs, meaning events can be missed. Instead of having the processor directly read the output of a rising-edge detector, it would be better to have the processor read a flag indicating a rising edge event has occurred previously. This can be accomplished with a register that only sets on an event. There must also be some reset mechanism for the register, otherwise the first rising edge would permanently set its value.

Challenge 2 (Create an IP that can generate random numbers (using an LSFR) )

Random numbers are often very useful in software and hardware systems. Generating true random numbers requires some form of entropy (often measured through measuring natural phenomena). However, for many applications pseudo random numbers are sufficient. Pseudorandom number sequences are typically generated through an algorithm or hardware circuit, often the current state of the generator (output and/or internal state) are used to generate the next output value. The initial state of the generator is often set using a ‘seed’ value, which dictates all future states. Thus, pseudorandom numbers are deterministic, however may appear random outside of the system. In critical applications, such as cryptography, it is necessary to have as unpredictable a generator as possible. For more trivial applications, such as games, it is possible to use a counter in lieu of a more complex system; A counter’s output is very predictable, however were a counter fast enough and constantly overflowing, a human would have almost no chance of predicting the current value of it.

A common method of generating pseudo random numbers is to use a linear feedback shift register (LFSR). These function similarly to a normal serial shift register, however one or more bits in the shift chain can be set as a function of other bits in the register. Different structures for LFSRs exist; A fibonacchi LFSR only has the first bit as a function of the others, all other bits are a normal shift register chain.

Create a system that has an APB-connected pseudorandom number generator. Periodically read random numbers and display them on your blackboard’s LEDs or 7-segment display.

Challenge 3 (Use ILA to scope both AXI and APB at the same time).

Use the ILA to scope a hardware design that has an APB slave connected to the Zynq through an AXI-APB bridge. Connect ILA probes to both the AXI bus and corresponding translated APB bus signals. When using the ILA to monitor your implemented design, explain to your TA how an AXI transactions correlates to the translated APB transaction. (Hint: This is easier if you write your c program so separate bus transactions will be easier to tell apart from one another.)