A real AHB system has more than one slave: on-chip RAM, flash, an APB bridge, perhaps a memory controller. The decoder and the multiplexor connect them, and getting their timing right is the main design problem. The decoder works in the address phase, the multiplexor in the data phase, and an unmapped address needs a default slave. With more than one master, a multi-layer interconnect gives each master its own path. This article builds a single-master system with two RAMs and a default slave, then looks at multi-layer AHB.

9 min read | Intermediate

What You'll Learn

  • Write an AHB address decoder and a data-phase multiplexor
  • Explain why the multiplexor select must be registered
  • Add a default slave for unmapped addresses
  • Describe how a multi-layer interconnect supports several masters

The System

The fabric below connects one master to three slaves:

Address rangeSlaveBehaviour
0x0000 - 0x03FFRAM 0No wait states
0x1000 - 0x13FFRAM 1One wait state on the first beat of a burst
Everything elseDefault slaveERROR for NONSEQ and SEQ, OKAY for IDLE and BUSY

The Decoder

The decoder is a combinational decode of the high address bits. Each slave owns at least 1 KB starting on a 1 KB boundary, so bits 31:10 are enough:


wire hsel_ram0 = (HADDR[31:10] == 22'h0);       // 0x0000 - 0x03FF
wire hsel_ram1 = (HADDR[31:10] == 22'h4);       // 0x1000 - 0x13FF
wire hsel_def  = !hsel_ram0 && !hsel_ram1;      // everything else

The 1 KB rule is what makes this simple. Because an incrementing burst never crosses a 1 KB boundary, all beats of a burst decode to the same slave, and no slave ever sees half a burst. The specification encourages simple decoding like this to keep it fast.

The Multiplexor and Its Select

The multiplexor returns HRDATA, HRESP and HREADYOUT of one slave to the master. Which slave? The one in the data phase. But HSEL follows HADDR, which already shows the next transfer. The decoder output must therefore be registered at the end of each address phase, which is every edge where HREADY is high:


reg [2:0] dsel;                          // which slave owns the data phase

always @(posedge HCLK) begin
  if (!HRESETn)
    dsel <= 3'b000;
  else if (HREADY)
    dsel <= {hsel_def, hsel_ram1, hsel_ram0};
end

assign HREADY = dsel[0] ? ready0 :
                dsel[1] ? ready1 :
                dsel[2] ? ready_d : 1'b1;
assign HRESP  = dsel[0] ? resp0 :
                dsel[1] ? resp1 :
                dsel[2] ? resp_d : 1'b0;
assign HRDATA = dsel[0] ? rdata0 :
                dsel[1] ? rdata1 : 32'h0;

Note that the multiplexor output HREADY feeds back into its own select register and into every slave. When no slave owns a data phase, such as after reset, HREADY is high so that the first transfer can start.

Quick Check

Q: What goes wrong if the multiplexor uses HSEL directly instead of the registered dsel?

Show Answer

In back-to-back transfers to different slaves, the master gets the response and read data of the slave in the address phase instead of the one in the data phase. A read from RAM 0 followed by an access to RAM 1 would return RAM 1's data, and RAM 1's HREADYOUT would decide whether the RAM 0 read is finished.

The Default Slave

If the memory map has gaps, the specification requires a default slave. Without one, an access to a gap selects nobody, and nobody drives HREADYOUT. The bus hangs or completes with garbage. The default slave answers NONSEQ and SEQ transfers with a two-cycle ERROR, and IDLE and BUSY with a zero-wait OKAY:


module ahb_default_slave (
  input        HCLK,
  input        HRESETn,
  input        HSEL,
  input  [1:0] HTRANS,
  input        HREADY,
  output       HREADYOUT,
  output       HRESP
);
  reg err1;
  reg err2;

  always @(posedge HCLK) begin
    if (!HRESETn) begin
      err1 <= 1'b0;
      err2 <= 1'b0;
    end
    else begin
      err1 <= HREADY && HSEL && HTRANS[1];
      err2 <= err1;
    end
  end

  assign HREADYOUT = !err1;
  assign HRESP     = err1 || err2;
endmodule

The Simulation

The master writes and reads both RAMs, then reads 0x2000, which belongs to nobody, and finally reads RAM 0 again:


burst(1, SINGLE, 32'h0004, WORD, 1, 32'hD0);    // RAM 0
burst(1, SINGLE, 32'h1004, WORD, 1, 32'hD1);    // RAM 1: one wait state
burst(0, SINGLE, 32'h0004, WORD, 1, 0);
burst(0, SINGLE, 32'h1004, WORD, 1, 0);
burst(0, SINGLE, 32'h2000, WORD, 1, 0);         // nothing here: default slave
burst(0, SINGLE, 32'h0004, WORD, 1, 0);
Output
35  write 0x0004 = 0x000000d0  OKAY
55  write 0x1004 = 0x000000d1  OKAY
65  read  0x0004 = 0x000000d0  OKAY
85  read  0x1004 = 0x000000d1  OKAY
105  read  0x2000 = 0x00000000  ERROR
115  read  0x0004 = 0x000000d0  OKAY

In the waveform, each HSEL line rises together with the address it decodes. The multiplexor select follows one cycle later, when that transfer is in its data phase, and it does not move while RAM 1 holds HREADY low. The read of 0x2000 reaches the default slave and fails with a two-cycle ERROR; the master then carries on with the next transfer.

More Than One Master: Multi-Layer AHB

AHB-Lite has one master per bus. To connect a processor and a DMA engine, you use a multi-layer interconnect. Each master gets its own AHB-Lite layer into an interconnect matrix, and each slave port of the matrix has its own arbiter:

Two masters that want different slaves proceed at the same time, which a single shared bus could never do. Two masters that want the same slave are arbitrated at that slave's port, and the loser sees wait states on its own layer. From each slave's point of view nothing changed: it still sees one AHB-Lite transfer at a time.

A multi-layer interconnect may also end a burst early to let another master reach the slave, which is why a slave must work correctly when a burst is not completed. And when a slave can be reached by several masters, locked transfers matter: HMASTLOCK tells the interconnect not to let another master in between, for example during the read and write of a semaphore.

Quick Check

Q: In a multi-layer system, the processor reads flash while the DMA engine writes RAM. How many transfers can complete in one cycle?

Show Answer

Two, one on each layer, because they go to different slaves with different arbiters. On a single shared bus only one could complete.

Running It in ChipVerify Lab

The example contains the fabric with both RAMs and the default slave. Compare the HSEL lines with the multiplexor select in the waveform.

Common Mistakes

Mistake #1: Selecting the multiplexor with HSEL

The response must come from the slave in the data phase. Register the decoder output when HREADY is high and use that for the multiplexor.

Mistake #2: No default slave

A gap in the memory map with no default slave leaves the master waiting for an HREADYOUT that nobody drives. Always cover the whole address space.

Mistake #3: Slave regions smaller than 1 KB

A slave region smaller than 1 KB, or one that does not start on a 1 KB boundary, lets a legal burst run from one slave into the next. Keep regions at least 1 KB and 1 KB aligned.

Practice Exercise

Challenge: Just Past the End

Change the read of 0x2000 to a read of 0x1400. Which slave answers, and what is the result?

Hint

RAM 1 owns 0x1000 to 0x13FF. Work out HADDR[31:10] for 0x1400.

Solution
Output
35  write 0x0004 = 0x000000d0  OKAY
55  write 0x1004 = 0x000000d1  OKAY
65  read  0x0004 = 0x000000d0  OKAY
85  read  0x1004 = 0x000000d1  OKAY
105  read  0x1400 = 0x00000000  ERROR
115  read  0x0004 = 0x000000d0  OKAY

HADDR[31:10] for 0x1400 is 5, not 4, so neither RAM is selected and the default slave answers with ERROR. The result is identical to the read of 0x2000: one address past the end of a region is just as unmapped as one far away.

Open the ready-made example in the lab and run the simulation.

Summary

  • The decoder raises one HSEL per slave from the high address bits, in the address phase.
  • The multiplexor returns the response of the slave in the data phase, using a select registered when HREADY is high.
  • A default slave answers unmapped addresses: ERROR for NONSEQ and SEQ, OKAY for IDLE and BUSY.
  • Slave regions of at least 1 KB on 1 KB boundaries keep every burst inside one slave.
  • Multi-layer AHB gives each master its own layer and each slave its own arbiter, so masters reach different slaves in parallel.
Did you find what you were looking for?

Quiz

No quiz questions available for this article.