05-10-2020 11:22 PM
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" ?
05-11-2020 12:00 AM
05-11-2020 12:14 AM
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;
09-05-2020 02:53 PM - edited 09-05-2020 02:54 PM
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.
09-05-2020 04:19 PM
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?
09-07-2020 09:57 PM
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.
09-08-2020 12:12 AM
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).