当前位置:网站首页>SOC_SD_DATA_FSM
SOC_SD_DATA_FSM
2022-07-05 06:37:00 【捌肆幺幺】
1.接口
- 正常的时钟复位软复位
- 从sd卡过来的in_data_ready、in_sd_data、in_data_direction
- 从fifo模块过来的sd_fifo_full
- 需要接收发送的byte以及块的数量,need_to_receive_byte、need_to_receive_block等
- 数据传输位宽in_data_width,有1线和4线传输
- 读数据超时in_read_to
- 给小弟模块的状态信号current_state、next_state
- 发送接收的bit数以及计数器
- crc状态计数receive_crc_status_counter
- 格式中间信号EZZS计数,interval_counter
- 传输结束信号out_transfer_complete、one_bk_re_end
input in_sd_clk; //clock for sd card
input hrst_n; //ahb reset signal
input in_soft_reset; //software reset
input in_data_ready; //从sd if 的data_fsm_ready传来
input sd_fifo_full;
input [3:0] in_sd_data; //data input from sd card 一般只用到[0]
input in_data_direction; //data direction 1:write 0:read
input [10:0] need_to_receive_byte; //block length
input [10:0] need_to_receive_block; //block number
input [31:0] need_to_send_byte; //block length
input [31:0] need_to_send_block; //block number
input in_data_width; //data width 1:4bit 0:1bit
input [31:0] in_read_to; //time out of read data fsm
output [3:0] current_state; //current state of data fsm
output [3:0] next_state; //next state of data fsm
output has_send_bit_counter_en;//has send bit counter enable
output [3:0] send_crc_counter; //has sent crc bits counter
output [13:0] has_send_bit; //has send data bits counter
output [1:0] receive_crc_status_counter; //has receive crc status bits counter
output [13:0] has_receive_bit; //has receive data bits counter
output out_transfer_complete; //indicate data transfer has completed
output [1:0] interval_counter; //time interval between data end bit and crc status
output out_read_to_error; //read timeout error flag 给到sd if
output one_bk_re_end;
2.状态机
①描述状态的转移
always @ (posedge in_sd_clk or negedge hrst_n) begin
if(!hrst_n)
current_state <= `CMD_STATE_STOP;
else if(!in_soft_reset)
current_state <= `CMD_STATE_STOP;
else
current_state <= next_state;
end
②组合逻辑状态跳转,并赋值相应使能
状态介绍,此模块的状态比较多,我直接简写了,反正也能看懂
- STOP :停止状态,in_data_ready高有效时进入IDLE状态
- IDLE: 读写判断状态,in_data_direction高有效时,表示host准备发送数据,WAIT_SEND状态,反之,则表示host准备接收数据,进入WAIT_RECEIVE状态
- WAIT_RECEIVE : 读操作准备状态,首先判断数据块是否满足要求,满足则跳入STATE_STOP,并给出状态信号read_to_error;最后,检测数据线data[0]是否低有效,有效则跳入RECEIVE状态,否则保持;
- RECEIVE :数据读操作处理过程,并需要判断每块byte数据是否读完,满足则跳入RECEIVE_CRC状态,否则保持;
- RECEIVE_CRC :判断每块crc数据是否读完,满足则跳入RECEIVE_END_BIT状态,否则保持;
- RECEIVE_END_BIT :首先判断数据块是否满足要求,满足则跳入STOP,不满足则跳入WAIT_RECEIVE状态;
- WAIT_SEND :数据输出等待状态,在条件fifo已被写满情况下,判断所有数据块是否发送完成,满足则跳入STOP状态,否则进行data[0]数据判断,高有效,跳入SNED_Z状态,否则保持;
- SNED_Z:不做任何数据处理,进入DATA_STATE_SNED_P状态;
- SNED_P:总线方向改变方向,进入SNED_START_BIT状态;
- SNED_START_BIT:开始数据发送状态,跳入STATE_SEND状态;
- SEND:数据发送状态,单块数据所有bit发送完成后,进入STATE_SEND_CRC状态,否则保持;
- SEND_CRC:CRC数据发送状态,完成后,跳入STATE_SEND_END_BIT;
- SEND_END_BIT:结束位发送状态,并用于数据线的方向切换(状态中间点),进入RECEIVE_CRC_STATUS状态;
- RECEIVE_CRC_STATUS:收到crc3个bit以及一个‘E’后,进入SEND_BUSY状态;
- SEND_BUSY:数据块传输结束判断状态,所有block发送结束,跳入STATE_STOP状态,停止操作。否则,进入DATA_STATE_WAIT_SEND状态,等待下一次块数据传输的开始;
在状态的跳转中还伴随着相应的使能如:
- 接收bit计数使能has_receive_bit_counter_en
- 发送bit计数使能has_send_bit_counter_en
- 接收block计数使能has_receive_block_counter_en
- 发送block计数使能has_send_block_counter_en
- 接收crc计数使能receive_crc_counter_en
- 发送crc计数使能send_crc_counter_en
- 读超时计数使能read_resp_time_counter_en
- 中间EZZS数据计数使能interval_counter_en
- 接收crc状态计数receive_crc_status_counter_en
- 一次传输完成信号out_transfer_complete
always @(*) begin
out_read_to_error = 1'b0;
case (current_state)
`DATA_STATE_STOP: //0
begin
has_receive_bit_counter_en = 1'b0;
has_send_bit_counter_en = 1'b0;
has_receive_block_counter_en = 1'b0;
has_send_block_counter_en = 1'b0;
receive_crc_counter_en = 1'b0;
read_resp_time_counter_en = 1'b0;
send_crc_counter_en = 1'b0;
interval_counter_en = 1'b0;
receive_crc_status_counter_en = 1'b0;
out_transfer_complete = 1'b0;
if(in_data_ready)
next_state = `DATA_STATE_IDLE;
else
next_state = `DATA_STATE_STOP;
end
`DATA_STATE_IDLE: //1
//IDLE状态判断读/写sd,进入读写等待状态
begin
has_receive_bit_counter_en = 1'b0;
has_send_bit_counter_en = 1'b0;
has_receive_block_counter_en = 1'b0;
has_send_block_counter_en = 1'b0;
receive_crc_counter_en = 1'b0;
read_resp_time_counter_en = 1'b0;
send_crc_counter_en = 1'b0;
interval_counter_en = 1'b0;
receive_crc_status_counter_en = 1'b0;
out_transfer_complete = 1'b0;
if(!in_data_direction)
next_state = `DATA_STATE_WAIT_RECEIVE;
else
next_state = `DATA_STATE_WAIT_SEND;
end
`DATA_STATE_WAIT_RECEIVE: //2
//数据等待接收状态:所有blcok收完STOP;读超时STOP;
//接收到数据的开始位data[0]==0,进入数据接收模式
begin
has_receive_bit_counter_en = 1'b0;
has_send_bit_counter_en = 1'b0;
has_receive_block_counter_en = 1'b0;
has_send_block_counter_en = 1'b0;
receive_crc_counter_en = 1'b0;
read_resp_time_counter_en = 1'b0;
send_crc_counter_en = 1'b0;
interval_counter_en = 1'b0;
receive_crc_status_counter_en = 1'b0;
if (has_receive_block == need_to_receive_block)
begin
next_state = `DATA_STATE_STOP;
out_transfer_complete = 1'b1;
end
else if (read_resp_time_counter == in_read_to)
begin
next_state = `DATA_STATE_STOP;
out_read_to_error = 1'b1;
end
else begin
if(!in_sd_data[0])
next_state = `DATA_STATE_RECEIVE;
else begin
next_state = `DATA_STATE_WAIT_RECEIVE;
read_resp_time_counter_en = 1'b1;
end
end
end
`DATA_STATE_RECEIVE: //3
//数据接收状态,启用接收bit计数器,需要接收的bit全接收了
//进入接收crc的状态,
begin
//has_receive_bit_counter_en = 1'b0;
has_send_bit_counter_en = 1'b0;
has_receive_block_counter_en = 1'b0;
has_send_block_counter_en = 1'b0;
receive_crc_counter_en = 1'b0;
read_resp_time_counter_en = 1'b0;
send_crc_counter_en = 1'b0;
interval_counter_en = 1'b0;
receive_crc_status_counter_en = 1'b0;
out_transfer_complete = 1'b0;
if(!in_data_width) begin
if (has_receive_bit == need_to_receive_bit - 1)
begin
next_state = `DATA_STATE_RECEIVE_CRC;
has_receive_bit_counter_en = 1'b0;
end
else begin
next_state = `DATA_STATE_RECEIVE;
has_receive_bit_counter_en = 1'b1;
end
end
else begin
if (has_receive_bit_4 == (need_to_receive_bit_4 - 1))
begin
next_state = `DATA_STATE_RECEIVE_CRC;
has_receive_bit_counter_en = 1'b0;
end
else begin
next_state = `DATA_STATE_RECEIVE;
has_receive_bit_counter_en = 1'b1;
end
end
end
`DATA_STATE_RECEIVE_CRC: //4
//接收crc状态,启用接收crc计数器,接收完成进入,接收end_bit状态
begin
has_receive_bit_counter_en = 1'b0;
has_send_bit_counter_en = 1'b0;
has_receive_block_counter_en = 1'b0;
has_send_block_counter_en = 1'b0;
//receive_crc_counter_en = 1'b0;
read_resp_time_counter_en = 1'b0;
send_crc_counter_en = 1'b0;
interval_counter_en = 1'b0;
receive_crc_status_counter_en = 1'b0;
out_transfer_complete = 1'b0;
if(receive_crc_counter == 15) begin
next_state =`DATA_STATE_RECEIVE_END_BIT;
receive_crc_counter_en = 1'b0;
end
else begin
next_state = `DATA_STATE_REVEIVE_CRC;
receive_crc_counter_en = 1'b1;
end
end
`DATA_STATE_RECEIVE_END_BIT: //5
//接收end_bit,全部block接收完则回到STOP
//否则blcok计数器启用,调到等待接收,启用被释放,相当于block计数只加了1
begin
has_receive_bit_counter_en = 1'b0;
has_send_bit_counter_en = 1'b0;
//has_receive_block_counter_en = 1'b0;
has_send_block_counter_en = 1'b0;
receive_crc_counter_en = 1'b0;
read_resp_time_counter_en = 1'b0;
send_crc_counter_en = 1'b0;
interval_counter_en = 1'b0;
receive_crc_status_counter_en = 1'b0;
out_transfer_complete = 1'b0;
if(has_receive_block == (need_to_receive_block - 1)) begin
next_state = `DATA_STATE_STOP;
has_receive_block_counter_en = 1'b0;
out_transfer_complete = 1'b1;
end
else begin
next_state = `DATA_STATE_WAIT_RECEIVE;
has_receive_block_counter_en = 1'b1;
end
end
`DATA_STATE_WAIT_SEND: //6
begin
has_receive_bit_counter_en = 1'b0;
has_send_bit_counter_en = 1'b0;
has_receive_block_counter_en = 1'b0;
has_send_block_counter_en = 1'b0;
receive_crc_counter_en = 1'b0;
read_resp_time_counter_en = 1'b0;
send_crc_counter_en = 1'b0;
interval_counter_en = 1'b0;
receive_crc_status_counter_en = 1'b0;
out_transfer_complete = 1'b0;
if(sd_fifo_full) begin
if(has_send_block == need_to_send_block)
begin
next_state = `DATA_STATE_STOP;
out_transfer_complete = 1'b1;
end
else begin
// if (!in_sd_data[0])
if (in_sd_data[0])
next_state = `DATA_STATE_WAIT_SEND;
else
next_state = `DATA_STAET_SEND_Z;
end
end
else
next_state = `DATA_STATE_WAIT_SEND;
end
`DATA_STATE_SEND: //7
//启用发送bit计数,发送完数据准备发crc,
begin
has_receive_bit_counter_en = 1'b0;
//has_send_bit_counter_en = 1'b0;
has_receive_block_counter_en = 1'b0;
has_send_block_counter_en = 1'b0;
receive_crc_counter_en = 1'b0;
read_resp_time_counter_en = 1'b0;
send_crc_counter_en = 1'b0;
interval_counter_en = 1'b0;
receive_crc_status_counter_en = 1'b0;
out_transfer_complete = 1'b0;
if (!in_data_width)
begin
if (has_send_bit == (need_send_bit - 1))
begin
next_state = `DAYA_STATE_SEND_CRC;
has_send_bit_counter_en = 1'b0;
end
else begin
next_state = `DATA_STATE_SEND;
has_send_bit_counter_en = 1'b1;
end
end
else begin
if (has_send_bit == (need_to_seed_bit_4 - 1))
begin
next_state = `DAYA_STATE_SEND_CRC;
has_send_bit_counter_en = 1'b0;
end
else begin
next_state = `DATA_STATE_SEND;
has_send_bit_counter_en = 1'b1;
end
end
end
`DATA_STATE_SEND_CRC: //8
//启用发送crc bit计数,发送完crc准备发end bit
begin
has_receive_bit_counter_en = 1'b0;
has_send_bit_counter_en = 1'b0;
has_receive_block_counter_en = 1'b0;
has_send_block_counter_en = 1'b0;
receive_crc_counter_en = 1'b0;
read_resp_time_counter_en = 1'b0;
//send_crc_counter_en = 1'b0;
interval_counter_en = 1'b0;
receive_crc_status_counter_en = 1'b0;
out_transfer_complete = 1'b0;
if (send_crc_counter == 15)
begin
next_state = `DATA_STATE_SEND_END_BIT;
send_crc_counter_en = 1'b0;
end
else begin
next_state = `DATA_STATE_SEND_CRC;
send_crc_counter_en = 1'b1;
end
end
`DATA_STATE_SEND_END_BIT: //9
//发送完endbit ,准备接收数据是否正确的信号,
//这里应该增加一个状态更好,而不是用计数的方式
begin
has_receive_bit_counter_en = 1'b0;
has_send_bit_counter_en = 1'b0;
has_receive_block_counter_en = 1'b0;
has_send_block_counter_en = 1'b0;
receive_crc_counter_en = 1'b0;
read_resp_time_counter_en = 1'b0;
send_crc_counter_en = 1'b0;
interval_counter_en = 1'b0;
receive_crc_status_counter_en = 1'b0;
out_transfer_complete = 1'b0;
//这里4个周期接收EZZS
if (interval_counter == 3)
begin
next_state = `DATA_STATE_RECEIVE_CRC_STATUS;
interval_counter_en = 1'b0;
end
else begin
next_state = `DATA_STATE_SNED_END_BIT;
interval_counter_en = 1'b1;
end
end
`DATA_STATE_RECEIVE_CRC_STATUS ://10
begin
has_receive_bit_counter_en = 1'b0;
has_send_bit_counter_en = 1'b0;
has_receive_block_counter_en = 1'b0;
has_send_block_counter_en = 1'b0;
receive_crc_counter_en = 1'b0;
read_resp_time_counter_en = 1'b0;
send_crc_counter_en = 1'b0;
interval_counter_en = 1'b0;
receive_crc_status_counter_en = 1'b0;
out_transfer_complete = 1'b0;
//这里4个周期接收status(3bit)+E
if (receive_crc_status_counter == 3)
begin
next_state = `DATA_STATE_SEND_BUSY;
receive_crc_status_counter_en = 1'b0;
end
else begin
next_state = `DATA_STATE_RECEIVE_CRC_STATUS;
receive_crc_status_counter_en = 1'b1;
end
end
`DATA_STATE_SEND_BUSY: //11
//数据块传输结束判断状态,所有block发送结束,
//跳入STATE_STOP状态,停止操作。
//否则,进入DATA_STATE_WAIT_SEND状态,等待下一次块数据传输的开始。
begin
has_receive_bit_counter_en = 1'b0;
has_send_bit_counter_en = 1'b0;
has_receive_block_counter_en = 1'b0;
//has_send_block_counter_en = 1'b0;
receive_crc_counter_en = 1'b0;
read_resp_time_counter_en = 1'b0;
send_crc_counter_en = 1'b0;
interval_counter_en = 1'b0;
receive_crc_status_counter_en = 1'b0;
out_transfer_complete = 1'b0;
if (has_send_block == (need_to_send_block - 1))
begin
next_state = `DATA_STATE_STOP;
has_send_block_counter_en = 1'b0;
out_transfer_complete = 1'b1;
end
else begin
next_state = `DATA_STATE_WAIT_SEND;
has_send_block_counter_en = 1'b1;
end
end
`DATA_STATE_SEND_START_BIT: //12
begin
has_receive_bit_counter_en = 1'b0;
has_send_bit_counter_en = 1'b0;
has_receive_block_counter_en = 1'b0;
has_send_block_counter_en = 1'b0;
receive_crc_counter_en = 1'b0;
read_resp_time_counter_en = 1'b0;
send_crc_counter_en = 1'b0;
interval_counter_en = 1'b0;
receive_crc_status_counter_en = 1'b0;
out_transfer_complete = 1'b0;
next_state = `DATA_STATE_SEND;
end
`DATA_STATE_SEND_Z:
begin
has_receive_bit_counter_en = 1'b0;
has_send_bit_counter_en = 1'b0;
has_receive_block_counter_en = 1'b0;
has_send_block_counter_en = 1'b0;
receive_crc_counter_en = 1'b0;
read_resp_time_counter_en = 1'b0;
send_crc_counter_en = 1'b0;
interval_counter_en = 1'b0;
receive_crc_status_counter_en = 1'b0;
out_transfer_complete = 1'b0;
next_state = `DATA_STATE_SEND_P;
end
`DATA_STATE_SEND_P:
begin
has_receive_bit_counter_en = 1'b0;
has_send_bit_counter_en = 1'b0;
has_receive_block_counter_en = 1'b0;
has_send_block_counter_en = 1'b0;
receive_crc_counter_en = 1'b0;
read_resp_time_counter_en = 1'b0;
send_crc_counter_en = 1'b0;
interval_counter_en = 1'b0;
receive_crc_status_counter_en = 1'b0;
out_transfer_complete = 1'b0;
next_state = `DATA_STATE_SEND_START_BIT;
end
default:
begin
has_receive_bit_counter_en = 1'b0;
has_send_bit_counter_en = 1'b0;
has_receive_block_counter_en = 1'b0;
has_send_block_counter_en = 1'b0;
receive_crc_counter_en = 1'b0;
read_resp_time_counter_en = 1'b0;
send_crc_counter_en = 1'b0;
interval_counter_en = 1'b0;
receive_crc_status_counter_en = 1'b0;
out_transfer_complete = 1'b0;
next_state = `DATA_STATE_STOP;
end
endcase
end
3.one_bk_re_end的产生
- 在DATA_STATE_RECEIVE_END_BIT状态给one_bk_re_end_tp 置1
- 将one_bk_re_end_tp打一拍给到one_bk_re_end 输出,可以保证时序
assign one_bk_re_end_tp = (current_state == `DATA_STATE_RECEIVE_END_BIT);
always @(posedge in_sd_clk or negedge hrst_n) begin
if (!hrst_n)
one_bk_re_end <= 1'b0;
else
one_bk_re_end <= one_bk_re_end_tp;
4.一些计数器
- has_receive_bit计数
always @(posedge in_sd_clk or negedge hrst_n) begin
if (!hrst_n)
has_receive_bit <= 14'b0;
else if (!in_soft_reset)
has_receive_bit <= 14'b0;
else if (current_state == `DATA_STATE_RECEIVE_CRC)
has_receive_bit <= 14'b0;
else if (has_receive_bit == (need_to_send_block - 1))
has_receive_bit <= 14'b0;
else if (has_receive_bit_counter_en)
has_receive_bit <= has_receive_bit + 1;
end
- read_resp_time_counter计数
always @(posedge in_sd_clk or negedge hrst_n) begin
if (!hrst_n)
read_resp_time_counter <= 32'b0;
else if (!in_soft_reset)
read_resp_time_counter <= 32'b0;
else if (current_state == `DATA_STATE_STOP)
read_resp_time_counter <= 32'b0;
else if (read_resp_time_counter == in_read_to)
read_resp_time_counter <= 32'b0;
else if (read_resp_time_counter_en)
read_resp_time_counter <= read_resp_time_counter + 1;
end
- has_send_bit 计数
always @(posedge in_sd_clk or negedge hrst_n) begin
if (!hrst_n)
has_send_bit <= 14'b0;
else if (!in_soft_reset)
has_send_bit <= 14'b0;
else if (current_state == `DATA_STATE_SEND_CRC)
has_send_bit <= 14'b0;
else if (has_send_bit_counter_en)
has_send_bit <= has_send_bit + 1;
end
- receive_crc_counter
always @(posedge in_sd_clk or negedge hrst_n) begin
if (!hrst_n)
receive_crc_counter <= 14'b0;
else if (!in_soft_reset)
receive_crc_counter <= 14'b0;
else if (receive_crc_counter == 15)
receive_crc_counter <= 14'b0;
else if (receive_crc_counter_en)
receive_crc_counter <= receive_crc_counter + 1;
end
- has_receive_block
always @(posedge in_sd_clk or negedge hrst_n) begin
if (!hrst_n)
has_receive_block <= 32'b0;
else if (!in_soft_reset)
has_receive_block <= 32'b0;
else if (current_state == `DATA_STATE_STOP)
has_receive_block <= 32'b0;
else if (has_receive_block_counter_en)
has_receive_block <= has_receive_block + 1;
end
- has_send_block
always @(posedge in_sd_clk or negedge hrst_n) begin
if (!hrst_n)
has_send_block <= 32'b0;
else if (!in_soft_reset)
has_send_block <= 32'b0;
else if (current_state == `DATA_STATE_STOP)
has_send_block <= 32'b0;
else if (has_send_block_counter_en)
has_send_block <= has_send_block + 1;
end
- interval_counter
always @(posedge in_sd_clk or negedge hrst_n) begin
if (!hrst_n)
interval_counter <= 2'b0;
else if (!in_soft_reset)
interval_counter <= 2'b0;
else if (interval_counter == 3)
interval_counter <= 2'b0;
else if (interval_counter_en)
interval_counter <= interval_counter + 1;
end
- receive_crc_status_counter
always @(posedge in_sd_clk or negedge hrst_n) begin
if (!hrst_n)
receive_crc_status_counter <= 2'b0;
else if (!in_soft_reset)
receive_crc_status_counter <= 2'b0;
else if (receive_crc_status_counter == 3)
receive_crc_status_counter <= 14'b0;
else if (receive_crc_status_counter_en)
receive_crc_status_counter <= receive_crc_status_counter + 1;
end
- send_crc_counter
always @(posedge in_sd_clk or negedge hrst_n) begin
if (!hrst_n)
send_crc_counter <= 14'b0;
else if (!in_soft_reset)
send_crc_counter <= 14'b0;
else if (send_crc_counter == 15)
send_crc_counter <= 14'b0;
else if (send_crc_counter_en)
send_crc_counter <= send_crc_counter + 1;
end
边栏推荐
- Vant Weapp SwipeCell設置多個按鈕
- 1. Create Oracle database manually
- Relevant information of National Natural Science Foundation of China
- ROS2——功能包(六)
- Some classic recursion problems
- Genesis builds a new generation of credit system
- kata container
- Knapsack problem acwing 9 Group knapsack problem
- Log4qt usage of logbase in QT project
- H5 embedded app adapts to dark mode
猜你喜欢
Utf8 encoding
UTC, GPS time and Tai
Find the combination number acwing 889 01 sequence meeting conditions
LSA Type Explanation - lsa-1 [type 1 LSA - router LSA] detailed explanation
ROS2——功能包(六)
Sum of two numbers, the numbers in the array are converted to decimal, added, and output inversely
VLAN experiment
Orin two brushing methods
Record of problems in ollvm compilation
What is linting
随机推荐
In C language, int a= 'R'
6-3 find the table length of the linked table
‘mongoexport‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。
2022-5-the fourth week daily
. Net core stepping on the pit practice
LSA Type Explanation - detailed explanation of lsa-2 (type II LSA network LSA) and lsa-3 (type III LSA network Summary LSA)
Vant weapp swippecell set multiple buttons
PR automatically moves forward after deleting clips
时间很快,请多做有意义的事情
Page type
Marvell 88e1515 PHY loopback mode test
3. Oracle control file management
2048 project realization
ROS2——功能包(六)
Orin 两种刷机方式
Build a microservice cluster environment locally and learn to deploy automatically
在新线程中使用Handler
Redis-01. First meet redis
Huawei bracelet, how to add medicine reminder?
Ret2xx---- common CTF template proposition in PWN