FPGA Intellectual Property
PCI Express*, Networking and Connectivity, Memory Interfaces, DSP IP, and Video IP
Announcements
Intel Support hours are Monday-Fridays, 8am-5pm PST, except Holidays. Thanks to our community members who provide support during our down time or before we get to your questions. We appreciate you!

Need Forum Guidance? Click here
Search our FPGA Knowledge Articles here.

altera_onchip_flash

Altera_Forum
Honored Contributor II
824 Views

The submodule "altera_onchip_flash_avmm_data_controller" in this IP has some problem. 

WRITE_STATE, this FSM will unexpectedly been hold when I continues write data to flash. 

It will cause status stock in write busy. csr_readdata[1:0] will equal to 2'b10 which means BUSY_WRITE for a long time. 

It might be something wrong with its' state machine.  

I guess the register "write_count " is overflow, so I replace "write_count != 0" to "write_count > 0" . 

Finally, it work out. 

 

 

// ------------------------------------------------------------------- 

// Avalon_MM data interface fsm - communicate between Avalon_MM and Flash IP (Write Operation) 

// -------------------------------------------------------------------
0 Kudos
4 Replies
Altera_Forum
Honored Contributor II
101 Views

// ------------------------------------------------------------------- 

// 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
Altera_Forum
Honored Contributor II
101 Views

i replace all (write_count != 0) to (write_count > 0) in the WRITE_STATE FSM 

 

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
Altera_Forum
Honored Contributor II
101 Views

I do some simulation. Two type coding looks totally different on technology map. 

 

A type coding : "write_count != 0" 

The FSM will fail if there is a glitch on clock. 

 

B type coding : "write_count > 0" 

The FSM will be fine if there is a glitch on clock. 

 

By the way, my device is MAX10. I think MAX10's clock may have some problem. 

 

Where can i share these simulation file?  

Can anyone teach me why these two type coding make so much different on the end? 

Thanks a lot.
Altera_Forum
Honored Contributor II
101 Views

I think you saw success with the modification you made because the actual problem is a timing error. You must have gotten lucky on the new compile to have it not lock up the internal logic. The real issue is a timing bug with the busy signal. The fix I put in place for the 14.1 standard release code was to change line 446 from: 

 

always @ (negedge reset_n or negedge is_busy or posedge flash_osc) begin 

 

to 

 

always @ (negedge reset_n or negedge is_busy or posedge clock) begin 

 

The problem was that the flash_busy_reg signal needed to get latched in the clock domain, not the flash_osc domain. When I made this change it resolved all the timing errors and also worked flawlessly. After I reported this to Altera they informed me that there is a patch to install on 14.1 that also fixes this.
Reply