Package com.cburch.logisim.std.plexers

Source Code of com.cburch.logisim.std.plexers.PriorityEncoder

/* Copyright (c) 2010, Carl Burch. License information is located in the
* com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */

package com.cburch.logisim.std.plexers;

import java.awt.Color;
import java.awt.Graphics;

import com.cburch.logisim.data.Attribute;
import com.cburch.logisim.data.AttributeSet;
import com.cburch.logisim.data.BitWidth;
import com.cburch.logisim.data.Bounds;
import com.cburch.logisim.data.Direction;
import com.cburch.logisim.data.Value;
import com.cburch.logisim.instance.Instance;
import com.cburch.logisim.instance.InstanceFactory;
import com.cburch.logisim.instance.InstancePainter;
import com.cburch.logisim.instance.InstanceState;
import com.cburch.logisim.instance.Port;
import com.cburch.logisim.instance.StdAttr;
import com.cburch.logisim.tools.key.BitWidthConfigurator;
import com.cburch.logisim.util.GraphicsUtil;

public class PriorityEncoder extends InstanceFactory {
  private static final int OUT = 0;
  private static final int EN_IN = 1;
  private static final int EN_OUT = 2;
  private static final int GS = 3;
 
  public PriorityEncoder() {
    super("Priority Encoder", Strings.getter("priorityEncoderComponent"));
    setAttributes(new Attribute[] {
        StdAttr.FACING, Plexers.ATTR_SELECT, Plexers.ATTR_DISABLED
      }, new Object[] {
        Direction.EAST, BitWidth.create(3), Plexers.DISABLED_FLOATING
      });
    setKeyConfigurator(new BitWidthConfigurator(Plexers.ATTR_SELECT, 1, 5, 0));
    setIconName("priencod.gif");
    setFacingAttribute(StdAttr.FACING);
  }
 
