AMBA总线(一)APB总线

AMBA(Advanced Microcontroller Bus Architecture)
APB(Advanced Peripheral Bus):主要用在低速且低功率的外围,可针对外围设备作功率消耗及复杂接口的最佳化。
AHB(Advanced High-performance Bus):主要是针对高效率、高频宽及快速系统模块所设计的总线,它可以连接如微处理器、芯片上或芯片外的内存模块和DMA等高效率模块。
AXI(Advanced eXtensible Interface):高速度、高带宽,管道化互联,单向通道,只需要首地址,读写并行,支持乱序,支持非对齐操作,有效支持初始延迟较高的外设,连线非常多。
本章主要介绍APB总线
在这里插入图片描述
APB总线:

  • 低速总线、低功耗
  • 接口简单
  • 在bridge中锁存地址信号和控制信号,送出片选信号给APB从设备
  • 适用于多种外设
  • 上升沿触发

APB 组成部分:

  • AHB2APB Bridge
    锁存所有的地址、数据和控制信号
    进行二级译码来产生APB Slave选择信号
  • 其他模块都是APB Slave
    不是流水线方式传递数据
    接口零功耗

在这里插入图片描述
APB总线信号

  • PCLK
  • PRESETn
  • PADDR[31:0] ,地址总线,由设备总线的bridge单元驱动
  • PSELx,从译码器的片选信号,到每一个总线从设备
  • PENABLE,用于在设备总线上把所有访问按时间阶段进行
  • PWRITE,高电平为写,低电平为读
  • PRDATA
  • PWDATA
    在这里插入图片描述
    写传输
    在这里插入图片描述
    由图所示,地址(PADDR)、写信号(PWRITE)、选择信号(PSEL)、写数据(PWDATA)在时钟上升沿之后同时有效。表明一次写传输的开始,传输的第一个时钟周期称为SETUP周期。在下个时钟上升沿使能信号(PENABLE)有效,紧接着就是ENABLE周期。而地址、写数据和控制信号需要在此期间保持有效。传输在ENABLE周期结束时完成,此时PENABLE变为低电平,PSEL也变为低电平。
    读传输
    在这里插入图片描述
    由图所示,地址、写信号、选择信号的时序和写传输一样,即在读传输时,从设备必须在ENABLE周期提供数据,读数据在ENABLE周期结束的时钟上升沿被主设备采样。
    多说无益,上代码!!!
    示例:如下是一个APB_Slave 代码以及tb文件如下:
module apb_slave(
	input psel,
	input penable,
	input [31:0] paddr,
	input pwrite,
	input presetn,
	input pclk,
	input [31:0] pwdata,
	output reg [31:0] prdata);
reg [31:0] data1;
reg [31:0] data2;
reg [31:0] data3;
reg [31:0] data4;
//write and read
always@(posedge pclk or negedge presetn)
begin
	if(!presetn)
	begin
		data1<=32'h0;
		data2<=32'h0;
		data3<=32'h0;
		data4<=32'h0;
		prdata<=32'h0000_0000;
	end
	else if(psel&&penable&&pwrite)
	begin
		case(paddr[7:0])
		8'h00:data1<=pwdata;
		8'h04:data2<=pwdata;
		8'h08:data3<=pwdata;
		8'h0c:data4<=pwdata;	
		endcase	
	end
	else if (psel&&penable&&!pwrite)
	begin
		case(paddr[7:0])
		8'h00:prdata<=data1;
		8'h04:prdata<=data2;
		8'h08:prdata<=data3;
		8'h0c:prdata<=data4;
		endcase
	end
end
endmodule
module tb();
reg psel;
reg penable;
reg [31:0] paddr;
reg pwrite;
reg presetn;
reg pclk;
reg [31:0] pwdata;
wire [31:0] prdata;

apb_slave u1(
	.psel(psel),
	.penable(penable),
	.paddr(paddr),
	.pwrite(pwrite),
	.presetn(presetn),
	.pclk(pclk),
	.pwdata(pwdata),
	.prdata(prdata));

initial
begin
	pclk=1;
	forever #(20/2) pclk=~pclk;
end

initial
begin
	presetn=0;
	#(60) presetn=1;
end

//write test
initial
begin
	#80 psel=1;
	    paddr=32'h0000_0100;
	    pwrite=1;
	    pwdata=32'd7200;
	#20 penable=1;
	#20 penable=0;
	    psel=0;
end
//read test
initial
begin
	#200 psel=1;
	     paddr=32'h0000_0100;
	     pwrite=0;
	#20  penable=1;
        #20  penable=0;
             psel=0;
end
endmodule

在这里插入图片描述

或者

module apb_slave(
	input psel,
	input penable,
	input [7:0] paddr,
	input pwrite,
	input presetn,
	input pclk,
	input [31:0] pwdata,
	output reg [31:0] prdata);
reg [31:0] data [256-1:0];
integer i;
//write and read
always@(posedge pclk or negedge presetn)
begin
	if(!presetn)
	begin
		prdata<=32'h0000_0000;
		for(i=0;i<=8'hff;i=i+1)
		begin
			data[i]<=32'h0;
		end
	end
	else if(psel&&penable&&pwrite)
	begin
		data[paddr]<=pwdata;
	end
	else if (psel&&penable&&!pwrite)
	begin
		prdata<=data[paddr];
	end
end
endmodule

在这里插入图片描述

发布了54 篇原创文章 · 获赞 4 · 访问量 1038

猜你喜欢

转载自blog.csdn.net/buzhiquxiang/article/details/103553177