当前位置:网站首页>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
边栏推荐
- 【可信计算】第十三次课:TPM扩展授权与密钥管理
- 本周小贴士#134:make_unique与私有构造函数
- Dragging the custom style of Baidu map to the right makes the global map longitude 0 unable to be displayed normally
- 百度地图自定义样式向右拖拽导致全球地图经度0度无法正常显示
- In depth understanding of USB communication protocol
- 【可信计算】第十二次课:TPM授权与会话
- Dateticket and timeticket, functions and usage of date and time selectors
- Management by objectives [14 of management]
- viewflipper的功能和用法
- Enum + Validation 的个人最佳实践 demo 分享
猜你喜欢
随机推荐
【TPM2.0原理及应用指南】 1-3章
第2章搭建CRM项目开发环境(数据库设计)
深度学习机器学习各种数据集汇总地址
Mysql 索引命中级别分析
Machine vision (1) - Overview
Deep learning - make your own dataset
notification是显示在手机状态栏的通知
Import requirements in batches during Yolo training Txt
mui侧边导航锚点定位js特效
深入浅出【机器学习之线性回归】
Cf:c. factors and powers of two [DP + sort + Select Board + select several numbers equal to the minimum number of known sums]
基于PyTorch利用CNN对自己的数据集进行分类
VSCode关于C语言的3个配置文件
Notification is the notification displayed in the status bar of the phone
企业经营12法的领悟
【网络攻防原理与技术】第3章:网络侦察技术
Dateticket and timeticket, functions and usage of date and time selectors
原生js验证码
actionBar 导航栏学习
Youth experience and career development