我在VHDL中完成一些简单的数学运算会遇到很多麻烦。我对这种语言很不好,所以如果我的语法很愚蠢或者其他什么,我有一个借口:P。我正在尝试实现一个非常简单的随机数生成器,它通过以下公式计算伪随机数:
seed =(seed * 1103515245)+ 12345
我是怎么做的:
信号在这里
signal seed: std_logic_vector(31 downto 0) := x"2B4C96B9";
signal multiply: std_logic_vector(31 downto 0) := x"41C64E6D";
signal add: std_logic_vector(31 downto 0) := x"00003039";
signal temp1: std_logic_vector(63 downto 0);
signal temp2: std_logic_vector(31 downto 0);
这里的计算(在状态机中的状态下完成)
temp2 <= seed;
temp1 <= std_logic_vector((unsigned(temp2)*unsigned(multiply)));
seed <= std_logic_vector(unsigned(temp1(31 downto 0)) + unsigned(add));
temp2总是最终未定义。此外,种子最终也未定义。我尝试了几种不同的方法,但所有这些都是错误的,主要是因为矢量大小和顺序或操作。根据我通过半广泛的谷歌搜索发现的内容,我觉得我现在正在做这件事,但我无法理解。
我现在能想到的最好的事情就是在状态机中以自己的状态执行计算的每一步。谁能看到我在这里做错了什么?
答案 0 :(得分:2)
VHDL与其他语言的不同之处在于<=
分配的信号在增量延迟之后才会生效,因此如果您这样做:
temp2 <= seed;
temp1 <= std_logic_vector((unsigned(temp2)*unsigned(multiply)));
seed <= std_logic_vector(unsigned(temp1(31 downto 0)) + unsigned(add));
然后temp2
实际上没有更新用于在用于分配temp1
的表达式中读取,直到delta延迟已经过去。
根据您的设计细节,您可以考虑将中间变量声明为变量:
variable temp1: std_logic_vector(63 downto 0);
variable temp2: std_logic_vector(31 downto 0);
然后分配如:
temp2 := seed;
temp1 := std_logic_vector((unsigned(temp2)*unsigned(multiply)));
seed <= std_logic_vector(unsigned(temp1(31 downto 0)) + unsigned(add));
在这种情况下,中间变量temp1
和temp2
将在分配后立即准备好读取结果,seed
将在delta延迟后具有值,假设在下一个周期之前,你不会进行下一次迭代。
如果声明常量,它将阐明代码中的意图,执行:
constant MULTIPLY : std_logic_vector(31 downto 0) := x"41C64E6D";
constant ADD : std_logic_vector(31 downto 0) := x"00003039";
对你的计算进行评论,然后VHDL设计会截断乘法的结果,从而做到:
seed =(seed * 1103515245)mod(2 ** 32)+ 12345