Forum Discussion
Shweta_sawant
Occasional Contributor
2 years agoAs per the document mentioned in the answer above, we developed the code as below. But, we are facing issue in tehe read operation.
Code
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;
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";
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 <= std_logic_vector(unsigned(addr_counter_s));
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
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
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
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
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
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;