当前位置:网站首页>SD_DATA_RECEIVE_SHIFT_REGISTER
SD_DATA_RECEIVE_SHIFT_REGISTER
2022-07-07 15:46:00 【捌肆幺幺】
1.接口
- 时钟复位软复位
- 状态信号in_current_state
- sd卡过来的数据信号in_serial_data
- 数据位宽in_data_width,决定1线还是4线传输
- 已经接受的bit数in_has_receive_bit
- sd发过来的数据信号sd_fifo_wdata,
- fifo使能信号sd_fifo_we,在收完32bit的参数后给出
- crc上报错误out_receive_data_crc_error
input in_sd_clk; //clock for sd card
input hrst_n;
input in_soft_reset; //software reset
input [3:0] in_current_state; //surrent state of data fsm
input [3:0] in_serial_data; //data input from sd card
input in_data_width; //data width 1:4bit 0:1bit
input [13:0] in_has_receive_bit; //has received data bits
output [31:0] sd_fifo_wdata; //output parallel data to rx fifo
output sd_fifo_we; //host writes rx_fifo
output out_receive_data_crc_error; //receive data crc error flag
2.内部信号
后面都会讲到
reg out_receive_data_crc_error;
reg sd_fifo_we;
reg [15:0] crc_reg0;
reg [15:0] crc_reg1;
reg [15:0] crc_reg2;
reg [15:0] crc_reg3;
reg [15:0] generate_crc_reg0;
reg [15:0] generate_crc_reg1;
reg [15:0] generate_crc_reg2;
reg [15:0] generate_crc_reg3;
reg [31:0] shift_reg;
reg out_write_receive_fifo;
3.数据位的转换
以为高位低位的手法存在差异,这里需要将bit数的顺序换一下
assign sd_fifo_wdata = {
shift_reg[7:0],shift_reg[15:8],shift_reg[23:16],shift_reg[31:24]};
4.fifo使能sd_fifo_we
- 由out_write_receive_fifo打一拍输出
- 当接收完参数(32位)后给出,相当于这里做了串转并的操作
always @(posedge in sd_clk or negedhe hrst_n) begin
if (!hrst_n)
sd_fifo_we <= 1'b0;
else if (!in_soft_reset)
sd_fifo_we <= 1'b0;
else
sd_fifo_we <= out_write_receive_fifo;
end
/----------------------------------------------------------
always @(*) begin
out_write_receive_fifo = 1'b0;
if (!in_data_width)
begin
if ((in_current_state == `DATA_STATE_RECEIVE) && (in_has_receive_bit[4:0] == 5'b11111))
out_write_receive_fifo = 1'b1;
end
else begin
if((in_current_state == `DATA_STATE_RECEIVE) && (in_has_receive_bit[2:0] == 3'b111))
out_write_receive_fifo = 1'b1;
end
end
5.并转串
- 两种情况,一线和四线传输的时候移位不同
always @(posedge in_sd_clk or negedge hrst_n) begin
if(!hrst_n)
shift_reg <= 32'b0;
else if (!in_soft_reset)
shift_reg <= 32'b0;
else begin
if (in_current_state == `DATA_STATE_RECEIVE)
begin
if(!in_data_width)
shift_reg <= {
shift_reg[30:0],in_serial_data[0]};
else
shift_reg <= {
shift_reg[27:0],in_serial_data};
end
end
end
6.接收crc16
- 在接收完参数后接收crc16,也是串转并的操作
always @(posedge in_sd_clk or negedge hrst_n)
if (!hrst_n)
begin
crc_reg0 <= 16'b0;
crc_reg1 <= 16'b0;
crc_reg2 <= 16'b0;
crc_reg3 <= 16'b0;
end
else if (in_soft_reset)
begin
crc_reg0 <= 16'b0;
crc_reg1 <= 16'b0;
crc_reg2 <= 16'b0;
crc_reg3 <= 16'b0;
end
else if ((in_current_state == `DATA_STATE_RECEIVE_END_BIT))
begin
crc_reg0 <= 16'b0;
crc_reg1 <= 16'b0;
crc_reg2 <= 16'b0;
crc_reg3 <= 16'b0;
end
else if (in_current_state == `DATA_STATE_RECEIVE_CRC)
begin
if(in_data_width == 1'b0)
crc_reg0 <= {
crc_reg0[14:0],in_serial_data[0]};
else begin
crc_reg0 <= {
crc_reg0[14:0],in_serial_data[0]};
crc_reg1 <= {
crc_reg1[14:0],in_serial_data[1]};
crc_reg2 <= {
crc_reg2[14:0],in_serial_data[2]};
crc_reg3 <= {
crc_reg3[14:0],in_serial_data[3]};
end
end
end
7.自己计算crc16
- 方法和前面说cmd模块时的crc7类似
- 主要是做异或的运算
- 记住是在接收的同时一起算crc16
always @(posedge in_sd_clk or negedge hrst_n) begin
if (!hrst_n)
begin
generate_crc_reg0 <= 16'b0;
generate_crc_reg1 <= 16'b0;
generate_crc_reg2 <= 16'b0;
generate_crc_reg3 <= 16'b0;
end
else if (!in_soft_reset)
begin
generate_crc_reg0 <= 16'b0;
generate_crc_reg1 <= 16'b0;
generate_crc_reg2 <= 16'b0;
generate_crc_reg3 <= 16'b0;
end
else if ((in_current_state == `DATA_STATE_RECEIVE_END_BIT))
begin
generate_crc_reg0 <= 16'b0;
generate_crc_reg1 <= 16'b0;
generate_crc_reg2 <= 16'b0;
generate_crc_reg3 <= 16'b0;
end
else if (in_current_state == `DATA_STATE_RECEIVE)
begin
if (in_data_width == 1'b0)
begin
generate_crc_reg0[0] <= in_serial_data[0] ^ generate_crc_reg0[15];
generate_crc_reg0[1] <= generate_crc_reg0[0];
generate_crc_reg0[2] <= generate_crc_reg0[1];
generate_crc_reg0[3] <= generate_crc_reg0[2];
generate_crc_reg0[4] <= generate_crc_reg0[3];
generate_crc_reg0[5] <= generate_crc_reg0[4] ^ in_serial_data[0] ^ generate_crc_reg0[15];
generate_crc_reg0[6] <= generate_crc_reg0[5];
generate_crc_reg0[7] <= generate_crc_reg0[6];
generate_crc_reg0[8] <= generate_crc_reg0[7];
generate_crc_reg0[9] <= generate_crc_reg0[8];
generate_crc_reg0[10] <= generate_crc_reg0[9];
generate_crc_reg0[11] <= generate_crc_reg0[10];
generate_crc_reg0[12] <= generate_crc_reg0[11] ^ in_serial_data[0] ^ generate_crc_reg0[15];
generate_crc_reg0[13] <= generate_crc_reg0[12];
generate_crc_reg0[14] <= generate_crc_reg0[13];
generate_crc_reg0[15] <= generate_crc_reg0[14];
end
else begin
generate_crc_reg0[0] <= in_serial_data[0] ^ generate_crc_reg0[15];
generate_crc_reg0[1] <= generate_crc_reg0[0];
generate_crc_reg0[2] <= generate_crc_reg0[1];
generate_crc_reg0[3] <= generate_crc_reg0[2];
generate_crc_reg0[4] <= generate_crc_reg0[3];
generate_crc_reg0[5] <= generate_crc_reg0[4] ^ in_serial_data[0] ^ generate_crc_reg0[15];
generate_crc_reg0[6] <= generate_crc_reg0[5];
generate_crc_reg0[7] <= generate_crc_reg0[6];
generate_crc_reg0[8] <= generate_crc_reg0[7];
generate_crc_reg0[9] <= generate_crc_reg0[8];
generate_crc_reg0[10] <= generate_crc_reg0[9];
generate_crc_reg0[11] <= generate_crc_reg0[10];
generate_crc_reg0[12] <= generate_crc_reg0[11] ^ in_serial_data[0] ^ generate_crc_reg0[15];
generate_crc_reg0[13] <= generate_crc_reg0[12];
generate_crc_reg0[14] <= generate_crc_reg0[13];
generate_crc_reg0[15] <= generate_crc_reg0[14];
generate_crc_reg1[0] <= in_serial_data[1] ^ generate_crc_reg1[15];
generate_crc_reg1[1] <= generate_crc_reg1[0];
generate_crc_reg1[2] <= generate_crc_reg1[1];
generate_crc_reg1[3] <= generate_crc_reg1[2];
generate_crc_reg1[4] <= generate_crc_reg1[3];
generate_crc_reg1[5] <= generate_crc_reg1[4] ^ in_serial_data[1] ^ generate_crc_reg1[15];
generate_crc_reg1[6] <= generate_crc_reg1[5];
generate_crc_reg1[7] <= generate_crc_reg1[6];
generate_crc_reg1[8] <= generate_crc_reg1[7];
generate_crc_reg1[9] <= generate_crc_reg1[8];
generate_crc_reg1[10] <= generate_crc_reg1[9];
generate_crc_reg1[11] <= generate_crc_reg1[10];
generate_crc_reg1[12] <= generate_crc_reg1[11] ^ in_serial_data[1] ^ generate_crc_reg1[15];
generate_crc_reg1[13] <= generate_crc_reg1[12];
generate_crc_reg1[14] <= generate_crc_reg1[13];
generate_crc_reg1[15] <= generate_crc_reg1[14];
generate_crc_reg2[0] <= in_serial_data[2] ^ generate_crc_reg2[15];
generate_crc_reg2[1] <= generate_crc_reg2[0];
generate_crc_reg2[2] <= generate_crc_reg2[1];
generate_crc_reg2[3] <= generate_crc_reg2[2];
generate_crc_reg2[4] <= generate_crc_reg2[3];
generate_crc_reg2[5] <= generate_crc_reg2[4] ^ in_serial_data[2] ^ generate_crc_reg2[15];
generate_crc_reg2[6] <= generate_crc_reg2[5];
generate_crc_reg2[7] <= generate_crc_reg2[6];
generate_crc_reg2[8] <= generate_crc_reg2[7];
generate_crc_reg2[9] <= generate_crc_reg2[8];
generate_crc_reg2[10] <= generate_crc_reg2[9];
generate_crc_reg2[11] <= generate_crc_reg2[10];
generate_crc_reg2[12] <= generate_crc_reg2[11] ^ in_serial_data[2] ^ generate_crc_reg2[15];
generate_crc_reg2[13] <= generate_crc_reg2[12];
generate_crc_reg2[14] <= generate_crc_reg2[13];
generate_crc_reg2[15] <= generate_crc_reg2[14];
generate_crc_reg3[0] <= in_serial_data[3] ^ generate_crc_reg3[15];
generate_crc_reg3[1] <= generate_crc_reg3[0];
generate_crc_reg3[2] <= generate_crc_reg3[1];
generate_crc_reg3[3] <= generate_crc_reg3[2];
generate_crc_reg3[4] <= generate_crc_reg3[3];
generate_crc_reg3[5] <= generate_crc_reg3[4] ^ in_serial_data[3] ^ generate_crc_reg3[15];
generate_crc_reg3[6] <= generate_crc_reg3[5];
generate_crc_reg3[7] <= generate_crc_reg3[6];
generate_crc_reg3[8] <= generate_crc_reg3[7];
generate_crc_reg3[9] <= generate_crc_reg3[8];
generate_crc_reg3[10] <= generate_crc_reg3[9];
generate_crc_reg3[11] <= generate_crc_reg3[10];
generate_crc_reg3[12] <= generate_crc_reg3[11] ^ in_serial_data[3] ^ generate_crc_reg3[15];
generate_crc_reg3[13] <= generate_crc_reg3[12];
generate_crc_reg3[14] <= generate_crc_reg3[13];
generate_crc_reg3[15] <= generate_crc_reg3[14];
end
end
end
8.比较crc16
- 在DATA_STATE_RECEIVE_END_BIT状态,对接收的crc16和自己算出来的crc16进行对比
- 不同则报错
always @(*) begin
out_receive_data_crc_error = 1'b0;
if(!in_data_width)
begin
if ((in_current_state == `DATA_STATE_RECEIVE_END_BIT) && !(crc_reg0 == generate_crc_reg0))
out_receive_data_crc_error = 1'b1;
end
else begin
if((in_current_state == `DATA_STATE_RECEIVE_END_BIT) &&
(!(crc_reg0 == generate_crc_reg0) ||
!(crc_reg1 == generate_crc_reg1) ||
!(crc_reg2 == generate_crc_reg2) ||
!(crc_reg3 == generate_crc_reg3) )
out_receive_data_crc_error = 1'b1;
end
end
边栏推荐
猜你喜欢
线上比赛相关规则补充说明
Management by objectives [14 of management]
In depth understanding of USB communication protocol
【深度学习】3分钟入门
物联网OTA技术介绍
[answer] if the app is in the foreground, the activity will not be recycled?
Click on the top of today's headline app to navigate in the middle
深入浅出图解CNN-卷积神经网络
使用OneDNS完美解决办公网络优化问题
第3章业务功能开发(用户访问项目)
随机推荐
Show progress bar above window
Face recognition attendance system based on Baidu flying plasma platform (easydl)
利用七种方法对一个文件夹里面的所有图像进行图像增强实战
深入浅出图解CNN-卷积神经网络
【信息安全法律法规】复习篇
机器视觉(1)——概述
漫画 | 宇宙第一 IDE 到底是谁?
百度地图自定义样式向右拖拽导致全球地图经度0度无法正常显示
Functions and usage of serachview
【TPM2.0原理及应用指南】 5、7、8章
Notification is the notification displayed in the status bar of the phone
如何在软件研发阶段落地安全实践
Sanxian Guidong JS game source code
Mui side navigation anchor positioning JS special effect
【信息安全法律法規】複習篇
Understanding of 12 methods of enterprise management
Cf:c. factors and powers of two [DP + sort + Select Board + select several numbers equal to the minimum number of known sums]
Self made dataset in pytoch for dataset rewriting
TaffyDB开源的JS数据库
Easy to understand [linear regression of machine learning]