AHB_Slave(SD_INTERFACE)部分代码 未完待续

 

AHB_SLAVE(SD_IF)部分代码如下:

module sd_if (
//-- ahb 
    input              hclk;
    input              hrst_n;
    input              hsl;
    input              hwrite;//1->write      0->read
    input       [1:0]  htrans; //4种 idel busy seq nonseq
    input       [2:0]  hburst;//8种 singal incr beat4/8/16 wrap4/8/16
    input  reg  [31:0] hwdata;//
    input       [31:0] haddr;
    input       [2:0]  hsize;//bus的宽度
    input              hready_in;//所有slave为高,hready_in才为高
    output             hready_out;//内部是否在忙,忙为0
    output      [1:0]  hresp;
    output      [31:0] hrdata;

//-- host_dma
    output reg         dma_en;
    output reg         dma_direc;//判断是从ahb->fifo还是从sd_fifo->ahb外部
    output reg  [15:0] transfer_size;//DMA这次搬多少
    output reg  [31:0] dma_addr;//若从外面搬,dma_addr是起始地址;往外面搬,dma_addr是目标地址。

    output reg         fifo_full_int_gen;
    output reg         fifo_empty_int_gen;
    output reg         dma_finish_int_gen;
    output reg         clr_fifo_full_int;
    output reg         clr_fifo_empty_int;
    output reg         clr_dma_finish_int;
    input              clr_dma_en;
    input              fifo_full_int;
    input              fifo_empty_int;
    input              dma_finish_int;

    input       [31:0] response0;//cmd给的response
    input       [31:0] response1;
    input       [31:0] response2;
    input       [31:0] response3;
    input              in_sd_clk;
    input              sd_fifo_empty;
    input              sd_fifo_full;
    input              sd_fifo_re;

    input              in_end_command;
    input              in_end_command_and_response;
    input              in_transfer_complete;
    input              in_send_data_crc_error;
    input              in_receive_data_crc_error;
    input              in_response_timeout;
    input              in_cmd_current_state;//当前cmd状态
    input              in_read_to_error;
    input              one_bk_re_end;
    output reg         sd_clk_enable;
    output reg         hw_stop_clk;
    output reg  [7:0]  sd_clk_divider;
    output reg         sd_soft_reset;
    output reg         high_speed_clk;
//  output reg         read_acce_option;
    output reg  [31:0] command_argument;
    output reg  [5:0]  command_index;
    output reg  [10:0] block_size;//需要发送多少个block
    output reg  [10:0] block_len;//一个block有多少byte
    output             sd_op_finish;
    output reg  [31:0] block_number;
    output reg         data_direction;
    output reg         data_width;
    output reg  [31:0] read_to;//read_timeout
    output             irq;
    output reg         out_response;//48bit
    output reg         out_longresponse;//136bit
    output reg         cmd_fsm_ready;
    output             data_fsm_ready;
);

    reg                hw_stop_clk_en;
    reg                command_enable;
    reg                data_present;
    reg         [1:0]  response_type;
    reg         [10:0] block_len_r;
    reg                read_to_error;
    reg                dma_finish_interrupt_mask;
    reg                end_command_and_response_interrupt_mask;
    reg                sd_fifo_empty_interrupt_mask;
    reg                fifo_full_interrpt_mask;
    reg                fifo_empty_interrupt_mask;
    reg                sd_fifo_full_interrupt_mask;
    reg                command_complete_interrupt_mask;
    reg                transfer_complete_interrupt_mask;
    reg                read_to_error_interrupt_mask;
    reg                rx_fifo_write_error_interrupt_mask;
    reg                tx_fifo_read_error_interrupt_mask;
    reg                read_data_crc_error_interrupt_mask;
    reg                write_data_crc_error_interrupt_mask;
    reg                response_timeout_error_interrupt_mask;

    reg                sd_fifo_empty_r;
    reg                       sd_fifo_full_r;
    reg                end_command;
    reg                transfer_complete;
    reg                 send_data_crc_error;
    reg                receive_data_crc_error;
    reg                response_timeout;              
    reg                end_command_and_response;

