📄 ddr_command.vhd
字号:
-- logic that generates the OE signal for the data path module
-- For normal burst write he duration of OE is dependent on the configured burst length.
-- For page mode accesses(SC_PM=1) the OE signal is turned on at the start of the write command
-- and is left on until a PRECHARGE(page burst terminate) is detected.
--
process(CLK, RESET_N)
begin
if (RESET_N = '0') then
oe_shift <= (others => '0');
oe1 <= '0';
oe2 <= '0';
oe3 <= '0';
oe4 <= '0';
OE <= '0';
elsif rising_edge(CLK) then
-- if (SC_PM = '0') then
if (do_writea1 = '1') then
if (SC_BL = "0001") then -- Set the shift register to the appropriate
oe_shift <= "00000001"; -- value based on burst length.
elsif (SC_BL = "0010") then
oe_shift <= "00000011";
elsif (SC_BL = "0100") then
oe_shift <= "00001111";
end if;
oe1 <= '1';
else
oe_shift(6 downto 0) <= oe_shift(7 downto 1); -- Do the shift operation
oe_shift(7) <= '0';
oe1 <= oe_shift(0);
oe2 <= oe1;
oe3 <= oe2;
oe4 <= oe3;
if (SC_RC = "10") then
OE <= oe3;
else
OE <= oe4;
end if;
end if;
-- else
-- if (do_writea1 = '1') then -- OE generation for page mode accesses
-- oe4 <= '1';
-- elsif (do_precharge = '1' or do_reada = '1' or do_refresh = '1') then
-- oe4 <= '0';
-- end if;
-- OE <= oe4;
-- end if;
end if;
end process;
-- This process tracks the time between the activate command and the
-- subsequent WRITEA or READA command, RC. The shift register is set using
-- the configuration register setting SC_RC. The shift register is loaded with
-- a single '1' with the position within the register dependent on SC_RC.
-- When the '1' is shifted out of the register it sets so_rw which triggers
-- a writea or reada command
--
process(CLK, RESET_N)
begin
if (RESET_N = '0') then
rw_shift <= (others => '0');
do_rw <= '0';
elsif rising_edge(CLK) then
if ((do_reada = '1') or (do_writea = '1')) then
if (SC_RC = "01") then -- Set the shift register
do_rw <= '1';
elsif (SC_RC = "10") then
rw_shift <= "0001";
elsif (SC_RC = "11") then
rw_shift <= "0010";
end if;
else
rw_shift(2 downto 0) <= rw_shift(3 downto 1); -- perform the shift operation
rw_shift(3) <= '0';
do_rw <= rw_shift(0);
end if;
end if;
end process;
-- This process generates the command acknowledge, CM_ACK, signal.
-- It also generates the acknowledge signal, REF_ACK, that acknowledges
-- a refresh request that was generated by the internal refresh timer circuit.
process(CLK, RESET_N)
begin
if (RESET_N = '0') then
CM_ACK <= '0';
REF_ACK <= '0';
elsif rising_edge(CLK) then
if (do_refresh = '1' and REF_REQ = '1') then -- Internal refresh timer refresh request
REF_ACK <= '1';
elsif ((do_refresh = '1') or (do_reada = '1') or (do_writea = '1') or (do_precharge = '1') -- externa commands
or (do_load_mode = '1')) then
CM_ACK <= '1';
else
REF_ACK <= '0';
CM_ACK <= '0';
end if;
end if;
end process;
-- This process generates the address, cs, cke, and command signals(ras,cas,wen)
--
process(CLK, RESET_N)
begin
if (RESET_N = '0') then
SA <= (others => '0');
BA <= (others => '0');
CS_N <= "01";
RAS_N <= '1';
CAS_N <= '1';
WE_N <= '1';
CKE <= '0';
elsif rising_edge(CLK) then
CKE <= '1';
-- Generate SA
if (do_writea = '1' or do_reada = '1') then -- ACTIVATE command is being issued, so present the row address
SA(ROWSIZE-1 downto 0) <= rowaddr;
else
SA(COLSIZE-1 downto 0) <= coladdr; -- else alway present column address
end if;
if ((do_rw='1') or (do_precharge='1')) then
SA(10) <= not(SC_PM); -- set SA(10) for autoprecharge read/write or for a precharge all command
end if;
-- don't set it if the controller is in page mode.
if (do_precharge='1' or do_load_mode='1') then
BA <= "00"; -- Set BA=0 if performing a precharge or load_mode command
else
BA <= bankaddr(1 downto 0); -- else set it with the appropriate address bits
end if;
if (do_refresh='1' or do_precharge='1' or do_load_mode='1') then
CS_N <= "00"; -- Select both chip selects if performing
else -- refresh, precharge(all) or load_mode
CS_N(0) <= SADDR(ASIZE-1); -- else set the chip selects based off of the
CS_N(1) <= not(SADDR(ASIZE-1)); -- msb address bit
end if;
--Generate the appropriate logic levels on RAS_N, CAS_N, and WE_N
--depending on the issued command.
--
if (do_refresh='1') then -- Refresh: S=00, RAS=0, CAS=0, WE=1
RAS_N <= '0';
CAS_N <= '0';
WE_N <= '1';
elsif ((do_precharge='1') and ((oe4 = '1') or (rw_flag = '1'))) then -- burst terminate if write is active
RAS_N <= '1';
CAS_N <= '1';
WE_N <= '0';
elsif ((do_precharge='1')) then -- precharge
RAS_N <= '0';
CAS_N <= '1';
WE_N <= '0';
elsif (do_load_mode='1') then -- Mode Write: S=00, RAS=0, CAS=0, WE=0
RAS_N <= '0';
CAS_N <= '0';
WE_N <= '0';
elsif (do_reada = '1' or do_writea = '1') then -- Activate: S=01 or 10, RAS=0, CAS=1, WE=1
RAS_N <= '0';
CAS_N <= '1';
WE_N <= '1';
elsif (do_rw = '1') then -- Read/Write: S=01 or 10, RAS=1, CAS=0, WE=0 or 1
RAS_N <= '1';
CAS_N <= '0';
WE_N <= rw_flag;
else
RAS_N <= '1';
CAS_N <= '1';
WE_N <= '1';
end if;
end if;
end process;
end RTL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -