I'm trying to pack simple code into a function. Here is the VHDL code:
process(CLK, RST)
variable newdata : std_logic_vector(7 downto 0) := (others => '0');
variable tempdata : std_logic_vector(7 downto 0) := (others => '0');
begin
if (RST = '1') then
tempdata := (others => '0');
newdata := (others => '0');
elsif rising_edge(CLK) then
tempdata := DIN;
newdata := newdata XOR tempdata;
end if;
DOUT <= newdata;
end process;
Everything works fine as i wanted to. But if a trying implement this code as a function it will fail
function f_MOD2ALG (foo : std_logic_vector)
return std_logic_vector;
...
function f_MOD2ALG (foo : std_logic_vector)
return std_logic_vector is
variable tempdata : std_logic_vector(foo'range);
variable newdata : std_logic_vector(foo'range);
begin
tempdata := foo;
newdata := newdata xor tempdata;
return newdata;
end function;
No errors, no warnings.
On the RTL model look's like he is nulle'd data input, but i dont understand why. Can someon explain to me why it's happen? And how to properly create a function that's implement my code? Thank's!
Here is the calling of the function:
...
signal temp : std_logic_vector(7 downto 0) := (others => '0');
begin
process(CLK, RST)
begin
if (RST = '1') then
temp <= (others => '0');
elsif rising_edge(CLK) then
temp <= f_MOD2ALG(DIN);
end if;
end process;
DOUT <= temp;
...
As already written in my comment, the issue with your code is that the variable newdata
inside your function will always be "UUUUUUUU"
because it never gets initialized and it does not preserve its value between two function calls. And XORing something with U will always give U.
If you initialize newdata
to all zeros, the output will corresond to the input because XORing foo
with 0
will give foo
.
I know Easics' CRC generator. In their function, they pass the previous CRC value as argument. You could do something similar:
function f_MOD2ALG (foo : std_logic_vector; last_bar: std_logic_vector)
return std_logic_vector is
variable new_bar : std_logic_vector(foo'range);
begin
new_bar := foo xor last_bar;
return new_bar;
end function;
And calling it somehow like that:
signal bar : std_logic_vector(31 downto 0) := (others=>'0');
...
process(clk)
begin
if rising_edge(clk) then
bar <= f_MOD2ALG(foo, bar);
end if;
end process;