Engine
Engine

Reputation: 5422

Using matrix in VHDL

I'm trying to use a matrix in VHDL here's what I've done so far:

type MAT is array ( 7 downto 0 ) of bit_vector( 9 downto 0);
signal MAT_WORD:MAT:= (others=>X"00");
signal BREAKCODe :NATURAL:=0;



for I in 9 downto 0 loop 
                        if(MAT_WORD(I) = x"88") then 
                            BREAKCODE <= I;
                        end if ;
                    end loop; 

............

I get an error that I get is that :

Implicit array operator "=" always returns FALSE (left length 10 is not equal to right length 8

any idea how can use the loop or the matrix as one with 8 columns and 10 rows ?

Upvotes: 1

Views: 7952

Answers (4)

user1155120
user1155120

Reputation:

The answers you've received so far provide bits and pieces, in part because your code is not a Minimal, Complete, and Verifiable example.

There are standard version issues with a comprehensive answer, otherwise Matthew Sainsbury's answer is spot on for -2008 compliant simulators and synthesis tools. In IEEE Std 1076-2008, 15.8 Bit string literals, an option length prefix of an integer value has been added, allowing in the case of base X for 0 filling the resulting bit string with a length longer than the value provided by the following bit string literal value.

In lieu of -2008 tools you can use concatenation (which is how the bit string literal is 'stretched' by length in -2008) or in a limited number of cases aggregation with an others choice (and none of those cases are present in the following example):

entity engine is
end entity;

architecture foo of engine is

    type MAT is array ( 9 downto 0 ) of bit_vector( 9 downto 0);
    signal MAT_WORD: MAT := (others =>  ( others => '0'));
    signal BREAKCODE: NATURAL := 0;

begin
    MAT_WORD(5) <= "00" & x"88";

SCAN:
    process(MAT_WORD)
    begin
        BREAKCODE <= 0;     -- when no "0010001000" occurs, clear BREAKCODE
        for I in  MAT_WORD'range loop 
            if MAT_WORD(I) = "00" & x"88"  then 
                BREAKCODE <= I;
            end if;
        end loop; 
    end process;
NARK:
    process (BREAKCODE)
    begin
        if BREAKCODE > 0 then
            report "MAT_WORD(" & integer'image(BREAKCODE) & 
                    ") = ""00"" & x""88""";
        end if;
    end process;
end architecture;

The above code analyzes, elaborates and runs:

ghdl -a engine.vhdl
ghdl -e engine
ghdl -r engine
engine.vhdl:27:13:@0ms:(report note): MAT_WORD(5) = "00" & x"88"

And you can see it reports the location the concurrent signal assignment writes.

Note there was one additional error in your code where you declare the range of I in the loop statement to have a range 9 downto 0 which is out of range for type MAT. That has been corrected here by using correcting the range of MAT. (The loop constant I has been modified to use the range of the declared object, allowing you to change the size of your matrix in exactly one place).

You could also use an incomplete type declaration:

type MAT is array (natural range <>)  of bit_vector (9 downto 0);

and specify the range in the object declaration:

signal MAT_WORD:  MAT (9 downto 0) := (others => (others => '0'));

Fixing the range in the type declaration seems more appropriate.

Upvotes: 2

Martin Zabel
Martin Zabel

Reputation: 3659

I think you mixed up the dimensions. You defined a matrix with 8 elements (7 downto 0) where each element stores a 10-bit vector (9 downto 0).

In your for-loop you can only iterate through the elements and check each element against a 10-bit vector. For example:

process(MAT_WORD)
begin
  BREAK_CODE <= 0; -- move initialization here or the following 
                   -- must be encapsulated into a clocked process

  for i in 7 downto 0 loop -- order may be important
    if MAT_WORD(i) = "0010001000" then -- x"88" with two '0' prepended
      BREAK_CODE <= i;
    end if;
  end loop;
end process;

Also in the initialization of MAT_WORD you must assign 10-bit vectors, e.g,

signal MAT_WORD:MAT:= (others=> "0000000000");

or more generic:

signal MAT_WORD:MAT:= (others=> (others => '0'));

Upvotes: 1

Matthew Sainsbury
Matthew Sainsbury

Reputation: 1488

Isn't this a data width issue? MAT_WORD(I) is 10 bits wide, right? and x"88" is a hex constant of 0x88 which is an eight-bit constant.

Try

if (MAT_WORD(I) = 10x"88")

I am not a VHDL user, sorry if this is totally wrong

Edit: Amended code to add the new 10x"88" syntax

Upvotes: 0

NIM
NIM

Reputation: 111

As Brian says you need to compare against a 10 bit value, as your matrix is composed of an array of 10 bit bit_vector.

The hexadecimal literal x"88" against which you are comparing is only 8 bits long, hence the error.

Try if(MAT_WORD(I) = "10001000") instead - "10001000" being the binary representation of x"88".

If you can use VHDL 2000, you have another option - use a sized literal, e.g. 10x"088".

In addition you are looping over 9 downto 0 when your MAT_WORD array is defined as 7 downto 0...

Upvotes: 0

Related Questions