Vhdl FPGA中的编译日期和时间

Vhdl FPGA中的编译日期和时间,vhdl,fpga,intel-fpga,nios,Vhdl,Fpga,Intel Fpga,Nios,我可以在VHDL中使用类似于C-Sourcecode-Macros的东西吗 要使编译时间作为一种版本时间戳在FPGA中可用 作为>>>新来者,当前日期和时间在VHDL中不直接可用,但下面建议解决方案 编辑2013-08-10:增加了Altera Quartus II Tcl自动发电的说明 使日期和时间可用的一种方法是通过自动生成的VHDL包,如下所示: library ieee; use ieee.std_logic_1164.all; package datetime is -- Dat

我可以在VHDL中使用类似于C-Sourcecode-Macros的东西吗 要使编译时间作为一种版本时间戳在FPGA中可用


作为>>>新来者,当前日期和时间在VHDL中不直接可用,但下面建议解决方案

编辑2013-08-10:增加了Altera Quartus II Tcl自动发电的说明

使日期和时间可用的一种方法是通过自动生成的VHDL包,如下所示:

library ieee;
use ieee.std_logic_1164.all;

package datetime is
  -- Date information
  constant YEAR_INT  : integer                       := 2013;
  constant YEAR_HEX  : std_logic_vector(15 downto 0) := X"2013";
  constant MONTH_INT : integer                       := 08;
  constant MONTH_HEX : std_logic_vector(7 downto 0)  := X"08";
  constant DAY_INT   : integer                       := 09;
  constant DAY_HEX   : std_logic_vector(7 downto 0)  := X"09";
  constant DATE_HEX  : std_logic_vector(31 downto 0) := YEAR_HEX & MONTH_HEX & DAY_HEX;
  -- Time information
  constant HOUR_INT   : integer                       := 13;
  constant HOUR_HEX   : std_logic_vector(7 downto 0)  := X"13";
  constant MINUTE_INT : integer                       := 06;
  constant MINUTE_HEX : std_logic_vector(7 downto 0)  := X"06";
  constant SECOND_INT : integer                       := 29;
  constant SECOND_HEX : std_logic_vector(7 downto 0)  := X"29";
  constant TIME_HEX   : std_logic_vector(31 downto 0) := X"00" & HOUR_HEX & MINUTE_HEX & SECOND_HEX;
  -- Miscellaneous information
  constant EPOCH_INT  : integer := 1376046389;  -- Seconds since 1970-01-01_00:00:00
end package;
此VHDL包可以使用以下Tcl脚本创建:

# Make datetime.vhd package from Tcl script

# Current date, time, and seconds since epoch
# Array index                                            0  1  2  3  4  5  6
set datetime_arr [clock format [clock seconds] -format {%Y %m %d %H %M %S %s}]

# Write VHDL package
set filename datetime.vhd
set file [open $filename w]
puts $file "library ieee;"
puts $file "use ieee.std_logic_1164.all;"
puts $file ""
puts $file "package datetime is"
puts $file "  -- Date information"
puts $file "  constant YEAR_INT  : integer                       := [lindex $datetime_arr 0];"
puts $file "  constant YEAR_HEX  : std_logic_vector(15 downto 0) := X\"[lindex $datetime_arr 0]\";"
puts $file "  constant MONTH_INT : integer                       := [lindex $datetime_arr 1];"
puts $file "  constant MONTH_HEX : std_logic_vector(7 downto 0)  := X\"[lindex $datetime_arr 1]\";"
puts $file "  constant DAY_INT   : integer                       := [lindex $datetime_arr 2];"
puts $file "  constant DAY_HEX   : std_logic_vector(7 downto 0)  := X\"[lindex $datetime_arr 2]\";"
puts $file "  constant DATE_HEX  : std_logic_vector(31 downto 0) := YEAR_HEX & MONTH_HEX & DAY_HEX;"
puts $file "  -- Time information"
puts $file "  constant HOUR_INT   : integer                       := [lindex $datetime_arr 3];"
puts $file "  constant HOUR_HEX   : std_logic_vector(7 downto 0)  := X\"[lindex $datetime_arr 3]\";"
puts $file "  constant MINUTE_INT : integer                       := [lindex $datetime_arr 4];"
puts $file "  constant MINUTE_HEX : std_logic_vector(7 downto 0)  := X\"[lindex $datetime_arr 4]\";"
puts $file "  constant SECOND_INT : integer                       := [lindex $datetime_arr 5];"
puts $file "  constant SECOND_HEX : std_logic_vector(7 downto 0)  := X\"[lindex $datetime_arr 5]\";"
puts $file "  constant TIME_HEX   : std_logic_vector(31 downto 0) := X\"00\" & HOUR_HEX & MINUTE_HEX & SECOND_HEX;"
puts $file "  -- Miscellaneous information"
puts $file "  constant EPOCH_INT  : integer := [lindex $datetime_arr 6];  -- Seconds since 1970-01-01_00:00:00"
puts $file "end package;"
close $file
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity Datum2 is
  port(
    Day   : out std_logic_vector(4 downto 0);
    Month : out std_logic_vector(3 downto 0);
    Year  : out std_logic_vector(4 downto 0));
