ARM APB总线介绍

testing software:ISE14.7
author: Rose Island

APB总线介绍

APB总线

APB(Advanced Peripheral Bus) 遵循 AMBA协议(Advanced Microcontroller Bus Architecture Protocol)。信号转换和时钟上升沿相关,每次读写传输至少两个周期,读数据和写数据不能同时发生。APB桥为APB总线中唯一主设备,UART/SPI/I2C等均为从设备。

APB接口信号

APBWidthSourceDirectionFunction
pclk1 bit系统时钟源inputAPB总线从设备的时钟源
preset_n1 bit系统复位信号input系统复位
rst1 bit复位信号input从设备复位
psel1 bitAPB桥input高电平表示APB桥与从设备进行数据传输
paddr10 bitsAPB桥input对从设备寄存器进行读写的相应地址
penable1 bitAPB桥input读写使能信号,指示一次APB传输的第二个时钟周期,存储阶段
pwrite1 bitAPB桥input指示信号,高写,低读
pwdata32 bitsAPB桥input写数据
prdata32 bits从设备output读数据
pready1 bit从设备output从设备就绪时为1,从设备在下一个上升沿可以完成传输,引入等待,传输周期可大于2

Transfer States

states

  • Setup phase:需要数据传输时psel置1,这个阶段只会有一个时钟周期,下一个上升沿就进入Access phase
  • Access phase:传输的第二个时钟周期penable置1,pwrite/paddr/pwdata/prdata/psel保持。等待pready,这个阶段的时钟周期个数由pready决定,pready为1后有一个时钟周期,之后传输完成。

写数据 With no wait states

write_with_no_waiting_states

  • APB:T1(Setup phase):上升沿时,pwrite输出1(写),paddr输出写地址,pwdata输出写数据,psel输出1,penable输出0;

    ​ T2(Access phase):penable输出1,pwrite/paddr/pwdata/psel保持;

    ​ T3(Idle phase):传输结束后penable才能输出0,如果下一个传输不是立即到达的话,psel输出0。

  • UART: T2:采样写数据并更新数据。

  • Recommendation:pwrite/paddr/pwdata保持直到下一个传输开始,可以减少功耗。

写数据 With wait states

write_with_wait_states

  • pready:由从设备输出,在Access phase阶段,当penable为高时,pready保证了一次传输至少两个时钟周期或更长,只有当pready为高时一次传输才算结束。

读数据 With no wait states

read_with_no_wait_states

  • APB: T1(Setup phase):上升沿时,pwrite输出0(读),paddr输出写地址,psel输出1,penable输出0;

    ​ T2(Access phase):penable输出1,prdata输出写数据(从设备提供),pwrite/paddr/psel保持;

    ​ T3(Idle phase):传输结束后penable才能输出0,如果下一个传输不是立即到达的话,psel输出0。

  • UART:T2:采样指令并发送读数据。

读数据 With wait states

read_with_wait_states

  • pready:由从设备输出,在Access phase阶段,可拉长传输周期。

APB对寄存器的读写仿真

输入激励

apb信号:pclk、prest_n、rst、psel、paddr、penable、pwrite、pwdata

CSDN的markdown竟然不支持verilog代码了,差评!就用C语言的代码块凑合一下吧……

reg [31:0]		pwdata_buff;
reg [31:0]		prdata_buff;

reg [9:0]		pwaddr_buff;
reg [9:0]		praddr_buff;

// input
reg				pclk;
reg				preset_n;
reg				rst;
reg				psel;
reg [9:0]		paddr;
reg				penable;
reg				pwrite;
reg [31:0]		pwdata;

// output
wire [31:0]		prdata;
wire			pready;
	
task apb_write(input [9:0] addr, input [31:0] data);
begin
	@(negedge pclk);
		psel	= 1'b1;
		penable	= 1'b0;
		pwrite	= 1'b1;
		paddr	= addr;
		pwdata	= data;
	@(posedge pclk);

	@(negedge pclk);
		penable	= 1'b1;
	@(posedge pclk);

	while(pready != 1'b1) @(posedge pclk);
		psel	= 1'b0;
		penable	= 1'b0;
		// pwrite	= 1'b0;
		// paddr	= 32'b0;
		// pwdata	= 32'b0;
	repeat (10) @(posedge pclk);
end
endtask //apb_write

task apb_read(input [9:0] addr, output [31:0] data);
begin
	@(negedge pclk);
		psel	= 1'b1;
		penable	= 1'b0;
		pwrite	= 1'b0;
		paddr	= addr;
	@(posedge pclk);

	@(negedge pclk);
		penable = 1'b1;
	@(posedge pclk);

	while(pready != 1'b1) @(posedge pclk);
		data	= prdata;
		psel	= 1'b0;
		penable	= 1'b0;
		// pwrite	= 1'b0;
		// paddr	= 32'b0;
	repeat(10) @(posedge pclk);
end
endtask //apb_read

initial begin
	pwaddr_buff = 10'h000;
	pwdata_buff = 32'b1101;
	apb_write(pwaddr_buff,pwdata_buff);

	praddr_buff = 10'h000;
	apb_read(praddr_buff,prdata_buff);
	if(prdata_buff == 32'b1101) begin
		$display("\n ------ write and read successfully -------");
	end
	else begin
		$display("\n ------ write or read failed -------");
	end
end

观察信号

  1. 写数据:e.g. 写CR寄存器,观察CR_EN位是否被置1
  2. 读数据:e.g. 读取CR寄存器里的值

波形

  1. 写数据:e.g. CR_EN

    write_test

  2. 读数据:e.g. 读取CR寄存器

    read_test

实际结果

  1. 写入成功,通过√
  2. 读出成功,通过√

Conclusion

在上一篇里说好要周更的,可惜又没有做到,今天国庆节,国庆快乐呀!

最近就是好像每天都在忙,但也没啥进度,但总算有点东西可以写一下啦。加班比较多,我很讨厌硬性加班,可是还是被卷了进去。

我想要生活但生活需要我赚钱。

分享一部日剧《我,到点下班》

pic

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值