153 lines
4.9 KiB
PHP
153 lines
4.9 KiB
PHP
<?php
|
|
|
|
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
|
|
|
|
class LogicFunction
|
|
{
|
|
public array $input_vars;
|
|
public string $verilog_form;
|
|
public string $tex_form;
|
|
|
|
public function __construct(array $input_vars = [], string $verilog_form = "", string $tex_form = "")
|
|
{
|
|
$this->input_vars = $input_vars;
|
|
$this->verilog_form = $verilog_form;
|
|
$this->tex_form = $tex_form;
|
|
}
|
|
|
|
public function getTruthTable(): array {
|
|
$tt = [];
|
|
|
|
$N = count($this->input_vars);
|
|
$M = pow(2, $N);
|
|
|
|
$exp_lang = new ExpressionLanguage();
|
|
|
|
$vars = [];
|
|
foreach ($this->input_vars as $var) {
|
|
$vars[$var] = 0;
|
|
}
|
|
|
|
$cooked_form = str_replace(["&", "|", "~"], ["&&", "||", "!"], $this->verilog_form);
|
|
printf("Cooked: %s\n", $cooked_form);
|
|
|
|
for ($i = 0; $i < $M; $i++) {
|
|
for ($k = 0; $k < $N; $k++) {
|
|
$vars[$this->input_vars[$k]] = (($i >> ($N - $k - 1)) & 1) === 1;
|
|
printf("%d ", $vars[$this->input_vars[$k]]);
|
|
}
|
|
$out = $exp_lang->evaluate($cooked_form, $vars);
|
|
printf("%d\n", $out);
|
|
$tt[] = $out;
|
|
}
|
|
|
|
return $tt;
|
|
}
|
|
|
|
public static function genRandom(array $input_vars, int $min_depth = 2, int $max_depth = 3): LogicFunction
|
|
{
|
|
function genTerm(array $vars, int $ftn, int $tn, int $mind, int $maxd, bool $top = true, int $opindex = 1): array
|
|
{
|
|
$verilog_term = "";
|
|
$tex_term = "";
|
|
$m = max($ftn, random_int(1, $tn));
|
|
if ((($maxd === 0) || ($m === 1)) && ($ftn === 0)) {
|
|
$neg = random_int(0, 1) === 1;
|
|
$var = $vars[array_rand($vars, 1)];
|
|
$verilog_term = ($neg ? "~" : "") . $var;
|
|
$tex_term = $neg ? ("\\overline{" . $var . "}") : $var;
|
|
} else {
|
|
$depth = random_int(0, max(0, $maxd - 1));
|
|
|
|
$verilog_ops = [" & ", " | "];
|
|
$tex_ops = ["", " | "];
|
|
|
|
$verilog_op = $verilog_ops[$opindex];
|
|
$tex_op = $tex_ops[$opindex];
|
|
|
|
$verilog_term = !$top ? "(" : "";
|
|
$tex_term = !$top ? "\\left(" : "";
|
|
|
|
$nextopindex = ($opindex === 0) ? 1 : 0;
|
|
|
|
for ($i = 0; $i < $m; $i++) {
|
|
$term = genTerm($vars, (($mind - 1) > 0) ? $ftn : 0, $tn, $mind - 1, $depth, false, $nextopindex);
|
|
$verilog_term .= $term["verilog"];
|
|
$tex_term .= $term["tex"];
|
|
if ($i < $m - 1) {
|
|
$verilog_term .= $verilog_op;
|
|
$tex_term .= $tex_op;
|
|
}
|
|
}
|
|
$verilog_term .= !$top ? ")" : "";
|
|
$tex_term .= !$top ? "\\right)" : "";
|
|
}
|
|
return ["verilog" => $verilog_term, "tex" => $tex_term];
|
|
}
|
|
|
|
$term = genTerm($input_vars, count($input_vars), count($input_vars), $min_depth, $max_depth);
|
|
|
|
return new LogicFunction($input_vars, $term["verilog"], $term["tex"]);
|
|
|
|
}
|
|
|
|
public static function genRandomDF($input_vars): LogicFunction
|
|
{
|
|
$N = count($input_vars);
|
|
$states = pow(2, $N);
|
|
|
|
$verilog_term = "";
|
|
$tex_term = "";
|
|
for ($i = 0; $i < $states; $i++) {
|
|
|
|
$verilog_inside = "";
|
|
$tex_inside = "";
|
|
|
|
$omit = random_int(0, 1); // omit the variable or not?
|
|
|
|
if (!$omit) {
|
|
for ($j = 0; $j < $N; $j++) {
|
|
$neg = !($i & (1 << $j)); // is it an inverted variable?
|
|
$term = $input_vars[$j];
|
|
if ($neg) {
|
|
$verilog_inside .= "~" . $term;
|
|
$tex_inside .= "\\overline{" . $term . "}";
|
|
} else {
|
|
$verilog_inside .= $term;
|
|
$tex_inside .= $term;
|
|
}
|
|
|
|
if ($j < ($N - 1)) {
|
|
$verilog_inside .= " & ";
|
|
$tex_inside .= "";
|
|
}
|
|
}
|
|
}
|
|
|
|
//$verilog_inside = rtrim($verilog_inside, "&");
|
|
//$tex_inside = rtrim($tex_inside, "\\&");
|
|
|
|
if ($verilog_inside !== "") {
|
|
$verilog_term .= "(";
|
|
$tex_term .= "\\left(";
|
|
|
|
$verilog_term .= $verilog_inside;
|
|
$tex_term .= $tex_inside;
|
|
|
|
$verilog_term .= ")";
|
|
$tex_term .= "\\right)";
|
|
|
|
if (($i < ($states - 1)) && !$omit) {
|
|
$verilog_term .= " | ";
|
|
$tex_term .= " | ";
|
|
}
|
|
}
|
|
}
|
|
|
|
$verilog_term = rtrim($verilog_term, "| ");
|
|
$tex_term = rtrim($tex_term, "| ");
|
|
|
|
|
|
return new LogicFunction($input_vars, $verilog_term, $tex_term);
|
|
}
|
|
} |