URL
https://opencores.org/ocsvn/sdcard_mass_storage_controller/sdcard_mass_storage_controller/trunk
Subversion Repositories sdcard_mass_storage_controller
Compare Revisions
- This comparison shows the changes necessary to convert path
/sdcard_mass_storage_controller/trunk
- from Rev 118 to Rev 119
- ↔ Reverse comparison
Rev 118 → Rev 119
/rtl/sdc_dma/verilog/SD_cmd_serial_host.v
1,581 → 1,581
`include "SD_defines.v" |
//------------------------- |
//------------------------- |
module SD_CMD_SERIAL_HOST ( SD_CLK_IN, RST_IN, SETTING_IN,GO_IDLE ,CMD_IN, REQ_IN, ACK_OUT, REQ_OUT,ACK_IN, CMD_OUT, STATUS, cmd_dat_i, cmd_out_o, cmd_oe_o, st_dat_t); |
//---------------Input ports--------------- |
input SD_CLK_IN; |
input RST_IN; |
input [15:0] SETTING_IN; |
input GO_IDLE; |
input [39:0] CMD_IN; |
input REQ_IN; |
input ACK_IN; |
input cmd_dat_i; |
|
//---------------Output ports--------------- |
output [39:0] CMD_OUT; |
output ACK_OUT; |
output REQ_OUT; |
output [7:0] STATUS; |
output reg cmd_oe_o; |
output reg cmd_out_o; |
output reg [1:0] st_dat_t; |
//---------------Input ports Data Type------ |
wire SD_CLK_IN; |
wire RST_IN; |
wire [15:0] SETTING_IN; |
wire [39:0] CMD_IN; |
wire REQ_IN; |
wire ACK_IN; |
wire GO_IDLE; |
//---------------Output ports Data Type------ |
reg [39:0] CMD_OUT; |
wire ACK_OUT ; |
reg [7:0] STATUS; |
reg REQ_OUT; |
|
//-------------Internal Constant------------- |
|
`ifdef SIM |
`define INIT_DELAY 2 |
`else |
`define INIT_DELAY 64 |
`endif |
|
`define NCR 2 |
parameter SEND_SIZE = 48; |
parameter SIZE = 10; |
parameter CONTENT_SIZE = 40; |
parameter |
INIT = 10'b0000_0000_01, |
IDLE = 10'b0000_0000_10, |
WRITE_WR = 10'b0000_0001_00, |
DLY_WR = 10'b0000_0010_00, |
READ_WR = 10'b0000_0100_00, |
DLY_READ = 10'b0000_1000_00, |
ACK_WR = 10'b0001_0000_00, |
WRITE_WO = 10'b0010_0000_00, |
DLY_WO = 10'b0100_0000_00, |
ACK_WO = 10'b1000_0000_00; |
parameter Read_Delay = 7; |
parameter EIGHT_PAD = 8; |
//---------------Internal variable----------- |
//-Internal settings/buffers |
reg [6:0] Response_Size; |
reg [2:0] Delay_Cycler; |
reg [CONTENT_SIZE-1:0] In_Buff; |
reg [39:0] Out_Buff; |
//-Internal State input |
reg Write_Read; |
reg Write_Only; |
|
//-CRC |
reg [4:0] word_select_counter; |
reg CRC_RST; |
reg [6:0]CRC_IN; |
wire [6:0] CRC_VAL; |
reg CRC_Enable; |
reg CRC_OUT; |
reg CRC_Check_On; |
reg Crc_Buffering; |
reg CRC_Valid; |
//-Internal Counterns |
//6 bit sent counter |
reg [7:0]Cmd_Cnt; //8 bit recive counter |
reg [2:0]Delay_Cnt; //3 bit Delay counter |
//-State Variable |
reg [SIZE-1:0] state; |
reg [SIZE-1:0] next_state; |
//Misc |
`define Vector_Index (CONTENT_SIZE-1-Cmd_Cnt) |
`define Bit_Nr (SEND_SIZE-Cmd_Cnt) |
|
//TRI-STATE |
reg block_write; |
reg block_read; |
|
|
// |
reg [1:0]word_select; |
reg FSM_ACK; |
reg DECODER_ACK; |
|
reg q; |
reg Req_internal_in; |
reg q1; |
reg Ack_internal_in; |
//------------------------------------------ |
SD_CRC_7 CRC_7( |
CRC_OUT, |
CRC_Enable, |
SD_CLK_IN, |
CRC_RST, |
CRC_VAL); |
//------------------------------------------ |
always @ (state or Delay_Cnt or Write_Read or Cmd_Cnt or Write_Only or Ack_internal_in or cmd_dat_i or Response_Size or Delay_Cycler) |
begin : FSM_COMBO |
next_state = 0; |
case(state) |
INIT: begin |
if (Cmd_Cnt >= `INIT_DELAY )begin |
next_state = IDLE; |
end |
|
else begin |
|
next_state = INIT; |
end |
|
end |
|
|
IDLE: begin |
if (Write_Read ) begin |
next_state = WRITE_WR; |
end |
else if (Write_Only ) begin |
next_state = WRITE_WO; |
end |
else begin |
next_state = IDLE; |
end |
end |
WRITE_WR: |
if (Cmd_Cnt >=SEND_SIZE-1) begin |
next_state = DLY_WR; |
end |
else begin |
next_state = WRITE_WR; |
end |
WRITE_WO: |
if (Cmd_Cnt >= SEND_SIZE-1) begin |
next_state = DLY_WO; |
end |
else begin |
next_state = WRITE_WO; |
end |
DLY_WR : |
if ( (Delay_Cnt >= `NCR) && ( !cmd_dat_i)) begin |
next_state = READ_WR; |
end |
else begin |
next_state = DLY_WR; |
end |
DLY_WO : |
if (Delay_Cnt >= Delay_Cycler) begin |
next_state = ACK_WO; |
end |
else begin |
next_state = DLY_WO; |
end |
READ_WR : |
if (Cmd_Cnt >= (Response_Size+EIGHT_PAD)) begin |
next_state = DLY_READ; |
end |
else begin |
next_state = READ_WR; |
end |
|
ACK_WO : |
next_state = IDLE; |
|
DLY_READ : |
if (Ack_internal_in ) begin |
next_state = ACK_WR; |
end |
else begin |
next_state = DLY_READ; |
end |
|
ACK_WR : |
next_state = IDLE; |
|
|
default : next_state = INIT; |
|
endcase |
end |
//---- |
|
always @ (posedge SD_CLK_IN or posedge RST_IN or posedge GO_IDLE) |
begin : REQ_SYNC |
if (RST_IN || GO_IDLE) begin |
Req_internal_in <=1'b0; |
q <=1'b0; |
end |
else begin |
q<=REQ_IN; |
Req_internal_in<=q; |
end |
|
|
end |
|
always @ (posedge SD_CLK_IN or posedge RST_IN or posedge GO_IDLE) |
begin :ACK_SYNC |
if (RST_IN || GO_IDLE) begin |
Ack_internal_in <=1'b0; |
q1 <=1'b0; |
end |
else begin |
q1<=ACK_IN; |
Ack_internal_in<=q1; |
end |
|
|
end |
|
|
|
|
|
|
|
always @ (posedge SD_CLK_IN or posedge RST_IN or posedge GO_IDLE ) |
begin:COMMAND_DECODER |
if (RST_IN || GO_IDLE ) begin |
Delay_Cycler <=3'b0; |
Response_Size <=7'b0; |
DECODER_ACK <= 1; |
Write_Read<=1'b0; |
Write_Only<=1'b0; |
CRC_Check_On <=0; |
In_Buff <=0; |
block_write<=0; |
block_read <=0; |
word_select<=0; |
end |
else begin |
if (Req_internal_in == 1) begin |
Response_Size[6:0] <= SETTING_IN [6:0]; |
CRC_Check_On <= SETTING_IN [7]; |
Delay_Cycler[2:0] <= SETTING_IN [10:8]; |
block_write <= SETTING_IN [11]; |
block_read <= SETTING_IN [12]; |
word_select <=SETTING_IN [14:13]; |
In_Buff <= CMD_IN; |
DECODER_ACK<=0; |
if (SETTING_IN [6:0]>0) begin |
Write_Read<=1'b1; |
Write_Only<=1'b0; |
end |
else begin |
Write_Read<=1'b0; |
Write_Only<=1'b1; |
end |
end |
else begin |
Write_Read<=1'b0; |
Write_Only<=1'b0; |
DECODER_ACK <= 1; |
end |
end |
end |
//End block COMMAND_DECODER |
|
//-------Function for Combo logic----------------- |
|
|
|
assign ACK_OUT = FSM_ACK & DECODER_ACK; |
|
//----------------Seq logic------------ |
always @ (posedge SD_CLK_IN or posedge RST_IN or posedge GO_IDLE ) |
begin : FSM_SEQ |
if (RST_IN ) begin |
state <= #1 INIT; |
end |
else if (GO_IDLE) begin |
state <= #1 IDLE; |
end |
else begin |
state <= #1 next_state; |
end |
end |
|
//-------------OUTPUT_LOGIC------- |
always @ (posedge SD_CLK_IN or posedge RST_IN or posedge GO_IDLE ) |
begin : FSM_OUT |
if (RST_IN || GO_IDLE ) begin |
CRC_Enable=0; |
word_select_counter<=0; |
Delay_Cnt =0; |
cmd_oe_o=1; |
cmd_out_o = 1; |
Out_Buff =0; |
FSM_ACK=1; |
REQ_OUT =0; |
CRC_RST =1; |
CRC_OUT =0; |
CRC_IN =0; |
CMD_OUT =0; |
Crc_Buffering =0; |
STATUS = 0; |
CRC_Valid=0; |
Cmd_Cnt=0; |
st_dat_t<=0; |
if(GO_IDLE) begin |
cmd_oe_o=0; |
cmd_out_o = 0; |
end |
end |
else begin |
case(state) |
INIT : begin |
Cmd_Cnt=Cmd_Cnt+1; |
cmd_oe_o=1; |
cmd_out_o = 1; |
end |
|
IDLE : begin |
cmd_oe_o=0; //Put CMD to Z |
Delay_Cnt =0; |
Cmd_Cnt =0; |
CRC_RST =1; |
CRC_Enable=0; |
CMD_OUT=0; |
st_dat_t<=0; |
|
end |
|
WRITE_WR: begin |
FSM_ACK=0; |
CRC_RST =0; |
CRC_Enable=1; |
|
|
|
if (Cmd_Cnt==0) begin |
STATUS = 16'b0000_0000_0000_0001; |
REQ_OUT=1; |
end |
else if (Ack_internal_in) begin |
REQ_OUT=0; |
end |
|
//Wait one cycle before sending, for setting up the CRC unit. |
if (Crc_Buffering==1) begin |
cmd_oe_o =1; |
if (`Bit_Nr > 8 ) begin // 1->40 CMD, (41 >= CNT && CNT <=47) CRC, 48 stop_bit |
cmd_out_o = In_Buff[`Vector_Index]; |
if (`Bit_Nr > 9 ) begin //1 step ahead |
CRC_OUT = In_Buff[`Vector_Index-1]; |
end else begin |
CRC_Enable=0; |
end |
end |
else if ( (`Bit_Nr <=8) && (`Bit_Nr >=2) ) begin |
CRC_Enable=0; |
cmd_out_o = CRC_VAL[(`Bit_Nr)-2]; |
|
if (block_read & block_write) |
st_dat_t<=2'b11; |
else if (block_read) |
st_dat_t<=2'b10; |
end |
else begin |
cmd_out_o =1'b1; |
end |
Cmd_Cnt = Cmd_Cnt+1 ; |
end |
else begin //Pre load CRC |
Crc_Buffering=1; |
CRC_OUT = In_Buff[`Vector_Index]; |
end |
end |
|
WRITE_WO: begin |
FSM_ACK=0; |
CRC_RST =0; |
CRC_Enable=1; |
|
|
if (Cmd_Cnt==0) begin |
STATUS[3:0] = 16'b0000_0000_0000_0010; |
REQ_OUT=1; |
end |
else if (Ack_internal_in) begin |
REQ_OUT=0; |
end |
|
|
|
//Wait one cycle before sending, for setting up the CRC unit. |
if (Crc_Buffering==1) begin |
cmd_oe_o =1; |
if (`Bit_Nr > 8 ) begin // 1->40 CMD, (41 >= CNT && CNT <=47) CRC, 48 stop_bit |
cmd_out_o = In_Buff[`Vector_Index]; |
if (`Bit_Nr > 9 ) begin //1 step ahead |
CRC_OUT = In_Buff[`Vector_Index-1]; |
end |
else begin |
CRC_Enable=0; |
end |
end |
else if( (`Bit_Nr <=8) && (`Bit_Nr >=2) ) begin |
CRC_Enable=0; |
cmd_out_o = CRC_VAL[(`Bit_Nr)-2]; |
if (block_read) |
st_dat_t<=2'b10; |
end |
else begin |
cmd_out_o =1'b1; |
end |
Cmd_Cnt = Cmd_Cnt+1; |
end |
else begin //Pre load CRC |
Crc_Buffering=1; |
CRC_OUT = In_Buff[`Vector_Index]; |
end |
end |
|
DLY_WR : begin |
if (Delay_Cnt==0) begin |
STATUS[3:0] = 4'b0011; |
REQ_OUT=1; |
end |
else if (Ack_internal_in) begin |
REQ_OUT=0; |
end |
CRC_Enable=0; |
CRC_RST =1; |
Cmd_Cnt = 1; |
cmd_oe_o=0; |
if (Delay_Cnt<3'b111) |
Delay_Cnt =Delay_Cnt+1; |
Crc_Buffering=0; |
end |
|
DLY_WO : begin |
if (Delay_Cnt==0) begin |
STATUS[3:0] = 4'b0100; |
STATUS[5] = 0; |
STATUS[6] = 1; |
REQ_OUT=1; |
end |
else if (Ack_internal_in) begin |
REQ_OUT=0; |
end |
CRC_Enable=0; |
CRC_RST =1; |
Cmd_Cnt = 0; |
cmd_oe_o=0; |
Delay_Cnt =Delay_Cnt+1; |
Crc_Buffering=0; |
end |
|
READ_WR : begin |
Delay_Cnt =0; |
CRC_RST =0; |
CRC_Enable=1; |
cmd_oe_o =0; |
|
if (Cmd_Cnt==1) begin |
STATUS[3:0] = 16'b0000_0000_0000_0101; |
REQ_OUT=1; |
Out_Buff[39]=0; //startbit (0) |
end |
else if (Ack_internal_in) begin |
REQ_OUT=0; |
end |
|
|
|
if (Cmd_Cnt < (Response_Size))begin |
|
if (Cmd_Cnt<8 ) //1+1+6 (S,T,Index) |
Out_Buff[39-Cmd_Cnt] = cmd_dat_i; |
else begin |
|
if (word_select == 2'b00) begin |
if(Cmd_Cnt<40) begin |
word_select_counter<= word_select_counter+1; |
Out_Buff[31-word_select_counter] = cmd_dat_i; |
end |
end |
else if (word_select == 2'b01) begin |
if ( (Cmd_Cnt>=40) && (Cmd_Cnt<72) )begin |
word_select_counter<= word_select_counter+1; |
Out_Buff[31-word_select_counter] = cmd_dat_i; |
end |
|
end |
else if (word_select == 2'b10) begin |
if ( (Cmd_Cnt>72) && (Cmd_Cnt<104) )begin |
word_select_counter<= word_select_counter+1; |
Out_Buff[31-word_select_counter] = cmd_dat_i; |
end |
end |
else if (word_select == 2'b11) begin |
if ( (Cmd_Cnt>104) && (Cmd_Cnt<126) )begin |
word_select_counter<= word_select_counter+1; |
Out_Buff[31-word_select_counter] = cmd_dat_i; |
end |
end |
|
|
end |
CRC_OUT = cmd_dat_i; |
|
end |
else if ( Cmd_Cnt - Response_Size <=6 ) begin |
CRC_IN [(Response_Size+6)-(Cmd_Cnt)] = cmd_dat_i; |
CRC_Enable=0; |
end |
else begin |
if ((CRC_IN != CRC_VAL) && ( CRC_Check_On == 1)) begin |
CRC_Valid=0; |
CRC_Enable=0; |
end |
else begin |
CRC_Valid=1; |
CRC_Enable=0; |
end |
if (block_read & block_write) |
st_dat_t<=2'b11; |
else if (block_write) |
st_dat_t<=2'b01; |
|
end |
Cmd_Cnt = Cmd_Cnt+1; |
end |
|
DLY_READ: begin |
|
if (Delay_Cnt==0) begin |
STATUS[3:0] = 4'b0110; |
STATUS[5] = CRC_Valid; |
STATUS[6] = 1; |
REQ_OUT=1; |
end |
else if (Ack_internal_in) begin |
REQ_OUT=0; |
end |
|
CRC_Enable=0; |
CRC_RST =1; |
Cmd_Cnt = 0; |
cmd_oe_o=0; |
|
CMD_OUT[39:0]=Out_Buff; |
Delay_Cnt =Delay_Cnt+1; |
end |
|
ACK_WO: begin |
FSM_ACK=1; |
end |
|
ACK_WR: begin |
FSM_ACK=1; |
REQ_OUT =0; |
|
end |
|
endcase |
end |
end |
|
|
endmodule |
|
|
`include "SD_defines.v" |
//------------------------- |
//------------------------- |
module SD_CMD_SERIAL_HOST ( SD_CLK_IN, RST_IN, SETTING_IN,GO_IDLE ,CMD_IN, REQ_IN, ACK_OUT, REQ_OUT,ACK_IN, CMD_OUT, STATUS, cmd_dat_i, cmd_out_o, cmd_oe_o, st_dat_t); |
//---------------Input ports--------------- |
input SD_CLK_IN; |
input RST_IN; |
input [15:0] SETTING_IN; |
input GO_IDLE; |
input [39:0] CMD_IN; |
input REQ_IN; |
input ACK_IN; |
input cmd_dat_i; |
|
//---------------Output ports--------------- |
output [39:0] CMD_OUT; |
output ACK_OUT; |
output REQ_OUT; |
output [7:0] STATUS; |
output reg cmd_oe_o; |
output reg cmd_out_o; |
output reg [1:0] st_dat_t; |
//---------------Input ports Data Type------ |
wire SD_CLK_IN; |
wire RST_IN; |
wire [15:0] SETTING_IN; |
wire [39:0] CMD_IN; |
wire REQ_IN; |
wire ACK_IN; |
wire GO_IDLE; |
//---------------Output ports Data Type------ |
reg [39:0] CMD_OUT; |
wire ACK_OUT ; |
reg [7:0] STATUS; |
reg REQ_OUT; |
|
//-------------Internal Constant------------- |
|
`ifdef SIM |
`define INIT_DELAY 2 |
`else |
`define INIT_DELAY 64 |
`endif |
|
`define NCR 2 |
parameter SEND_SIZE = 48; |
parameter SIZE = 10; |
parameter CONTENT_SIZE = 40; |
parameter |
INIT = 10'b0000_0000_01, |
IDLE = 10'b0000_0000_10, |
WRITE_WR = 10'b0000_0001_00, |
DLY_WR = 10'b0000_0010_00, |
READ_WR = 10'b0000_0100_00, |
DLY_READ = 10'b0000_1000_00, |
ACK_WR = 10'b0001_0000_00, |
WRITE_WO = 10'b0010_0000_00, |
DLY_WO = 10'b0100_0000_00, |
ACK_WO = 10'b1000_0000_00; |
parameter Read_Delay = 7; |
parameter EIGHT_PAD = 8; |
//---------------Internal variable----------- |
//-Internal settings/buffers |
reg [6:0] Response_Size; |
reg [2:0] Delay_Cycler; |
reg [CONTENT_SIZE-1:0] In_Buff; |
reg [39:0] Out_Buff; |
//-Internal State input |
reg Write_Read; |
reg Write_Only; |
|
//-CRC |
reg [4:0] word_select_counter; |
reg CRC_RST; |
reg [6:0]CRC_IN; |
wire [6:0] CRC_VAL; |
reg CRC_Enable; |
reg CRC_OUT; |
reg CRC_Check_On; |
reg Crc_Buffering; |
reg CRC_Valid; |
//-Internal Counterns |
//6 bit sent counter |
reg [7:0]Cmd_Cnt; //8 bit recive counter |
reg [2:0]Delay_Cnt; //3 bit Delay counter |
//-State Variable |
reg [SIZE-1:0] state; |
reg [SIZE-1:0] next_state; |
//Misc |
`define Vector_Index (CONTENT_SIZE-1-Cmd_Cnt) |
`define Bit_Nr (SEND_SIZE-Cmd_Cnt) |
|
//TRI-STATE |
reg block_write; |
reg block_read; |
|
|
// |
reg [1:0]word_select; |
reg FSM_ACK; |
reg DECODER_ACK; |
|
reg q; |
reg Req_internal_in; |
reg q1; |
reg Ack_internal_in; |
//------------------------------------------ |
SD_CRC_7 CRC_7( |
CRC_OUT, |
CRC_Enable, |
SD_CLK_IN, |
CRC_RST, |
CRC_VAL); |
//------------------------------------------ |
always @ (state or Delay_Cnt or Write_Read or Cmd_Cnt or Write_Only or Ack_internal_in or cmd_dat_i or Response_Size or Delay_Cycler) |
begin : FSM_COMBO |
next_state = 0; |
case(state) |
INIT: begin |
if (Cmd_Cnt >= `INIT_DELAY )begin |
next_state = IDLE; |
end |
|
else begin |
|
next_state = INIT; |
end |
|
end |
|
|
IDLE: begin |
if (Write_Read ) begin |
next_state = WRITE_WR; |
end |
else if (Write_Only ) begin |
next_state = WRITE_WO; |
end |
else begin |
next_state = IDLE; |
end |
end |
WRITE_WR: |
if (Cmd_Cnt >=SEND_SIZE-1) begin |
next_state = DLY_WR; |
end |
else begin |
next_state = WRITE_WR; |
end |
WRITE_WO: |
if (Cmd_Cnt >= SEND_SIZE-1) begin |
next_state = DLY_WO; |
end |
else begin |
next_state = WRITE_WO; |
end |
DLY_WR : |
if ( (Delay_Cnt >= `NCR) && ( !cmd_dat_i)) begin |
next_state = READ_WR; |
end |
else begin |
next_state = DLY_WR; |
end |
DLY_WO : |
if (Delay_Cnt >= Delay_Cycler) begin |
next_state = ACK_WO; |
end |
else begin |
next_state = DLY_WO; |
end |
READ_WR : |
if (Cmd_Cnt >= (Response_Size+EIGHT_PAD)) begin |
next_state = DLY_READ; |
end |
else begin |
next_state = READ_WR; |
end |
|
ACK_WO : |
next_state = IDLE; |
|
DLY_READ : |
if (Ack_internal_in ) begin |
next_state = ACK_WR; |
end |
else begin |
next_state = DLY_READ; |
end |
|
ACK_WR : |
next_state = IDLE; |
|
|
default : next_state = INIT; |
|
endcase |
end |
//---- |
|
always @ (posedge SD_CLK_IN or posedge RST_IN or posedge GO_IDLE) |
begin : REQ_SYNC |
if (RST_IN || GO_IDLE) begin |
Req_internal_in <=1'b0; |
q <=1'b0; |
end |
else begin |
q<=REQ_IN; |
Req_internal_in<=q; |
end |
|
|
end |
|
always @ (posedge SD_CLK_IN or posedge RST_IN or posedge GO_IDLE) |
begin :ACK_SYNC |
if (RST_IN || GO_IDLE) begin |
Ack_internal_in <=1'b0; |
q1 <=1'b0; |
end |
else begin |
q1<=ACK_IN; |
Ack_internal_in<=q1; |
end |
|
|
end |
|
|
|
|
|
|
|
always @ (posedge SD_CLK_IN or posedge RST_IN or posedge GO_IDLE ) |
begin:COMMAND_DECODER |
if (RST_IN || GO_IDLE ) begin |
Delay_Cycler <=3'b0; |
Response_Size <=7'b0; |
DECODER_ACK <= 1; |
Write_Read<=1'b0; |
Write_Only<=1'b0; |
CRC_Check_On <=0; |
In_Buff <=0; |
block_write<=0; |
block_read <=0; |
word_select<=0; |
end |
else begin |
if (Req_internal_in == 1) begin |
Response_Size[6:0] <= SETTING_IN [6:0]; |
CRC_Check_On <= SETTING_IN [7]; |
Delay_Cycler[2:0] <= SETTING_IN [10:8]; |
block_write <= SETTING_IN [11]; |
block_read <= SETTING_IN [12]; |
word_select <=SETTING_IN [14:13]; |
In_Buff <= CMD_IN; |
DECODER_ACK<=0; |
if (SETTING_IN [6:0]>0) begin |
Write_Read<=1'b1; |
Write_Only<=1'b0; |
end |
else begin |
Write_Read<=1'b0; |
Write_Only<=1'b1; |
end |
end |
else begin |
Write_Read<=1'b0; |
Write_Only<=1'b0; |
DECODER_ACK <= 1; |
end |
end |
end |
//End block COMMAND_DECODER |
|
//-------Function for Combo logic----------------- |
|
|
|
assign ACK_OUT = FSM_ACK & DECODER_ACK; |
|
//----------------Seq logic------------ |
always @ (posedge SD_CLK_IN or posedge RST_IN or posedge GO_IDLE ) |
begin : FSM_SEQ |
if (RST_IN ) begin |
state <= #1 INIT; |
end |
else if (GO_IDLE) begin |
state <= #1 IDLE; |
end |
else begin |
state <= #1 next_state; |
end |
end |
|
//-------------OUTPUT_LOGIC------- |
always @ (posedge SD_CLK_IN or posedge RST_IN or posedge GO_IDLE ) |
begin : FSM_OUT |
if (RST_IN || GO_IDLE ) begin |
CRC_Enable=0; |
word_select_counter<=0; |
Delay_Cnt =0; |
cmd_oe_o=1; |
cmd_out_o = 1; |
Out_Buff =0; |
FSM_ACK=1; |
REQ_OUT =0; |
CRC_RST =1; |
CRC_OUT =0; |
CRC_IN =0; |
CMD_OUT =0; |
Crc_Buffering =0; |
STATUS = 0; |
CRC_Valid=0; |
Cmd_Cnt=0; |
st_dat_t<=0; |
if(GO_IDLE) begin |
cmd_oe_o=0; |
cmd_out_o = 0; |
end |
end |
else begin |
case(state) |
INIT : begin |
Cmd_Cnt=Cmd_Cnt+1; |
cmd_oe_o=1; |
cmd_out_o = 1; |
end |
|
IDLE : begin |
cmd_oe_o=0; //Put CMD to Z |
Delay_Cnt =0; |
Cmd_Cnt =0; |
CRC_RST =1; |
CRC_Enable=0; |
CMD_OUT=0; |
st_dat_t<=0; |
|
end |
|
WRITE_WR: begin |
FSM_ACK=0; |
CRC_RST =0; |
CRC_Enable=1; |
|
|
|
if (Cmd_Cnt==0) begin |
STATUS = 16'b0000_0000_0000_0001; |
REQ_OUT=1; |
end |
else if (Ack_internal_in) begin |
REQ_OUT=0; |
end |
|
//Wait one cycle before sending, for setting up the CRC unit. |
if (Crc_Buffering==1) begin |
cmd_oe_o =1; |
if (`Bit_Nr > 8 ) begin // 1->40 CMD, (41 >= CNT && CNT <=47) CRC, 48 stop_bit |
cmd_out_o = In_Buff[`Vector_Index]; |
if (`Bit_Nr > 9 ) begin //1 step ahead |
CRC_OUT = In_Buff[`Vector_Index-1]; |
end else begin |
CRC_Enable=0; |
end |
end |
else if ( (`Bit_Nr <=8) && (`Bit_Nr >=2) ) begin |
CRC_Enable=0; |
cmd_out_o = CRC_VAL[(`Bit_Nr)-2]; |
|
if (block_read & block_write) |
st_dat_t<=2'b11; |
else if (block_read) |
st_dat_t<=2'b10; |
end |
else begin |
cmd_out_o =1'b1; |
end |
Cmd_Cnt = Cmd_Cnt+1 ; |
end |
else begin //Pre load CRC |
Crc_Buffering=1; |
CRC_OUT = In_Buff[`Vector_Index]; |
end |
end |
|
WRITE_WO: begin |
FSM_ACK=0; |
CRC_RST =0; |
CRC_Enable=1; |
|
|
if (Cmd_Cnt==0) begin |
STATUS[3:0] = 16'b0000_0000_0000_0010; |
REQ_OUT=1; |
end |
else if (Ack_internal_in) begin |
REQ_OUT=0; |
end |
|
|
|
//Wait one cycle before sending, for setting up the CRC unit. |
if (Crc_Buffering==1) begin |
cmd_oe_o =1; |
if (`Bit_Nr > 8 ) begin // 1->40 CMD, (41 >= CNT && CNT <=47) CRC, 48 stop_bit |
cmd_out_o = In_Buff[`Vector_Index]; |
if (`Bit_Nr > 9 ) begin //1 step ahead |
CRC_OUT = In_Buff[`Vector_Index-1]; |
end |
else begin |
CRC_Enable=0; |
end |
end |
else if( (`Bit_Nr <=8) && (`Bit_Nr >=2) ) begin |
CRC_Enable=0; |
cmd_out_o = CRC_VAL[(`Bit_Nr)-2]; |
if (block_read) |
st_dat_t<=2'b10; |
end |
else begin |
cmd_out_o =1'b1; |
end |
Cmd_Cnt = Cmd_Cnt+1; |
end |
else begin //Pre load CRC |
Crc_Buffering=1; |
CRC_OUT = In_Buff[`Vector_Index]; |
end |
end |
|
DLY_WR : begin |
if (Delay_Cnt==0) begin |
STATUS[3:0] = 4'b0011; |
REQ_OUT=1; |
end |
else if (Ack_internal_in) begin |
REQ_OUT=0; |
end |
CRC_Enable=0; |
CRC_RST =1; |
Cmd_Cnt = 1; |
cmd_oe_o=0; |
if (Delay_Cnt<3'b111) |
Delay_Cnt =Delay_Cnt+1; |
Crc_Buffering=0; |
end |
|
DLY_WO : begin |
if (Delay_Cnt==0) begin |
STATUS[3:0] = 4'b0100; |
STATUS[5] = 0; |
STATUS[6] = 1; |
REQ_OUT=1; |
end |
else if (Ack_internal_in) begin |
REQ_OUT=0; |
end |
CRC_Enable=0; |
CRC_RST =1; |
Cmd_Cnt = 0; |
cmd_oe_o=0; |
Delay_Cnt =Delay_Cnt+1; |
Crc_Buffering=0; |
end |
|
READ_WR : begin |
Delay_Cnt =0; |
CRC_RST =0; |
CRC_Enable=1; |
cmd_oe_o =0; |
|
if (Cmd_Cnt==1) begin |
STATUS[3:0] = 16'b0000_0000_0000_0101; |
REQ_OUT=1; |
Out_Buff[39]=0; //startbit (0) |
end |
else if (Ack_internal_in) begin |
REQ_OUT=0; |
end |
|
|
|
if (Cmd_Cnt < (Response_Size))begin |
|
if (Cmd_Cnt<8 ) //1+1+6 (S,T,Index) |
Out_Buff[39-Cmd_Cnt] = cmd_dat_i; |
else begin |
|
if (word_select == 2'b00) begin |
if(Cmd_Cnt<40) begin |
word_select_counter<= word_select_counter+1; |
Out_Buff[31-word_select_counter] = cmd_dat_i; |
end |
end |
else if (word_select == 2'b01) begin |
if ( (Cmd_Cnt>=40) && (Cmd_Cnt<72) )begin |
word_select_counter<= word_select_counter+1; |
Out_Buff[31-word_select_counter] = cmd_dat_i; |
end |
|
end |
else if (word_select == 2'b10) begin |
if ( (Cmd_Cnt>=72) && (Cmd_Cnt<104) )begin |
word_select_counter<= word_select_counter+1; |
Out_Buff[31-word_select_counter] = cmd_dat_i; |
end |
end |
else if (word_select == 2'b11) begin |
if ( (Cmd_Cnt>=104) && (Cmd_Cnt<128) )begin |
word_select_counter<= word_select_counter+1; |
Out_Buff[31-word_select_counter] = cmd_dat_i; |
end |
end |
|
|
end |
CRC_OUT = cmd_dat_i; |
|
end |
else if ( Cmd_Cnt - Response_Size <=6 ) begin |
CRC_IN [(Response_Size+6)-(Cmd_Cnt)] = cmd_dat_i; |
CRC_Enable=0; |
end |
else begin |
if ((CRC_IN != CRC_VAL) && ( CRC_Check_On == 1)) begin |
CRC_Valid=0; |
CRC_Enable=0; |
end |
else begin |
CRC_Valid=1; |
CRC_Enable=0; |
end |
if (block_read & block_write) |
st_dat_t<=2'b11; |
else if (block_write) |
st_dat_t<=2'b01; |
|
end |
Cmd_Cnt = Cmd_Cnt+1; |
end |
|
DLY_READ: begin |
|
if (Delay_Cnt==0) begin |
STATUS[3:0] = 4'b0110; |
STATUS[5] = CRC_Valid; |
STATUS[6] = 1; |
REQ_OUT=1; |
end |
else if (Ack_internal_in) begin |
REQ_OUT=0; |
end |
|
CRC_Enable=0; |
CRC_RST =1; |
Cmd_Cnt = 0; |
cmd_oe_o=0; |
|
CMD_OUT[39:0]=Out_Buff; |
Delay_Cnt =Delay_Cnt+1; |
end |
|
ACK_WO: begin |
FSM_ACK=1; |
end |
|
ACK_WR: begin |
FSM_ACK=1; |
REQ_OUT =0; |
|
end |
|
endcase |
end |
end |
|
|
endmodule |
|
|