RISC-V学习笔记(三):RISC-V的SOC总线和外设

前提

RISC-V的SOC在没有总线的情况下和外设连接的话,core就需要直接与外设直接连接交互了

处理器核core直接与每个外设进行交互。假设一个外设有一条地址总线和一条数据总线,总共有N个外设,那么处理器核就有N条地址总线和N条数据总线,而且每增加一个外设就要修改(改动还不小)core的代码。有了总线之后,处理器核只需要一条地址总线和一条数据总线,大大简化了处理器核与外设之间的连接。

1.总线(实践项目采用单总线结构rib.v)

计算机(实际上RISC-V处理器就相当于一个小的计算机)所有功能的实现过程就是各种信息在计算机内各大功能部件之间进行交换的过程,因此,总线出现了为部件之间构筑了信息传输的公共通路。

目前已经有不少成熟、标准的总线,比如AMBA、wishbone、AXI等。设计CPU时大可以直接使用其中某一种,以节省开发时间。但是为了追求简单,实践项目并没有使用这些总线,而是自主设计了一种名为RIB(RISC-V Internal Bus)的总线。RIB总线支持多主多从连接,但是同一时刻只支持一主一从通信。RIB总线上的各个主设备之间采用固定优先级仲裁机制。

1.单总线结构

在单总线结构的系统中只有一条系统总线,因此所有的外设都只能连接在这一条总线上构成完整的系统。

RIB总线本质上是一个多路选择器,从多个主设备中选择其中一个来访问对应的从设备。

RIB总线地址的最高4位决定要访问的是哪一个从设备,因此最多支持16个从设备。

注意:RIB总线上不同的主设备切换是需要一个时钟周期的,因此如果想要在执行阶段读取到外设的数据,则需要在译码阶段就发出总线访问请求。

2.总线的仲裁方式(实践项目采用的是作者自己设计的类似状态机的方式:固定优先级仲裁机制,有点意思的这个,可以去网上看看这种仲裁方式)

总线的仲裁也称总线的控制。因为总线为多个部件共享,为防止有多个部件同时使用总线导致数据冲突,需要有一个总线控制机构来解决总线使用权的仲裁,以某种方式选 择其中一个设备作为主设备。总线控制机构,又称总线控制器,它的组成与总线控制方式有关。

3.总线的定时方式

总线的一次信息传送有地址传送和数据传送两个过程,四个阶段

1.总线请求与仲裁:需要使用总线的主部件(或源部件)提出请求,由总线控制器确定将下一个总线使用权分配给哪一个请求者。(在rib.v里面有主设备请求)

2.寻址阶段:取得使用权的主部件通过总线发出本次要访问的从部件(或目的部件)的存储器地址或1/。端口地址及有关命令,启动相应的目的部件。

3.信息传送阶段:主从部件之间进行数据传输。

4.结束阶段:主部件撤销总线请求等有关信息,让出总线,以便总线控制器重新分配总线使用权。
定时方式:
1.同步通信: 通信双方在统一的时钟控制下进行信息的传输。
2.异步通信:又称应答通信,是指通信联络的控制信号采用异步式的一种通信方式,即总线上的部件通过总线传送信息时,源部件不只是单向发送信息,它在发出一个信息后,要等待目的部件发回确认信号,再发送下一个信息。
4.rib.v(RIB总线模块)

rib总线有很强的主从关系且很类似所有感觉没必要列太多。RIB总线实际是多路选择器,主选从。

序号信号名输入/输出位宽(bits)说明
1m0_addr_i输入32主设备0读写外设地址
2m0_data_i输入32主设备0写外设数据
3m0_data_o输出32主设备0读取到的数据
4m0_ack_o输出1主设备0访问完成标志
5m0_req_i输入1主设备0访问请求标志
6m0_we_i输入1主设备0写标志
7s0_addr_o输出32从设备0读、写地址
8s0_data_o输出32从设备0写数据
9s0_data_i输入32从设备0读取到的数据
10s0_ack_i输入1从设备0访问完成标志
11s0_req_o输出1从设备0访问请求标志
12s0_we_o输出1从设备0写标志