end Datum2;


library work;
use work.datetime;

architecture rtl of Datum2 is
begin
  Day   <= conv_std_logic_vector(datetime.day_int, 5);
  Month <= conv_std_logic_vector(datetime.month_int, 4);
  Year  <= conv_std_logic_vector(datetime.year_int mod 100, 5);
end architecture rtl;
# Make datetime.vhd package from shell script

# Current date, time, and seconds since epoch
# Array index           0  1  2  3  4  5  6
datetime_arr=($(date +"%Y %m %d %H %M %S %s"))

# Write VHDL package
filename="datetime.vhd"
echo "library ieee;" > $filename
echo "use ieee.std_logic_1164.all;" >> $filename
echo "" >> $filename
echo "package datetime is" >> $filename
echo "  -- Date information" >> $filename
echo "  constant YEAR_INT  : integer                       := ${datetime_arr[0]};" >> $filename
echo "  constant YEAR_HEX  : std_logic_vector(15 downto 0) := X\"${datetime_arr[0]}\";" >> $filename
echo "  constant MONTH_INT : integer                       := ${datetime_arr[1]};" >> $filename
echo "  constant MONTH_HEX : std_logic_vector(7 downto 0)  := X\"${datetime_arr[1]}\";" >> $filename
echo "  constant DAY_INT   : integer                       := ${datetime_arr[2]};" >> $filename
echo "  constant DAY_HEX   : std_logic_vector(7 downto 0)  := X\"${datetime_arr[2]}\";" >> $filename
echo "  constant DATE_HEX  : std_logic_vector(31 downto 0) := YEAR_HEX & MONTH_HEX & DAY_HEX;" >> $filename
echo "  -- Time information" >> $filename
echo "  constant HOUR_INT   : integer                       := ${datetime_arr[3]};" >> $filename
echo "  constant HOUR_HEX   : std_logic_vector(7 downto 0)  := X\"${datetime_arr[3]}\";" >> $filename
echo "  constant MINUTE_INT : integer                       := ${datetime_arr[4]};" >> $filename
echo "  constant MINUTE_HEX : std_logic_vector(7 downto 0)  := X\"${datetime_arr[4]}\";" >> $filename
echo "  constant SECOND_INT : integer                       := ${datetime_arr[5]};" >> $filename
echo "  constant SECOND_HEX : std_logic_vector(7 downto 0)  := X\"${datetime_arr[5]}\";" >> $filename
echo "  constant TIME_HEX   : std_logic_vector(31 downto 0) := X\"00\" & HOUR_HEX & MINUTE_HEX & SECOND_HEX;" >> $filename
echo "  -- Miscellaneous information" >> $filename
echo "  constant EPOCH_INT  : integer := ${datetime_arr[6]};  -- Seconds since 1970-01-01_00:00:00" >> $filename
echo "end package;" >> $filename
library ieee;
use ieee.std_logic_1164.all;
entity tb is
end entity;

library work;
use work.datetime;
architecture sim of tb is
  signal date_hex : std_logic_vector(31 downto 0);
  signal time_hex : std_logic_vector(31 downto 0);
begin
  date_hex <= datetime.DATE_HEX;
  time_hex <= datetime.TIME_HEX;
  process is begin wait; end process;
