diff options
author | Tristan Gingold <tgingold@free.fr> | 2017-11-27 21:10:49 +0100 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2017-11-27 21:10:49 +0100 |
commit | 9e4ec135ab7bfec367acbfd6e7c742b7f1d9b1ea (patch) | |
tree | 9d171046f7c457e949b9e082af9bbbf94925b11a | |
parent | 93e1e6fa9bd08d36307bd4767e94203ca123fbd5 (diff) | |
download | ghdl-9e4ec135ab7bfec367acbfd6e7c742b7f1d9b1ea.tar.gz ghdl-9e4ec135ab7bfec367acbfd6e7c742b7f1d9b1ea.tar.bz2 ghdl-9e4ec135ab7bfec367acbfd6e7c742b7f1d9b1ea.zip |
Add reproducer for #467
-rw-r--r-- | testsuite/gna/issue467/AbstractMmPkg.vhd | 651 | ||||
-rw-r--r-- | testsuite/gna/issue467/axi_master.vhd | 170 | ||||
-rw-r--r-- | testsuite/gna/issue467/eu_tb.vhdl | 30 | ||||
-rw-r--r-- | testsuite/gna/issue467/testbench.vhdl | 21 | ||||
-rw-r--r-- | testsuite/gna/issue467/testbench2.vhdl | 78 | ||||
-rwxr-xr-x | testsuite/gna/issue467/testsuite.sh | 11 |
6 files changed, 961 insertions, 0 deletions
diff --git a/testsuite/gna/issue467/AbstractMmPkg.vhd b/testsuite/gna/issue467/AbstractMmPkg.vhd new file mode 100644 index 000000000..2752a07c2 --- /dev/null +++ b/testsuite/gna/issue467/AbstractMmPkg.vhd @@ -0,0 +1,651 @@ +------------------------------------------------------------------------------- +-- Title : Abstract Memory-Mapped Interface +-- Project : +------------------------------------------------------------------------------- +-- File : AbstractMmPkg.vhd +-- Author : Rob Gaddi <rgaddi@highlandtechnology.com> +-- Company : Highland Technology, Inc. +-- Created : 20-Nov-2017 +-- Last update: 2017-11-25 +-- Platform : Simulation +-- Standard : VHDL-2008 +------------------------------------------------------------------------------- +-- Description: Support package for abstract memory-mapped interface BFMs. +------------------------------------------------------------------------------- +-- Revision History: +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library osvvm; +use osvvm.AlertLogPkg.all; +use osvvm.TbUtilPkg.all; +use osvvm.ResolutionPkg.all; + +package AbstractMmPkg is + + ----------------------------------------------------------------------- + -- Constants and Types + ----------------------------------------------------------------------- + + type AlertLogIDArrayType is array(integer range <>) of AlertLogIDType; + function alert_resolver(ta: AlertLogIDArrayType) return AlertLogIDType; + subtype ResolvedAlert is alert_resolver AlertLogIDType; + + -- Transaction types + type TransactionType_unresolved is ( + NONE, + SINGLE, + + LINEAR_BURST, + CONSTANT_BURST, + CYCLE_BURST, + + BURST_DATA, + + PARAM + ); + type TransactionArrayType is array(integer range <>) of TransactionType_unresolved; + function resolved(ta: TransactionArrayType) return TransactionType_unresolved; + subtype TransactionType is resolved TransactionType_unresolved; + + type AbstractMmRecType is record + writedata : std_logic_vector; + readdata : std_logic_vector; + address : unsigned; + byteen : std_logic_vector; + write : std_logic; + burstlen : integer_max; + trans : TransactionType; + + addressiswords : std_logic; + alert : ResolvedAlert; + + rdy : std_logic; + ack : std_logic; + end record AbstractMmRecType; + + constant AMR_READ: std_logic := '0'; + constant AMR_WRITE: std_logic := '1'; + + constant AMR_ADDRESS_BYTES : std_logic := '0'; + constant AMR_ADDRESS_WORDS : std_logic := '1'; + + constant ALRT : AlertLogIDType := GetAlertLogID("AbstractMmPkg"); + + ----------------------------------------------------------------------- + -- Driver Functions + ----------------------------------------------------------------------- + + -- AmrRead (single read) + procedure AmrRead( + data: out std_logic_vector; + addr: in unsigned; + byteen: in std_logic_vector; + signal rec: inout AbstractMmRecType + ); + procedure AmrRead( + data: out std_logic_vector; + addr: in std_logic_vector; + byteen: in std_logic_vector; + signal rec: inout AbstractMmRecType + ); + procedure AmrRead( + data: out std_logic_vector; + addr: in natural; + byteen: in std_logic_vector; + signal rec: inout AbstractMmRecType + ); + procedure AmrRead( + data: out std_logic_vector; + addr: in unsigned; + signal rec: inout AbstractMmRecType + ); + procedure AmrRead( + data: out std_logic_vector; + addr: in std_logic_vector; + signal rec: inout AbstractMmRecType + ); + procedure AmrRead( + data: out std_logic_vector; + addr: in natural; + signal rec: inout AbstractMmRecType + ); + + -- AmrWrite (single write) + procedure AmrWrite( + data: in std_logic_vector; + addr: in unsigned; + byteen: in std_logic_vector; + signal rec: inout AbstractMmRecType + ); + procedure AmrWrite( + data: in std_logic_vector; + addr: in std_logic_vector; + byteen: in std_logic_vector; + signal rec: inout AbstractMmRecType + ); + procedure AmrWrite( + data: in std_logic_vector; + addr: in natural; + byteen: in std_logic_vector; + signal rec: inout AbstractMmRecType + ); + procedure AmrWrite( + data: in std_logic_vector; + addr: in unsigned; + signal rec: inout AbstractMmRecType + ); + procedure AmrWrite( + data: in std_logic_vector; + addr: in std_logic_vector; + signal rec: inout AbstractMmRecType + ); + procedure AmrWrite( + data: in std_logic_vector; + addr: in natural; + signal rec: inout AbstractMmRecType + ); + + -- AmrAssert (single assert) + procedure AmrAssert( + data: in std_logic_vector; + addr: in unsigned; + byteen: in std_logic_vector; + signal rec: inout AbstractMmRecType + ); + procedure AmrAssert( + data: in std_logic_vector; + addr: in std_logic_vector; + byteen: in std_logic_vector; + signal rec: inout AbstractMmRecType + ); + procedure AmrAssert( + data: in std_logic_vector; + addr: in natural; + byteen: in std_logic_vector; + signal rec: inout AbstractMmRecType + ); + procedure AmrAssert( + data: in std_logic_vector; + addr: in unsigned; + signal rec: inout AbstractMmRecType + ); + procedure AmrAssert( + data: in std_logic_vector; + addr: in std_logic_vector; + signal rec: inout AbstractMmRecType + ); + procedure AmrAssert( + data: in std_logic_vector; + addr: in natural; + signal rec: inout AbstractMmRecType + ); + + ----------------------------------------------------------------------- + -- Model Support Functions + ----------------------------------------------------------------------- + + procedure InterpretByteEnable( + rec : in AbstractMmRecType; + width : out natural; + align : out natural + ); + + function GetByteAddress(rec: in AbstractMmRecType; unalign: boolean := false) return unsigned; + function GetWordAddress(rec: in AbstractMmRecType) return unsigned; + + ----------------------------------------------------------------------- + -- Utility Functions + ----------------------------------------------------------------------- + + -- Initialization + procedure InitializeAmr(signal rec: out AbstractMmRecType); +-- function INIT_AMR(datalen, addrlen : positive) return AbstractMmRecType; +-- function INIT_AMR(datalen, addrlen, belen : positive) return AbstractMmRecType; + + -- Selecting word/byte addressing + procedure SetAddressWords(signal rec: inout AbstractMmRecType); + procedure SetAddressBytes(signal rec: inout AbstractMmRecType); + + -- Overriding the default alert + procedure OverrideAlert(signal rec: inout AbstractMmRecType; alert: AlertLogIDType); + +end package AbstractMmPkg; + +package body AbstractMmPkg is + + procedure InitializeAmr(signal rec: out AbstractMmRecType) is + variable local : AbstractMmRecType( + writedata(rec.writedata'range), + readdata(rec.readdata'range), + address(rec.address'range), + byteen(rec.byteen'range) + ); + constant WD : std_logic_vector(rec.writedata'range) := (others => 'Z'); + constant RD : std_logic_vector(rec.readdata'range) := (others => 'Z'); + constant AD : unsigned(rec.address'range) := (others => 'Z'); + constant BE : std_logic_vector(rec.byteen'range) := (others => 'Z'); + begin + local := ( + writedata => WD, + readdata => RD, + address => AD, + byteen => BE, + write => 'Z', + burstlen => integer'left, + trans => NONE, + addressiswords => 'Z', + alert => ALRT, + rdy => 'Z', + ack => 'Z' + ); + rec <= local; + end procedure InitializeAmr; + + --function INIT_AMR( + -- datalen, addrlen : positive + --) return AbstractMmRecType is + -- constant belen : positive := datalen / 8; + --begin + -- return INIT_AMR(datalen, addrlen, belen); + --end function INIT_AMR; + + --function INIT_AMR( + -- datalen, addrlen, belen: positive + --) return AbstractMmRecType is + --begin + -- return ( + -- writedata => (datalen downto 1 => 'Z'), + -- readdata => (datalen downto 1 => 'Z'), + -- address => (addrlen downto 1 => 'Z'), + -- byteen => (belen downto 1 => 'Z'), + -- write => 'Z', + -- burstlen => integer'left, + -- trans => NONE, + + -- addressiswords => 'Z', + -- alert => ALRT, + + -- rdy => 'Z', + -- ack => 'Z' + -- ); + --end function INIT_AMR; + + procedure SetAddressWords(signal rec: inout AbstractMmRecType) is + begin + rec.addressiswords <= AMR_ADDRESS_WORDS; + end procedure SetAddressWords; + + procedure SetAddressBytes(signal rec: inout AbstractMmRecType) is + begin + rec.addressiswords <= AMR_ADDRESS_BYTES; + end procedure SetAddressBytes; + + ----------------------------------------------------------------------- + -- AmrRead + ----------------------------------------------------------------------- + + procedure AmrRead( + data: out std_logic_vector; + addr: in unsigned; + byteen: in std_logic_vector; + signal rec: inout AbstractMmRecType + ) is + constant WD : std_logic_vector(rec.writedata'range) := (others => 'X'); + begin + rec.writedata <= WD; + rec.address <= RESIZE(addr, rec.address'length); + rec.byteen <= byteen; + rec.write <= AMR_READ; + rec.burstlen <= 1; + rec.trans <= SINGLE; + RequestTransaction(rec.rdy, rec.ack); + data := rec.readdata; + end procedure AmrRead; + + procedure AmrRead( + data: out std_logic_vector; + addr: in std_logic_vector; + byteen: in std_logic_vector; + signal rec: inout AbstractMmRecType + ) is + begin + AmrRead(data, UNSIGNED(addr), byteen, rec); + end procedure AmrRead; + + procedure AmrRead( + data: out std_logic_vector; + addr: in natural; + byteen: in std_logic_vector; + signal rec: inout AbstractMmRecType + ) is + begin + AmrRead(data, TO_UNSIGNED(addr, rec.address'length), byteen, rec); + end procedure AmrRead; + + procedure AmrRead( + data: out std_logic_vector; + addr: in unsigned; + signal rec: inout AbstractMmRecType + ) is + variable byteen : std_logic_vector(rec.byteen'range) := (others => '1'); + begin + AmrRead(data, addr, byteen, rec); + end procedure AmrRead; + + procedure AmrRead( + data: out std_logic_vector; + addr: in std_logic_vector; + signal rec: inout AbstractMmRecType + ) is + variable byteen : std_logic_vector(rec.byteen'range) := (others => '1'); + begin + AmrRead(data, UNSIGNED(addr), byteen, rec); + end procedure AmrRead; + + procedure AmrRead( + data: out std_logic_vector; + addr: in natural; + signal rec: inout AbstractMmRecType + ) is + variable byteen : std_logic_vector(rec.byteen'range) := (others => '1'); + begin + AmrRead(data, TO_UNSIGNED(addr, rec.address'length), byteen, rec); + end procedure AmrRead; + + ----------------------------------------------------------------------- + -- AmrWrite (single write) + ----------------------------------------------------------------------- + + procedure AmrWrite( + data: in std_logic_vector; + addr: in unsigned; + byteen: in std_logic_vector; + signal rec: inout AbstractMmRecType + ) is + begin + rec.writedata <= data; + rec.address <= RESIZE(addr, rec.address'length); + rec.byteen <= byteen; + rec.write <= AMR_WRITE; + rec.burstlen <= 1; + rec.trans <= SINGLE; + RequestTransaction(rec.rdy, rec.ack); + end procedure AmrWrite; + + procedure AmrWrite( + data: in std_logic_vector; + addr: in std_logic_vector; + byteen: in std_logic_vector; + signal rec: inout AbstractMmRecType + ) is begin + AmrWrite(data, UNSIGNED(addr), byteen, rec); + end procedure AmrWrite; + + procedure AmrWrite( + data: in std_logic_vector; + addr: in natural; + byteen: in std_logic_vector; + signal rec: inout AbstractMmRecType + ) is begin + AmrWrite(data, TO_UNSIGNED(addr, rec.address'length), byteen, rec); + end procedure AmrWrite; + + procedure AmrWrite( + data: in std_logic_vector; + addr: in unsigned; + signal rec: inout AbstractMmRecType + ) is + constant byteen : std_logic_vector(rec.byteen'range) := (others => '1'); + begin + AmrWrite(data, addr, byteen, rec); + end procedure AmrWrite; + + procedure AmrWrite( + data: in std_logic_vector; + addr: in std_logic_vector; + signal rec: inout AbstractMmRecType + ) is + constant byteen : std_logic_vector(rec.byteen'range) := (others => '1'); + begin + AmrWrite(data, UNSIGNED(addr), byteen, rec); + end procedure AmrWrite; + + procedure AmrWrite( + data: in std_logic_vector; + addr: in natural; + signal rec: inout AbstractMmRecType + ) is + constant byteen : std_logic_vector(rec.byteen'range) := (others => '1'); + begin + AmrWrite(data, TO_UNSIGNED(addr, rec.address'length), byteen, rec); + end procedure AmrWrite; + + ----------------------------------------------------------------------- + -- AmrAssert (single assert) + ----------------------------------------------------------------------- + + procedure AmrAssert( + data: in std_logic_vector; + addr: in unsigned; + byteen: in std_logic_vector; + signal rec: inout AbstractMmRecType + ) is + variable readdata : std_logic_vector(data'range); + begin + AmrRead(readdata, addr, byteen, rec); + --AffirmIfEqual(rec.alert, readdata, data, "Assert @ 0x" & TO_HSTRING(addr)); + end procedure AmrAssert; + + procedure AmrAssert( + data: in std_logic_vector; + addr: in std_logic_vector; + byteen: in std_logic_vector; + signal rec: inout AbstractMmRecType + ) is begin + AmrAssert(data, UNSIGNED(addr), byteen, rec); + end procedure AmrAssert; + + procedure AmrAssert( + data: in std_logic_vector; + addr: in natural; + byteen: in std_logic_vector; + signal rec: inout AbstractMmRecType + ) is begin + AmrAssert(data, TO_UNSIGNED(addr, rec.address'length), byteen, rec); + end procedure AmrAssert; + + procedure AmrAssert( + data: in std_logic_vector; + addr: in unsigned; + signal rec: inout AbstractMmRecType + ) is + constant byteen : std_logic_vector(rec.byteen'range) := (others => '1'); + begin + AmrAssert(data, addr, byteen, rec); + end procedure AmrAssert; + + procedure AmrAssert( + data: in std_logic_vector; + addr: in std_logic_vector; + signal rec: inout AbstractMmRecType + ) is + constant byteen : std_logic_vector(rec.byteen'range) := (others => '1'); + begin + AmrAssert(data, UNSIGNED(addr), byteen, rec); + end procedure AmrAssert; + + procedure AmrAssert( + data: in std_logic_vector; + addr: in natural; + signal rec: inout AbstractMmRecType + ) is + constant byteen : std_logic_vector(rec.byteen'range) := (others => '1'); + begin + AmrAssert(data, TO_UNSIGNED(addr, rec.address'length), byteen, rec); + end procedure AmrAssert; + + ----------------------------------------------------------------------- + -- Utility Functions + ----------------------------------------------------------------------- + + -- Turn a number into the number of bits needed to represent it. + function clog2(x : positive) return natural is + variable y : natural := 1; + begin + for log in 0 to 255 loop + if y >= x then + return log; + end if; + y := y * 2; + end loop; + return natural'right; + end function clog2; + + -- Allow only 1 entry to be other than NONE. + function resolved(ta: TransactionArrayType) return TransactionType_unresolved is + variable r : TransactionType_unresolved := NONE; + variable t : TransactionType_unresolved; + begin + for idx in ta'range loop + t := ta(idx); + if t /= NONE then + assert r = NONE + report "Multiple non-NONE transaction types." + severity failure; + r := t; + end if; + end loop; + return r; + end function resolved; + + -- Allow up to 1 entry to be other than our local ALRT, in which + -- case it wins. + function alert_resolver(ta: AlertLogIDArrayType) return AlertLogIDType is + variable r : AlertLogIDType := ALRT; + variable t : AlertLogIDType; + begin + for idx in ta'range loop + t := ta(idx); + if (t /= ALRT) and (t >= ALERTLOG_BASE_ID) then + assert r = ALRT + report "Multiple alerts provided." + severity failure; + r := t; + end if; + end loop; + return r; + end function alert_resolver; + + procedure InterpretByteEnable( + rec : in AbstractMmRecType; + width : out natural; + align : out natural + ) is + alias byteen : std_logic_vector(rec.byteen'range) is rec.byteen; + alias LA : AlertLogIDType is rec.alert; + variable first, last: integer; + variable found : boolean := false; + begin + if (and byteen) = '1' then + -- Try to provide fast resolution for the most common case. + width := byteen'length; + align := 0; + else + -- Alright, do it the hard way. Scan for contiguous enables. + for i in byteen'low to byteen'high loop + if byteen(i) = '1' then + found := true; + first := i; + exit; + end if; + end loop; + + if not found then + -- No byte enables are set + Alert(LA, "No byte enables set.", WARNING); + width := 0; + align := 0; + else + last := first; + for i in first+1 to byteen'high loop + if byteen(i) = '1' then + last := i; + else + exit; + end if; + end loop; + + if last /= byteen'high then + for i in last+1 to byteen'high loop + if byteen(i) = '1' then + Alert(LA, "Non-contiguous byte enables " & TO_STRING(byteen), WARNING); + exit; + end if; + end loop; + end if; + + width := last-first+1; + align := first; + end if; + end if; + end procedure InterpretByteEnable; + + function GetByteAddress(rec: in AbstractMmRecType; unalign: boolean := false) return unsigned is + variable padding : unsigned(clog2(rec.byteen'length)-1 downto 0); + variable alignment : integer := integer'left; + begin + case rec.addressiswords is + when AMR_ADDRESS_BYTES => + return rec.address; + + when AMR_ADDRESS_WORDS => + if unalign then + for i in rec.byteen'low to rec.byteen'high loop + if rec.byteen(i) = '1' then + alignment := i; + exit; + end if; + end loop; + if alignment /= integer'left then + report "All bytes disabled." severity warning; + alignment := 0; + end if; + padding := TO_UNSIGNED(alignment, padding'length); + else + padding := (others => '0'); + end if; + return rec.address & PADDING; + + when others => + report "Byte/word addressing not defined." severity failure; + return (rec.address'range => 'X'); + end case; + end function GetByteAddress; + + function GetWordAddress(rec: in AbstractMmRecType) return unsigned is + variable padding : unsigned(clog2(rec.byteen'length)-1 downto 0); + variable alignment, width : integer; + begin + case rec.addressiswords is + when AMR_ADDRESS_BYTES => + return rec.address(rec.address'high downto padding'length); + + when AMR_ADDRESS_WORDS => + return rec.address; + + when others => + report "Byte/word addressing not defined." severity failure; + return (rec.address'range => 'X'); + end case; + end function GetWordAddress; + + procedure OverrideAlert(signal rec: inout AbstractMmRecType; alert: AlertLogIDType) is + begin + rec.alert <= alert; + end procedure OverrideAlert; + +end package body AbstractMmPkg; diff --git a/testsuite/gna/issue467/axi_master.vhd b/testsuite/gna/issue467/axi_master.vhd new file mode 100644 index 000000000..d72f7ea55 --- /dev/null +++ b/testsuite/gna/issue467/axi_master.vhd @@ -0,0 +1,170 @@ +------------------------------------------------------------------------------- +-- Title : AXI-Lite Master BFM +-- Project : P500 +------------------------------------------------------------------------------- +-- File : axi_master.vhd +-- Author : Rob Gaddi <rgaddi@highlandtechnology.com> +-- Company : Highland Technology, Inc. +-- Created : 21-Nov-2017 +-- Last update: 21-Nov-2017 +-- Platform : Simulation +-- Standard : VHDL-2008 +------------------------------------------------------------------------------- +-- Description: Simulation model of an AXI4-Lite bus master. +------------------------------------------------------------------------------- +-- Revision History: +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library osvvm; +use osvvm.TbUtilPkg.all; +use osvvm.AlertLogPkg.all; + +use work.AbstractMmPkg.all; + +entity axi_master is + generic ( + LOG_NAME : string := "axi_master"; + DATAWIDTH : positive := 32; + ADDRWIDTH : positive := 12 + ); + port ( + -- AXI interface + AWADDR : out std_logic_vector(ADDRWIDTH-1 downto 0); + AWPROT : out std_logic_vector(2 downto 0); + AWVALID : out std_logic; + AWREADY : in std_logic; + + WDATA : out std_logic_vector(DATAWIDTH-1 downto 0); + WSTRB : out std_logic_vector((DATAWIDTH/8)-1 downto 0); + WVALID : out std_logic; + WREADY : in std_logic; + + BRESP : in std_logic_vector(1 downto 0); + BVALID : in std_logic; + BREADY : out std_logic; + + ARADDR : out std_logic_vector(ADDRWIDTH-1 downto 0); + ARPROT : out std_logic_vector(2 downto 0); + ARVALID : out std_logic; + ARREADY : in std_logic; + + RDATA : in std_logic_vector(DATAWIDTH-1 downto 0); + RRESP : in std_logic_vector(1 downto 0); + RVALID : in std_logic; + RREADY : out std_logic; + + ACLK : in std_logic; + ARESETn : in std_logic; + + -- AMR interface + amr : inout AbstractMmRecType + ); +end entity axi_master; + +architecture Behavioral of axi_master is + + constant ALRT : AlertLogIDType := GetAlertLogID(LOG_NAME); + + signal prot: std_logic_vector(2 downto 0); + constant BADREADDATA : std_logic_vector(RDATA'range) := (others => 'X'); + +begin + + INITIALIZE: process + begin + prot <= (others => '0'); + wait; + end process INITIALIZE; + + AXI: process + + procedure SingleRead is + variable request_ack : boolean := false; + begin + ARADDR <= STD_LOGIC_VECTOR(GetByteAddress(amr)); + ARPROT <= prot; + ARVALID <= '1'; + + while not request_ack loop + wait until rising_edge(ACLK); + if RVALID = '1' then + RREADY <= '0'; + request_ack := true; + end if; + end loop; + + RREADY <= '1'; + wait until rising_edge(ACLK) and RVALID='1'; + if RRESP = "00" then + amr.readdata <= RDATA; + else + amr.readdata <= BADREADDATA; + end if; + RREADY <= '0'; + end procedure SingleRead; + + procedure SingleWrite is + variable addr_ack : boolean := false; + variable data_ack : boolean := false; + variable resp_ack : boolean := false; + begin + AWADDR <= STD_LOGIC_VECTOR(GetByteAddress(amr)); + AWPROT <= prot; + AWVALID <= '1'; + WDATA <= amr.writedata; + WSTRB <= amr.byteen; + WVALID <= '1'; + + while not (addr_ack and data_ack) loop + wait until rising_edge(ACLK); + if AWREADY = '1' then + AWVALID <= '0'; + addr_ack := true; + end if; + if WREADY = '1' then + WVALID <= '0'; + data_ack := true; + end if; + end loop; + + BREADY <= '1'; + wait until rising_edge(ACLK) and BVALID='1'; + BREADY <= '0'; + end procedure SingleWrite; + + begin + InitializeAmr(amr); + amr.alert <= ALRT; + + loop + AWVALID <= '0'; + WVALID <= '0'; + BREADY <= '0'; + ARVALID <= '0'; + RREADY <= '0'; + + WaitForTransaction(ACLK, amr.rdy, amr.ack); + if ARESETn = '0' then + wait until ARESETn = '1'; + end if; + case amr.trans is + when SINGLE => + if amr.write = AMR_READ then + SingleRead; + else + SingleWrite; + end if; + + when others => + Alert(ALRT, "Transaction type " & TransactionType'image(amr.trans) & + " not supported by model.", FAILURE); + + end case; + end loop; + end process AXI; + +end architecture Behavioral; diff --git a/testsuite/gna/issue467/eu_tb.vhdl b/testsuite/gna/issue467/eu_tb.vhdl new file mode 100644 index 000000000..ce989056e --- /dev/null +++ b/testsuite/gna/issue467/eu_tb.vhdl @@ -0,0 +1,30 @@ +package unbound_rec is + type UnbRecType is record + writedata: bit_vector; + end record; +end package; + +use work.unbound_rec.all; +entity eut is + port ( + form_sig: out UnbRecType + ); +end entity; + +architecture foo of eut is +begin +end architecture; + +use work.unbound_rec.all; +entity eu_tb is +end entity; + +architecture fum of eu_tb is + signal act_sig: UnbRecType (writedata (7 downto 0)); +begin +UUT: + entity work.eut + port map ( + form_sig => act_sig + ); +end architecture; diff --git a/testsuite/gna/issue467/testbench.vhdl b/testsuite/gna/issue467/testbench.vhdl new file mode 100644 index 000000000..957b733dc --- /dev/null +++ b/testsuite/gna/issue467/testbench.vhdl @@ -0,0 +1,21 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.AbstractMmPkg.all; + +entity testbench is +end entity testbench; + +architecture TB of testbench is + + signal rec : AbstractMmRecType( + writedata(31 downto 0), + readdata(31 downto 0), + address(4 downto 0), + byteen(3 downto 0) + ); + +begin + +end architecture TB; diff --git a/testsuite/gna/issue467/testbench2.vhdl b/testsuite/gna/issue467/testbench2.vhdl new file mode 100644 index 000000000..9d611cb71 --- /dev/null +++ b/testsuite/gna/issue467/testbench2.vhdl @@ -0,0 +1,78 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.AbstractMmPkg.all; + +entity testbench is +end entity testbench; + +architecture TB of testbench is + + signal AWADDR : std_logic_vector(6 downto 0); + signal AWPROT : std_logic_vector(2 downto 0); + signal AWVALID : std_logic; + signal AWREADY : std_logic; + signal WDATA : std_logic_vector(31 downto 0); + signal WSTRB : std_logic_vector(3 downto 0); + signal WVALID : std_logic; + signal WREADY : std_logic; + signal BRESP : std_logic_vector(1 downto 0); + signal BVALID : std_logic; + signal BREADY : std_logic; + signal ARADDR : std_logic_vector(6 downto 0); + signal ARPROT : std_logic_vector(2 downto 0); + signal ARVALID : std_logic; + signal ARREADY : std_logic; + signal RDATA : std_logic_vector(31 downto 0); + signal RRESP : std_logic_vector(1 downto 0); + signal RVALID : std_logic; + signal RREADY : std_logic; + signal ACLK : std_logic; + signal ARESETn : std_logic; + + signal rec : AbstractMmRecType( + writedata(31 downto 0), + readdata(31 downto 0), + address(4 downto 0), + byteen(3 downto 0) + ); + +begin + + BFM: entity work.axi_master + generic map ( + DATAWIDTH => 32, + ADDRWIDTH => AWADDR'length + ) port map( + -- AXI interface, + AWADDR => AWADDR, + AWPROT => AWPROT, + AWVALID => AWVALID, + AWREADY => AWREADY, + + WDATA => WDATA, + WSTRB => WSTRB, + WVALID => WVALID, + WREADY => WREADY, + + BRESP => BRESP, + BVALID => BVALID, + BREADY => BREADY, + ARADDR => ARADDR, + ARPROT => ARPROT, + ARVALID => ARVALID, + ARREADY => ARREADY, + + RDATA => RDATA, + RRESP => RRESP, + RVALID => RVALID, + RREADY => RREADY, + + ACLK => ACLK, + ARESETn => ARESETn, + + -- AMR interface + amr => rec + ); +end architecture TB; diff --git a/testsuite/gna/issue467/testsuite.sh b/testsuite/gna/issue467/testsuite.sh new file mode 100755 index 000000000..45609d665 --- /dev/null +++ b/testsuite/gna/issue467/testsuite.sh @@ -0,0 +1,11 @@ +#! /bin/sh + +. ../../testenv.sh + +export GHDL_STD_FLAGS=--std=08 +analyze eu_tb.vhdl +elab_simulate eu_tb + +clean + +echo "Test successful" |