Package com.cburch.logisim.std.plexers

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

/* 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.Attributes;
import com.cburch.logisim.data.BitWidth;
import com.cburch.logisim.data.Bounds;
import com.cburch.logisim.data.Direction;
import com.cburch.logisim.data.Location;
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.tools.key.JoinedConfigurator;
import com.cburch.logisim.util.GraphicsUtil;

public class BitSelector extends InstanceFactory {
  public static final Attribute<BitWidth> GROUP_ATTR
    = Attributes.forBitWidth("group", Strings.getter("bitSelectorGroupAttr"));

  public BitSelector() {
    super("BitSelector", Strings.getter("bitSelectorComponent"));
    setAttributes(new Attribute[] {
        StdAttr.FACING, StdAttr.WIDTH, GROUP_ATTR
      }, new Object[] {
        Direction.EAST, BitWidth.create(8), BitWidth.ONE
      });
    setKeyConfigurator(JoinedConfigurator.create(
        new BitWidthConfigurator(GROUP_ATTR, 1, Value.MAX_WIDTH, 0),
        new BitWidthConfigurator(StdAttr.WIDTH)));

    setIconName("bitSelector.gif");
    setFacingAttribute(StdAttr.FACING);
  }
 
  @Override
  public Bounds getOffsetBounds(AttributeSet attrs) {
    Direction facing = attrs.getValue(StdAttr.FACING);
    Bounds base = Bounds.create(-30, -15, 30, 30);
    return base.rotate(Direction.EAST, facing, 0, 0);
  }
 
  @Override
  protected void configureNewInstance(Instance instance) {
    instance.addAttributeListener();
    updatePorts(instance);
  }
 
  @Override
  protected void instanceAttributeChanged(Instance instance, Attribute<?> attr) {
    if (attr == StdAttr.FACING) {
      instance.recomputeBounds();
      updatePorts(instance);
    } else if (attr == StdAttr.WIDTH || attr == GROUP_ATTR) {
      updatePorts(instance);
    }
  }

  private void updatePorts(Instance instance) {
    Direction facing = instance.getAttributeValue(StdAttr.FACING);
    BitWidth data = instance.getAttributeValue(StdAttr.WIDTH);
    BitWidth group = instance.getAttributeValue(GROUP_ATTR);
    int groups = (data.getWidth() + group.getWidth() - 1) / group.getWidth() - 1;
    int selectBits = 1;
    if (groups > 0) {
      while (groups != 1) { groups >>= 1; selectBits++; }
    }
    BitWidth select = BitWidth.create(selectBits);

    Location inPt;
    Location selPt;
    if (facing == Direction.WEST) {
      inPt  = Location.create(30, 0);
      selPt = Location.create(10, 10);
    } else if (facing == Direction.NORTH) {
      inPt  = Location.create0, 30);
      selPt = Location.create(-10, 10);
    } else if (facing == Direction.SOUTH) {
      inPt  = Location.create0, -30);
      selPt = Location.create(-10, -10);
    } else {
      inPt  = Location.create(-30, 0);
      selPt = Location.create(-10, 10);
    }
   
    Port[] ps = new Port[3];
    ps[0] = new Port(0, 0, Port.OUTPUT, group.getWidth());
    ps[1] = new Port(inPt.getX(), inPt.getY(), Port.INPUT, data.getWidth());
    ps[2] = new Port(selPt.getX(), selPt.getY(), Port.INPUT, select.getWidth());
    ps[0].setToolTip(Strings.getter("bitSelectorOutputTip"));
    ps[1].setToolTip(Strings.getter("bitSelectorDataTip"));
    ps[2].setToolTip(Strings.getter("bitSelectorSelectTip"));
    instance.setPorts(ps);
  }

  @Override
  public void propagate(InstanceState state) {
    Value data = state.getPort(1);
    Value select = state.getPort(2);
    BitWidth groupBits = state.getAttributeValue(GROUP_ATTR);
    Value group;
    if (!select.isFullyDefined()) {
      group = Value.createUnknown(groupBits);
    } else {
      int shift = select.toIntValue() * groupBits.getWidth();
      if (shift >= data.getWidth()) {
        group = Value.createKnown(groupBits, 0);
      } else if (groupBits.getWidth() == 1) {
        group = data.get(shift);
      } else {
        Value[] bits = new Value[groupBits.getWidth()];
        for (int i = 0; i < bits.length; i++) {
          if (shift + i >= data.getWidth()) {
            bits[i] = Value.FALSE;
          } else {
            bits[i] = data.get(shift + i);
          }
        }
        group = Value.create(bits);
      }
    }
    state.setPort(0, group, Plexers.DELAY);
  }

  @Override
  public void paintGhost(InstancePainter painter) {
    Plexers.drawTrapezoid(painter.getGraphics(), painter.getBounds(),
        painter.getAttributeValue(StdAttr.FACING), 9);
  }

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

    Plexers.drawTrapezoid(g, painter.getBounds(), facing, 9);
    Bounds bds = painter.getBounds();
    g.setColor(Color.BLACK);
    GraphicsUtil.drawCenteredText(g, "Sel",
        bds.getX() + bds.getWidth() / 2,
        bds.getY() + bds.getHeight() / 2);
    painter.drawPorts();
  }
}
TOP

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

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.