📄 data_statemachine.vhd
字号:
--------------------------------------------------------------------------------
-- Combinational process
DATASM_CMB: process (Pend_write, Pend_read, DDR_brst_end, datasm_cs, Tcaslat_end,
Twr_end,
Bus2IP_Burst, Comb_Bus2IP_CS,
read_cnt,
Rdack,
Read_pause)
begin
-- Set default values
wrdata_ack <= '0';
write_data_en_cmb <= '0';
read_data_en_cmb <= '0';
read_data_done_cmb <= '0';
datasm_ns <= datasm_cs;
Tbrst_cnt_en <= '0';
Tbrst_load <= '0';
Tcaslat_load <= '0';
Tcaslat_cnt_en <= '0';
Twr_load <= '0';
Twr_cnten <= '0';
data_mask <= '1';
rdack_rst_i <= '0';
case datasm_cs is
-------------------------- IDLE --------------------------
when IDLE =>
-- idle state
-- wait in this state for pending read or write
rdack_rst_i <= '1';
if Pend_write = '1' then
datasm_ns <= WR_DATA;
wrdata_ack <= '1';
Tbrst_load <= '1';
write_data_en_cmb <= '1';
data_mask <= '0';
end if;
if Pend_read = '1' then
datasm_ns <= WAIT_CASLAT;
Tcaslat_load <= '1';
end if;
-------------------------- WAIT_CASLAT --------------------------
when WAIT_CASLAT =>
-- wait in this state for cas latency timer to expire
Tcaslat_cnt_en <= '1';
-- since this is a state only accessable from READ,
-- assert read data enable a clock before caslatency expires
read_data_en_cmb <= '1';
rdack_rst_i <= '1';
if Tcaslat_end = '1' then
datasm_ns <= RD_DATA;
Tbrst_load <= '1';
end if;
-------------------------- WR_DATA --------------------------
when WR_DATA =>
-- write data in this state
-- stay in this state while pend_wr is asserted
-- check to see if the DDR burst cycle is complete
Tbrst_cnt_en <= '1';
write_data_en_cmb <= '1';
if Pend_write = '0' then
-- single transaction or burst has finished
if DDR_brst_end = '1' then
-- DDR is done, wait for Twr
-- kill the data enable for writes
Twr_load <= '1';
datasm_ns <= WAIT_TWR;
else
-- DDR is not done with burst, stay in this state and keep the data enable asserted
data_mask <= '0';
end if;
else
wrdata_ack <= '1';
-- still transferring data
if DDR_brst_end = '1' then
--stay in this state, need to reset pending command and reload burst counter
Tbrst_load <= '1';
Tbrst_cnt_en <= '0';
data_mask <= '0';
else
-- DDR is not done with burst, stay in this state and keep the data enable asserted
data_mask <= '0';
end if;
end if;
-------------------------- RD_DATA --------------------------
when RD_DATA =>
-- read data in this state
-- stay in this state while pend_rd is asserted
-- check to see if the DDR burst cycle is complete
Tbrst_cnt_en <= '1';
read_data_en_cmb <= '1';
-- If bursting supported
if C_INCLUDE_BURSTS = 1 then
-- If burst is finished while waiting to service a refresh
if Comb_Bus2IP_CS = '0' then
-- go to DONE, no need to wait for more RdAcks
datasm_ns <= DONE;
read_data_done_cmb <= '1';
rdack_rst_i <= '1';
elsif Bus2IP_Burst = '0' and Read_pause = '0' and C_INCLUDE_ECC_SUPPORT = 0 then
-- single transaction or burst has finished
if Rdack = '1' then
-- DDR is done with burst, go to DONE
datasm_ns <= DONE;
read_data_done_cmb <= '1';
rdack_rst_i <= '1';
else
-- wait for read data ack
datasm_ns <= WAIT_RDACK;
end if;
elsif read_cnt = READ_CNTR_ZEROS then
-- read transaction has been interrupted and
-- all read acks have been received
datasm_ns <= DONE;
read_data_done_cmb <= '1';
rdack_rst_i <= '1';
else
-- still transferring data
if DDR_brst_end = '1' then
--stay in this state, need to reset pending command and reload burst counter
Tbrst_load <= '1';
Tbrst_cnt_en <= '0';
end if;
end if;
else
-- No bursting supported
if Rdack = '1' then
datasm_ns <= DONE;
read_data_done_cmb <= '1';
rdack_rst_i <= '1';
else
-- wait for read data ack
datasm_ns <= WAIT_RDACK;
end if;
end if; -- if bursts supported
-------------------------- WAIT_TWR --------------------------
when WAIT_TWR =>
-- wait in this state for write recovery timer to expire
Twr_cnten <= '1';
if Twr_end = '1' then
datasm_ns <= DONE;
write_data_en_cmb <= '0';
end if;
-------------------------- WAIT_RDACK --------------------------
when WAIT_RDACK =>
read_data_en_cmb <= '1';
-- wait in this state for read data ack to assert
if Rdack = '1' then
-- DDR is done with burst, go to DONE
datasm_ns <= DONE;
read_data_done_cmb <= '1';
rdack_rst_i <= '1';
end if;
-------------------------- DONE --------------------------
when DONE =>
-- Read_data_done is asserted in this state
-- if pend_op asserts, go to XFER_DATA, otherwise
-- go back to IDLE
rdack_rst_i <= '1';
if Pend_write = '1' then
datasm_ns <= WR_DATA;
Tbrst_load <= '1';
write_data_en_cmb <= '1';
data_mask <= '0';
elsif Pend_read = '1' then
datasm_ns <= WAIT_CASLAT;
Tcaslat_load <= '1';
else
datasm_ns <= IDLE;
end if;
-------------------------- DEFAULT --------------------------
when others =>
datasm_ns <= IDLE;
end case;
end process DATASM_CMB;
DATASM_REG: process (Clk)
begin
if (Clk'event and Clk = '1') then
if (Rst = RESET_ACTIVE) then
datasm_cs <= IDLE;
else
datasm_cs <= datasm_ns;
end if;
end if;
end process DATASM_REG;
DATADONE_REG: process (Clk)
begin
if (Clk'event and Clk = '1') then
if (Rst = RESET_ACTIVE or Read_data_done_rst='1') then
read_data_done_reg <= '0';
elsif read_data_done_cmb = '1' then
read_data_done_reg <= '1';
end if;
end if;
end process DATADONE_REG;
-- Only generate this read_cnt if bursting is supported
W_BURST: if C_INCLUDE_BURSTS = 1 generate
-- reset RdAck when the read transaction has been interrupted and the last
-- read ack has been received and during all states of the read side of the
-- data state machine except RD_DATA
RdAck_rst <= '1'
when ((read_cnt = READ_CNTR_ONE and RdAck = '1' and Read_pause='1')
or rdack_rst_i = '1')
else '0';
-- Read counter
-- Counts up when there is a pending read command, counts
-- down everytime a read acknowledge is received
-- Reset whenever read data is finished
read_cntr_ce <= Pend_read xor RdAck;
read_cntr_rst <= read_data_done_cmb or Rst;
READCNTR_I: entity proc_common_v2_00_a.Counter(imp)
generic map (C_NUM_BITS => READ_CNTR_WIDTH)
port map
(
Clk => Clk,
Rst => read_cntr_rst,
Load_In => READ_CNTR_ZEROS,
Count_Enable => read_cntr_ce,
Count_Load => '0',
Count_Down => RdAck,
Count_Out => read_cnt,
Carry_Out => open
);
end generate W_BURST;
WO_BURST: if C_INCLUDE_BURSTS = 0 generate
-- For NO burst support Read_pause is tied to 0
RdAck_rst <= rdack_rst_i;
end generate WO_BURST;
end imp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -