Altera_Forum
Honored Contributor
13 years agostate machine not holding variable value outside state
I'm trying to build a RAM function that will write data to RAM then take the average of the array for N samples.
My current problem is that (in simulation) I cannot get variables to hold their value outside the states where their value is explicitly stated (i.e. sum := 0). This is causing an issue with the sum variable as I cannot calculate the sum of the array. I suspect that this issue is the result of the way I have my state machine setup. I'm also having issues with zero time oscillations when i use the statement sum := sum + ram_data. I can see how this would cause the osculations however i have seen this method used to increment a variable so I'm confused as to why it cannot be used to add something other than a constant to a variable. I apologize for portions of the code being awkward. I've been beating my head and trying different things for a while.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.Numeric_Std.all;
entity WriteAverage is
port(
Dready, Sclk, reset: in std_logic;
Data: in std_logic_vector (15 downto 0);
RDataIn: in std_logic_vector (15 downto 0);
Nsamples: in std_logic_vector (7 downto 0);
Raddr: out std_logic_vector (7 downto 0);
Rdata: out std_logic_vector (15 downto 0);
Average: out std_logic_vector (15 downto 0);
Rclk, We, AvgDone: out std_logic;
state: out std_logic_vector (3 downto 0);
test2, sum_temp_out:out std_logic_vector (15 downto 0);
test: out std_logic_vector (7 downto 0)
);
end;
architecture state of WriteAverage is
signal Next_state : integer range 0 to 15;
signal Current_state : integer range 0 to 15;
begin
state <= (std_logic_vector(to_unsigned(current_state, 4)));
PROCESS (Sclk, Next_state)
BEGIN
IF (reset = '0') THEN -- if we get a reset input from the blue push button, return to the idle state at any time
Current_state <= 0;
ELSIF (rising_edge (Sclk)) THEN
Current_state <= Next_state;
END IF;
END PROCESS;
PROCESS(Sclk, Dready, Data, NSamples, RDataIn)
variable Waddress :integer range 0 to 255; --write addr location
variable Waddress_temp :integer range 0 to 255;
variable Raddress :integer range 0 to 255; --read addr location
variable Raddress_temp :integer range 0 to 255;
variable Nsamples_int :integer range 0 to 255;
variable sum :integer range 0 to 16777215;
variable sum_temp1, sum_temp2 :integer range 0 to 16777215;
variable avg :integer range 0 to 16777215;
Begin
Next_state <= Current_state;
Nsamples_int := 2; --to_integer(unsigned(Nsamples));
test <= RDataIn (7 downto 0);
test2 <= (std_logic_vector(to_unsigned(sum, 16)));
sum_temp_out <= (std_logic_vector(to_unsigned(sum_temp1, 16)));
Rclk <= '0';
if (current_state = 0) then --reset state machine
waddress := 0; --reset write address
Next_state <= 1;
elsif (Current_state = 1)then --idle
We <= '1'; --enable RAM write
Raddress := 0; --set initial read addr = 0
Raddress_temp := 0;
avg := 0; --reset average
sum := 0; --reset sum of array
AvgDone <= '0';
if (Dready ='0') then --for testing, was 1
Next_state <= 2;
end if;
elsif (Current_state =2) then
Rdata <= Data; --ram data = data input
if (Waddress = Nsamples_int) then --if write addres = max address...
Waddress := 0; --loop to top of array
end if;
Raddr <= (std_logic_vector(to_unsigned(Waddress, 8))); --ram addr = write address
Next_state <= 3;
elsif (Current_state = 3) then
Rclk <= '1'; --clk ram
Waddress_temp := Waddress; --part 1 incrimenting write address, trying to prevent zero time oscilation
Next_state <= 4;
elsif (Current_state = 4) then
We <= '0'; --enable ram read
waddress := Waddress_temp + 1; --part 2 incriment write address
Next_state <= 5;
elsif (Current_state = 5) then --doing nothing ATM
Next_state <= 6;
elsif (Current_state = 6) then
--if (Raddress = Nsamples_int) then --comented out for testing
-- Next_state <= 10; --if read address = aray siize finish sum of array
--else
Next_state <= 7;
--end if;
elsif (Current_state = 7) then
Raddr <= (std_logic_vector(to_unsigned(Raddress, 8))); --ram addr = next array location to be read
Next_state <= 8;
elsif (Current_state = 8) then
Rclk <= '1'; --clk ram
Raddress_temp := raddress; --part 1 readd addr incriment, trying to prevent z-time osc
sum_temp2 := sum; --trying to add ram data to sum of array
sum_temp1 := to_integer(unsigned(RDataIn)); --trying to add ram data to sum
Next_state <= 9;
elsif (Current_state = 9) then
sum := sum_temp2 + sum_temp1; --trying to add ram data to sum
Raddress := Raddress_temp + 1; --go to next ram address
Next_state <= 6;
elsif (Current_state = 10) then
avg := sum / Nsamples_int; --average sum of array
Average <= std_logic_vector(to_unsigned(sum, 16)); --output avg
AvgDone <= '1';
Next_state <= 11;
elsif (Current_state = 11) then --wait for Dready = 0 before idle
if (Dready = '1') then --for testing, was 0
Next_state <= 1; --go to idle
end if;
end if;
END PROCESS;
END;