Caglayan Dokme
Caglayan Dokme

Reputation: 1158

VHDL Operands Have Different Lengths Error During Synthesis

I have a code piece that concatenates two variable length vectors and XORs the result with another fixed-length vector. The variable lengths of related vectors does not affect the total length of concatenation result. Here is the respected code

-- Find the number of bits to be skipped.
-- This is done for better optimization of hardware.
bits2MSB := 15 - findHighestIndex(m_xorResult);

-- If there are sufficient number of remaining bits in the extended data
-- Then we can continue the XOR operation
if(bits2MSB < remainingXorCount) then
    m_xorResult         <= (m_xorResult((15 - bits2MSB - 1) downto 0) & m_dataExtended(remainingXorCount downto (remainingXorCount - bits2MSB))) xor STD_LOGIC_VECTOR(to_unsigned(polynom, 16));
    remainingXorCount   := remainingXorCount - bits2MSB - 1; -- Decrease remainingXorCount

-- If the remaining bit count of the extended data is equal to the number of bits to be skipped until the first HIGH bit
-- Then the last XOR operation for given data can be made.
elsif(bits2MSB = remainingXorCount) then
    m_xorResult         <= (m_xorResult((14 - remainingXorCount) downto 0) & m_dataExtended(remainingXorCount downto 0)) xor STD_LOGIC_VECTOR(to_unsigned(polynom, 16));
    remainingXorCount   := remainingXorCount - bits2MSB;
    state               <= FINISH;

-- If the remaining bits are not sufficient for a new XOR operation 
-- Then the result is equal to the extended version of the last XOR result.
else
    m_xorResult         <= (m_xorResult((14 - remainingXorCount) downto 0) & m_dataExtended(remainingXorCount downto 0));
    remainingXorCount   := 0; -- Decrease remainingXorCount
    state               <= FINISH;
end if;

The error message points to the line below the if statement. It says that

[Synth 8-509] operands of logical operator '^' have different lengths (40 vs. 16)

The declaration of related vectors are as following

variable bits2MSB : integer range 0 to 8 := 0;
variable remainingXorCount : integer range 0 to 7 := 7;
signal m_xorResult : STD_LOGIC_VECTOR(15 downto 0);
signal m_dataExtended : STD_LOGIC_VECTOR(23 downto 0);
variable polynom : natural := 16#1021#;

In addition to these, the function findHighestIndex(...) can return an integer value in range 7 to 15.

The testbench for the given module works without any problem. I tested it for any given input to the module. Somehow, Vivado says that in some condition I can produce a length of 40 bits vector and try to XOR it with a length of 16 bit vector. What do you think the problem is?

Upvotes: 0

Views: 814

Answers (1)

user1818839
user1818839

Reputation:

Instead of concatenating variable width words to make a fixed width word, you can OR two fixed width words together, each with a variable number of bits masked out.

In outline, instead of

X"AAAA"(15 downto var) & X"5555"(var-1 downto 0) XOR X"1234";

compute

((X"AAAA" AND upper_mask(var)) OR (X"5555" AND not upper_mask(var))) XOR X"1234";

The masks can be generated by functions like this;

function upper_mask(var : natural) return std_logic_vector is
   mask : std_logic_vector(15 downto 0) := (others => '1');
begin
   mask(var - 1 downto 0) := (others => '0');
   return mask;
end;

If Vivado still can't synthesise upper_mask, a loop over all bits in upper_mask should work:

for i in mask'range loop
   if i < var then
      mask(i) := '0';
   end if;
end loop

Upvotes: 1

Related Questions