-------------------------------------------------------------------------------- -- WeeklyEventManager.vhd -- 1998 Nov 3 -- Sydney Tang -- -- memory read/write manager for weekly alarm events -- -- 46 (3%) logic cells, 20 embedded cells, 3 EABs, 40.3ns, 24.81MHz -- -- eventID: ID number of the event (0 to 7) -- -- writeEvent: indicates if the input_ values should be written to the memory -- slot specified by eventID -- -- checkforEvent: input, set to 1 when a check for an event is requested. -- the input time will be compared to the times stored in RAM -- -- eventMatched: issued in response to a checkforEvent request. Is '1' if -- a match was found between the input time and a time stored in memory. -- -- hour, minute, weekday: current data stored at eventID. While an event -- check is being done, this data is unstable, and hence should not be read -- anytime soon after requesting an event check. -- -- input_hour, input_minute, input_weekday: input data -- -------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; library lpm; use lpm.lpm_components.lpm_ram_dq; library work; use work.Constants_Package.all; use work.Time_Package.all; use work.BCD_Package.all; entity WeeklyEventManager is port( clock: in std_logic; eventID: in std_logic_vector(EVENT_ID_WIDTH-1 downto 0); writeEvent: in std_logic; checkForEvent: in std_logic; eventMatched: out std_logic; eventMatchAcknowledged: in std_logic; hour: out std_logic_vector(HOUR_WIDTH-1 downto 0); minute: out std_logic_vector(MINUTE_WIDTH-1 downto 0); weekday: out std_logic_vector(WEEKDAY_WIDTH-1 downto 0); test_hour: in std_logic_vector(HOUR_WIDTH-1 downto 0); test_minute: in std_logic_vector(MINUTE_WIDTH-1 downto 0); test_weekday: in std_logic_vector(WEEKDAY_WIDTH-1 downto 0); input_hour: in std_logic_vector(HOUR_WIDTH-1 downto 0); input_minute: in std_logic_vector(MINUTE_WIDTH-1 downto 0); input_weekday: in std_logic_vector(WEEKDAY_WIDTH-1 downto 0) ); end WeeklyEventManager; -------------------------------------------------------------------------------- architecture manager of WeeklyEventManager is signal address, -- address input to RAM component addressBeingChecked: -- address whose data is being checked std_logic_vector(EVENT_ID_WIDTH-1 downto 0); signal eventCheckInProgress, -- duh. brute force search for event match eventCheckCompleted: -- finished checking all addresses std_logic; signal WeeklyEventData, -- data at current address TestWeeklyEventData, -- data to be tested for event match InputWeeklyEventData, -- data sitting on the input ports WeeklyEventDataToBeTested: -- input data when checkForEvent = '1' std_logic_vector(WEEKLY_EVENT_WIDTH-1 downto 0); begin ------------------------------------------------------------------------------ -- direct the data coming out of RAM into the appropriate output ports hour <= WeeklyEventData(WEEKLY_EVENT_WIDTH-1 downto WEEKLY_EVENT_WIDTH-HOUR_WIDTH); minute <= WeeklyEventData(MINUTE_WIDTH+WEEKDAY_WIDTH-1 downto WEEKDAY_WIDTH); weekday <= WeeklyEventData(WEEKDAY_WIDTH-1 downto 0); -- direct the test data into one convenient signal bus. TestWeeklyEventData(WEEKLY_EVENT_WIDTH-1 downto WEEKLY_EVENT_WIDTH-HOUR_WIDTH) <= test_hour; TestWeeklyEventData(MINUTE_WIDTH+WEEKDAY_WIDTH-1 downto WEEKDAY_WIDTH) <= test_minute; TestWeeklyEventData(WEEKDAY_WIDTH-1 downto 0) <= test_weekday; -- direct the input data into one convenient signal bus. InputWeeklyEventData(WEEKLY_EVENT_WIDTH-1 downto WEEKLY_EVENT_WIDTH-HOUR_WIDTH) <= input_hour; InputWeeklyEventData(MINUTE_WIDTH+WEEKDAY_WIDTH-1 downto WEEKDAY_WIDTH) <= input_minute; InputWeeklyEventData(WEEKDAY_WIDTH-1 downto 0) <= input_weekday; ------------------------------------------------------------------------------ -- interface to our little block of RAM where we store our events eventRAM: lpm_ram_dq generic map( LPM_WIDTH => WEEKLY_EVENT_WIDTH, LPM_WIDTHAD => EVENT_ID_WIDTH, LPM_FILE => "WeeklyEventManager.mif", LPM_INDATA => "REGISTERED", LPM_ADDRESS_CONTROL => "REGISTERED", -- for secure addressing LPM_OUTDATA => "UNREGISTERED" -- want output to change ASAP ) port map( data => InputWeeklyEventData, address => address, --eventAddress, we => writeEvent, inclock => clock, --outclock => clock, -- used only for registered outdata q => WeeklyEventData ); -- Normally, the memory address being referenced is the input event ID, -- but when we're checking for an event, the referenced address is an -- internal signal. address <= eventID when eventCheckInProgress = '0' else addressBeingChecked; ------------------------------------------------------------------------------ eventCheck: process(clock) is begin if rising_edge(clock) then if checkForEvent = '1' then -- Set the address being checked to the first record in memory -- Indicate that we are checking for an event -- Copy the current input data addressBeingChecked <= FIRST_EVENT; eventCheckInProgress <= '1'; WeeklyEventDataToBeTested <= TestWeeklyEventData; end if; -- checkForEvent if eventCheckInProgress = '1' then if WeeklyEventDataToBeTested = WeeklyEventData then -- if we find a match, indicate that we did, and stop checking eventMatched <= '1'; eventCheckInProgress <= '0'; else -- No match. -- If we're on the last address, flag completion of the check. On -- the next clock, we will compare the last event in memory to the -- current input data, and turn off eventCheckInProgress. eventMatched <= '0'; if addressBeingChecked = LAST_EVENT then eventCheckCompleted <= '1'; elsif eventCheckCompleted = '1' then eventCheckCompleted <= '0'; eventCheckInProgress <= '0'; end if; -- increment address being checked. addressBeingChecked <= addressBeingChecked + '1'; end if; -- no event match else -- event check not in progress -- Obviously, if we're not checking for an event, there can be no match! if eventMatchAcknowledged = '1' then eventMatched <= '0'; end if; end if; -- event check end if; -- rising clock edge end process eventCheck; ------------------------------------------------------------------------------ end manager;