  @Override
  public Bounds getOffsetBounds(AttributeSet attrs) {
    Direction dir = attrs.getValue(StdAttr.FACING);
    BitWidth select = attrs.getValue(Plexers.ATTR_SELECT);
    int inputs = 1 << select.getWidth();
    int offs = -5 * inputs;
    int len = 10 * inputs + 10;
    if (dir == Direction.NORTH) {
      return Bounds.create(offs,   0, len, 40);
    } else if (dir == Direction.SOUTH) {
      return Bounds.create(offs, -40, len, 40);
    } else if (dir == Direction.WEST) {
      return Bounds.create0, offs, 40, len);
    } else { // dir == Direction.EAST
      return Bounds.create(-40, offs, 40, len);
    }
  }

  @Override
  protected void configureNewInstance(Instance instance) {
    instance.addAttributeListener();
    updatePorts(instance);
  }
 
  @Override
  protected void instanceAttributeChanged(Instance instance, Attribute<?> attr) {
    if (attr == StdAttr.FACING || attr == Plexers.ATTR_SELECT) {
      instance.recomputeBounds();
      updatePorts(instance);
    } else if (attr == Plexers.ATTR_SELECT) {
      updatePorts(instance);
    } else if (attr == Plexers.ATTR_DISABLED) {
      instance.fireInvalidated();
    }
  }

  private void updatePorts(Instance instance) {
    Object dir = instance.getAttributeValue(StdAttr.FACING);
    BitWidth select = instance.getAttributeValue(Plexers.ATTR_SELECT);
    int n = 1 << select.getWidth();
    Port[] ps = new Port[n + 4];
    if (dir == Direction.NORTH || dir == Direction.SOUTH) {
      int x = -5 * n + 10;
      int y = dir == Direction.NORTH ? 40 : -40;
      for (int i = 0; i < n; i++) {
        ps[i] = new Port(x + 10 * i, y, Port.INPUT, 1);
      }
      ps[n + OUT] = new Port(0, 0, Port.OUTPUT, select.getWidth());
      ps[n + EN_IN] = new Port(x + 10 * n, y / 2, Port.INPUT, 1);
      ps[n + EN_OUT] = new Port(x - 10, y / 2, Port.OUTPUT, 1);
      ps[n + GS] = new Port(10, 0, Port.OUTPUT, 1);
    } else {
      int x = dir == Direction.EAST ? -40 : 40;
      int y = -5 * n + 10;
      for (int i = 0; i < n; i++) {
        ps[i] = new Port(x, y + 10 * i, Port.INPUT, 1);
      }
      ps[n + OUT] = new Port(0, 0, Port.OUTPUT, select.getWidth());
      ps[n + EN_IN] = new Port(x / 2, y + 10 * n, Port.INPUT, 1);
      ps[n + EN_OUT] = new Port(x / 2, y - 10, Port.OUTPUT, 1);
      ps[n + GS] = new Port(0, 10, Port.OUTPUT, 1);
    }

    for (int i = 0; i < n; i++) {
      ps[i].setToolTip(Strings.getter("priorityEncoderInTip", "" + i));
    }
    ps[n + OUT].setToolTip(Strings.getter("priorityEncoderOutTip"));
    ps[n + EN_IN].setToolTip(Strings.getter("priorityEncoderEnableInTip"));
    ps[n + EN_OUT].setToolTip(Strings.getter("priorityEncoderEnableOutTip"));
    ps[n + GS].setToolTip(Strings.getter("priorityEncoderGroupSignalTip"));

    instance.setPorts(ps);
  }

  @Override
  public void propagate(InstanceState state) {
    BitWidth select = state.getAttributeValue(Plexers.ATTR_SELECT);
    int n = 1 << select.getWidth();
    boolean enabled = state.getPort(n + EN_IN) != Value.FALSE;
   
    int out = -1;
    Value outDefault;
    if (enabled) {
      outDefault = Value.createUnknown(select);
      for (int i = n - 1; i >= 0; i--) {
        if (state.getPort(i) == Value.TRUE) {
          out = i;
          break;
        }
      }
    } else {
      Object opt = state.getAttributeValue(Plexers.ATTR_DISABLED);
      Value base = opt == Plexers.DISABLED_ZERO ? Value.FALSE : Value.UNKNOWN;
      outDefault = Value.repeat(base, select.getWidth());
    }
    if (out < 0) {
      state.setPort(n + OUT, outDefault, Plexers.DELAY);
      state.setPort(n + EN_OUT, enabled ? Value.TRUE : Value.FALSE, Plexers.DELAY);
      state.setPort(n + GS, Value.FALSE, Plexers.DELAY);
    } else {
      state.setPort(n + OUT, Value.createKnown(select, out), Plexers.DELAY);
      state.setPort(n + EN_OUT, Value.FALSE, Plexers.DELAY);
      state.setPort(n + GS, Value.TRUE, Plexers.DELAY);
    }
  }

  @Override
  public void paintInstance(InstancePainter painter) {
    Graphics g = painter.getGraphics();
    Direction facing = painter.getAttributeValue(StdAttr.FACING);

    painter.drawBounds();
    Bounds bds = painter.getBounds();
    g.setColor(Color.GRAY);
    int x0;
    int y0;
    int halign;
    if (facing == Direction.WEST) {
      x0 = bds.getX() + bds.getWidth() - 3;
      y0 = bds.getY() + 15;
      halign = GraphicsUtil.H_RIGHT;
    } else if (facing == Direction.NORTH) {
      x0 = bds.getX() + 10;
      y0 = bds.getY() + bds.getHeight() - 2;
      halign = GraphicsUtil.H_CENTER;
    } else if (facing == Direction.SOUTH) {
      x0 = bds.getX() + 10;
      y0 = bds.getY() + 12;
      halign = GraphicsUtil.H_CENTER;
    } else {
      x0 = bds.getX() + 3;
      y0 = bds.getY() + 15;
      halign = GraphicsUtil.H_LEFT;
    }
    GraphicsUtil.drawText(g, "0", x0, y0, halign, GraphicsUtil.V_BASELINE);
    g.setColor(Color.BLACK);
    GraphicsUtil.drawCenteredText(g, "Pri",
        bds.getX() + bds.getWidth() / 2,
        bds.getY() + bds.getHeight() / 2);
    painter.drawPorts();
  }
}
TOP

Related Classes of com.cburch.logisim.std.plexers.PriorityEncoder

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.