当前位置:网站首页>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
边栏推荐
- Deep learning machine learning various data sets summary address
- Click on the top of today's headline app to navigate in the middle
- datepicket和timepicket,日期、时间选择器的功能和用法
- 99%的人都不知道|私有化部署还永久免费的即时通讯软件!
- 机器人工程终身学习和工作计划-2022-
- js拉下帷幕js特效显示层
- calendarview日历视图组件的功能和用法
- Robot engineering lifelong learning and work plan-2022-
- 手机版像素小鸟游js戏代码
- 本周小贴士#135:测试约定而不是实现
猜你喜欢
随机推荐
Robot engineering lifelong learning and work plan-2022-
第3章业务功能开发(用户登录)
Youth experience and career development
目标管理【管理学之十四】
深度学习机器学习各种数据集汇总地址
Numberpick的功能和用法
Mui side navigation anchor positioning JS special effect
Taffydb open source JS database
notification是显示在手机状态栏的通知
js拉下帷幕js特效显示层
Define menus using XML resource files
actionBar 导航栏学习
Main work of digital transformation
Target detection 1 -- actual operation of Yolo data annotation and script for converting XML to TXT file
Function and usage of calendar view component
Notification is the notification displayed in the status bar of the phone
TabHOST 选项卡的功能和用法
简单的loading动画
Function and usage of numberpick
2021-06-28








