max10 on chip flash write issue (without nios)
hi, can anyone help to answer this question?
I am trying to write data to max10 on chip flash(UFM) without using NIOS.
what i am doing is to write a simple controller module and send the control signal required by on_chip_flash ip.
The steps can be described as follows:
1, disable write protection
2, do sector erase
3, write data to UFM
4, read back the data and verify the writing is successful or not.
5, enable write protection bit
my question is if i read back signal after write, data is correct. However, if i disable the write process, and read the address
directly (same address as i write before), the data is always FFFF. It seems that the data is not write into flash successfully.
However, during the wite process, the statue signal from avmm_csr_readdata shows that the erase/write operation is successful.
And the data can be read back correctly after the write process. Please help to solve this problem. Thanks!
Attached please find the cource code of the controller.
module main_controller
(
clock,
reset_n,
UFM_ADDRESS1,
UFM_ADDRESS2,
display_count1,
display_count2,
data_valid,
csr_status,
CSR_IDLE,
CSR_OP_WRITE_PASS,
CSR_OP_READ_PASS,
CSR_OP_ERASE_PASS,
CSR_BUSY_ERASE,
CSR_BUSY_WRITE,
CSR_BUSY_READ,
write_protect,
mc_state_machine
);
parameter COUNTER_BITS = 32;
parameter read_only = 1;
input clock;
input reset_n;
input [19:0] UFM_ADDRESS1;
input [19:0] UFM_ADDRESS2;
input [COUNTER_BITS-1:0] display_count1; //
input [COUNTER_BITS-1:0] display_count2;
output reg data_valid; //
output [9:0] csr_status;
output CSR_IDLE;
output CSR_OP_WRITE_PASS;
output CSR_OP_READ_PASS;
output CSR_OP_ERASE_PASS;
output CSR_BUSY_ERASE;
output CSR_BUSY_WRITE;
output CSR_BUSY_READ;
output [4:0] write_protect;
output [5:0] mc_state_machine; //
///////////////////////////////////////////////
// mc_state_machine states
`define IDLE 6'b000000
`define FETCH_FLASH 6'b000001
`define FLASH_READ1 6'b000010
`define FLASH_READ2 6'b000011
`define FLASH_READ3 6'b000100
`define FLASH_READ4 6'b000101
`define READ_FLASH_DONE 6'b000110
`define WAIT_FOR_INIT_SHUTDOWN 6'b000111
`define START_SHUTDOWN 6'b001000
`define CSR_MASK_OFF1 6'b001001
`define CSR_MASK_OFF2 6'b001010
`define CSR_MASK_OFF3 6'b001011
`define CSR_MASK_OFF4 6'b001100
`define CSR_READ1 6'b001101
`define CSR_READ2 6'b001110
`define CSR_READ3 6'b001111
`define CSR_READ4 6'b010000
`define CSR_READ5 6'b010001
`define CSR_READ6 6'b010010
`define FLASH_WRITE0 6'b010011
`define FLASH_WRITE1 6'b010100
`define FLASH_WRITE2 6'b010101
`define FLASH_WRITE3 6'b010110
`define FLASH_WRITE4 6'b010111
`define FLASH_WRITE5 6'b011000
`define FLASH_WRITE6 6'b011001
`define FLASH_WRITE7 6'b011010
`define FLASH_WRITE_DONE 6'b011011
`define FLASH_VERIFY1 6'b011100
`define FLASH_VERIFY2 6'b011101
`define FLASH_VERIFY3 6'b011110
`define FLASH_VERIFY4 6'b011111
`define CSR_MASK_ON1 6'b100000
`define CSR_MASK_ON2 6'b100001
`define CSR_MASK_ON3 6'b100010
`define CSR_MASK_VERIFY1 6'b100011
`define CSR_MASK_VERIFY2 6'b100100
`define CSR_MASK_VERIFY3 6'b100101
`define POWER_DOWN_READY 6'b100110
////////////////////////////////////////////////
reg [19:0] avmm_data_addr;
reg avmm_data_read;
reg [31:0] avmm_data_writedata;
reg avmm_data_write;
reg [3:0] avmm_data_burstcount;
wire [31:0] avmm_data_readdata;
reg avmm_csr_addr;
reg avmm_csr_read;
reg [31:0] avmm_csr_writedata;
reg avmm_csr_write;
reg [31:0] flash_dataout1, flash_dataout2;
reg [5:0] mc_state_machine;
wire [31:0] avmm_csr_readdata;
wire avmm_data_waitrequest;
wire avmm_data_readdatavalid;
assign csr_status = avmm_csr_readdata[9:0];
assign write_protect= avmm_csr_readdata[9:5];
////////////////////////
//wire CSR_IDLE, CSR_OP_WRITE_PASS,CSR_OP_READ_PASS,CSR_OP_ERASE_PASS;
assign CSR_IDLE=(csr_status[1:0]==2'b00)?1'b1:1'b0;
assign CSR_BUSY_ERASE=(csr_status[1:0]==2'b01)?1'b1:1'b0;///5'bxxx01
assign CSR_BUSY_WRITE=(csr_status[1:0]==2'b10)?1'b1:1'b0;///5'bxxx10
assign CSR_BUSY_READ=(csr_status[1:0]==2'b11)?1'b1:1'b0;///5'bxxx11
assign CSR_OP_WRITE_PASS=(csr_status[3]);
assign CSR_OP_READ_PASS=(csr_status[2]);
assign CSR_OP_ERASE_PASS=(csr_status[4]);
//////////////////////////////////////////////////////
// Flash IP instance
on_chip_flash flash_inst (
.clock (clock), // clk.clk
.reset_n (reset_n), // nreset.reset_n
.avmm_data_addr (avmm_data_addr), // data.address
.avmm_data_read (avmm_data_read), // .read
.avmm_data_writedata (avmm_data_writedata), // .writedata
.avmm_data_write (avmm_data_write), // .write
.avmm_data_readdata (avmm_data_readdata), // .readdata
.avmm_data_waitrequest (avmm_data_waitrequest), // .waitrequest
.avmm_data_readdatavalid (avmm_data_readdatavalid), // .readdatavalid
.avmm_data_burstcount (avmm_data_burstcount), // .burstcount
.avmm_csr_addr (avmm_csr_addr), // csr.address
.avmm_csr_read (avmm_csr_read), // .read
.avmm_csr_writedata (avmm_csr_writedata), // .writedata
.avmm_csr_write (avmm_csr_write), // .write
.avmm_csr_readdata (avmm_csr_readdata) // .readdata
);
always @ (posedge clock)
if (~reset_n) data_valid<=1'b0;
else if (flash_dataout1==display_count1) data_valid<=1'b1;
else data_valid<=data_valid;
always @ (posedge clock)
begin
if (~reset_n)
begin
//inputs
//AV MM
//////////////////////////
avmm_data_addr <= 20'h00000;
avmm_data_read <= 1'b0;
avmm_data_writedata <= 32'h0000_0000;
avmm_data_write <= 1'b0;
avmm_data_burstcount <= 4'b0001;
//AV CSR
avmm_csr_addr <= 1'b0;
avmm_csr_read <= 1'b0;
avmm_csr_write <= 1'b0;
avmm_csr_writedata <= 32'hFFFF_FFFF;
//General Purpose
mc_state_machine <= 6'b000000;
flash_dataout1 <=32'b0;
flash_dataout2 <=32'b0;
///////////////////
end
else begin
case (mc_state_machine)
`IDLE : begin///0
//////////////////////////
avmm_data_addr <= 20'h00000;
avmm_data_read <= 1'b0;
avmm_data_writedata <= 32'h0000_0000;
avmm_data_write <= 1'b0;
avmm_data_burstcount <= 4'b0001;
//AV CSR
avmm_csr_addr <= 1'b0;
avmm_csr_read <= 1'b0;
avmm_csr_write <= 1'b0;
avmm_csr_writedata <= 32'hFFFF_FFFF;
//General Purpose
flash_dataout1 <=32'b0;
flash_dataout2 <=32'b0;
///////////////////
mc_state_machine <= `FETCH_FLASH;////read
end
//////////////////////////////////////////
`FETCH_FLASH : begin ///1
avmm_data_burstcount <= 4'b0001;
if (avmm_data_waitrequest) mc_state_machine <= `FETCH_FLASH;
else mc_state_machine <= `FLASH_READ1;
end
`FLASH_READ1 : begin///2
data_read1(UFM_ADDRESS1-0);
mc_state_machine <= `FLASH_READ2;
end
`FLASH_READ2 : begin///3
data_read2;
mc_state_machine <= `FLASH_READ3;
end
`FLASH_READ3 : begin///4
if (!avmm_data_readdatavalid) mc_state_machine <= `FLASH_READ3;
else
begin
data_read3;
flash_dataout1 <= avmm_data_readdata;
mc_state_machine <= `FLASH_READ4;
end
end
`FLASH_READ4 : begin///5
mc_state_machine <= `READ_FLASH_DONE;
end
`READ_FLASH_DONE : begin////6
////////////////////////
if(read_only) mc_state_machine <= `POWER_DOWN_READY;
else mc_state_machine <= `WAIT_FOR_INIT_SHUTDOWN;
////////////////////////
//mc_state_machine <= `POWER_DOWN_READY;
end
//////////////////////////////////////////
///write start here
`WAIT_FOR_INIT_SHUTDOWN : begin////7
avmm_data_burstcount <= 4'b0001;
avmm_csr_addr <= 1'b1;///control register
if (CSR_IDLE) mc_state_machine <= `START_SHUTDOWN;
else mc_state_machine <=`WAIT_FOR_INIT_SHUTDOWN;
end
`START_SHUTDOWN : begin////8
avmm_csr_writedata[24:23] <= 2'b00;
mc_state_machine <= `CSR_MASK_OFF1;
end
`CSR_MASK_OFF1 : begin////9
csr_write1(1,avmm_csr_writedata);///write control data
mc_state_machine <= `CSR_MASK_OFF2;
end
`CSR_MASK_OFF2 : begin////A
csr_write2(0);///
mc_state_machine <= `CSR_MASK_OFF3;
end
`CSR_MASK_OFF3 : begin////B
csr_read1(0);///
mc_state_machine <= `CSR_MASK_OFF4;
end
`CSR_MASK_OFF4 : begin////C
csr_read2(0);///
mc_state_machine <= `CSR_READ1;
end
////////////////////////////////////////////////////////////////
`CSR_READ1 : begin////
//avmm_csr_writedata[22:20] <= 3'b010;///!!!!
//avmm_csr_writedata[22:20] <= 3'b001;
avmm_csr_writedata[19:0] <= 20'h0001;
if (CSR_IDLE) mc_state_machine <= `CSR_READ2;
else mc_state_machine <= `CSR_READ1;
end
`CSR_READ2 : begin////E
csr_write1(1,avmm_csr_writedata);
mc_state_machine <= `CSR_READ3;
end
`CSR_READ3 : begin////F
csr_write2(0);
mc_state_machine <= `CSR_READ4;
end
`CSR_READ4 : begin////10
mc_state_machine <= `CSR_READ5;
end
`CSR_READ5 : begin////11
mc_state_machine <= `CSR_READ6;
end
`CSR_READ6 : begin////12
if (CSR_IDLE && CSR_OP_ERASE_PASS) mc_state_machine <= `FLASH_WRITE0;
else mc_state_machine <= `CSR_READ6;
end
///////////////////////////////////////
`FLASH_WRITE0 : begin////15
if (avmm_data_waitrequest) mc_state_machine <= `FLASH_WRITE0;
else mc_state_machine <= `FLASH_WRITE1;
end
`FLASH_WRITE1 : begin////13
data_write1(UFM_ADDRESS1, display_count1);
mc_state_machine <= `FLASH_WRITE2;
end
`FLASH_WRITE2 : begin////14
if (avmm_data_waitrequest) mc_state_machine <= `FLASH_WRITE2;
else begin
data_write2(UFM_ADDRESS1, display_count1);
mc_state_machine <= `FLASH_WRITE3;
end
////////////////
//data_write2(UFM_ADDRESS1, display_count1);
//mc_state_machine <= `FLASH_WRITE3;
end
//////////////////////////
`FLASH_WRITE3 : begin////15
if (avmm_data_waitrequest) mc_state_machine <= `FLASH_WRITE3;
else mc_state_machine <= `FLASH_WRITE4;
end
`FLASH_WRITE4 : begin////16
data_write1(UFM_ADDRESS2, display_count2);
mc_state_machine <=`FLASH_WRITE5;
end
`FLASH_WRITE5 : begin////16
if (avmm_data_waitrequest) mc_state_machine <= `FLASH_WRITE5;
else begin
data_write2(UFM_ADDRESS2, display_count2);
mc_state_machine <= `FLASH_WRITE6;
end
///////////////
//data_write2(UFM_ADDRESS2, display_count2);
//mc_state_machine <=`FLASH_WRITE6;
end
`FLASH_WRITE6 : begin////16
if (avmm_data_waitrequest) mc_state_machine <= `FLASH_WRITE6;
else mc_state_machine <= `FLASH_WRITE7;
end
`FLASH_WRITE7 : begin////17
if (CSR_IDLE && CSR_OP_WRITE_PASS) mc_state_machine <= `FLASH_VERIFY4;
else mc_state_machine <= `FLASH_WRITE7;
end
///////////////////////////////
// `FLASH_WRITE_DONE : begin////18
// //avmm_data_burstcount <= 4'b0001;
// if (avmm_data_waitrequest) mc_state_machine <= `FLASH_WRITE_DONE;
// else mc_state_machine <= `FLASH_VERIFY1;
// end
// `FLASH_VERIFY1 : begin////19
// data_read1(UFM_ADDRESS1);
// mc_state_machine <= `FLASH_VERIFY2;
// end
// `FLASH_VERIFY2 : begin////1A
// data_read2;
// mc_state_machine <= `FLASH_VERIFY3;
// end
// `FLASH_VERIFY3 : begin////1B
// data_read3;
// if (!avmm_data_readdatavalid) mc_state_machine <= `FLASH_VERIFY3;
// else
// begin
// flash_dataout1 <= avmm_data_readdata;
// mc_state_machine <= `FLASH_VERIFY4;
// end
// end
///////////////////////////////
`FLASH_VERIFY4 : begin////1c
avmm_csr_writedata[24:20] <= 5'b11111;
avmm_csr_writedata[19:0] <= 20'hFFFF;
mc_state_machine <= `CSR_MASK_ON1;
end
`CSR_MASK_ON1 : begin////1D
csr_write1(1,avmm_csr_writedata);
mc_state_machine <= `CSR_MASK_ON2;
end
`CSR_MASK_ON2 : begin////1E
csr_write2(0);
mc_state_machine <= `CSR_MASK_VERIFY1;
end
`CSR_MASK_ON3 : begin////1F
if (CSR_IDLE) mc_state_machine <= `CSR_MASK_VERIFY1;
else mc_state_machine <= `CSR_MASK_ON3;
end
////////////////////////////////
`CSR_MASK_VERIFY1 : begin////20
csr_read1(0);
mc_state_machine <= `CSR_MASK_VERIFY2;
end
`CSR_MASK_VERIFY2 : begin////21
csr_read2(0);
mc_state_machine <= `CSR_MASK_VERIFY3;
end
`CSR_MASK_VERIFY3 : begin////22
mc_state_machine <= `POWER_DOWN_READY;
end
`POWER_DOWN_READY : begin////23
mc_state_machine <= `POWER_DOWN_READY;
end
default : mc_state_machine <= `IDLE;
endcase //end case(mc_state_machine)
end
end //end always
///////////////////////////////////////////
task csr_write1;
input addr;
input [31:0] data;
begin
avmm_csr_addr <= addr;
avmm_csr_writedata <= data;
avmm_csr_write <= 1'b1;
end
endtask
task csr_write2;
input addr;
begin
avmm_csr_addr <= addr;
avmm_csr_write <= 1'b0;
end
endtask
task csr_read1;
input addr;
begin
avmm_csr_addr <= addr;
avmm_csr_read <= 1'b1;
end
endtask
task csr_read2;
input addr;
begin
avmm_csr_addr <= addr;
avmm_csr_read <= 1'b0;
end
endtask
task data_read1;
input [19:0] addr;
begin
avmm_csr_read <= 1'b0;
avmm_csr_write <= 1'b0;
avmm_csr_addr <= 1'b0;
avmm_data_addr <= addr;
avmm_data_read <= 1'b1;
end
endtask
task data_read2;
begin
avmm_csr_read <= 1'b0;
avmm_csr_write <= 1'b0;
avmm_csr_addr <= 1'b0;
avmm_data_read <= 1'b0;
end
endtask
task data_read3;
begin
avmm_csr_read <= 1'b0;
avmm_csr_write <= 1'b0;
avmm_csr_addr <= 1'b0;
end
endtask
task data_write1;
input [19:0] addr;
input [31:0] data;
begin
avmm_csr_read <= 1'b0;
avmm_csr_write <= 1'b0;
avmm_csr_addr <= 1'b0;
avmm_data_addr <= addr;
avmm_data_writedata <= data;
avmm_data_write <= 1'b1;
end
endtask
task data_write2;
input [19:0] addr;
input [31:0] data;
begin
avmm_csr_read <= 1'b0;
avmm_csr_write <= 1'b0;
avmm_csr_addr <= 1'b0;
avmm_data_addr <= addr;
avmm_data_writedata <= data;
avmm_data_write <= 1'b0;
end
endtask
endmodule