注意:RIB总线上不同的主设备切换是需要一个时钟周期的,因此如果想要在执行阶段读取到外设的数据,则需要在译码阶段就发出总线访问请求。

注释:这里是主设备优先仲裁,顺序对应依次为uart串口模块(uart.v)、执行模块(ex.v)、jtag模块(jtag_top.v)、PC寄存器模块(pc_reg.v),其中除了pc_reg外其他主设备访问总线都需要流水线停顿。

2.外设

1.ROM(rom.v)

ROM:只读存储器,存储内容在制造时就固定的存储器,此后的内容仅可读。

功能

存储指令码,根据PC寄存器输出的地址码向外输出指令码。(在取指篇会详细讲)

2.RAM(ram.v,RAM模块的实现和ROM一样)

RAM:随机存取存储器又称作“随机存储器”,是与CPU直接交换数据的内部存储器,也叫主存(内存),存储单元的内容可按需随意取出或存入,且存取的速度与存储单元的位置无关的存储器。

1.SRAM

SRAM:静态随机存取储存器,具有静止存取功能的内存

2.DRAM

DRAM:动态随机存取存储器,每隔一段时间,固定要对DRAM刷新充电一次,否则内部的数据即会消失。将实践项目移植到PGL22G的时候,DRAM资源不够,无法像项目作者在原来代码里面一样直接使用定义reg的方式来构造存储器,必须要使用BRAM的ip核。

3.TIMER(timer.v)

TIMER:在这里我理解为总线定时用的32位计数器,用于触发定时器中断的。

序号信号名输入/输出位宽(bits)说明
1clk输入1时钟输入信号
2rst输入1复位输入信号
3data_i输入32计数器读数据,来源于rib.v的s2_data_o
4addr_i输入32计数器数据读地址,来源于rib.v的s2_addr_o
5we_i输入1计数器写标志,来源于rib.v的s2_we_o
6data_o输出32

计数器写数据,输出到rib.v的s2_data_i

7int_sig_o输出1定时器中断信号,最终会流向if_id.v的int_flag_i
1.三个寄存器的定义:

1.REG_CTRL(控制寄存器):

1)[0]:计数器计时使能

2)[1]:定时器中断使能

3)[2]:计时器等待使能,置1清0

4)地址偏移量:0x00

2.REG_COUNT(计数器阈值寄存器):

3.REG_VALUE:

1)计数器预期值(阈值)

2)地址偏移量:0x08

2.定时器中断信号设置

定时器中断使能且定时器等待使能时赋值为1,否者赋值为0。

3.定时器计数

每个周期时钟自增1,达到阈值(或者异常情况)后归零。

4.写寄存器

定时器使能赋值,定时器中断使能赋值,计时器等待使能赋值(置1清0),计数器使能且定时器计数达到阈值时,计数器计时使能失效,计时器等待使能失效,以此判断定时器中断触发。

5.读寄存器

4.UART(uart.v)

UART:通用异步收发器。

1.UART通信的异步通信机制

UART:一种常用的串行通信协议,广泛应用于单片机或各种嵌入式设备之间的通信。

注释:1.TX:发送数据端,要接另一设备的RX

           2.RX:接收数据端,要接另一设备的TX

 UART通信是一种异步串行通信方式,原理是通过数据线传输二进制数据位。UART通信系统主要由发送端和接收端两部分组成。UART通信采用异步通信方式,即发送端和接收端之间通过数据线进行数据传输。在异步通信中,发送端和接收端不需要同时处于激活状态,而是通过起始位和停止位来标识数据帧的开始和结束。具体来说,当发送端产生起始位后,发送一个数据位;然后等待接收端的起始位,如果接收到起始位,则继续发送下一个数据位;如果没有接收到起始位,则认为数据帧传输失败。同样,当接收端产生停止位后,发送一个校验位;然后等待发送端的停止位,如果接收到停止位,则认为数据帧传输成功。

2.UART通信协议

1.起始位:数据传输开始时发送方要先发出一个低电平’0’来表示传输字符的开始,空闲位一直是高电平,开始第一次通讯时先发送一个明显区别于空闲状态的信号即为低电平。

