-- CMPE498 Interfacing SDRAM to a microprocessor -- file: constant_timer.vhd -- Author: Kevin Mlazgar -- Revision 1.1 1999/07/25 -- Complete overhaul so that is more generic... -- -- Revision 1.0 1999/07/25 -- initial revision. -- -- -- This entity makes use of CONSTANT compare signals, a carry save counter, -- and two comparators to calculate a time period which is controlled by the -- value loaded into the compare value signals when the frequency of the -- timer_clk is known... -- Since we only want to know when a certain count is reached all we need to -- know is the value of the two vectors expected out of the cscounter when a -- certain count is reached. Thus we avoid the critical path of a ripple-carry -- counter! -- Say we will design a refresh timer at the lowest frequency -- that we should ever run at...say 16MHz (16.38MHz for the MMC2001.) -- Say we want a refresh period of 15.625us as per sdram spec. Therefore -- since we design for 16MHz, we have a period of 62.5ns and need to count -- 250 of them...meaning a minimum of 8 bits wide for the constant_timer_width. -- refresh_timer_compare_value1 <= "11110000"; -- F0H in binary -- refresh_timer_compare_value2 <= "00001010"; -- 0AH in binary -- F0H + 0AH = FAH = 250 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; library work; use work.sdram_package.all; library lpm; use lpm.lpm_components.all; entity constant_timer is generic ( -- width for parameterized counter, and comparator... -- *** Can choose smallest optimal width depending on frequency of -- operation. constant_timer_width : positive := 5 ); port ( -- initialize count constant_timer_clr_count : in std_logic; -- Clock constant_timer_clk : in std_logic; -- Constant signal input1 constant_timer_value1 : in std_logic_vector(constant_timer_width-1 downto 0); -- Constant signal input2 constant_timer_value2 : in std_logic_vector(constant_timer_width-1 downto 0); -- Active high line which indicates that the period of -- the timer has passed. Only lasts one clock cycle then -- count restarts... constant_timer_period_elapsed : out std_logic ); end entity constant_timer; -- Using Altera macro function architecture using_macrofunction of constant_timer is signal internal_compare_value1 : std_logic_vector(constant_timer_width-1 downto 0); signal internal_compare_value2 : std_logic_vector(constant_timer_width-1 downto 0); signal internal_counter_part1 : std_logic_vector(constant_timer_width-1 downto 0); signal internal_counter_part2 : std_logic_vector(constant_timer_width-1 downto 0); signal part1_same : std_logic; signal part2_same : std_logic; signal compare_value_clrn : std_logic; signal sload_val : std_logic; signal period_elapsed : std_logic; signal clr_count : std_logic; begin sload_val <= '1'; -- output indication that one period has elapsed constant_timer_period_elapsed <= period_elapsed; -- give ability for count to restart after each period, -- or when the timer_clr_count goes high... clr_count <= period_elapsed OR constant_timer_clr_count; -- value to count up to is held in two binary weighted vectors -- that represent the two vectors out of carry-save counter internal_compare_value1 <= constant_timer_value1; internal_compare_value2 <= constant_timer_value2; refresh_counter : cscounter generic map ( datawidth => constant_timer_width ) port map ( clock => constant_timer_clk, sreset => clr_count, count_part1_out => internal_counter_part1, count_part2_out => internal_counter_part2 ); refresh_compare1 : lpm_compare generic map ( LPM_WIDTH => constant_timer_width ) port map ( dataa => internal_compare_value1, datab => internal_counter_part1, aeb => part1_same ); refresh_compare2 : lpm_compare generic map ( LPM_WIDTH => constant_timer_width ) port map ( dataa => internal_compare_value2, datab => internal_counter_part2, aeb => part2_same ); period_elapsed <= (part1_same AND part2_same); end using_macrofunction;