diff --git a/lib/SDRAM/ddr_sdr_v1_5/src/sdram_ctrl.vhd b/lib/SDRAM/ddr_sdr_v1_5/src/sdram_ctrl.vhd index dbb5b80..42ad1c9 100644 --- a/lib/SDRAM/ddr_sdr_v1_5/src/sdram_ctrl.vhd +++ b/lib/SDRAM/ddr_sdr_v1_5/src/sdram_ctrl.vhd @@ -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;