?? ddr_sdr.vhd
字號:
tras_cnt_q <= TRAS-1;
state_q <= ST_RFSH_4;
else
state_q <= ST_RFSH_3;
end if;
end if;
when ST_RFSH_3 =>
if ct_cnt_q=1 then
state_q <= ST_WAIT_CMD;
end if;
when ST_RFSH_4 =>
if tras_cnt_q = 0 then
state_q <= ST_WAIT_CMD;
else
tras_cnt_q <= tras_cnt_q -1;
end if;
when RD_PRECH =>
sdr_if_q <= COMMAND(PRECHARGE);
ld_ct_cnt_q <= true;
state_q <= ST_RD_ACTIVATE;
a_int_q(auto_precharge) <= '1'; -- precharge all
when ST_READ1 =>
state_q <= ST_WAIT_CMD;
when ST_RD_ACTIVATE =>
if ct_cnt_q=1 then
ld_ct_cnt_q <= true;
sdr_if_q <= COMMAND(ACTIVE);
a_int_q <= row_adr_q; -- ROW address
state_q <= ST_WAIT_RD;
end if;
when ST_WAIT_RD =>
if ct_cnt_q=1 then
start_rd := true;
a_int_q <= col_adr_q; -- Col Address
sdr_if_q <= COMMAND(BURST_RD); -- set burst read command
state_q <= ST_READ1;
end if;
end case;
sdr_if2_q <= sdr_if_q;
ba_int2_q <= ba_int_q;
a_int2_q <= a_int_q;
cke_int2_q <= cke_int_q;
-- Write Control Signals
if start_wr then
wr_ena_q <= '1';
else
wr_ena_q <= '0';
end if;
wr_ena2_q <= wr_ena_q;
wr_ena3_q <= wr_ena2_q;
-- Data Input Shiftreg
if wr_ena2_q='1' then
shift_q(0) <= data_in; -- 2 clocks delayed MUX signal
end if;
-- Read Control Signals
if start_rd then
rd_ena_q <= true;
bus_switch_q(0) <= '1';
else
rd_ena_q <= false;
bus_switch_q(0) <= '0';
end if;
-- On and off-switching for Tristate buffer
-- is controlled by bus_switch_q
bus_switch_q(bus_switch_q'LEFT downto 1) <= bus_switch_q(bus_switch_q'LEFT-1 downto 0);
z_q <= bus_switch_q(bus_switch_q'LEFT) or bus_switch_q(bus_switch_q'LEFT-1);
----------------------------------------------------
-- cycle time counter
if ld_ct_cnt_q then
ct_cnt_q <= sdr_if_q.ct;
elsif ct_cnt_q > 0 then
ct_cnt_q <= ct_cnt_q -1;
end if;
ct0_q <= ct_cnt_q=1;
-- delay time counter
if ld_del_cnt_q then
del_cnt_q <= 3;
elsif del_cnt_q > 0 then
del_cnt_q <= del_cnt_q -1;
end if;
del0_q <= del_cnt_q=1;
-- Wait time shift register for Read2Write and Write2Read delay
-- Note that there is 1 more clock needed for a change from WRITE to READ
-- due to pipeline delay, compared to READ to WRITE
if start_rd or start_wr then
w_srg_q <= "000111";
else
w_srg_q <= '0' & w_srg_q(w_srg_q'LEFT downto 1);
end if;
end if;
end process;
process(sys_clk, rst_int_n)
begin
if rst_int_n='0' then
shift_q(1) <= (others=>'0');
elsif falling_edge(sys_clk) then
shift_q(1) <= shift_q(0);
end if;
end process;
-- Create iob FFs without reset
process (sys_clk) is
begin
if rising_edge(sys_clk) then
for n in 0 to DDR_DQS_WIDTH-1 loop
if wr_ena2_q='1' or wr_ena3_q='1' then -- ML: verlaengert + noch 1 clock
dqsz_q(n) <= '0';
else
dqsz_q(n) <= '1';
end if;
end loop;
end if;
end process;
process (sys_clk270)
begin
if rising_edge(sys_clk270) then
for n in 0 to DDR_DATA_WIDTH-1 loop
tristate_q(n) <= z_q='1';
end loop;
end if;
end process ;
------------------------------------------------------------------------------------------------------------------------------------------------
-- ctrl signals on negative edge, all FFs without Async Reset
------------------------------------------------------------------------------------------------------------------------------------------------
process (sys_clk) is
begin
if falling_edge(sys_clk) then
case mux_q is
when NORMAL => -- Read Command
ras_qn <= sdr_if_q.ras_n;
cas_qn <= sdr_if_q.cas_n;
we_qn <= sdr_if_q.we_n;
cs_qn <= sdr_if_q.cs_n;
ba_q <= ba_int_q;
a_q <= a_int_q;
cke_q <= cke_int_q;
when DELAYED => -- Write Command
ras_qn <= sdr_if2_q.ras_n;
cas_qn <= sdr_if2_q.cas_n;
we_qn <= sdr_if2_q.we_n;
cs_qn <= sdr_if2_q.cs_n;
ba_q <= ba_int2_q;
a_q <= a_int2_q;
cke_q <= cke_int2_q;
end case;
end if;
end process;
-- Data MSBs, e.g. (31 downto 16)
ddr_data(U_DATA_WIDTH-1 downto U_DATA_WIDTH/2) <= shift_q(0)(U_DATA_WIDTH/2-1 downto 0);
-- Data LSBs, e.g. (15 downto 0)
ddr_data(U_DATA_WIDTH/2-1 downto 0) <= shift_q(1)(U_DATA_WIDTH-1 downto U_DATA_WIDTH/2);
------------------------------------------------------------------------------------------------------------------------------------------------
-- DDR-FFs and Tristate Buffers
------------------------------------------------------------------------------------------------------------------------------------------------
-- SDRAM Clock
fddr1 : entity work.my_fddr
port map( d0 => '0',
d1 => '1',
ce => '1',
c1 => clk_int,
r => '0',
s => '0',
q => sdr_clk
);
fddr2 : entity work.my_fddr
port map( d0 => '1',
d1 => '0',
ce => '1',
c1 => clk_int,
r => '0',
s => '0',
q => sdr_clk_n
);
-- Data OUT FFs
gen_d1: for n in 0 to DDR_DATA_WIDTH-1 generate
begin
fddr3 : entity work.my_fddr
port map( d0 => ddr_data(n),
d1 => ddr_data(n + DDR_DATA_WIDTH),
ce => '1',
c1 => sys_clk270,
r => '0',
s => '0',
q => d2sdr(n));
end generate gen_d1;
-- DQS OUT FFs
gen_d2: for n in 0 to DDR_DQS_WIDTH-1 generate
begin
fddr4 : entity work.my_fddr
port map( d0 => '0',
d1 => '1',
ce => '1',
c1 => sys_clk,
r => wr_ena3_qn,
s => '0',
q => dqs(n));
end generate gen_d2;
-- Usage of DM signals not supported in this version
dm_q <= (others=>'0');
gen3: for n in 0 to DDR_DATA_WIDTH-1 generate
data(n) <= 'Z' when tristate_q(n) else d2sdr(n);
end generate;
wr_ena3_qn <= not wr_ena3_q;
-- Tristate-Buffer fuer dqs_q
gen_dqs : for n in 0 to DDR_DQS_WIDTH-1 generate
dqs_q(n) <= 'Z' when dqsz_q(n)='1' else dqs(n);
end generate gen_dqs;
------------------------------------------------------------------------------------------------------------------------------------------------
-- READ DATA Processing
------------------------------------------------------------------------------------------------------------------------------------------------
process (sys_clk)
begin
if rising_edge(sys_clk) then
-- sample HI-data word with rising edge
data_hi_q <= data;
-- store HI- und LO- data word in 32bit output register
data_out_q <= data_hi_q & data_lo2_q;
end if;
end process;
process(sys_clk)
begin
if rising_edge(sys_clk) then
-- derive window for valid data from rd_ena_q
rd_ena_del_q <= rd_ena_del_q(rd_ena_del_q'LEFT-1 downto 0) & rd_ena_q;
end if;
end process;
data_vld_q <= '1' when rd_ena_del_q(rd_ena_del_q'LEFT) else '0';
process (sys_clk)
begin
if falling_edge(sys_clk) then
-- sample LO- word with falling edge
data_lo1_q <= data;
-- 1 clock additional delay to store HI- and LO-word
-- with the next rising edge as 32bit word
data_lo2_q <= data_lo1_q;
end if;
end process;
-----------------------------------------------
-- Write Data Processing
-----------------------------------------------
data_req_q <= '1' when wr_ena_q='1' else '0';
------------------------------------------------------------------------------
-- wait counter for first 200 us
------------------------------------------------------------------------------
init_cnt: block
signal init_cnt_q : unsigned (0 to 13);
begin
process (sys_clk, rst_int_n) is
begin
if rst_int_n = '0' then
init_cnt_q <= (others => '0');
init_cnt0_q <= false;
init_cnt1_q <= false;
elsif rising_edge(sys_clk) then
init_cnt0_q <= init_cnt_q=1;
init_cnt1_q <= init_cnt_q=2;
if ld_init_cnt_q then
init_cnt_q <= conv_unsigned(get_init_max -1, init_cnt_q'length);
init_cnt0_q <= false;
init_cnt1_q <= false;
elsif init_cnt_q /= 0 then
init_cnt_q <= init_cnt_q -1;
end if;
end if;
end process;
end block init_cnt;
------------------------------------------------------------------------------------------------------------------------------------------------
-- wait counter for 200 clk cycles for dll
------------------------------------------------------------------------------------------------------------------------------------------------
dll_cnt: block
constant DLL_DELAY : integer := 200 -1;
signal dll_cnt_q : integer range 0 to DLL_DELAY;
begin
process (sys_clk, rst_int_n) is
begin
if rst_int_n='0' then
dll_cnt0_q <= false;
dll_cnt_q <= DLL_DELAY;
elsif rising_edge(sys_clk) then
if ld_dll_cnt_q then
dll_cnt_q <= DLL_DELAY;
elsif dll_cnt_q > 0 then
dll_cnt_q <= dll_cnt_q -1;
end if;
dll_cnt0_q <= dll_cnt_q = 1;
end if;
end process;
end block dll_cnt;
end block ctrl;
end architecture behave;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -