当前位置:网站首页>SD_ CMD_ SEND_ SHIFT_ REGISTER

SD_ CMD_ SEND_ SHIFT_ REGISTER

2022-07-05 07:07:00 Eight four one one

1. Interface

  • Normal clock reset soft reset
  • eldest brother cmd_fsm The current status signal sent in_current_state
  • Sent bit Count in_has_send_bit
  • from sd The command signal from the card in_command_index、 Parameter signal in_command_argument
  • And high-speed clock signals in_high_speed_clk, It will be different from ordinary
  • Give to the sd Card command signal out_sd_cmd
  • similar pad Of oen The signal out_cmd_dir Direction signal ,1 Issued by the representative sd card
input           in_sd_clk;
input           hrst_n;
input           in_soft_reset;

//from fsm
input [2:0]     in_current_state;
input [5:0]     in_has_send_bit;

//from sd if
input [5:0]     in_command_index;
input [31:0]    in_command_argument;
input           in_high_speed_clk;


output          out_sd_cmd;
output          out_cmd_dir;

2. Transmission direction out_cmd_dir

  • Select the rising edge according to whether to use the high-speed clock cmd_dir_pos Or the falling edge cmd_dir_neg transmission
  • cmd_dir_neg Than cmd_dir_pos Delay half a cycle
always @(posedge in_sd_clk or negedge hrst_n) begin
    if(!hrst_n)
        cmd_dir_pos <= 1'b0;
	else if (in_current_state == `CMD_STATE_SEND)
		cmd_dir_pos <= 1'b1;
	else if (in_current_state == `CMD_STATE_STOP)
		cmd_dir_pos <= 1'b0;
	else if (in_current_state == `CMD_STATE_WAIT_RECEIVE)
		cmd_dir_pos <= 1'b0;
end

always @(negedge in_sd_clk or negedge hrst_n) begin
    if(!hrst_n)
        cmd_dir_neg <= 1'b0;
    else
        cmd_dir_neg <= cmd_dir_pos;
end

assign out_cmd_dir = in_high_speed_clk ? cmd_dir_pos : cmd_dir_neg;

3. Command generation cmd_for_send

  • stay SEND According to the sent bit Count in_has_send_bit Give the corresponding command
  • The format of the command is as follows : common 48 position need 6bit
  • Use case Give each one separately bit At the time of the cmd_for_send assignment
  • Only to argument( Parameters ), After that crc、 The end bit is not given
  • If the combinational logic is not written completely, a latch will be generated latch, So let... At the beginning cmd_for_send by 0
     Insert picture description here
always @(*) begin
    cmd_for_send = 8'b0;
    if (in_current_state == `CMD_STATE_SEND)
        begin
            case(in_has_send_bit)
                6'b0,6'b1,6'b10,6'b11,6'b100,6'b101,6'b110,6'b111:
                    cmd_for_send = {
    1'b0,1'b1,in_command_index};
                6'b001000,6'b001001,6'b001010,6'b001011,6'b001100,6'b001101,6'b001110,6'b001111:
                    cmd_for_send = {
    in_command_argument[31:24]};
                6'b010000,6'b010001,6'b010010,6'b010011,6'b010100,6'b010101,6'b010110,6'b010111:
                    cmd_for_send = {
    in_command_argument[23:16]};
                6'b011000,6'b011001,6'b011010,6'b011011,6'b011100,6'b011101,6'b011110,6'b011111:
                    cmd_for_send = {
    in_command_argument[15:8]};
                6'b100000,6'b100001,6'b100010,6'b100011,6'b100100,6'b100101,6'b100110,6'b100111:
                    cmd_for_send = {
    in_command_argument[7:0]};
            endcase
        end
end

4. Command output out_sd_cmd

  • Select the rising edge output according to whether to use the high-speed clock sd_cmd_pos Or the falling edge output sd_cmd_neg
  • sd_cmd_neg Than sd_cmd_pos It's still half a beat slow
  • Because the board level path is long , If it's all combinatorial logic pos The establishment time may not be satisfied , Then moving for half a cycle may be enough
  • Parallel to serial conversion with shift register ,in_has_send_bit[2:0] == 3’b0 No 8bit Enter case Take the data from the library
always @(posedge in_sd_clk or negedge hrst_n) begin
    if(!hrst_n)
        begin
            sd_cmd_pos <= 1'b1;
            shift_r <= 8'b0;
        end
    else if(!in_soft_reset)
        begin
            sd_cmd_pos <= 1'b1;
            shift_r <= 8'b0;
        end
    else
        begin
            if(in_current_state == `CMD_STATE_SEND)
                begin
                    if(in_has_send_bit[2:0] == 3'b0)
                        begin
                            case(in_has_send_bit)
                                6'b000000:
                                    {
    sd_cmd_pos,shift_r} <= {
    1'b0,1'b1,in_command_index,1'b0};
                                6'b001000:
                                    {
    sd_cmd_pos,shift_r} <= {
    in_command_argument[31:24],1'b0};
                                6'b010000:
                                    {
    sd_cmd_pos,shift_r} <= {
    in_command_argument[23:16],1'b0};
                                6'b011000:
                                    {
    sd_cmd_pos,shift_r} <= {
    in_command_argument[15:8],1'b0};
                                6'b100000:
                                    {
    sd_cmd_pos,shift_r} <= {
    in_command_argument[7:0],1'b0};
								6'b101000:
                                    {
    sd_cmd_pos,shift_r} <= {
    crc_reg,1'b1,1'b0};
                            endcase
                        end
                    else
                        {
    sd_cmd_pos,shift_r} <= {
    shift_r,1'b0};
                end
        end
end

always @(negedge in_sd_clk or negedge hrst_n) begin
    if (!hrst_n)
        sd_cmd_neg <= 1'b0;
    else
        sd_cmd_neg <= sd_cmd_pos;
end

assign out_sd_cmd = in_high_speed_clk ? sd_cmd_pos : sd_cmd_neg;

5. Calculation crc7

  • Calculation crc7, And pass out_sd_cmd Send to sd card
  • Calculation crc7 Methods :[0] and [3] These two bits need to be XOR , Other shifts are ok , See the picture below
     Insert picture description here
always @(posedge in_sd_clk or negedge hrst_n) begin
    if(!hrst_n)
        crc_reg <= 7'b0;
    else if (!in_soft_reset)
        crc_reg <= 7'b0;
    else
        if((in_current_state == `CMD_STATE_SEND) &&
            (in_has_send_bit >= 6'b0)            &&
            (in_has_send_bit < 6'd40))
        begin
            crc_reg[0] <= cmd_for_send[in_has_send_bit[2:0]]^crc_reg[6];
            crc_reg[1] <= crc_reg[0];
            crc_reg[2] <= crc_reg[1];
            crc_reg[3] <= cmd_for_send[in_has_send_bit[2:0]]^crc_reg[6]^crc_reg[2];
            crc_reg[4] <= crc_reg[3];
            crc_reg[5] <= crc_reg[4];
            crc_reg[6] <= crc_reg[5];
        end
        else
            crc_reg <= 7'b0;
end
原网站

版权声明
本文为[Eight four one one]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/186/202207050637248983.html