Commit 099b58d1 authored by Guillem's avatar Guillem
Browse files

Dualcore setup & area synth

include RTL and software changes to run multicore SIMULATIONS with pmu, no FPGA tested. Includes yosys scripts for area calculation
parent 4e60307f
......@@ -53,6 +53,9 @@
input wire EV13_i ,// signal
input wire EV14_i ,// signal
input wire EV15_i ,// signal
input wire EV16_i ,// signal
input wire EV17_i ,// signal
input wire EV18_i ,// signal
//outputs
output wire int_overflow_o,
......@@ -62,13 +65,87 @@
output wire int_quota_c0_o,
output wire int_quota_c1_o
);
localparam integer N_COUNTERS = 16;
//Different configurations to get are usage
`ifdef YOSYS_1
localparam integer N_COUNTERS = 19;
// Configuration registers
localparam integer N_CONF_REGS = 5;
localparam N_CORES = 1;
localparam OVERFLOW = 1;
localparam QUOTA= 1;
localparam MCCU= 1;
`elsif YOSYS_2
localparam integer N_COUNTERS = 19;
// Configuration registers
localparam integer N_CONF_REGS = 5;
localparam N_CORES = 2;
localparam OVERFLOW = 1;
localparam QUOTA= 1;
localparam MCCU= 1;
`elsif YOSYS_3
localparam integer N_COUNTERS = 19;
// Configuration registers
localparam integer N_CONF_REGS = 5;
localparam N_CORES = 3;
localparam OVERFLOW = 1;
localparam QUOTA= 1;
localparam MCCU= 1;
`elsif YOSYS_4
localparam integer N_COUNTERS = 19;
// Configuration registers
localparam integer N_CONF_REGS = 5;
localparam N_CORES = 4;
localparam OVERFLOW = 1;
localparam QUOTA= 1;
localparam MCCU= 1;
`elsif YOSYS_5
localparam integer N_COUNTERS = 19;
// Configuration registers
localparam integer N_CONF_REGS = 5;
localparam N_CORES = 1;
localparam OVERFLOW = 0;
localparam QUOTA= 0;
localparam MCCU= 0;
`elsif YOSYS_6
localparam integer N_COUNTERS = 19;
// Configuration registers
localparam integer N_CONF_REGS = 5;
localparam N_CORES = 1;
localparam OVERFLOW = 1;
localparam QUOTA= 0;
localparam MCCU= 0;
`elsif YOSYS_7
localparam integer N_COUNTERS = 19;
// Configuration registers
localparam integer N_CONF_REGS = 5;
localparam N_CORES = 1;
localparam OVERFLOW = 0;
localparam QUOTA= 1;
localparam MCCU= 0;
`elsif YOSYS_8
localparam integer N_COUNTERS = 19;
// Configuration registers
localparam integer N_CONF_REGS = 5;
localparam N_CORES = 1;
localparam OVERFLOW = 0;
localparam QUOTA= 0;
localparam MCCU= 1;
`else
localparam integer N_COUNTERS = 19;
// Configuration registers
localparam integer N_CONF_REGS = 5;
localparam N_CORES = 2;
localparam OVERFLOW = 1;
localparam QUOTA= 1;
localparam MCCU= 1;
`endif
wire [N_COUNTERS-1:0] events_i;
// Assign individual signals to packed array
assign events_i= { EV15_i,
assign events_i= {
EV18_i,
EV17_i,
EV16_i,
EV15_i,
EV14_i,
EV13_i,
EV12_i,
......@@ -85,7 +162,6 @@
EV1_i,
EV0_i
};
localparam N_CORES = 2;
wire MCCU_int_o [N_CORES-1:0];
//TODO: MCCU_int_o is not assigned parametrically
//A pack array will look better. Consider chang it on the MCCU
......@@ -99,10 +175,10 @@
.C_S_AXI_ADDR_WIDTH(C_S_AXI_ADDR_WIDTH),
.N_COUNTERS(N_COUNTERS),
.N_CONF_REGS(N_CONF_REGS),
.OVERFLOW(1), //No
.QUOTA(1), //No
.MCCU(1), //Yes
.N_CORES(2)
.OVERFLOW(OVERFLOW), //No
.QUOTA(QUOTA), //No
.MCCU(MCCU), //Yes
.N_CORES(N_CORES)
) inst_AXI_PMU (
.*
/* .S_AXI_ACLK_i(S_AXI_ACLK_i),
......
......@@ -161,7 +161,7 @@
end else begin
//if the unit has been reseted in current or previous cycle
for (i=0; i<N_CORES; i=i+1) begin : AssertionsQuotaReset
assert(quota_int[i] == {DATA_WIDTH{1'b0}});
assert(quota_int[i] == {DATA_WIDTH{1'b1}});
end
end
`endif
......
How to run synthesis?
===============
In order to do the synthesis of this module you need installed:
Yosys -> http://www.clifford.at/yosys/
Verific -> http://www.clifford.at/yosys/
FreePDK45 -> https://www.eda.ncsu.edu/wiki/FreePDK45:Contents#Current_Version
Verific can be obtained for free through the sby package granted to BSC.
https://symbiyosys.readthedocs.io/en/latest/
All the paths in the .ys files containing the falg -liberty have the absolute
path to the liberty files of the pdk that we are using. Since this paths are
hardcoded you will need to set yours manually. it shall be replaced by a system
variable in the future.
#Name of the report follows this format
# Q: Quota on
# O: Overflow on
# M: MCCU on
# NC: Number of counters
# NCFG: Number configuration registers
# C: Number of cores
echo "Starting synth in parallel of the different test cases"
echo "This use to take between 1 and 3 minutes"
echo "Area for FreePDK45 is reported in square micrometers"
echo "0/8 runs done"
#`ifdef YOSYS_1
# localparam integer N_COUNTERS = 19;
# // Configuration registers
# localparam integer N_CONF_REGS = 5;
# localparam N_CORES = 1;
# localparam OVERFLOW = 1;
# localparam QUOTA= 1;
# localparam MCCU= 1;
yosys -D YOSYS_1 yosys_45.ys > ./logs/QOM_NC19-NCFG5-C1.log &
#`elsif YOSYS_2
# localparam integer N_COUNTERS = 19;
# // Configuration registers
# localparam integer N_CONF_REGS = 5;
# localparam N_CORES = 2;
# localparam OVERFLOW = 1;
# localparam QUOTA= 1;
# localparam MCCU= 1;
yosys -D YOSYS_2 yosys_45.ys > ./logs/QOM_NC19-NCFG5-C2.log &
#`elsif YOSYS_3
# localparam integer N_COUNTERS = 19;
# // Configuration registers
# localparam integer N_CONF_REGS = 5;
# localparam N_CORES = 3;
# localparam OVERFLOW = 1;
# localparam QUOTA= 1;
# localparam MCCU= 1;
yosys -D YOSYS_3 yosys_45.ys > ./logs/QOM_NC19-NCFG5-C3.log &
#`elsif YOSYS_4
# localparam integer N_COUNTERS = 19;
# // Configuration registers
# localparam integer N_CONF_REGS = 5;
# localparam N_CORES = 4;
# localparam OVERFLOW = 1;
# localparam QUOTA= 1;
# localparam MCCU= 1;
yosys -D YOSYS_4 yosys_45.ys > ./logs/QOM_NC19-NCFG5-C4.log
echo "4/8 runs done"
#`elsif YOSYS_5
# localparam integer N_COUNTERS = 19;
# // Configuration registers
# localparam integer N_CONF_REGS = 5;
# localparam N_CORES = 1;
# localparam OVERFLOW = 0;
# localparam QUOTA= 0;
# localparam MCCU= 0;
yosys -D YOSYS_5 yosys_45.ys > ./logs/NC19-NCFG5-C1.log &
#`elsif YOSYS_6
# localparam integer N_COUNTERS = 19;
# // Configuration registers
# localparam integer N_CONF_REGS = 5;
# localparam N_CORES = 1;
# localparam OVERFLOW = 1;
# localparam QUOTA= 0;
# localparam MCCU= 0;
yosys -D YOSYS_6 yosys_45.ys > ./logs/O_NC19-NCFG5-C1.log &
#`elsif YOSYS_7
# localparam integer N_COUNTERS = 19;
# // Configuration registers
# localparam integer N_CONF_REGS = 5;
# localparam N_CORES = 1;
# localparam OVERFLOW = 0;
# localparam QUOTA= 1;
# localparam MCCU= 0;
yosys -D YOSYS_7 yosys_45.ys > ./logs/Q_NC19-NCFG5-C1.log &
#`elsif YOSYS_8
# localparam integer N_COUNTERS = 19;
# // Configuration registers
# localparam integer N_CONF_REGS = 5;
# localparam N_CORES = 1;
# localparam OVERFLOW = 0;
# localparam QUOTA= 0;
# localparam MCCU= 1;
yosys -D YOSYS_8 yosys_45.ys > ./logs/M_NC19-NCFG5-C1.log
wait
echo "8/8 runs done"
echo "Done! Reporting area & cycle time"
cd logs
ack "Chip area for top module "
ack "Delay "
cd ..
set_driving_cell INVX1
set_load 0.015
#read file
verific -sv ../hdl/AXI_PMU.sv
verific -sv ../hdl/AXI_PMU_interface_v1_0_S00_AXI.sv
verific -sv ../submodules/MCCU/hdl/MCCU.sv
verific -import AXI_PMU
prep -top AXI_PMU
#high-level
proc; opt; fsm; opt; memory; opt
#internal cell library
techmap; opt
#mapping flip-flops to mycells.lib
#TODO: Replace absolute path libraries by a variable
dfflibmap -liberty /home/bscuser/PDK_opensource/NCSU-FreePDK45-1.4/ncsu-FreePDK45-1.4/FreePDK45/osu_soc/lib/files/gscl45nm.lib
#mapping logic to mycells.lib
#abc -liberty mycells.lib
#TODO: Replace absolute path libraries by a variable
abc -D 10 -constr synth.constr -liberty /home/bscuser/PDK_opensource/NCSU-FreePDK45-1.4/ncsu-FreePDK45-1.4/FreePDK45/osu_soc/lib/files/gscl45nm.lib
#get area
#TODO: Replace absolute path libraries by a variable
stat -liberty /home/bscuser/PDK_opensource/NCSU-FreePDK45-1.4/ncsu-FreePDK45-1.4/FreePDK45/osu_soc/lib/files/gscl45nm.lib
#cleanup
clean
#write synthsized design
write_verilog synth.v
......@@ -94,6 +94,9 @@ module tb_AXI_PMU();
reg tb_EV13_i;
reg tb_EV14_i;
reg tb_EV15_i;
reg tb_EV16_i;
reg tb_EV17_i;
reg tb_EV18_i;
wire int_overflow_o;
wire int_quota_o;
wire int_quota_c0_o;
......@@ -186,6 +189,9 @@ module tb_AXI_PMU();
.EV13_i (tb_EV13_i),
.EV14_i (tb_EV14_i),
.EV15_i (tb_EV15_i),
.EV16_i (tb_EV16_i),
.EV17_i (tb_EV17_i),
.EV18_i (tb_EV18_i),
.int_overflow_o (int_overflow_o),
.int_quota_o(int_quota_o),
.int_quota_c0_o(int_quota_c0_o),
......@@ -555,8 +561,10 @@ task automatic init_sim;
);
value = tb_r_data;
if (up2!=dut_AXI_PMU.inst_AXI_PMU.slv_reg[r_addr>>2]) begin
`START_RED_PRINT
$error("FAIL all_counters. Register %d has captured %h \
events instead of expected %h", r_addr>2,dut_AXI_PMU.inst_AXI_PMU.slv_reg[r_addr>>2], up2);
`END_COLOR_PRINT
tmp=1;
end
end
......@@ -580,19 +588,21 @@ task automatic init_sim;
.delay(4)
);
value = tb_r_data;
up2 ='hffff;
up2 ='h7ffff;// Depends on the nº of counters
if (dut_AXI_PMU.inst_AXI_PMU.slv_reg[base_overflow>>2]!=up2) begin
`START_RED_PRINT
$error("FAIL all_counters. Overflow register %d has captured %h \
interrupts instead of expected %h", base_overflow>2
,dut_AXI_PMU.inst_AXI_PMU.slv_reg[base_overflow>>2], up2);
`END_COLOR_PRINT
tmp=1;
end
if(int_overflow_o != 1'b1)
$error("Overflow Interrupt has not been risen");
if(tmp==0)
`START_GREEN_PRINT
$display("PASS overflow_counters.");
$display("PASS all_counters.");
$display("PASS overflow_counters.");
$display("PASS all_counters.");
`END_COLOR_PRINT
end
......@@ -616,6 +626,9 @@ task automatic init_sim;
tb_EV13_i=1;
tb_EV14_i=1;
tb_EV15_i=1;
tb_EV16_i=1;
tb_EV17_i=1;
tb_EV18_i=1;
end
endtask
......@@ -638,6 +651,9 @@ task automatic init_sim;
tb_EV13_i=0;
tb_EV14_i=0;
tb_EV15_i=0;
tb_EV16_i=0;
tb_EV17_i=0;
tb_EV18_i=0;
end
endtask
......
......@@ -55,8 +55,35 @@ add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/generate_MCCU/inst_MCCU/
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/generate_MCCU/inst_MCCU/WEIGHTS_WIDTH
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/generate_MCCU/MCCU_events_weights_int
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/generate_MCCU/weights_flat_bitarray
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/C_S_AXI_DATA_WIDTH
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/C_S_AXI_ADDR_WIDTH
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/N_COUNTERS
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/N_CONF_REGS
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/OVERFLOW
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/QUOTA
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/MCCU
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/N_CORES
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/ADDR_LSB
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/OPT_MEM_ADDR_BITS
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/N_OVERFLOW_REGS
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/N_QUOTA_MASK
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/N_QUOTA_LIMIT
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/BASE_QUOTA
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/BASE_MCCU
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/MCCU_DATA_WIDTH
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/MCCU_WEIGHTS_WIDTH
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/MCCU_N_CORES
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/MCCU_CORE_EVENTS
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/MCCU_WEIGHTS_REGS
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/MCCU_REGS
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/MCCU_R_REGS
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/MCCU_RW_REGS
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/BASE_MCCU_R_ONLY
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/R_ONLY_REGS
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/RW_REGS
add wave -noupdate /tb_AXI_PMU/dut_AXI_PMU/inst_AXI_PMU/TOTAL_REGS
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {1766058 ps} 0}
WaveRestoreCursors {{Cursor 1} {1764651 ps} 0}
quietly wave cursor active 1
configure wave -namecolwidth 506
configure wave -valuecolwidth 241
......
*~
*.riscv
*.host
*.o
*.dump
*.out
*.hex
.*.swp
autom4te.cache
prefix := @prefix@
abs_top_src_dir := @abs_top_srcdir@
instbasedir := $(DESTDIR)$(prefix)
bmarkdir := $(abs_top_src_dir)/programs
isa_src_dir := $(abs_top_src_dir)/isa
all: programs isa
install: all
install -p -m 644 *.hex $(instbasedir)/share/riscv-tests
programs:
$(MAKE) -f $(bmarkdir)/Makefile bmarkdir=$(bmarkdir)
isa:
$(MAKE) -f $(isa_src_dir)/Makefile isa_src_dir=$(isa_src_dir)
.PHONY: programs isa
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.68 for riscv-tests 1.0.
#
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
# Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##
# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
NULLCMD=:
# Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
# is contrary to our usage. Disable this feature.
alias -g '${1+"$@"}'='"$@"'
setopt NO_GLOB_SUBST
else
case `(set -o) 2>/dev/null` in #(
*posix*) :
set -o posix ;; #(
*) :
;;
esac
fi
as_nl='
'
export as_nl
# Printing a long string crashes Solaris 7 /usr/bin/printf.
as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
# Prefer a ksh shell builtin over an external printf program on Solaris,
# but without wasting forks for bash or zsh.
if test -z "$BASH_VERSION$ZSH_VERSION" \
&& (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
as_echo='print -r --'
as_echo_n='print -rn --'
elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
as_echo='printf %s\n'
as_echo_n='printf %s'
else
if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
as_echo_n='/usr/ucb/echo -n'
else
as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
as_echo_n_body='eval
arg=$1;
case $arg in #(
*"$as_nl"*)
expr "X$arg" : "X\\(.*\\)$as_nl";
arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
esac;
expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
'
export as_echo_n_body
as_echo_n='sh -c $as_echo_n_body as_echo'
fi
export as_echo_body
as_echo='sh -c $as_echo_body as_echo'
fi
# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
PATH_SEPARATOR=:
(PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
(PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
PATH_SEPARATOR=';'
}
fi
# IFS
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent editors from complaining about space-tab.
# (If _AS_PATH_WALK were called with IFS unset, it would disable word
# splitting by setting IFS to empty value.)
IFS=" "" $as_nl"
# Find who we are. Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
*[\\/]* ) as_myself=$0 ;;
*) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
done
IFS=$as_save_IFS
;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
as_myself=$0
fi
if test ! -f "$as_myself"; then
$as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
exit 1
fi
# Unset variables that we do not need and which cause bugs (e.g. in
# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
# suppresses any "Segmentation fault" message there. '((' could
# trigger a bug in pdksh 5.2.14.
for as_var in BASH_ENV ENV MAIL MAILPATH
do eval test x\${$as_var+set} = xset \
&& ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done
PS1='$ '
PS2='> '
PS4='+ '
# NLS nuisances.
LC_ALL=C
export LC_ALL
LANGUAGE=C
export LANGUAGE
# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
if test "x$CONFIG_SHELL" = x; then
as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
NULLCMD=:
# Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
# is contrary to our usage. Disable this feature.
alias -g '\${1+\"\$@\"}'='\"\$@\"'
setopt NO_GLOB_SUBST
else
case \`(set -o) 2>/dev/null\` in #(
*posix*) :
set -o posix ;; #(
*) :
;;
esac
fi
"
as_required="as_fn_return () { (exit \$1); }
as_fn_success () { as_fn_return 0; }
as_fn_failure () { as_fn_return 1; }
as_fn_ret_success () { return 0; }
as_fn_ret_failure () { return 1; }
exitcode=0
as_fn_success || { exitcode=1; echo as_fn_success failed.; }
as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
else
exitcode=1; echo positional parameters were not saved.
fi
test x\$exitcode = x0 || exit 1"
as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1"
if (eval "$as_required") 2>/dev/null; then :
as_have_required=yes
else
as_have_required=no
fi
if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
as_found=false
for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
as_found=:
case $as_dir in #(
/*)
for as_base in sh bash ksh sh5; do
# Try only shells that exist, to save several forks.
as_shell=$as_dir/$as_base
if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&