// receiving data from Data FIS, bypass it into buffer at upper level
begin
if(incom_done)
// EOF received
begin
state<=STATE_IDLE;
end
else
if(ll_data_val_in)
begin
if(dword_cnt==14'd2049)
// if too much data for a data FIS TODO handle this excpetion properly
state<=STATE_IDLE;
else
// continuing receiving data
begin
dword_cnt<=dword_cnt+1'b1;
state<=STATE_IN_DATA;
end
end
end
STATE_IN_REG_1:
// receiving register FIS, dword by dword
begin
if(ll_data_val_in)
if(ll_data_last_in)
// incorrect frame size
begin
bad_fis_received<=1'b1;
state<=STATE_IDLE;
end
else
// going to the next dword, parse current one: {Device, LBA High, LBA Mid, LBA Low}
begin
loc_lba[7:0]<=ll_data_in[7:0];
loc_lba[23:16]<=ll_data_in[15:8];
loc_lba[39:32]<=ll_data_in[23:16];
loc_dev[7:0]<=ll_data_in[31:24];
state<=STATE_IN_REG_2:
end
end
STATE_IN_REG_2:
// receiving register FIS, dword by dword
begin
if(ll_data_val_in)
if(ll_data_last_in)
// incorrect frame size
begin
bad_fis_received<=1'b1;
STATE_IDLE<=STATE_IDLE;
end
else
// going to the next dword, parse current one: {Reserved, LBA High (exp), LBA Mid (exp), LBA Low (exp)}
begin
loc_lba[15:8]<=ll_data_in[7:0];
loc_lba[31:24]<=ll_data_in[15:8];
loc_lba[47:40]<=ll_data_in[23:16];
state<=STATE_IN_REG_3;
end
end
STATE_IN_REG_3:
// receiving register FIS, dword by dword
begin
if(ll_data_val_in)
if(ll_data_last_in)
// incorrect frame size
begin
bad_fis_received<=1'b1;
state<=STATE_IN_IDLE;
end
else
// going to the next dword, parse current one: {Reserved, Reserved, Sector Count (exp), Sector Count}
begin
loc_count[15:0]<=ll_data_in[15:0];
state<=STATE_IN_REG_4;
end
end
STATE_IN_REG_4:
// receiving register FIS, dword by dword
begin
if(ll_data_val_in)
if(ll_data_last_in)
// correct frame size, finishing
begin
state<=STATE_IN_IDLE;
end
else
// incorrect frame size
begin
state<=STATE_IN_REG_ERR;
err_timer<=14'h4;
end
end
STATE_IN_REG_ERR:
// FIS was started as REG, but for some reason it has a size more than needed
// just wait until it's over and assert an error
begin
if(ll_data_val_in)
if(ll_data_last_in)
begin
bad_fis_received<=1'b1;
state<=STATE_IDLE;
end
else
begin
if(err_timeout)
// if for some reason FIS continue transferring for too long, terminate it
begin
state<=STATE_IDLE;
incom_stop_req_timeout<=1'b1;
end
else
err_timer<=err_timer+1'b1;
end
end
STATE_IN_DMAA_ERR:
// FIS was started as DMA Activate, but for some reason it has a size more than needed
// just wait until it's over and assert an error
begin
if(ll_data_val_in)
if(ll_data_last_in)
begin
bad_fis_received<=1'b1;
state<=STATE_IDLE;
end
else
begin
if(err_timeout)
// if for some reason FIS continue transferring for too long, terminate it
begin
state<=STATE_IDLE;
incom_stop_req_timeout<=1'b1;
end
else
err_timer<=err_timer+1'b1;
end
end
STATE_IN_DMAS_1:
// receiving DMA Setup FIS, dword by dword
begin
if(ll_data_val_in)
if(ll_data_last_in)
// incorrect frame size
begin
bad_fis_received<=1'b1;
state<=STATE_IDLE;
end
else
// going to the next dword, parse current one: DMA Buffer Id Low
begin
loc_dma_id[31:0]<=ll_data_in[31:0];
state<=STATE_IN_DMAS_2;
end
end
STATE_IN_DMAS_2:
// receiving DMA Setup FIS, dword by dword
begin
if(ll_data_val_in)
if(ll_data_last_in)
// incorrect frame size
begin
bad_fis_received<=1'b1;
state<=STATE_IDLE;
end
else
// going to the next dword, parse current one: DMA Buffer Id High
begin
loc_lba[63:32]<=ll_data_in[31:0];
state<=STATE_IN_DMAS_3;
end
end
STATE_IN_DMAS_3:
// receiving DMA Setup FIS, dword by dword
begin
if(ll_data_val_in)
if(ll_data_last_in)
// incorrect frame size
begin
bad_fis_received<=1'b1;
STATE_IDLE<=STATE_IDLE;
end
else
// going to the next dword, parse current one: Reserved
begin
state<=STATE_IN_DMAS_4;
end
end
STATE_IN_DMAS_4:
// receiving DMA Setup FIS, dword by dword
begin
if(ll_data_val_in)
if(ll_data_last_in)
// incorrect frame size
begin
bad_fis_received<=1'b1;
STATE_IDLE<=STATE_IDLE;
end
else
// going to the next dword, parse current one: DMA Buffer Offset
begin
loc_dma_off[31:0]<=ll_data_in[31:0];
state<=STATE_IN_DMAS_5;
end
end
STATE_IN_DMAS_5:
// receiving DMA Setup FIS, dword by dword
begin
if(ll_data_val_in)
if(ll_data_last_in)
// incorrect frame size
begin
bad_fis_received<=1'b1;
STATE_IDLE<=STATE_IDLE;
end
else
// going to the next dword, parse current one: DMA Transfer Count
begin
loc_dma_cnt[31:0]<=ll_data_in[31:0];
state<=STATE_IN_DMAS_6;
end
end
STATE_IN_DMAS_6:
// receiving DMA Setup FIS, dword by dword
begin
if(ll_data_val_in)
if(ll_data_last_in)
// correct frame size, finishing, current dword: Reserved
begin
state<=STATE_IN_IDLE;
end
else
// incorrect frame size
begin
state<=STATE_IN_DMAS_ERR;
err_timer<=14'h6;
end
end
STATE_IN_DMAS_ERR:
// FIS was started as DMA Setup, but for some reason it has a size more than needed
// just wait until it's over and assert an error
begin
if(ll_data_val_in)
if(ll_data_last_in)
begin
bad_fis_received<=1'b1;
state<=STATE_IDLE;
end
else
begin
if(err_timeout)
// if for some reason FIS continue transferring for too long, terminate it
begin
state<=STATE_IDLE;
incom_stop_req_timeout<=1'b1;
end
else
err_timer<=err_timer+1'b1;
end
end
STATE_IN_BIST_1:
// receiving BIST FIS, dword by dword
begin
if(ll_data_val_in)
if(ll_data_last_in)
// incorrect frame size
begin
bad_fis_received<=1'b1;
STATE_IDLE<=STATE_IDLE;
end
else
// going to the next dword, parse current one: TODO
begin
state<=STATE_IN_BIST_2;
end
end
STATE_IN_BIST_2:
// receiving BIST FIS, dword by dword
begin
if(ll_data_val_in)
if(ll_data_last_in)
// correct frame size, finishing, current dword: Reserved
begin
state<=STATE_IN_IDLE;
end
else
// incorrect frame size
begin
state<=STATE_IN_BIST_ERR;
err_timer<=14'h2;
end
end
STATE_IN_BIST_ERR:
// FIS was started as BIST Activate, but for some reason it has a size more than needed
// just wait until it's over and assert an error
begin
if(ll_data_val_in)
if(ll_data_last_in)
begin
bad_fis_received<=1'b1;
state<=STATE_IDLE;
end
else
begin
if(err_timeout)
// if for some reason FIS continue transferring for too long, terminate it
begin
state<=STATE_IDLE;
incom_stop_req_timeout<=1'b1;
end
else
err_timer<=err_timer+1'b1;
end
end
STATE_IN_PIOS_1:
// receiving PIO Setup FIS, dword by dword
begin
if(ll_data_val_in)
if(ll_data_last_in)
// incorrect frame size
begin
bad_fis_received<=1'b1;
STATE_IDLE<=STATE_IDLE;
end
else
// going to the next dword, parse current one: {Device, LBA High, LBA Mid, LBA Low}
begin
loc_lba[7:0]<=ll_data_in[7:0];
loc_lba[23:16]<=ll_data_in[15:8];
loc_lba[39:32]<=ll_data_in[23:16];
loc_device<=ll_data_in[31:24];
state<=STATE_IN_PIOS_2;
end
end
STATE_IN_PIOS_2:
// receiving PIO Setup FIS, dword by dword
begin
if(ll_data_val_in)
if(ll_data_last_in)
// incorrect frame size
begin
bad_fis_received<=1'b1;
STATE_IDLE<=STATE_IDLE;
end
else
// going to the next dword, parse current one: {Reserved, LBA High (exp), LBA Mid (exp), LBA Low (exp)}
begin
loc_lba[15:8]<=ll_data_in[7:0];
loc_lba[31:24]<=ll_data_in[15:8];
loc_lba[47:40]<=ll_data_in[23:16];
state<=STATE_IN_PIOS_3;
end
end
STATE_IN_PIOS_3:
// receiving PIOS FIS, dword by dword
begin
if(ll_data_val_in)
if(ll_data_last_in)
// incorrect frame size
begin
bad_fis_received<=1'b1;
STATE_IDLE<=STATE_IDLE;
end
else
// going to the next dword, parse current one: {E_Status, Reserved, Sector Count (exp), Sector Count}
begin
loc_count[15:0]<=ll_data_in[15:0];
loc_estatus<=ll_data_in[31:24];
state<=STATE_IN_PIOS_4;
end
end
STATE_IN_BIST_4:
// receiving BIST FIS, dword by dword
begin
if(ll_data_val_in)
if(ll_data_last_in)
// correct frame size, finishing, current dword: {Reserved, Transfer Count}
begin
loc_tran_cnt<=ll_data_in[15:0];
state<=STATE_IN_IDLE;
end
else
// incorrect frame size
begin
state<=STATE_IN_BIST_ERR;
err_timer<=14'h4;
end
end
STATE_IN_PIOS_ERR:
// FIS was started as PIO Setup Activate, but for some reason it has a size more than needed
// just wait until it's over and assert an error
begin
if(ll_data_val_in)
if(ll_data_last_in)
begin
bad_fis_received<=1'b1;
state<=STATE_IDLE;
end
else
begin
if(err_timeout)
// if for some reason FIS continue transferring for too long, terminate it
begin
state<=STATE_IDLE;
incom_stop_req_timeout<=1'b1;
end
else
err_timer<=err_timer+1'b1;
end
end
STATE_IN_SDB_1:
// receiving Set Device Bits FIS, dword by dword
begin
if(ll_data_val_in)
if(ll_data_last_in)
// correct frame size, finishing, current dword: Reserved
begin
state<=STATE_IN_IDLE;
end
else
// incorrect frame size
begin
state<=STATE_IN_SDB_ERR;
err_timer<=14'h1;
end
end
STATE_IN_SDB_ERR:
// FIS was started as Set Device Bits FIS, but for some reason it has a size more than needed
// just wait until it's over and assert an error
begin
if(ll_data_val_in)
if(ll_data_last_in)
begin
bad_fis_received<=1'b1;
state<=STATE_IDLE;
end
else
begin
if(err_timeout)
// if for some reason FIS continue transferring for too long, terminate it
begin
state<=STATE_IDLE;
incom_stop_req_timeout<=1'b1;
end
else
err_timer<=err_timer+1'b1;
end
end
STATE_OUT_DATA_H:
// Send data FIS header
begin
if(ll_data_strobe_in)
begin
state<=STATE_OUT_DATA_D;
dword_cnt<=14'h1;
end
end
STATE_OUT_DATA_D:
// Send data FIS data payload
begin
if(ll_data_strobe_in)
begin
if(cl_data_last_in)
// All data is transmitted
dword_cnt<=14'h0;
state<=STATE_OUT_WAIT_RESP;
else
if(dword_cnt==2048)
// data_limit_exceed - wire assigned
state<=STATE_IDLE;
else
begin
state<=STATE_OUT_DATA_D;
dword_cnt<=dword_cnt+1'b1;
end
end
end
STATE_OUT_REG:
// Register Host 2 Device FIS
begin
if(ll_data_strobe_in)
// 5 header dwords, then wait for a reception on a device side
if(dword_cnt[2:0]==3'h4)
dword_cnt<=14'h0;
state<=STATE_OUT_WAIT_RESP;
else
begin
state<=STATE_OUT_REG;
dword_cnt<=dword_cnt+1'b1;
end
end
STATE_OUT_DMAS:
// DMA Setup outcoming FIS
begin
if(ll_data_strobe_in)
// 7 header dwords, then wait for a reception on a device side
if(dword_cnt[2:0]==3'h6)
dword_cnt<=14'h0;
state<=STATE_OUT_WAIT_RESP;
else
begin
state<=STATE_OUT_DMAS;
dword_cnt<=dword_cnt+1'b1;
end
end
STATE_OUT_BIST:
begin
if(ll_data_strobe_in)
// 3 header dwords, then wait for a reception on a device side
if(dword_cnt[2:0]==3'h2)
dword_cnt<=14'h0;
state<=STATE_OUT_WAIT_RESP;
else
begin
state<=STATE_OUT_BIST;
dword_cnt<=dword_cnt+1'b1;
end
end
STATE_OUT_WAIT_RESP:
begin
if(frame_done_good)
// cmd_done_good wire assigned
state<=STATE_IDLE;
else
if(frame_done_bad)
// cmd_done_bad wire assigned
state<=STATE_IDLE;
else
if(dword_cnt==WATCHDOG_EOF_LIMIT)
// in here dword_cnt works as a watchdog timer
begin
state<=STATE_IDLE;
// watchdog_eof wire assigned
// for now while debugging let it be indicated on higher level TODO Choose exception. May be send incom stop req.
// Be aware of no response for that. In such case go for rst for ll. Or better make link_reset -> 1. And dont forget for oob
else
begin
dword_cnt<=dword_cnt+1'b1;
state<=STATE_OUT_WAIT_RESP;
end
end
STATE_IN_UNRECOG:
begin
end
default:
begin
end
endcase
// Reg H2D FIS header
wire[31:0]header_regfis;
assignheader_regfis=dword_cnt[2:0]==3'h0?{sh_feature_in[7:0],sh_command_in,cmd_type_r==CMD_TYPE_REG_CMD,3'h0,cmd_port_r,8'h27}:// features command C R R R PMPort FISType
assignheader_dmas=dword_cnt[3:0]==3'h0?{8'h0,8'h0,sh_autoact_in,sh_inter_in,sh_dir_in,1'b0,cmd_port_r,8'h41}:// Reserved, Reserved, A I D R PMPort, FIS Type