Перейти к содержанию
    

Сделал модуль RTC

entity RTC is
port(
     RST      : in    Std_logic;
     CLK      : in    Std_logic;
      
    SECONDS   : out    Std_logic_vector(5 downto 0);
    MINUTES   : out    Std_logic_vector(5 downto 0);
    HOURS     : out     Std_logic_vector(4 downto 0);
     
     DAY       : out    Std_logic_vector(5 downto 0);
    MONTH     : out     Std_logic_vector(3 downto 0);
    YEAR      : out    Std_logic_vector(11 downto 0)
  );
end RTC;

и вычисляю часы, минуты, дни и так далее.

Но модуль надо инициализировать реальным временем. Получается надо сделать что то вроде такого

entity RTC is
port(
     RST      : in    Std_logic;
     CLK      : in    Std_logic;
      
    SECONDS_IN   : in    Std_logic_vector(5 downto 0);
    MINUTES_IN   : in    Std_logic_vector(5 downto 0);
    HOURS_IN     : in     Std_logic_vector(4 downto 0); 
    DAY_IN       : in     Std_logic_vector(5 downto 0);
    MONTH_IN    : in Std_logic_vector(3 downto 0);
    YEAR_IN      : in Std_logic_vector(11 downto 0);

        SET  : in Std_logic;

    SECONDS_OUT   : out    Std_logic_vector(5 downto 0);
    MINUTES_OUT   : out    Std_logic_vector(5 downto 0);
    HOURS_OUT     : out    Std_logic_vector(4 downto 0); 
    DAY_OUT       : out    Std_logic_vector(5 downto 0);
    MONTH_OUT    : out    Std_logic_vector(3 downto 0);
    YEAR_OUT      : out    Std_logic_vector(11 downto 0)
  );
end RTC;

набор для ввода и набор для вывода. А по другому никак?

Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сделал модуль RTC

Можно и по-другому.

Один вход для загрузки данных назовём его DATA_LOAD : Std_logic_vector(N-1 downto 0);

И загружаете по нему последовательно данные. Разрядность выбираете в зависимости от придуманного Вами алгоритма.

Загружать данные можно последовательно сначала секунды, потом минуты, потом часы, потом дни, месяцы, года.

Изменено пользователем Flip-fl0p

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно и по-другому.

Один вход для загрузки данных назовём его DATA_LOAD : Std_logic_vector(N-1 downto 0);

И загружаете по нему последовательно данные. Разрядность выбираете в зависимости от придуманного Вами алгоритма.

Загружать данные можно последовательно сначала секунды, потом минуты, потом часы, потом дни, месяцы, года.

последовательно не очень удобно. у меня связь с DSP паралельная шина данных и шина адреса.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

последовательно не очень удобно. у меня связь с DSP паралельная шина данных и шина адреса.

Тогда не пойму Вашего вопроса. Что вы хотите получить в итоге ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тогда не пойму Вашего вопроса. Что вы хотите получить в итоге ?

хочу получить способ настраивать часы реального времени.

хотя..по сигналу SET я могу собрать все данные и передать сериально.

Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сделал модуль RTC и вычисляю часы, минуты, дни и так далее.

Но модуль надо инициализировать реальным временем. Получается надо сделать что то вроде такого

...

набор для ввода и набор для вывода. А по другому никак?

 

Способов можно придумать, наверное, немало, но не будут ли они при этом более неудачными? Что не устраивает в этом варианте?

Изменено пользователем Tausinov

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Способов можно придумать, наверное, немало, но не будут ли они при этом более неудачными? Что не устраивает в этом варианте?

хотелось послушать более опытных товарищей. я не очень искушен в написании под FPGA.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

хотелось послушать более опытных товарищей. я не очень искушен в написании под FPGA.

чем не устраивает внешняя микросхема

например

 

вот тут можете под свои нужды выбрать(параметрический поиск)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

чем не устраивает внешняя микросхема

например

железо уже разработано. это старый проект. я только модули добавляю.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

железо уже разработано. это старый проект. я только модули добавляю.

 

Будьте готовы к тому, что такие часы будут не так точны, как специализированная RTC микросхема.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Будьте готовы к тому, что такие часы будут не так точны, как специализированная RTC микросхема.

ну это да. но периодически происходит корекция.

 

а как мне высчитать високосный год? в Си делал

