微架构设计思路
- ahb_slave_if中的寄存器可以在datasheet中进行描述
- sd_clk - 时钟产生模块的接口描述
- sd_data_fsm和sd_cmd_fsm - 状态机描述
- 发送时序需要遵守,并且在发送的时候需要产生CRC
- 接受时序需要遵守,并且要接收CRC,进行比较
- FiFo中有存储体存储数据,FiFo_ctrl模块进行fifo的控制
- DMA - AHB_master的设计
sd_clk设计
- 具有分频电路,根据ahb_slave_if中寄存器的配置对hclk进行分频
- 硬件停止时钟
- 软件开关时钟
- 需要考虑在DFT模式下,时钟如何?
- 时钟分频,使用计数器进行时钟周期,实现分频;如果分频配置为0,表示使用原始时钟hclk进行输入
- 软硬件开关时钟,就是在使能信号的条件下,选择时钟的输入
- test mode下同样是在test_en的条件下,选择hclk,保证扫描链的时钟频率是一样的
sd_if模块功能
- ahb总线信号处理,进行地址和数据对齐
- 其中有一些寄存器,对寄存器及其中的地址域段进行读写操作
- 有两个时钟域,ahb时钟域和sd时钟域,进行时钟域的同步
sd_clk模块
- 允许软硬件干预时钟
- in_clk_divider - 分频大小
- in_sd_clk_enable - 软件使能clk
- hw_stop_clk - 硬件使能(硬件在读的时候,进行数据搬移的时候,可以关闭时钟)
- out_sd_clk_dft - 输出clk
sd_clk模块:时钟输出描述
- 分频大小通过寄存器配置,如果分频寄存器为0,就输出原时钟
- sd_io - 是更通用的协议,可以连接Wifi设备或者GPS设备
sd_cmd_fsm
- 硬件检测sd card是否是busy
- 将一条命令(比如48bit)作为一个状态
- idle状态通过cpu trigger信号进入到wait send状态,此时通过硬件检查sd card是否处于busy状态,就是data总线的data[0]是否为1,转到wait resp状态,当cmd=0的时候,转到receive resp状态
sd_cmd_fsm模块:状态机控制图
- in_command_ready = 1表示cpu让硬件去发送cmd
- in_sd_dat[0] - 拉高之后,进位send状态
- wait response时间超过预设的值Ncr,给出timeout信号,进入state stop状态
- in_soft_reset - 软件复位,高电平有效
- in_response - 表示当前命令有没有resp
- in_longresponse - 回复长命令信号
- in_cmmmand_ready - 软件置位,硬件清0
- has_send_bit - 表示当前发送了多少位(48bit,6bit)
- has_receive_bit - 表示当前已经接收的多少位(136bit,8bit)
- end_command - 命令结束信号
- end_command_and_response - 命令结束并且完成回复接收
- response_timeout - 响应超时信号
sd_cmd_send_shift_register模块
- in_current_state - 处于特特定的状态才能发送数据
- has_send_bit - 用于判断当前的命令发送的是crc还是argument
- out_cmd_dir - 控制输出的方向,输入还是输出
- out_sd_cmd - 并行数据转换为串行数据,利用移位寄存器,每次输出最高位然后左移一位,
- 0-25MHz - 数据是在下降沿进行驱动的
- 50Hz - 数据驱动沿是上升沿
sd_cmd_recieve_shift_register模块
- in_serial_cmd - 接收sd card发送的cmd
- in_longrespone - 接收136bit resp
sd_data_fsm 模块
读操作
- data传输包含读写
- 经过一个Nac之后,进行读数据,start bit为0表示数据开始
- 设置一些状态判断当前正在接收什么数据
- content和crc可以合并在一起不太好?receive data的时间于block length和data总线的位宽相关,所以和crc合在一起不好计算时间
写操作
- 写操作,先发送数据,再接受sd card的resp信息
- 中间会产生总线的移交
-
硬件停止时钟?假设fifo只能存储一个block数据,读取完之后,将数据存储到fifo中,fifo满了之后,需要DMA将fifo中的数据搬移掉之后,才能进行下一次的读操作;在DMA搬移fifo中数据的过程中,停止sd card的时钟
-
读数据的返回都是需要时钟进行驱动的
-
读操作过程:首先CPU配置寄存器,然后host发送读操作命令,然后启动multi block read的状态机
-
首先等待fifo empty,然后使能sd_clk,读取数据,当fifo满了之后,产生中断,CPU收到中断之后,通过DMA,将fifo中的数据搬移
-
one_bk_re_end的作用:进行低功耗设计,防止出现前一个block中的数据还没读取完的时候,写入下一个block的数据,防止数据丢失
sd_data_fsm模块:控制状态机
- in_data_ready - 软件置位,硬件清0
sd_data_send_shift_register模块信号
- 发送数据的时候,需要接受sd card返回的crc的值,crc只会在data[0]中进行返回,data[0:3]只有在写的时候才会使用