当前位置:网站首页>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

原网站

版权声明
本文为[捌肆幺幺]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_38502780/article/details/125580035