I'm writing a simple RAM and VGA testing module.
At first data gets written to the SDRAM (repeatedly 0 to 4095) and then it's read from the sdram and written to a FIFO to show it as pixels on the 4 bit VGA.
Because it didn't work properly I analyzed it in Signal Tap.
The expected output would be a 0 at read_pointer 0, a 10 at read_pointer 10 and so on.
At first the outputs seemed random, but I realized that I forgot the phase shift in the sdram clock. Now it's still wrong but in another, maybe better way.
I extracted the phase shift from the SDRAM test application that is delivered together with the board.
The error now is that the output numbers go up as expected, but the timing is wrong. While the readdatavalid signal is HIGH the data is obviously not correct but old.
As you can see in the Signal Tap screenshot, the 1 as ram output is visible when the read_pointer hits 4 but the ram_rdval signal is always high thus I can't trust it.
I can't find the error and don't have starting point. Is it a wrongly tuned PLL? Is there some fault in my sdram controller config?
I'm using Quartus 20.1 lite and a DE10-lite board that uses a 10M50DAF484C7G FPGA and a 45S16320d sdram.
I can't use a newer Quartus version because the SDRAM Controller component was moved to the paid version.
SDRAM docs
Board page
Code of the main entity:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ram_vga_demonstrator is
port (
clock_50 : in std_logic;
reset_n : in std_logic;
------------------SDRAM---------------------------
dram_addr : out std_logic_vector(12 downto 0);
dram_ba : out std_logic_vector(1 downto 0);
dram_cas_n : out std_logic;
dram_cke : out std_logic;
dram_clk : out std_logic;
dram_cs_n : out std_logic;
dram_dq : inout std_logic_vector(15 downto 0);
dram_ras_n : out std_logic;
dram_we_n : out std_logic;
dram_ldqm : out std_logic;
dram_udqm : out std_logic;
-------------------VGA----------------------------
h_sync : out std_logic;
v_sync : out std_logic;
valid_pixel : out std_logic;
vga_out : out std_logic_vector(11 downto 0);
----------------- flags -----------------------------
wr_full : out std_logic;
rd_empty : out std_logic;
ram_rdval : out std_logic;
----------------------------------------------------
data_out : out std_logic_vector(15 downto 0);
data_in : in std_logic_vector(9 downto 0)
);
end entity ram_vga_demonstrator;
architecture arch of ram_vga_demonstrator is
type modes is (read_t, write_t);
----------------- clocks ------------------------------
signal clk143_s : std_logic;
signal clk25_175_s : std_logic;
signal clk_143_shift_s : std_logic; --! Signal zur Versorgnung von Signaltap
------------------sdram--------------------------------
signal mode_s : modes := write_t;
signal sdram_addr_s : std_logic_vector(24 downto 0);
signal sdram_be_n_s : std_logic_vector(1 downto 0);
signal sdram_cs_s : std_logic;
signal sdram_rdval_s, sdram_wait_s : std_logic;
signal sdram_re_n_s, sdram_we_n_s : std_logic;
signal sdram_readdata_s, sdram_writedata_s : std_logic_vector(15 downto 0);
signal dram_dqm_s : std_logic_vector(1 downto 0);
signal sdram_out_data_s : std_logic_vector(15 downto 0);
-----------------fifo-------------------------------------
signal fifo_data_s : std_logic_vector(15 downto 0);
-- signal fifo_rdclk_s : std_logic;
signal fifo_rdreq_s : std_logic;
-- signal fifo_wrclk_s : std_logic;
signal fifo_wrreq_s : std_logic;
signal fifo_q_s : std_logic_vector(15 downto 0);
signal fifo_rdempty_s : std_logic;
signal fifo_wrfull_s : std_logic;
signal fifo_wrusedw_s : std_logic_vector(7 downto 0);
signal fifo_rdusedw_s : std_logic_vector(7 downto 0);
signal fifo_wralmostfull_s : std_logic;
signal fifo_rd_almostempty_s : std_logic;
-------------------vga-------------------------------------
signal valid_pixel_s : std_logic;
signal pixel_data_s : std_logic_vector(11 downto 0);
---------------app-----------------------------------
signal ram_write_pointer_s : integer range 0 to 307199; -- 480*640 = 307.200
signal ram_read_pointer_s : integer range -1 to 307199; -- 480*640 = 307.200
signal ram_write_ready_s : std_logic;
signal vga_out_almost_finished_s : std_logic;
signal rgb_count_s : integer range 0 to 4094;
component ramsys is
port (
clk_clk : in std_logic := 'X';
clk_143_shift_clk : out std_logic;
clk_25_175_clk : out std_logic;
reset_reset_n : in std_logic := 'X';
sdram_address : in std_logic_vector(24 downto 0) := (others => 'X');
sdram_byteenable_n : in std_logic_vector(1 downto 0) := (others => 'X');
sdram_chipselect : in std_logic := 'X';
sdram_writedata : in std_logic_vector(15 downto 0) := (others => 'X');
sdram_read_n : in std_logic := 'X';
sdram_write_n : in std_logic := 'X';
sdram_readdata : out std_logic_vector(15 downto 0);
sdram_readdatavalid : out std_logic;
sdram_waitrequest : out std_logic;
wire_addr : out std_logic_vector(12 downto 0);
wire_ba : out std_logic_vector(1 downto 0);
wire_cas_n : out std_logic;
wire_cke : out std_logic;
wire_cs_n : out std_logic;
wire_dq : inout std_logic_vector(15 downto 0) := (others => 'X');
wire_dqm : out std_logic_vector(1 downto 0);
wire_ras_n : out std_logic;
wire_we_n : out std_logic;
clk_143_clk : out std_logic
);
end component ramsys;
component fifo is
port (
data : in std_logic_vector(15 downto 0);
rdclk : in std_logic;
rdreq : in std_logic;
wrclk : in std_logic;
wrreq : in std_logic;
q : out std_logic_vector(15 downto 0);
rdempty : out std_logic;
wrfull : out std_logic;
wrusedw : out std_logic_vector(7 downto 0);
rdusedw : out std_logic_vector(7 downto 0)
);
end component fifo;
component vga_controller is
port (
clock_25 : in std_logic;
reset_n : in std_logic;
h_sync : out std_logic;
v_sync : out std_logic;
valid_pixel : out std_logic;
data_in : in std_logic_vector(11 downto 0);
data_out : out std_logic_vector(11 downto 0)
);
end component vga_controller;
begin
u0 : component ramsys
port map (
clk_clk => clock_50,
reset_reset_n => reset_n,
clk_143_clk => clk143_s,
clk_25_175_clk => clk25_175_s,
clk_143_shift_clk => clk_143_shift_s,
wire_addr => dram_addr,
wire_ba => dram_ba,
wire_cas_n => dram_cas_n,
wire_cke => dram_cke,
wire_cs_n => dram_cs_n,
wire_dq => dram_dq,
wire_dqm => dram_dqm_s,
wire_ras_n => dram_ras_n,
wire_we_n => dram_we_n,
sdram_address => sdram_addr_s,
sdram_byteenable_n => sdram_be_n_s,
sdram_chipselect => sdram_cs_s,
sdram_writedata => sdram_writedata_s,
sdram_read_n => sdram_re_n_s,
sdram_write_n => sdram_we_n_s,
sdram_readdata => sdram_readdata_s,
sdram_readdatavalid => sdram_rdval_s,
sdram_waitrequest => sdram_wait_s
);
u1 : component fifo
port map (
data => sdram_out_data_s,
rdclk => clk25_175_s,
rdreq => fifo_rdreq_s,
wrclk => clk143_s,
wrreq => fifo_wrreq_s,
q => fifo_q_s,
rdempty => fifo_rdempty_s,
wrfull => fifo_wrfull_s,
wrusedw => fifo_wrusedw_s,
rdusedw => fifo_rdusedw_s
);
u2 : component vga_controller
port map (
clock_25 => clk25_175_s,
reset_n => reset_n,
h_sync => h_sync,
v_sync => v_sync,
valid_pixel => valid_pixel_s,
data_in => pixel_data_s,
data_out => vga_out
);
dram_ldqm <= dram_dqm_s(0);
dram_udqm <= dram_dqm_s(1);
dram_clk <= clk_143_shift_s;
sdram_cs_s <= '1';
sdram_be_n_s <= "00";
data_out <= sdram_readdata_s;
p_ram_flag : process (sdram_wait_s, ram_read_pointer_s) is
begin
end process p_ram_flag;
p_ram : process (clk143_s) is
begin
if rising_edge(clk143_s) then
case mode_s is
when write_t =>
if (sdram_wait_s = '0') then
sdram_we_n_s <= '0';
sdram_writedata_s <= "0000" & std_logic_vector(to_unsigned(rgb_count_s, 12));
if (rgb_count_s < 4095) then
rgb_count_s <= rgb_count_s + 1;
else
rgb_count_s <= 0;
end if;
sdram_addr_s(24 downto 0) <= std_logic_vector(to_unsigned(ram_write_pointer_s, sdram_addr_s'length));
if (ram_write_pointer_s < 307199) then
ram_write_pointer_s <= ram_write_pointer_s + 1;
else
ram_write_pointer_s <= 0;
ram_read_pointer_s <= 0;
mode_s <= read_t;
end if;
end if;
when read_t =>
sdram_we_n_s <= '1';
sdram_addr_s(24 downto 0) <= std_logic_vector(to_unsigned(ram_read_pointer_s, sdram_addr_s'length));
if (sdram_rdval_s = '1' and fifo_wrfull_s = '0') then
fifo_wrreq_s <= '1';
sdram_out_data_s <= sdram_readdata_s;
if (ram_read_pointer_s < 307199) then
ram_read_pointer_s <= ram_read_pointer_s + 1;
else
ram_write_pointer_s <= 0;
ram_read_pointer_s <= 0;
mode_s <= write_t;
end if;
else
fifo_wrreq_s <= '0';
end if;
end case;
end if;
end process p_ram;
vga : process (clk25_175_s) is
begin
if rising_edge(clk25_175_s) then
if (fifo_rdempty_s = '0' and valid_pixel_s = '1') then
fifo_rdreq_s <= '1';
pixel_data_s <= fifo_q_s(11 downto 0);
else
fifo_rdreq_s <= '0';
end if;
end if;
end process vga;
wr_full <= fifo_wrfull_s;
rd_empty <= fifo_rdempty_s;
ram_rdval <= sdram_rdval_s;
end architecture arch;