/* This file is part of JOP, the Java Optimized Processor see <http://www.jopdesign.com/> Copyright (C) 2010, Martin Schoeberl (martin@jopdesign.com) 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/>. */ package csp; import util.Timer; import joprt.RtThread; import com.jopdesign.io.IOFactory; import com.jopdesign.io.SysDevice; import com.jopdesign.sys.Native; import com.jopdesign.sys.Startup; /** * @author martin * */ public class EratosthenesCsp2 implements Runnable { final static int PRIMECNT = 20; int id; int nid; // next processor id int crtlvl; int[] primes; int[] mulprimes; public EratosthenesCsp2(int i, int ni) { id = i; nid = ni; crtlvl = 0; primes = new int[PRIMECNT]; mulprimes = new int[PRIMECNT]; } public static int cpuIndex2NoCAddress(int i) { // this is when I use two rings, with the other ring starting at Addr 4 // if(i==2) return 4; // else return i; // this is with a single ring! return i; } /** * @param args */ public static void main(String[] args) { System.out.println("Eratosthenes Sieve, v2"); // System.out.print("Status: "); // System.out.println(Native.rd(NoC.NOC_REG_STATUS)); SysDevice sys = IOFactory.getFactory().getSysDevice(); // ni must be translated from proc index to NoC address! for (int i=1; i<sys.nrCpu; i++) { int ni = i+1; if(ni==sys.nrCpu) ni = 0; // System.out.println(i+" -> "+cpuIndex2NoCAddress(ni)); Runnable r = new EratosthenesCsp2(i, cpuIndex2NoCAddress(ni)); Startup.setRunnable(r, i-1); } EratosthenesCsp2 r = new EratosthenesCsp2(0,1); // Startup.setRunnable(r, 0); System.out.println("starting cpus."); // start the other CPUs sys.signal = 1; // set the WD LED for the simulation sys.wd = 1; int i=2; // The main loop. while(r.crtlvl < PRIMECNT) { int lvl = 0; int candidate = i; // attempt to receive if(NoC.isReceiving()) { // System.out.println("<"); // something to process /////////////////////// receive a two word message instead //////////////// // while(!NoC.isReceiving()); lvl = Native.rd(NoC.NOC_REG_RCVDATA); // while(NoC.isReceiveBufferEmpty()); candidate = Native.rd(NoC.NOC_REG_RCVDATA); Native.wr(0, NoC.NOC_REG_RCVRESET); /////////////////////////////////////////////////////////////////////////// // level increases here lvl++; } else { i++; } // System.out.print(" Processing "); // System.out.print(candidate); // System.out.print(" level = "); // System.out.print(lvl); if(r.sendAlong(lvl, candidate)) { // System.out.println("->"); ////////////////// send a two word message instead /////////////////////////// while(NoC.isSending()); Native.wr(1, NoC.NOC_REG_SNDDST); Native.wr(2, NoC.NOC_REG_SNDCNT); Native.wr(lvl, NoC.NOC_REG_SNDDATA); // while(NoC.isSendBufferFull()); Native.wr(candidate, NoC.NOC_REG_SNDDATA); ////////////////////////////////////////////////////////////////////////////// } else { // System.out.println("."); } // RtThread.sleepMs(10); } // print out the result for this processor System.out.print("Primes on cpu0 "); for(i=0;i<PRIMECNT;i++) System.out.println(r.primes[i]); } public void run() { while(crtlvl < PRIMECNT) { // receive a level and a candidate int lvl, candidate; /////////////////////// receive a two word message instead //////////////// while(!NoC.isReceiving()); lvl = Native.rd(NoC.NOC_REG_RCVDATA); // while(NoC.isReceiveBufferEmpty()); candidate = Native.rd(NoC.NOC_REG_RCVDATA); Native.wr(0, NoC.NOC_REG_RCVRESET); /////////////////////////////////////////////////////////////////////////// // check it against the current prime if(sendAlong(lvl, candidate)) { // send it further ////////////////// send a two word message instead /////////////////////////// while(NoC.isSending()); Native.wr(nid, NoC.NOC_REG_SNDDST); Native.wr(2, NoC.NOC_REG_SNDCNT); Native.wr(lvl, NoC.NOC_REG_SNDDATA); // while(NoC.isSendBufferFull()); Native.wr(candidate, NoC.NOC_REG_SNDDATA); ////////////////////////////////////////////////////////////////////////////// // RtThread.sleepMs(10); } } // all entries are full } public boolean sendAlong(int lvl, int candidate) { if(lvl==crtlvl) { // this is a new prime, so store it primes[crtlvl] = candidate; // next number to check is.. mulprimes[crtlvl] = candidate; // + candidate; crtlvl++; return false; // do not send further } else { // check whether is divisible with the current prime // if(candidate % primes[lvl] == 0) // must bring the current multiple up to the candidate size while(mulprimes[lvl] < candidate) mulprimes[lvl] = mulprimes[lvl] + primes[lvl]; if(candidate == mulprimes[lvl]) // not prime, discard return false; else // might still be prime return true; } } }