1 package edu.berkeley.fleet.ir;
2 import java.util.concurrent.Semaphore;
5 import edu.berkeley.fleet.two.*;
6 import edu.berkeley.fleet.fpga.*;
7 import edu.berkeley.fleet.api.*;
8 import edu.berkeley.fleet.api.Instruction.*;
9 import edu.berkeley.fleet.api.Instruction.Set;
10 import edu.berkeley.fleet.api.Instruction.Set.*;
11 import edu.berkeley.fleet.ir.Context.LoopFactory;
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.*;
18 import edu.berkeley.fleet.ir.Context.LoopFactory;
21 - Change Alu behavior to "drain one"
24 - facility for launching and Concluding a context
25 - implement the merge operation and test it
26 - test case for DRAM ship
27 - hideously ugly hacks in Verilog.java!
28 - dispatch ALWAYS needs to go via memory first, unless transmissions to
29 debugIn are flow-controlled properly
30 - current write-to-mem transformation screws up -- it can clog
33 public class Gadgets {
35 public static void readMem(FleetProcess fp, Ship memory, long offset, BitVector[] vals) throws RuntimeException {
36 doMem(true, fp, memory, offset, vals);
38 public static void writeMem(FleetProcess fp, Ship memory, long offset, BitVector[] vals) throws RuntimeException {
39 doMem(false, fp, memory, offset, vals);
41 public static void doMem(final boolean read, final FleetProcess fp, final Ship memory, final long offset, final BitVector[] vals) throws RuntimeException {
42 if (fp.getFleet() != memory.getFleet())
43 throw new RuntimeException("Fleet mismatch");
45 final Dock inAddrWrite = memory.getDock("inAddrWrite");
46 final Dock inDataWrite = memory.getDock("inDataWrite");
47 final Dock inAddrRead = memory.getDock("inAddrRead");
48 final Dock out = memory.getDock("out");
49 final Dock debugIn = fp.getDebugInputDock();
51 final Semaphore sem = new Semaphore(12 /* FIXME */);
53 Context ctx = new Context(fp.getFleet());
56 lf = ctx.new LoopFactory(inAddrRead, 0);
57 lf.abortLoopIfTorpedoPresent();
61 lf = ctx.new LoopFactory(inAddrWrite, 0);
62 lf.abortLoopIfTorpedoPresent();
65 lf = ctx.new LoopFactory(inDataWrite, 0);
66 lf.abortLoopIfTorpedoPresent();
71 lf = ctx.new LoopFactory(out, 0);
72 lf.abortLoopIfTorpedoPresent();
74 lf.sendWord(debugIn.getDataDestination());
76 lf = ctx.new LoopFactory(debugIn, 0);
77 lf.abortLoopIfTorpedoPresent();
81 ArrayList<Instruction> ai = new ArrayList<Instruction>();
83 for(Instruction ins : ai)
84 fp.sendInstruction(ins);
87 public void run() { try {
88 for(int i=0; i<vals.length; i++) {
89 if (!sem.tryAcquire()) {
94 fp.sendWord(inAddrRead.getDataDestination(), new BitVector(fp.getFleet().getWordWidth()).set(i+offset));
96 fp.sendWord(inAddrWrite.getDataDestination(), new BitVector(fp.getFleet().getWordWidth()).set(i+offset));
97 fp.sendWord(inDataWrite.getDataDestination(), vals[i]);
101 } catch (Exception e) { throw new RuntimeException(e); }
105 for(int i=0; i<vals.length; i++) {
106 BitVector outv = fp.recvWord();
107 if (read) vals[i] = outv;
108 if (read) System.out.print("\rread from address: " + i + ", got " + vals[i] + " = " + vals[i].toLong()+" ");
109 else System.out.print("\rwrote to address: " + i+" ");
114 fp.sendToken(inAddrRead.getInstructionDestination());
116 fp.sendToken(inAddrWrite.getInstructionDestination());
117 fp.sendToken(inDataWrite.getInstructionDestination());
119 fp.sendToken(out.getInstructionDestination());
120 fp.sendToken(debugIn.getInstructionDestination());
121 System.out.println();
124 /** returns the output Dock at which the merged values may be collected */
125 public static Dock mergeSort(FleetProcess fp,
131 int stride_length, /* per arity */
135 throws RuntimeException {
137 if (arity != 2) throw new RuntimeException();
138 if (num_strides != 1) throw new RuntimeException();
141 Dock mem_inAddrData = sourceMem.getDock("inAddrData");
142 Dock mem_out = sourceMem.getDock("out");
144 Ship merger = ctx.allocateShip("Alu");
145 Dock[] merger_inputs = new Dock[] { merger.getDock("in1"), merger.getDock("in2") };
146 Dock merger_inOp = merger.getDock("inOp");
148 // Address Generators (arity-many) /////////////////////////////////////////////////////////////////////
150 Ship[] address_generators = new Ship[arity];
151 for(int i=0; i<address_generators.length; i++) {
152 address_generators[i] = ctx.allocateShip("Alu");
153 long start = read_start + i*stride_length;
154 int count = stride_length;
156 Dock ag_out = address_generators[i].getDock("out");
157 Dock ag_op = address_generators[i].getDock("inOp");
158 Dock ag_in1 = address_generators[i].getDock("in1");
159 Dock ag_in2 = address_generators[i].getDock("in2");
160 BitVector signal = new BitVector(1/*FIXME*/).set(i/*FIXME*/);
162 lf = ctx.new LoopFactory(ag_in1, 0);
164 lf = lf.makeNext(count);
167 lf = ctx.new LoopFactory(ag_out, 1);
171 lf.sendWord(mem_inAddrData.getDataDestination(), signal);
172 //lf.sendWord(ag_in1);
176 // Memory Read ////////////////////////////////////////////////////////////////////////////////////////
178 lf = ctx.new LoopFactory(mem_inAddrData, 0);
180 lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
181 lf.setPredicate(Predicate.NotFlagA);
182 lf.sendToken(mem_out.getDataDestination(), new BitVector(1/*FIXME*/).set(0)); // note: arity-many tokens may pile up at mem_out...
183 lf.setPredicate(Predicate.FlagA);
184 lf.sendToken(mem_out.getDataDestination(), new BitVector(1/*FIXME*/).set(1));
185 lf.setPredicate(null);
188 lf = ctx.new LoopFactory(mem_out, 0);
191 lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
192 lf.setPredicate(Predicate.NotFlagA);
193 lf.sendWord(merger_inputs[0].getDataDestination());
194 lf.setPredicate(Predicate.FlagA);
195 lf.sendWord(merger_inputs[1].getDataDestination());
196 lf.setPredicate(null);
198 // Merger /////////////////////////////////////////////////////////////////////////////////////////////
200 for(int i=0; i<merger_inputs.length; i++) {
201 lf = ctx.new LoopFactory(merger_inputs[i], stride_length);
202 lf.sendToken(address_generators[i].getDock("out").getDataDestination());
211 lf = ctx.new LoopFactory(merger_inOp, 1);
212 lf.literal(5); // MIN
213 lf = lf.makeNext(stride_length * arity);
216 lf.literal(7); // DROP1
218 lf.literal(8); // DROP2
221 return merger.getDock("out");
224 public static void dispatch(FleetProcess fp, Context ctx) {
225 ArrayList<Instruction> ai;
226 ctx.emit(ai = new ArrayList<Instruction>());
227 for(Instruction ins : ai) {
228 fp.sendInstruction(ins);
232 public static void main(String[] s) throws Exception {
233 Random random = new Random(System.currentTimeMillis());
234 Fleet fleet = new Fpga();
235 FleetProcess fp = fleet.run(new Instruction[0]);
236 Ship memory = fleet.getShip("DDR2",0);
237 //Ship memory = fleet.getShip("Memory",0);
238 BitVector[] vals = new BitVector[2 * 1024];
239 BitVector[] vals2 = new BitVector[2 * 1024];
240 for(int i=0; i<vals.length; i++)
241 vals[i] = new BitVector(fleet.getWordWidth()).set(random.nextLong());
242 writeMem(fp, memory, 0, vals);
243 readMem(fp, memory, 0, vals2);
244 for(int i=0; i<vals.length; i++)
245 if (!vals[i].equals(vals2[i]))
246 System.out.println("disagreement! on index " + i + "\n "+vals[i]+"\n "+vals2[i]);
247 System.out.println("done!");