logo资料库

APB_timer.pdf

第1页 / 共10页
第2页 / 共10页
第3页 / 共10页
第4页 / 共10页
第5页 / 共10页
第6页 / 共10页
第7页 / 共10页
第8页 / 共10页
资料共10页,剩余部分请下载后查看
第二次作业 一、 实验目的和要求 设计一个挂载在 APB 总线上的计数器,按照 APB 的时序给计数器赋值,主 机通过地址对计数器进行配置,通过数据输入端口给计数器设置计数器最大值, 并通过数据输出端口输出计数器的计数值。该设计还设置了一个计数完成信号, 当计数器满足模式配置后的计数要求时,会将该信号拉高。 二、 实验设计方法 该实验设计,设计了一个挂载在 APB 上的计数器,该计数器有两个模式, 模式 1 为一个从 0 计数到 300 的计数器,模式 2 为一个从 0 计数 cnt_MAX(主机 发送给计数器的计数最大值),通过 APB 总线中的 PADDR 信号获取模式配置, 然后计数器的输出到 APB 总线的读数据输出端口。 计数器模块示意图如下图 2-1 所示: 图 2-1:计数器模块 APB 模块示意图如下图 2-2 所示:
图 2-2:APB 模块 计数器中的 CM_cnt = Pwrdata[7:0],该信号的作用是给计数器分配模式,如果 CM_cnt[7]=1,且 CM_cnt[1:0]=00 时,计数器进入模式 1,即从 0 开始计数到计数 器内部最大值(这里规定的是 300);如果 CM_cnt[7]=1,且 CM_cnt[1:0]=01 时, 计数器进入模式 2,即从 0 开始计数到 cnt_MAX(这个值为主机发送给计数器, 本设计发送的是 100),cnt_MAX 与 Pwdata 相连,计数器的 cnt_done 信号是为 了便于观察仿真波形而设置的,该处不与 APB slave 相连,作为计数器的输出 cnt 与 Prdata 相连。其他 APB 的信号端口按照时序图给相应的输入。 以上两张图为代码设计中端口的输入和输出信号的命名,下面两张 APB 的时 序图为课件截图,他们信号的命名只有大小写的区别。 APB 写传输时序图如图 2-3 所示:
图 2-3:APB 写传输时序图 由 APB 写时序图可以得出:当 PWRITE、PSEL、PENABLE 信号都是高,且地 址信号输入有效地址的时候,PWDATA 信号输入开始有效,然后锁存写数据。 APB 读传输时序图如图 2-4 所示: 图 2-4:APB 读传输时序图 由 APB 读时序图可以得出:当 PWRITE 为低,PSEL 和 PENABLE 为高,且 PADDR 地址信号输入有效地址的时候,PRDATA 信号输出有效,驱动读数据总 线。
三、 实验结果与分析 按照设计方法编写 Verilog HDL 代码,并编写 testbench,在 quartusⅡ中进 行综合,用 modelsim 进行仿真,相应的 Verilog HDL 代码和 testbench 代码见附录。 首先是计数器模式 1:从 0 开始计数,计数到 300,发送计数完成信号,仿 真结果如下图 3-1 所示: 图 3-1:计数器模式 1 波形图 从波形图可以得出,,Paddr 为 32‘hffff_fff0 且 Pwdata[7]为 1 且 Pwdata[1:0], 即为计数器模式 1(计数器从 0 计数到 300);Psel,Penable 为高,Pwrite 为低, 即为 APB 读模式,Prdata 输出的是计数器的当前计数值,计数到 300 的时候重 新开始计数,功能符合 其次是计数器模式 2:从 0 开始技术,计数到主机给定计数器的值(这里给 的是 100),如图 3-2 所示,当 Psel、Penable、Pwrite 为高,即 APB 写模式的时 候,将 100 写入计数器中,这时 100 将作为计数器的最大值。 图 3-2 计数器为模式 2 波形图如下图 3-3 所示:
图 3-3:计数器模式 2 波形图 从上图可以得出,当 Psel、Penable 为高,Pwrite 为低,即 APB 读模式; Pwdata[7]=1, Pwdata[1:0]=01,即模式 2。Prdata 输出计数器的当前值,计数到 100 的时候重新开始计数,功能符合。
附录: module APB_Timer#( APB_Timer 设计代码 parameter data_size = 32, CM_size = 8,cnt_max = 300//计数器最大值 ) ( ); input [data_size-1:0]Paddr,Pwdata, input Psel,Penable,Pwrite,Prst_n,Pclk, output reg [data_size-1:0]Prdata, output reg cnt_done reg [CM_size-1:0]CM_cnt;//计数器的控制端口,根据输入的数据来判断计数器的模式 选择 reg [data_size-1:0]cnt; //计数器 reg [data_size-1:0]cnt_MAX;//主机给计数器的最大值 reg [data_size-1:0]cnt_MAX_reg; //reg [data_size-1:0]cnt_reg; //存储计数器的值,等待计数器的模式为模式 1 时使用 reg ini_cnt_done;//计数器赋值完成信号 reg CM_cnt_done; reg [CM_size-1:0]CM_cnt_reg; //存储计数器模式赋值的值 //计数器模式赋值完成信号 //控制信号,数据传送 always@(posedge Pclk or negedge Prst_n) if(!Prst_n) begin cnt_MAX_reg <= 0; CM_cnt_reg <= 0; ini_cnt_done <= 0; CM_cnt_done <= 0; Prdata <= 0; end else if(Pwrite == 1 && Psel == 1 && Penable == 1) begin if(Paddr == 32'hffff_fff1)//写计数器模式赋值配置 begin CM_cnt_reg <= Pwdata[7:0]; CM_cnt_done <= 1; ini_cnt_done <= 0; end else if(Paddr == 32'hffff_fff0)//给模式 2 主机给计数器指定最大计数器 begin
cnt_MAX_reg <= Pwdata; ini_cnt_done <= 1; CM_cnt_done <= 0; else end begin CM_cnt_done <= 0; ini_cnt_done <= 0; end end else if(Pwrite == 0 && Psel == 1 && Penable == 1)//读数据,将计数器的值从 APB 的数据输出端口输出 if(Paddr == 32'hffff_fff0) begin Prdata <= cnt; CM_cnt_done <= 0; ini_cnt_done <= 0; end else begin Prdata <= 0; CM_cnt_done <= 0; ini_cnt_done <= 0; end always@(posedge Pclk or negedge Prst_n) if(!Prst_n) begin cnt <= 0; CM_cnt <= 0; end else if(CM_cnt_done) CM_cnt <= CM_cnt_reg; else if(ini_cnt_done) cnt_MAX <= cnt_MAX_reg; else if(CM_cnt[7] == 1) //计数器开始计数 begin if(CM_cnt[1:0] == 2'b00)//模式 1,计数器从 0 开始,计数到固定的最大 值 begin if(cnt == cnt_max) begin cnt <= 0; cnt_done <= 1;
else end begin cnt <= cnt + 1; cnt_done <= 0; end end else if(CM_cnt[1:0] == 2'b01)//模式 2,计数器从 0 开始计数,计数到给 定的最大值 begin if(cnt == cnt_MAX) begin cnt <= 0; cnt_done <= 1; else end begin cnt <= cnt + 1; cnt_done <= 0; end end end endmodule `timescale 1ns/1ns `define clk_period 20 module APB_Timer_tb; //source define testbench 测试功能代码 reg [31:0]Paddr,Pwdata; reg Psel,Penable,Pwrite,Prst_n,Pclk; //probe define wire [31:0]Prdata; wire cnt_done; //instant user module APB_Timer APB_Timer1( .Paddr(Paddr), .Pwdata(Pwdata),
分享到:
收藏