0
votes

I have a module with D_IN_VAL std_logic_vector(n-1 downto 0) input port, and internal signal CUR_MAX_S : std_logic_vector(n-1 downto 0). I wish to use only parts of D_IN_VAL data (e.g 4 bits out of 20 bit signal) so I figured I'll 'save' D_IN_VAL in CUR_MAX_S and then use parts of CUR_MAX_S. Ive assigned D_IN_VAL to CUR_MAX_S synchronously if RISING_EDGE(CLK) then and under certain conditions if D_SEND = '1' AND WHAT_STATE = 0 then.

But what happens when value of D_IN_VAL changes? Does the value of CUR_MAX_S change, too? Or does Quartus generate a latch, that remembers what Ive assigned to CUR_MAX_S? According to simulation, it 'remembers' the value, but Ive already learned not to trust simulation 100%. Its a signal and not variable, so I'm not sure.

EDIT: added example code, changed names of variables in question to match code

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;

entity MYMUX1 is
    generic (
    -- dlugosc rejestru jako potega 2-ki, nie mniej niz 3
    -- 2^2 = 4, 2^3 = 8, 2^4 = 16, 2^5 = 32, 2^6 = 64, 2^7 = 128, 2^8 = 256, 
        M : INTEGER := 4;
    -- szerokosc we/wy rejestru (w bitach)
        N : INTEGER := 5
    );
    port(
    -- wartosc maksimum
        D_IN_VAL    :   in STD_LOGIC_VECTOR(2*N+M-1 downto 0);
    -- pozycja maksimum
        D_IN_POS :  in STD_LOGIC_VECTOR(M+1 downto 0);
    -- wyslij nastepne dane
        D_SEND :        in STD_LOGIC;
    -- zegar, duh.
        CLK :       in STD_LOGIC;
    -- resET
        RST :           in STD_LOGIC;

    -- dane wyjsciowe, do UARTu
        D_OUT :     out STD_LOGIC_VECTOR(7 downto 0);
    -- dane gotowe
        D_RDY :         out STD_LOGIC;

    -- testowe
        test1 :     out STD_LOGIC_VECTOR(11 downto 0);
        test2 :     out STD_LOGIC_VECTOR(11 downto 0);
        test3 :     out STD_LOGIC_VECTOR(11 downto 0);
        test4 :     out STD_LOGIC_VECTOR(11 downto 0);
        test5 :     out STD_LOGIC_VECTOR(3 downto 0);
        test_state : out STD_LOGIC_VECTOR(3 downto 0);
        test_neg :  out STD_LOGIC_VECTOR(2*N+M-1 downto 0)
    );
end MYMUX1;

architecture AMYMUX1 of MYMUX1 is

    signal CUR_MAX_S : STD_LOGIC_VECTOR(2*N+M-1+4 downto 0);
    signal WHERE_MAX_S : STD_LOGIC_VECTOR(M+1+4 downto 0);

    begin

    process(CLK)
    -- ile bajtow na wartosc? maks 4mln, 2^32. na przyklad n=12 bajtow, 2^m, m=8, 256 razy
    variable COUNT1 :       INTEGER range 0 to 7; 
    -- ile bajtow na pozycje? maks 65k, 2^16
    variable COUNT2 :       INTEGER range 0 to 3;
    variable COUNT_MAIN :   INTEGER range 0 to 11;
    variable CUR_MAX :      INTEGER range -(2**(2*N+M)) to (2**(2*N+M)-1);
    variable WHERE_MAX :    INTEGER range 0 to (2*2**M-1);
    variable WHAT_STATE :   INTEGER range 0 to 6; -- albo 6



    begin
--  if(RISING_EDGE(CLK)) then
        if(((2*N+M) mod 4)>0) then
            COUNT1 := ((2*N+M)/4)+1;
        else
            COUNT1 := (2*N+M)/4;
        end if;

        if(((M+1+1) mod 4)>0) then
            COUNT2 := ((M+1+1)/4)+1;
        else
            COUNT2 := (M+1+1)/4;
        end if; 

    if(RISING_EDGE(CLK)) then
        if(RST = '1') then
            WHAT_STATE := 0;
            test_state <= STD_LOGIC_VECTOR(to_signed(0,4));
        else

        -- state 0 - jesli wartosc > od zera, zapisz, jesli mniejsza, odwroc i zapisz, wyslij ! jako znak poczatku paczki
            if(D_SEND = '1' AND WHAT_STATE = 0) then
                if(to_integer(signed(D_IN_VAL))>=0) then
                --  CUR_MAX := to_integer(signed(D_IN_VAL));
                    CUR_MAX_S <= "0000" & STD_LOGIC_VECTOR((signed(D_IN_VAL)));
                -- skocz od razu do wysylania danych
                    WHAT_STATE := 2;

                else
                --  CUR_MAX := -to_integer(signed(D_IN_VAL));
                    CUR_MAX_S <= "0000" & STD_LOGIC_VECTOR((-signed(D_IN_VAL)));
                -- wyslij znak a dopiero potem dane
                    WHAT_STATE := 1;

                end if;

                WHERE_MAX_S <= "0000" & D_IN_POS;

                test_neg <= STD_LOGIC_VECTOR(-signed(D_IN_VAL));
                WHERE_MAX := to_integer(signed(D_IN_POS));

                COUNT_MAIN := COUNT1;

                D_OUT <= STD_LOGIC_VECTOR(to_unsigned(33,8));

                test1 <= STD_LOGIC_VECTOR(to_signed(CUR_MAX,12));
                test2 <= STD_LOGIC_VECTOR(to_signed(WHERE_MAX,12));
                test3 <= STD_LOGIC_VECTOR(to_signed(COUNT_MAIN,12));
                test4 <= STD_LOGIC_VECTOR(to_signed(WHAT_STATE,12));
                test_state <= STD_LOGIC_VECTOR(to_signed(0,4));

            -- oba teoretycznie dzialaja, ale ktore jest poprawne...?
            --  CUR_MAX_S <= STD_LOGIC_VECTOR(to_unsigned(CUR_MAX,14));
            --  CUR_MAX_S <= D_IN_VAL;

        -- state 1 - wyslij minus, jesli liczba jest ujemna
            elsif(WHAT_STATE = 1) then
-- and so on, and so forth... the rest of the code goes here.
1
You need to add a properly formatted example of your actual code. - scary_jeff
Added part of the code that contains the part that's problematic for me - CUR_MAX_S <= "0000" & STD_LOGIC_VECTOR((signed(D_IN_VAL))); - will it latch and remain unchanged until I decide to override it? Or will it change, whenever D_IN_VAL changes? Also, any idea why those zeros ive concatenated display as XXXX in simulation instead of 0's? - Benji
*ZZZZ's, not XXXX's. Still, IDK why they dont just appear as 0000's - Benji

1 Answers

0
votes

First, please write a "minimal code example" to help people help you. Have a look at https://stackoverflow.com/help/mcve

Based on your description not your long code:

  • CUR_MAX_S will be synthesized as n bit register with CLK signal routed to the clock inputs and output of the combinational logic D_SEND = '1' AND WHAT_STATE = 0 routed to the enable inputs of each bit.
  • The outputs will change after the rising edge of the clock signal, if and only if the enable signal is high, not when the input value changes.

That is the whole idea of registers: to store data when you want to, not when the input changes.

I hope this helps...