APB 您所在的位置:网站首页 apb怎么注册 APB

APB

2023-09-09 02:18| 来源: 网络整理| 查看: 265

目录 SPECcongfigUart CongfigurationAPB Congfiguration scoreboard

SPEC 典型的基于AMBA总线的SOC系统结构如下图所示。 在这里插入图片描述

这种SOC结构是在高速总线协议和低速总线协议的互联支持下,将工作在不同频率的各个系统模块进行整合,最终协同处理器完成运算工作。其中低速总线往往采用APB协议,两种总线之间使用转接桥(bridge)完成协议转换。APB协议作为外围总线协议,将为各个低速模块提供通信接口。

DUT结构图如下: 在这里插入图片描述 APB-UART模块可以实现串行数据和并行数据的转换,发送和接收逻辑分别用FIFO来存储数据,CPU可以通过APB总线访问该模块,进而间接的实现对UART串行数据的访问。 在进行数据发送操作时,需要发送的数据通过APB总线被写入到该模块后,会暂时存储在Transmit FIFO中,发送逻辑模块会在特定的时刻从Transmit FIFO中取走数据,并添上起始位、奇偶校验位以及停止位,形成一个完整的数据帧。最后发送逻辑会将该数据帧放入到发送端口另一端的移位寄存器中,按照特定的波特率将数据串行移位,实现数据发送的功能。 在进行数据接收操作时,串行数据通过接收端口后会进入到接收逻辑模块,该模块对数据进行格式检测后,会将其中的起始位、校验位以及停止位移除,并把剩下的数据暂时存储在Receive FIFO中,等待CPU访问。 APB协议可参考:AMBA-APB协议 UART协议可参考:UART概述 congfig Uart Congfiguration

uart的相关配置主要包括波特率、帧长、奇偶校验以及停止位。在apbuart_base_test中,有一个set_config_params的方法用来实现这些配置,同时,此方法中还有一个flag来决定是使用定向配置还是随机配置设置。 代码如下:

function void apbuart_base_test::set_config_params(input [31:0] bd_rate , input [3:0] frm_len , input [1:0] parity , input sb , input flag); if(flag)//flag是用来决定使用定向配置还是随机配置(1 for random , 0 for directed) begin if (!cfg.randomize()) `uvm_error("RNDFAIL", " Config Randomization") end else begin cfg.frame_len = frm_len; cfg.n_sb = sb; cfg.parity = parity; cfg.bRate = bd_rate; end cfg.baudRateFunc(); endfunction function void uart_config::baudRateFunc(); case (bRate) 32'd4800: baud_rate = 32'd10416; 32'd9600: baud_rate = 32'd5208; 32'd14400: baud_rate = 32'd3472; 32'd19200: baud_rate = 32'd2604; 32'd38400: baud_rate = 32'd1302; 32'd57600: baud_rate = 32'd868; 32'd115200: baud_rate = 32'd434; 32'd128000: baud_rate = 32'd392; default: baud_rate = 32'd5208; endcase endfunction APB Congfiguration

APB相关的主要配置包括address以及pselect(APB中的slave引脚)。使用apbuart_base_test中的set_apbconfig_params方法来实现相关配置。 代码如下:

function void apbuart_base_test::set_apbconfig_params(input [31:0] addr, input flag); if(flag) begin if (!apb_cfg.randomize()) `uvm_error("RNDFAIL", " APB Config Randomization") end else begin apb_cfg.slave_Addr = addr; end apb_cfg.AddrCalcFunc(); endfunction function void apb_config::AddrCalcFunc(); if ((slave_Addr >= ` UART_START_ADDR) && (slave_Addr = ` I2C_START_ADDR) && (slave_Addr = ` SPI_START_ADDR) && (slave_Addr 0); // checking the fifo that it contains any valid entry from monitor apb apb_pkt_mon = pkt_qu_monapb.pop_front(); // getting the entry from the start of fifo if(apb_pkt_mon.PWRITE==1 && (apb_pkt_mon.PADDR == cfg.baud_config_addr || apb_pkt_mon.PADDR == cfg.frame_config_addr || apb_pkt_mon.PADDR == cfg.parity_config_addr || apb_pkt_mon.PADDR == cfg.stop_bits_config_addr)) begin case(apb_pkt_mon.PADDR) cfg.baud_config_addr : baud_rate_reg = apb_pkt_mon.PWDATA; cfg.frame_config_addr : frame_len_reg = apb_pkt_mon.PWDATA; cfg.parity_config_addr : parity_reg = apb_pkt_mon.PWDATA; cfg.stop_bits_config_addr : stopbit_reg = apb_pkt_mon.PWDATA; default : `uvm_error(get_type_name(),$sformatf("------ :: Incorrect Config Address :: ------")) endcase end else if(apb_pkt_mon.PWRITE==0 && (apb_pkt_mon.PADDR == cfg.baud_config_addr || apb_pkt_mon.PADDR == cfg.frame_config_addr || apb_pkt_mon.PADDR == cfg.parity_config_addr || apb_pkt_mon.PADDR == cfg.stop_bits_config_addr)) begin compare_config (apb_pkt_mon) ; end else if (apb_pkt_mon.PADDR == cfg.trans_data_addr) begin wait(pkt_qu_monuart.size() > 0); uart_pkt_mon = pkt_qu_monuart.pop_front(); compare_transmission (apb_pkt_mon,uart_pkt_mon); end else if (apb_pkt_mon.PADDR == cfg.receive_data_addr) begin wait(pkt_qu_drvuart.size() > 0); uart_pkt_drv = pkt_qu_drvuart.pop_front(); compare_receive (apb_pkt_mon,uart_pkt_drv); end end endtask : run_phase

这里的pkt_qu_monapb、pkt_qu_monuart、pkt_qu_uartdrv分别用来存储scoreboard通过analysis_port从apb_monitor、uart_monitor、uart_driver取出的数据。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有