summaryrefslogtreecommitdiff
path: root/translate
diff options
context:
space:
mode:
Diffstat (limited to 'translate')
-rw-r--r--translate/grt/config/win32.c174
-rw-r--r--translate/grt/ghwlib.c29
-rw-r--r--translate/grt/ghwlib.h3
-rw-r--r--translate/grt/grt-signals.adb9
-rw-r--r--translate/grt/grt-waves.adb51
5 files changed, 118 insertions, 148 deletions
diff --git a/translate/grt/config/win32.c b/translate/grt/config/win32.c
index 80ea270..583b885 100644
--- a/translate/grt/config/win32.c
+++ b/translate/grt/config/win32.c
@@ -1,5 +1,5 @@
-/* GRT stack implementation for Win32
- Copyright (C) 2004, 2005 Felix Bertram.
+/* GRT stack implementation for Win32 using fibers.
+ Copyright (C) 2005 Tristan Gingold.
GHDL is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
@@ -16,139 +16,74 @@
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
-//-----------------------------------------------------------------------------
-// Project: GHDL - VHDL Simulator
-// Description: Win32 port of stacks package
-// Note: Tristan's original i386/Linux used assembly-code
-// to manually switch stacks for performance reasons.
-// History: 2004feb09, FB, created.
-//-----------------------------------------------------------------------------
#include <windows.h>
-//#include <pthread.h>
-//#include <stdlib.h>
-//#include <stdio.h>
+#include <stdio.h>
+struct stack_type
+{
+ LPVOID fiber; // Win fiber.
+ void (*func)(void *); // Function
+ void *arg; // Function argument.
+};
-//#define INFO printf
-#define INFO (void)
-
-// GHDL names an endless loop calling FUNC with ARG a 'stack'
-// at a given time, only one stack may be 'executed'
-typedef struct
-{ HANDLE thread; // stack's thread
- HANDLE mutex; // mutex to suspend/resume thread
- void (*Func)(void*); // stack's FUNC
- void* Arg; // ARG passed to FUNC
-} Stack_Type_t, *Stack_Type;
-
-Stack_Type_t main_stack_context;
-extern Stack_Type grt_stack_main_stack;
+static struct stack_type main_stack_context;
+extern void grt_set_main_stack (struct stack_type *stack);
-//------------------------------------------------------------------------------
void grt_stack_init(void)
-// Initialize the stacks package.
-// This may adjust stack sizes.
-// Must be called after grt.options.decode.
-// => procedure Stack_Init;
-{ INFO("grt_stack_init\n");
- INFO(" main_stack_context=0x%08x\n", &main_stack_context);
-
- // create event. reset event, as we are currently running
- main_stack_context.mutex = CreateEvent(NULL, // lpsa
- FALSE, // fManualReset
- FALSE, // fInitialState
- NULL); // lpszEventName
-
- grt_stack_main_stack= &main_stack_context;
+{
+ main_stack_context.fiber = ConvertThreadToFiber (NULL);
+ if (main_stack_context.fiber == NULL)
+ {
+ fprintf (stderr, "convertThreadToFiber failed (err=%lu)\n",
+ GetLastError ());
+ abort ();
+ }
+ grt_set_main_stack (&main_stack_context);
}
-//------------------------------------------------------------------------------
-static unsigned long __stdcall grt_stack_loop(void* pv_myStack)
+static VOID __stdcall
+grt_stack_loop (void *v_stack)
{
- Stack_Type myStack= (Stack_Type)pv_myStack;
-
- INFO("grt_stack_loop\n");
-
- INFO(" myStack=0x%08x\n", myStack);
-
- // block until event becomes set again.
- // this happens when this stack is enabled for the first time
- WaitForSingleObject(myStack->mutex, INFINITE);
-
- // run stack's function in endless loop
- while(1)
- { INFO(" call 0x%08x with 0x%08x\n", myStack->Func, myStack->Arg);
- myStack->Func(myStack->Arg);
- }
-
- // we never get here...
- return 0;
+ struct stack_type *stack = (struct stack_type *)v_stack;
+ while (1)
+ {
+ (*stack->func)(stack->arg);
+ }
}
-//------------------------------------------------------------------------------
-Stack_Type grt_stack_create(void* Func, void* Arg)
-// Create a new stack, which on first execution will call FUNC with
-// an argument ARG.
-// => function Stack_Create (Func : Address; Arg : Address) return Stack_Type;
-{ Stack_Type newStack;
- DWORD m_IDThread; // Thread's ID (dummy)
-
- INFO("grt_stack_create\n");
- INFO(" call 0x%08x with 0x%08x\n", Func, Arg);
-
- newStack= malloc(sizeof(Stack_Type_t));
-
- // init function and argument
- newStack->Func= Func;
- newStack->Arg= Arg;
-
- // create event. reset event, so that thread will blocked in grt_stack_loop
- newStack->mutex= CreateEvent(NULL, // lpsa
- FALSE, // fManualReset
- FALSE, // fInitialState
- NULL); // lpszEventName
-
- INFO(" newStack=0x%08x\n", newStack);
-
- // create thread, which executes grt_stack_loop
- newStack->thread= CreateThread(NULL, // lpsa
- 0, // cbStack
- grt_stack_loop, // lpStartAddr
- newStack, // lpvThreadParm
- 0, // fdwCreate
- &m_IDThread); // lpIDThread
-
- return newStack;
+struct stack_type *
+grt_stack_create (void (*func)(void *), void *arg)
+{
+ struct stack_type *res;
+
+ res = malloc (sizeof (struct stack_type));
+ if (res == NULL)
+ return NULL;
+ res->func = func;
+ res->arg = arg;
+ res->fiber = CreateFiber (0, &grt_stack_loop, res);
+ if (res->fiber == NULL)
+ {
+ free (res);
+ return NULL;
+ }
+ return res;
}
-//------------------------------------------------------------------------------
-void grt_stack_switch(Stack_Type To, Stack_Type From)
-// Resume stack TO and save the current context to the stack pointed by
-// CUR.
-// => procedure Stack_Switch (To : Stack_Type; From : Stack_Type);
-{ INFO("grt_stack_switch\n");
- INFO(" from 0x%08x to 0x%08x\n", From, To);
-
- // set 'To' event. this will make the other thread either
- // - start for first time in grt_stack_loop
- // - resume at WaitForSingleObject below
- SetEvent(To->mutex);
-
- // block until 'From' event becomes set again
- // as we are running, our event is reset and we block here
- // when stacks are switched, with above SetEvent, we may proceed
- WaitForSingleObject(From->mutex, INFINITE);
+void
+grt_stack_switch (struct stack_type *to, struct stack_type *from)
+{
+ SwitchToFiber (to->fiber);
}
-//------------------------------------------------------------------------------
-void grt_stack_delete(Stack_Type Stack)
-// Delete stack STACK, which must not be currently executed.
-// => procedure Stack_Delete (Stack : Stack_Type);
-{ INFO("grt_stack_delete\n");
+void
+grt_stack_delete (struct stack_type *stack)
+{
+ DeleteFiber (stack->fiber);
+ stack->fiber = NULL;
}
-//----------------------------------------------------------------------------
#ifndef WITH_GNAT_RUN_TIME
void __gnat_raise_storage_error(void)
{
@@ -161,6 +96,3 @@ void __gnat_raise_program_error(void)
}
#endif
-//----------------------------------------------------------------------------
-// end of file
-
diff --git a/translate/grt/ghwlib.c b/translate/grt/ghwlib.c
index b230acf..4585688 100644
--- a/translate/grt/ghwlib.c
+++ b/translate/grt/ghwlib.c
@@ -1214,16 +1214,31 @@ ghw_read_cycle_end (struct ghw_handler *h)
return 0;
}
+static const char *
+ghw_get_lit (union ghw_type *type, int e)
+{
+ if (e >= type->en.nbr || e < 0)
+ return "??";
+ else
+ return type->en.lits[e];
+}
+
+static void
+ghw_disp_lit (union ghw_type *type, int e)
+{
+ printf ("%s (%d)", ghw_get_lit (type, e), e);
+}
+
void
ghw_disp_value (union ghw_val *val, union ghw_type *type)
{
switch (ghw_get_base_type (type)->kind)
{
case ghdl_rtik_type_b2:
- printf ("%s (%d)", type->en.lits[val->b2], val->b2);
+ ghw_disp_lit (type, val->b2);
break;
case ghdl_rtik_type_e8:
- printf ("%s (%d)", type->en.lits[val->e8], val->e8);
+ ghw_disp_lit (type, val->e8);
break;
case ghdl_rtik_type_i32:
printf ("%d", val->i32);
@@ -1582,10 +1597,14 @@ ghw_get_dir (int is_downto)
}
void
-ghw_disp_range (union ghw_range *rng)
+ghw_disp_range (union ghw_type *type, union ghw_range *rng)
{
switch (rng->kind)
{
+ case ghdl_rtik_type_e8:
+ printf ("%s %s %s", ghw_get_lit (type, rng->e8.left),
+ ghw_get_dir (rng->e8.dir), ghw_get_lit (type, rng->e8.right));
+ break;
case ghdl_rtik_type_i32:
case ghdl_rtik_type_p32:
printf ("%d %s %d",
@@ -1657,7 +1676,7 @@ ghw_disp_type (struct ghw_handler *h, union ghw_type *t)
printf ("subtype %s is ", s->name);
ghw_disp_typename (h, s->base);
printf (" range ");
- ghw_disp_range (s->rng);
+ ghw_disp_range (s->base, s->rng);
printf (";\n");
}
break;
@@ -1692,7 +1711,7 @@ ghw_disp_type (struct ghw_handler *h, union ghw_type *t)
{
if (i != 0)
printf (", ");
- ghw_disp_range (a->rngs[i]);
+ ghw_disp_range ((union ghw_type *)a->base, a->rngs[i]);
}
printf (");\n");
}
diff --git a/translate/grt/ghwlib.h b/translate/grt/ghwlib.h
index 7441d1e..dbf20fe 100644
--- a/translate/grt/ghwlib.h
+++ b/translate/grt/ghwlib.h
@@ -390,7 +390,8 @@ void ghw_close (struct ghw_handler *h);
const char *ghw_get_dir (int is_downto);
-void ghw_disp_range (union ghw_range *rng);
+/* Note: TYPE must be a base type (used only to display literals). */
+void ghw_disp_range (union ghw_type *type, union ghw_range *rng);
void ghw_disp_type (struct ghw_handler *h, union ghw_type *t);
diff --git a/translate/grt/grt-signals.adb b/translate/grt/grt-signals.adb
index 520fbe4..5b3a12f 100644
--- a/translate/grt/grt-signals.adb
+++ b/translate/grt/grt-signals.adb
@@ -1095,15 +1095,6 @@ package body Grt.Signals is
when others =>
Internal_Error ("ghdl_create_signal_attribute");
end case;
--- Sig_Instance_Name := new Ghdl_Instance_Name_Type'
--- (Kind => Ghdl_Name_Signal,
--- Name => null,
--- Parent => null,
--- Brother => null,
--- Sig_Mode => Mode,
--- Sig_Kind => Kind_Signal_No,
--- Sig_Indexes => (First => Sig_Table.Last + 1, Last => Sig_Table.Last),
--- Sig_Type_Desc => Sig_Type);
-- Note: bit and boolean are both mode_b2.
Res := Create_Signal
(Mode_B2, Value_Union'(Mode => Mode_B2, B2 => True),
diff --git a/translate/grt/grt-waves.adb b/translate/grt/grt-waves.adb
index 8a189e6..bfe4cec 100644
--- a/translate/grt/grt-waves.adb
+++ b/translate/grt/grt-waves.adb
@@ -785,6 +785,15 @@ package body Grt.Waves is
Nbr_Scope_Signals : Natural := 0;
Nbr_Dumped_Signals : Natural := 0;
+ -- This is only valid during write_hierarchy.
+ function Get_Signal_Number (Sig : Ghdl_Signal_Ptr) return Natural
+ is
+ function To_Integer_Address is new Ada.Unchecked_Conversion
+ (Ghdl_Signal_Ptr, Integer_Address);
+ begin
+ return Natural (To_Integer_Address (Sig.Alink));
+ end Get_Signal_Number;
+
procedure Write_Signal_Number (Val_Addr : Address;
Val_Name : Vstring;
Val_Type : Ghdl_Rti_Access)
@@ -792,20 +801,28 @@ package body Grt.Waves is
pragma Unreferenced (Val_Name);
pragma Unreferenced (Val_Type);
- function To_Integer_Address is new Ada.Unchecked_Conversion
- (Ghdl_Signal_Ptr, Integer_Address);
+ Num : Natural;
+
function To_Ghdl_Signal_Ptr is new Ada.Unchecked_Conversion
(Source => Integer_Address, Target => Ghdl_Signal_Ptr);
Sig : Ghdl_Signal_Ptr;
begin
+ -- Convert to signal.
Sig := To_Ghdl_Signal_Ptr (To_Addr_Acc (Val_Addr).all);
- if not Sig.Flags.Is_Dumped then
- Sig.Flags.Is_Dumped := True;
+
+ -- Get signal number.
+ Num := Get_Signal_Number (Sig);
+
+ -- If the signal number is 0, then assign a valid signal number.
+ if Num = 0 then
Nbr_Dumped_Signals := Nbr_Dumped_Signals + 1;
- Sig.Flink := To_Ghdl_Signal_Ptr
+ Sig.Alink := To_Ghdl_Signal_Ptr
(Integer_Address (Nbr_Dumped_Signals));
+ Num := Nbr_Dumped_Signals;
end if;
- Wave_Put_ULEB128 (Ghdl_E32 (To_Integer_Address (Sig.Flink)));
+
+ -- Do the real job: write the signal number.
+ Wave_Put_ULEB128 (Ghdl_E32 (Num));
end Write_Signal_Number;
procedure Foreach_Scalar_Signal_Number is new
@@ -1370,13 +1387,18 @@ package body Grt.Waves is
Table_Initial => 32,
Table_Increment => 100);
+ function Get_Dump_Entry (N : Natural) return Ghdl_Signal_Ptr is
+ begin
+ return Dump_Table.Table (N);
+ end Get_Dump_Entry;
+
procedure Write_Hierarchy (Root : VhpiHandleT)
is
N : Natural;
begin
- -- Check Flink is 0.
+ -- Check Alink is 0.
for I in Sig_Table.First .. Sig_Table.Last loop
- if Sig_Table.Table (I).Flink /= null then
+ if Sig_Table.Table (I).Alink /= null then
Internal_Error ("wave.write_hierarchy");
end if;
end loop;
@@ -1393,15 +1415,20 @@ package body Grt.Waves is
Wave_Put_Byte (0);
Dump_Table.Set_Last (Nbr_Dumped_Signals);
+ for I in Dump_Table.First .. Dump_Table.Last loop
+ Dump_Table.Table (I) := null;
+ end loop;
-- Save and clear.
- N := 0;
for I in Sig_Table.First .. Sig_Table.Last loop
- if Sig_Table.Table (I).Flags.Is_Dumped then
- N := N + 1;
+ N := Get_Signal_Number (Sig_Table.Table (I));
+ if N /= 0 then
+ if Dump_Table.Table (N) /= null then
+ Internal_Error ("wave.write_hierarchy(2)");
+ end if;
Dump_Table.Table (N) := Sig_Table.Table (I);
+ Sig_Table.Table (I).Alink := null;
end if;
- Sig_Table.Table (I).Flink := null;
end loop;
end Write_Hierarchy;