Sei sulla pagina 1di 8

APB SLAVE BLOCK DIAGRAM

PCLK

PRESETn

PCLK

PRESETn

PSEL

PWRITE

PADDR[31:0]

APB SLAVE

CS

REGISTER BANK

PENABLE

W/Rn

PWDATA[31:0]

ADDR[4:0]

INTERFACE WITH THE CONROLLER BLOCK

WDATA[31:0] PRDATA[31:0] RDATA[31:0]

TIMING DIAGRAM WRITE CYCLE

PSEL

PWRITE

PADDR[31:0]

ADDRESS

PENABLE

PWDATA[31:0]

DATA

CS

W/Rn

ADDR[4:0]

ADDRESS [4:0]

WDATA[31:0]

DATA

DATA WRITTEN INTO THE SELECTED REGISTER IN THE REGISTER BANK

READ CYCLE

PSEL

PWRITE

PADDR[31:0]

ADDRESS

PENABLE

PRDATA[31:0]

DATA

CS

W/Rn

ADDR[4:0]

ADDRESS [4:0]

RDATA[31:0]

DATA

DATA WRITTEN INTO DATA READ REGISTER

STATE MACHINE

PSEL=0

IDLE

PSEL=1

NO CONDITION

BUSY

BUSY STATE THIS STATE INCLUDES THE DATA PHASE WHICH OCCURS ONLY WHEN PENABLE IS HIGH (ACCESS). IDLE STATE THIS STATE INCLUDES THE ADDRESS PHASE (SETUP) AND THE SLAVE GOES INTO THE IDLE STATE ALSO WHEN THE TRANSACTION IS COMPLETED OR IF PSEL = 0.

STATE TRANSITION TABLE

CLK

PSEL 0 1 1 1 0 1

PWRITE 0 0 1 1 1 1

PENABLE 0 1 0 1 0 1

Qn S0 S0 S1 S0 S1 S0

Qn+1 S0 S1 S0 S1 S0 S1

CS 1 0 0 1 0 1

W/Rn 0 0 1 1 1 1

VERILOG CODE

OUTPUT

IDLE

BUSY

CS

PSEL, !PWRITE

PSEL, PWRITE, PENABLE PADDR[4:0]

ADDR [4:0]

PADDR[4:0]

W/Rn

PWRITE

PWRITE

WDATA

PWDATA

PRDATA

DATA READ REG

module apb_interface (pclk,presetn,psel,pwrite,paddr,penable,prdata,pwdata, cs,wrn,addr,wdata,rdata); input pclk,presetn,psel,pwrite,penable; input [31:0] paddr, pwdata; output [31:0] prdata; inout cs,wrn; inout [4:0] addr; inout [31:0] wdata,rdata; reg [31:0] dataread; reg [31:0] datacap,status,control,slaveaddr,datacount; reg state; parameter idle = 0; parameter busy = 1; assign wrn <= pwrite; assign addr [4:0] <= paddr [4:0]; assign wdata [31:0] <= pwdata [31:0]; assign prdata [31:0] <= dataread [31:0]; case (state) idle: cs = (psel & (!pwrite)); busy: cs = (psel & pwrite & penable); endcase if ((cs == 1) && (wrn ==0)) begin casex (addr) 3b000xx : rdata [31:0] = datacap [31:0]; 3b001xx : rdata [31:0] = status [31:0] ; 3b010xx : rdata [31:0] = control [31:0]; 3b011xx : rdata [31:0] = slaveaddr [31:0] ; 3b100xx : rdata [31:0] = datacount [31:0] ; Endcase

always @ (posedge clk || negedge presetn) begin if (presetn == 0) begin state <= idle; dataread [31:0] = 32d0; datacap [31:0] = 32d0; status [31:0] = 32d0; control [31:0] = 32d0; slaveaddr [31:0] = 32d0; datacount [31:0] = 32d0; end else if (presetn ==1) begin case (state) idle : state <= (psel)? Busy : idle; busy: state <= idle; status [0] <= (addr[4] & (addr[3] | addr[2]));end endcase if ((cs == 1) && (wrn ==1) ) begin casex addr 3b000xx : datacap [31:0] = wdata [31:0]; 3b001xx : status [31:0] = wdata [31:0]; 3b010xx : control [31:0] = wdata [31:0]; 3b011xx : slaveaddr [31:0] = wdata [31:0]; 3b100xx : datacount [31:0] = wdata [31:0]; endcase end else if ((cs == 1) && (wrn ==0)) dataread [31:0] = rdata [31:0]; end endmodule

Potrebbero piacerti anche