RISC-V MCU中文社区

【分享】 基于蜂鸟E203处理器的DMA模块设计

发表于 全国大学生集成电路创新创业大赛 2021-07-07 10:52:17
1
6170
16

一、团队介绍

  我们的队伍名称是我要吃火锅,报名编号为CICC2882。


二、设计思路

   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、主函数



喜欢16
用户评论 (1)
  • JP_Shi

    2023-04-08 18:50:15 JP_Shi 1#

    你好,请问DMA的master端应该如何挂载到系统存储总线的slave端?

clever

clever 实名认证

懒的都不写签名

积分
问答
粉丝
关注
  • RV-STAR 开发板
  • RISC-V处理器设计系列课程
  • 培养RISC-V大学土壤 共建RISC-V教育生态
RV-STAR 开发板