Search code examples
vhdlxilinx-ise

Combining `others` expression with `signed` cast


Let var stand for a signed vector (library IEEE.NUMERIC_STD.ALL) of size m.

Let foo be another variable of type std_logic_vector(n-1 downto 0), where n is smaller than m.

I want to concatenate a '0' left of foo, then pad it with zeroes in its right until it size is m and then store the result in var.

I tried

rdsor <= signed('0' & divisor & others=>'0');

But Xilinx complains with the following message on synthesis:

Syntax error near "others".

How do I do what I want?


Solution

  • Assuming rdsor is equivalent to your theoretical var and divisor equivalent to foo you could use two assignments in a process statement:

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    
    entity jsevillamol is
    end entity;
    
    architecture fum of jsevillamol is
        constant M:     natural := 42;
        constant N:     natural := 23;
        signal rdsor:   signed (M - 1 downto 0);
        signal divisor: std_logic_vector (N - 1 downto 0);
    begin
        -- rdsor <= signed('0' & divisor & others=>'0');
        process (divisor)
        begin
            rdsor <= (others => '0');
            rdsor (rdsor'LEFT downto rdsor'LEFT - divisor'LENGTH) 
                <= signed('0' & divisor);
        end process;
    end architecture;
    

    This works because each element of rdsor is a separate signal and there is only one value for any particular time in a projected output waveform. By not providing an after time_expression in the waveform element of the second assignment the elements of rdsor slice will be assigned the second assignments expression values. (The elements of the first assignment are supplanted by the second). This method of overwriting the projected output waveform is commonly used in providing default values prior to incomplete condition coverage with if statements.

    This example analyzes, elaborates and simulates, while doing nothing interesting it demonstrates index ranges are constructed properly.

    Notice it avoids the issue of concatenation versus aggregation brought up by Matthew Taylor's answer.

    For a single signal assignment in a method not sensitive to tool VHDL revision:

    architecture fie of jsevillamol is
        constant M:     natural := 42;
        constant N:     natural := 23;
        signal rdsor:   signed (M - 1 downto 0);
        signal divisor: std_logic_vector (N - 1 downto 0);
        subtype other is signed (rdsor'LEFT - divisor'LENGTH - 1 downto 0);
    begin
        -- rdsor <= signed('0' & divisor & others=>'0');
        rdsor <= '0' & signed(divisor)  &  other'(others => '0');
    end architecture;
    

    This uses concatenation and subsumes the others into an aggregate. There's a subtype declaration for the trailing '0's portion to allow the aggregate expression to be the target of a qualified expression.

    This architecture also analyzes, elaborates and simulates proving index arithmetic is correct.