Forum Discussion

Gouri's avatar
Gouri
Icon for New Contributor rankNew Contributor
2 years ago

On chip flash memory not updating avmm_data_readvalid signal in Read operation

https://www.intel.com/content/dam/altera-www/global/en_US/uploads/7/73/MAX10_On-Chip_Flash_IP_Read_Operation_Example.pdf

  • With respect above document of read write operation in On chip flash UFM IP written as below 2 files NVM_top.v & NVM_Read_write.v
  • Using max10m16 FPGA
  • still facing error during read operation in signal tap that IP not giving AVMM_DATA_READVALIED signal

NVM_top.v

library ieee;
use ieee.numeric_std.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.std_logic_1164.all;
entity NVM_top is
port(
clock_20mhz_i : in std_logic;
reset_ni : in std_logic;
en_read_i : in STD_LOGIC;
en_write_i : in STD_LOGIC;
data_write_i : in STD_LOGIC_VECTOR(31 DOWNTO 0);
avmm_data_readdata_o : out std_logic_vector(31 downto 0)
);
end entity;
architecture arch of NVM_top is
component eLADEP_NVM
port (
clock : in std_logic := '0'; -- clk.clk
avmm_csr_addr : in std_logic := '0'; -- csr.address
avmm_csr_read : in std_logic := '0'; -- .read
avmm_csr_writedata : in std_logic_vector(31 downto 0) := (others => '0'); -- .writedata
avmm_csr_write : in std_logic := '0'; -- .write
avmm_csr_readdata : out std_logic_vector(31 downto 0); -- .readdata
avmm_data_addr : in std_logic_vector(12 downto 0) := (others => '0'); -- data.address
avmm_data_read : in std_logic := '0'; -- .read
avmm_data_writedata : in std_logic_vector(31 downto 0) := (others => '0'); -- .writedata
avmm_data_write : in std_logic := '0'; -- .write
avmm_data_readdata : out std_logic_vector(31 downto 0); -- .readdata
avmm_data_waitrequest : out std_logic; -- .waitrequest
avmm_data_readdatavalid : out std_logic; -- .readdatavalid
avmm_data_burstcount : in std_logic_vector(3 downto 0) := (others => '0'); -- .burstcount
reset_n : in std_logic := '0' -- nreset.reset_n
);
end component;
component NVM_Read_write is
port(
clock_20mhz_i : in std_logic;
reset_ni : in std_logic;
csr_readdata_i : in STD_LOGIC_VECTOR(31 DOWNTO 0);
waitrequest_i : in STD_LOGIC;
readvalid_i : in STD_LOGIC;
en_read_i : in STD_LOGIC;
en_write_i : in STD_LOGIC;
data_write_i : in STD_LOGIC_VECTOR(31 DOWNTO 0);
csr_addr_o : OUT STD_LOGIC;
csr_writedata_o : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
csr_write_o : OUT STD_LOGIC;
csr_read_o : OUT STD_LOGIC;
data_addr_o : OUT STD_LOGIC_VECTOR(12 DOWNTO 0);
data_writedata_o : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
data_write_o : OUT STD_LOGIC;
data_read_o : OUT STD_LOGIC;
readvalid_counter_o : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
burstcount_o : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
end component;
signal avmm_csr_readdata_s : std_logic_vector(31 downto 0); -- .readdata
signal avmm_data_readdata_s : std_logic_vector(31 downto 0); -- .readdata
signal avmm_data_waitrequest_s : std_logic; -- .waitrequest
signal avmm_data_readdatavalid_s : std_logic; -- .readdatavalid
SIGNAL csr_readdata_s : std_logic_vector (31 downto 0);
SIGNAL waitrequest_s : STD_LOGIC;
SIGNAL readvalid_s : STD_LOGIC;
--SIGNAL en_read_s : STD_LOGIC;
--SIGNAL en_write_s : STD_LOGIC;
SIGNAL csr_addr_s : STD_LOGIC;
SIGNAL csr_writedata_s : std_logic_vector (31 downto 0);
SIGNAL csr_write_s : STD_LOGIC;
SIGNAL csr_read_s : STD_LOGIC;
SIGNAL data_addr_s : std_logic_vector (12 downto 0);
SIGNAL data_writedata_s : std_logic_vector (31 downto 0);
SIGNAL data_write_s : STD_LOGIC;
SIGNAL data_read_s : STD_LOGIC;
SIGNAL readvalid_counter_s : std_logic_vector (3 downto 0);
SIGNAL burstcount_s : std_logic_vector (3 downto 0);
begin
inst1: eLADEP_NVM
PORT MAP(
clock => clock_20mhz_i, -- clk.clk
avmm_csr_addr => csr_addr_s, -- csr.address
avmm_csr_read => csr_read_s, -- .read
avmm_csr_writedata => csr_writedata_s, -- .writedata
avmm_csr_write => csr_write_s, -- .write
avmm_csr_readdata => avmm_csr_readdata_s, -- .readdata
avmm_data_addr => data_addr_s, -- data.address
avmm_data_read => data_read_s, -- .read
avmm_data_writedata => data_writedata_s, -- .writedata
avmm_data_write => data_write_s, -- .write
avmm_data_readdata => avmm_data_readdata_s,-- .readdata
avmm_data_waitrequest => avmm_data_waitrequest_s, -- .waitrequest
avmm_data_readdatavalid => avmm_data_readdatavalid_s, -- .readdatavalid
avmm_data_burstcount => burstcount_s,-- .burstcount
reset_n => reset_ni -- nreset.reset_n
);
inst2: NVM_Read_write
PORT MAP(
clock_20mhz_i => clock_20mhz_i,
reset_ni => reset_ni ,
csr_readdata_i => avmm_csr_readdata_s ,
waitrequest_i => avmm_data_waitrequest_s ,
readvalid_i => avmm_data_readdatavalid_s ,
en_read_i => en_read_i ,
en_write_i => en_write_i ,
data_write_i => data_write_i ,
csr_addr_o => csr_addr_s,
csr_writedata_o => csr_writedata_s,
csr_write_o => csr_write_s,
csr_read_o => csr_read_s,
data_addr_o => data_addr_s,
data_writedata_o => data_writedata_s,
data_write_o => data_write_s,
data_read_o => data_read_s,
readvalid_counter_o => readvalid_counter_s,
burstcount_o => burstcount_s
);
avmm_data_readdata_o <= avmm_data_readdata_s;
END ARCHITECTURE arch;

NVM_Read_write.v

library ieee;
use ieee.numeric_std.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.std_logic_1164.all;
entity NVM_Read_write is
port(
clock_20mhz_i : in std_logic;
reset_ni : in std_logic;
csr_readdata_i : in STD_LOGIC_VECTOR(31 DOWNTO 0);
waitrequest_i : in STD_LOGIC;
readvalid_i : in STD_LOGIC;
en_read_i : in STD_LOGIC;
en_write_i : in STD_LOGIC;
data_write_i : in STD_LOGIC_VECTOR(31 DOWNTO 0); -- GA
csr_addr_o : OUT STD_LOGIC;
csr_writedata_o : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
csr_write_o : OUT STD_LOGIC;
csr_read_o : OUT STD_LOGIC;
data_addr_o : OUT STD_LOGIC_VECTOR(12 DOWNTO 0);
data_writedata_o : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
data_write_o : OUT STD_LOGIC;
data_read_o : OUT STD_LOGIC;
readvalid_counter_o : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
burstcount_o : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
end entity;
architecture arch of NVM_Read_write is
--type STATES is (STATE_RESET, STATE_DISABLE_WP, STATE_WR_DATA, STATE_WR_WAITREQ, STATE_CHK_STATUS, STATE_EN_WP,
-- STATE_RD_DATA, STATE_RD_WAITREQ, STATE_RD_WAIT_RDVALID_HIGH, STATE_RD_WAIT_FINISH, STATE_INC_ADDR,
-- STATE_STOP_RD);
--signal STATE ,NEXT_STATE : STATES;
SIGNAL STATE_s : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL NEXT_STATE_s : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL addr_counter_s : unsigned(31 DOWNTO 0);
SIGNAL data_addr_s : STD_LOGIC_VECTOR(12 DOWNTO 0);
SIGNAL readvalid_counter_s : STD_LOGIC_VECTOR(3 DOWNTO 0);
CONSTANT STATE_RESET_c : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0000"; -- Reset
CONSTANT STATE_DISABLE_WP_c : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0001"; -- Disable write protection
CONSTANT STATE_WR_DATA_c : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0010"; -- write data up to address#256
CONSTANT STATE_WR_WAITREQ_c : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0011"; -- increase the address counter only when waitrequest goes low
CONSTANT STATE_CHK_STATUS_c : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0100"; -- check status register to confirm write is successful
CONSTANT STATE_EN_WP_c : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0101"; -- enable back write protection
CONSTANT STATE_RD_DATA_c : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0110"; -- read data
CONSTANT STATE_RD_WAITREQ_c : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0111"; -- if waitrequest goes high, check readvalid signal
CONSTANT STATE_RD_WAIT_RDVALID_HIGH_c: STD_LOGIC_VECTOR(3 DOWNTO 0) := "1000"; -- if readvalid signal goes high, check readvalid counter
CONSTANT STATE_RD_WAIT_FINISH_c: STD_LOGIC_VECTOR(3 DOWNTO 0) := "1001"; -- check if readvalid counter reached 8
CONSTANT STATE_INC_ADDR_c : STD_LOGIC_VECTOR(3 DOWNTO 0) := "1010"; -- increase the addrress by 8 since the burstcount is set to 8 for burst read
CONSTANT STATE_STOP_RD_c : STD_LOGIC_VECTOR(3 DOWNTO 0) := "1011"; -- stop reading if addrress reach 256
begin
data_addr_o<= data_addr_s;
readvalid_counter_o<= readvalid_counter_s;
process (reset_ni, clock_20mhz_i) is
begin
if reset_ni='0' then
STATE_s <= STATE_RESET_c;
elsif rising_edge(clock_20mhz_i) then
STATE_s <= NEXT_STATE_s;
end if;
end process;
process (reset_ni, clock_20mhz_i) is
begin
if reset_ni='0' then
data_addr_s <= (others =>'0');
addr_counter_s <= (others =>'0');
csr_addr_o <= '0';
csr_write_o <= '0';
csr_writedata_o <= x"FFFFFFFF";
burstcount_o <= "0000";
elsif rising_edge(clock_20mhz_i) then
case STATE_s is
When STATE_RESET_c =>
data_addr_s <= (others =>'0');
addr_counter_s <= (others =>'0');
csr_addr_o <= '0';
csr_write_o <= '0';
csr_writedata_o <= x"FFFFFFFF";
burstcount_o <= "0000";
data_write_o <= '0';
data_read_o <= '0';
When STATE_DISABLE_WP_c =>
csr_addr_o <= '1';
csr_write_o <= '1';
csr_writedata_o <= x"FC7FFFFF";
--csr_writedata_o <= x"FC2FFFFF";
burstcount_o <= "0001";
When STATE_WR_DATA_c =>
csr_addr_o <= '0';
csr_write_o <= '0';
csr_writedata_o <= x"FFFFFFFF";
data_addr_s <= std_logic_vector(unsigned(addr_counter_s(12 downto 0)));
data_write_o <= '1';
data_writedata_o <= data_write_i;
When STATE_WR_WAITREQ_c =>
if waitrequest_i ='0' then
addr_counter_s <= addr_counter_s + 1;
data_write_o <= '0';
end if;
When STATE_CHK_STATUS_c =>
data_write_o <= '0';
csr_addr_o <= '0';
csr_read_o <= '1';
When STATE_EN_WP_c =>
csr_addr_o <= '1';
csr_write_o <= '1';
csr_writedata_o <= x"FFFFFFFF";
data_addr_s <= "0000000000000";
When STATE_RD_DATA_c =>
data_read_o <= '1';
burstcount_o <= "1000";
When STATE_RD_WAITREQ_c =>
When STATE_RD_WAIT_RDVALID_HIGH_c =>
data_read_o <= '0';
When STATE_RD_WAIT_FINISH_c =>
When STATE_INC_ADDR_c =>
data_addr_s <= data_addr_s + "0000000001000";
When STATE_STOP_RD_c =>
data_read_o <= '0';
data_addr_s <= (others => '0');
when others =>
NULL;
end case;
end if;
end process;
process (en_read_i,en_write_i) is
begin
if (en_read_i='0') and (en_write_i='0') then
NEXT_STATE_s <= STATE_RESET_c;
else
case STATE_s is
When STATE_RESET_c =>
if en_write_i ='1' then
NEXT_STATE_s <= STATE_DISABLE_WP_c;
else
if en_read_i='1' then
NEXT_STATE_s <= STATE_RD_DATA_c;
else
NEXT_STATE_s <= STATE_RESET_c;
end if;
end if;
When STATE_DISABLE_WP_c =>
NEXT_STATE_s <= STATE_WR_DATA_c ;
When STATE_WR_DATA_c =>
NEXT_STATE_s <= STATE_WR_WAITREQ_c;
When STATE_WR_WAITREQ_c =>
if waitrequest_i = '0' then
--if addr_counter_s < x"00000100" then
if addr_counter_s < x"00000005" then
NEXT_STATE_s <= STATE_WR_DATA_c;
else
NEXT_STATE_s <= STATE_CHK_STATUS_c;
end if;
else
NEXT_STATE_s <= STATE_WR_WAITREQ_c;
end if;
When STATE_CHK_STATUS_c =>
NEXT_STATE_s <= STATE_EN_WP_c;
When STATE_EN_WP_c =>
if csr_readdata_i(3) = '1' then
NEXT_STATE_s <= STATE_RESET_c;
else
NEXT_STATE_s <= STATE_EN_WP_c;
end if;
When STATE_RD_DATA_c =>
--if data_addr_s < "0000100000000" then
if data_addr_s = "0000000000100" then
NEXT_STATE_s <= STATE_RD_WAITREQ_c;
else
NEXT_STATE_s <= STATE_STOP_RD_c;
end if;
When STATE_RD_WAITREQ_c =>
if waitrequest_i = '1' then
--if waitrequest_i = '0' then
NEXT_STATE_s <= STATE_RD_WAIT_RDVALID_HIGH_c;
else
NEXT_STATE_s <= STATE_RD_WAITREQ_c;
end if;
When STATE_RD_WAIT_RDVALID_HIGH_c =>
if readvalid_i = '1' then
--if readvalid_i = '0' then
NEXT_STATE_s <= STATE_RD_WAIT_FINISH_c;
else
NEXT_STATE_s <= STATE_RD_WAIT_RDVALID_HIGH_c;
end if;
When STATE_RD_WAIT_FINISH_c =>
if readvalid_counter_s = "1000" then
NEXT_STATE_s <= STATE_INC_ADDR_c;
else
NEXT_STATE_s <= STATE_RD_WAIT_FINISH_c;
end if;
When STATE_INC_ADDR_c =>
NEXT_STATE_s <= STATE_RD_DATA_c;
When STATE_STOP_RD_c =>
NEXT_STATE_s <= STATE_STOP_RD_c;
when others =>
NULL;
end case;
end if;
end process;
process (clock_20mhz_i ) is
begin
if rising_edge(clock_20mhz_i ) then
if en_read_i ='0' then
readvalid_counter_s <= "0000";
elsif en_read_i ='1' then
if readvalid_i = '1' then
--if readvalid_i = '0' then
readvalid_counter_s <= readvalid_counter_s + "0001";
elsif readvalid_counter_s = "1000" then ---hex8
readvalid_counter_s <= "0000";
end if;
end if;
end if;
end process;
end architecture;

11 Replies

  • FvM's avatar
    FvM
    Icon for Super Contributor rankSuper Contributor

    Hi,
    admit that I didn't yet dive into the code. I'm using MAX10 flash IP and know that it basically works well.

    A useful Signaltap recording would show the read sequence from asserting read request up to expected data valid after about 16 clock cycles.

  • Gouri's avatar
    Gouri
    Icon for New Contributor rankNew Contributor

    Hello

    • Actually I have run the signal tap continuously still no update in the avmm_data_readvalid signal and avmm_data_waitrequest.
    • Also data I'm reading out at avmm_ data_readdata is only for 0th location of avmm_data_addr (refer below signal tap image ) means address is not incrementing in read opeartion ( in Write operation all signals, addr working correctly )
    • Also do check code attached in above query.
    • Is there any problem in specific Read operation.
    • Also while Power OFF then ON, written data is not store in NVM ( any settings for this )(no data in on readdata signal during power cycle)

    Thank You

    Gouri Adsure

  • ShengN_altera's avatar
    ShengN_altera
    Icon for Super Contributor rankSuper Contributor

    Hi Gouri Adsure,

    I tested the design and found out that avmm_data_readvalid signal and avmm_data_waitrequest signal do updating as well check screenshot attached below.

    One thing to take note that have you go to Tools -> In-System Sources and Probes Editor and toggle the Index S[0] to start?

    Thanks,

    Best Regards,

    Sheng

    • Gouri's avatar
      Gouri
      Icon for New Contributor rankNew Contributor

      Hello ,

      So you are using same code which is mentioned above?

      Because with same code we found that IP is not incrementing avmm_data_addr (13 bit address ) in the read operation.

      Can you just check in code is there other logic for read operation

      ( Also why we increment addr by 8 bits any specific reason)

      Thank you

      Gouri Adsure

  • ShengN_altera's avatar
    ShengN_altera
    Icon for Super Contributor rankSuper Contributor

    Hi Gouri Adsure,


    No. I tested on the original design. May I know where you get the code from? Do you mean replace the original design flash ip with the code above mentioned?

    And then for component eLADEP_NVM, where is the respective entity module?


    Thanks,

    Regards,

    Sheng


  • ShengN_altera's avatar
    ShengN_altera
    Icon for Super Contributor rankSuper Contributor

    Hi Gouri Adsure,


    Do you have any further update on where is the respective entity module eLADEP_NVM?


    Thanks,

    Regards,

    Sheng


    • Gouri's avatar
      Gouri
      Icon for New Contributor rankNew Contributor

      Hello

      Code - eLADEP_NVM is just a IP instantiated just given the different name for IP instant as per project

      Other things are same as per ufm_write_test_project.par

      Still We stuck at read operation of UFM IP as avmm_data_addr is not incrementing

      Please check the code

      Below is screen shot for your reference

      Thank You

      Gouri Adsure

  • ShengN_altera's avatar
    ShengN_altera
    Icon for Super Contributor rankSuper Contributor

    Hi Gouri Adsure,

    Have you use the same setting like the original design On-Chip Flash IP check the screenshot attached?

    I had used a new On-Chip Flash IP named flash_ip1 which is generated in VHDL and followed the same setting. Then instantiated that ip in top verilog module and compiled as mixed language. I'm able to see the same result on flash_ip1.

    Attached the file for your reference.

    Thanks,

    Regards,

    Sheng

    • Gouri's avatar
      Gouri
      Icon for New Contributor rankNew Contributor

      Hello,

      Thank you for your valuable time.

      • Is there any On-Chip Flash IP setting difference for FPGA 10M16SCU169I7G.
      • Is Any change in avmm_data_burstcount for above FPGA.
      • Any other changes we need to do for this FPGA as per datasheet for read write operation.

      Thank You

      Gouri Adsure

  • ShengN_altera's avatar
    ShengN_altera
    Icon for Super Contributor rankSuper Contributor

    Hi Gouri Adsure,


    Do you have any further concern or consideration?


    Thanks,

    Regards,

    Sheng