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