ghdl
ghdl copied to clipboard
GHDL Analysis Crash on Pointers and Multidimensional arrays
Description Working on updating MemoryPkg to handle variations in storage patterns. Current code runs in other simulators. It is on the OSVVM Dev branch with the tag: GHDL-Crashes-220805b
How to reproduce? Check out OsvvmLibraries dev branch with the tag GHDL-Crashes-220805b
In OSVVM build scripts run it with:
build <path-to-OsvvmLibraries>/osvvm
In GHDL, assuming my filters worked correctly, it ran:
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/TextUtilPkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/ResolutionPkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/NamePkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/OsvvmGlobalPkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/VendorCovApiPkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/TranscriptPkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/AlertLogPkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/NameStorePkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/MessageListPkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/SortListPkg_int.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/RandomBasePkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/RandomPkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/RandomProcedurePkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/CoveragePkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/ScoreboardGenericPkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/ScoreboardPkg_slv.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/ScoreboardPkg_int.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/ResizePkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/MemorySupportPkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/MemoryGenericPkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/MemoryPkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/TbUtilPkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/ReportPkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/OsvvmTypesPkg.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev ../../OsvvmLibraries/osvvm/OsvvmContext.vhd
** Code Insights ** Crashing code has:
if (MemStructPtr(ID).MemArrayPtr(BlockAddr) = NULL) then
MemStructPtr(ID).MemArrayPtr(BlockAddr) := new MemBlockType(0 to 2**BlockWidth-1)(MemoryBaseTypeWidth downto 1) ;
MemStructPtr(ID).MemArrayPtr(BlockAddr)(0 to 2**BlockWidth-1) := (0 to 2**BlockWidth-1 => InitMemoryBaseType(Data'length)) ;
end if ;
If I change the code to a loop, it analyzes
if (MemStructPtr(ID).MemArrayPtr(BlockAddr) = NULL) then
MemStructPtr(ID).MemArrayPtr(BlockAddr) := new MemBlockType(0 to 2**BlockWidth-1)(MemoryBaseTypeWidth downto 1) ;
for i in 0 to 2**BlockWidth-1 loop
MemStructPtr(ID).MemArrayPtr(BlockAddr)(i) := InitMemoryBaseType(Data'length) ;
end loop ;
end if ;
From a code execution standpoint, I suspect there is little difference here.
Context Please, provide the following information:
- OS:
- Origin:
- [ ] Package manager:
version
- [ ] Released binaries:
tarball_url
- [ ] Built from sources:
commit SHA
- [ ] Package manager:
If a GHDL Bug occurred
block is shown in the log, please paste it here:
ghdl -a --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 {*}-PC:/tools/sim_temp/GHDL-2.0.0-dev {*} ../../
OsvvmLibraries/osvvm/MemoryPkg.vhd
# ** Error: analyze For tcl errorInfo, puts $::osvvm::AnalyzeErrorInfo
AnalyzeError: analyze 'MemoryPkg.vhd ' failed:
******************** GHDL Bug occurred ***************************
Please report this bug on https://github.com/ghdl/ghdl/issues
GHDL release: 2.0.0-dev (1.0.0.r964.g70f3c162b) [Dunoon edition]
Compiled with GNAT Version: 11.2.0
Target: x86_64-w64-mingw32
C:\Synthworks\Dev\_osvvm\_sim\ghdl\
Command line:
C:\tools\msys64\mingw64\bin\ghdl1-llvm.exe --std=08 -Wno-library -Wno-hide --work=osvvm --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08 -PC:/tools/sim_temp/GHDL-2.0.0-dev\ -PC:\tools\msys64\mingw64\lib/ghdl
\ieee\v08\ -PC:\tools\msys64\mingw64\lib/ghdl\ -c -o C:/tools/sim_temp/GHDL-2.0.0-dev/osvvm/v08\MemoryPkg.o ../../OsvvmLibraries/osvvm/MemoryPkg.vhd
Exception PROGRAM_ERROR raised
Exception information:
raised PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION
Call stack traceback locations:
0x7ff705ce55db 0x7ffc514b229d 0x7ffc51461452 0x7ffc514b0dcc 0x7ff7064e089f 0x7ff7069696e0 0x7ff7066441a2 0x7ff705d0d148 0x7ff705a57aff 0x7ff705be30e5 0x7ff705be7fb0 0x7ff705be85dd 0x7ff705c1eeb3 0x7ff705c1efdb 0
x7ff705c1f97d 0x7ff705c1ffc3 0x7ff705c2071f 0x7ff705c1fae2 0x7ff705c22927 0x7ff705c229e9 0x7ff705c26a02 0x7ff705c26d8e 0x7ff705c26af3 0x7ff705c6c5d3 0x7ff705c807c6 0x7ff705c808e5 0x7ff705c68c9a 0x7ff705c68d3b 0x
7ff705c80751 0x7ff705c80921 0x7ff705c49a59 0x7ff705c5fffb 0x7ff705bdf482 0x7ff705c60054 0x7ff705c4ac3f 0x7ff705c507d0 0x7ff705c335fd 0x7ff705c96f62 0x7ff705c98b45 0x7ff705c9a48c 0x7ff705a526e8 0x7ff705a513af 0x7
ff705a514e4 0x7ffc50467032 0x7ffc5146264f
******************************************************************
Additional context Add any other context about the problem here. If applicable, add screenshots to help explain your problem.
What is the URL of the repo ?
@tgingold, see https://github.com/OSVVM/OsvvmLibraries/tree/GHDL-Crashes-220805b.
Reproducer:
entity repro1 is
end;
architecture behav of repro1 is
function InitMemoryBaseType(Size : integer) return integer_vector is
begin
return (1 to Size => 0);
end InitMemoryBaseType;
subtype MemoryBaseType is integer_vector ;
type MemBlockType is array (integer range <>) of MemoryBaseType ;
type MemBlockPtrType is access MemBlockType ;
begin
process
variable MemArr : MemBlockPtrType;
variable BlockWidth : natural;
begin
BlockWidth := 4;
MemArr := new MemBlockType (0 to BlockWidth - 1)(0 to 31);
MemArr(0 to BlockWidth-1) :=
(0 to BlockWidth-1 => InitMemoryBaseType(32)) ;
wait;
end process;
end;
To be honest, I don't think this is valid according to the LRM.
The bounds of an aggregate must be determinable either from the context (but not in that case) or from the choices. Here you first need to evaluate the expression.
Then this should fix it right?
entity repro1 is
end;
architecture behav of repro1 is
function InitMemoryBaseType(Size : integer) return integer_vector is
begin
return (1 to Size => 0);
end InitMemoryBaseType;
constant INIT_MEM_BASE : integer_vector := InitMemoryBaseType(32) ;
subtype MemoryBaseType is integer_vector ;
type MemBlockType is array (integer range <>) of MemoryBaseType ;
type MemBlockPtrType is access MemBlockType ;
begin
process
variable MemArr : MemBlockPtrType;
variable BlockWidth : natural;
begin
BlockWidth := 4;
MemArr := new MemBlockType (0 to BlockWidth - 1)(0 to 31);
MemArr(0 to BlockWidth-1) :=
(0 to BlockWidth-1 => INIT_MEM_BASE) ;
wait;
end process;
end;
Then this too should work. It analyzes, but it fails during simulate.
entity MemPkgReproducer4 is
end;
architecture behav of MemPkgReproducer4 is
function InitMemoryBaseType(Size : integer) return integer_vector is
begin
return (1 to Size => 0);
end InitMemoryBaseType;
subtype MemoryBaseType is integer_vector ;
type MemBlockType is array (integer range <>) of MemoryBaseType ;
type MemBlockPtrType is access MemBlockType ;
begin
process
variable MemArr : MemBlockPtrType;
variable BlockWidth : natural;
begin
BlockWidth := 4;
MemArr := new MemBlockType'( 0 to BlockWidth - 1 => (0 to 31 => -1));
-- MemArr(0 to BlockWidth-1) :=
-- (0 to BlockWidth-1 => (0 to 31 => 0)) ;
wait;
end process;
end;
During simulate, it does:
ghdl -a --std=08 -Wno-library -Wno-hide --work=TbMemoryPkg_X --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/tbmemorypkg_x/v08 {*}-PC:/tools/sim_temp/GHD
L-2.0.0-dev {*} ../../osvvm_testbench/MemoryPkg_X/LocalTestPkg.vhd
RunTest TbMem_Width39.vhd
TestCase TbMem_Width39
analyze TbMem_Width39.vhd
ghdl -a --std=08 -Wno-library -Wno-hide --work=TbMemoryPkg_X --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/tbmemorypkg_x/v08 {*}-PC:/tools/sim_temp/GHD
L-2.0.0-dev {*} ../../osvvm_testbench/MemoryPkg_X/TbMem_Width39.vhd
simulate TbMem_Width39
Simulation Start time 19:12:09
ghdl --elab-run {*}--std=08 --syn-binding --work=TbMemoryPkg_X --workdir=C:/tools/sim_temp/GHDL-2.0.0-dev/tbmemorypkg_x/v08 -PC:/tools/sim_temp/GHDL
-2.0.0-dev TbMem_Width39 {*}
Simulation Finish time 19:12:10, Elasped time: 0:00:01
# ** Error: simulate For tcl errorInfo, puts $::osvvm::SimulateErrorInfo
SimulateError: 'TbMem_Width39 ' failed:
Build Start time 19:12:09 PDT Tue Aug 09 2022
Build Finish time 19:12:10, Elasped time: 0:00:01
Build: MemoryPkg_X_tests FAILED, Passed: 0, Failed: 1, Skipped: 0, Analyze Errors: 0, Simulate Errors: 1
Error: Build failed with SimulateErrorCount = 1. .
For tcl errorInfo, puts $::osvvm::BuildErrorInfo
% puts $::osvvm::SimulateErrorInfo
ghdl --elab-run ended with error %% Log DEBUG in Mem, MemoryPkg.FileReadX: MemWrite(Addr => 1000, Data => 0100010000) at 0 ns
.\tbmem_width39:error: bound check failure at ../../OsvvmLibraries/osvvm/MemoryPkg.vhd:572
in process .tbmem_width39(memorypkg_fileread1).readproc
.\tbmem_width39:error: simulation failed
child process exited abnormally
while executing
"error "ghdl --elab-run ended with error $SimResults""
(procedure "vendor_simulate" line 29)
invoked from within
"vendor_simulate ${VhdlWorkingLibrary} ${LibraryUnit} ${AllOptionalCommands}"
(procedure "LocalSimulate" line 43)
invoked from within
"LocalSimulate $LibraryUnit $OptionalCommands"
TbMem_Width39.vhd is:
--
-- File Name: TbMem_Width39.vhd
-- Design Unit Name: TbMem_Width39
-- Revision: STANDARD VERSION
--
-- Copyright (c) 2022 by SynthWorks Design Inc. All rights reserved.
--
-- Maintainer: Jim Lewis email: [email protected]
-- Contributor(s):
-- Jim Lewis email: [email protected]
--
-- Description:
-- Test Suite for RandomPkg.vhd
--
-- Developed for:
-- SynthWorks Design Inc.
-- Training Courses
-- 11898 SW 128th Ave.
-- Tigard, Or 97223
-- http://www.SynthWorks.com
--
--
-- Revision History:
-- Date Version Description
-- 08/2022 2022.08 Initial
--
--
library osvvm ;
context osvvm.OsvvmContext ;
use osvvm.MemoryPkg.all ;
library IEEE ;
use ieee.std_logic_1164.all ;
use ieee.numeric_std.all ;
use ieee.numeric_std_unsigned.all ;
use work.LocalTestPkg.all ;
use work.OsvvmTestCommonPkg.all ;
entity TbMem_Width39 is
end TbMem_Width39 ;
architecture MemoryPkg_FileRead1 of TbMem_Width39 is
signal SyncPoint, TestDone : std_logic := '0' ;
constant ADDR_LEN : integer := 16 ;
constant DATA_LEN : integer := 39 ;
-- constant MemID : osvvm.MemoryPkg.MemoryIDType := NewID("Mem_FileRead1", ADDR_LEN, DATA_LEN) ;
signal MemID : osvvm.MemoryPkg.MemoryIDType ;
begin
MemID <= NewID("Mem", ADDR_LEN, DATA_LEN) ;
ControlProc : process
begin
SetAlertLogName("TbMem_Width39") ;
TranscriptOpen(RESULTS_DIR & "TbMem_Width39.txt") ;
SetTranscriptMirror(TRUE) ;
SetLogEnable(PASSED, TRUE) ;
SetLogEnable(DEBUG, TRUE) ;
WaitForBarrier(TestDone) ; -- Wrap-up Test Done
print("");
TranscriptClose ;
AffirmIfNotDiff(RESULTS_DIR & "TbMem_Width39.txt", VALIDATED_RESULTS_DIR & "TbMem_Width39.txt", "Check Transcript") ;
EndOfTestSummary ;
std.env.stop(GetAlertCount) ;
wait ;
end process ControlProc ;
ReadProc : process
variable Addr : std_logic_vector(ADDR_LEN-1 downto 0) ;
variable rData, eData : std_logic_vector(DATA_LEN-1 downto 0) ;
variable iVal : std_logic_vector(3 downto 0) ;
begin
wait for 0 ns ; -- Get MemID first
FileReadH(MemID, SOURCE_DIR & "TbMem_Width39_FileRead.mem") ;
wait for 1 ns ;
print("MemRead X1000") ;
Addr := X"1000" ;
eData := 39UX"01_0001_0000" ;
for i in 0 to 7 loop
MemRead(MemID, Addr+i, rData) ;
AffirmIfEqual(rData, eData+i, "Address: " & to_hstring(Addr) & " Data, ") ;
wait for 1 ns ;
end loop ;
print("MemRead X2000") ;
Addr := X"2000" ;
eData := 39UX"02_0002_0000" ;
for i in 0 to 7 loop
rData := MemRead(MemID, Addr+i) ;
AffirmIfEqual(rData, eData+i, "Address: " & to_hstring(Addr) & " Data, ") ;
wait for 1 ns ;
end loop ;
print("MemRead X3000") ;
Addr := X"3000" ;
eData := 39UX"03_0003_UUUU" ;
MemRead(MemID, Addr, rData) ;
AffirmIfEqual(rData, eData, "Address: " & to_hstring(Addr) & " Data, ") ;
Addr := X"3001" ;
eData := 39UX"03_0003_XXXX" ;
MemRead(MemID, Addr, rData) ;
AffirmIfEqual(rData, eData, "Address: " & to_hstring(Addr) & " Data, ") ;
Addr := X"3002" ;
eData := 39UX"03_0003_U0X1" ;
MemRead(MemID, Addr, rData) ;
AffirmIfEqual(rData, eData, "Address: " & to_hstring(Addr) & " Data, ") ;
Addr := X"3003" ;
eData := 39SX"UU_UUUU_UUUU" ;
MemRead(MemID, Addr, rData) ;
AffirmIfEqual(rData, eData, "Address: " & to_hstring(Addr) & " Data, ") ;
print("MemWrite X4000") ;
Addr := X"4000" ;
eData := 39UX"04_0004_0000" ;
for i in 0 to 7 loop
MemWrite(MemID, Addr+i, eData+i) ;
wait for 1 ns ;
end loop ;
FileWriteH(MemID, RESULTS_DIR & "TbMem_Width39_FileWrite.mem") ;
AffirmIfNotDiff(RESULTS_DIR & "TbMem_Width39_FileWrite.mem", VALIDATED_RESULTS_DIR & "TbMem_Width39_FileWrite.mem", "FileWrite Test") ;
WaitForBarrier(TestDone) ; -- Wrap-up Test Done
wait ;
end process ReadProc ;
end MemoryPkg_FileRead1 ;
In MemoryGenericPkg.MemWrite, I did the following:
if (MemStructPtr(ID).MemArrayPtr(BlockAddr) = NULL) then
MemStructPtr(ID).MemArrayPtr(BlockAddr) := new MemBlockType'(0 to 2**BlockWidth-1 => (MemoryBaseTypeWidth downto 1 => -1)) ;
--No MemStructPtr(ID).MemArrayPtr(BlockAddr) := new MemBlockType'(0 to 2**BlockWidth-1 => InitMemoryBaseType(Data'length)) ;
--Yes MemStructPtr(ID).MemArrayPtr(BlockAddr) := new MemBlockType(0 to 2**BlockWidth-1)(MemoryBaseTypeWidth downto 1) ;
--No MemStructPtr(ID).MemArrayPtr(BlockAddr)(0 to 2**BlockWidth-1) := (0 to 2**BlockWidth-1 => InitMemoryBaseType(Data'length)) ;
--Yes for i in 0 to 2**BlockWidth-1 loop
--Yes MemStructPtr(ID).MemArrayPtr(BlockAddr)(i) := InitMemoryBaseType(Data'length) ;
--Yes end loop ;
end if ;
The reality I was working toward was that MemoryBaseType is a GenericType and hence needed the function InitMemBaseType to return the correct type. Other tools seemed to be able to see that MemBaseType was an integer_vector and complained about that. So I have been backtracking to find what actually works in simulators and what does not
I pushed the updates above to the Debug branch of OsvvmLibraries and debug branch of osvvm
It is here: https://github.com/OSVVM/OsvvmLibraries/tree/Debug
@tgingold @umarcor Is the updated version of GHDL available on MSYS2 pacman?
@JimLewis, you can download the *.pkg.tar.zst
packages from https://github.com/ghdl/ghdl/releases/tag/nightly and install them through pacman. However, the version of GHDL available on MSYS2 repositories was last updated a month ago. See https://github.com/msys2/MINGW-packages/commits/master/mingw-w64-ghdl.
They have been updated today.