当前位置:网站首页>SOC_SD_CMD_FSM
SOC_SD_CMD_FSM
2022-07-05 06:37:00 【捌肆幺幺】
1.状态机流程图

- CMD_STATE_STOP:空闲中
- CMD_STATE_WAIT_SEND:等待发送中
- CMD_STATE_SEND:发送中
- CMD_STATE_WAIT_RECEIVE:等待接收中
- CMD_STATE_RECEIVE:接收中
2.接口描述
- 时钟复位软复位
- 响应类型有两种,R2响应是较长的in_longresponse,其他都是in_response
- 驱动状态机开始工作的in_command_ready信号
- sd卡过来的数据信号in_sd_dat以及命令信号in_sd_cmd
- 给到两个小弟模块的收发信号has_send_bit、has_receive_bit以及状态机当前状态current_state
- 给回sd卡的响应反馈信号end_command、end_command_and_response、response_timeout
input in_sd_clk;
input in_soft_reset;
input hrst_n;
//sd if
input in_longresponse;
input in_response;
input in_command_ready;
//sd bus (sd card)
input [3:0] in_sd_dat;
input in_sd_cmd;
//给到两个小弟模块
output [2:0] current_state;
output [5:0] has_send_bit;
output [7:0] has_receive_bit;
//返回sd if
output end_command;
output end_command_and_response;
output response_timeout;
3.响应位数选择
- 长响应R2是136bit,而短响应是48bit
assign need_to_receive_bit = in_longresponse ? 8'd136 : 8'd47; // Use to compare with has received bits
4. 三段式状态机
①第一段描述次态迁移,默认状态是CMD_STATE_STOP
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
②状态机第二段,用组合逻辑描述状态转移,根据上面的状态转移图完成相应转移
always @(*) begin
case (current_state)
`CMD_STATE_STOP:
if (in_command_ready)
next_state = `CMD_STATE_WAIT_SEND;
else
next_state = current_state;
`CMD_STATE_WAIT_SEND:
if (in_sd_dat[0])
next_state = `CMD_STATE_SEND;
else
next_state = current_state;
`CMD_STATE_SEND:
if (has_send_bit != 47)
next_state = `CMD_STATE_SEND;
else if (!in_response)
next_state = `CMD_STATE_STOP;
else
next_state = `CMD_STATE_WAIT_RECEIVE;
`CMD_SEND_WAITE_RECEIVE:
if(resp_time == 7'b0111111)
next_state = `CMD_STATE_STOP;
else if (!in_sd_cmd)
next_state = `CMD_STATE_RECEIVE;
else
next_state = `CMD_SEND_WAITE_RECEIVE;
`CMD_STATE_RECEIVE:
if(has_receive_bit == (need_to_receive_bit - 1))
next_state = `CMD_STATE_STOP;
else
next_state = `CMD_STATE_RECEIVE;
default: next_state = `CMD_STATE_STOP;
endcase
end
③状态机第三段,描述每个状态执行什么操作,主要有以下信号的赋值
- has_send_bit:已经发送的bit数
- receive_bit_counter_en:接收bit计数器使能
- resp_time_counter_en:等待超时计数器使能
- end_command_and_response:有响应的命令整个周期结束信号
- end_command:无响应的命令整个周期结束信号
- response_timeout:等待超时信号
always @(*) begin
case (current_state)
`CMD_STATE_STOP:
begin
has_send_bit = 1'b0;
receive_bit_counter_en = 1'b0;
resp_time_counter_en = 1'b0;
end_command_and_response = 1'b0;
end_command = 1'b0;
response_timeout =1'b0;
end
`CMD_STATE_WAIT_SEND:
begin
has_send_bit = 1'b0;
receive_bit_counter_en = 1'b0;
resp_time_counter_en = 1'b0;
end_command_and_response = 1'b0;
end_command = 1'b0;
response_timeout =1'b0;
end
`CMD_STATE_SEND:
begin
receive_bit_counter_en = 1'b0;
resp_time_counter_en = 1'b0;
end_command_and_response = 1'b0;
end_command = 1'b0;
response_timeout =1'b0;
if (has_send_bit !=47)
begin
send_bit_counter_en = 1'b1;
next_state = `CMD_STATE_SEND;
end
else
begin
if(!in_response)
begin
next_state = `CMD_STATE_STOP;
send_bit_counter_en = 1'b0 ;
end_command_and_response= 1'b1;
end_command = 1'b1;
end
else
begin
next_state =`CMD_STATE_WAIT_RECEIVE;
send_bit_counter_en = 1'b0;
end_command = 1'b1 ;
end
end
end
`CMD_SEND_WAITE_RECEIVE:
begin
end_command = 1'b1;
send_bit_counter_en = 1'b0;
receive_bit_counter_en = 1'b0;
resp_time_counter_en = 1'b0;
end_command_and_response = 1'b0;
response_timeout =1'b0;
if(resp_time == 7'b0111111)
response_timeout = 1'b1;
else if (!in_sd_cmd)
resp_time_counter_en = 1'b0;
else
resp_time_counter_en = 1'b1;
end
`CMD_STATE_RECEIVE:
begin
send_bit_counter_en = 1'b0;
resp_time_counter_en = 1'b0;
end_command = 1'b1;
end_command_and_response = 1'b0;
response_timeout = 1'b0;
if(has_receive_bit == (need_to_receive_bit - 1))
begin
end_command_and_response = 1'b1;
receive_bit_counter_en = 1'b0;
end
else
receive_bit_counter_en = 1'b1;
end
default:
begin
has_send_bit = 1'b0;
receive_bit_counter_en = 1'b0;
resp_time_counter_en = 1'b0;
end_command_and_response = 1'b0;
end_command = 1'b0;
response_timeout =1'b0;
end
endcase
end
5.对应的3个计数器
- 发送计数
- 接收计数
- 超时计数
always @(posedge in_sd_clk or negedge hrst_n) begin
if(!hrst_n)
has_send_bit <= 6'b0;
else if(!in_soft_reset)
has_send_bit <= 6'b0;
else
begin
if(has_send_bit == 47)
has_send_bit <= 6'b0;
else if (send_bit_counter_en == 1'b1)
has_send_bit <= has_send_bit + 1;
end
end
always @(posedge in_sd_clk or negedge hrst_n) begin
if(!hrst_n)
has_receive_bit <= 8'b0;
else if (!in_soft_reset)
has_receive_bit <= 8'b0;
else begin
if(has_receive_bit == (need_to_receive_bit - 1))
has_receive_bit <= 8'b0;
else if (receive_bit_counter_en == 1'b1)
has_receive_bit <= has_receive_bit + 1;
end
end
always @(posedge in_sd_clk or negedge hrst_n) begin
if(!hrst_n)
resp_time <= 7'b0;
else if (!in_soft_reset)
resp_time <= 7'b0;
else if( current_state == `CMD_STATE_RECEIVE)
resp_time <= 7'b0;
else if (resp_time == 63)
resp_time <= 7'b0;
else if (resp_time_counter_en == 1'b1)
resp_time <= resp_time + 1;
end
边栏推荐
猜你喜欢

VLAN experiment

Qt项目中的日志库log4qt使用

Vant weapp swippecell set multiple buttons

Vant weave swipecell sets multiple buttons

Instruction execution time

Find the combination number acwing 889 01 sequence meeting conditions

Genesis builds a new generation of credit system

Adg5412fbruz-rl7 applies dual power analog switch and multiplexer IC

在本地搭建一个微服务集群环境,学习自动化部署

摄像头的MIPI接口、DVP接口和CSI接口
随机推荐
Vant Weapp SwipeCell設置多個按鈕
Some classic recursion problems
Chinese remainder theorem acwing 204 Strange way of expressing integers
Vscode editor
Time is fast, please do more meaningful things
vsCode创建自己的代码模板
Redis-02. Redis command
The problem of Chinese garbled code in the vscode output box can be solved once for life
Markdown syntax
Paper reading report
GDB code debugging
UTC, GPS time and Tai
Vant Weapp SwipeCell设置多个按钮
微信小程序路由再次跳轉不觸發onload
Game theory acwing 892 Steps Nim game
[nvidia] CUDA_ VISIBLE_ DEVICES
Skywalking全部
Use ffmpeg to rotate, flip up and down, and flip horizontally
2022-5-the fourth week daily
Vant weapp swippecell set multiple buttons