当前日期和时间在 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
在 Altera Quartus II 中,可以使流程在综合之前运行该脚本,从而可以创建 datetime 包。这是在 .qsf 文件中使用以下行完成的,其中脚本名为“make_datetime.tcl”:
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:make_datetime.tcl"
可以在Quartus II Tcl 示例:自动脚本执行中找到有关该 Quartus II 特性的进一步描述。
然后 Datum2 模块可以像这样使用包:
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;
在 Quartus II 中综合后,RTL 查看器显示模块输出如下:
前面描述的替代解决方案是使用这样的 Bash 脚本创建 VHDL 包:
# 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
对于平台独立性,可以使用这样的 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 位寄存器值表示日期和时间,模块可以是这样的:
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;
波形如下图。
Bash 或 Python 脚本方法需要在构建流程中集成以自动生成包。
Damien 于 2016-08-08 编辑:来自 Altera Quartus 的非 Tcl 脚本调用的描述。
要集成 bash 脚本(在 Linux 下),请创建一个 Tcl 包装脚本,该脚本将 bash 脚本作为进程的一部分进行调用。在此示例中,有一个“scripts”目录,其中包含一个“call_bash.tcl”脚本和一个执行实际工作的“make_datetime.sh”:
# Useful if the script is in a subdirectory
proc getScriptDirectory {} {
set dispScriptFile [file normalize [info script]]
set scriptFolder [file dirname $dispScriptFile]
return $scriptFolder
}
set scriptDir [getScriptDirectory]
# Call the bash script which does the real work
exec $scriptDir/make_datetime_vhdl.sh
# Add a message the Altera workflow
post_message -type info "Created datetime.vhd"
然后可以通过将以下内容添加到 qsf 文件来实现集成到 Altera 的构建流程:
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:scripts/call_bash.tcl"