// -------------------------------------------------------------------
// Avalon_MM data interface fsm - communicate between Avalon_MM and Flash IP (Write Operation)
// -------------------------------------------------------------------
always @ (posedge clock) begin
if (~reset_n_w) begin
write_state <= WRITE_STATE_IDLE;
write_wait <= 0;
end
else begin
case (write_state)
WRITE_STATE_IDLE: begin
// reset all register
write_count <= 0;
write_timeout <= 1'b0;
enable_drclk_neg_pos_write_reg <= 0;
// check command
if (avmm_write) begin
if (~valid_csr_erase && ~is_erase_busy && ~is_read_busy) begin
write_wait <= 1;
// address legality check
if (is_addr_writable && is_valid_write_burst_count) begin
write_state <= WRITE_STATE_WRITE;
write_count <= DATA_WIDTH[5:0];
end
else begin
write_state <= WRITE_STATE_ERROR;
write_wait <= 0;
write_count <= 2;
end
end
end
end
WRITE_STATE_WRITE: begin
if (write_count > 0) begin//(write_count != 0) begin write_drclk_en <= 1;
write_count <= write_count - 16'd1;
end
else begin
enable_drclk_neg_pos_write_reg <= 1;
write_drclk_en <= 0;
write_count <= FLASH_BUSY_TIMEOUT_CYCLE_MAX_INDEX[15:0];
write_state <= WRITE_STATE_WAIT_BUSY;
end
end
WRITE_STATE_WAIT_BUSY: begin
if (flash_busy_reg) begin
write_count <= FLASH_WRITE_TIMEOUT_CYCLE_MAX_INDEX[15:0];
write_state <= WRITE_STATE_WAIT_DONE;
end
else begin
if (write_count > 0) //(write_count != 0) write_count <= write_count - 16'd1;
else begin
write_timeout <= 1'b1;
write_count <= FLASH_RESET_CYCLE_MAX_INDEX[15:0];
write_state <= WRITE_STATE_RESET;
end
end
end
WRITE_STATE_WAIT_DONE: begin
if (~flash_busy) begin
write_count <= FLASH_RESET_CYCLE_MAX_INDEX[5:0];
write_state <= WRITE_STATE_RESET;
end
else begin
if (write_count > 0) begin//(write_count != 0) begin write_count <= write_count - 16'd1;
end
else begin
write_timeout <= 1'b1;
write_count <= FLASH_RESET_CYCLE_MAX_INDEX[15:0];
write_state <= WRITE_STATE_RESET;
end
end
end
WRITE_STATE_RESET: begin
if (write_timeout) begin
csr_status_w_pass <= 1'b0;
end
else begin
csr_status_w_pass <= flash_sp_pass_reg;
end
if (write_count == 1) begin
write_wait <= 0;
end
if (write_count > 0) begin//(write_count != 0) begin write_count <= write_count - 16'd1;
end
else begin
write_state <= WRITE_STATE_IDLE;
end
end
WRITE_STATE_ERROR: begin
csr_status_w_pass <= 0;
if (write_count == 1) begin
write_wait <= 0;
end
if (write_count > 0) begin//(write_count != 0) begin write_count <= write_count - 16'd1;
end
else begin
write_state <= WRITE_STATE_IDLE;
end
end
default: begin
write_state <= WRITE_STATE_IDLE;
end
endcase
end
end