2.数据位:通常是5-9位数据(在实践项目中是8位数据)构成一个字符。先发送低位再发高位。

3.奇偶检验位:一般为0-1位

4.停止位:一般为1-2位的高电平。

 3.UART的波特率

波特率表示单位时间内通过线路传输的二进制数据的位数,通常用bps表示,波特率为9600bps,则每秒钟可以传输9600个比特位的数据。串口传输数据的波特率是单片机的时钟系统来产生的,因此它和单片机的系统时钟存在算式关系如下:

波特率= (16 * 时钟频率) / (32 * 采样时间) + (1 * 时钟频率) / (32 * 采样时间) - (1 * 时钟频率) / (64 * 采样时间)

注释:采样时间指上次起始位到本次的间隔时间

序号信号名输入/输出位宽(bits)说明
1clk输入1时钟输入信号
2rst输入1复位输入信号
3we_i输入1串口写标志,来源于rib.v的s3_we_o
4addr_i输入32串口数据读地址,来源于rib.v的s3_addr_o
5data_i输入32串口读数据,来源于rib.v的s3_data_o
6data_o输出32串口写数据,输出到rib.v的s3_data_i
7tx_pin输出1串口的tx接口,直接接到tinyriscv_soc_top
8rx_pin输入1串口的rx接口,直接接到tinyriscv_soc_top

1.S_IDLE:串口闲置使能地址

2.S_START:串口通信开始使能地址

3.S_SEND_BYTE:串口发送数据使能地址

4.S_STOP:串口通信结束使能地址

串口寄存器地址定义

串口的TX发送

当复位信号来临时,串口状态赋为空闲状态,其余赋0

当串口状态为空闲时,发送端置1;发送的数据有效时,状态更新为串口通信开始,要发送的数据写入UART_TXDATA寄存器,发送端置0(计数周期)

串口的RX接收

检测信号在这里使用下降沿触发,我看了其他博主的文章他们给出的解释是类似按键触发时会触发大量毛刺一样,为了保证检测的准确性,使用下降沿触发有效屏蔽毛刺带来的影响。

而这里就是检测信号的赋值,这里采用了非阻塞型赋值,这样q1就会等于的是未被pin赋值前的q0,有效避免了逻辑上的错误:(下图配合UART通信协议的图2看的话会更好理解。)

接收数据时钟到9时,8bit数据接收完毕

5.GPIO(gpio.v)

GPIO:输入/输出接口,可以配置成输出模式来控制外部设备,也可以配置成输入模式来读取外部信号。(玩过stm32或者树莓派吧,上面一堆接口,FPGA开发板上也有一堆接口)

6.SPI(spi.v)

SPI:串行外围设备接口,是一种高速的,全双工,同步的通信总线。主要应用于EEPROM(带电可擦可编程只读存储器),FLASH,RTC(实时时钟),AD转换器,还有数字信号处理器和数字信号解码器。

1.SPI通信协议

SPI是一个同步的数据总线,也就是说它是用单独的数据线和一个单独的时钟信号来保证发送端和接收端的完美同步。

整体的传输大概可以分为以下几个过程:

1.主机先将NSS信号拉低,这样保证开始接收数据;

2.当接收端检测到时钟的边沿信号时,它将立即读取数据线上的信号,这样就得到了一位数据(1bit);
由于时钟是随数据一起发送的,因此指定数据的传输速度并不重要,尽管设备将具有可以运行的最高速度(稍后我们将讨论选择合适的时钟边沿和速度)。
 

3.主机发送到从机时:主机产生相应的时钟信号,然后数据一位一位地将从MOSI信号线上进行发送到从机;

4.主机接收从机数据:如果从机需要将数据发送回主机,则主机将继续生成预定数量的时钟信号,并且从机会将数据通过MISO信号线发送;

SPI总线包括4条逻辑线:

1.SCLK: 串行时钟信号,主设备产生。

2.MOSI:主机输出,从机输入(数据来自主机)。

3.MISO:主机输入,从机输出(数据来自从机)。

4.SS:片选信号,用于主机发送片选CS信号,选择控制的从设备,常是低电平有效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值