Package org.pshdl.interpreter.utils

Source Code of org.pshdl.interpreter.utils.ComparisonInterpreter

/*******************************************************************************
* PSHDL is a library and (trans-)compiler for PSHDL input. It generates
*     output suitable for implementation or simulation of it.
*
*     Copyright (C) 2013 Karsten Becker (feedback (at) pshdl (dot) org)
*
*     This program is free software: you can redistribute it and/or modify
*     it under the terms of the GNU General Public License as published by
*     the Free Software Foundation, either version 3 of the License, or
*     (at your option) any later version.
*
*     This program is distributed in the hope that it will be useful,
*     but WITHOUT ANY WARRANTY; without even the implied warranty of
*     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*     GNU General Public License for more details.
*
*     You should have received a copy of the GNU General Public License
*     along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
*     This License does not grant permission to use the trade names, trademarks,
*     service marks, or product names of the Licensor, except as required for
*     reasonable and customary use in describing the origin of the Work.
*
* Contributors:
*     Karsten Becker - initial API and implementation
******************************************************************************/
package org.pshdl.interpreter.utils;

import java.io.PrintStream;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.pshdl.interpreter.ExecutableModel;
import org.pshdl.interpreter.IHDLBigInterpreter;
import org.pshdl.interpreter.IHDLInterpreter;
import org.pshdl.interpreter.VariableInformation;

public class ComparisonInterpreter implements IHDLBigInterpreter {

  public static class ConsoleReporter implements DiffReport {
    private final PrintStream out;

    public ConsoleReporter() {
      this(System.out);
    }

    public ConsoleReporter(PrintStream out) {
      this.out = out;
    }

    @Override
    public void reportOutputLongDiff(long deltaCycle, long aVal, long bVal, String name, int... idx) {
      String sIdx = "";
      if ((idx != null) && (idx.length != 0)) {
        sIdx = Arrays.toString(idx);
      }
      out.printf("deltaCycle:%5d %s%s aVal=%X bVal=%X%n", deltaCycle, name, sIdx, aVal, bVal);
    }

    @Override
    public void reportOutputBigDiff(long deltaCycle, BigInteger aVal, BigInteger bVal, String name, int... idx) {
      String sIdx = "";
      if ((idx != null) && (idx.length != 0)) {
        sIdx = Arrays.toString(idx);
      }
      out.printf("deltaCycle:%5d %s%s aVal=%X bVal=%X%n", deltaCycle, name, sIdx, aVal, bVal);
    }

    @Override
    public void reportDeltaCycleDiff(long deltaCycleA, long deltaCycleB) {
      out.printf("Delta Cycle diff, a: %d b: %d%n", deltaCycleA, deltaCycleB);
    }

  }

  public static interface DiffReport {

    void reportOutputLongDiff(long deltaCycle, long aVal, long bVal, String name, int... idx);

    void reportOutputBigDiff(long deltaCycle, BigInteger aVal, BigInteger bVal, String name, int... idx);

    void reportDeltaCycleDiff(long deltaCycleA, long deltaCycleB);

  }

  private final IHDLInterpreter b;
  private final IHDLBigInterpreter bBig;
  private final IHDLInterpreter a;
  private final IHDLBigInterpreter aBig;
  private final List<Integer> varListA = new ArrayList<>();
  private final List<Integer> varListB = new ArrayList<>();
  private final Map<String, Integer> varIdx = new LinkedHashMap<>();
  private final DiffReport report;
  private final ExecutableModel em;
  private final boolean terminate;

  public ComparisonInterpreter(IHDLInterpreter a, IHDLInterpreter b, ExecutableModel em, DiffReport report, boolean terminate) {
    this.a = a;
    this.aBig = BigInterpreterAdapter.adapt(a);
    this.b = b;
    this.bBig = BigInterpreterAdapter.adapt(b);
    this.em = em;
    this.terminate = terminate;
    if (report != null) {
      this.report = report;
    } else {
      this.report = new ConsoleReporter();
    }
    final VariableInformation[] variables = em.variables;
    for (int i = 0; i < variables.length; i++) {
      final VariableInformation v = variables[i];
      varIdx.put(v.name, i);
      if (!"#null".equals(v.name)) {
        varListA.add(getIndexOf(a, v));
        varListB.add(getIndexOf(b, v));
      } else {
        varListA.add(-1);
        varListB.add(-1);
      }
    }
  }

  protected int getIndexOf(IHDLInterpreter a, final VariableInformation v) {
    try {
      return a.getIndex(v.name);
    } catch (final Exception e) {
      if (v.name.startsWith(em.moduleName))
        return a.getIndex(v.name.substring(em.moduleName.length() + 1));
      return a.getIndex(em.moduleName + "." + v.name);
    }
  }