//-- internal register
    reg                hwrite_r;
    reg         [2:0]  hsize_r;
    reg         [2:0]  hburst_r;
    reg         [1:0]  htrans_r;
    reg         [31:0] haddr_r;

    reg                dma_end_tp;
    reg                dma_end;
    reg                dma_end_r;
    
    reg                cmd_ready_pre;

    reg         [31:0] block_number_ahb;
    reg         [31:0] block_num_tp;
    reg                one_bk_re_end_tp_1;
    reg                one_bk_re_end_tp_2;
    reg                one_bk_re_end_tp_3;
    reg                cmd_state_send_tp1;
    reg                cmd_state_send_tp2;
    reg                cmd_state_send_tp3;
    reg                in_end_cmd_and_resp_tp_1;
    reg                in_end_cmd_and_resp_tp_2;
    reg                in_end_cmd_and_resp_tp_3;
    reg                sd_fifo_empty_tp1;
    reg                in_end_cmd_tp_1;
    reg                in_end_cmd_tp_2;
    reg                in_end_cmd_tp_3;
    reg                in_transfer_end_tp_1;
    reg                in_transfer_end_tp_2;
    reg                in_transfer_end_tp_3;
    reg                in_rd_to_err_tp_1;
    reg                in_rd_to_err_tp_2;
    reg                in_rd_to_err_tp_3;
    reg                in_send_data_crc_err_tp_1;
    reg                in_send_data_crc_err_tp_2;
    reg                in_send_data_crc_err_tp_3;
    reg                in_receive_data_crc_err_tp_1;
    reg                in_receive_data_crc_err_tp_2;
    reg                in_receive_data_crc_err_tp_3;
    reg                in_resp_timeout_tp_1;
    reg                in_resp_timeout_tp_2;
    reg                in_resp_timeout_tp_3;
    reg         [31:0] response0_ahb;
    reg         [31:0] response1_ahb;
    reg         [31:0] response2_ahb;
    reg         [31:0] response3_ahb;
    wire               cmd_state_send;
    wire               ahb_wr_reg_en;
    wire               ahb_rd_reg_en;

// Generate AHB hready_out and hresp singals
// ------------------------------------------

assign hready_out = 1'b1;
assign hresp = 2'b0;

//------------------------------------------
// Register AHB bus control and Addr
// -----------------------------------------

always @ (posedge hclk) 
begin
   if(hrst_n == 0)
   begin
      hwrite_r <= 1'b0;
      hsize_r <= 3'b0;
      hburst_r <= 3'b0;
      htrans_r <= 2'b0;
      haddr_r <= 32'b0;
   end
   else if (hsel && hready_in)
   begin
      hwrite_r <= hwrite;
      hsize_r <= hsize;
      hburst_r <= hburst;
      htrans_r <= htrans;
      haddr_r <= haddr;
   end
   else 
   begin
      hwrite_r <= 1'b0;
      hsize_r <= 3'b0;
      hburst_r <= 3'b0;
      htrans_r <= 2'b0;
      haddr_r <= 32'b0;
   end
end

//-----------------------------------------
//Generate ahb_wr_reg_en and ahb_rd_reg_en
//-----------------------------------------

assign ahb_wr_reg_en = hready_in & hwrite_r & (htrans_r == 2'b10 | htrans_r == 2'b11);
assign ahb_rd_reg_en = hsel & hready_in & !hwrite & (htrans == 2'b0 | htrans == 2'b11);

//-----------------------------------------
//Generate block_length for fifo
//-----------------------------------------

always @ (posedge in_sd_clk or negedge hrst_n)
begin
    if (hrst_n == 0)
    begin
       block_len <= 11'd200;
       block_len_r <= 11'd200;
    end
    else
    begin
       block_len_r <= block_size;
       block_len <= block_len_r;
    end
