- introduced per-bank activation (avoids multiple activations on same bank)

- some other improvements


git-svn-id: http://moon:8086/svn/vhdl/trunk@70 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
2008-10-18 11:36:07 +00:00
parent c104c6e67d
commit f50a47246a
+88 -84
View File
@@ -57,7 +57,7 @@ architecture behaviour of sdram_ctrl is
constant LMR_BURST_LEN : natural := NextExpBaseTwo(BL);
type ctrl_state_t is (RESET, POWER_WAIT, INIT, INIT_WAIT, USER_READY, USER_WRITE_PRE, USER_WRITE_ACT, USER_WRITE, USER_READ_PRE, USER_READ_ACT, USER_READ, REFRESH);
type ctrl_state_t is (RESET, POWER_WAIT, INIT, INIT_WAIT, USER_READY, USER_WRITE_PRE, USER_WRITE_ACT, USER_WRITE, USER_READ_PRE, USER_READ_ACT, USER_READ, REFRESH_PRE, REFRESH);
signal st_ctrl, st_ctrl_next : ctrl_state_t;
constant PWR_UP_CLOCK_INTERVAL : natural := PWR_UP_WAIT*(f_sysclk/1E6);
@@ -85,14 +85,18 @@ architecture behaviour of sdram_ctrl is
signal bank_addr_reg : bank_addr_t;
signal row_addr_reg : row_addr_t;
signal col_addr_reg : col_addr_t;
signal bank_addr_last : bank_addr_t;
signal row_addr_last : row_addr_t;
signal col_addr_last : col_addr_t;
signal u_bank_addr : bank_addr_t;
signal u_row_addr : row_addr_t;
signal u_col_addr : col_addr_t;
signal act_request : std_logic;
signal act_request_set : std_logic;
signal act_request_clr : std_logic;
signal bank_active_reg : unsigned(0 to 3);
signal bank_is_active : std_logic;
signal bank_activate : std_logic;
signal bank_clr : std_logic;
type init_seq_rom_t is array (0 to 14) of init_seq_t;
@@ -181,10 +185,11 @@ begin
u_row_addr <= u_addr(user_addr_t'left downto user_addr_t'left-row_addr_t'length+1);
u_bank_addr <= u_addr(user_addr_t'left-row_addr_t'length downto user_addr_t'left-row_addr_t'length-bank_addr_t'length+1);
u_col_addr <= u_addr(user_addr_t'left-row_addr_t'length-bank_addr_t'length downto 0);
bank_is_active <= bank_active_reg(to_integer(u_bank_addr));
------------------------------------------------------------------------------------------
fsm_ctrl_state:
process (st_ctrl, u_tag_in, u_tag_reg, u_cmd, u_cmd_we, sdr_cmd_busy, pwr_up_finished, seq_cnt, cycle_finished, u_bank_addr, u_row_addr, bank_addr_reg, row_addr_reg, u_col_addr, col_addr_reg, refresh_request, act_request)
process (st_ctrl, u_tag_in, u_tag_reg, u_cmd, u_cmd_we, sdr_cmd_busy, pwr_up_finished, seq_cnt, cycle_finished, u_bank_addr, u_row_addr, bank_addr_reg, row_addr_reg, u_col_addr, col_addr_reg, bank_addr_last, row_addr_last, refresh_request, bank_is_active)
begin
u_busy <= '1';
@@ -200,8 +205,8 @@ fsm_ctrl_state:
seq_rst_en <= '0';
addr_reg_load_en <= '0';
refresh_cnt_rst <= '0';
act_request_set <= '0';
act_request_clr <= '0';
bank_activate <= '0';
bank_clr <= '0';
u_tag_out <= u_tag_reg;
st_ctrl_next <= st_ctrl;
@@ -223,7 +228,7 @@ fsm_ctrl_state:
sdr_cmd <= init_seq_rom(seq_cnt).cmd;
cc_preset <= init_seq_rom(seq_cnt).wait_cycle;
if seq_cnt = init_seq_rom_t'high then
act_request_set <= '1';
bank_clr <= '1';
refresh_cnt_rst <= '1';
st_ctrl_next <= USER_READY;
elsif sdr_cmd_busy = '0' then
@@ -239,119 +244,116 @@ fsm_ctrl_state:
end if;
when USER_READY =>
if sdr_cmd_busy = '0' then
if refresh_request = '1' then
sdr_mode(BIT_PRE_ALL) <= '1';
sdr_cmd_we <= '1';
sdr_cmd <= SD_PRE;
st_ctrl_next <= REFRESH;
else
u_busy <= '0';
if u_cmd_we = '1' then
case u_cmd is
when UCMD_NOP =>
sdr_cmd <= SD_NOP;
when UCMD_LMR =>
sdr_cmd <= SD_NOP;
when UCMD_WRITE =>
col_addr <= u_col_addr;
u_tag_out <= u_tag_in;
sdr_mode(BIT_AUTO_PRE) <= ENABLE_AUTO_PRE;
addr_reg_load_en <= '1';
act_request_clr <= '1';
sdr_cmd <= SD_WRITE;
if (u_row_addr /= row_addr_reg) or act_request = '1' then
st_ctrl_next <= USER_WRITE_PRE;
elsif (u_bank_addr /= bank_addr_reg) then
if ENABLE_PRE_ALL = '1' then
st_ctrl_next <= USER_WRITE_ACT;
else
st_ctrl_next <= USER_WRITE_PRE;
end if;
elsif sdr_cmd_busy = '0' then
sdr_cmd_we <= '1';
else
st_ctrl_next <= USER_WRITE;
end if;
when UCMD_READ =>
col_addr <= u_col_addr;
u_tag_out <= u_tag_in;
sdr_mode(BIT_AUTO_PRE) <= ENABLE_AUTO_PRE;
addr_reg_load_en <= '1';
act_request_clr <= '1';
sdr_cmd <= SD_READ;
if (u_row_addr /= row_addr_reg) or act_request = '1' then
st_ctrl_next <= USER_READ_PRE;
elsif (u_bank_addr /= bank_addr_reg) then
if ENABLE_PRE_ALL = '1' then
st_ctrl_next <= USER_READ_ACT;
else
st_ctrl_next <= USER_READ_PRE;
end if;
elsif sdr_cmd_busy = '0' then
sdr_cmd_we <= '1';
else
st_ctrl_next <= USER_READ;
end if;
when others => null;
end case;
end if;
if refresh_request = '1' then
st_ctrl_next <= REFRESH_PRE;
else
u_busy <= '0';
col_addr <= u_col_addr;
u_tag_out <= u_tag_in;
sdr_mode <= u_bank_addr & u_row_addr;
sdr_mode(BIT_AUTO_PRE) <= ENABLE_AUTO_PRE;
if u_cmd_we = '1' then
addr_reg_load_en <= '1';
case u_cmd is
when UCMD_NOP =>
sdr_cmd <= SD_NOP;
when UCMD_LMR =>
sdr_cmd <= SD_NOP;
when UCMD_WRITE =>
sdr_cmd <= SD_WRITE;
if (u_row_addr /= row_addr_reg) then
st_ctrl_next <= USER_WRITE_PRE;
elsif bank_is_active = '0' then
st_ctrl_next <= USER_WRITE_ACT;
elsif sdr_cmd_busy = '1' then
st_ctrl_next <= USER_WRITE;
else
sdr_cmd_we <= '1';
end if;
when UCMD_READ =>
sdr_cmd <= SD_READ;
if (u_row_addr /= row_addr_reg) then
st_ctrl_next <= USER_READ_PRE;
elsif bank_is_active = '0' then
st_ctrl_next <= USER_READ_ACT;
elsif sdr_cmd_busy = '1' then
st_ctrl_next <= USER_READ;
else
sdr_cmd_we <= '1';
end if;
when others => null;
end case;
end if;
end if;
when USER_WRITE_PRE =>
sdr_cmd <= SD_PRE;
sdr_mode(BIT_PRE_ALL) <= ENABLE_PRE_ALL;
bank_clr <= '1';
sdr_cmd <= SD_PRE;
sdr_mode <= bank_addr_last & row_addr_last;
sdr_mode(BIT_PRE_ALL) <= ENABLE_PRE_ALL;
if sdr_cmd_busy = '0' then
sdr_cmd_we <= '1';
st_ctrl_next <= USER_WRITE_ACT;
end if;
when USER_WRITE_ACT =>
sdr_cmd <= SD_ACT;
bank_activate <= '1';
sdr_cmd <= SD_ACT;
if sdr_cmd_busy = '0' then
sdr_cmd_we <= '1';
st_ctrl_next <= USER_WRITE;
end if;
when USER_WRITE =>
sdr_cmd <= SD_WRITE;
sdr_mode(BIT_AUTO_PRE) <= ENABLE_AUTO_PRE;
sdr_cmd <= SD_WRITE;
sdr_mode(BIT_AUTO_PRE) <= ENABLE_AUTO_PRE;
if sdr_cmd_busy = '0' then
sdr_cmd_we <= '1';
st_ctrl_next <= USER_READY;
end if;
when USER_READ_PRE =>
bank_clr <= '1';
sdr_cmd <= SD_PRE;
sdr_mode(BIT_PRE_ALL) <= ENABLE_PRE_ALL;
sdr_mode <= bank_addr_last & row_addr_last;
sdr_mode(BIT_PRE_ALL) <= ENABLE_PRE_ALL;
if sdr_cmd_busy = '0' then
sdr_cmd_we <= '1';
st_ctrl_next <= USER_READ_ACT;
end if;
when USER_READ_ACT =>
sdr_cmd <= SD_ACT;
bank_activate <= '1';
sdr_cmd <= SD_ACT;
if sdr_cmd_busy = '0' then
sdr_cmd_we <= '1';
st_ctrl_next <= USER_READ;
end if;
when USER_READ =>
sdr_cmd <= SD_READ;
sdr_mode(BIT_AUTO_PRE) <= ENABLE_AUTO_PRE;
sdr_cmd <= SD_READ;
sdr_mode(BIT_AUTO_PRE) <= ENABLE_AUTO_PRE;
if sdr_cmd_busy = '0' then
sdr_cmd_we <= '1';
st_ctrl_next <= USER_READY;
end if;
when REFRESH_PRE =>
bank_clr <= '1';
sdr_cmd <= SD_PRE;
-- sdr_mode <= bank_addr_last & row_addr_last;
sdr_mode(BIT_PRE_ALL) <= ENABLE_PRE_ALL;
if sdr_cmd_busy = '0' then
sdr_cmd_we <= '1';
st_ctrl_next <= REFRESH;
end if;
when REFRESH =>
sdr_cmd <= SD_AR;
if sdr_cmd_busy = '0' then
sdr_cmd_we <= '1';
st_ctrl_next <= USER_READY;
refresh_cnt_rst <= '1';
act_request_set <= '1';
end if;
when others =>
@@ -371,20 +373,19 @@ fsm_ctrl_state_next:
end process;
------------------------------------------------------------------------------------------
act_request_register:
process (rst, clk)
bank_active_register:
process (clk)
begin
if rst = '1' then
act_request <= '1';
elsif rising_edge(clk) then
if act_request_set = '1' then
act_request <= '1';
elsif act_request_clr = '1' then
act_request <= '0';
if rising_edge(clk) then
if bank_clr = '1' then
bank_active_reg <= (others => '0'); -- assumes PRE_ALL !!!!!!!!!!!!!
elsif bank_activate = '1' then
bank_active_reg(to_integer(bank_addr_reg)) <= '1';
end if;
end if;
end process;
------------------------------------------------------------------------------------------
user_addr_register:
process (rst, clk)
@@ -396,6 +397,9 @@ user_addr_register:
u_tag_reg <= (others => '0');
elsif rising_edge(clk) then
if addr_reg_load_en = '1' then
bank_addr_last <= bank_addr_reg;
row_addr_last <= row_addr_reg;
col_addr_last <= col_addr_reg;
bank_addr_reg <= u_bank_addr;
row_addr_reg <= u_row_addr;
col_addr_reg <= u_col_addr;