- 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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user