end

//--------------------------------------------
//DMA control operation
//DMA_CTRL_ADDR : [0] dma_en
//                [4] dma_direc
//            [31:16] transfer_size
//       [15:5]/[3:1] reserved
//--------------------------------------------
always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
      dma_en <= 1'b0;
   else if (clr_dma_en)
      dma_en <= 1'b0;
   else if (ahb_wr_reg_en & (haddr_r[7:0] == `DMA_CTRL_ADDR))
      dma_en <= hwdata[0];
end

always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
   begin
      dma_direc <= 1'b0;
      transfer_size <= 16'b0;
      dma_addr <= 32'b0;
   end
   else if (ahb_wr_reg_en)
   begin
      case (haddr_r[7:0])
         `DMA_CTRL_ADDR:
         begin
            dma_direc <= hwdata[4];
            transfer_size <= hwdata[31:16];
         end
         `DMA_CTRL_ADDR:
         begin
            dma_addr <= hwdata[31:0];
         end
      endcase
   end
end

//----------------------------------------------
// configure interrupt mask registers
// ---------------------------------------------
always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
   begin
      fifo_full_int_gen <= 1'b1;
      fifo_empty_int_gen <= 1'b1;
      dma_finish_int_gen <= 1'b1;
   end
   else if (ahb_wr_reg_en && (haddr_r[7:0] == `INT_GEN_REG_ADDR))
   begin
      fifo_full_int_gen <= hwdata[0];
      fifo_empty_int_gen <= hwdata[4];
      dma_finish_int_gen <= hwdata[8];
   end
end