end architecture;
在AlteraQuartus II中,可以在合成之前让流程运行此脚本,从而可以创建datetime包。这是在.qsf文件中完成的,下面一行是脚本名为“make_datetime.tcl”:

有关Quartus II功能的进一步说明,请参见

然后,Datum2模块可以像这样使用软件包:

# Make datetime.vhd package from Tcl script

# Current date, time, and seconds since epoch
# Array index                                            0  1  2  3  4  5  6
set datetime_arr [clock format [clock seconds] -format {%Y %m %d %H %M %S %s}]

# Write VHDL package
set filename datetime.vhd
set file [open $filename w]
puts $file "library ieee;"
puts $file "use ieee.std_logic_1164.all;"
puts $file ""
puts $file "package datetime is"
puts $file "  -- Date information"
puts $file "  constant YEAR_INT  : integer                       := [lindex $datetime_arr 0];"
puts $file "  constant YEAR_HEX  : std_logic_vector(15 downto 0) := X\"[lindex $datetime_arr 0]\";"
puts $file "  constant MONTH_INT : integer                       := [lindex $datetime_arr 1];"
puts $file "  constant MONTH_HEX : std_logic_vector(7 downto 0)  := X\"[lindex $datetime_arr 1]\";"
puts $file "  constant DAY_INT   : integer                       := [lindex $datetime_arr 2];"
puts $file "  constant DAY_HEX   : std_logic_vector(7 downto 0)  := X\"[lindex $datetime_arr 2]\";"
puts $file "  constant DATE_HEX  : std_logic_vector(31 downto 0) := YEAR_HEX & MONTH_HEX & DAY_HEX;"
puts $file "  -- Time information"
puts $file "  constant HOUR_INT   : integer                       := [lindex $datetime_arr 3];"
puts $file "  constant HOUR_HEX   : std_logic_vector(7 downto 0)  := X\"[lindex $datetime_arr 3]\";"
puts $file "  constant MINUTE_INT : integer                       := [lindex $datetime_arr 4];"
puts $file "  constant MINUTE_HEX : std_logic_vector(7 downto 0)  := X\"[lindex $datetime_arr 4]\";"
puts $file "  constant SECOND_INT : integer                       := [lindex $datetime_arr 5];"
puts $file "  constant SECOND_HEX : std_logic_vector(7 downto 0)  := X\"[lindex $datetime_arr 5]\";"
puts $file "  constant TIME_HEX   : std_logic_vector(31 downto 0) := X\"00\" & HOUR_HEX & MINUTE_HEX & SECOND_HEX;"
puts $file "  -- Miscellaneous information"
puts $file "  constant EPOCH_INT  : integer := [lindex $datetime_arr 6];  -- Seconds since 1970-01-01_00:00:00"
puts $file "end package;"
close $file
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity Datum2 is
  port(
    Day   : out std_logic_vector(4 downto 0);
    Month : out std_logic_vector(3 downto 0);
    Year  : out std_logic_vector(4 downto 0));
end Datum2;


library work;
use work.datetime;

architecture rtl of Datum2 is
begin
  Day   <= conv_std_logic_vector(datetime.day_int, 5);
  Month <= conv_std_logic_vector(datetime.month_int, 4);
  Year  <= conv_std_logic_vector(datetime.year_int mod 100, 5);
end architecture rtl;
# Make datetime.vhd package from shell script

# Current date, time, and seconds since epoch
# Array index           0  1  2  3  4  5  6
datetime_arr=($(date +"%Y %m %d %H %M %S %s"))

