cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
bherren72
Visitor
Visitor
1,533 Views
Registered: ‎08-22-2019

VHDL: "others =>" fails with record with unconstrained vector that has been specialized

Hi !

So I have a type defined like this:

    type wb_master_out_t is record
        adr : std_ulogic_vector;
        dat : std_ulogic_vector;
        cyc : std_ulogic;
        stb : std_ulogic;
        sel : std_ulogic_vector;
        we  : std_ulogic;
    end record;

    constant wb_cpu_addr_bits : integer := 32;
    constant wb_cpu_data_bits : integer := 64;

    subtype wishbone_master_out is wb_master_out_t(adr(wb_cpu_addr_bits-1 downto 0),
                                            dat(wb_cpu_data_bits-1 downto 0),
                                            sel(wb_cpu_data_bits/8-1 downto 0));

 

In a different module, I try to use that wishbone_master_out subtype. It's part of a register:

    type reg_internal_t is record
        .../...
        wb               : wishbone_master_out;
        .../...
    end record;

 

Finally, when I assign to it, such statement triggers an error:

		r.wb.dat <= (others => '0');

 

It leads to the following error in synthesis:

ERROR: [Synth 8-211] could not evaluate expression: OTHERS in array aggregate without constraining context [/home/benh/hackplace/microwatt-fusesoc/build/microwatt_0/src/microwatt_0/icache.vhdl:458]

 

This happens with Vivado 2019.2, the file is compiled as VHDL-2008.

 

Any idea or workaround other than replacing "others" with something like x"0000000000000000" ?

 

0 Kudos
9 Replies
pulim
Xilinx Employee
Xilinx Employee
1,514 Views
Registered: ‎02-16-2014

Hi @bherren72 

This seems to be bug with vivado. I will report this bug.

How about using as below?

 

constant C: std_ulogic_vector(31 downto 0) := (others => '0');

r.ele1.dat <= C;

 

Thanks,

Manusha

bherren72
Visitor
Visitor
1,511 Views
Registered: ‎08-22-2019

Yes, that's a workaround I could use. Thanks for reporting !

0 Kudos
richardhead
Scholar
Scholar
1,503 Views
Registered: ‎08-01-2012

Also get the failure is 19.2 - the following is fine though:

architecture rtl of record_of_record is
  signal  reg     :  reg_internal_t;
begin

  reg.wb <= ( adr => (others => '0'),
              dat => (others => '0'),
              cyc => '0',
              stb => '0',
              sel => (others => '0'),
              we  => '0' );

end rtl;
pulim
Xilinx Employee
Xilinx Employee
1,499 Views
Registered: ‎02-16-2014

Hi @bherren72 

Filed CR to get this issue fixed

Thanks,

Manusha

Tags (1)
ddwashbu
Newbie
Newbie
1,241 Views
Registered: ‎08-27-2020

Does anyone know if this bug was fixed in 2020.1?

0 Kudos
bitjockey
Adventurer
Adventurer
1,143 Views
Registered: ‎03-21-2011

Using records as ports between modules has always been a bit finicky for years.  We just avoid it.

When you are in a "different module" is subtype wishbone_master_out still defined?  did you bring in the package in which it's defined?  Re define it exactly the same?  Including downto/to ranges?

You could try something like

 

r.wb.dat <= (wishbone_master_out.wb'RANGE => '0');
or
r.wb.dat(wishbone_master_out.wb'RANGE) <= (others => '0');

 

 if it is somehow thinking a range is non-static when in reality there is only one possible range.

Also an opinion on coding style: constants in ALL_UPPER read better.

0 Kudos
richardhead
Scholar
Scholar
1,133 Views
Registered: ‎08-01-2012

@bitjockey 

We run AXI4 (full and axi4l) and AXI streaming via records, in VHDL 2008 (ie. unconstrained). Its been working fine since Vivado got VHDL unconstrained records working (in 2017.4 or 2018.2)

We also run registers around in record types.

What "finicky" problems have you had?

0 Kudos
bitjockey
Adventurer
Adventurer
1,043 Views
Registered: ‎03-21-2011

When i say "finicky for years" I mean the old-timers back circa 2000s told us that older 1990s ASIC tools didn't like them.

So yeah, it may be a "width of a horse's ass" type rule that the tools have long since outgrown. 

There is something too that I don't think individual elements of a record can be in vs out? So you have to handle the RDY/ACK signals outside the record?  SV though has actual 'interface' types though.

0 Kudos
richardhead
Scholar
Scholar
1,031 Views
Registered: ‎08-01-2012

Some "old timers" have a coding style that they use with rules learned years ago using tools that were rather limited and usually are not interested in learning how the tools have changed. This will include things like 2 or 3 process state machines, insistance on std_logic_vectors on all ports on all modules, a love of std_logic_unisnged/arith and reluctance to use records. To compound this problem, most of the textbooks around are many years old and follow these stylings and are never updated.

You are correct, VHDL up to 2008 cannot have directions in a record. RDY/ACK (valid/ready in AXI) is carried as separate std_logic in my design. I have seen some where they put the valid in one record and ready in the other.

VHDL 2019 has interfaces in VHDL. But that is unlikely to see support in Vivado any time soon given the track record in supporting new VHDL features (its 2020, and VHDL 2008 has only recently seen a decent bump in support).

0 Kudos