----------------------------------------------------------------------- -- $Header: D:\usr\cvsroot/VHDL/lib/JBUS/src/busmaster_async.vhd,v 1.1 2013/07/21 09:21:30 jens Exp $ ----------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; use work.utils_pkg.all; use work.busmaster_types.all; ------------------------------------------------------------------ entity busmaster_async is Generic ( DATA_WIDTH : natural := 32; FIFO_DEPTH : natural := 4 ); Port ( clk : in std_logic; rst : in std_logic; cmd_cycle_finished : out std_logic; cmd_cycle_en : in std_logic; cmd_rdy : out std_logic; cmd_we : in std_logic; cmd_in : in bm_cmd_t; din : in unsigned(DATA_WIDTH-1 downto 0); din_rdy : out std_logic; din_we : in std_logic; dout : out unsigned(DATA_WIDTH-1 downto 0); dout_vld : out std_logic; dout_re : in std_logic; -- J-BUS signals RST_I : in STD_LOGIC; CLK_I : in STD_LOGIC; ACK_I : in std_logic; SRDY_I : in std_logic; MDAT_I : in unsigned(DATA_WIDTH-1 downto 0); MDAT_O : out unsigned(DATA_WIDTH-1 downto 0); ADDR_O : out unsigned(31 downto 0); SEL_O : out unsigned(DATA_WIDTH/8-1 downto 0); WE_O : out std_logic; CYC_O : out std_logic; STB_O : out std_logic; MRDY_O : out std_logic ); end busmaster_async; architecture Behavioral of busmaster_async is -- Bus Command FIFO signal cmd_fifo_din : unsigned(32+DATA_WIDTH/8+1-1 downto 0); signal cmd_fifo_dout : unsigned(32+DATA_WIDTH/8+1-1 downto 0); signal cmd_fifo_re : std_logic; signal cmd_fifo_we : std_logic; signal cmd_fifo_full : std_logic; signal cmd_fifo_empty : std_logic; -- Bus Read FIFO signal read_fifo_re : std_logic; signal read_fifo_we : std_logic; signal read_fifo_full : std_logic; signal read_fifo_empty : std_logic; signal write_fifo_re : std_logic; signal write_fifo_we : std_logic; signal write_fifo_full : std_logic; signal write_fifo_empty : std_logic; signal cycle_busy : std_logic; signal cycle_active : std_logic; signal cmd_en : std_logic; signal cmd_read_en : std_logic; signal read_cnt : integer range 0 to 65535; signal write : std_logic; signal jbus_cycle_busy : std_logic; type debug_t is record read_cnt : integer range 0 to 65535; end record; signal debug : debug_t; begin cmd_en <= cmd_we and not cmd_fifo_full; cmd_read_en <= cmd_en and not cmd_in.rw; write <= cmd_fifo_dout(32+DATA_WIDTH/8); dout_vld <= not read_fifo_empty; MRDY_O <= not read_fifo_full; ADDR_O <= cmd_fifo_dout(31 downto 0); SEL_O <= cmd_fifo_dout(32+DATA_WIDTH/8-1 downto 32); WE_O <= write; cmd_fifo_din <= cmd_in.rw & cmd_in.sel & cmd_in.addr; cmd_rdy <= not cmd_fifo_full; din_rdy <= not write_fifo_full; cmd_fifo_we <= cmd_en; cmd_fifo_re <= SRDY_I and jbus_cycle_busy; read_fifo_we <= ACK_I and jbus_cycle_busy; read_fifo_re <= dout_re; write_fifo_we <= din_we; write_fifo_re <= SRDY_I and jbus_cycle_busy and write and not cmd_fifo_empty; STB_O <= not cmd_fifo_empty; -- J-Bus domain proc_JBUS_to_local_cmd_cycle_finished: process(clk) begin if rising_edge(clk) then cmd_cycle_finished <= not jbus_cycle_busy; end if; end process; proc_JBUS_cycle: process(CLK_I) begin if rising_edge(CLK_I) then jbus_cycle_busy <= cycle_busy or cycle_active; CYC_O <= cycle_busy or cycle_active or cmd_we; end if; end process; proc_bus_read_counter: process(clk) begin if rising_edge(clk) then if rst = '1' then read_cnt <= 0; elsif cmd_read_en = '1' and read_fifo_empty = '1' then read_cnt <= read_cnt + 1; elsif cmd_read_en = '0' and read_fifo_empty = '0' and dout_re = '1' then read_cnt <= read_cnt - 1; end if; end if; end process; debug_bus_read_counter: process(CLK_I) variable rd_en : std_logic; begin if rising_edge(CLK_I) then rd_en := not cmd_fifo_empty and cmd_fifo_re; if RST_I = '1' then debug.read_cnt <= 0; elsif read_fifo_we = '0' and rd_en = '1' then if write = '0' then debug.read_cnt <= debug.read_cnt + 1; end if; elsif read_fifo_we = '1' and rd_en = '0' then if read_fifo_full = '0' then debug.read_cnt <= debug.read_cnt - 1; end if; end if; end if; end process; proc_cycle_active: process(clk) begin if rising_edge(clk) then if rst = '1' then cycle_busy <= '0'; elsif cycle_active = '1' and cmd_fifo_empty = '0' then cycle_busy <= '1'; elsif cycle_active = '0' then cycle_busy <= '0'; end if; end if; end process; proc_cycle_busy: process(clk) begin if rising_edge(clk) then if rst = '1' then cycle_active <= '0'; elsif cycle_busy = '0' then if cmd_we = '1' then cycle_active <= '1'; end if; elsif debug.read_cnt = 0 and write_fifo_empty = '1' and cmd_fifo_empty = '1' then cycle_active <= '0'; end if; end if; end process; -- Bus READ FIFO inst_BM_READ_FIFO: entity work.fifo_async GENERIC MAP ( addr_width => NextExpBaseTwo(FIFO_DEPTH), data_width => DATA_WIDTH, do_last_read_update => true ) PORT MAP ( rst => rst, clk_r => clk, clk_w => CLK_I, we => read_fifo_we, re => read_fifo_re, fifo_full => read_fifo_full, fifo_empty => read_fifo_empty, fifo_afull => open, fifo_aempty => open, data_r => dout, data_w => MDAT_I ); -- Bus WRITE FIFO inst_BM_WRITE_FIFO: entity work.fifo_async GENERIC MAP ( addr_width => NextExpBaseTwo(FIFO_DEPTH), data_width => DATA_WIDTH, do_last_read_update => false ) PORT MAP ( rst => rst, clk_r => CLK_I, clk_w => clk, we => write_fifo_we, re => write_fifo_re, fifo_full => write_fifo_full, fifo_empty => write_fifo_empty, fifo_afull => open, fifo_aempty => open, data_r => MDAT_O, data_w => din ); -- Bus command FIFO inst_BM_CMD_FIFO: entity work.fifo_async GENERIC MAP ( addr_width => NextExpBaseTwo(FIFO_DEPTH), data_width => cmd_fifo_din'length, do_last_read_update => false ) PORT MAP ( rst => rst, clk_r => CLK_I, clk_w => clk, we => cmd_fifo_we, re => cmd_fifo_re, fifo_full => cmd_fifo_full, fifo_empty => cmd_fifo_empty, fifo_afull => open, fifo_aempty => open, data_r => cmd_fifo_dout, data_w => cmd_fifo_din ); end Behavioral;