Line 231... |
Line 231... |
constant CMD_LOAD_MR : std_logic_vector(2 downto 0) := "000";
|
constant CMD_LOAD_MR : std_logic_vector(2 downto 0) := "000";
|
|
|
-- various wait counter values
|
-- various wait counter values
|
constant AUTO_REFRESH_CLKS : integer := 700; -- spec says 7.8us, which is 780 clocks @ 100Mhz, I'm setting it to 700
|
constant AUTO_REFRESH_CLKS : integer := 700; -- spec says 7.8us, which is 780 clocks @ 100Mhz, I'm setting it to 700
|
constant WRITE_RECOVER_CLKS : integer := 5; -- these are fudged a bit, you *might* be able to shave a clock or two off
|
constant WRITE_RECOVER_CLKS : integer := 5; -- these are fudged a bit, you *might* be able to shave a clock or two off
|
constant READ_DONE_CLKS : integer := 5;
|
constant READ_DONE_CLKS : integer := 4; -- or shave a clock or two off if your board timing is a bit wedgy
|
|
|
type CMD_STATES is ( STATE_START, STATE_INIT, STATE_WAIT_INIT, STATE_IDLE, STATE_IDLE_AUTO_REFRESH,
|
type CMD_STATES is ( STATE_START, STATE_INIT, STATE_WAIT_INIT, STATE_IDLE, STATE_IDLE_AUTO_REFRESH,
|
STATE_IDLE_CHECK_OP_PENDING, STATE_IDLE_WAIT_AR_CTR, STATE_IDLE_WAIT_AUTO_REFRESH,
|
STATE_IDLE_CHECK_OP_PENDING, STATE_IDLE_WAIT_AR_CTR, STATE_IDLE_WAIT_AUTO_REFRESH,
|
STATE_WRITE_ROW_OPEN, STATE_WRITE_WAIT_ROW_OPEN, STATE_WRITE_ISSUE_CMD, STATE_WRITE_WAIT_RECOVER,
|
STATE_WRITE_ROW_OPEN, STATE_WRITE_WAIT_ROW_OPEN, STATE_WRITE_ISSUE_CMD, STATE_WRITE_WAIT_RECOVER,
|
STATE_READ_ROW_OPEN, STATE_READ_WAIT_ROW_OPEN, STATE_READ_ISSUE_CMD, STATE_READ_WAIT_CAPTURE );
|
STATE_READ_ROW_OPEN, STATE_READ_WAIT_ROW_OPEN, STATE_READ_ISSUE_CMD, STATE_READ_WAIT_CAPTURE );
|
Line 456... |
Line 456... |
|
|
debug_reg <= x"00";
|
debug_reg <= x"00";
|
dram_cs <= '0';
|
dram_cs <= '0';
|
data_o <= data1_o when addr_save(0) = '1' else data0_o;
|
data_o <= data1_o when addr_save(0) = '1' else data0_o;
|
|
|
|
-- process (clk_000)
|
|
-- begin
|
|
-- if (cap_en = '1') then
|
|
-- if (rising_edge(clk_000)) then
|
|
-- addr_save <= addr;
|
|
-- datai_save <= data_i;
|
|
-- op_save <= op;
|
|
-- end if;
|
|
-- end if;
|
|
-- end process;
|
|
|
|
-- this will probably make the synthesizer scream bloody murder
|
|
-- over either a transparent latch or gated clock or both
|
|
-- but i've got it working again with my SoC and I'll see about
|
|
-- changing it back to something less icky later
|
-- capture addr, data_i and op for the cmd fsm
|
-- capture addr, data_i and op for the cmd fsm
|
-- op needs to be captured during AR or it might get dropped
|
-- op needs to be captured during AR or it might get dropped
|
process (clk_000)
|
addr_save <= addr when cap_en = '1' else addr_save;
|
begin
|
datai_save <= data_i when cap_en = '1' else datai_save;
|
if (rising_edge(clk_000)) then
|
op_save <= op when cap_en = '1' else op_save;
|
if (cap_en = '1') then
|
|
addr_save <= addr;
|
|
datai_save <= data_i;
|
|
op_save <= op;
|
|
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 514... |
Line 522... |
busy_n <= '0';
|
busy_n <= '0';
|
cmd_state <= STATE_IDLE_AUTO_REFRESH;
|
cmd_state <= STATE_IDLE_AUTO_REFRESH;
|
elsif (op = "01") then
|
elsif (op = "01") then
|
busy_n <= '0';
|
busy_n <= '0';
|
op_ack <= '1';
|
op_ack <= '1';
|
|
cap_en <= '0';
|
cmd_state <= STATE_READ_ROW_OPEN;
|
cmd_state <= STATE_READ_ROW_OPEN;
|
elsif (op = "10") then
|
elsif (op = "10") then
|
busy_n <= '0';
|
busy_n <= '0';
|
op_ack <= '1';
|
op_ack <= '1';
|
|
cap_en <= '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 558... |
Line 568... |
else
|
else
|
cmd_state <= cmd_state;
|
cmd_state <= cmd_state;
|
end if;
|
end if;
|
|
|
when STATE_IDLE_CHECK_OP_PENDING =>
|
when STATE_IDLE_CHECK_OP_PENDING =>
|
|
if ( cap_en = '0') then
|
if (op_save = "01") then
|
if (op_save = "01") then
|
op_ack <= '1';
|
op_ack <= '1';
|
cmd_state <= STATE_READ_ROW_OPEN;
|
cmd_state <= STATE_READ_ROW_OPEN;
|
elsif (op_save = "10") then
|
elsif (op_save = "10") then
|
op_ack <= '1';
|
op_ack <= '1';
|
cmd_state <= STATE_WRITE_ROW_OPEN;
|
cmd_state <= STATE_WRITE_ROW_OPEN;
|
else
|
else
|
cmd_state <= STATE_IDLE;
|
cmd_state <= STATE_IDLE;
|
end if;
|
end if;
|
|
else
|
|
cmd_state <= STATE_IDLE;
|
|
end if;
|
|
|
when STATE_WRITE_ROW_OPEN =>
|
when STATE_WRITE_ROW_OPEN =>
|
cap_en <= '0';
|
|
dqs_dir <= '1';
|
dqs_dir <= '1';
|
dq_dir <= '1';
|
dq_dir <= '1';
|
main_cmd <= CMD_ACTIVE;
|
main_cmd <= CMD_ACTIVE;
|
main_bank <= addr_save(25 downto 24);
|
main_bank <= addr_save(25 downto 24);
|
main_addr <= addr_save(23 downto 11);
|
main_addr <= addr_save(23 downto 11);
|
Line 603... |
Line 616... |
else
|
else
|
cmd_state <= cmd_state;
|
cmd_state <= cmd_state;
|
end if;
|
end if;
|
|
|
when STATE_READ_ROW_OPEN =>
|
when STATE_READ_ROW_OPEN =>
|
cap_en <= '0';
|
|
dqs_dir <= '0';
|
dqs_dir <= '0';
|
dq_dir <= '0';
|
dq_dir <= '0';
|
main_cmd <= CMD_ACTIVE;
|
main_cmd <= CMD_ACTIVE;
|
main_bank <= addr_save(25 downto 24);
|
main_bank <= addr_save(25 downto 24);
|
main_addr <= addr_save(23 downto 11);
|
main_addr <= addr_save(23 downto 11);
|