From d1b9423d66a26b050390ee47fe1cdd7ebc356c17 Mon Sep 17 00:00:00 2001 From: David Doose <david.doose@gmail.com> Date: Thu, 2 Mar 2017 18:12:04 +0100 Subject: [PATCH] mauve generator: first shot --- include/arrow.hpp | 1 + src/_tags | 1 + src/backends/C/c_backend.ml | 28 +++++ src/backends/C/c_backend_common.ml | 2 +- src/backends/C/c_backend_mauve.ml | 169 +++++++++++++++++++++++++++++ src/options.ml | 4 + 6 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 src/backends/C/c_backend_mauve.ml diff --git a/include/arrow.hpp b/include/arrow.hpp index 636c2301..e8e04500 100644 --- a/include/arrow.hpp +++ b/include/arrow.hpp @@ -2,6 +2,7 @@ #ifndef _ARROW_CPP #define _ARROW_CPP +#include <stdint.h> #include <stdlib.h> struct _arrow_mem { diff --git a/src/_tags b/src/_tags index 90ced608..286ec864 100644 --- a/src/_tags +++ b/src/_tags @@ -9,3 +9,4 @@ <*.ml{,i}>: package(ocamlgraph) <*.ml{,i}>: use_str <*.ml{,i}>: use_unix + diff --git a/src/backends/C/c_backend.ml b/src/backends/C/c_backend.ml index d5749dd5..3a9f1e91 100644 --- a/src/backends/C/c_backend.ml +++ b/src/backends/C/c_backend.ml @@ -10,6 +10,7 @@ (********************************************************************) open Format +open C_backend_mauve (********************************************************************************************) (* Translation function *) (********************************************************************************************) @@ -65,6 +66,33 @@ let gen_files funs basename prog machines dependencies = end )); + (match !Options.mauve with + | "" -> () + | mauve -> ( + (* looking for the main node *) + match Machine_code.get_machine_opt mauve machines with + | None -> begin + Global.main_node := mauve; + Format.eprintf "Code generation error: %a@." Corelang.pp_error LustreSpec.Main_not_found; + raise (Corelang.Error (Location.dummy_loc, LustreSpec.Main_not_found)) + end + | Some m -> begin + let source_mauve_file = destname ^ "_mauve.hpp" in + let source_mauve_out = open_out source_mauve_file in + let source_mauve_fmt = formatter_of_out_channel source_mauve_out in + (* Header *) + print_mauve_header source_mauve_fmt m basename prog machines dependencies; + (* Shell *) + print_mauve_shell source_mauve_fmt m basename prog machines dependencies; + (* Core *) + print_mauve_core source_mauve_fmt m basename prog machines dependencies; + (* FSM *) + print_mauve_fsm source_mauve_fmt m basename prog machines dependencies; + + close_out source_mauve_out; + end + )); + (* Makefiles: - for the moment two cases diff --git a/src/backends/C/c_backend_common.ml b/src/backends/C/c_backend_common.ml index 803b426e..a8aa3b25 100644 --- a/src/backends/C/c_backend_common.ml +++ b/src/backends/C/c_backend_common.ml @@ -125,7 +125,7 @@ let is_basic_c_type t = | _ -> false let pp_c_basic_type_desc t_dsec = - match (t_dsec) with + match t_dsec with | Types.Tbool when !Options.cpp -> "bool" | Types.Tbool -> "_Bool" | Types.Tint -> !Options.int_type diff --git a/src/backends/C/c_backend_mauve.ml b/src/backends/C/c_backend_mauve.ml new file mode 100644 index 00000000..29797592 --- /dev/null +++ b/src/backends/C/c_backend_mauve.ml @@ -0,0 +1,169 @@ +open LustreSpec +open Corelang +open Machine_code +open Format +open C_backend_common +open Utils + +(* module type MODIFIERS_MAINSRC = +sig +end + +module EmptyMod = +struct +end + +module Mauve = functor (Mod: MODIFIERS_MAINSRC) -> +struct +end + *) +(********************************************************************************************) +(* Main related functions *) +(********************************************************************************************) + +let mauve_default_value v = + let v_name = v.var_id in + let v_type = (Types.repr v.var_type).Types.tdesc in + match v_type with + | Types.Tbool -> "false" + | Types.Tint -> "0" + | Types.Treal -> "0.0" + | _ -> assert false + +let shell_name node = node ^ "Shell" +let core_name node = node ^ "Core" +let fsm_name node = node ^ "FSM" + +let print_mauve_header fmt mauve_machine basename prog machines _ (*dependencies*) = + fprintf fmt "#include \"mauve/runtime.hpp\"@."; + print_import_alloc_prototype fmt (Dep (true, basename, [], true (* assuming it is stateful*) )); + pp_print_newline fmt (); + pp_print_newline fmt () + + +let print_mauve_shell fmt mauve_machine basename prog machines _ (*dependencies*) = + let node_name = mauve_machine.mname.node_id in + + fprintf fmt "/*@."; + fprintf fmt " * SHELL@."; + fprintf fmt " */@."; + + fprintf fmt "struct %s: public Shell {@." (shell_name node_name); + + (* in ports *) + fprintf fmt "\t// InputPorts@."; + List.iter + (fun v -> + let v_name = v.var_id in + let v_type = pp_c_basic_type_desc (Types.repr v.var_type).Types.tdesc in + let default = mauve_default_value v in + fprintf fmt "\tReadPort<%s> port_%s = mk_readPort<%s>(\"%s\", %s);@." v_type v_name v_type v_name default; + ) mauve_machine.mstep.step_inputs; + (* out ports *) + fprintf fmt "\t// OutputPorts@."; + List.iter + (fun v -> + let v_name = v.var_id in + let v_type = pp_c_basic_type_desc (Types.repr v.var_type).Types.tdesc in + fprintf fmt "\tWritePort<%s> port_%s = mk_writePort<%s>(\"%s\");@." v_type v_name v_type v_name; + ) mauve_machine.mstep.step_outputs; + + fprintf fmt "};@."; + + pp_print_newline fmt () + +let print_mauve_step fmt node_name mauve_machine = + fprintf fmt "\t\t%s_step(" node_name; + List.iter + (fun v -> + let v_name = v.var_id in + fprintf fmt "%s, " v_name; + ) mauve_machine.mstep.step_inputs; + List.iter + (fun v -> + let v_name = v.var_id in + fprintf fmt "&%s, " v_name; + ) mauve_machine.mstep.step_outputs; + fprintf fmt "node"; + fprintf fmt ");@." + +let print_mauve_core fmt mauve_machine basename prog machines _ (*dependencies*) = + let node_name = mauve_machine.mname.node_id in + + fprintf fmt "/*@."; + fprintf fmt " * CORE@."; + fprintf fmt " */@."; + + fprintf fmt "struct %s: public Core<%s> {@." (core_name node_name) (shell_name node_name); + + (* Attribute *) + fprintf fmt "\tstruct %s_mem * node;@." node_name; + pp_print_newline fmt (); + (* Update *) + fprintf fmt "\tvoid update() {@."; + List.iter + (fun v -> + let v_name = v.var_id in + let v_type = pp_c_basic_type_desc (Types.repr v.var_type).Types.tdesc in + fprintf fmt "\t\t%s %s = port_%s.read();@." v_type v_name v_name; + ) mauve_machine.mstep.step_inputs; + List.iter + (fun v -> + let v_name = v.var_id in + let v_type = pp_c_basic_type_desc (Types.repr v.var_type).Types.tdesc in + fprintf fmt "\t\t%s %s;@." v_type v_name; + ) mauve_machine.mstep.step_outputs; + print_mauve_step fmt node_name mauve_machine; + List.iter + (fun v -> + let v_name = v.var_id in + fprintf fmt "\t\tport_%s.write(%s);@." v_name v_name; + ) mauve_machine.mstep.step_outputs; + fprintf fmt "\t}@."; + pp_print_newline fmt (); + (* Configure *) + fprintf fmt "\tbool configure_hook() override {@."; + fprintf fmt "\t\tnode = %s_alloc();@." node_name; + fprintf fmt "\t\t%s_reset(node);@." node_name; + fprintf fmt "\t\treturn true;@."; + fprintf fmt "\t}@."; + pp_print_newline fmt (); + (* Cleanup *) + fprintf fmt "\tvoid cleanup_hook() override {@."; + fprintf fmt "\t\t%s_reset(node);@." node_name; + fprintf fmt "\t\tfree(node);@."; + fprintf fmt "\t}@."; + fprintf fmt "};@."; + pp_print_newline fmt () + + +let print_mauve_fsm fmt mauve_machine basename prog machines _ (*dependencies*) = + let node_name = mauve_machine.mname.node_id in + + fprintf fmt "/*@."; + fprintf fmt " * FSM@."; + fprintf fmt " */@."; + + fprintf fmt "struct %s: public FiniteStateMachine<%s, %s> {@." (fsm_name node_name) (shell_name node_name) (core_name node_name); + + (* Attribute *) + fprintf fmt "\tExecState<%s> & update = mk_execution (\"Update\" , &%s::update);@." (core_name node_name) (core_name node_name); + fprintf fmt "\tSynchroState<%s> & synchro = mk_synchronization(\"Synchro\", ms_to_ns(100));@." (core_name node_name); + pp_print_newline fmt (); + (* Configure *) + fprintf fmt "\tbool configure_hook() override {@."; + fprintf fmt "\t\tset_initial(update);@."; + fprintf fmt "\t\tset_next(update, synchro);@."; + fprintf fmt "\t\tset_next(synchro, update);@."; + fprintf fmt "\t\treturn true;@."; + fprintf fmt "\t}@."; + pp_print_newline fmt (); + (* Cleanup *) + fprintf fmt "\tvoid cleanup_hook() override {@."; + fprintf fmt "\t}@."; + fprintf fmt "};@."; + pp_print_newline fmt () + +(* Local Variables: *) +(* compile-command:"make -C ../../.." *) +(* End: *) diff --git a/src/options.ml b/src/options.ml index 98d684e6..b678d85a 100755 --- a/src/options.ml +++ b/src/options.ml @@ -55,6 +55,8 @@ let cpp = ref false let int_type = ref "int" let real_type = ref "double" +let mauve = ref "" + let sfunction = ref "" let set_mpfr prec = @@ -98,6 +100,8 @@ let options = "-c++" , Arg.Set cpp , "c++ backend"; "-int" , Arg.Set_string int_type , "specifies the integer type (default=\"int\")"; "-real", Arg.Set_string real_type, "specifies the real type (default=\"double\" without mpfr option)"; + + "-mauve", Arg.String (fun node -> mauve := node; cpp := true; static_mem := false), "generates the mauve code"; ] -- GitLab