I'm having a lot of trouble getting some simple math done in VHDL. I'm terrible at this language so if my syntax is stupid or something, I have an excuse :P. I'm trying to implement a very simple random number generator that calculates a pseudo-random number by this formula:
seed = (seed*1103515245) + 12345
How I'm trying to do it:
Signalss here
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);
Computation here (done in a state in a state machine)
temp2 <= seed;
temp1 <= std_logic_vector((unsigned(temp2)*unsigned(multiply)));
seed <= std_logic_vector(unsigned(temp1(31 downto 0)) + unsigned(add));
temp2 always ends up being undefined. Additionally, seed ends up being undefined as well. I've tried it several different ways but all of them were wrong mostly because of the vector sizes and order or operations. I feel like I'm doing it right at the moment based on what I've found through semi-extensive Googling but I just can't figure it out.
The best thing I can think of right now is to do each step of the calculation in its own state in a state machine. Can anyone see what I'm doing wrong here?
VHDL is different from other languages in that signal assign by
<=
does not take effect for read until after a delta delay, thus if you do:then the
temp2
not actually updated for read in the expression used to assigntemp1
until a delta delay has passed.Depending on the details about your design, you can consider declaring the intermediate variables as variables:
and then assign like:
In this case the intermediate variables
temp1
andtemp2
will have the result ready for read right after the assign, and theseed
will have the value after a delta delay, assuming that you will not do the next iteration until next cycle.It will clarify the intention in the code if constants are declared as such, doing:
A comment on you calculation, then the VHDL design truncates the result of the multiplication, thus doing: