Search code examples
vhdl

Std logic vector in VHDL compare with zero and other vector


when S3 =>

    NS<=S5;
    Rd_ack<='0';
    if (u=0) then
        send:=u;
        NS<=S4;
    end if;

    if (v=0) then
        send:=u;
        NS<=S4;
    end if;

when S4 =>

How can I compare u and v with 0 and u with v ? I want following statements

if( v= u) then. ....
if( u= 0) then
u and v are signa

signal u, v: std_logic_vector(0 to 31);

In VHDL can i use send to store the value? send is a variable. If when we go to state s4 we want to take data in send and assign it to a signal.


Solution

  • You've handicapped someone answering without providing type information for the numerical literal.

    If you're serious about testing a std_logic_vector against an integer type you can write an equality operator ("=") function that performs the comparison:

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    
    entity fum is
    end entity;
    
    architecture foo of fum is
        signal u,v:     std_logic_vector (31 downto 0);
        signal NS,S4:   std_logic;
        function "=" (a:std_logic_vector; b: natural) return BOOLEAN is
            variable as_slv:    std_logic_vector(a'range);
        begin
            as_slv := std_logic_vector(to_unsigned(b,as_slv'length));
            for i in a'range loop
                if a(i) /= as_slv(i) then
                    return FALSE;
                end if;
            end loop;
            
            return TRUE;
        end function;
    begin
    SOME_PROCESS:
        process(u,v,S4)
        variable send:  std_logic_vector (u'range);
        begin
            if u = 0  then
                send := u;
                NS <= S4;
            end if;
    
            if v = 0 then
                send := u;
                NS <= S4;
            end if;
        end process;
    end architecture;
    

    This example code analyzes, elaborates and simulates (despite doing nothing interesting).

    Notice this one uses natural as the type, std_logic_vector is inherently unsigned, it's a 'bag of bits'.

    If you're instead interested in only testing for all '0' values:

    architecture fee of fum is
        signal u,v:     std_logic_vector (31 downto 0);
        signal NS,S4:   std_logic;
        constant ZERO:  std_logic_vector (u'range) := (others => '0');
    begin
    SOME_PROCESS:
        process(u,v,S4)
        variable send:  std_logic_vector (u'range);
        begin
            if u = ZERO  then
                send := u;
                NS <= S4;
            end if;
    
            if v = ZERO then
                send := u;
                NS <= S4;
            end if;
        end process;
    end architecture;
    

    fum with architecture fee also analyzes, elaborates and simulates while doing nothing interesting.

    The constant ZERO instead of the equivalent X"00000000", (others => '0') not allowed in the expression.

    The scope of the variable send in this example code is limited to the declarative region, in this case to the process statement SOME_PROCESS. Assuming one were to flesh out the process with a case statement operating off a state value, send could be used to assign a signal in that process.

    And instead of writing a new operator "=" function when comparing a numerical literal you could use type conversion:

    architecture fie of fum is
        signal u,v:     std_logic_vector (31 downto 0);
        signal NS,S4:   std_logic;
    begin
    SOME_PROCESS:
        process(u,v,S4)
        variable send:  std_logic_vector (u'range);
        begin
            if unsigned (u) = 0  then
                send := u;
                NS <= S4;
            end if;
    
            if unsigned(v) = 0 then
                send := u;
                NS <= S4;
            end if;
            v <= send;
        end process;
    end architecture;
    

    This has a drawback when simulating:

    #> ghdl -r fum
    ../../../src/ieee/numeric_std-body.v93:1710:7:@0ms:(assertion
    warning): NUMERIC_STD."=": metavalue detected, returning FALSE
    ../../../src/ieee/numeric_std-body.v93:1710:7:@0ms:(assertion
    warning): NUMERIC_STD."=": metavalue detected, returning FALSE
    #>

    comparison in the numerical domain (using package numeric_std's "=") is sensitive to metavalues.