# Write VHDL package
filename="datetime.vhd"
echo "library ieee;" > $filename
echo "use ieee.std_logic_1164.all;" >> $filename
echo "" >> $filename
echo "package datetime is" >> $filename
echo "  -- Date information" >> $filename
echo "  constant YEAR_INT  : integer                       := ${datetime_arr[0]};" >> $filename
echo "  constant YEAR_HEX  : std_logic_vector(15 downto 0) := X\"${datetime_arr[0]}\";" >> $filename
echo "  constant MONTH_INT : integer                       := ${datetime_arr[1]};" >> $filename
echo "  constant MONTH_HEX : std_logic_vector(7 downto 0)  := X\"${datetime_arr[1]}\";" >> $filename
echo "  constant DAY_INT   : integer                       := ${datetime_arr[2]};" >> $filename
echo "  constant DAY_HEX   : std_logic_vector(7 downto 0)  := X\"${datetime_arr[2]}\";" >> $filename
echo "  constant DATE_HEX  : std_logic_vector(31 downto 0) := YEAR_HEX & MONTH_HEX & DAY_HEX;" >> $filename
echo "  -- Time information" >> $filename
echo "  constant HOUR_INT   : integer                       := ${datetime_arr[3]};" >> $filename
echo "  constant HOUR_HEX   : std_logic_vector(7 downto 0)  := X\"${datetime_arr[3]}\";" >> $filename
echo "  constant MINUTE_INT : integer                       := ${datetime_arr[4]};" >> $filename
echo "  constant MINUTE_HEX : std_logic_vector(7 downto 0)  := X\"${datetime_arr[4]}\";" >> $filename
echo "  constant SECOND_INT : integer                       := ${datetime_arr[5]};" >> $filename
echo "  constant SECOND_HEX : std_logic_vector(7 downto 0)  := X\"${datetime_arr[5]}\";" >> $filename
echo "  constant TIME_HEX   : std_logic_vector(31 downto 0) := X\"00\" & HOUR_HEX & MINUTE_HEX & SECOND_HEX;" >> $filename
echo "  -- Miscellaneous information" >> $filename
echo "  constant EPOCH_INT  : integer := ${datetime_arr[6]};  -- Seconds since 1970-01-01_00:00:00" >> $filename
echo "end package;" >> $filename
library ieee;
use ieee.std_logic_1164.all;
entity tb is
end entity;

library work;
use work.datetime;
architecture sim of tb is
  signal date_hex : std_logic_vector(31 downto 0);
  signal time_hex : std_logic_vector(31 downto 0);
begin
  date_hex <= datetime.DATE_HEX;
  time_hex <= datetime.TIME_HEX;
  process is begin wait; end process;
end architecture;
为了实现平台独立性,可以使用类似这样的Python 3.x脚本:

# Make datetime.vhd package from Python 3.x script

# Get date and time
import datetime
import time
now = datetime.datetime.now()
now_epoch_sec = int(time.time())

# Write VHDL package
file = open('datetime.vhd', 'wt')
file.write('library ieee;\n')
file.write('use ieee.std_logic_1164.all;\n')
file.write('\n')
file.write('package datetime is\n')
file.write('  -- Date information\n')
file.write('  constant YEAR_INT  : integer                       := {};\n'.format(now.strftime('%Y')))
file.write('  constant YEAR_HEX  : std_logic_vector(15 downto 0) := X\"{}\";\n'.format(now.strftime('%Y')))
file.write('  constant MONTH_INT : integer                       := {};\n'.format(now.strftime('%m')))
file.write('  constant MONTH_HEX : std_logic_vector(7 downto 0)  := X\"{}\";\n'.format(now.strftime('%m')))
file.write('  constant DAY_INT   : integer                       := {};\n'.format(now.strftime('%d')))
file.write('  constant DAY_HEX   : std_logic_vector(7 downto 0)  := X\"{}\";\n'.format(now.strftime('%d')))
file.write('  constant DATE_HEX  : std_logic_vector(31 downto 0) := YEAR_HEX & MONTH_HEX & DAY_HEX;\n')
file.write('  -- Time information\n')
file.write('  constant HOUR_INT   : integer                       := {};\n'.format(now.strftime('%H')))
file.write('  constant HOUR_HEX   : std_logic_vector(7 downto 0)  := X\"{}\";\n'.format(now.strftime('%H')))
file.write('  constant MINUTE_INT : integer                       := {};\n'.format(now.strftime('%M')))
file.write('  constant MINUTE_HEX : std_logic_vector(7 downto 0)  := X\"{}\";\n'.format(now.strftime('%M')))
file.write('  constant SECOND_INT : integer                       := {};\n'.format(now.strftime('%S')))
file.write('  constant SECOND_HEX : std_logic_vector(7 downto 0)  := X\"{}\";\n'.format(now.strftime('%S')))
file.write('  constant TIME_HEX   : std_logic_vector(31 downto 0) := X\"00\" & HOUR_HEX & MINUTE_HEX & SECOND_HEX;\n')
file.write('  -- Miscellaneous information\n')
file.write('  constant EPOCH_INT  : integer := {};  -- Seconds since 1970-01-01_00:00:00\n'.format(now_epoch_sec))
file.write('end package;\n')
file.close()
对于以32位寄存器值表示日期和时间,模块可以如下所示:

