diff --git a/src/soc2c.ml b/src/soc2c.ml index 5d30ee3337577d1b473fb5840fd4d691f872a5eb..a6db91949142a69a8b31a72e7c0bac5909e2d889 100644 --- a/src/soc2c.ml +++ b/src/soc2c.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 13/05/2015 (at 09:38) by Erwan Jahier> *) +(* Time-stamp: <modified the 11/09/2015 (at 11:22) by Erwan Jahier> *) (* let put (os: out_channel) (fmt:('a, unit, string, unit) format4) : 'a = *) @@ -440,8 +440,8 @@ let (gen_loop_file : Soc.t -> out_channel -> Soc.tbl -> unit) = let (n,_,_) = soc.key in let n = id2s n in let inputs,outputs = soc.profile in - let inputs_io = SocVar.expand_profile true false inputs in - let outputs_io = SocVar.expand_profile true false outputs in + let inputs_io = SocVar.expand_profile true false inputs in + let outputs_io = SocVar.expand_profile true false outputs in let inputs_exp = SocVar.expand_profile true true inputs in let outputs_exp= SocVar.expand_profile true true outputs in Lv6util.entete oc "/*" "*/"; @@ -635,45 +635,144 @@ int main(){ } " + +let (gen_loop_file4ogensim : Soc.t -> out_channel -> Soc.tbl -> unit) = + fun soc oc stbl -> + let base = (string_of_soc_key soc.key) in + let putc s = output_string oc s in + let ctx = get_ctx_name soc.key in + let step = Soc2cDep.step_name soc.key "step" in + let (n,_,_) = soc.key in + let n = id2s n in + let inputs,outputs = soc.profile in + let inputs_io = SocVar.expand_profile true false inputs in + let outputs_io = SocVar.expand_profile true false outputs in + let inputs_exp = SocVar.expand_profile true true inputs in + let outputs_exp= SocVar.expand_profile true true outputs in + let define_define i (var_name,_) = + putc (Printf.sprintf "#define _%s\t 0xe%07X\n" var_name ((i+1)*8)); + in + Lv6util.entete oc "/*" "*/"; + + putc ("#include \""^base ^".h\" + +#define tickBegin 0xe0000000 +"); + List.iteri define_define (inputs_io@ outputs_io); + + + putc ( + "/* Main procedure *************************/ +int main(){" ^ ( + match io_transmit_mode () with + | Lv6MainArgs.Stack -> + let to_c_decl (n,t) = ((Soc2cUtil.data_type_to_c t n)^ ";\n ") in + let inputs_t = List.map to_c_decl inputs in + let outputs_t = List.map to_c_decl outputs in + let inputs_decl = Printf.sprintf "\n %s" (String.concat "" inputs_t) in + let outputs_decl = Printf.sprintf "%s" (String.concat "" outputs_t) in + let ctx_decl = if SocUtils.is_memory_less soc then "" else + ctx^"_type* ctx = "^ ctx^"_new_ctx(NULL);\n" + in + inputs_decl ^ outputs_decl ^ ctx_decl + | Lv6MainArgs.Heap -> (" + /* Context allocation */ + " ^ (if SocUtils.is_memory_less soc then ctx^"_type* ctx = &"^ctx^";\n" + else ctx^"_type* ctx = "^ ctx^"_new_ctx(NULL);") + ) + | Lv6MainArgs.HeapStack -> (" +/* Context allocation */ + " ^ (if SocUtils.is_memory_less soc then ctx^"" + else ctx^"_type* ctx ;\n"^ ctx^"_reset(ctx);") + ) + )); + let to_rif_decl (n,t) = ("\\\""^n^"\\\":" ^(type_to_string t)) in + let inputs_t = List.map to_rif_decl inputs_io in + let outputs_t = List.map to_rif_decl outputs_io in + let inputs_decl = Printf.sprintf "#inputs %s" (String.concat " " inputs_t) in + let outputs_decl = Printf.sprintf "#outputs %s" (String.concat " " outputs_t) in + + putc (" + /* Main loop */ + while(1){ + // notify the simulator that it is time to load the inputs from Lurette + // to the specified address + *((unsigned int*)tickBegin) = 0; + // load inputs from the memory locations +"); + List.iter2 + (fun (id,t) (id_flat,_) -> + let t = Soc2cUtil.data_type_to_c t "" in + let str = + Printf.sprintf " %s = *((%s*)_%s);\n" id t id_flat + in + putc str + ) + inputs_exp inputs_io; + + assert (io_transmit_mode () = Lv6MainArgs.Stack); + + let i = fst (List.split inputs) in + let o = List.map (fun (n,t) -> match t with Data.Array(_,_) -> n | _ ->"&"^n) outputs in + let io = String.concat "," (i@o) in + let io = if SocUtils.is_memory_less soc then io else if io = "" then "ctx" else io^",ctx" in + putc (" " ^ step^"("^io^"); + + // now write the output to the memory which will be output to Lurette +"); + List.iter2 + (fun (id,t) (id_flat,_) -> + let t = Soc2cUtil.data_type_to_c t "" in + let str = Printf.sprintf " *((%s*)_%s) = %s;\n" t id id_flat in + putc str + ) + outputs_io outputs_exp; + + putc "}\n return 1; +} +" + (****************************************************************************) (* The entry point for lus2lic --to-c *) let (f : Lv6MainArgs.t -> Soc.key -> Soc.tbl -> LicPrg.t -> unit) = fun args msoc stbl licprg -> - let socs = Soc.SocMap.bindings stbl in - let socs = snd (List.split socs) in - (* XXX que fait-on pour les soc predef ? *) - (* let _, socs = List.partition is_predef socs in *) - let base = - if args.Lv6MainArgs.outfile = "" then - string_of_soc_key msoc + let socs = Soc.SocMap.bindings stbl in + let socs = snd (List.split socs) in + (* XXX que fait-on pour les soc predef ? *) + (* let _, socs = List.partition is_predef socs in *) + let base = + if args.Lv6MainArgs.outfile = "" then + string_of_soc_key msoc else - Filename.basename ( + Filename.basename ( try Filename.chop_extension args.Lv6MainArgs.outfile with Invalid_argument _ -> args.Lv6MainArgs.outfile) - in - let hfile = base ^ ".h" in - let cfile = base ^ ".c" in - let ext_cfile = Printf.sprintf "%s_ext.c" base in - let ext_hfile = Printf.sprintf "%s_ext.h" base in - let loopfile = base^"_loop.c" in - let occ = open_out cfile in - let och = open_out hfile in - let ocl = open_out loopfile in - try - let putc s = output_string occ s in - let puth s = output_string och s in - let main_soc = Soc.SocMap.find msoc stbl in + in + let hfile = base ^ ".h" in + let cfile = base ^ ".c" in + let ext_cfile = Printf.sprintf "%s_ext.c" base in + let ext_hfile = Printf.sprintf "%s_ext.h" base in + let loopfile = base^"_loop.c" in + let occ = open_out cfile in + let och = open_out hfile in + let ocl = open_out loopfile in + try + let putc s = output_string occ s in + let puth s = output_string och s in + let main_soc = Soc.SocMap.find msoc stbl in (* Generate ext files if necessary *) - let needs_cfile, needs_hfile = - Soc2cExtern.gen_files main_soc stbl licprg ext_cfile ext_hfile hfile - in - - Lv6util.entete occ "/*" "*/" ; - Lv6util.entete och "/*" "*/"; + let needs_cfile, needs_hfile = + Soc2cExtern.gen_files main_soc stbl licprg ext_cfile ext_hfile hfile + in + Lv6util.entete occ "/*" "*/" ; + Lv6util.entete och "/*" "*/"; + if args.Lv6MainArgs.gen_wcet then + gen_loop_file4ogensim main_soc ocl stbl + else gen_loop_file main_soc ocl stbl; - if args.Lv6MainArgs.gen_wcet then gen_main_wcet_file main_soc base stbl; - - output_string och " + if args.Lv6MainArgs.gen_wcet then gen_main_wcet_file main_soc base stbl; + + output_string och " #include <stdlib.h> #include <string.h> @@ -723,32 +822,105 @@ typedef float _float; Printf.printf "%s has been generated.\n" hfile; Printf.printf "%s has been generated.\n" cfile; flush stdout; - let execfile = if args.Lv6MainArgs.outfile = "" then "a.out" + let node = args.main_node in + let execfile = if args.Lv6MainArgs.outfile = "" then (node^"4otawa.out") else args.Lv6MainArgs.outfile in let cflags = try Sys.getenv "CFLAGS" with Not_found -> "" in - let main_file,gcc = - if args.Lv6MainArgs.gen_wcet then base^"_main.c","arm-elf-gcc -g" else loopfile,"gcc" + let ocsh = open_out (node ^".sh") in + let main_file, ogensim_main_file, gcc = + if args.Lv6MainArgs.gen_wcet then + base^"_main.c",base^"_loop.c","arm-elf-gcc --specs=linux.specs -g" + else + loopfile, "I am a dead string...", "gcc" in - let gcc = + let ogensim_exe = node^"4ogensim.out" in + let gcc, gcc_ogensim = if needs_cfile then - Printf.sprintf "%s -o %s %s %s %s %s" gcc execfile cfile cflags ext_cfile main_file + Printf.sprintf "%s -o %s \\\n\t%s %s %s %s" gcc execfile cfile cflags ext_cfile main_file, + Printf.sprintf "%s -o %s \\\n\t%s %s %s %s" gcc ogensim_exe cfile cflags + ext_cfile ogensim_main_file else - Printf.sprintf "%s -o %s %s %s %s" gcc execfile cfile cflags main_file - in - let main_step = (string_of_soc_key msoc)^"_step" in + Printf.sprintf "%s -o %s \\\n\t%s %s %s" gcc execfile cfile cflags main_file, + Printf.sprintf "%s -o %s \\\n\t%s %s %s" gcc ogensim_exe cfile cflags ogensim_main_file + in let main_step = (string_of_soc_key msoc)^"_step" in let gcc = if args.Lv6MainArgs.gen_wcet then - (gcc ^ " > owcet.out; owcet.arm "^execfile^ " " ^ - (* " --add-prop otawa::ilp::OUTPUT_PATH="^main_step^".0.lp "^ *) - main_step^" 2>&1 | grep WCET") + ("#!/bin/bash +set -x + +otawa=\"true\" +ogensim=\"true\" +xpdf=\"true\" + +if [ $# -gt 0 ] + then + case \"$1\" in + \"otawa\") + otawa=\"true\" + ogensim=\"false\" + xpdf=\"false\" + ;; + \"ogensim\") + otawa=\"false\" + ogensim=\"true\" + xpdf=\"false\" + ;; + esac +fi +cfile="^cfile^ " +execfile="^execfile^ " +main_step="^main_step^ " +n="^node^ " +n_n="^base ^ " +freeport=`python -c 'import socket; s=socket.socket(); s.bind((\"\", 0)); print(s.getsockname()[1]); s.close()'` +if [ \"$otawa\" = \"true\" ] +then +# ZZZ otawa won't work with programs that use division because of orange (!?) +# Let's compile the c files for otawa\n" ^ + gcc ^ " > \\\n\t$n_n.owcet.log 2>&1 &&\n\n"^ + "orange $cfile ${n_n}_step -o $n_n.ffx > $n_n.orange.log 2>&1 &&\n" ^ + "# Let's run otawa (owcet.arm)\n" ^ + "owcet.arm $execfile $main_step -f $n_n.ffx \\\n\t>"^ + "$n_n.owcet.arm.log 2>&1 && \n"^ + "grep WCET $n_n.owcet.arm.log | cut -d \" \" -f 3 > "^ + "$n.wcet &&\n\n" ^ + "WCET=`cat $n.wcet` \n\n" ^ + "# Let's compile the c files for ogensim \n" ^ + " +fi +if [ \"$ogensim\" = \"true\" ] +then +# Now let's run ogensim \n(" ^ + gcc_ogensim ^ " >>$n_n.owcet.log 2>&1 &&\n"^ + "lus2lic "^(String.concat " " args.infiles)^" -n $n"^ + " -interface > $n.io &&\n"^ + "lus2lic "^(String.concat " " args.infiles)^" -n $n --gen-autotest &&\n\n"^ + "# Now let's run ogensim \n" ^ + "(ogensim.arm "^ogensim_exe^" -ul 1 \\\n\t-e $main_step"^ + " -cl $n.cycles -lp $freeport \\\n\t-iol $n.io > $n_n"^ + ".ogensim.log 2>&1&) && \n\nsleep 1 &&\n"^ + "(lurettetop -l 1000 -go -ns2c -o ogensim.rif \\\n\t \ + -rp \"sut:socket:127.0.0.1:$freeport:\" \\\n\t \ + -rp \"env:lutin:_${n}_env.lut:${n}_env\" || true)) &&\n\n"^ + "getstat.r $n.cycles $WCET +fi +if [ \"$xpdf\" = \"true\" ] +then + xpdf $n.cycles.pdf & +fi +" + ) else gcc in + output_string ocsh (gcc^"\n\n"); + flush ocsh; + close_out ocsh; + let call_script = "sh "^node^".sh" in if args.Lv6MainArgs.launch_cc then ( - print_string (gcc^"\n\n"); flush stdout; - if (Sys.command gcc)=0 then () else - print_string ("sys call: '"^gcc^"' failed\n") + if (Sys.command call_script)=0 then () else + print_string ("sys call: '"^call_script^"' failed\n") ) else - print_string ("you can compile those files doing, e.g.,\n "^gcc^"\n"); + print_string ("you can compile those files calling: "^call_script^"\n"); flush stdout with | Delete_C_files ->