diff --git a/MSF/RTC/hdl/rtc.vhd b/MSF/RTC/hdl/rtc.vhd index ee198ff4f216a43800b3806fc3adaf85f314b85b..c0d5dae52ecf5bb293c6092709aff15cced1f7be 100644 --- a/MSF/RTC/hdl/rtc.vhd +++ b/MSF/RTC/hdl/rtc.vhd @@ -16,6 +16,10 @@ entity rtc is hour_in : in std_logic_vector (4 downto 0); minute_in : in std_logic_vector (5 downto 0); + year_out : out std_logic_vector (6 downto 0); + month_out : out std_logic_vector (3 downto 0); + d_month_out : out std_logic_vector (4 downto 0); + d_week_out : out std_logic_vector (2 downto 0); hour_out : out std_logic_vector (4 downto 0); minute_out : out std_logic_vector (5 downto 0); second_out : out std_logic_vector (5 downto 0) @@ -26,56 +30,97 @@ architecture behavioral of rtc is signal clk_second : std_logic := '1'; - signal crys_count : unsigned (13 downto 0) := (others => '0'); + signal crys_count : unsigned (13 downto 0) := (others => '0'); --13 downto 0 signal year_int : unsigned (6 downto 0) := (others => '0'); - signal month_int : unsigned (3 downto 0) := (others => '0'); - signal d_month_int : unsigned (4 downto 0) := (others => '0'); - signal d_week_int : unsigned (2 downto 0) := (others => '0'); + signal month_int : unsigned (3 downto 0) := "0001"; + signal d_month_int : unsigned (4 downto 0) := "00001"; + signal d_week_int : unsigned (2 downto 0) := (others => '1'); signal hour_int : unsigned (4 downto 0) := (others => '0'); signal minute_int : unsigned (5 downto 0) := (others => '0'); signal second_int : unsigned (5 downto 0) := (others => '0'); begin - + --Divide crystal oscillator down to 1Hz clock-- - CLOCK_GEN: process(rst, time_ready, clk_crystal) + CLOCK_GEN: process(time_ready, clk_crystal) begin - if rst = '1' then --or start of pulse - crys_count <= (others => '0'); - clk_second <= '1'; - elsif rising_edge(time_ready) then --synchronise to msf + if rising_edge(time_ready) then --synchronise to msf crys_count <= (others => '0'); clk_second <= '1'; elsif rising_edge(clk_crystal) then - crys_count <= crys_count + 1; - if crys_count = 15 then --16383 officially - clk_second <= not(clk_second); + if rst = '1' then -- sync rst + crys_count <= (others => '0'); + clk_second <= '1'; + else + crys_count <= crys_count + 1; + if crys_count = 16383 then --16383 officially + clk_second <= not(clk_second); + end if; end if; end if; end process; --Count seconds minutes and hours-- - CLOCK_COUNT: process(rst, time_ready, clk_second) + CLOCK_COUNT: process(time_ready, clk_second, clk_crystal) begin - if rst = '1' then - second_int <= (others => '0'); - minute_int <= (others => '0'); - hour_int <= (others => '0'); - - elsif rising_edge(time_ready) then --set time + + if rising_edge(time_ready) then --set time second_int <= "111011"; --assume data comes at 59 seconds minute_int <= unsigned(minute_in); hour_int <= unsigned(hour_in); + d_week_int <= unsigned(d_week_in); + d_month_int <= unsigned(d_month_in); + month_int <= unsigned(month_in); + year_int <= unsigned(year_in); elsif rising_edge(clk_second) then - if second_int = 59 then + if second_int = 59 then --SECONDS second_int <= (others => '0'); - if minute_int = 59 then + + if minute_int = 59 then --MINUTE minute_int <= (others => '0'); - if hour_int = 23 then + if hour_int = 23 then --HOUR hour_int <= (others => '0'); + + if d_week_int = 7 then --DOW + d_week_int <= "001"; + else + d_week_int <= d_week_int + 1; + end if; + + if ((month_int = 1 or month_int = 3 or --odd days + month_int = 5 or month_int = 7 or + month_int = 8 or month_int = 10 or + month_int = 12) and (d_month_int = 31)) or + + ((month_int = 4 or month_int = 6 or --even days + month_int = 9 or month_int = 11) and + (d_month_int = 30)) or + + (month_int = 2 and year_int mod 4 = 0 and --leap year + d_month_int = 29) or + + (month_int = 2 and not (year_int mod 4 = 0) and --normal feb + d_month_int = 28) then --DOM + d_month_int <= "00001"; + + if month_int = 12 then --MONTH + month_int <= "0001"; + + if year_int = 99 then --YEAR + year_int <= (others => '0'); + else + year_int <= year_int + 1; + end if; + else + month_int <= month_int + 1; + end if; + else + d_month_int <= d_month_int + 1; + end if; + else hour_int <= hour_int + 1; end if; @@ -85,12 +130,25 @@ architecture behavioral of rtc is else second_int <= second_int + 1; end if; + + elsif rising_edge(clk_crystal) then + if rst = '1' then -- sync rst + second_int <= (others => '0'); + minute_int <= (others => '0'); + hour_int <= (others => '0'); + end if; end if; + + end process; --Concurrent assignments-- second_out <= std_logic_vector(second_int); minute_out <= std_logic_vector(minute_int); hour_out <= std_logic_vector(hour_int); + d_week_out <= std_logic_vector(d_week_int); + d_month_out <= std_logic_vector(d_month_int); + month_out <= std_logic_vector(month_int); + year_out <= std_logic_vector(year_int); end behavioral; \ No newline at end of file