# Make datetime.vhd package from Tcl script

# Current date, time, and seconds since epoch
# Array index                                            0  1  2  3  4  5  6
set datetime_arr [clock format [clock seconds] -format {%Y %m %d %H %M %S %s}]

# Write VHDL package
set filename datetime.vhd
set file [open $filename w]
puts $file "library ieee;"
puts $file "use ieee.std_logic_1164.all;"
puts $file ""
puts $file "package datetime is"
puts $file "  -- Date information"
puts $file "  constant YEAR_INT  : integer                       := [lindex $datetime_arr 0];"
puts $file "  constant YEAR_HEX  : std_logic_vector(15 downto 0) := X\"[lindex $datetime_arr 0]\";"
puts $file "  constant MONTH_INT : integer                       := [lindex $datetime_arr 1];"
puts $file "  constant MONTH_HEX : std_logic_vector(7 downto 0)  := X\"[lindex $datetime_arr 1]\";"
puts $file "  constant DAY_INT   : integer                       := [lindex $datetime_arr 2];"
puts $file "  constant DAY_HEX   : std_logic_vector(7 downto 0)  := X\"[lindex $datetime_arr 2]\";"
puts $file "  constant DATE_HEX  : std_logic_vector(31 downto 0) := YEAR_HEX & MONTH_HEX & DAY_HEX;"
puts $file "  -- Time information"
puts $file "  constant HOUR_INT   : integer                       := [lindex $datetime_arr 3];"
puts $file "  constant HOUR_HEX   : std_logic_vector(7 downto 0)  := X\"[lindex $datetime_arr 3]\";"
puts $file "  constant MINUTE_INT : integer                       := [lindex $datetime_arr 4];"
puts $file "  constant MINUTE_HEX : std_logic_vector(7 downto 0)  := X\"[lindex $datetime_arr 4]\";"
puts $file "  constant SECOND_INT : integer                       := [lindex $datetime_arr 5];"
puts $file "  constant SECOND_HEX : std_logic_vector(7 downto 0)  := X\"[lindex $datetime_arr 5]\";"
puts $file "  constant TIME_HEX   : std_logic_vector(31 downto 0) := X\"00\" & HOUR_HEX & MINUTE_HEX & SECOND_HEX;"
puts $file "  -- Miscellaneous information"
puts $file "  constant EPOCH_INT  : integer := [lindex $datetime_arr 6];  -- Seconds since 1970-01-01_00:00:00"
puts $file "end package;"
close $file
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity Datum2 is
  port(
    Day   : out std_logic_vector(4 downto 0);
    Month : out std_logic_vector(3 downto 0);
    Year  : out std_logic_vector(4 downto 0));
end Datum2;


library work;
use work.datetime;

architecture rtl of Datum2 is
begin
  Day   <= conv_std_logic_vector(datetime.day_int, 5);
  Month <= conv_std_logic_vector(datetime.month_int, 4);
  Year  <= conv_std_logic_vector(datetime.year_int mod 100, 5);
end architecture rtl;
# Make datetime.vhd package from shell script

# Current date, time, and seconds since epoch
# Array index           0  1  2  3  4  5  6
datetime_arr=($(date +"%Y %m %d %H %M %S %s"))

