当前位置:网站首页>SD_ DATA_ RECEIVE_ SHIFT_ REGISTER

SD_ DATA_ RECEIVE_ SHIFT_ REGISTER

2022-07-07 18:58:00 Eight four one one

1. Interface

  • Clock reset soft reset
  • Status signals in_current_state
  • sd The data signal from the card in_serial_data
  • Data bit width in_data_width, decision 1 Line or 4 Line transmission
  • accepted bit Count in_has_receive_bit
  • sd The data signal sent sd_fifo_wdata,
  • fifo Enable signal sd_fifo_we, At the end of collection 32bit Given after the parameter of
  • crc Report an error 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. Internal signals

I 'll talk about it later

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. Conversion of data bits

I think there are differences in the high and low positions , Here we need to bit Change the order of counting

assign sd_fifo_wdata = {
    shift_reg[7:0],shift_reg[15:8],shift_reg[23:16],shift_reg[31:24]};

4.fifo Can make sd_fifo_we

  • from out_write_receive_fifo One beat output
  • When receiving parameters (32 position ) The following is given , It is equivalent to the operation of serial to parallel
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. Parallel to serial

  • Two cases , One line and four line transmission have different shifts
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. receive crc16

  • Receive after receiving parameters crc16, It is also a series to parallel operation
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. Calculate for yourself crc16

  • The method is the same as before cmd Module crc7 similar
  • Mainly doing XOR operations
  • Remember to count together while receiving crc16

 Insert picture description here

 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. Compare crc16

  • stay DATA_STATE_RECEIVE_END_BIT state , To receive crc16 And calculated by yourself crc16 Contrast
  • Different is wrong
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
原网站

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