RISC-V技术论坛
直播中

ejlwj

9年用户 979经验值
擅长:处理器/DSP
私信 关注
[经验]

基于蜂鸟E203处理器的DMA模块设计

设计思路

   DMA模块主要是完成数据的搬运工作,其中它与总线有两个接口,一个是与CPU进行通信,一个是与内存进行通信。与CPU通信的总线接口DMA作为从机,CPU通过对DMA的寄存器进行读写来控制DMA的状态。与内存通信的总线接口DMA作为主机,发出命令信号从SRAM中读或者写数据。
  所以DMA模块主要有两个部分,一个是与CPU通信的部分,另一个是与SRAM通信的部分。与CPU通信的部分的ICB时序较为简单,收到命令后可直接与其握手。另一个部分是与SRAM通信,由于DMA中有FIFOFIFO的时序也影响这ICB总线时序,所以需要整体考虑。
  除了ICB时序部分,再添加一个FIFO,以及进行相应的寄存器维护就能使DMA正常工作了。


RTL代码分析
(一)寄存器配置ICB时序
1、dma_cfg_icb_cmd_ready


如果是读寄存器的值,则需要等待rsp_valid信号为0时才能读,此时表示没有对寄存器进行写值,如果是写寄存器时,当dma_cfg_icb_cmd_valid产生时则立即将ready拉高。





2、dma_cfg_icb_rsp_valid


cmd信号握手后,表明写或者读寄存器值正常,则可以在下一个周期将该信号拉高,直到与rsp信号握手,将这个值拉低。




3、dma_cfg_icb_rsp_rdata


可以利用组合逻辑实现,但本次模块中采用握手后的下一个周期读出寄存器的值。并且当rsp_valid信号没有拉低时(也就是握手还没有成功时),rdata的值需要一直保持,握手成功后根据寄存器地址进行赋值。




寄存器维护

维护的寄存器如下表

  寄存器名称

  
  寄存器功能

  
  读写

  
  地址

  
  S_reg

  
  存放搬运起始地址

  
  可读可写

  
  0’h00

  
  D_reg

  
  存放搬运目的地址

  
  可读可写

  
  0’h04

  
  Data_len_reg

  
  存放搬运长度

  
  可读可写

  
  0’h08

  
  CR

  
  CR[7]:产生开始/再开始命令

  CR[0]:中断应答,置1时清除等待的中断

  
  可读可写

  
  0’h0d

  
  CTR

  
  CTR[7]:置1时表示DMA功能使能,软件能够配置命令寄存器来发起命令操作

  CTR[6]:中断使能

  
  可读可写

  
  0’h0e

  
  SR

  
  状态寄存器

  SR[0]:中断标志

  SR[1]:1表示正在传输数据,0表示传输完成

  SR[2]:1表示DMA忙状态

  SR[3]:1表示寄存器配置已经完成

  
  只读

  
  0’h0c

  
  寄存器的写功能基本一致,当cmd信号握手后,如果地址匹配并且检测到read信号为0,则对相应地址的寄存器写入值。




中断模块

1. 状态寄存器中的中断标志:irq_flag

DMA工作结束并且CR寄存器中中断应答置为0时,该信号拉高。

2. 整个DMA的中断标志



当状态寄存器中的中断标志为1,并且DMA模块中断使能为1时,可以中断。




FIFO模块
1、读与写地址


初始地址都为0,当空的时候无法进行读操作,满的时候无法进行写操作。





2、空、满与溢出信号


当地址的低5位相同,并且最高位不同时,则表示FIFO已经满了,当读写指针所有位都相同时,则表示FIFO为空。





溢出信号是当FIFO满的时候,还要继续写进数据时,指示的信号,所以可以利用时序逻辑




3、读数据与写数据


读数据与写数据根据读写使能信号以及空满信号,将指针对应的数据读出或者写入。




4、sub_full

由于时序逻辑的延迟,导致状态机在判断下一个状态时要提前知道fifo是否满了,由于fifofull信号比next_state信号晚两个周期,所以需要一个sub_full信号来指示fifo是否即将满了。


DMA的数据传输

1、传输阶段状态机的实现

在传输阶段,主要有三个状态:初始状态,读SRAM状态,写SRAM状态。

初始状态:当DMA使能信号为0时或者开始信号未拉高时,初始状态下一状态一直未初始状态,表示DMA还未开始传输。

SRAM状态:当DMA使能信号为0时,其下一状态为初始状态。

     FIFO还没有满,并且读的数据数目还没有达到要求的数目,下一状态继续读。

     否则下一个状态为写。

SRAM状态:当DMA使能信号为0时,其下一状态为初始状态。

     FIFO还未空,并且写的数据数目没有达到要求的数目,下一个状态继续写。

     如果读的数据还没读完,则下一个状态变为读。


     否则下一个状态变为初始状态。


1、dma_busy


dma在读或者写状态时,dma为忙状态,但是由于为时序逻辑,会在下一个周期改变值,所以用next_state作为判断依据。
2、dma_done


当写进SRAM的中的data数达到要求的数时,则dma工作结束。



3、w_data


当从机发来rsp信号与主机握手时,将传来的数据赋值给要写进FIFO的数据,为组合逻辑。






ICB访存时序

1、read_cmd_cnt


always块用来计数发出了多少次访问SRAM的命令,当为读状态时,每cmd握手一次就加一。Write_cmd_cntwrite_rsp_cntread_rsp_cnt同理



2、dma_icb_cmd_valid

每握手一次需要拉低一次,由于从机的ready信号不知道何时来,所以不能持续拉高,进行连续的读或者写。

当为读状态,如果读的命令还没有超过需要读的数,则发出命令。

当为写状态,如果写的命令还没有超过需要写的数,则可发出命令。

否则该信号不变。

注意这里不需要考虑从机还没有发出rsp_valid信号主机就再次发出cmd_valid信号了,就算发出了它们也不能握手成功,则该信号就会保持。



3、dma_icb_cmd_addr

注意为组合逻辑,当cmd握手后时,如果为读状态,则地址为s_reg中地址加上偏移量


如果为写状态,则为d_reg中的地址加偏移量。其中偏移量用发出的读或者写命令的次数代替。



  • 软件代码分析
1、寄存器地址定义

根据rtl中定义的寄存器地址进行定义


2、中断清除函数

通过对CR寄存器写入值对存在的中断进行清除。



3、DMA初始化

CTR寄存器写值,对DMA模块使能。



4、数据搬移函数

首先对源地址寄存器,目的地址寄存器,搬移数据长度寄存器分别进行配置,每配置一个寄存器后,不断读状态寄存器的值,当寄存器配置好后则进行下一个寄存器的配置。


当寄存器配置好后,开始搬运数据,直到状态寄存器指示DMA工作已经结束


5、主函数



更多回帖

发帖
×
20
完善资料,
赚取积分