I want to write 512KByte data on SRAM(IS61/64WV512).I'm using spartan6 lx9 FPGA. In the program routine, the initial step involves writing all the data. Subsequently, upon completion of the writing process, the state transitions to reading. For write state I used a known data stream(AA, BB, CC, DD) to track and validate the code.
The problem according to ChipScope result is, the reading state doesn't work correctly, as the expected data is not being read(always is DD). I'm using 50mhz clock in my design. during reading state I considered an excessive state to put more time for reading but it wasn't helpful. I've put the relevant part here.
note1: The DATA_SRAM is IO bus(IO0-IO7)
note2: sram_datasheet link
note3: s2f means : sram to fpga, f2s is fpga 2 sram
SRAM_READ_WRITE_PROC:process(CLK)
begin
if rising_edge(CLK) then
case state_sram_sig is
when IDLE =>
-- Check if writing process should start
read_sram_state_status <= "0000";
if start_pixel_capturing_sig = '1' then
rw_sig <= '0'; -- Set to WRITE mode
state_sram_sig <= WRITE0; -- Transition to WRITE state
end if;
when WRITE0 =>
-- Perform writing process
read_sram_state_status <= "0001";
we_to_sram_sig <= '0';
oe_to_sram_sig <= '1';
ce_to_sram_sig <= '0';
whole_data_p0 <= X"AA";
whole_data_p1 <= X"BB";
whole_data_p2 <= X"CC";
whole_data_p3 <= X"DD";
rw_sig <= '0';
ADDRESS_SRAM <= std_logic_vector(address_input_sig);
DATA_SRAM <= data_f2s_sig ;
if address_input_sig = X"4" then
state_sram_sig <= READ0;
address_input_sig_4_read <= (others=>'0');
address_input_sig <= (others=>'0');
rw_sig <= '1';
end if;
if cnt = 6 then
-- Write data to SRAM at current address
address_input_sig <= address_input_sig;
we_to_sram_sig <= '0';
oe_to_sram_sig <= '1';
ce_to_sram_sig <= '0';
elsif cnt = 0 then
data_f2s_sig <= whole_data_p0;
address_input_sig <= address_input_sig + 1;
we_to_sram_sig <= '0';
oe_to_sram_sig <= '1';
ce_to_sram_sig <= '0';
DATA_SRAM <= data_f2s_sig ;
ADDRESS_SRAM <= std_logic_vector(address_input_sig);
--state_sram_sig <= READ0;
--address_input_sig_4_read <= address_input_sig;
elsif cnt = 1 then
data_f2s_sig <= whole_data_p1;
address_input_sig <= address_input_sig + 1;
we_to_sram_sig <= '0';
oe_to_sram_sig <= '1';
ce_to_sram_sig <= '0';
DATA_SRAM <= data_f2s_sig ;
ADDRESS_SRAM <= std_logic_vector(address_input_sig);
--state_sram_sig <= READ0;
--address_input_sig_4_read <= address_input_sig;
elsif cnt = 2 then
data_f2s_sig <= whole_data_p2;
address_input_sig <= address_input_sig + 1;
we_to_sram_sig <= '0';
oe_to_sram_sig <= '1';
ce_to_sram_sig <= '0';
DATA_SRAM <= data_f2s_sig ;
ADDRESS_SRAM <= std_logic_vector(address_input_sig);
elsif cnt = 3 then
data_f2s_sig <= whole_data_p3;
address_input_sig <= address_input_sig + 1;
we_to_sram_sig <= '0';
oe_to_sram_sig <= '1';
ce_to_sram_sig <= '0';
DATA_SRAM <= data_f2s_sig ;
ADDRESS_SRAM <= std_logic_vector(address_input_sig);
else
address_input_sig <= address_input_sig;
whole_data_p0 <= whole_data_p0;
whole_data_p1 <= whole_data_p1;
whole_data_p2 <= whole_data_p2;
whole_data_p3 <= whole_data_p3;
we_to_sram_sig <= ce_to_sram_sig;
oe_to_sram_sig <= oe_to_sram_sig;
ce_to_sram_sig <= we_to_sram_sig;
end if;
when READ0 =>
-- Perform reading process
read_sram_state_status <= "0010";
we_to_sram_sig <= '1';
oe_to_sram_sig <= '0';
ce_to_sram_sig <= '0';
rw_sig <= '1';
if address_input_sig_4_read = X"4" then
state_sram_sig <= WRITE0; -- Transition to IDLE state after reading
address_input_sig <= (others=>'0');
address_input_sig_4_read <= (others=>'0');
rw_sig <= '0';
else
state_sram_sig <= WAIT0;
end if;
when WAIT0 =>
we_to_sram_sig <= '1';
oe_to_sram_sig <= '0';
ce_to_sram_sig <= '0';
data_s2f_sig <= DATA_SRAM;
read_sram_state_status <= "0100";
state_sram_sig <= READ0;
ADDRESS_SRAM <= std_logic_vector(address_input_sig_4_read);
address_input_sig_4_read <= address_input_sig_4_read+ 1;
when WAIT1 =>
read_sram_state_status <= "1000";
if address_input_sig_4_read = X"3FFFF" then
state_sram_sig <= WRITE0; -- Transition to IDLE state after reading
address_input_sig <= (others=>'0');
address_input_sig_4_read <= (others=>'0');
else
state_sram_sig <= READ0;
end if;
end case;
end if;
end process;
1 Answer 1
The SRAM does not work like you use it. You need to end the write cycle for each word you write.
See the data sheet pages 7 to 9. During the write cycle no change in the address is expected. Notice \$t_{AW}\$ and \$t_{SD}\$, too. Apparently the data write is triggered by the edge at the end of the write cycle.
In contrast, you can change the address in read cycles while /CE and /OE are active, according to the figure on page 6 ("READ CYCLE NO. 1").
Unfortunately this does not explain why you read 0xDD from all words. But since you work outside the specification, undefined things happen.
-
\$\begingroup\$ Thanks for the reply. You're right; I used two clock cycles for each byte to read and write: one clock cycle for enabling and one clock cycle for disabling and getting data. \$\endgroup\$MH.AI.eAgLe– MH.AI.eAgLe2024年05月19日 08:11:02 +00:00Commented May 19, 2024 at 8:11
the reading state doesn't work correctly
. Is it that the expected data isn't read from the SRAM, or something else? Also, is theDATA_SRAM
variable directly used to connect to theI/O0
toI/O7
pins of the SRAM or is their some intermediate buffering? From the posted VHDL I can't see how theI/O0
toI/O7
pins will be driven as outputs during a SRAM write, and then changed to be inputs during a SRAM read. \$\endgroup\$