  public void checkAllVarsLong() {
    final VariableInformation[] variables = em.variables;
    boolean hasDiff = false;
    for (int i = 0; i < variables.length; i++) {
      final VariableInformation v = variables[i];
      if (!"#null".equals(v.name)) {
        if (v.dimensions.length == 0) {
          final long aVal = a.getOutputLong(varListA.get(i));
          final long bVal = b.getOutputLong(varListB.get(i));
          if (aVal != bVal) {
            hasDiff = true;
            report.reportOutputLongDiff(getDeltaCycle(), aVal, bVal, v.name);
          }
        } else {
          final int[] arrIdx = new int[v.dimensions.length];
          for (int j = 0; j < v.dimensions[0]; j++) {
            arrIdx[0] = j;
            final long aVal = a.getOutputLong(varListA.get(i), arrIdx);
            final long bVal = b.getOutputLong(varListB.get(i), arrIdx);
            if (aVal != bVal) {
              hasDiff = true;
              report.reportOutputLongDiff(getDeltaCycle(), aVal, bVal, v.name, arrIdx);
            }
          }
        }
      }
    }
    if (hasDiff && terminate)
      throw new RuntimeException("A mismatch has been found");
  }

  @Override
  public void setInput(String name, BigInteger value, int... arrayIdx) {
    aBig.setInput(name, value, arrayIdx);
    bBig.setInput(name, value, arrayIdx);
  }

  @Override
  public void setInput(int idx, BigInteger value, int... arrayIdx) {
    aBig.setInput(varListA.get(idx), value, arrayIdx);
    bBig.setInput(varListB.get(idx), value, arrayIdx);
  }

  @Override
  public void setInput(String name, long value, int... arrayIdx) {
    a.setInput(name, value, arrayIdx);
    b.setInput(name, value, arrayIdx);
  }

  @Override
  public void setInput(int idx, long value, int... arrayIdx) {
    a.setInput(varListA.get(idx), value, arrayIdx);
    b.setInput(varListB.get(idx), value, arrayIdx);
  }

  @Override
  public int getIndex(String name) {
    return varIdx.get(name);
  }

  @Override
  public String getName(int idx) {
    return null;
  }

  @Override
  public long getOutputLong(String name, int... arrayIdx) {
    final long aVal = a.getOutputLong(name, arrayIdx);
    final long bVal = b.getOutputLong(name, arrayIdx);
    if (aVal != bVal) {
      report.reportOutputLongDiff(getDeltaCycle(), aVal, bVal, name);
    }
    return aVal;
  }

  @Override
  public long getOutputLong(int idx, int... arrayIdx) {
    final long aVal = a.getOutputLong(varListA.get(idx), arrayIdx);
    final long bVal = b.getOutputLong(varListB.get(idx), arrayIdx);
    if (aVal != bVal) {
      report.reportOutputLongDiff(getDeltaCycle(), aVal, bVal, em.variables[idx].name);
    }
    return aVal;
  }

  @Override
  public BigInteger getOutputBig(String name, int... arrayIdx) {
    final BigInteger aVal = aBig.getOutputBig(name, arrayIdx);
    final BigInteger bVal = bBig.getOutputBig(name, arrayIdx);
    if (!aVal.equals(bVal)) {
      report.reportOutputBigDiff(getDeltaCycle(), aVal, bVal, name);
    }
    return aVal;
  }

  @Override
  public BigInteger getOutputBig(int idx, int... arrayIdx) {
    final BigInteger aVal = aBig.getOutputBig(varListA.get(idx), arrayIdx);
    final BigInteger bVal = bBig.getOutputBig(varListB.get(idx), arrayIdx);
    if (!aVal.equals(bVal)) {
      report.reportOutputBigDiff(getDeltaCycle(), aVal, bVal, em.variables[idx].name);
    }
    return aVal;
  }

  @Override
  public void run() {
    a.run();
    b.run();
  }

  @Override
  public long getDeltaCycle() {
    final long deltaCycleA = a.getDeltaCycle();
    final long deltaCycleB = b.getDeltaCycle();
    if (deltaCycleA != deltaCycleB) {
      report.reportDeltaCycleDiff(deltaCycleA, deltaCycleB);
    }
    return deltaCycleA;
  }

  @Override
  public void initConstants() {
    a.initConstants();
    b.initConstants();
  }

  @Override
  public void close() throws Exception {
    a.close();
    b.close();
  }

  @Override
  public void setFeature(Feature feature, Object value) {
    a.setFeature(feature, value);
    b.setFeature(feature, value);
  }

}
TOP

Related Classes of org.pshdl.interpreter.utils.ComparisonInterpreter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.