blob: 67780b531134bb491ecf4932d4e3216151f42805 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 CEA LIST.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and Implementation
*******************************************************************************/
package org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph.mocc.ast;
import org.eclipse.efm.modeling.codegen.xlia.sdf.polygraph.util.Rational;
public class MoccPort {
public final MoccActor actor;
public enum Direction { INPUT , OUTPUT }
protected final Direction direction;
protected final String name;
protected boolean isDeciding;
public int rate;
protected final int rateDenominator;
protected int[] cycloStaticRate;
protected MoccChannel channel;
public MoccPort(final MoccActor actor, final Direction direction,
final String name, final boolean isDeciding,
final int rate, final int rateDenominator)
{
super();
assert (actor != null) : "Unexpected a null MoccActor";
this.actor = actor;
this.direction = direction;
this.name = name;
this.isDeciding = isDeciding;
this.rate = rate;
this.rateDenominator = rateDenominator;
cycloStaticRate = null;
this.channel = null;
actor.addPort( this );
}
public MoccPort(final MoccActor actor, final Direction direction,
final String name, final boolean isDeciding, final int rate)
{
this(actor, direction, name, isDeciding, rate, 1);
}
// GETTERS - SETTERS
public MoccActor getActor() {
return actor;
}
public boolean isInput() {
return( direction == Direction.INPUT );
}
public boolean isInputMode() {
return( isDeciding
&& (direction == Direction.INPUT)
&& channel.getOutputActor().isModeProducer() );
}
public MoccActor getModeSelector() {
if( direction == Direction.INPUT ) {
if( channel.getOutputActor().isModeProducer() ) {
return channel.getOutputActor().getSelector();
}
}
else if( this.actor.isModeProducer() ) {
return this.actor.getSelector();
}
return null;
}
public boolean isOutput() {
return( direction == Direction.OUTPUT );
}
public boolean isOutputMode() {
return( isDeciding
&& (direction == Direction.OUTPUT)
&& actor.isModeProducer() );
}
public String getName() {
return name;
}
public boolean isDeciding() {
return isDeciding;
}
public boolean isDecidingInputMode() {
return( isDeciding
&& (direction == Direction.INPUT)
&& (channel.getOutputActor().isModeProducer()) );
}
public int getRate() {
return rate;
}
public int getRateDenominator() {
return rateDenominator;
}
public boolean isRational() {
return( rateDenominator > 1 );
}
public int[] getCycloStaticRate() {
return cycloStaticRate;
}
public boolean hasCycloStaticRate() {
return( cycloStaticRate != null );
}
public boolean hasCycloStaticChannel() {
return( channel.hasCycloStaticPort() );
}
public boolean isInputRational() {
return( (channel != null) && channel.getInputPort().isRational() );
}
public boolean hasEnoughInitialRate() {
assert (channel != null) :
"Unexpected a null MoccChannel in updateInputChannel";
return( ((channel.getInitialRate() * rateDenominator)
>= (rate * channel.getInitialRateDenominator())) );
}
public boolean hasEnoughInitialRate(final MoccActor sourceActor) {
assert (channel != null) :
"Unexpected a null MoccChannel in updateInputChannel";
return( (channel.getOutputPort().getActor() == sourceActor)
&& hasEnoughInitialRate() );
}
public boolean hasInitialRate() {
return( (channel != null) && channel.hasInitialRate() );
}
public boolean isOutputRational() {
return( (channel != null) && channel.getOutputPort().isRational() );
}
public boolean isRationalTokenCount() {
return( isRational() || isOutputRational() );
}
/*
def csdf_sequence(rate, rate_initial):
s = []
for i in range(rate.denominator):
r = rate_initial + rate
s += [abs(floor(r)-floor(rate_initial))]
rate_initial = r
return s
*/
public static int[] computeRateCSDF(final Rational rate, Rational initial ) {
final int[] cycloStaticRate = new int[rate.getDenominator()];
for (int i = 0; i < cycloStaticRate.length; i++) {
final Rational sum = (new Rational(initial)).add(rate);
cycloStaticRate[i] = Math.abs(sum.floor() - initial.floor());
initial = sum;
}
return cycloStaticRate;
}
public static void printRate(final int[] rate) {
System.out.print('[');
for (final int r : rate) {
System.out.print(' ');
System.out.print(r);
}
System.out.println(" ]");
}
/*
for den in range(5):
for num in range(1,den):
rate = Fraction(num,den)
for ps in range(den):
rate_initial = Fraction(ps,den)
print("case:",rate,"-",rate_initial,"->",2)
print("csdf production:",csdf_sequence(rate,rate_initial))
print("csdf consumption:",csdf_sequence(-2,rate_initial))
print("case:",2,"-",rate_initial,"->",rate)
print("csdf production:",csdf_sequence(2,rate_initial))
print("csdf consumption:",csdf_sequence(-rate,rate_initial))
print()
print()
print()
*/
public static void main(final String[] args) {
final Rational deux = new Rational(2, 1);
final Rational neg_deux = new Rational(-2, 1);
for (int den = 0; den < 5; den++) {
for (int num = 1; num < den; num++) {
final Rational rate = new Rational(num,den);
for (int ps = 0; ps < den; ps++) {
final Rational rate_initial = new Rational(ps,den);
System.out.println("case: " + rate + " -- " + rate_initial + " --> " + 2);
System.out.print("csdf production : "); printRate(computeRateCSDF(rate , rate_initial));
System.out.print("csdf consumption: "); printRate(computeRateCSDF(neg_deux , rate_initial));
System.out.println("case: " + 2 + " -- " + rate_initial + " --> " + rate);
System.out.print("csdf production : "); printRate(computeRateCSDF(deux , rate_initial));
System.out.print("csdf consumption: "); printRate(computeRateCSDF(rate.negate() , rate_initial));
System.out.println();
}
System.out.println();
}
System.out.println();
}
final Rational prod = new Rational(4, 3);
final Rational init = new Rational(0, 1);
final Rational conso = new Rational(-1, 1);
System.out.println("case: 4/3 -- 0 --> 1");
System.out.print("csdf prod : "); printRate(computeRateCSDF(prod , init));
System.out.print("csdf conso: "); printRate(computeRateCSDF(conso , init));
System.out.println();
}
public void computeCycloStaticInputRate() {
cycloStaticRate = computeRateCSDF(
new Rational(-rate, rateDenominator),
new Rational(channel.initialRate, channel.initialRateDenominator));
// cycloStaticRate = new int[rateDenominator];
// int intTokenCount = 0;
// float floatTokenCount = 0;
// for (int i = 0; i < cycloStaticRate.length; i++) {
// floatTokenCount += ((float)rate) / rateDenominator;
// if( ((int) floatTokenCount) <= (rate - 1) ) {
// cycloStaticRate[i] = ((int) floatTokenCount ) + 1 - intTokenCount;
//
// intTokenCount += cycloStaticRate[i];
// }
// else {
// cycloStaticRate[i] = 0;
// }
// }
}
public void computeCycloStaticOutputRate() {
cycloStaticRate = computeRateCSDF(
new Rational(rate, rateDenominator),
// new Rational(0, 1));
new Rational(channel.initialRate, channel.initialRateDenominator));
// cycloStaticRate = new int[rateDenominator];
// int intTokenCount = 0;
// float floatTokenCount = 0;
// for (int i = 0; i < cycloStaticRate.length; i++) {
// floatTokenCount += rate;
// cycloStaticRate[i] = ((int) (floatTokenCount / rateDenominator)) - intTokenCount;
// intTokenCount += cycloStaticRate[i];
// }
}
public MoccChannel getChannel() {
return channel;
}
public void updateInputChannel(final MoccChannel channel) {
assert (channel != null) :
"Unexpected a null MoccChannel in updateInputChannel";
this.channel = channel;
this.actor.updateInputChannel(this.channel);
}
public void updateOutputChannel(final MoccChannel channel) {
assert (channel != null) :
"Unexpected a null MoccChannel in updateOutputChannel";
this.channel = channel;
this.actor.updateOutputChannel(this.channel);
}
public String strRate() {
if( isRational() ) {
return( rate + "/" + rateDenominator );
}
else {
return( Integer.toString(rate) );
}
}
public void strCycloStaticRate(final StringBuilder sout) {
sout.append('[');
for (final int rate : cycloStaticRate) {
sout.append(' ').append(rate);
}
sout.append(" ]");
}
@Override
public String toString() {
final StringBuilder sout = new StringBuilder();
sout.append(direction.toString().toLowerCase())
.append(isDeciding ? " deciding" : "")
.append(" port< rate = ").append(strRate());
if( cycloStaticRate != null ) {
sout.append(" , cyclo = ");
strCycloStaticRate(sout);
}
if( channel.hasInitialRate() ) {
sout.append(" , initial = ").append(channel.strInitialRate());
}
if( channel.hasInitialMode() ) {
sout.append(" , mode = ")
.append(channel.getInitialMode().getLiteral());
}
sout.append(" > ").append(name);
return sout.toString();
}
}