# Write VHDL package
filename="datetime.vhd"
echo "library ieee;" > $filename
echo "use ieee.std_logic_1164.all;" >> $filename
echo "" >> $filename
echo "package datetime is" >> $filename
echo "  -- Date information" >> $filename
echo "  constant YEAR_INT  : integer                       := ${datetime_arr[0]};" >> $filename
echo "  constant YEAR_HEX  : std_logic_vector(15 downto 0) := X\"${datetime_arr[0]}\";" >> $filename
echo "  constant MONTH_INT : integer                       := ${datetime_arr[1]};" >> $filename
echo "  constant MONTH_HEX : std_logic_vector(7 downto 0)  := X\"${datetime_arr[1]}\";" >> $filename
echo "  constant DAY_INT   : integer                       := ${datetime_arr[2]};" >> $filename
echo "  constant DAY_HEX   : std_logic_vector(7 downto 0)  := X\"${datetime_arr[2]}\";" >> $filename
echo "  constant DATE_HEX  : std_logic_vector(31 downto 0) := YEAR_HEX & MONTH_HEX & DAY_HEX;" >> $filename
echo "  -- Time information" >> $filename
echo "  constant HOUR_INT   : integer                       := ${datetime_arr[3]};" >> $filename
echo "  constant HOUR_HEX   : std_logic_vector(7 downto 0)  := X\"${datetime_arr[3]}\";" >> $filename
echo "  constant MINUTE_INT : integer                       := ${datetime_arr[4]};" >> $filename
echo "  constant MINUTE_HEX : std_logic_vector(7 downto 0)  := X\"${datetime_arr[4]}\";" >> $filename
echo "  constant SECOND_INT : integer                       := ${datetime_arr[5]};" >> $filename
echo "  constant SECOND_HEX : std_logic_vector(7 downto 0)  := X\"${datetime_arr[5]}\";" >> $filename
echo "  constant TIME_HEX   : std_logic_vector(31 downto 0) := X\"00\" & HOUR_HEX & MINUTE_HEX & SECOND_HEX;" >> $filename
echo "  -- Miscellaneous information" >> $filename
echo "  constant EPOCH_INT  : integer := ${datetime_arr[6]};  -- Seconds since 1970-01-01_00:00:00" >> $filename
echo "end package;" >> $filename
library ieee;
use ieee.std_logic_1164.all;
entity tb is
end entity;

library work;
use work.datetime;
architecture sim of tb is
  signal date_hex : std_logic_vector(31 downto 0);
  signal time_hex : std_logic_vector(31 downto 0);
begin
  date_hex <= datetime.DATE_HEX;
  time_hex <= datetime.TIME_HEX;
  process is begin wait; end process;
end architecture;
通过将以下内容添加到qsf文件中,可以实现与Altera构建流程的集成:

set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:scripts/call_bash.tcl"

我使用一个64位的
std\u逻辑\u向量
常量

我有一个TCL脚本,它在合成之前运行,将当前时间编码成一个包中的常量,然后包含在FPGA中,以便以某种方式读取


我在模拟中使用的同一个包有一个非自动生成的版本-这不会改变,因此我不必不断更新测试。

您不需要每次更新时间戳时都写出完整的代码。在Quartus中,您可以在编译之前使用TCL设置顶级泛型:

将泛型传递给时间戳实体:

entity top is
generic (day, month, year : integer);
end entity top;

architecture struct of top is
begin
timestamp_inst : entity work.timestamp generic map(day, month, year);
end architecture struct;
然后使用预流脚本设置泛型:

set_parameter -name day $someday
set_parameter -name year $someyear
# etc

我已经成功地在时间戳、git修订版和构建ID中使用了这种方法。我发现将其转换为单词数组,然后作为ROM访问非常方便。请发挥您的想象力。

我做了类似的事情,并将subversion修订版和日期作为自动构建脚本的一部分放入版本注册中。有很多方法可以做到这一点,但通常可以归结为让一个非VHDL进程更新设计中使用的VHDL文件,其中包含您想要包含的特定元数据。缺少的是在特定工具环境中从标签(fpga altera和nios)自动化进程的方法。一个恰当的响应似乎需要有人使用该环境。还要注意,问题集中在三个位字段上:日标准逻辑向量(4到0)、月标准逻辑向量(3到0)和年标准逻辑向量(4到0)。另外,一些工具环境(请参阅)具有直接设置参数的功能。@David Koontz:Good point;我已经用Altera Quartus II的具体建议更新了答案,该建议集成到Quartus II流程中,用于自动运行。现在,这是彻底的、信息丰富的、特别有用的。据我所知,也可以从tcl脚本调用外部程序(如在bash或python脚本中)。@David Koontz:是的,但最好只将其保存在tcl域中,因为Quartus II可以独立地在平台(bash)和外部程序(python)上使用它。