Line 56... |
Line 56... |
-- seem to be OK, but pay attention to the synthesizer reports!
|
-- seem to be OK, but pay attention to the synthesizer reports!
|
|
|
-- TODO: implement reset signal
|
-- TODO: implement reset signal
|
entity sdram_controller is
|
entity sdram_controller is
|
port( -- user facing signals
|
port( -- user facing signals
|
clk50mhz : in std_logic;
|
clk100mhz : in std_logic;
|
en : in std_logic;
|
en : in std_logic;
|
reset : in std_logic;
|
reset : in std_logic;
|
op : in std_logic_vector(1 downto 0); -- 00/11: NOP, 01: READ, 10: write
|
op : in std_logic_vector(1 downto 0); -- 00/11: NOP, 01: READ, 10: write
|
addr : in std_logic_vector(25 downto 0); -- address to read/write
|
addr : in std_logic_vector(25 downto 0); -- address to read/write
|
op_ack : out std_logic; -- op, addr and data_i should be captured when this goes high
|
op_ack : out std_logic; -- op, addr and data_i should be captured when this goes high
|
Line 89... |
Line 89... |
|
|
-- component decls begin here
|
-- component decls begin here
|
component sdram_dcm is
|
component sdram_dcm is
|
port(
|
port(
|
reset : in std_logic;
|
reset : in std_logic;
|
clk50mhz : in std_logic;
|
clk100mhz : in std_logic;
|
locked : out std_logic;
|
locked : out std_logic;
|
dram_clkp : out std_logic;
|
dram_clkp : out std_logic;
|
dram_clkn : out std_logic;
|
dram_clkn : out std_logic;
|
clk_000 : out std_logic;
|
clk_000 : out std_logic;
|
clk_090 : out std_logic;
|
clk_090 : out std_logic;
|
Line 290... |
Line 290... |
signal read_wait_done : std_logic;
|
signal read_wait_done : std_logic;
|
|
|
signal data0_o : std_logic_vector(7 downto 0);
|
signal data0_o : std_logic_vector(7 downto 0);
|
signal data1_o : std_logic_vector(7 downto 0);
|
signal data1_o : std_logic_vector(7 downto 0);
|
|
|
|
--
|
|
signal cap_en : std_logic;
|
|
signal addr_save : std_logic_vector(25 downto 0);
|
|
signal datai_save : std_logic_vector(7 downto 0);
|
|
|
begin
|
begin
|
|
|
-- component instantiations begin here
|
-- component instantiations begin here
|
DRAM_DCM: sdram_dcm
|
DRAM_DCM: sdram_dcm
|
port map(
|
port map(
|
reset => reset,
|
reset => reset,
|
clk50mhz => clk50mhz,
|
clk100mhz => clk100mhz,
|
locked => dcm_locked,
|
locked => dcm_locked,
|
dram_clkp => dram_clkp,
|
dram_clkp => dram_clkp,
|
dram_clkn => dram_clkn,
|
dram_clkn => dram_clkn,
|
clk_000 => clk_000,
|
clk_000 => clk_000,
|
clk_090 => clk_090,
|
clk_090 => clk_090,
|
Line 439... |
Line 444... |
clk => clk_000,
|
clk => clk_000,
|
clk090 => clk_090,
|
clk090 => clk_090,
|
clk180 => clk_180,
|
clk180 => clk_180,
|
clk270 => clk_270,
|
clk270 => clk_270,
|
rst => writer_rst,
|
rst => writer_rst,
|
addr => addr(0),
|
addr => addr_save(0),
|
data_o => data_i,
|
data_o => datai_save,
|
dqs => dqs_out,
|
dqs => dqs_out,
|
dm => dram_dm,
|
dm => dram_dm,
|
dq => dq_out
|
dq => dq_out
|
);
|
);
|
-- end component allocs
|
-- end component allocs
|
|
|
debug_reg <= x"00";
|
debug_reg <= x"00";
|
dram_cs <= '0';
|
dram_cs <= '0';
|
data_o <= data1_o when addr(0) = '1' else data0_o;
|
data_o <= data1_o when addr_save(0) = '1' else data0_o;
|
|
|
|
process (clk_000)
|
|
begin
|
|
if (rising_edge(clk_000)) then
|
|
if (cap_en = '1') then
|
|
addr_save <= addr;
|
|
datai_save <= data_i;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
-- command state machine
|
-- command state machine
|
process (clk_000)
|
process (clk_000)
|
begin
|
begin
|
if (rising_edge(clk_000)) then
|
if (rising_edge(clk_000)) then
|
Line 461... |
Line 476... |
case cmd_state is
|
case cmd_state is
|
when STATE_START =>
|
when STATE_START =>
|
busy_n <= '0';
|
busy_n <= '0';
|
op_ack <= '0';
|
op_ack <= '0';
|
init_reset <= '1';
|
init_reset <= '1';
|
|
cap_en <= '0';
|
main_sel <= '0';
|
main_sel <= '0';
|
main_cmd <= CMD_NOP;
|
main_cmd <= CMD_NOP;
|
main_bank <= "00";
|
main_bank <= "00";
|
main_addr <= "0000000000000";
|
main_addr <= "0000000000000";
|
cmd_state <= STATE_INIT;
|
cmd_state <= STATE_INIT;
|
Line 485... |
Line 501... |
-- this is the main hub state
|
-- this is the main hub state
|
-- this is where reads and writes return to after being completed
|
-- this is where reads and writes return to after being completed
|
busy_n <= '1';
|
busy_n <= '1';
|
op_ack <= '0';
|
op_ack <= '0';
|
need_ar_rst <= '0';
|
need_ar_rst <= '0';
|
|
cap_en <= '1';
|
main_sel <= '1';
|
main_sel <= '1';
|
writer_rst <= '1';
|
writer_rst <= '1';
|
reader_rst <= '1';
|
reader_rst <= '1';
|
if (need_ar = '1') then
|
if (need_ar = '1') then
|
|
busy_n <= '0';
|
cmd_state <= STATE_IDLE_AUTO_REFRESH;
|
cmd_state <= STATE_IDLE_AUTO_REFRESH;
|
elsif (op = "01" and en = '1') then
|
elsif (op = "01" and en = '1') then
|
|
busy_n <= '0';
|
cmd_state <= STATE_READ_ROW_OPEN;
|
cmd_state <= STATE_READ_ROW_OPEN;
|
elsif (op = "10" and en = '1') then
|
elsif (op = "10" and en = '1') then
|
|
busy_n <= '0';
|
cmd_state <= STATE_WRITE_ROW_OPEN;
|
cmd_state <= STATE_WRITE_ROW_OPEN;
|
else
|
else
|
cmd_state <= cmd_state;
|
cmd_state <= cmd_state;
|
end if;
|
end if;
|
|
|
Line 524... |
Line 544... |
else
|
else
|
cmd_state <= cmd_state;
|
cmd_state <= cmd_state;
|
end if;
|
end if;
|
|
|
when STATE_WRITE_ROW_OPEN =>
|
when STATE_WRITE_ROW_OPEN =>
|
|
op_ack <= '1';
|
busy_n <= '0';
|
busy_n <= '0';
|
dqs_dir <= '1';
|
dqs_dir <= '1';
|
dq_dir <= '1';
|
dq_dir <= '1';
|
|
cap_en <= '0';
|
main_cmd <= CMD_ACTIVE;
|
main_cmd <= CMD_ACTIVE;
|
main_bank <= addr(25 downto 24);
|
main_bank <= addr_save(25 downto 24);
|
main_addr <= addr(23 downto 11);
|
main_addr <= addr_save(23 downto 11);
|
cmd_state <= STATE_WRITE_WAIT_ROW_OPEN;
|
cmd_state <= STATE_WRITE_WAIT_ROW_OPEN;
|
|
|
when STATE_WRITE_WAIT_ROW_OPEN =>
|
when STATE_WRITE_WAIT_ROW_OPEN =>
|
main_cmd <= CMD_NOP;
|
main_cmd <= CMD_NOP;
|
main_bank <= addr(25 downto 24); -- timing kludge
|
main_bank <= addr_save(25 downto 24); -- timing kludge
|
main_addr <= "001" & addr(10 downto 1); -- last bit determines upper/lower byte in word
|
main_addr <= "001" & addr_save(10 downto 1); -- last bit determines upper/lower byte in word
|
cmd_state <= STATE_WRITE_ISSUE_CMD;
|
cmd_state <= STATE_WRITE_ISSUE_CMD;
|
|
|
when STATE_WRITE_ISSUE_CMD =>
|
when STATE_WRITE_ISSUE_CMD =>
|
writer_rst <= '0';
|
writer_rst <= '0';
|
write_reco_rst <= '1';
|
write_reco_rst <= '1';
|
main_cmd <= CMD_WRITE;
|
main_cmd <= CMD_WRITE;
|
main_bank <= addr(25 downto 24);
|
main_bank <= addr_save(25 downto 24);
|
main_addr <= "001" & addr(10 downto 1); -- last bit determines upper/lower byte in word
|
main_addr <= "001" & addr_save(10 downto 1); -- last bit determines upper/lower byte in word
|
cmd_state <= STATE_WRITE_WAIT_RECOVER;
|
cmd_state <= STATE_WRITE_WAIT_RECOVER;
|
|
|
when STATE_WRITE_WAIT_RECOVER =>
|
when STATE_WRITE_WAIT_RECOVER =>
|
op_ack <= '1';
|
|
write_reco_rst <= '0';
|
write_reco_rst <= '0';
|
main_cmd <= CMD_NOP;
|
main_cmd <= CMD_NOP;
|
main_bank <= "00";
|
main_bank <= "00";
|
main_addr <= "0000000000000";
|
main_addr <= "0000000000000";
|
if (write_reco_done = '1') then
|
if (write_reco_done = '1') then
|
Line 559... |
Line 580... |
else
|
else
|
cmd_state <= cmd_state;
|
cmd_state <= cmd_state;
|
end if;
|
end if;
|
|
|
when STATE_READ_ROW_OPEN =>
|
when STATE_READ_ROW_OPEN =>
|
|
op_ack <= '1';
|
busy_n <= '0';
|
busy_n <= '0';
|
dqs_dir <= '0';
|
dqs_dir <= '0';
|
dq_dir <= '0';
|
dq_dir <= '0';
|
|
cap_en <= '0';
|
main_cmd <= CMD_ACTIVE;
|
main_cmd <= CMD_ACTIVE;
|
main_bank <= addr(25 downto 24);
|
main_bank <= addr_save(25 downto 24);
|
main_addr <= addr(23 downto 11);
|
main_addr <= addr_save(23 downto 11);
|
cmd_state <= STATE_READ_WAIT_ROW_OPEN;
|
cmd_state <= STATE_READ_WAIT_ROW_OPEN;
|
|
|
when STATE_READ_WAIT_ROW_OPEN =>
|
when STATE_READ_WAIT_ROW_OPEN =>
|
main_cmd <= CMD_NOP;
|
main_cmd <= CMD_NOP;
|
main_bank <= addr(25 downto 24); -- timing kludge
|
main_bank <= addr_save(25 downto 24); -- timing kludge
|
main_addr <= "001" & addr(10 downto 1); -- last bit determines upper/lower byte
|
main_addr <= "001" & addr_save(10 downto 1); -- last bit determines upper/lower byte
|
cmd_state <= STATE_READ_ISSUE_CMD;
|
cmd_state <= STATE_READ_ISSUE_CMD;
|
|
|
when STATE_READ_ISSUE_CMD =>
|
when STATE_READ_ISSUE_CMD =>
|
read_wait_rst <= '1';
|
read_wait_rst <= '1';
|
main_cmd <= CMD_READ;
|
main_cmd <= CMD_READ;
|
main_bank <= addr(25 downto 24);
|
main_bank <= addr_save(25 downto 24);
|
main_addr <= "001" & addr(10 downto 1); -- last bit determines upper/lower byte
|
main_addr <= "001" & addr_save(10 downto 1); -- last bit determines upper/lower byte
|
cmd_state <= STATE_READ_WAIT_CAPTURE;
|
cmd_state <= STATE_READ_WAIT_CAPTURE;
|
|
|
when STATE_READ_WAIT_CAPTURE =>
|
when STATE_READ_WAIT_CAPTURE =>
|
op_ack <= '1';
|
|
read_wait_rst <= '0';
|
read_wait_rst <= '0';
|
reader_rst <= '0';
|
reader_rst <= '0';
|
main_cmd <= CMD_NOP;
|
main_cmd <= CMD_NOP;
|
main_bank <= "00";
|
main_bank <= "00";
|
main_addr <= "0000000000000";
|
main_addr <= "0000000000000";
|