diff --git a/lib/misc/async_port_wb.vhd b/lib/misc/async_port_wb.vhd index 2ec000d..04d2861 100644 --- a/lib/misc/async_port_wb.vhd +++ b/lib/misc/async_port_wb.vhd @@ -1,5 +1,5 @@ ----------------------------------------------------------------------- --- $Header: /tmp/cvsroot/VHDL/lib/misc/async_port_wb.vhd,v 1.6 2009-10-27 21:25:36 Jens Exp $ +-- $Header: /tmp/cvsroot/VHDL/lib/misc/async_port_wb.vhd,v 1.7 2009-10-28 22:44:07 Jens Exp $ ----------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; @@ -17,25 +17,26 @@ entity async_port_wb is ); Port ( - CLK_I : in STD_LOGIC; - RST_I : in STD_LOGIC; - CYC_I : in STD_LOGIC; - STB_I : in STD_LOGIC; - WE_I : in STD_LOGIC; - ACK_O : out STD_LOGIC; - SRDY_O : out STD_LOGIC; - MRDY_I : in STD_LOGIC; - SEL_I : in unsigned(3 downto 0); - ADDR_I : in unsigned(31 downto 0); - DAT_I : in unsigned(31 downto 0); - DAT_O : out unsigned(31 downto 0); - async_a : out unsigned(addr_width-1 downto 0); - async_d : inout unsigned(data_width-1 downto 0); - async_cs : out std_logic; - async_wr : out std_logic; - async_rd : out std_logic; - async_be : out unsigned(byte_sel_width-1 downto 0); - async_rst : out std_logic + CLK_I : in STD_LOGIC; + RST_I : in STD_LOGIC; + CYC_I : in STD_LOGIC; + STB_I : in STD_LOGIC; + WE_I : in STD_LOGIC; + ACK_O : out STD_LOGIC; + SRDY_O : out STD_LOGIC; + MRDY_I : in STD_LOGIC; + SEL_I : in unsigned(3 downto 0); + ADDR_I : in unsigned(31 downto 0); + DAT_I : in unsigned(31 downto 0); + DAT_O : out unsigned(31 downto 0); + page_mode_en : in STD_LOGIC; + async_a : out unsigned(addr_width-1 downto 0); + async_d : inout unsigned(data_width-1 downto 0); + async_cs : out std_logic; + async_wr : out std_logic; + async_rd : out std_logic; + async_be : out unsigned(byte_sel_width-1 downto 0); + async_rst : out std_logic ); end async_port_wb; @@ -51,28 +52,35 @@ architecture Behavioral of async_port_wb is type async_state_t is (start, reset, idle, leadin, pulse, leadout, release); - signal s, sn : async_state_t; - signal as : async_t; - signal ack : std_logic; - signal cc_rst : std_logic; - signal cycle_cnt : natural range 0 to 15; - signal cycle_reload : natural range 0 to 15; - signal rdy : std_logic; - signal rdyo : std_logic; - signal en : std_logic; - signal data_reg : unsigned(data_width-1 downto 0); - signal byte_en : unsigned(byte_sel_width-1 downto 0); - signal write : std_logic; + signal s, sn : async_state_t; + signal as : async_t; + signal ack : std_logic; + signal cc_rst : std_logic; + signal cycle_cnt : natural range 0 to 15; + signal cycle_reload : natural range 0 to 15; + signal rdy : std_logic; + signal rdyo : std_logic; + signal en : std_logic; + signal is_idle : std_logic; + signal DAT_I_r : unsigned(data_width-1 downto 0); + signal SEL_I_r : unsigned(byte_sel_width-1 downto 0); + signal WE_I_r : std_logic; + signal ADDR_I_r : unsigned(addr_width-1 downto 0); + signal page_mode_en_r : std_logic; + signal do_page_read : std_logic; ------------------------------------------------------------------ begin ASSERT async_timespec.ncyc_pulse_rd > 0 report "Read pulse length must be greater than zero!" severity failure; ASSERT async_timespec.ncyc_pulse_wr > 0 report "Write pulse length must be greater than zero!" severity failure; + ASSERT (not async_timespec.can_page_rd OR (async_timespec.ncyc_pulse_page_rd > 0)) report "Read page pulse length must be greater than zero!" severity failure; SRDY_O <= CYC_I and rdyo; en <= CYC_I and STB_I; + do_page_read <= '1' when (async_timespec.can_page_rd and (WE_I = WE_I_r) and (WE_I = '0') and (ADDR_I(addr_width-1 downto async_timespec.nbits_page_rd) = ADDR_I_r(addr_width-1 downto async_timespec.nbits_page_rd))) else '0'; + proc_cycle_counter: process(CLK_I) begin @@ -99,7 +107,7 @@ architecture Behavioral of async_port_wb is end process; proc_state: - process(s, cycle_cnt, en, write, WE_I) + process(s, cycle_cnt, en, WE_I, WE_I_r, do_page_read) begin cycle_reload <= async_timespec.ncyc_pulse_rst; @@ -111,6 +119,7 @@ architecture Behavioral of async_port_wb is as.drive_d <= '0'; ack <= '0'; rdy <= '0'; + is_idle <= '0'; sn <= s; case s is @@ -125,6 +134,7 @@ architecture Behavioral of async_port_wb is end if; when idle => rdy <= '1'; + is_idle <= '1'; if en = '1' then as.cs <= '1'; cc_rst <= '1'; @@ -149,7 +159,7 @@ architecture Behavioral of async_port_wb is if cycle_cnt = 0 then cc_rst <= '1'; sn <= pulse; - if write = '1' then + if WE_I_r = '1' then cycle_reload <= async_timespec.ncyc_pulse_wr-1; as.wr <= '1'; as.drive_d <= '1'; @@ -161,16 +171,19 @@ architecture Behavioral of async_port_wb is when pulse => as.cs <= '1'; - as.rd <= not write; - as.drive_d <= write; - as.wr <= write; + as.rd <= not WE_I_r; + as.drive_d <= WE_I_r; + as.wr <= WE_I_r; if cycle_cnt = 0 then as.wr <= '0'; - as.rd <= '0'; cc_rst <= '1'; - ack <= not write; - if async_timespec.ncyc_leadout = 0 then - as.cs <= '0'; + ack <= not WE_I_r; + rdy <= do_page_read; + if en = '1' and do_page_read = '1' then + as.cs <= '1'; + cycle_reload <= async_timespec.ncyc_pulse_page_rd; + sn <= pulse; + elsif async_timespec.ncyc_leadout = 0 then if async_timespec.ncyc_release = 0 then sn <= idle; else @@ -185,10 +198,13 @@ architecture Behavioral of async_port_wb is when leadout => as.cs <= '1'; + as.drive_d <= WE_I_r; if cycle_cnt = 0 then cc_rst <= '1'; - as.cs <= '0'; - if async_timespec.ncyc_release = 0 then + rdy <= '1'; + if en = '1' then + sn <= idle; + elsif async_timespec.ncyc_release = 0 then sn <= idle; else cycle_reload <= async_timespec.ncyc_release-1; @@ -213,7 +229,7 @@ architecture Behavioral of async_port_wb is begin if rising_edge(CLK_I) then async_cs <= (not async_timespec.pol_cs) xor as.cs; - async_be <= (byte_sel_width-1 downto 0 => not async_timespec.pol_be) xor ((byte_sel_width-1 downto 0 => as.cs) and byte_en); + async_be <= (byte_sel_width-1 downto 0 => not async_timespec.pol_be) xor ((byte_sel_width-1 downto 0 => as.cs) and SEL_I_r); async_wr <= (not async_timespec.pol_we) xor as.wr; async_rd <= (not async_timespec.pol_oe) xor as.rd; async_rst <= (not async_timespec.pol_rst) xor as.rst; @@ -238,10 +254,13 @@ architecture Behavioral of async_port_wb is if rising_edge(CLK_I) then if RST_I = '1' then async_a <= (others => '0'); - byte_en <= (others => '0'); + SEL_I_r <= (others => '0'); elsif en = '1' and rdy = '1' then async_a <= ADDR_I(addr_width-1 downto 0); - byte_en <= SEL_I(byte_sel_width-1 downto 0); + SEL_I_r <= SEL_I(byte_sel_width-1 downto 0); + if is_idle = '1' then + ADDR_I_r <= ADDR_I(addr_width-1 downto 0); + end if; end if; end if; end process; @@ -251,9 +270,10 @@ architecture Behavioral of async_port_wb is process(CLK_I) begin if rising_edge(CLK_I) then + page_mode_en_r <= page_mode_en; if en = '1' and rdy = '1' then - data_reg <= DAT_I(data_width-1 downto 0); - write <= WE_I; + DAT_I_r <= DAT_I(data_width-1 downto 0); + WE_I_r <= WE_I; end if; end if; end process; @@ -291,7 +311,7 @@ architecture Behavioral of async_port_wb is if rising_edge(CLK_I) then async_d <= (others => 'Z'); if as.drive_d = '1' then - async_d <= data_reg; + async_d <= DAT_I_r; end if; end if; end process;