509 lines
22 KiB
VHDL
509 lines
22 KiB
VHDL
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
|
|
entity axis_dma is
|
|
generic (
|
|
DWIDTH : positive := 32;
|
|
IDWIDTH : positive := 1;
|
|
MAX_BURSTLEN : positive := 16;
|
|
FIFO_AWIDTH : positive := 8;
|
|
polynomial_default : std_logic_vector(31 downto 0) := x"04C11DB7"
|
|
);
|
|
port (
|
|
CLK : in std_logic;
|
|
RESETN : in std_logic;
|
|
|
|
INTERRUPT : out std_logic := '0';
|
|
|
|
-- for crc calulaction
|
|
initialValue : out std_logic_vector(31 downto 0);
|
|
polynomial : out std_logic_vector(31 downto 0);
|
|
finalXOR : out std_logic_vector(31 downto 0);
|
|
inOutReflected : out std_logic_vector( 1 downto 0);
|
|
|
|
-- FIFOs
|
|
FIFO_NUM_FREE : in std_logic_vector(7 downto 0);
|
|
FIFO_NUM_AVAIL : in std_logic_vector(7 downto 0);
|
|
|
|
-- AXIL Slave Interface
|
|
S_AXIL_AWADDR : in std_logic_vector(7 downto 0);
|
|
S_AXIL_AWVALID : in std_logic;
|
|
S_AXIL_AWREADY : out std_logic;
|
|
S_AXIL_WDATA : in std_logic_vector(31 downto 0);
|
|
S_AXIL_WVALID : in std_logic;
|
|
S_AXIL_WREADY : out std_logic;
|
|
S_AXIL_WSTRB : in std_logic_vector((32/8)-1 downto 0);
|
|
S_AXIL_BVALID : out std_logic;
|
|
S_AXIL_BREADY : in std_logic;
|
|
S_AXIL_BRESP : out std_logic_vector(1 downto 0);
|
|
S_AXIL_ARADDR : in std_logic_vector(7 downto 0);
|
|
S_AXIL_ARVALID : in std_logic;
|
|
S_AXIL_ARREADY : out std_logic;
|
|
S_AXIL_RDATA : out std_logic_vector(31 downto 0);
|
|
S_AXIL_RVALID : out std_logic;
|
|
S_AXIL_RREADY : in std_logic;
|
|
S_AXIL_RRESP : out std_logic_vector(1 downto 0);
|
|
|
|
-- AXI Master Interface (Memory)
|
|
M_AXI_ARREADY : in std_logic;
|
|
M_AXI_ARVALID : out std_logic := '0';
|
|
M_AXI_ARADDR : out std_logic_vector(31 downto 0);
|
|
M_AXI_ARID : out std_logic_vector(IDWIDTH-1 downto 0);
|
|
M_AXI_ARLEN : out std_logic_vector( 3 downto 0);
|
|
M_AXI_ARSIZE : out std_logic_vector( 2 downto 0);
|
|
M_AXI_ARBURST : out std_logic_vector( 1 downto 0);
|
|
M_AXI_ARPROT : out std_logic_vector( 2 downto 0);
|
|
M_AXI_ARCACHE : out std_logic_vector( 3 downto 0);
|
|
M_AXI_RREADY : out std_logic;
|
|
M_AXI_RVALID : in std_logic;
|
|
M_AXI_RDATA : in std_logic_vector(DWIDTH-1 downto 0);
|
|
M_AXI_RRESP : in std_logic_vector( 1 downto 0);
|
|
M_AXI_RID : in std_logic_vector(IDWIDTH-1 downto 0);
|
|
M_AXI_RLAST : in std_logic;
|
|
|
|
M_AXI_AWREADY : in std_logic := '0';
|
|
M_AXI_AWVALID : out std_logic := '0';
|
|
M_AXI_AWADDR : out std_logic_vector(31 downto 0);
|
|
M_AXI_AWLEN : out std_logic_vector( 3 downto 0);
|
|
M_AXI_AWSIZE : out std_logic_vector( 2 downto 0);
|
|
M_AXI_AWID : out std_logic_vector(IDWIDTH-1 downto 0);
|
|
M_AXI_AWBURST : out std_logic_vector( 1 downto 0);
|
|
M_AXI_AWPROT : out std_logic_vector( 2 downto 0);
|
|
M_AXI_AWCACHE : out std_logic_vector( 3 downto 0);
|
|
M_AXI_WREADY : in std_logic := '0';
|
|
M_AXI_WVALID : out std_logic := '0';
|
|
M_AXI_WDATA : out std_logic_vector(DWIDTH-1 downto 0);
|
|
M_AXI_WSTRB : out std_logic_vector(DWIDTH/8-1 downto 0);
|
|
M_AXI_WLAST : out std_logic := '0';
|
|
M_AXI_WID : out std_logic_vector(DWIDTH-1 downto 0);
|
|
M_AXI_BREADY : out std_logic;
|
|
M_AXI_BVALID : in std_logic := '0';
|
|
M_AXI_BID : in std_logic_vector( DWIDTH-1 downto 0);
|
|
M_AXI_BRESP : in std_logic_vector( 1 downto 0);
|
|
|
|
-- AXI Streaming Target Port
|
|
S_AXIS_TVALID : in std_logic;
|
|
S_AXIS_TDATA : in std_logic_vector(31 downto 0);
|
|
S_AXIS_TLAST : in std_logic := '0';
|
|
S_AXIS_TREADY : out std_logic;
|
|
|
|
-- AXI Streaming Initiator Port
|
|
M_AXIS_TVALID : out std_logic;
|
|
M_AXIS_TDATA : out std_logic_vector(31 downto 0);
|
|
M_AXIS_TLAST : out std_logic;
|
|
M_AXIS_TREADY : in std_logic
|
|
);
|
|
end entity;
|
|
|
|
architecture rtl of axis_dma is
|
|
|
|
-- AXIL Registers
|
|
signal run_reg : std_logic := '0';
|
|
signal interrupt_enable_reg : std_logic;
|
|
signal read_address_reg : std_logic_vector(31 downto 0);
|
|
signal write_address_reg : std_logic_vector(31 downto 0);
|
|
signal packet_size_reg : std_logic_vector(15 downto 0);
|
|
signal packet_number_reg : std_logic_vector(15 downto 0);
|
|
signal polynomial_reg : std_logic_vector(31 downto 0);
|
|
signal initialValue_reg : std_logic_vector(31 downto 0);
|
|
signal finalXOR_reg : std_logic_vector(31 downto 0);
|
|
signal inOut_reflected_reg : std_logic_vector( 1 downto 0);
|
|
|
|
-- Helper Signals
|
|
signal run_reg_set : std_logic;
|
|
signal run_reg_clear : std_logic;
|
|
|
|
-- M_AXI Read Data state machine
|
|
type read_state_t is (IDLE, REQ, WAIT_REQ_ACCEPT, READ_DATA, FINISHED);
|
|
signal read_state : read_state_t := IDLE;
|
|
|
|
-- M_AXI Write Data state machine
|
|
type write_state_t is (IDLE, REQ, WAIT_REQ_ACCEPT, WRITE_DATA, FINISHED);
|
|
signal write_state : write_state_t := IDLE;
|
|
|
|
-- control signals
|
|
signal packets_cnt : unsigned(15 downto 0);
|
|
signal data_cnt : unsigned(31 downto 0);
|
|
signal read_addr_cnt : unsigned(31 downto 0);
|
|
signal write_addr_cnt : unsigned(31 downto 0);
|
|
signal interrupt_reset : std_logic;
|
|
signal packet_last_word : std_logic := '0';
|
|
signal interrupt_sig : std_logic := '0';
|
|
begin
|
|
-------------------------------------------
|
|
-- Interrupt
|
|
-------------------------------------------
|
|
interrupt_sig <= '1' when read_state=FINISHED and write_state=FINISHED and interrupt_enable_reg='1' else '0';
|
|
INTERRUPT <= interrupt_sig;
|
|
|
|
|
|
-------------------------------------------
|
|
-- S_AXIL Schnittstelle
|
|
-------------------------------------------
|
|
S_AXIL_BRESP <= (others=>'0'); -- No write errors
|
|
S_AXIL_RRESP <= (others=>'0'); -- No read errors
|
|
S_AXIL_ARREADY <= '1'; -- IP is always ready
|
|
S_AXIL_AWREADY <= S_AXIL_AWVALID and S_AXIL_WVALID;
|
|
S_AXIL_WREADY <= S_AXIL_AWVALID and S_AXIL_WVALID;
|
|
|
|
-- AXIL Register nach Aussen fuehren
|
|
polynomial <= polynomial_reg;
|
|
initialValue <= initialValue_reg;
|
|
inOutReflected <= inOut_reflected_reg;
|
|
finalXOR <= finalXOR_reg;
|
|
|
|
process
|
|
begin
|
|
wait until rising_edge(CLK);
|
|
|
|
if RESETN = '0' then
|
|
S_AXIL_BVALID <= '0';
|
|
S_AXIL_RVALID <= '0';
|
|
|
|
-- AXIL-Register zuruecksetzen
|
|
run_reg <= '0';
|
|
interrupt_enable_reg <= '0';
|
|
read_address_reg <= (others=>'0');
|
|
write_address_reg <= (others=>'0');
|
|
packet_number_reg <= (others=>'0');
|
|
packet_size_reg <= (others=>'0');
|
|
polynomial_reg <= polynomial_default;
|
|
initialValue_reg <= (others=>'0');
|
|
finalXOR_reg <= (others=>'0');
|
|
inOut_reflected_reg <= (others=>'0');
|
|
else
|
|
-- FLip Flop-Register fuer sauberes Setzen und Loeschen des Run-Signals
|
|
if interrupt_sig = '1' then
|
|
run_reg <= '0';
|
|
elsif run_reg_set = '1' then
|
|
run_reg <= '1';
|
|
elsif run_reg_clear = '1' then
|
|
run_reg <= '0';
|
|
end if;
|
|
|
|
-- Lesezugriff
|
|
if S_AXIL_RREADY = '1' then
|
|
S_AXIL_RVALID <= '0';
|
|
end if;
|
|
|
|
if S_AXIL_ARVALID = '1' then
|
|
S_AXIL_RDATA <= (others=>'0');
|
|
if S_AXIL_ARADDR(7 downto 0) = x"00" then
|
|
S_AXIL_RDATA(0) <= run_reg;
|
|
S_AXIL_RDATA(1) <= interrupt_enable_reg;
|
|
elsif S_AXIL_ARADDR(7 downto 0) = x"04" then
|
|
S_AXIL_RDATA(0) <= interrupt_sig;
|
|
elsif S_AXIL_ARADDR(7 downto 0) = x"08" then
|
|
S_AXIL_RDATA <= read_address_reg;
|
|
elsif S_AXIL_ARADDR(7 downto 0) = x"0C" then
|
|
S_AXIL_RDATA <= write_address_reg;
|
|
elsif S_AXIL_ARADDR(7 downto 0) = x"10" then
|
|
S_AXIL_RDATA(15 downto 0) <= packet_size_reg;
|
|
elsif S_AXIL_ARADDR(7 downto 0) = x"14" then
|
|
S_AXIL_RDATA(15 downto 0) <= packet_number_reg;
|
|
elsif S_AXIL_ARADDR(7 downto 0) = x"18" then
|
|
S_AXIL_RDATA <= polynomial_reg;
|
|
elsif S_AXIL_ARADDR(7 downto 0) = x"1C" then
|
|
S_AXIL_RDATA <= initialValue_reg;
|
|
elsif S_AXIL_ARADDR(7 downto 0) = x"20" then
|
|
S_AXIL_RDATA <= finalXOR_reg;
|
|
elsif S_AXIL_ARADDR(7 downto 0) = x"24" then
|
|
S_AXIL_RDATA(1 downto 0) <= inOut_reflected_reg;
|
|
end if;
|
|
S_AXIL_RVALID <= '1';
|
|
end if;
|
|
|
|
if S_AXIL_BREADY = '1' then
|
|
S_AXIL_BVALID <= '0';
|
|
end if;
|
|
|
|
interrupt_reset <= '0';
|
|
run_reg_set <= '0';
|
|
|
|
if S_AXIL_AWVALID = '1' and S_AXIL_WVALID = '1' then
|
|
S_AXIL_BVALID <= '1';
|
|
|
|
-- Register schreiben
|
|
if S_AXIL_AWADDR = x"00" then
|
|
if S_AXIL_WSTRB(0) = '1' then
|
|
run_reg_set <= S_AXIL_WDATA(0);
|
|
interrupt_enable_reg <= S_AXIL_WDATA(1);
|
|
end if;
|
|
elsif S_AXIL_AWADDR = x"04" then
|
|
if S_AXIL_WSTRB(0) = '1' then
|
|
interrupt_reset <= not S_AXIL_WDATA(0);
|
|
end if;
|
|
elsif S_AXIL_AWADDR = x"08" then
|
|
if S_AXIL_WSTRB = "1111" then
|
|
read_address_reg <= S_AXIL_WDATA;
|
|
end if;
|
|
elsif S_AXIL_AWADDR = x"0C" then
|
|
if S_AXIL_WSTRB = "1111" then
|
|
write_address_reg <= S_AXIL_WDATA;
|
|
end if;
|
|
elsif S_AXIL_AWADDR = x"10" then
|
|
if S_AXIL_WSTRB(1 downto 0) = "11" then
|
|
packet_size_reg <= S_AXIL_WDATA(15 downto 0);
|
|
end if;
|
|
elsif S_AXIL_AWADDR = x"14" then
|
|
if S_AXIL_WSTRB(1 downto 0) = "11" then
|
|
packet_number_reg <= S_AXIL_WDATA(15 downto 0);
|
|
end if;
|
|
elsif S_AXIL_AWADDR = x"18" then
|
|
if S_AXIL_WSTRB = "1111" then
|
|
polynomial_reg <= S_AXIL_WDATA;
|
|
end if;
|
|
elsif S_AXIL_AWADDR = x"1C" then
|
|
if S_AXIL_WSTRB = "1111" then
|
|
initialValue_reg <= S_AXIL_WDATA;
|
|
end if;
|
|
elsif S_AXIL_AWADDR = x"20" then
|
|
if S_AXIL_WSTRB = "1111" then
|
|
finalXOR_reg <= S_AXIL_WDATA;
|
|
end if;
|
|
elsif S_AXIL_AWADDR = x"24" then
|
|
if S_AXIL_WSTRB(0) = '1' then
|
|
inOut_reflected_reg <= S_AXIL_WDATA(1 downto 0);
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-------------------------------------------
|
|
-- M_AXI Read data from DRAM state machine
|
|
-------------------------------------------
|
|
M_AXI_ARSIZE <= "010" when DWIDTH=32 else "011"; -- Data width 32/64
|
|
M_AXI_ARBURST <= "01";
|
|
M_AXI_ARPROT <= "000";
|
|
M_AXI_ARCACHE <= "0000";
|
|
M_AXI_ARID <= (others=>'0');
|
|
M_AXI_RREADY <= '1';
|
|
|
|
process
|
|
variable packets_cnt : unsigned(15 downto 0); -- Anzahl der verbleibenden Pakete Minus 1
|
|
variable packet_data_cnt : unsigned(15 downto 0); -- Anzahl der verbleibenden Worte beim aktuellen Packet Minus 1
|
|
variable data_cnt : unsigned(31 downto 0); -- Anzahl der insgesamt verbleibenden Worte Minus 1
|
|
variable read_addr_cnt : unsigned(31 downto 0); -- Zaehler fuer Adresse fuer AXI-Lesevorgaenge
|
|
begin
|
|
wait until rising_edge(CLK);
|
|
|
|
if RESETN = '0' then
|
|
packets_cnt := (others=>'0');
|
|
packet_data_cnt := (others=>'0');
|
|
data_cnt := (others=>'0');
|
|
read_addr_cnt := (others=>'0');
|
|
|
|
M_AXI_ARVALID <= '0';
|
|
M_AXI_ARADDR <= (others=>'0');
|
|
M_AXI_ARLEN <= (others=>'0');
|
|
|
|
read_state <= IDLE;
|
|
else
|
|
case read_state is
|
|
when IDLE =>
|
|
if run_reg_set = '1' then
|
|
packets_cnt := unsigned(packet_number_reg);
|
|
packet_data_cnt := unsigned(packet_size_reg);
|
|
data_cnt := (unsigned(packet_size_reg)+1) * (unsigned(packet_number_reg)+1) - 1;
|
|
read_addr_cnt := unsigned(read_address_reg);
|
|
read_state <= REQ;
|
|
end if;
|
|
|
|
when REQ =>
|
|
if (unsigned(FIFO_NUM_FREE) >= MAX_BURSTLEN) then -- Lesen, wenn genug Platz im FIFO frei ist
|
|
M_AXI_ARADDR <= std_logic_vector(read_addr_cnt);
|
|
M_AXI_ARVALID <= '1';
|
|
|
|
-- Burstlaenge setzen
|
|
if (data_cnt+1) >= MAX_BURSTLEN then
|
|
M_AXI_ARLEN <= std_logic_vector(to_unsigned(MAX_BURSTLEN-1, 4));
|
|
read_addr_cnt := read_addr_cnt + to_unsigned(MAX_BURSTLEN, 32); -- Adresse inkrementieren
|
|
else
|
|
M_AXI_ARLEN <= std_logic_vector(data_cnt(3 downto 0));
|
|
end if;
|
|
|
|
read_state <= WAIT_REQ_ACCEPT;
|
|
end if;
|
|
|
|
when WAIT_REQ_ACCEPT =>
|
|
if M_AXI_ARREADY = '1' then
|
|
M_AXI_ARVALID <= '0';
|
|
|
|
-- setzen des LAST Signals fuer Edge-case packet_size = 0
|
|
if packet_data_cnt = 0 then
|
|
packet_last_word <= '1';
|
|
end if;
|
|
|
|
read_state <= READ_DATA;
|
|
end if;
|
|
|
|
when READ_DATA =>
|
|
if M_AXI_RVALID = '1' then
|
|
|
|
-- Markieren des letzten Wortes
|
|
if packet_data_cnt = 1 then
|
|
packet_last_word <= '1';
|
|
end if;
|
|
|
|
-- Zaehler runterzaehlen
|
|
if packet_data_cnt = 0 then
|
|
packet_last_word <= '0';
|
|
if packets_cnt = 0 then
|
|
|
|
else
|
|
packets_cnt := packets_cnt - 1;
|
|
packet_data_cnt := unsigned(packet_size_reg);
|
|
end if;
|
|
else
|
|
packet_data_cnt := packet_data_cnt - 1;
|
|
end if;
|
|
|
|
if M_AXI_RLAST = '1' then
|
|
packet_last_word <= '0';
|
|
if data_cnt = 0 then -- Alle Datenpakete gelesen?
|
|
if interrupt_enable_reg = '1' then
|
|
read_state <= FINISHED;
|
|
else
|
|
read_state <= IDLE;
|
|
end if;
|
|
else
|
|
read_state <= REQ;
|
|
end if;
|
|
end if;
|
|
|
|
data_cnt := data_cnt - 1;
|
|
end if;
|
|
|
|
when FINISHED =>
|
|
-- Interrupt zuruecksetzen
|
|
if interrupt_reset = '1' then
|
|
read_state <= IDLE;
|
|
end if;
|
|
when others => null;
|
|
end case;
|
|
end if;
|
|
end process;
|
|
|
|
|
|
-------------------------------------------
|
|
-- M_AXIS und S_AXIS Interface connections
|
|
-------------------------------------------
|
|
M_AXIS_TVALID <= M_AXI_RVALID;
|
|
M_AXIS_TDATA <= M_AXI_RDATA;
|
|
M_AXIS_TLAST <= M_AXI_RVALID and packet_last_word;
|
|
|
|
S_AXIS_TREADY <= '1' when (write_state=WRITE_DATA) and M_AXI_WREADY = '1' else '0';
|
|
M_AXI_WVALID <= '1' when (write_state=WRITE_DATA) and S_AXIS_TVALID = '1' else '0';
|
|
M_AXI_WDATA <= S_AXIS_TDATA;
|
|
|
|
|
|
-------------------------------------------
|
|
-- M_AXI Write data to DRAM state machine
|
|
-------------------------------------------
|
|
M_AXI_AWSIZE <= "010" when DWIDTH=32 else "011"; -- Data width 32/64
|
|
M_AXI_AWBURST <= "01";
|
|
M_AXI_AWPROT <= "000";
|
|
M_AXI_AWCACHE <= "0000";
|
|
M_AXI_BREADY <= '1';
|
|
M_AXI_WSTRB <= (others=>'1');
|
|
M_AXI_AWID <= (others=>'0');
|
|
M_AXI_WID <= (others=>'0');
|
|
|
|
process
|
|
variable burst_data_cnt : integer range 0 to MAX_BURSTLEN; -- Zaehler fuer aktuellen Burst
|
|
variable data_cnt : unsigned(31 downto 0); -- Zaehler fuer noch zu schreibende Worte
|
|
variable write_addr : unsigned(31 downto 0); -- Zaehler fuer Schreibadresse
|
|
begin
|
|
wait until rising_edge(CLK);
|
|
|
|
if RESETN = '0' then
|
|
M_AXI_AWVALID <= '0';
|
|
M_AXI_AWADDR <= (others=>'0');
|
|
M_AXI_AWLEN <= (others=>'0');
|
|
M_AXI_WLAST <= '0';
|
|
|
|
burst_data_cnt := 0;
|
|
data_cnt := (others=>'0');
|
|
write_addr := (others=>'0');
|
|
|
|
write_state <= IDLE;
|
|
else
|
|
case write_state is
|
|
when IDLE =>
|
|
if run_reg = '1' then
|
|
-- insgesamt zu sendende Worte = Paketanzahl * Paketgroesse
|
|
data_cnt := (unsigned(packet_size_reg)+1) * (unsigned(packet_number_reg)+1) - 1 + unsigned(packet_number_reg) + 1;
|
|
write_addr := unsigned(write_address_reg);
|
|
|
|
write_state <= REQ;
|
|
end if;
|
|
|
|
when REQ =>
|
|
-- Senden wenn mindestens eine ganze Burstlaenge zu Verfuegung steht
|
|
-- oder wenn nur noch restliche Daten, die weniger als eine Burstlaenge sind zur Verfuegung stehen
|
|
if unsigned(FIFO_NUM_AVAIL) >= MAX_BURSTLEN or ((data_cnt+1) < MAX_BURSTLEN and unsigned(FIFO_NUM_AVAIL) = (data_cnt+1)) then
|
|
M_AXI_AWADDR <= std_logic_vector(write_addr);
|
|
M_AXI_AWVALID <= '1';
|
|
|
|
-- Burstlaenge setzen
|
|
if unsigned(FIFO_NUM_AVAIL) >= MAX_BURSTLEN then
|
|
burst_data_cnt := MAX_BURSTLEN - 1;
|
|
M_AXI_AWLEN <= std_logic_vector(to_unsigned(MAX_BURSTLEN-1, 4));
|
|
write_addr := write_addr + to_unsigned(MAX_BURSTLEN, 32); -- increment address
|
|
else
|
|
M_AXI_AWLEN <= std_logic_vector(data_cnt(3 downto 0));
|
|
burst_data_cnt := to_integer(data_cnt);
|
|
end if;
|
|
|
|
write_state <= WAIT_REQ_ACCEPT;
|
|
end if;
|
|
|
|
when WAIT_REQ_ACCEPT =>
|
|
if M_AXI_AWREADY = '1' then
|
|
M_AXI_AWVALID <= '0';
|
|
|
|
if burst_data_cnt = 1 then
|
|
M_AXI_WLAST <= '1';
|
|
end if;
|
|
|
|
write_state <= WRITE_DATA;
|
|
end if;
|
|
|
|
when WRITE_DATA =>
|
|
if M_AXI_WREADY = '1' then
|
|
if burst_data_cnt = 1 then
|
|
M_AXI_WLAST <= '1';
|
|
end if;
|
|
|
|
if burst_data_cnt = 0 then
|
|
M_AXI_WLAST <= '0';
|
|
|
|
if data_cnt = 0 then
|
|
write_state <= FINISHED;
|
|
-- clear run register
|
|
run_reg_clear <= '1';
|
|
else
|
|
write_state <= REQ;
|
|
end if;
|
|
end if;
|
|
burst_data_cnt := burst_data_cnt - 1;
|
|
data_cnt := data_cnt - 1;
|
|
|
|
end if;
|
|
|
|
when FINISHED =>
|
|
run_reg_clear <= '0';
|
|
|
|
-- Interrupt zuruecksetzen, falls Interrupt aktiviert
|
|
if interrupt_enable_reg = '0' then
|
|
write_state <= IDLE;
|
|
elsif interrupt_reset = '1' then
|
|
write_state <= IDLE;
|
|
end if;
|
|
when others => null;
|
|
end case;
|
|
end if;
|
|
end process;
|
|
end architecture; |