uint32_t IsLeapYear(uint32_t year)
{
    if(((year%4==0)&&(year%100!=0))||(year%400==0))
        return 1;
    else
       return 0;
}

а тут

function IsLeapYear(year : integer) return std_logic_vector is
variable ret : std_logic_vector;
begin
    if( (year mod 4)= 0 and (year mod 100) /= 0 or (year mod 400) = 0) then
        ret := 1;
     else
        ret := 0;
    end if;     
return ret;        
end function IsLeapYear;

ругается

Error (10500): VHDL syntax error at RTC.vhd(41) near text "or"; expecting ")", or ","

Error (10500): VHDL syntax error at RTC.vhd(41) near text ")"; expecting "then"

вроде со скобками все в порядке

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

function IsLeapYear(year : integer) return std_logic_vector is
variable ret : std_logic_vector;
begin
    if( (year mod 4)= 0 and (year mod 100) /= 0 or (year mod 400) = 0) then
        ret := 1;
     else
        ret := 0;
    end if;     
return ret;        
end function IsLeapYear;

ругается

Error (10500): VHDL syntax error at RTC.vhd(41) near text "or"; expecting ")", or ","

Error (10500): VHDL syntax error at RTC.vhd(41) near text ")"; expecting "then"

вроде со скобками все в порядке

 

Возьмите в скобки операцию "И" вместе с операндами. Видимо, что-то с приоритетами операций. Ну и ret нужно все-таки значения std_logic_vector'а присваивать, а не целые числа.

Изменено пользователем Tausinov

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Возьмите в скобки операцию "И" вместе с операндами. Видимо, что-то с приоритетами операций. Ну и ret нужно все-таки значения std_logic_vector'а присваивать, а не целые числа.

так тоже ругается

function IsLeapYear(year : integer) return std_logic_vector is
variable ret : std_logic_vector;
begin
    if ( ((year mod 4) = 0) and ((year mod 100) /= 0) or ((year mod 400) = 0) ) then
        ret <= '1';
     else
        ret <= '0';
    end if;     
return ret;        
end function IsLeapYear;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

так тоже ругается

function IsLeapYear(year : integer) return std_logic_vector is
variable ret : std_logic_vector;
begin
    if ( ((year mod 4) = 0) and ((year mod 100) /= 0) or ((year mod 400) = 0) ) then
        ret <= '1';
     else
        ret <= '0';
    end if;     
return ret;        
end function IsLeapYear;

 

Ага, еще не заметил:

variable ret : std_logic_vector(0 downto 0);

вместо

variable ret : std_logic_vector;

и значения в двойных кавычках должны быть вместо одинарных.

 

library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;

entity isLeapYear is 
end isLeapYear;

architecture behav of isLeapYear is 

    signal testYear : integer := 2008;

    function IsLeapYear(year : integer) return std_logic_vector is
        variable ret : std_logic_vector(0 downto 0);
    begin
        if ((year mod 4 = 0 and year mod 100 /= 0) or (year mod 400 = 0)) then
        ret := "1";
      else
        ret := "0";
      end if;    

        return ret;        
    end function IsLeapYear;
begin

    process
        variable temp : std_logic_vector(0 downto 0); 
    begin
        temp := IsLeapYear(testYear);
        report "function result is " & integer'image(to_integer(unsigned(temp)));
        wait;
    end process;

end behav;

Изменено пользователем Tausinov

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ага, еще не заметил:

variable ret : std_logic_vector(0 downto 0);

вместо

variable ret : std_logic_vector;

и значения в двойных кавычках должны быть вместо одинарных.

 

library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;

entity isLeapYear is 
end isLeapYear;

architecture behav of isLeapYear is 

    signal testYear : integer := 2008;

    function IsLeapYear(year : integer) return std_logic_vector is
        variable ret : std_logic_vector(0 downto 0);
    begin
        if ((year mod 4 = 0 and year mod 100 /= 0) or (year mod 400 = 0)) then
        ret := "1";
      else
        ret := "0";
      end if;    

        return ret;        
    end function IsLeapYear;
begin

    process
        variable temp : std_logic_vector(0 downto 0); 
    begin
        temp := IsLeapYear(testYear);
        report "function result is " & integer'image(to_integer(unsigned(temp)));
        wait;
    end process;

end behav;

да. спасибо. так компилируется.

 

в конце концов вот такая петрушка получилась.