//---------------------------------------------------------------
//CLR_INT_REG_ADDR spec
//         [0]  clr_fifo_full_int
//         [4]  clr_fifo_empty_int
//         [8]  clr_dma_finish_int
//       [...]  reserved
//--------------------------------------------------------------- 
always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
   begin
      clr_fifo_full_int <= 1'b0;
      clr_fifo_empty_int <= 1'b0;
      clr_dma_finish_int <= 1'b0;
   end
   else if (ahb_wr_reg_en && (haddr_r[7:0] == `CLR_INT_REG_ADDR))
   begin
      clr_fifo_full_int <= hwdata[4];
      clr_fifo_empty_int <= hwdata[8];
      clr_dma_finish_int <= hwdata[0];
   end
   else
   begin
      clr_fifo_full_int <= 1'b0;
      clr_fifo_empty_int <= 1'b0;
      clr_dma_finish_int <= 1'b0;
   end
end

//--------------------------------------------
// Generate DATA FSM start signal
// -------------------------------------------

assign data_fsm_ready = data_present && 
                        (data_direction ? (sd_fifo_full) : (in_end_command));

//added by xxx,sd_op_finish decide which time to clr fifo wr/rd ptr-------------
//if host transmit operation,after transfer_complete begin clr----------------
//if host receive operation,after dma_transmit_finish,begin clr------------------
always @ (posedge in_sd_clk or negedge hrst_n)
begin
   if (hrst_n == 0)
   begin
      dma_end_tp <= 1'b0;
      dma_end <= 1'b0;
      dma_end_r <= 1'b0;
   end
   else
   begin
      dma_end_tp <= dma_finish_int;
      dma_end <= dma_end_tp;
      dma_end_r <= dma_end;
   end
end
// sd_op_finish used to clear FIFO ptr------------------
assign sd_op_finish = data_direction ? in_transfer_complete : !dma_end_r && dma_end;

// hw_stop_sd_clk,added by xxx--------------------------
always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
   begin
      one_bk_re_end_tp_1 <= 1'b0;
      one_bk_re_end_tp_2 <= 1'b0;
      one_bk_re_end_tp_3 <= 1'b0;
   end
   else
   begin
      one_bk_re_end_tp_1 <= one_bk_re_end;
      one_bk_re_end_tp_2 <= one_bk_re_end_tp_1;
      one_bk_re_end_tp_3 <= one_bk_re_end_tp_2;
   end
end
always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
      hw_stop_clk <= 1'b0;
   else if (!data_direction && hw_stop_clk_en)
   begin
      if (!one_bk_re_end_tp_3 && one_bk_re_end_tp_2)
         hw_stop_clk <= 1'b1;
      else if (dma_finish_int)
         hw_stop_clk <= 1'b0;
   end
   else
      hw_stop_clk <= 1'b0;
end

// assign out_sd_clk_en = ! hw_stop_clk; // || sd_clk_enable;
// ----------------------------------------------------------
// Generate COMMAND FSM start signal
// ----------------------------------------------------------
assign cmd_state_send = (in_cmd_current_state == `CMD_STATE_SEND);

always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
   begin
      cmd_state_send_tp1 <= 1'b0;
      cmd_state_send_tp2 <= 1'b0;
      cmd_state_send_tp3 <= 1'b0;
   end
   else
   begin
      cmd_state_send_tp1 <= cmd_state_send;
      cmd_state_send_tp2 <= cmd_state_send_tp1;
      cmd_state_send_tp3 <= cmd_state_send_tp2;
   end
end

always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
      cmd_ready_pre <= 1'b0;
   else if (!cmd_state_send_tp3 && cmd_state_send_tp2)
      cmd_ready_pre <= 1'b0;
   else if (command_enable && (ahb_wr_reg_en && (haddr_r[7:0] == `ARGUMENT_REGISTER_ADDR)))
      cmd_ready_pre <= 1'b1;
end

always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
      cmd_fsm_ready <= 1'b0;
   else
      cmd_fsm_ready <= cmd_ready_pre;
end
//-------------------------------------------------------
// Generate Interrupt signal
//--------------------------------------------------------

assign irq = ( (dma_finish_int && !dma_finish_interrupt_mask) || 
               (end_command_and_response && !end_command_and_response_interrupt_mask) ||
               (sd_fifo_empty_r && !sd_fifo_empty_intrrupt_mask) ||
               (fifo_full_int && !fifo_full_interrpt_mask) ||
               (fifo_empty_int && !fifo_empty_interrupt_mask) ||
               (sd_fifo_full_r && !sd_fifo_full_interrupt_mask) ||
               (end_command && !command_complete_interrupt_mask) ||
               (transfer_complete && !transfer_complete_interrupt_mask) || 
               (1'b0 && !rx_fifo_write_error_interrupt_mask) ||
               (1'b0 && !tx_fifo_read_error_interrupt_mask) ||
               (receive_data_crc_error && !read_data_crc_error_interrupt_mask) ||
               (send_data_crc_error && !write_data_crc_error_interrupt_mask) ||
               (response_timeout && !response_timeout_error_interrupt_mask) ||
               (read_to_error && !read_to_error_interrupt_mask) );

//--------------------------------------------------------
always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
   begin
      in_end_cmd_and_resp_tp_1 <= 1'b0;
      in_end_cmd_and_resp_tp_2 <= 1'b0;
      in_end_cmd_and_resp_tp_3 <= 1'b0;
   end
   else
   begin
      in_end_cmd_and_resp_tp_1 <= in_end_command_and_response;
      in_end_cmd_and_resp_tp_2 <= in_end_cmd_and_resp_tp_1;
      in_end_cmd_and_resp_tp_3 <= in_end_cmd_and_resp_tp_2;
   end
end

always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
      end_command_and_response <= 1'b0;
   else if (cmd_ready_pre)
      end_command_and_response <= 1'b0;
   else if (!in_end_cmd_and_resp_tp_3 && in_end_cmd_and_resp_tp_2)
      end_command_and_response <= 1'b1; //是不是缺一个else
end
//-------------------------------------------------------
// Generate Interrupt state signal tx_fifo_empty
//-------------------------------------------------------
always @ (posedge hclk or negedge hrst_n)
begin
   if (rst_n == 0)
   begin
      sd_fifo_empty_tp1 <= 1'b0;
      sd_fifo_empty_r <= 1'b0;
   end
   else
   begin
      sd_fifo_empty_tp1 <= sd_fifo_empty;
      sd_fifo_empty_r <= sd_fifo_empty_tp1;
   end
end
//-------------------------------------------------------
// Generate Interrupt state signal rx_fifo_full
//-------------------------------------------------------
reg    sd_fifo_full_tp1;

always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
   begin
      sd_fifo_full_tp1 <= 1'b0;
      sd_fifo_full_r <= 1'b0;
   end
   else
   begin
      sd_fifo_full_tp1 <= sd_fifo_full;
      sd_fifo_full_r <= sd_fifo_full_tp1;
   end
end
//-------------------------------------------------------
// Generate Interrupt state signal command sending complete
//-------------------------------------------------------
always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
   begin
      in_end_cmd_tp_1 <= 1'b0;
      in_end_cmd_tp_2 <= 1'b0;
      in_end_cmd_tp_3 <= 1'b0;
   end
   else
   begin
      in_end_cmd_tp_1 <= in_end_command;
      in_end_cmd_tp_2 <= in_end_cmd_tp_1;
      in_end_cmd_tp_3 <= in_end_cmd_tp_2;
   end
end

always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
      end_command <= 1'b0;
   else if (cmd_ready_pre)
      end_command <= 1'b0;
   else if (!in_end_cmd_tp_3 && in_end_cmd_tp_2)
      end_command <= 1'b1;
end

//-------------------------------------------------------
// Generate Interrupt state signal data transfer complete
//-------------------------------------------------------
always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
   begin
      in_transfer_end_tp_1 <= 1'b0;
      in_transfer_end_tp_2 <= 1'b0;
      in_transfer_end_tp_3 <= 1'b0;
   end
   else
   begin
      in_transfer_end_tp_1 <= in_transfer_complete;
      in_transfer_end_tp_2 <= in_transfer_end_tp_1;
      in_transfer_end_tp_3 <= in_transfer_end_tp_2;
   end
end

always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
      transfer_complete <= 1'b0;
   else if (cmd_ready_pre)
      transfer_complete <= 1'b0;
   else if (!in_transfer_end_tp_3 && in_transfer_end_tp_2)
      transfer_complete <= 1'b1;
end

//-------------------------------------------------------
// Generate Interrupt state signal data read timeout
//-------------------------------------------------------
always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
   begin
      in_rd_to_err_tp_1 <= 1'b0;
      in_rd_to_err_tp_2 <= 1'b0;
      in_rd_to_err_tp_3 <= 1'b0;
   end
   else
   begin
      in_rd_to_err_tp_1 <= in_read_to_error;
      in_rd_to_err_tp_2 <= in_rd_to_err_tp_1;
      in_rd_to_err_tp_3 <= in_rd_to_err_tp_2;
   end
end

always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
      read_to_error <= 1'b0;
   else if (cmd_ready_pre)
      read_to_error <= 1'b0;
   else if (!in_rd_to_err_tp_3 && in_rd_to_err_tp_2)
      read_to_error <= 1'b1;
end

//-------------------------------------------------------
// Generate Interrupt state signal sending data crc error
//-------------------------------------------------------
always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
   begin
      in_send_data_crc_err_tp_1 <= 1'b0;
      in_send_data_crc_err_tp_2 <= 1'b0;
      in_send_data_crc_err_tp_3 <= 1'b0;
   end
   else
   begin
      in_send_data_crc_err_tp_1 <= in_send_data_crc_error;
      in_send_data_crc_err_tp_2 <= in_send_data_crc_err_tp_1;
      in_send_data_crc_err_tp_3 <= in_send_data_crc_err_tp_2;
   end
end

always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
      send_data_crc_error <= 1'b0;
   else if (cmd_ready_pre)
      send_data_crc_error <= 1'b0;
   else if (!in_send_data_crc_err_tp_3 && in_send_data_crc_err_tp_2)
      send_data_crc_error <= 1'b1;
end

//-------------------------------------------------------
// Generate Interrupt state signal receiving data crc error
//-------------------------------------------------------
//in_receive_data_crc_error from sd_data_receive_shift_register module's
// out_receive_data_crc_error signal---------------------
always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
   begin
      in_receive_data_crc_err_tp_1 <= 1'b0;
      in_receive_data_crc_err_tp_2 <= 1'b0;
      in_receive_data_crc_err_tp_3 <= 1'b0;
   end
   else
      begin
      in_receive_data_crc_err_tp_1 <= in_receive_data_crc_error;
      in_receive_data_crc_err_tp_2 <= in_receive_data_crc_err_tp_1;
      in_receive_data_crc_err_tp_3 <= in_receive_data_crc_err_tp_2;
      end
end

always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
      receive_data_crc_error <= 1'b0;
   else if (cmd_ready_pre)
      receive_data_crc_error <= 1'b0;
   else if (!in_receive_data_crc_err_tp_3 && in_receive_data_crc_err_tp_2)
      receive_data_crc_error <= 1'b1;
end
//-------------------------------------------------------
// Generate Interrupt state signal command response timeout
//-------------------------------------------------------
always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
   begin
      in_resp_timeout_tp_1 <= 1'b0;
      in_resp_timeout_tp_2 <= 1'b0;
      in_resp_timeout_tp_3 <= 1'b0;
   end
   else
   begin
      in_resp_timeout_tp_1 <= in_response_timeout;
      in_resp_timeout_tp_2 <= in_resp_timeout_tp_1;
      in_resp_timeout_tp_3 <= in_resp_timeout_tp_2;
   end
end

always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
      response_timeout <= 1'b0;
   else if (cmd_ready_pre)
      response_timeout <= 1'b0;
   else if (!in_resp_timeout_tp_3 && in_resp_timeout_tp_2)
      response_timeout <= 1'b1;
end
//--------------------------------------------------------
// Config control register
//--------------------------------------------------------

always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
   begin
      sd_clk_enable <= 1'b0;
      sd_clk_divider <= 8'b0;
      sd_soft_reset <= 1'b1;
      command_argument <= 32'b0;
      command_index <= 6'b0;
      command_enable <= 1'b0;
      data_present <= 1'b0;
      response_type <= 2'b0;
      block_size <= 11'd200;
      block_number_ahb <= 32'b0;
      data_direction <= 1'b0;
      data_width <= 1'b0;
      read_to <= 32'hffffffff;
      dma_finish_interrupt_mask <= 1'b0;
      end_command_and_response_interrupt_mask <= 1'b0;
      fifo_full_interrpt_mask <= 1'b0;
      command_complete_interrupt_mask <= 1'b0;
      transfer_complete_interrupt_mask <= 1'b0;
      read_to_error_interrupt_mask <= 1'b0;
      rx_fifo_write_error_interrupt_mask <= 1'b0;
      tx_fifo_read_error_interrupt_mask <= 1'b0;
      read_data_crc_error_interrupt_mask <= 1'b0;
      write_data_crc_error_interrupt_mask <= 1'b0;
      response_timeout_error_interrupt_mask <= 1'b0;
      fifo_empty_interrupt_mask <= 1'b0;
      sd_fifo_full_interrupt_mask <= 1'b0;
      sd_fifo_empty_interrupt_mask <= 1'b0;
      hw_stop_clk_en <= 1'b0;
      high_speed_clk <= 1'b0;
    //read_acce_option <= 1'b0;  
   end
   else if (ahb_wr_reg_en)
   begin
      case (haddr_r[7:0])
         `CLOCK_CONTROL_REGISTER_ADDR:
         begin
            sd_clk_enable <= hwdata[2];
            sd_clk_divider <= hwdata[15:8];
         end
         `SOFTWARE_RESET_REGISTER_ADDR:
         begin
            sd_soft_reset <= hwdata[0];
         end
         `CLK_EN_SPEED_UP_ADDR:
         begin
            hw_stop_clk_en <= hwdata[0];
            high_speed_clk <= hwdata[4];
          //read_acce_option <= hwdata[8];
         end
         `ARGUMENT_REGISTER_ADDR:
         begin
            command_argument <= hwdata;
         end
         `COMMAND_REGISTER_ADDR:
         begin
            command_index <= hwdata[10:5];
            command_enable <= hwdata[3];
            data_present <=hwdata[2];
            response_type <= hwdata[1:0];
         end
         `BLOCK_SIZE_REGISTER_ADDR:
         begin
            block_size <= hwdata[10:0];
         end
         `BLOCK_COUNT_REGISTER_ADDR:
         begin
            block_number_ahb <= hwdata[31:0];
         end
         `TRANSFER_MODE_REGISTER_ADDR:
         begin
            data_direction <= hwdata[1];
            data_width <= hwdata[0];
         end
         `READ_TIMEOUT_CONTROL_REGISTER_ADDR:
         begin
            read_to <= hwdata[31:0];
         end
         `INTERRUPT_STATUS_MASK_REGISTER_ADDR:
         begin
            dma_finish_interrupt_mask <= hwdata[13];
            end_command_and_response_interrupt_mask <= hwdata[12];
            sd_fifo_empty_interrupt_mask <= hwdata[11];
            fifo_full_interrpt_mask <= hwdata[10];
            fifo_empty_interrupt_mask <= hwdata[9];
            sd_fifo_full_interrupt_mask <= hwdata[8];
            command_complete_interrupt_mask <= hwdata[7];
            transfer_complete_interrupt_mask <= hwdata[6];
            read_to_error_interrupt_mask <= hwdata[5];
            rx_fifo_write_error_interrupt_mask <= hwdata[4];
            tx_fifo_read_error_interrupt_mask <= hwdata[3];
            read_data_crc_error_interrupt_mask <= hwdata[2];
            write_data_crc_error_interrupt_mask <= hwdata[1];
            response_timeout_error_interrupt_mask <= hwdata[0];
         end
      endcase
   end
end

// response0-3 sd_clk domian to shb clk damain(时钟域)----
// these data are generated in CMD_STATE_RECEIVE of cmd_current_state---------------------------
// end_command_and_response can become the sync enable-----------------------------------
always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
   begin
      response0_ahb <= 32'h0;
      response1_ahb <= 32'h0;
      response2_ahb <= 32'h0;
      response3_ahb <= 32'h0;
   end
   else if (!in_end_cmd_and_resp_tp_3 && in_end_cmd_and_resp_tp_2)
   begin
      response0_ahb <= response0;
      response1_ahb <= response1;
      response2_ahb <= response2;
      response3_ahb <= response3;
   end
end

//--------------------------------------------------------
// Read state registers
//--------------------------------------------------------
always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
   begin
      hrdata <= 32'b0;   
   end
   else if (ahb_rd_reg_en)
   begin
      case (haddr[7:0])
         `CLOCK_CONTROL_REGISTER_ADDR:
            hrdata <= {16'b0,sd_clk_divider,5'b0,sd_clk_enable,2'b0};
         `SOFTWARE_RESET_REGISTER_ADDR:
            hrdata <= {31'b0,sd_soft_reset};
         `CLK_EN_SPEED_UP_ADDR:
          //hrdata <= {23'b0,read_acce_option,3'b0,high_speed_clk,3'b0,hw_stop_clk_en};
            hrdata <= {27'b0,high_speed_clk,3'b0,hw_stop_clk_en};
         `ARGUMENT_REGISTER_ADDR:
            hrdata <= command_argument;
         `COMMAND_REGISTER_ADDR:
            hrdata <= {21'b0,command_index,1'b0,command_enable,data_present,response_type};
         `BLOCK_SIZE_REGISTER_ADDR:
            hrdata <= {21'b0,block_size};
         `BLOCK_COUNT_REGISTER_ADDR:
            hrdata <= block_number_ahb;
         `TRANSFER_MODE_REGISTER_ADDR:
            hrdata <= {30'b0,data_direction,data_width};
         `READ_TIMEOUT_CONTROL_REGISTER_ADDR:
            hrdata <= read_to;
         `DMA_ADDR_ADDR:
            hrdata <= dma_addr;
         `DMA_CTRL_ADDR:
            hrdata <= {transfer_size,11'b0,dma_direc,3'b0,dma_en};
         `INT_GEN_REG_ADDR:
            hrdata <= {23'b0,dma_finish_int_gen,3'b0,fifo_empty_int_gen,3'b0,fifo_full_int_gen};
         `CLR_INT_REG_ADDR:
            hrdata <= {23'b0,clr_fifo_empty_int,3'b0,clr_fifo_full_int,3'b0,clr_dma_finish_int};
         `INTERRUPT_STATUS_MASK_REGISTER_ADDR
            hrdata <= { 18'b0,
               dma_finish_interrupt_mask,
               end_command_and_response_interrupt_mask,
               sd_fifo_empty_interrupt_mask,
               fifo_full_interrpt_mask,
               fifo_empty_interrupt_mask,
               sd_fifo_full_interrupt_mask,
               command_complete_interrupt_mask,
               transfer_complete_interrupt_mask,
               read_to_error_interrupt_mask,
               rx_fifo_write_error_interrupt_mask,
               tx_fifo_read_error_interrupt_mask,
               read_data_crc_error_interrupt_mask,
               write_data_crc_error_interrupt_mask,
               response_timeout_error_interrupt_mask
             };
         `RESPONSE0_REGISTER_ADDR:
            hrdata <= response0_ahb;
         `RESPONSE1_REGISTER_ADDR:
            hrdata <= response1_ahb;
         `RESPONSE2_REGISTER_ADDR:
            hrdata <= response2_ahb;
         `RESPONSE3_REGISTER_ADDR:
            hrdata <= response3_ahb;
         `INTERRUPT_STATUS_REGISTER_ADDR:
         begin
            hrdata <= { 18'b0,
                        dma_finish_int,
                        end_command_and_response,
                        sd_fifo_empty_r,
                        fifo_full_int,
                        fifo_empty_int,
                        sd_fifo_full_r,
                        end_command,
                        transfer_complete,
                        read_to_error,
                        1'b0,
                        1'b0,
                        receive_data_crc_error,
                        send_data_crc_error,
                        response_timeout};
         end
default :   hrdata <= 32'h0; 
      endcase
   end
end

//-----------------------------------------------------
// Determine(确定) the response type 
//-----------------------------------------------------
always @ (response_type)
begin
   out_response = 1'b0;
   out_longresponse = 1'b0;
   case (response_type)
      2'b00:
      begin
         out_response = 1'b0;
         out_longresponse = 1'b0;
      end
      2'b01:
      begin
         out_response = 1'b1;
         out_longresponse = 1'b1;
      end
      2'b10:
      begin
         out_response = 1'b1;
         out_longresponse = 1'b0;
      end
      2'b11:
      begin
         out_response = 1'b1;
         out_longresponse = 1'b0;
      end
   endcase
end
//----------------------------------------------------
always @ (posedge hclk or negedge hrst_n)
begin
   if (hrst_n == 0)
   begin
      block_num_tp <= 32'h0;
      block_number <= 32'h0;
   end
   else
   begin
      block_num_tp <= block_number_ahb;
      block_number <= block_num_tp
   end
end
endmodule

 

  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值