1 package edu.berkeley.fleet.ir;
2 import edu.berkeley.fleet.loops.*;
3 import java.util.concurrent.Semaphore;
6 import edu.berkeley.fleet.two.*;
7 import edu.berkeley.fleet.fpga.*;
8 import edu.berkeley.fleet.api.*;
9 import edu.berkeley.fleet.api.Instruction.*;
10 import edu.berkeley.fleet.api.Instruction.Set;
11 import edu.berkeley.fleet.api.Instruction.Set.*;
12 import static edu.berkeley.fleet.util.BitManipulations.*;
13 import edu.berkeley.fleet.api.Instruction.Set.FlagFunction;
14 import edu.berkeley.fleet.api.Instruction.Set;
15 import edu.berkeley.fleet.api.Instruction.Set.SetDest;
16 import edu.berkeley.fleet.api.Instruction.Set.FlagFunction;
17 import static edu.berkeley.fleet.api.Predicate.*;
20 - Change Alu behavior to "drain one"
23 - facility for launching and Concluding a context
24 - implement the merge operation and test it
25 - test case for DRAM ship
26 - hideously ugly hacks in Verilog.java!
27 - dispatch ALWAYS needs to go via memory first, unless transmissions to
28 debugIn are flow-controlled properly
29 - current write-to-mem transformation screws up -- it can clog
32 public class Gadgets {
34 public static void readMem(FleetProcess fp, Ship memory, long offset, BitVector[] vals) throws RuntimeException {
35 doMem(true, fp, memory, offset, vals);
37 public static void writeMem(FleetProcess fp, Ship memory, long offset, BitVector[] vals) throws RuntimeException {
38 doMem(false, fp, memory, offset, vals);
40 public static void doMem(final boolean read, final FleetProcess fp, final Ship memory, final long offset, final BitVector[] vals) throws RuntimeException {
41 if (fp.getFleet() != memory.getFleet())
42 throw new RuntimeException("Fleet mismatch");
44 final Dock inAddrWrite = memory.getDock("inAddrWrite");
45 final Dock inDataWrite = memory.getDock("inDataWrite");
46 final Dock inAddrRead = memory.getDock("inAddrRead");
47 final Dock out = memory.getDock("out");
48 final Dock debugIn = fp.getDebugInputDock();
50 final Semaphore sem = new Semaphore(12 /* FIXME */);
52 Context ctx = new Context(fp.getFleet());
55 lf = new LoopFactory(ctx, inAddrRead, 0);
56 lf.abortLoopIfTorpedoPresent();
60 lf = new LoopFactory(ctx, inAddrWrite, 0);
61 lf.abortLoopIfTorpedoPresent();
64 lf = new LoopFactory(ctx, inDataWrite, 0);
65 lf.abortLoopIfTorpedoPresent();
70 lf = new LoopFactory(ctx, out, 0);
71 lf.abortLoopIfTorpedoPresent();
73 lf.sendWord(debugIn.getDataDestination());
75 lf = new LoopFactory(ctx, debugIn, 0);
76 lf.abortLoopIfTorpedoPresent();
80 ArrayList<Instruction> ai = new ArrayList<Instruction>();
82 for(Instruction ins : ai)
83 fp.sendInstruction(ins);
86 public void run() { try {
87 for(int i=0; i<vals.length; i++) {
88 if (!sem.tryAcquire()) {
93 fp.sendWord(inAddrRead.getDataDestination(), new BitVector(fp.getFleet().getWordWidth()).set(i+offset));
95 fp.sendWord(inAddrWrite.getDataDestination(), new BitVector(fp.getFleet().getWordWidth()).set(i+offset));
96 fp.sendWord(inDataWrite.getDataDestination(), vals[i]);
100 } catch (Exception e) { throw new RuntimeException(e); }
104 for(int i=0; i<vals.length; i++) {
105 BitVector outv = fp.recvWord();
106 if (read) vals[i] = outv;
107 if (read) System.out.print("\rread from address: " + i + ", got " + vals[i] + " = " + vals[i].toLong()+" ");
108 else System.out.print("\rwrote to address: " + i+" ");
113 fp.sendToken(inAddrRead.getInstructionDestination());
115 fp.sendToken(inAddrWrite.getInstructionDestination());
116 fp.sendToken(inDataWrite.getInstructionDestination());
118 fp.sendToken(out.getInstructionDestination());
119 fp.sendToken(debugIn.getInstructionDestination());
120 System.out.println();
123 /** returns the output Dock at which the merged values may be collected */
124 public static Dock mergeSort(FleetProcess fp,
130 int stride_length, /* per arity */
134 throws RuntimeException {
136 if (arity != 2) throw new RuntimeException();
137 if (num_strides != 1) throw new RuntimeException();
140 Dock mem_inAddrData = sourceMem.getDock("inAddrData");
141 Dock mem_out = sourceMem.getDock("out");
143 Ship merger = ctx.allocateShip("Alu");
144 Dock[] merger_inputs = new Dock[] { merger.getDock("in1"), merger.getDock("in2") };
145 Dock merger_inOp = merger.getDock("inOp");
147 // Address Generators (arity-many) /////////////////////////////////////////////////////////////////////
149 Ship[] address_generators = new Ship[arity];
150 for(int i=0; i<address_generators.length; i++) {
151 address_generators[i] = ctx.allocateShip("Alu");
152 long start = read_start + i*stride_length;
153 int count = stride_length;
155 Dock ag_out = address_generators[i].getDock("out");
156 Dock ag_op = address_generators[i].getDock("inOp");
157 Dock ag_in1 = address_generators[i].getDock("in1");
158 Dock ag_in2 = address_generators[i].getDock("in2");
159 BitVector signal = new BitVector(1/*FIXME*/).set(i/*FIXME*/);
161 lf = new LoopFactory(ctx, ag_in1, 0);
163 lf = lf.makeNext(count);
166 lf = new LoopFactory(ctx, ag_out, 1);
170 lf.sendWord(mem_inAddrData.getDataDestination(), signal);
171 //lf.sendWord(ag_in1);
175 // Memory Read ////////////////////////////////////////////////////////////////////////////////////////
177 lf = new LoopFactory(ctx, mem_inAddrData, 0);
179 lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
180 lf.setPredicate(Predicate.NotFlagA);
181 lf.sendToken(mem_out.getDataDestination(), new BitVector(1/*FIXME*/).set(0)); // note: arity-many tokens may pile up at mem_out...
182 lf.setPredicate(Predicate.FlagA);
183 lf.sendToken(mem_out.getDataDestination(), new BitVector(1/*FIXME*/).set(1));
184 lf.setPredicate(null);
187 lf = new LoopFactory(ctx, mem_out, 0);
190 lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
191 lf.setPredicate(Predicate.NotFlagA);
192 lf.sendWord(merger_inputs[0].getDataDestination());
193 lf.setPredicate(Predicate.FlagA);
194 lf.sendWord(merger_inputs[1].getDataDestination());
195 lf.setPredicate(null);
197 // Merger /////////////////////////////////////////////////////////////////////////////////////////////
199 for(int i=0; i<merger_inputs.length; i++) {
200 lf = new LoopFactory(ctx, merger_inputs[i], stride_length);
201 lf.sendToken(address_generators[i].getDock("out").getDataDestination());
210 lf = new LoopFactory(ctx, merger_inOp, 1);
211 lf.literal(5); // MIN
212 lf = lf.makeNext(stride_length * arity);
215 lf.literal(7); // DROP1
217 lf.literal(8); // DROP2
220 return merger.getDock("out");
223 public static void dispatch(FleetProcess fp, Context ctx) {
224 ArrayList<Instruction> ai;
225 ctx.emit(ai = new ArrayList<Instruction>());
226 for(Instruction ins : ai) {
227 fp.sendInstruction(ins);
231 public static void main(String[] s) throws Exception {
232 Random random = new Random(System.currentTimeMillis());
233 Fleet fleet = new Fpga();
234 FleetProcess fp = fleet.run(new Instruction[0]);
235 Ship memory = fleet.getShip("DDR2",0);
236 //Ship memory = fleet.getShip("Memory",0);
237 BitVector[] vals = new BitVector[2 * 1024];
238 BitVector[] vals2 = new BitVector[2 * 1024];
239 for(int i=0; i<vals.length; i++)
240 vals[i] = new BitVector(fleet.getWordWidth()).set(random.nextLong());
241 writeMem(fp, memory, 0, vals);
242 readMem(fp, memory, 0, vals2);
243 for(int i=0; i<vals.length; i++)
244 if (!vals[i].equals(vals2[i]))
245 System.out.println("disagreement! on index " + i + "\n "+vals[i]+"\n "+vals2[i]);
246 System.out.println("done!");