library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity RTC is
port(
    RST      : in   Std_logic;
    CLK      : in   Std_logic;

    SET      :In    Std_logic; 

 SECONDS_SET : in    Std_logic_vector(5 downto 0);
 MINUTES_SET : in    Std_logic_vector(5 downto 0);
 HOURS_SET   : in    Std_logic_vector(4 downto 0);
 DAY_SET     : in    Std_logic_vector(5 downto 0);
   MONTH_SET   : in    Std_logic_vector(3 downto 0);
 YEAR_SET    : in    Std_logic_vector(11 downto 0);

 MILISECONDS : out    Std_logic_vector(9 downto 0);
   SECONDS   : out    Std_logic_vector(5 downto 0);
   MINUTES   : out    Std_logic_vector(5 downto 0);
   HOURS     : out    Std_logic_vector(4 downto 0);
 DAY       : out    Std_logic_vector(5 downto 0);
   MONTH     : out    Std_logic_vector(3 downto 0);
 YEAR      : out    Std_logic_vector(11 downto 0)

 --DAY_OF_WEEK :in    Std_logic_vector(3 downto 0) 
 );
end RTC;



architecture STRUCTURE of RTC is

function IsLeapYear(year : integer) return std_logic_vector is
variable ret : std_logic_vector(0 downto 0);
begin
   if ((year mod 4 = 0 and year mod 100 /= 0) or (year mod 400 = 0)) then
       ret := "1";
   else
       ret := "0";
    end if;    
return ret;        
end function IsLeapYear;

type  arr_type1 is array (0 to 12) of integer range 0 to 32; -- := (0,31,28,31,30,31,30,31,31,30,31,30,31);
signal days_in_month : arr_type1 := (0,31,28,31,30,31,30,31,31,30,31,30,31);

signal count : integer := 1;
signal tick_1ms : std_logic := '0';

signal milisec : integer range 0 to 1000 := 0;
signal sec,min,hour : integer range 0 to 60 := 0;
signal days : integer range 0 to 31 := 1;
signal months : integer range 0 to 12 := 1;
signal years : integer := 0;

signal days_per_month : integer range 0 to 31 := 0;

begin

MILISECONDS  <= std_logic_vector(to_unsigned(milisec,10));
SECONDS      <= std_logic_vector(to_unsigned(sec,6));
MINUTES      <= std_logic_vector(to_unsigned(min,6));
HOURS        <= std_logic_vector(to_unsigned(hour,5));

DAY          <= std_logic_vector(to_unsigned(days,6));
MONTH        <= std_logic_vector(to_unsigned(months,4));
YEAR         <= std_logic_vector(to_unsigned(years, 12));


--clk generation. For 30 MHz clock this generates 1 milisec clock.
process (CLK,RST)

begin

   if (RST='1') then
     count <= 1;
   elsif (rising_edge(CLK) ) then
     count <= count + 1;
	  if(count = 15000) then  --15000000
	      tick_1ms <= not tick_1ms;
			count <= 1;
	  end if;
   end if;

end process;


process (CLK,RST)
begin

   if (SET='1') then
     sec <= to_integer(unsigned(SECONDS_SET));
	  min <= to_integer(unsigned(MINUTES_SET));
	  hour <= to_integer(unsigned(HOURS_SET));
	  days <= to_integer(unsigned(DAY_SET));
	  months <= to_integer(unsigned(MONTH_SET));
	  years <= to_integer(unsigned(YEAR_SET));
   elsif (rising_edge(tick_1ms) ) then
     milisec <= milisec + 1;
	  if (milisec = 999) then
	      milisec <= 0;
         sec <= sec+ 1;
	  end if;		
	  if(sec = 59) then
           sec <= 0;
           min <= min + 1;
	  end if;		
       if(min = 59) then
	      min <= 0;
           hour <= hour + 1;
       end if;   
       if(hour = 23) then
           hour <= 0;
			days <= days + 1;
			if (months = 2) then --calculate days for february
			    if (IsLeapYear(years) = 1) then
				     days_per_month <= 29;
				  else
			   	  days_per_month <= 28;
				  end if;
			else
			   days_per_month <= days_in_month(months);
			end if;
	  end if;
	  if(days = days_per_month) then
	      days <= 0;
			months <= months + 1;
	  end if;
	  if (months = 12) then
	      months <= 0;
			years <= years + 1;
	  end if;

 end if;

end process;

end STRUCTURE;

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...