我正在为Salsa20流密码编写VHDL代码。它的主要功能是我成功编写的'quarterround'。我想在继续之前在Modelsim中测试它,但我遇到了困难。我知道我必须“刺激”观察输出的输入。我所做的所有尝试都导致输出z,没有给出任何值。 Quarterround的代码(最高级别):
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY quarter_round is
GENERIC(l:integer:=9);
PORT(y : in unsigned(127 downto 0);
z : out unsigned( 127 downto 0)
);
END quarter_round;
ARCHITECTURE quarter_round_arch of quarter_round is
COMPONENT left is
GENERIC(l:integer);
PORT( a: in unsigned( 31 downto 0);
b: out unsigned( 31 downto 0));
end COMPONENT;
signal i1,i2,i3,i4 :unsigned( 31 downto 0);
signal j1,j2,j3,j4 :unsigned( 31 downto 0);
signal z0,z1,z2,z3 :unsigned( 31 downto 0);
signal y0 : unsigned( 31 downto 0);
signal y1 : unsigned( 31 downto 0);
signal y2 : unsigned( 31 downto 0);
signal y3 : unsigned( 31 downto 0);
BEGIN
y0 <=y(127 downto 96);
y1 <=y(95 downto 64);
y2 <=y(63 downto 32);
y3 <=y(31 downto 0);
i1<=y0+y3;
a1:left generic map(7) port map(i1,j1);
z1<=j1 xor y1;
i2<=z1+y0;
a2:left generic map(9) port map(i2,j2);
z2<=j2 xor y2;
i3<=z2+z1;
a3:left generic map(13) port map(i3,j3);
z3<=j3 xor y3;
i4<=z3+z2;
a4:left generic map(18) port map(i4,j4);
z0<=j4 xor y0;
z<=z0&z1&z2&z3;
END quarter_round_arch;
COMPONENT离开:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY left is
GENERIC (l:integer:=7);
PORT( n: in unsigned( 31 downto 0);
m: out unsigned( 31 downto 0));
END left;
ARCHITECTURE dataflow of left is
begin
m<=n(31-l downto 0)& n(31 downto 31-l+1);
END dataflow;
我正在尝试编写的测试平台将被赋予y(128位)的值,处理该函数,z应该在Modelsim中输出正确的答案。我意识到这是一个基本的VHDL问题,但它让我疯了!
此代码失败了Modelsim:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY quarter_round_vhd_tst IS
END quarter_round_vhd_tst;
ARCHITECTURE test of quarter_round_vhd_tst IS
COMPONENT quarter_round
PORT (
y : IN STD_LOGIC_VECTOR(127 DOWNTO 0);
z : OUT STD_LOGIC_VECTOR(127 DOWNTO 0)
);
END COMPONENT;
SIGNAL clk : std_logic := '0';
SIGNAL reset : std_logic := '0';
SIGNAL y : STD_LOGIC_VECTOR(127 DOWNTO 0);
SIGNAL z : STD_LOGIC_VECTOR(127 DOWNTO 0);
BEGIN
DUT : quarter_round
PORT MAP (
y => y,
z => z
);
y <= x"201f1e1d1c1b1a191817161514131211";
PROCESS
BEGIN
clk <= '0' ;
wait for 10 ns;
z <= y ;
clk <= '1';
wait for 10 ns;
END PROCESS;
END test;
编辑:这是最新的尝试。代码正在编译,但Modelsim给出错误说类型不匹配..任何想法赞赏。 CT
答案 0 :(得分:0)
您一定忽略了与&#34; left.vhd&#34;相关的编译错误。信号&#34; a&#34;和&#34; b&#34;是未宣布的。
答案 1 :(得分:0)
david_koontz @ Macbook:ghdl -a quarter_round.vhdl
david_koontz @ Macbook:ghdl -e quarter_round_vhd_tst
quarter_round.vhdl:100:1:来自组件的信号接口“y”的类型 实体“quarter_round”中的“quarter_round”和端口“y”不是 兼容的关联quarter_round.vhdl:100:1:类型 信号接口“z”来自组件“quarter_round”和端口“z”来自 实体“quarter_round”与关联ghdl不兼容: 编译错误
因此,编辑后描述的问题会在详细说明中显示出来。请注意组件声明中的类型和实体quarter_round不匹配。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity quarter_round_vhd_tst is
end quarter_round_vhd_tst;
architecture test of quarter_round_vhd_tst is
component quarter_round
port (
y: in unsigned(127 downto 0);
z: out unsigned(127 downto 0)
);
end component;
signal clk : std_logic := '0';
signal reset : std_logic := '0';
signal y : unsigned(127 downto 0);
signal z : unsigned(127 downto 0);
begin
DUT: quarter_round
port map (
y => y,
z => z
);
CLOCK:
process
begin
wait for 10 ns;
clk <= not clk;
if Now > 30 ns then
wait;
end if;
end process;
STIMULUS:
process
begin
wait for 10 ns;
y <= x"201f1e1d1c1b1a191817161514131211";
wait for 10 ns;
-- z <= y ;
wait;
end process;
end test;
更改是针对时钟的单独进程,一旦您添加更多内容,您可能需要它。您最初尝试在测试平台中分配z,z是quarter_round的输出。
我将y任务移到了刺激过程中。如果重置被使用,你也可以把它放在那里。
使用不带参数的wait语句背后的想法是阻止进程无休止地重复。只要你分配信号,他们就会进入Time'HIGH。现在处理CLOCK的比较可以针对多个刺激或执行的时间长度而改变。同样地,如果(最终)模型中出现了表示模拟结束的信息,则可以引入用于停止在进程中分配的时钟的信号(例如STIMULUS)而不是Now来停止时钟。 / p>
分配y后,如果DUT不依赖于时钟(或复位),则会为z分配结果。 (这就是我在y任务之前加上延迟的原因,以证明这一点。)
我使用了quarter_round并离开了我昨天更正了,所以我有a和b而不是m和n。
结果看起来是对的吗?
一旦完成了某些事情,那么顺序(计时)的过程就应该开始取得良好的进展。
您可以在端口映射中使用四分之一轮的类型转换:
signal y : std_logic_vector(127 downto 0);
signal z : std_logic_vector(127 downto 0);
begin
DUT: quarter_round
port map (
y => unsigned(y),
std_logic_vector(z)=> z
);
但是组件声明仍然需要匹配quarter_round的实体声明。
如果您确定永远不需要在测试平台中配置quarter_round,则可以使用直接实体实例化,从而消除组件声明:
-- component quarter_round
-- port (
-- y: in unsigned(127 downto 0);
-- z: out unsigned(127 downto 0)
-- );
-- end component;
...
begin
DUT: -- quarter_round
entity work.quarter_round
port map (
y => unsigned(y),
std_logic_vector(z)=> z
);
拥有有效的组件声明或至少使用正式关联(而不是位置,以上显示正式)通常很有用。这样,有人在阅读代码时不必在查看其他地方时计算参数。
请注意,直接实例化的实体使用选定的名称指定,该名称指定了实体所在的库。