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
[email protected](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
[email protected](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