分频
奇:双沿,取或
偶:计数(n/2)-1,反转一次
协议
SPI
module spi
(
input I_clk , // 全局时钟50MHz
input I_rst_n , // 复位信号,低电平有效
input I_rx_en , // 读使能信号
input I_tx_en , // 发送使能信号
input [7:0] I_data_in , // 要发送的数据
output reg [7:0] O_data_out , // 接收到的数据
output reg O_tx_done , // 发送一个字节完毕标志位
output reg O_rx_done , // 接收一个字节完毕标志位
// 四线标准SPI信号定义
input I_spi_miso , // SPI串行输入,用来接收从机的数据
output reg O_spi_sck , // SPI时钟
output reg O_spi_cs , // SPI片选信号
output reg O_spi_mosi // SPI输出,用来给从机发送数据
);
4线 全双工
3线 半双工(MOSI 和 MISO两根信号线在时间上复用)
SCK (Serial Clock):时钟信号线,用于同步通讯数据。由通讯主机产生,决定了通讯的速率,不同的设备支持的最高时钟频率不同
MOSI (Master Output, Slave Input):主设备输出/从设备输入引脚。数据方向由主机到从机
MISO (Master Input,Slave Output):主设备输入/从设备输出引脚。数据方向由从机到主机
CS (Chip Select):片选信号线。通信期间低电平有效,表示对应从机被选中
4种模式,由时钟极性(CPOL,Clock Polarity)和时钟相位(CPHA,Clock Phase)来定义
时钟极性(CPOL)决定SPI总线空闲时的时钟信号是高电平还是低电平。
CPOL = 1:表示空闲时是高电平;
CPOL = 0:表示空闲时是低电平。
时钟相位(CPHA)决定SPI总线从哪个跳变沿开始采样数据。
CPHA = 0:在时钟信号SCK的第1个跳变沿采样;
CPHA = 1:在时钟信号SCK的第2个跳变沿采样。
UART(异步收发传输器)
是一种异步传输方式,发送方和接收方之间没有共享的时钟信号,而是通过一个预定的波特率来同步数据,通信双方波特率一致
其在数据发送时将并行数据转换成串行数据来传输,在数据接收时将接收到的串行数据转换成并行数据,RS232 RS485
232单端通信,距离近,容易被干扰
485差分信号(周期相同,极性相反,靠干扰强,可以多支路多个从机地址)
差分信号逻辑“1”以两线间的电压差为+(2-6)V表示;逻辑“0”以两线间的电压差为-(2-6)V表示
发送先从低位开始DATA[0] 、 DATA[1] 、 ... 、DATA[7]
UART最多一次传输8位而不是更多位的原因在于收发双方并不是时钟同源的,并不像SPI系统有一个主时钟供主、从机共享。UART的设计标准就是允许收发两端的频率偏差在10%以内,因此当接收8位数据后,收发双方的误差刚好控制在1位内,对数据的采样不会出错,可正确通信。
三根数据线TX RX GND
波特率是指单位时间内传送二进制数据的位数,单位用bps(位/秒)表示,记作波特
比特率来衡量异步串行通信的数据传输速率,即单位时间内传送二进制有效数据的位数,单位用bps表示
发送时候从baud_cnt=1开始,接收时候从baud_cnt=half开始
[(1/9600)*10^9]/20=5208 发送一位需要的时钟
接收时候要打拍,消除亚稳态
发送
moudle uart_tx{
input sys_clk ,
input sys_rst ,
input start ,// 开始发送数据标志
input [7:0] data ,// 要发送的数据
output rs232 ,// 发送的串行数据,从低位开始发送
output done // 一帧结束发送数据标志
}
接收
moudle uart_rx{
input sys_clk ,
input sys_rst ,
input rs232 ,// 接收的串行数据
// 找到rs232的下降沿,就开始读信号
output [7:0] data ,// 拼接好的正确的数据
output done // 一帧接收数据完成标志
}
比特率:单位 Bps(bit per second),即每秒传输的 bit 数。
波特率:单位 Baud,即每秒传输的 码元 数
IIC
起始位:SCL信号为高电平的时候,SDA出现一个下降沿(类比uart)
停止位:SCL信号为高电平的时候,SDA出现一个上升沿
SCLK为高电平时,SDA数据保持或者说需要保持稳定
SCLK为低电平时,SDA数据发生变化
module iic{
input sysclk,
input sysrst,
input iic_scl,
inout iic_sda
};
IIC通信,高位在先,低位在后
R/W:IIC从机的7位设备地址后面添一个0表示主机向从机写数据,
1表示主机从从机读数据,
然后组成一个8位的数据
写:起始+器件地址0+应答+存储地址+应答+数据+应答+停止
读:起始+器件地址0+应答+存储地址+应答+起始+器件地址1+应答+数据+无应答+停止
应答信号:从机给主机
无应答信号(最后一个数据之后才有,多字节读取时中间都是应答信号):主机给从机
USB
高速串行
7域
同步域:8位,值固定0000-0001,用于本地时钟与输入同步
标识域:8位,4位标识符+4位标识符反码,用于表明包的类型和格式
地址域:7位,设备在主机上的地址
端点域:4位,
帧号域:11位
数据域:最大1024字节长度,整数字节长度
校验域:
采用NRZI编码:0跳变,1不变,连续六个1跳变
三个阶段:令牌包、数据包、握手包,由域组成
事务:三种IN OUT SETUP,每种事务都由令牌包、数据包、握手包三个阶段构成
IN事务(主机要数据)
令牌包:主机发送一个标识域为IN的输入包给设备,告诉设备要发数据给主机
数据包:三种情况:1、设备端点正常,正常发送数据
2、设备在忙,无法发送数据包给主机,会发送NAK无效包,主机IN事务提前 结束,等待下次的IN事务到来
3、设备端点禁止,发送STALL包,事务结束
握手包:主机接收数据正确,会发送ACK包给设备
OUT事务(主机发数据)
和IN事务一样,只是过程相反
SETUP事务(主机发数据)
令牌包:主机发送一个标识域为SETUP的输入包给设备,告诉设备要发数据给主机
数据包:只有8字节但是有11种情况,每个都是8字节的内容是标准的usb设备请求命令
握手包:设备接收到主机的命令信息之后,返回ack,然后进入空闲,准备下一次传输
一般setup之后通常是一个in或者out事务
传输:中断传输、批量传输、同步传输、控制传输
同步传输的in、out在数据包之后没有握手包,只有data0,不会有data1来交叉传输
中断传输:鼠标键盘
批量传输:大容量
控制传输:最复杂
宏观上看:位->域->包->事务->传输
硬件上基本上直接使用封装好的usb芯片,只要把指令送进端口即可
rxf wxf
AXI
zynq异构芯片(两种或多种不同类型的微处理器或微控制器的架构的芯片),内部总线使用AXI总线,突发传输
三种:AXI-FULL、AXI-LITE、AXI-STREAM
独立的地址数据通道,通道传输为单方向。可同时做数据读写
五个通道:主要信号作用
写地址通道:AWVALID AWREADY同为1为有效,把AWADDR地址写入
写数据通道:WVALID WREADY同为1为有效,把WDATA地址写入,数据长度是突发长度(1,2,4,8,16,32,64,128,256),WLAST在一个突发完成的最后一个数据拉高一次
写响应通道:BVALID BREADY同为1,表示一次突发完成
读地址通道:ARVALID ARREADY同为1为有效,把ARADDR地址写入
读数据通道:RVALID RREADY同为1为有效,把RDATA地址读出,RLAST在一个突发完成的最后一个数据拉高一次
AXI中一次突发不能越过4K字节边界!
AWLEN=突发长度
AWSIZE=(数据位宽/8)- 1
AWBURST= (突发类型)[三种模式:地址固定(00)、自增(01)、扫描(10)]
AWLOCK=0,没用到
AWCACHE=4位,缓存模式,一般选择无缓存,手册查
AWPROT,AWQOS,AWUSER=0
WSTRB=data_width{1'b1},掩码信号,取1表示数据有效
AWID ARID=0 用不到
读写地址都需要加一个基地址
握手机制理解就是valid和ready同为高,才可以,并且在主从接口的代码逻辑里相互制约。
主模式
写地址通道
接收到写开始脉冲之后开始工作
// 地址,每次写地址成功之后变化,地址每次突发只写入一个值
output wire [addr_width-1:0] AWADDR ,
// 有效信号和准备信号同为1之后才拉低
output wire AWVALID ,
// 从机发来的
input wire AWREADY ,
写地址完成之后,马上写数据
写数据通道
// 数据
output wire [data_width-1:0] WDATA ,
// 有效
output wire WVALID ,
// 一次突发最后的数据标志脉冲
output wire WLAST ,
// 从机发来的
input wire WREADY ,
写数据完成之后
写响应通道
两个信号同为1表示
input wire BVALID ,// 从机发送来的
output wire BREADY ,// 主机可以一直把这个信号置1
读地址通道
接收到读开始脉冲之后开始工作
// 地址
output wire [addr_width-1:0] ARADDR ,
// 有效和准备同为1,之后拉低
output wire ARVALID ,
// 从机发来的
input wire ARREADY ,
读地址完成之后,马上读数据
读数据通道
// 从机发送来的
input wire RVALID ,
// 主机可以一直把这个信号置1,有效和准备同为1,数据有效
output wire RREADY ,
// 从机发送来的数据
input wire [data_width-1:0] RDATA ,
从模式
和主模式逻辑相同,只是各通道的valid和ready输入输出相反
FIFO
异步fifo,读写时钟不一致;同步fifo,读写时钟一致
写入频率和读出频率不一致时:
fifo数据深度计算
题目:100个写时钟周期可以写入80个数据,10个读时钟可以读出8个数据,计算FIFO深度
解析: 写时钟频率 w_clk,
读时钟频率 r_clk,
写时钟周期里,每B个时钟周期会有A个数据写入FIFO
读时钟周期里,每Y个时钟周期会有X个数据读出FIFO
则,FIFO的最小深度是?
计算公式如下:
fifo_depth = burst_length - burst_length * X/Y * r_clk/w_clk
所以带入:
fifo_depth = 160-160X(80%)=160-128= 32
二进制如何转化为格雷码
二进制数的最高位保持不变, 后续位依次与前一位进行异或运算
assign a_gray = (a>> 1) ^ a;
把读写地址转换为格雷码,降低出现亚稳态问题,然后对比读写地址,判断是否读空or写满
因为是异步,需要把格雷码的读写地址做跨时钟域处理,打两拍
assign empty = (rd_adr_gray == wr_adr_gray2)?1'b1:1'b0;
assign full =
(wr_adr_gray[data_depth:data_depth-1] == (~(rd_adr_gray2[data_depth:data_depth-1])))
&& (wr_adr_gray[data_depth-2:0] == rd_adr_gray2[data_depth-2:0]);
二进制指针转换为格雷码,跨时钟后进行空满判断。读空是写时钟域下的写指针同步到读时钟域下与读指针进行比较,完全一样即为读空。写满是读时钟域的读指针同步到写时钟域与写指针比较,高两位不同,低位相同即为写满。
存储器
eeprom iic
flash spi
SDRAM:同步动态随机存储器,需要一直刷新保证数据不丢失,断电就寄
随机:存储地址可以自己指定
DQM写时序时拉高可屏蔽数据,读时序时需要延时CL个时钟
每个操作都由cs/ras/cas/we组成
列读写:读写命令和列寻址同时发出
状态机实现:初始化——配置模式寄存器——行激活(无论是读操作还是写操作)——列读写——预充电(必须!!)——idle
读数据有延时,写数据没有延时
突发读写长度(BL)可以为1、2、4、8和“全页(Full Page)”,其中“全页”是指突发传输一整行的数据量。
DDR(Double Data Rate SDRAM)
DDR1,比较sdram快2倍,有两个clk,一对差分时钟,一个时钟传两个数据,上升沿下降沿都传数据
DDR2,比较sdram快4倍,因为外部时钟频率变大到两倍
两种AD的区别(SAR ADC与Sigma Delta ADC)
SAR:时间延迟小,几乎0延迟;低功耗;分辨率稍微低一些;采用速率较低
采样速率 精度
ADS7XXX <4Msps <16bit
ADS8XXX <1.25Msps <20bit
逐次逼近 1、1/2、1/4、1/8....,一点一点加去逼近
Sigma Delta:clock延迟大;分辨率最高;高稳定性