【发布时间】:2021-09-28 15:25:36
【问题描述】:
我在这上面花了太多时间,完全搞糊涂了。我有一个记录类型:
--t_dp_sosi record
TYPE t_fft_sosi_out IS RECORD -- Source Out or Sink In
sync : STD_LOGIC;
bsn : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); -- ctrl
re : STD_LOGIC_VECTOR(c_fft_out_dat_w-1 DOWNTO 0); -- data
im : STD_LOGIC_VECTOR(c_fft_out_dat_w-1 DOWNTO 0); -- data
valid : STD_LOGIC; -- ctrl
sop : STD_LOGIC; -- ctrl
eop : STD_LOGIC; -- ctrl
empty : STD_LOGIC_VECTOR(c_dp_stream_empty_w-1 DOWNTO 0); -- info at eop
channel : STD_LOGIC_VECTOR(c_dp_stream_channel_w-1 DOWNTO 0); -- info at sop
err : STD_LOGIC_VECTOR(c_dp_stream_error_w-1 DOWNTO 0); -- info at eop (name field 'err' to avoid the 'error' keyword)
END RECORD;
并将其设为数组类型:
TYPE t_fft_sosi_arr_out IS ARRAY (INTEGER RANGE <>) OF t_fft_sosi_out;
用于定义类型中字段范围的所有常量都在同一个文件中事先定义。这种类型作为接口在我的代码中随处使用,并且运行良好。
现在我有了这个功能:
FUNCTION func_dp_stream_arr_combine_data_info_ctrl(dp : t_fft_sosi_arr_out; info, ctrl : t_fft_sosi_out) RETURN t_fft_sosi_arr_out IS
VARIABLE v_dp : t_fft_sosi_arr_out(dp'RANGE) := dp; -- hold sosi data
BEGIN
FOR I IN dp'RANGE LOOP -- set sosi info
v_dp(I).bsn := info.bsn;
v_dp(I).channel := info.channel;
v_dp(I).empty := info.empty;
v_dp(I).err := info.err;
-- set sosi ctrl
v_dp(I).valid := ctrl.valid;
v_dp(I).sop := ctrl.sop;
v_dp(I).eop := ctrl.eop;
v_dp(I).sync := ctrl.sync;
END LOOP;
RETURN v_dp;
END func_dp_stream_arr_combine_data_info_ctrl;
这意味着获取记录数组并将每个记录的某些字段(减去 re 和 im 字段)更改为类似于提供的 ctrl 或 info 记录的字段.
在我的代码中的某个时刻,我使用了这样的函数:
nxt_src_out_arr <= func_dp_stream_arr_combine_data_info_ctrl(snk_in_arr, out_sosi, out_sosi);
它完全弄乱了我的 re 和 im 字段,请参见此处(抱歉有点模糊):
snk_in_arr 和 nxt_src_out_arr 都是 ```t_fft_sosi_arr_out(g_nof_streams-1 DOWNTO 0);`` 数组,其中 g_nof_streams 是定义的泛型。如果我不通过这样的功能:
nxt_src_out_arr <= snk_in_arr;
我在 Windows 10 上的 Vivado 2020.2 上运行它。 我发现 Vivado 2020.1(在 Mint 或 Windows 10 上)不会出现此问题。
提前致谢。
【问题讨论】:
-
使用 MCVE 会容易得多。但我倾向于添加(在函数的循环中)
ASSERT v_dp(i).re = dp(i).re REPORT "v_dp initialisation FAILED" severity FAILURE;,如果触发,请将 MCVE 发送给 Xilinx 以征求意见。解决方法:如果不起作用,则在循环体开始时将 dp(i) 复制到 v_dp(i) 中,而不是依赖于初始化。 -
Quartus 没有功能仿真器——它只有一个合成后仿真工具。您是否尝试过另一个模拟器 - 例如 GHDL?如果没有 MCVE,就很难看到发生了什么。 vivado是什么版本的?你用的是最新的 2021.1 吗?
-
What topics can I ask about here? "1.寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包含所需的行为,特定问题或错误以及在问题本身中重现它所需的最短代码。请参阅:How to create a Minimal, Reproducible Example。如果您的芯片能够像其他模拟器一样关注 Vivado 模拟器(版本?)。
-
抱歉,我意识到我应该提供一个 MCVE,我会尝试创建一个。我没有尝试过其他模拟器,因为我的设计包含 Vivado XPM 模块,我无法使用其他软件进行模拟。我正在使用 Vivado 2020.2。当我遵循@user_1818839 的建议并将断言语句放在函数循环中时,我确实遇到了失败......所以我现在尝试你的解决方法并组合一个 MCVE 来尝试重现问题。感谢您的宝贵时间。
-
此外,即使我在循环内部的顶部进行复制而不是初始化,断言仍然会触发:
v_dp(I).re := dp(I).re; v_dp(I).im := dp(I).im; ASSERT v_dp(i).re = dp(i).re REPORT "v_dp initialisation FAILED" severity FAILURE;
标签: function vhdl record vivado