FlyingDutch
Advanced Member level 1
- Joined
- Dec 16, 2017
- Messages
- 458
- Helped
- 45
- Reputation
- 92
- Reaction score
- 55
- Trophy points
- 28
- Location
- Bydgoszcz - Poland
- Activity points
- 5,027
The RAM signals are all on 3.3V, that ready signal is NOT part of the SRAM interface it's some control signal from the FSM to report the data is ready. You can see the block diagram of the design in slide 7. Not sure what the OP is going to use to exercise the interface between the Main System and the Controller as they've put those signals on pins of the FPGA instead of connecting it to say an internal microblaze.
Yes, I know that. I was responding to another post that was asking if you properly check the SRAM could use both 1.8V and 3.3V, to which I replied that you did correctly assign pins and that the 1.8V ready which was (poorly) located next to the SRAM control signals was not part of the SRAM device pins.Hello @ads-ee
this limnit is in my Spartan7 FPGA board - some IO banks have 3.3 V voltages and some 1.8 V powering. I tried construct constraint file in the way all pins to external SRAM IC to be 3.3V level standard.
Best regards
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY sram_ctrl IS
PORT (
clk, reset : IN std_logic;
mem : BUFFER std_logic;
rw : BUFFER std_logic;
addr : BUFFER std_logic_vector(17 DOWNTO 0);
data_f2s : BUFFER std_logic_vector(7 DOWNTO 0);
ready : OUT std_logic;
data_s2f_r : OUT std_logic_vector(7 DOWNTO 0);
--data_s2f_ur : OUT std_logic_vector(7 DOWNTO 0);
ad : OUT std_logic_vector(17 DOWNTO 0);
we_n, oe_n : OUT std_logic;
dio : INOUT std_logic_vector(7 DOWNTO 0);
ce_n : OUT std_logic;
SRAM_UB_N : out std_logic; -- upper byte mask
SRAM_LB_N : out std_logic; -- lower byte mask
btn : IN std_logic_vector(1 DOWNTO 0);
LED1, LED2 : OUT std_logic
);
END sram_ctrl;
ARCHITECTURE arch OF sram_ctrl IS
TYPE state_type IS (idle, r1, r2, w1, w2);
SIGNAL state_reg, state_next : state_type;
SIGNAL data_f2s_reg, data_f2s_next :
std_logic_vector(7 DOWNTO 0);
SIGNAL data_s2f_reg, data_s2f_next :
std_logic_vector(7 DOWNTO 0);
SIGNAL addr_reg, addr_next :
std_logic_vector(17 DOWNTO 0);
SIGNAL we_buf, oe_buf, tri_buf : std_logic;
SIGNAL we_reg, oe_reg, tri_reg : std_logic;
SIGNAL db_btn : std_logic_vector(2 DOWNTO 0);
BEGIN
debounce_unit0 : ENTITY work.debounce
PORT MAP(
clk => clk, reset_n => reset, button => btn(0),
result => db_btn(0)
);
debounce_unit1 : ENTITY work.debounce
PORT MAP(
clk => clk, reset_n => reset, button => btn(1),
result => db_btn(1)
);
-- address
addr <= "000000000000000001";
-- command for test
PROCESS (db_btn, data_s2f_reg)
BEGIN
--data_f2s_reg <= (OTHERS => '0');
IF (db_btn(0) = '0') THEN -- write sw1
mem <= '1';
rw <= '0';
data_f2s <= "00001111";
LED1 <= '1';
LED2 <= '1';
ELSIF (db_btn(1) = '0') THEN -- read P4
mem <= '1';
rw <= '1';
ELSE
mem <= '0'; --IDLE
rw <= '1';
--compare if read data is valid
if (data_s2f_reg = "00001111") then
LED1 <= '1';
LED2 <= '1';
else
LED1 <= '0';
LED2 <= '0';
end if;
END IF;
END PROCESS;
---- from here impl. of SRAM CTRL ------------------------------------------------------
PROCESS (clk, reset)
BEGIN
IF (reset = '1') THEN
state_reg <= idle;
addr_reg <= (OTHERS => '0');
data_f2s_reg <= (OTHERS => '0');
data_s2f_reg <= (OTHERS => '0');
tri_reg <= '1';
we_reg <= '1';
oe_reg <= '1';
SRAM_LB_N <= '1'; -- mask low byte
SRAM_UB_N <= '1'; -- mask high byte
--LED1 <= '0';
--LED2 <= '0';
ELSIF (clk'event AND clk = '1') THEN
state_reg <= state_next;
addr_reg <= addr_next;
data_f2s_reg <= data_f2s_next;
data_s2f_reg <= data_s2f_next;
tri_reg <= tri_buf;
we_reg <= we_buf;
oe_reg <= oe_buf;
SRAM_LB_N <= '0'; -- unmask low byte
SRAM_UB_N <= '0'; -- unmask high byte
END IF;
END PROCESS;
-- next state logic
PROCESS (state_reg, mem, rw, dio, addr, data_f2s,
data_f2s_reg, data_s2f_reg, addr_reg)
BEGIN
addr_next <= addr_reg;
data_f2s_next <= data_f2s_reg;
data_s2f_next <= data_s2f_reg;
ready <= '0';
CASE state_reg IS
WHEN idle =>
IF (mem = '0') THEN
state_next <= idle;
ELSE
addr_next <= addr;
IF (rw = '0') THEN -- write
state_next <= w1;
data_f2s_next <= data_f2s;
ELSE
state_next <= r1;
END IF;
END IF;
ready <= '1';
WHEN w1 =>
state_next <= w2;
WHEN w2 =>
state_next <= idle;
WHEN r1 =>
state_next <= r2;
WHEN r2 =>
data_s2f_next <= dio;
state_next <= idle;
END CASE;
END PROCESS;
-- look-ahead output logic
PROCESS (state_next)
BEGIN
tri_buf <= '1';
we_buf <= '1';
oe_buf <= '1';
CASE state_next IS
WHEN idle =>
WHEN w1 =>
tri_buf <= '0';
we_buf <= '0';
WHEN w2 =>
tri_buf <= '0';
WHEN r1 =>
oe_buf <= '0';
WHEN r2 =>
oe_buf <= '0';
END CASE;
END PROCESS;
-- to main system
data_s2f_r <= data_s2f_reg;
--data_s2f_ur <= dio;
-- to SRAM
we_n <= we_reg;
oe_n <= oe_reg;
ad <= addr_reg;
-- I/O for SRAM chip
ce_n <= '0';
dio <= data_f2s_reg WHEN tri_reg = '0'
ELSE (OTHERS => 'Z');
END arch;
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY sram_ctrl IS
PORT (
clk, reset : IN std_logic;
mem : BUFFER std_logic;
rw : BUFFER std_logic;
addr : BUFFER std_logic_vector(17 DOWNTO 0);
data_f2s : BUFFER std_logic_vector(7 DOWNTO 0);
ready : OUT std_logic;
data_s2f_r : OUT std_logic_vector(7 DOWNTO 0);
--data_s2f_ur : OUT std_logic_vector(7 DOWNTO 0);
ad : OUT std_logic_vector(17 DOWNTO 0);
we_n, oe_n : OUT std_logic;
dio : INOUT std_logic_vector(7 DOWNTO 0);
ce_n : OUT std_logic;
SRAM_UB_N : out std_logic; -- upper byte mask
SRAM_LB_N : out std_logic; -- lower byte mask
btn : IN std_logic_vector(1 DOWNTO 0);
LED1, LED2 : OUT std_logic
);
END sram_ctrl;
ARCHITECTURE arch OF sram_ctrl IS
TYPE state_type IS (idle, r1, r2, w1, w2);
SIGNAL state_reg, state_next : state_type;
SIGNAL data_f2s_reg, data_f2s_next :
std_logic_vector(7 DOWNTO 0);
SIGNAL data_s2f_reg, data_s2f_next :
std_logic_vector(7 DOWNTO 0);
SIGNAL addr_reg, addr_next :
std_logic_vector(17 DOWNTO 0);
SIGNAL we_buf, oe_buf, tri_buf : std_logic;
SIGNAL we_reg, oe_reg, tri_reg : std_logic;
SIGNAL db_btn : std_logic_vector(2 DOWNTO 0);
BEGIN
debounce_unit0 : ENTITY work.debounce
PORT MAP(
clk => clk, reset_n => reset, button => btn(0),
result => db_btn(0)
);
debounce_unit1 : ENTITY work.debounce
PORT MAP(
clk => clk, reset_n => reset, button => btn(1),
result => db_btn(1)
);
-- address
addr <= "000000000000000001";
-- command for test
PROCESS (db_btn, data_s2f_reg)
BEGIN
--data_f2s_reg <= (OTHERS => '0');
IF (db_btn(0) = '0') THEN -- write sw1
mem <= '1';
rw <= '0';
data_f2s <= "00001111";
LED1 <= '1';
LED2 <= '1';
ELSIF (db_btn(1) = '0') THEN -- read P4
mem <= '1';
rw <= '1';
if (dio = "00001111") then
LED1 <= '0';
LED2 <= '0';
else
LED1 <= '1';
LED2 <= '1';
end if;
ELSE
mem <= '0'; --IDLE
rw <= '1';
--compare if read data is valid
-- if (data_s2f_reg = "00001111") then
-- LED1 <= '1';
-- LED2 <= '1';
-- else
-- LED1 <= '0';
-- LED2 <= '0';
-- end if;
END IF;
END PROCESS;
---- from here impl. of SRAM CTRL ------------------------------------------------------
PROCESS (clk, reset)
BEGIN
IF (reset = '0') THEN
state_reg <= idle;
addr_reg <= (OTHERS => '0');
data_f2s_reg <= (OTHERS => '0');
data_s2f_reg <= (OTHERS => '0');
tri_reg <= '1';
we_reg <= '1';
oe_reg <= '1';
SRAM_LB_N <= '1'; -- mask low byte
SRAM_UB_N <= '1'; -- mask high byte
--LED1 <= '0';
--LED2 <= '0';
ELSIF (clk'event AND clk = '1') THEN
state_reg <= state_next;
addr_reg <= addr_next;
data_f2s_reg <= data_f2s_next;
data_s2f_reg <= data_s2f_next;
tri_reg <= tri_buf;
we_reg <= we_buf;
oe_reg <= oe_buf;
SRAM_LB_N <= '0'; -- unmask low byte
SRAM_UB_N <= '0'; -- unmask high byte
END IF;
END PROCESS;
-- next state logic
PROCESS (state_reg, mem, rw, dio, addr, data_f2s,
data_f2s_reg, data_s2f_reg, addr_reg)
BEGIN
addr_next <= addr_reg;
data_f2s_next <= data_f2s_reg;
data_s2f_next <= data_s2f_reg;
ready <= '0';
CASE state_reg IS
WHEN idle =>
IF (mem = '0') THEN
state_next <= idle;
ELSE
addr_next <= addr;
IF (rw = '0') THEN -- write
state_next <= w1;
data_f2s_next <= data_f2s;
ELSE
state_next <= r1;
END IF;
END IF;
ready <= '1';
WHEN w1 =>
state_next <= w2;
WHEN w2 =>
state_next <= idle;
WHEN r1 =>
state_next <= r2;
WHEN r2 =>
data_s2f_next <= dio;
state_next <= idle;
END CASE;
END PROCESS;
-- look-ahead output logic
PROCESS (state_next)
BEGIN
tri_buf <= '1';
we_buf <= '1';
oe_buf <= '1';
CASE state_next IS
WHEN idle =>
WHEN w1 =>
tri_buf <= '0';
we_buf <= '0';
WHEN w2 =>
tri_buf <= '0';
WHEN r1 =>
oe_buf <= '0';
WHEN r2 =>
oe_buf <= '0';
END CASE;
END PROCESS;
-- to main system
data_s2f_r <= data_s2f_reg;
--data_s2f_ur <= dio;
-- to SRAM
we_n <= we_reg;
oe_n <= oe_reg;
ad <= addr_reg;
-- I/O for SRAM chip
ce_n <= '0';
dio <= data_f2s_reg WHEN tri_reg = '0'
ELSE (OTHERS => 'Z');
END arch;
4) Design of PCB board for 2Mega x 16-bit SRAM memory ( IS61WV204816BLL-10TLI IC)
5) To launch that PCB board (with 2Mega x 16-bit SRAM) together with Spartan7 FPGA board
If you intend to make a new SRAM PCB, take care that you provide a suitable digital ground. Presuming you are using 2-layer PCB as in your previous design https://www.edaboard.com/threads/static-ram-ic-selection-for-full-hd-resolution-frame-buffer.395013/, you should at least implement a combination of copper pours and multiple meshed ground traces. The external connector and cable should have multiple ground connections in parallel.
I didn't contribute to the original io-buffer question of this thread because I'm not familar with Xilinx tools. I'm a bit shocked how difficult the implementation seems to be. I made many Quartus FPGA designs involving external SRAM over the years, just wrote behavioral code without thinking about buffers...
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?