On Wed, 2013-04-10 at 07:11 +0200, René Doß wrote:
> Hi Jon,
> 
>  I can not call from C.  Your solution can be interesting for me.
> 
> I can give you only my commandline. For a Call from VHDL. 
> 
>     ghdl -e  -Wl,emulator_src.o -Wl,gdb_sim.o -Wl,-lpthread
> --ieee=synopsys  --workdir=work -Pwork tb_lm_cpu

> > 
> > I am attempting to write a multithreaded application in VHDL, using
> > GHDL as the compiler.  I need to call from C a function written in
> > VHDL and compiled into object form using GHDL back into the VHDL
> > code somehow, since I can't get direct access to pthreads from VHDL.

I have called VHDL from a gcc-compiled main program. Not individual VHDL
functions but a VHDL "main program" (which expected argc,argv). I
thought this was the only supported form of cal/ling VHDL from
externally but I would be delighted to be wrong.

The VHDL code in turn called back to functions in the foreign language.

This may not satisfy your requirements but it is probably worth briefly
placing it on record anyway.

Incidentally the "foreign" language here is Ada, and though the
functionality would translate to C easily enough, Ada would probably be
a more natural choice for multithreading thanks to its tasking
facilities. 

Forcing VHPI to be a C-like interface throws away a LOT of useful type
safety, but I guess we are stuck with that : assume consistency in e.g.
enumerations between VHDL and native (C or Ada) sides at your peril (as
this little example demonstrates!)

Command lines were:
ghdl -a test_vhpi.vhd
ghdl --bind vhpi_tb
gnatmake ada_main.adb -largs `ghdl --list-link -Wl,ada_tools.o vhpi_tb`
./ada_main

- Brian



with System;
with Ada.Text_IO; 	use Ada.Text_IO;
with Ada.Command_Line;
with Interfaces.C;
with System.Address_To_Access_Conversions;

procedure ada_main is

  function Ghdl_Main (Argc : Integer; Argv : System.Address)
     return Integer;
  pragma import (C, Ghdl_Main, "ghdl_main");

  Result : Integer;

  Name : aliased String := Ada.Command_Line.Command_Name;

  type StrAcc is access all String;

  NA : aliased StrAcc := Name'Access;
  
   package Acc is new System.Address_To_Access_Conversions(Object => StrAcc);

procedure P (S: in String) renames Ada.Text_IO.Put_Line;

begin

  P("Starting GHDL main program with argcount " & Integer'image(Ada.Command_Line.Argument_Count));

  Result := Ghdl_Main(Ada.Command_Line.Argument_Count, Acc.To_Address(NA'Access));
  --Result := Ghdl_Main(ArgC, ArgV);

  P("GHDL main program returned " & Integer'image(Result));

end ada_main;
package body ada_tools is

function ada_1 (v : integer) return integer is
begin
  return v + v;
end ada_1;

function ada_2 (v : integer) return integer is
begin
  return v * v;
end ada_2;

function get_c(v : integer) return colour is
begin
  case v is
  when 1 => return red;
  when 2 => return green;
  when 3 => return blue;
  when others => return brown;
  end case;
end get_c;

end ada_tools;

package ada_tools is

-- integers work
   function ada_1 (v : integer) return integer;
   pragma export (C, ada_1);

   function ada_2 (v : integer) return integer;
   pragma export (C, ada_2);

-- enumerations?
   type colour is (red, green, blue, brown);
   function get_c(v : integer) return colour;
   pragma export (C, get_c);
-- Work but note their fundamental insecurity...

end ada_tools;

entity vhpi_tb is

end entity vhpi_tb;
library ieee;
use ieee.std_logic_1164.all;
architecture test of vhpi_tb is

function ada_1 (v : integer) return integer;
attribute foreign of ada_1 : function is "VHPIDIRECT ada_1";

function ada_2 (v : integer) return integer;
attribute foreign of ada_2 : function is "VHPIDIRECT ada_2";

   type colour is (cyan, magenta, yellow, green, black);

   function get_c(v : integer) return colour;

attribute foreign of get_c : function is "VHPIDIRECT get_c";

function ada_1 (v : integer) return integer is
begin
  assert false severity failure;
end ada_1;

function ada_2 (v : integer) return integer is
begin
  assert false severity failure;
end ada_2;

function get_c (v : integer) return colour is
begin
  assert false severity failure;
end get_c;

begin  -- architecture test

tester : process is
begin
  for i in 1 to 5 loop
    assert ada_1(i) = ada_2(i) report "Mismatch  at " & integer'image(i) & " : " 
           & integer'image(ada_1(i)) & " vs " & integer'image(ada_2(i)) severity note;
    report "colour " & integer'image(i) & " is " & colour'image(get_c(i)) severity note;
  end loop;
  wait;
end process tester;

end architecture test;

_______________________________________________
Ghdl-discuss mailing list
[email protected]
https://mail.gna.org/listinfo/ghdl-discuss

Reply via email to