diff --git a/bin/runbsc b/bin/runbsc
index 87521883..a462ce6c 100755
--- a/bin/runbsc
+++ b/bin/runbsc
@@ -91,13 +91,13 @@ case "$CMD" in
#Run simulation in Bluesim
"$BSC" $ARGS -sim $BPATH "$TOP".bsv
"$BSC" $ARGS $BPATH -sim -o "$TB".bexe -e "$TB" "$TB".ba
- timeout "$TOUT"s ./"$TB".bexe | grep -v "WARNING" > "$SIMOUT"
+ timeout "$TOUT"s ./"$TB".bexe | grep -v "WARNING" | grep -v "\$finish" > "$SIMOUT"
;;
"s")
#Run simulation in Verilog
"$BSC" $ARGS $BPATH $VPATH $VSIM -vdir $VDIR -simdir $SDIR -u "$TOP".bsv
"$BSC" $ARGS $VPATH $VSIM -verilog -vdir $VDIR -simdir $SDIR -o "$TB".bexe -e "$TB" "$VDIR"/"$TB".v
- timeout "$TOUT"s ./"$TB".bexe | grep -v "WARNING" > "$SIMOUT"
+ timeout "$TOUT"s ./"$TB".bexe | grep -v "WARNING" | grep -v "\$finish" > "$SIMOUT"
;;
"c")
rm -f *.bi *.bo *.ba
diff --git a/bscRuntime/libs/BypassRF.v b/bscRuntime/libs/BypassRF.v
index 5e4b4168..288eaa25 100644
--- a/bscRuntime/libs/BypassRF.v
+++ b/bscRuntime/libs/BypassRF.v
@@ -1,3 +1,4 @@
+// BypassRF.v
`ifdef BSV_ASSIGNMENT_DELAY
`else
`define BSV_ASSIGNMENT_DELAY
diff --git a/bscRuntime/libs/Ehr.bsv b/bscRuntime/libs/Ehr.bsv
index 98048693..e85b6252 100644
--- a/bscRuntime/libs/Ehr.bsv
+++ b/bscRuntime/libs/Ehr.bsv
@@ -1,3 +1,4 @@
+// Ehr.bsv
// Copyright (c) 2017 Massachusetts Institute of Technology
//
diff --git a/bscRuntime/libs/Memories.bsv b/bscRuntime/libs/Memories.bsv
index d72fbb91..3a28f88f 100644
--- a/bscRuntime/libs/Memories.bsv
+++ b/bscRuntime/libs/Memories.bsv
@@ -1,3 +1,4 @@
+// Memories.bsv
package Memories;
import GetPut :: *;
diff --git a/bscRuntime/libs/Named.bsv b/bscRuntime/libs/Named.bsv
index 3c390739..a3b32418 100644
--- a/bscRuntime/libs/Named.bsv
+++ b/bscRuntime/libs/Named.bsv
@@ -1,3 +1,4 @@
+// Named.bsv
package Named;
import Memories :: *;
diff --git a/bscRuntime/libs/NamedEhr.bsv b/bscRuntime/libs/NamedEhr.bsv
index 70732d70..f8ed3b04 100644
--- a/bscRuntime/libs/NamedEhr.bsv
+++ b/bscRuntime/libs/NamedEhr.bsv
@@ -1,3 +1,4 @@
+// NamedEhr.bsv
package Named;
import RegFile :: *;
diff --git a/bscRuntime/libs/PdlFifo.bsv b/bscRuntime/libs/PdlFifo.bsv
deleted file mode 100644
index e69de29b..00000000
diff --git a/bscRuntime/libs/PrioFifo.bsv b/bscRuntime/libs/PrioFifo.bsv
index bd609eec..61341409 100644
--- a/bscRuntime/libs/PrioFifo.bsv
+++ b/bscRuntime/libs/PrioFifo.bsv
@@ -1,3 +1,4 @@
+// PrioFifo.bsv
package PrioFifo;
import FIFOF :: *;
diff --git a/bscRuntime/libs/Speculation.bsv b/bscRuntime/libs/Speculation.bsv
index 4397bd53..da90ce7b 100644
--- a/bscRuntime/libs/Speculation.bsv
+++ b/bscRuntime/libs/Speculation.bsv
@@ -1,3 +1,4 @@
+// Speculation.bsv
package Speculation;
import Vector :: *;
diff --git a/bscRuntime/libs/nametb.bsv b/bscRuntime/libs/nametb.bsv
index 7d74a0d9..ea43bdb0 100644
--- a/bscRuntime/libs/nametb.bsv
+++ b/bscRuntime/libs/nametb.bsv
@@ -1,3 +1,4 @@
+// nametb.bsv
import Named::*;
import FIFO::*;
diff --git a/bscRuntime/libs/project/build.properties b/bscRuntime/libs/project/build.properties
new file mode 100644
index 00000000..c8fcab54
--- /dev/null
+++ b/bscRuntime/libs/project/build.properties
@@ -0,0 +1 @@
+sbt.version=1.6.2
diff --git a/bscRuntime/libs/tb.bsv b/bscRuntime/libs/tb.bsv
index c4ce500b..7e2f1727 100644
--- a/bscRuntime/libs/tb.bsv
+++ b/bscRuntime/libs/tb.bsv
@@ -1,3 +1,4 @@
+// tb.bsv
import Memories :: *;
import Connectable :: *;
diff --git a/bscRuntime/memories/Ehr.bsv b/bscRuntime/memories/Ehr.bsv
index 98048693..e85b6252 100644
--- a/bscRuntime/memories/Ehr.bsv
+++ b/bscRuntime/memories/Ehr.bsv
@@ -1,3 +1,4 @@
+// Ehr.bsv
// Copyright (c) 2017 Massachusetts Institute of Technology
//
diff --git a/bscRuntime/memories/Interrupt.bsv b/bscRuntime/memories/Interrupt.bsv
new file mode 100644
index 00000000..b47c39ee
--- /dev/null
+++ b/bscRuntime/memories/Interrupt.bsv
@@ -0,0 +1,35 @@
+package Interrupt;
+
+import FIFOF :: *;
+import Ehr :: *;
+
+interface TimingInterruptController#(numeric type addr);
+ method ActionValue#(Bool) req(Int#(addr) a);
+ method Action ack(Int#(addr) a);
+endinterface
+
+module mkTimingInterruptController(TimingInterruptController#(addr) _unused_);
+
+ Reg#(Bool) status <- mkReg(False);
+ Reg#(UInt#(10)) timer <- mkReg(0);
+ Wire#(Int#(addr)) getAck <- mkWire();
+
+ // rule to update timer and set status to True every 1000 cycle
+ rule updateTimer;
+ timer <= timer + 1;
+ if (timer == 999) begin
+ timer <= 0;
+ status <= True;
+ end
+ endrule
+
+ method ActionValue#(Bool) req(Int#(addr) p);
+ return status;
+ endmethod
+
+ method Action ack(Int#(addr) a);
+ status <= False;
+ endmethod
+endmodule
+
+endpackage
\ No newline at end of file
diff --git a/bscRuntime/memories/Locks.bsv b/bscRuntime/memories/Locks.bsv
index b54b018a..8dbc14e7 100644
--- a/bscRuntime/memories/Locks.bsv
+++ b/bscRuntime/memories/Locks.bsv
@@ -1,3 +1,4 @@
+// Locks.bsv
package Locks;
import FIFOF :: *;
@@ -158,8 +159,8 @@ module mkCheckpointQueueLock(Put#(winfo) mem, CheckpointQueueLock#(LockId#(d), L
method Action abort();
nextId[0] <= 0;
- owner <= 0;
- empty <= True;
+ owner <= 0;
+ empty <= True;
wdata <= tagged Invalid;
endmethod
diff --git a/bscRuntime/memories/Makefile b/bscRuntime/memories/Makefile
index 8f592c0c..7b7c84dc 100644
--- a/bscRuntime/memories/Makefile
+++ b/bscRuntime/memories/Makefile
@@ -1,5 +1,5 @@
BSC=bsc -no-show-timestamps -no-show-version --aggressive-conditions
-TOBUILD=Ehr.bo Locks.bo Memories.bo Speculation.bo SpecialQueues.bo
+TOBUILD=Ehr.bo Locks.bo Memories.bo Speculation.bo SpecialQueues.bo Interrupt.bo
## Default simulator is iverilog
VSIM = -vsim iverilog
diff --git a/bscRuntime/memories/Memories.bsv b/bscRuntime/memories/Memories.bsv
index a49719d4..509cf149 100644
--- a/bscRuntime/memories/Memories.bsv
+++ b/bscRuntime/memories/Memories.bsv
@@ -1,3 +1,4 @@
+// Memories.bsv
package Memories;
import GetPut :: *;
@@ -21,6 +22,7 @@ export AsyncMem(..);
export AsyncMem2(..);
export QueueLockCombMem(..);
export CheckpointQueueLockCombMem(..);
+export CheckpointQueueLockAsyncMem(..);
export QueueLockAsyncMem(..);
export QueueLockAsyncMem2(..);
export BypassLockCombMem(..);
@@ -37,6 +39,7 @@ export mkAsyncMem;
export mkAsyncMem2;
export mkQueueLockCombMem;
export mkCheckpointQueueLockCombMem;
+export mkCheckpointQueueLockAsyncMem;
export mkQueueLockAsyncMem;
export mkQueueLockAsyncMem2;
export mkFAAddrLockCombMem;
@@ -61,6 +64,14 @@ function Bool isNewer(UInt#(sz) a, UInt#(sz) b, UInt#(sz) h);
return !isOlder(a, b, h);
endfunction
+function Put#(Tuple3#(Bit#(nsz), addr, elem)) asyncMemToPut (AsyncMem#(addr, elem, MemId#(inflight), nsz) amem);
+ return (interface Put;
+ method Action put(Tuple3#(Bit#(nsz), addr, elem) x);
+ amem.silentReq1(tpl_2(x), tpl_3(x), tpl_1(x));
+ endmethod
+ endinterface);
+endfunction
+
function Put#(Tuple2#(addr, elem)) rfToPut (RegFile#(addr, elem) rf);
return (interface Put;
method Action put(Tuple2#(addr, elem) x);
@@ -83,6 +94,7 @@ endinterface
interface AsyncMem#(type addr, type elem, type mid, numeric type nsz);
method ActionValue#(mid) req1(addr a, elem b, Bit#(nsz) wmask);
+ method Action silentReq1(addr a, elem b, Bit#(nsz) wmask);
method elem peekResp1(mid a);
method Bool checkRespId1(mid a);
method Action resp1(mid a);
@@ -129,6 +141,14 @@ interface CheckpointQueueLockCombMem#(type addr, type elem, type id, type cid);
method Action atom_w(addr a, elem b);
endinterface
+interface CheckpointQueueLockAsyncMem#(type addr, type elem, type rid, numeric type nsz, type id, type cid);
+ interface AsyncMem#(addr, elem, rid, nsz) mem;
+ interface CheckpointQueueLock#(id, cid, Tuple3#(Bit#(nsz), addr, elem)) lock;
+ method Action write(addr a, elem b, Bit#(nsz) wmask);
+ method Bool canAtom1(addr a);
+ method ActionValue#(rid) atom_req1(addr a, elem b, Bit#(nsz) wmask);
+endinterface
+
interface QueueLockAsyncMem#(type addr, type elem, type rid, numeric type nsz, type lid);
interface AsyncMem#(addr, elem, rid, nsz) mem;
interface QueueLock#(lid) lock;
@@ -242,7 +262,7 @@ module mkBramPort#(parameter Bool init, parameter String file)(BramPort#(addr, e
interface Server bram_server;
interface Put request;
method Action put (Tuple3#(Bit#(nsz), addr, elem) req);
- // $display("Sending request %t", $time());
+ //$display("Sending request %t %d %d ", $time(), tpl_1(req), tpl_3(req));
p.put(tpl_1(req), tpl_2(req), tpl_3(req));
doRead <= True;
endmethod
@@ -250,6 +270,7 @@ module mkBramPort#(parameter Bool init, parameter String file)(BramPort#(addr, e
interface Get response;
method ActionValue#(elem) get();
+ //$display("Returning data %t %d", nextData);
return nextData;
endmethod
endinterface
@@ -331,6 +352,8 @@ module mkAsyncMem(AsyncMem#(addr, elem, MemId#(inflight), n) _unused_)
Wire#(Tuple3#(Bit#(n), addr, elem)) toMem <- mkWire();
Wire#(elem) fromMem <- mkWire();
+ RWire#(Bool) doClear <- mkRWireSBR();
+
//this must be at least size 2 to work correctly (safe bet)
Vector#(inflight, Ehr#(2, elem)) outData <- replicateM( mkEhr(unpack(0)) );
Vector#(inflight, Ehr#(2, Bool)) valid <- replicateM( mkEhr(False) );
@@ -348,17 +371,24 @@ module mkAsyncMem(AsyncMem#(addr, elem, MemId#(inflight), n) _unused_)
valid[idx][0] <= True;
endrule
+ (*conflict_free = "freeResp, doClearRule"*)
(*fire_when_enabled*)
rule freeResp;
valid[freeEntry][1] <= False;
endrule
- method Action clear();
+ (*no_implicit_conditions*)
+ rule doClearRule (doClear.wget() matches tagged Valid.d);
+ //$display("Memory Cleared");
head <= 0;
for (Integer i = 0; i < valueOf(inflight); i = i + 1) begin
- MemId#(inflight) ent = fromInteger(i);
- valid[ent][1] <= False;
+ MemId#(inflight) ent = fromInteger(i);
+ valid[ent][1] <= False;
end
+ endrule
+
+ method Action clear();
+ doClear.wset(True);
endmethod
method ActionValue#(MemId#(inflight)) req1(addr a, elem b, Bit#(n) wmask) if (okToRequest);
@@ -368,6 +398,11 @@ module mkAsyncMem(AsyncMem#(addr, elem, MemId#(inflight), n) _unused_)
return head;
endmethod
+ method Action silentReq1(addr a, elem b, Bit#(n) wmask) if (okToRequest);
+ toMem <= tuple3(wmask, a, b);
+ head <= head + 1;
+ endmethod
+
method elem peekResp1(MemId#(inflight) a);
return outData[a][1];
endmethod
@@ -671,6 +706,30 @@ module mkDMAddrLockCombMem(RegFile#(addr, elem) rf, AddrLockCombMem#(addr, elem,
interface lock = l;
endmodule
+module mkCheckpointQueueLockAsyncMem(AsyncMem#(addr, elem, MemId#(inflight), nsz) amem, CheckpointQueueLockAsyncMem#(addr, elem, MemId#(inflight), nsz, LockId#(d), LockId#(d)) _unused_)
+provisos(Bits#(Tuple3#(Bit#(nsz), addr, elem), tuplsz));
+
+ Put#(Tuple3#(Bit#(nsz), addr, elem)) doWrite = asyncMemToPut(amem);
+ CheckpointQueueLock#(LockId#(d), LockId#(d), Tuple3#(Bit#(nsz), addr, elem)) l <- mkCheckpointQueueLock(doWrite);
+
+ interface lock = l;
+ interface mem = amem;
+
+ method Action write(addr a, elem b, Bit#(nsz) wmask);
+ l.write(tuple3(wmask, a, b));
+ endmethod
+
+ method Bool canAtom1(addr a);
+ return l.isEmpty;
+ endmethod
+
+ method ActionValue#(MemId#(inflight)) atom_req1(addr a, elem b, Bit#(nsz) wmask);
+ let r <- amem.req1(a, b, wmask);
+ return r;
+ endmethod
+
+endmodule
+
module mkQueueLockAsyncMem(AsyncMem#(addr, elem, MemId#(inflight), n) amem, QueueLockAsyncMem#(addr, elem, MemId#(inflight), n, LockId#(d)) _unused_)
provisos(Bits#(addr, szAddr), Bits#(elem, szElem));
diff --git a/bscRuntime/memories/SpecialQueues.bsv b/bscRuntime/memories/SpecialQueues.bsv
index b526a2f7..f7aa3214 100644
--- a/bscRuntime/memories/SpecialQueues.bsv
+++ b/bscRuntime/memories/SpecialQueues.bsv
@@ -1,3 +1,4 @@
+// SpecialQueues.bsv
package SpecialQueues;
import Ehr :: *;
@@ -57,26 +58,26 @@ module mkNBFIFOF(FIFOF#(dtyp)) provisos (Bits#(dtyp, szdtyp));
FIFOF#(dtyp) f <- mkFIFOF();
//allow multiple writes in the same cycle
RWire#(dtyp) enq_data <- mkRWireSBR();
+ RWire#(Bool) doClear <- mkRWireSBR();
- //Make sure no enq could happen during clear (takes 2 cycles)
- Reg#(Bool) clearCalled <- mkReg(False);
-
- rule doClear(clearCalled);
- f.clear();
- clearCalled <= False;
- endrule
-
+ (*conflict_free = "doEnqRule, doClearRule"*)
(*fire_when_enabled*)
- rule doEnq (enq_data.wget() matches tagged Valid.d);
+ rule doEnqRule (enq_data.wget() matches tagged Valid.d);
f.enq(d);
endrule
+ //reset to the initial state
+ (*no_implicit_conditions*)
+ rule doClearRule (doClear.wget() matches tagged Valid.d);
+ f.clear();
+ endrule
+
//only allow the LAST enq each cycle to work, drop the others
- method Action enq(dtyp a) if (f.notFull() && !clearCalled);
+ method Action enq(dtyp a) if (f.notFull());
enq_data.wset(a);
endmethod
- method Action deq() if (!clearCalled);
+ method Action deq();
f.deq();
endmethod
@@ -93,7 +94,7 @@ module mkNBFIFOF(FIFOF#(dtyp)) provisos (Bits#(dtyp, szdtyp));
endmethod
method Action clear();
- clearCalled <= True;
+ doClear.wset(True);
endmethod
endmodule
diff --git a/bscRuntime/memories/Speculation.bsv b/bscRuntime/memories/Speculation.bsv
index e2e019ab..3702903d 100644
--- a/bscRuntime/memories/Speculation.bsv
+++ b/bscRuntime/memories/Speculation.bsv
@@ -1,3 +1,4 @@
+// Speculation.bsv
package Speculation;
import Vector :: *;
@@ -41,30 +42,43 @@ module mkSpecTable(SpecTable#(SpecId#(entries), bypassCnt));
$display("Head: %d", head);
for (Integer i = 0; i < valueOf(entries); i = i + 1)
begin
- $display("Idx %d, InUse: %b", i, inUse[fromInteger(i)]);
- $display("Idx %d, Status: %b", i, specStatus[fromInteger(i)]);
+ $display("Idx %d, InUse: %b", i, inUse[fromInteger(i)]);
+ $display("Idx %d, Status: %b", i, specStatus[fromInteger(i)][0]);
end
endrule
- */
-
+ */
+ //Make sure no enq could happen during clear (takes 2 cycles)
+
RWire#(Bool) doAlloc <- mkRWireSBR();
+ RWire#(Bool) doClear <- mkRWireSBR();
+
+ /*
+ Reg#(Bool) enabled <- mkReg(True);
+ */
+ (*conflict_free = "doAllocRule, doClearRule"*)
(*fire_when_enabled*)
rule doAllocRule (doAlloc.wget() matches tagged Valid.d);
- head <= head + 1;
- inUse[head] <= True;
- specStatus[head][valueOf(bypassCnt)-1] <= tagged Invalid;
+ head <= head + 1;
+ inUse[head] <= True;
+ specStatus[head][valueOf(bypassCnt)-1] <= tagged Invalid;
endrule
-
+
//reset to the initial state
+ (*no_implicit_conditions*)
+ rule doClearRule (doClear.wget() matches tagged Valid.d);
+ //$display("SpecTable Cleared");
+ head <= 0;
+ for (Integer i = 0; i < valueOf(entries); i = i + 1) begin
+ SpecId#(entries) lv = fromInteger(i);
+ specStatus[lv][0] <= tagged Invalid;
+ inUse[lv] <= False;
+ end
+ endrule
+
method Action clear();
- head <= 0;
- for (Integer i = 0; i < valueOf(entries); i = i + 1) begin
- SpecId#(entries) lv = fromInteger(i);
- specStatus[lv][0] <= tagged Invalid;
- inUse[lv] <= False;
- end
+ doClear.wset(True);
endmethod
-
+
//allocate a new entry in the table to track speculation. do this in a nonblocking way
//and just assume that only 1 client calls per cycle
method ActionValue#(SpecId#(entries)) alloc() if (!full);
diff --git a/bscRuntime/memories/StgFIFOs.bsv b/bscRuntime/memories/StgFIFOs.bsv
new file mode 100644
index 00000000..2e757a1b
--- /dev/null
+++ b/bscRuntime/memories/StgFIFOs.bsv
@@ -0,0 +1,58 @@
+// StgFIFOs.bsv
+package StgFIFOs;
+
+import Ehr :: *;
+import ConfigReg :: *;
+import FIFOF :: *;
+
+export mkStgFIFOF;
+
+// Change to a CReg, two element Queue for per cycle.
+module mkStgFIFOF(FIFOF#(dtyp)) provisos (Bits#(dtyp, szdtyp));
+
+ FIFOF#(dtyp) f <- mkFIFOF();
+ //allow multiple writes in the same cycle
+ RWire#(dtyp) enq_data <- mkRWireSBR();
+ RWire#(Bool) doClear <- mkRWireSBR();
+
+ //Make sure no enq could happen during clear (takes 2 cycles)
+
+ (*conflict_free = "doEnqRule, doFIFOClearRule"*)
+ (*fire_when_enabled, no_implicit_conditions*)
+ rule doEnqRule (enq_data.wget() matches tagged Valid.d);
+ f.enq(d);
+ endrule
+
+ (*fire_when_enabled, no_implicit_conditions*)
+ rule doFIFOClearRule (doClear.wget() matches tagged Valid.d);
+ f.clear();
+ endrule
+
+ //only allow the LAST enq each cycle to work, drop the others
+ method Action enq(dtyp a) if (f.notFull());
+ enq_data.wset(a);
+ endmethod
+
+ method Action deq();
+ f.deq();
+ endmethod
+
+ method dtyp first();
+ return f.first();
+ endmethod
+
+ method Bool notFull();
+ return f.notFull();
+ endmethod
+
+ method Bool notEmpty();
+ return f.notEmpty();
+ endmethod
+
+ method Action clear();
+ doClear.wset(True);
+ endmethod
+
+endmodule
+
+endpackage
diff --git a/bscRuntime/memories/tb.bsv b/bscRuntime/memories/tb.bsv
index 53d0a29a..68a0c2ca 100644
--- a/bscRuntime/memories/tb.bsv
+++ b/bscRuntime/memories/tb.bsv
@@ -1,3 +1,4 @@
+// tb.bsv
import Locks :: *;
import Memories::*;
import FIFO::*;
diff --git a/bscRuntime/verilog/BHT.v b/bscRuntime/verilog/BHT.v
index 4f9d4aa0..97f6537f 100644
--- a/bscRuntime/verilog/BHT.v
+++ b/bscRuntime/verilog/BHT.v
@@ -1,3 +1,4 @@
+// BHT.v
`ifdef BSV_ASSIGNMENT_DELAY
`else
`define BSV_ASSIGNMENT_DELAY
diff --git a/bscRuntime/verilog/BypassRF.v b/bscRuntime/verilog/BypassRF.v
index 209c9205..f3920c9f 100644
--- a/bscRuntime/verilog/BypassRF.v
+++ b/bscRuntime/verilog/BypassRF.v
@@ -1,3 +1,4 @@
+// BypassRF.v
`ifdef BSV_ASSIGNMENT_DELAY
`else
`define BSV_ASSIGNMENT_DELAY
diff --git a/bscRuntime/verilog/CheckpointBypassRF.v b/bscRuntime/verilog/CheckpointBypassRF.v
index c1268d71..f042a687 100644
--- a/bscRuntime/verilog/CheckpointBypassRF.v
+++ b/bscRuntime/verilog/CheckpointBypassRF.v
@@ -1,3 +1,4 @@
+// CheckpointBypassRF.v
`ifdef BSV_ASSIGNMENT_DELAY
`else
`define BSV_ASSIGNMENT_DELAY
diff --git a/bscRuntime/verilog/CheckpointRenameRF.v b/bscRuntime/verilog/CheckpointRenameRF.v
index 149c0816..134e874c 100644
--- a/bscRuntime/verilog/CheckpointRenameRF.v
+++ b/bscRuntime/verilog/CheckpointRenameRF.v
@@ -1,3 +1,4 @@
+// CheckpointRenameRF.v
`ifdef BSV_ASSIGNMENT_DELAY
`else
`define BSV_ASSIGNMENT_DELAY
@@ -21,6 +22,7 @@ module CheckpointRenameRF(CLK,
VALID_NAME_2, VALID_OUT_2, //check valid data 2
NAME_F, FE, //free name
CHK_OUT, CHK_E, CHK_READY, //checkpoint req
+ ABORT, //abort req
ROLLBK_IN, DO_ROLL, DO_REL, ROLLBK_E //rollback req
);
@@ -83,7 +85,9 @@ module CheckpointRenameRF(CLK,
//rollback
input [replica_width - 1 : 0] ROLLBK_IN;
input ROLLBK_E, DO_ROLL, DO_REL;
-
+
+ //abort
+ input ABORT;
parameter copy_width = name_width * (hi_arch-lo_arch+1);
//arch reg file (name file)
@@ -155,24 +159,31 @@ module CheckpointRenameRF(CLK,
always@(*)
begin
- if (ROLLBK_E)
- begin
- case ({DO_REL, DO_ROLL})
- 2'b00 : nextFreeReplicas = freeReplicas;
- 2'b01 : nextFreeReplicas = ~(1 << ROLLBK_IN); // free everything but ROLLBK_IN
- 2'b10 : nextFreeReplicas = freeReplicas | (1 << ROLLBK_IN); //only free ROLLBK_IN
- 2'b11 : nextFreeReplicas = ~0; // free everything
- endcase // case ({DO_REL, DO_ROLL})
- end
- else
- begin
- nextFreeReplicas = freeReplicas;
- end // else: !if(ROLLBK_E)
+ if (ABORT)
+ begin
+ nextFreeReplicas = ~0;
+ end // if abort
+ else
+ begin
+ if (ROLLBK_E)
+ begin
+ case ({DO_REL, DO_ROLL})
+ 2'b00 : nextFreeReplicas = freeReplicas;
+ 2'b01 : nextFreeReplicas = ~(1 << ROLLBK_IN); // free everything but ROLLBK_IN
+ 2'b10 : nextFreeReplicas = freeReplicas | (1 << ROLLBK_IN); //only free ROLLBK_IN
+ 2'b11 : nextFreeReplicas = ~0; // free everything
+ endcase // case ({DO_REL, DO_ROLL})
+ end
+ else
+ begin
+ nextFreeReplicas = freeReplicas;
+ end // else: !if(ROLLBK_E)
+ end // if not abort
if (CHK_E & nextReplicaValid)
- begin
- nextFreeReplicas[nextReplica] = 0;
- end
- end // always@ begin
+ begin
+ nextFreeReplicas[nextReplica] = 0;
+ end
+ end // always@ begin
assign CHK_READY = nextReplicaValid;
assign CHK_OUT = nextReplica;
@@ -265,6 +276,14 @@ module CheckpointRenameRF(CLK,
end
else
begin
+ if (ABORT)
+ begin
+ names <= `BSV_ASSIGNMENT_DELAY name_copies[0] | name_copies[1];
+ free <= `BSV_ASSIGNMENT_DELAY free_copies[0] | free_copies[1] | (FE << oldName) | free;
+ freeReplicas <= `BSV_ASSIGNMENT_DELAY nextFreeReplicas;
+ end // if(abort)
+ else
+ begin
//ROLLBK_E & DO_ROLL => !CHK_E & !ALLOC_E
if (ROLLBK_E | (CHK_E & nextReplicaValid))
begin
@@ -302,6 +321,7 @@ module CheckpointRenameRF(CLK,
begin
free[oldName] <= `BSV_ASSIGNMENT_DELAY 1;
end
+ end // else: !if(ABORT)
end // else: !if(RST)
end // always@ (posedge CLK)
diff --git a/bscRuntime/verilog/ForwardRenameRF.v b/bscRuntime/verilog/ForwardRenameRF.v
index be253aa4..8f8f6a1c 100644
--- a/bscRuntime/verilog/ForwardRenameRF.v
+++ b/bscRuntime/verilog/ForwardRenameRF.v
@@ -1,3 +1,4 @@
+// ForwardRenameRF.v
`ifdef BSV_ASSIGNMENT_DELAY
`else
`define BSV_ASSIGNMENT_DELAY
diff --git a/bscRuntime/verilog/RenameRF.v b/bscRuntime/verilog/RenameRF.v
index 3a255523..0c821f6f 100644
--- a/bscRuntime/verilog/RenameRF.v
+++ b/bscRuntime/verilog/RenameRF.v
@@ -1,3 +1,4 @@
+// RenameRF.v
`ifdef BSV_ASSIGNMENT_DELAY
`else
`define BSV_ASSIGNMENT_DELAY
diff --git a/bscRuntime/verilog/VerilogLibs.bsv b/bscRuntime/verilog/VerilogLibs.bsv
index cdcb1df8..fe49cd11 100644
--- a/bscRuntime/verilog/VerilogLibs.bsv
+++ b/bscRuntime/verilog/VerilogLibs.bsv
@@ -1,3 +1,4 @@
+// VerilogLibs.bsv
package VerilogLibs;
import RegFile :: *;
@@ -39,6 +40,7 @@ interface CheckpointRF#(type addr, type elem, type name, type cid);
method Action write(name a, elem b); //write data given allocated name
method ActionValue#(cid) checkpoint();
method Action rollback(cid c, Bool doRoll, Bool doRel);
+ method Action abort(); //abort
endinterface
interface BypassRF#(type addr, type elem, type id);
@@ -136,7 +138,7 @@ import "BVI" ForwardRenameRF =
method D_OUT read[2] (NAME);
method NAME_OUT res_w1(ADDR_IN) enable(ALLOC_E) ready(ALLOC_READY);
method rel_w1(NAME_F) enable(FE);
- method write[2] (NAME_IN, D_IN) enable(WE);
+ method write[2] (NAME_IN, D_IN) enable(WE);
schedule (res_r1,res_r2) CF (res_r1,res_r2);
schedule (res_r1,res_r2) CF (owns_r1, owns_r2, read, res_w1, write, rel_w1);
@@ -183,11 +185,14 @@ import "BVI" CheckpointRenameRF =
method CHK_OUT checkpoint() enable(CHK_E) ready(CHK_READY);
method rollback (ROLLBK_IN, DO_ROLL, DO_REL) enable(ROLLBK_E);
-
+
+ method abort() enable(ABORT);
+
schedule (checkpoint) C (checkpoint);
schedule (rollback) C (rollback);
+ schedule (abort) C (abort);
schedule (checkpoint) CF (rollback);
- schedule (checkpoint, rollback) CF (res_r1, res_r2, owns_r1, owns_r2, read, write, rel_w1);
+ schedule (checkpoint, rollback) CF (res_r1, res_r2, owns_r1, owns_r2, read, write, rel_w1);
schedule (res_r1, res_r2) CF (res_r1, res_r2);
schedule (res_r1, res_r2) CF (owns_r1, owns_r2, read, res_w1, write, rel_w1);
schedule (owns_r1, owns_r2) CF (owns_r1, owns_r2);
@@ -198,7 +203,8 @@ import "BVI" CheckpointRenameRF =
schedule (res_w1) CF (write, rel_w1, checkpoint, rollback);
schedule (write) CF (write, rel_w1);
schedule (rel_w1) C (rel_w1);
-
+ schedule (abort) CF (checkpoint, rollback, res_r1, res_r2, res_w1, owns_r1, owns_r2, read, write, rel_w1);
+
endmodule
diff --git a/bscRuntime/verilog/tb.bsv b/bscRuntime/verilog/tb.bsv
index a6e9b836..3d2c92c0 100644
--- a/bscRuntime/verilog/tb.bsv
+++ b/bscRuntime/verilog/tb.bsv
@@ -1,3 +1,4 @@
+// tb.bsv
import VerilogLibs::*;
import FIFO::*;
import RegFile :: *;
diff --git a/src/main/scala/pipedsl/Interpreter.scala b/src/main/scala/pipedsl/Interpreter.scala
index 01a1936d..3439b50f 100644
--- a/src/main/scala/pipedsl/Interpreter.scala
+++ b/src/main/scala/pipedsl/Interpreter.scala
@@ -1,3 +1,4 @@
+/* Interpreter.scala */
package pipedsl
import java.io.{File, PrintWriter}
diff --git a/src/main/scala/pipedsl/Main.scala b/src/main/scala/pipedsl/Main.scala
index 95657717..f9b4a011 100644
--- a/src/main/scala/pipedsl/Main.scala
+++ b/src/main/scala/pipedsl/Main.scala
@@ -1,3 +1,4 @@
+/* Main.scala */
package pipedsl
import java.io.{File, PrintWriter}
@@ -73,6 +74,7 @@ object Main {
try {
val pinfo = new ProgInfo(prog)
+
MarkNonRecursiveModulePass.run(prog)
//First: add lock regions + checkpoints, then do other things
val inferredProg = new LockRegionInferencePass().run(prog)
diff --git a/src/main/scala/pipedsl/Parser.scala b/src/main/scala/pipedsl/Parser.scala
index 0ba7061c..83d7e849 100644
--- a/src/main/scala/pipedsl/Parser.scala
+++ b/src/main/scala/pipedsl/Parser.scala
@@ -1,3 +1,4 @@
+/* Parser.scala */
package pipedsl
import scala.util.parsing.combinator._
import common.Syntax._
@@ -262,7 +263,7 @@ class Parser(rflockImpl: String) extends RegexParsers with PackratParsers {
typ.? ~ lhs ~ "<-" ~ expr ^^ { case t ~ l ~ _ ~ r => l.typ = t; CRecv(l, r) } |
check |
resolveSpec |
- "except" ~> parens(repsep(expr, ",")) ^^ {args => CExcept(args)} |
+ catchInterrupt | throwExn |
"start" ~> parens(iden) ^^ { i => CLockStart(i) } |
"end" ~> parens(iden) ^^ { i => CLockEnd(i) } |
"acquire" ~> parens(lockArg ~ ("," ~> lockType).?) ^^ { case i ~ t => CSeq(CLockOp(i, Reserved, t, List(), None), CLockOp(i, Acquired, t, List(), None)) } |
@@ -318,12 +319,21 @@ class Parser(rflockImpl: String) extends RegexParsers with PackratParsers {
case ni ~ _ ~ _ ~ (oi ~ _ ~ e) => CUpdate(EVar(ni), oi, e, List(), List()) }
}
+ lazy val throwExn: P[Command] = positioned {
+ "throw" ~> parens(repsep(expr, ",")) ^^ {args => CExcept(args)}
+ }
+
lazy val resolveSpec: P[Command] = positioned {
"verify" ~> parens(variable ~ "," ~ repsep(expr,",")) ~ braces(methodCall).? ^^ {
case i ~ _ ~ e ~ u => CVerify(i, e, List(), u, List()) } |
"invalidate" ~> parens(variable) ^^ (i => CInvalidate(i, List()))
}
+ lazy val catchInterrupt: P[Command] = positioned {
+ "catch" ~> parens(iden) ~ braces(throwExn).? ^^ {
+ case i ~ u => CCatch(i, u.get)}
+ }
+
lazy val casestmt: P[CaseObj] = positioned {
"case:" ~> expr ~ block ^^ { case e ~ b => CaseObj(e, b) }
}
diff --git a/src/main/scala/pipedsl/codegen/Translations.scala b/src/main/scala/pipedsl/codegen/Translations.scala
index b4df86b5..4ddfe12e 100644
--- a/src/main/scala/pipedsl/codegen/Translations.scala
+++ b/src/main/scala/pipedsl/codegen/Translations.scala
@@ -1,3 +1,4 @@
+/* Translations.scala */
package pipedsl.codegen
import pipedsl.common.Syntax._
diff --git a/src/main/scala/pipedsl/codegen/bsv/BSVPrettyPrinter.scala b/src/main/scala/pipedsl/codegen/bsv/BSVPrettyPrinter.scala
index efc0e1e7..bda66356 100644
--- a/src/main/scala/pipedsl/codegen/bsv/BSVPrettyPrinter.scala
+++ b/src/main/scala/pipedsl/codegen/bsv/BSVPrettyPrinter.scala
@@ -1,6 +1,8 @@
+/* BSVPrettyPrinter.scala */
package pipedsl.codegen.bsv
import java.io.{File, FileOutputStream, OutputStreamWriter, Writer}
+import java.math.BigInteger
import pipedsl.codegen.bsv.BSVSyntax._
import pipedsl.common.Errors.BaseError
@@ -68,7 +70,7 @@ object BSVPrettyPrinter {
case BInteger() => "Integer"
}
- private def toIntString(base: Int, value: Int): String = base match {
+ private def toIntString(base: Int, value: Int, bits: Int): String = base match {
case 16 => "h" + value.toHexString
case 10 => "d" + value.toString
case 8 => "o" + value.toOctalString
@@ -96,7 +98,7 @@ object BSVPrettyPrinter {
"False"
}
case BUnsizedInt(v) => v.toString
- case BIntLit(v, base, bits) => bits.toString + "'" + toIntString(base, v)
+ case BIntLit(v, base, bits) => bits.toString + "'" + toIntString(base, v, bits)
case BStringLit(v) => "\"" + v + "\""
case BStructLit(typ, fields) =>
val fieldStr = fields.keys.map(k => {
@@ -128,6 +130,7 @@ object BSVPrettyPrinter {
val argstring = args.map(a => toBSVExprStr(a)).mkString(", ")
mkExprString(name, "(", argstring, ")")
case BMethodInvoke(mod, method, args) =>
+ println(mod, method, args)
val argstring = args.map(a => toBSVExprStr(a)).mkString(", ")
val argStringFull = if (argstring.isEmpty) "" else "(" + argstring + ")"
toBSVExprStr(mod) + "." + method + argStringFull
diff --git a/src/main/scala/pipedsl/codegen/bsv/BSVSyntax.scala b/src/main/scala/pipedsl/codegen/bsv/BSVSyntax.scala
index 01067bea..cbd24917 100644
--- a/src/main/scala/pipedsl/codegen/bsv/BSVSyntax.scala
+++ b/src/main/scala/pipedsl/codegen/bsv/BSVSyntax.scala
@@ -1,3 +1,4 @@
+/* BSVSyntax.scala */
package pipedsl.codegen.bsv
import pipedsl.codegen.Translations.Translator
@@ -182,7 +183,11 @@ object BSVSyntax {
}
def toExpr(e: Expr): BExpr = e match {
- case EInt(v, base, bits) => BIntLit(v, base, bits)
+ case EInt(v, base, bits) => bits match {
+ case -1 if v == 0 => BZero
+ case -1 if v == 1 => BAllOnes
+ case _ => BIntLit(v, base, bits)
+ } // TODO - EXN: Very ad-hoc stuff.. need Fix
case EBool(v) => BBoolLit(v)
case EString(v) => BStringLit(v)
case eu@EUop(_, _) => translateUOp(eu)
diff --git a/src/main/scala/pipedsl/codegen/bsv/BluespecGeneration.scala b/src/main/scala/pipedsl/codegen/bsv/BluespecGeneration.scala
index 92df2f91..d1b72e35 100644
--- a/src/main/scala/pipedsl/codegen/bsv/BluespecGeneration.scala
+++ b/src/main/scala/pipedsl/codegen/bsv/BluespecGeneration.scala
@@ -1,3 +1,4 @@
+/* BluespecGeneration.scala */
package pipedsl.codegen.bsv
import BSVSyntax.{BBOp, BEmpty, _}
@@ -20,6 +21,7 @@ object BluespecGeneration {
private val specLib = "Speculation"
private val fifoLib = "FIFOF"
private val specFifoLib = "SpecialFIFOs"
+ private val stgFifoLib = "StgFIFOs"
private val queueLib = "SpecialQueues"
private val combLib = "RegFile"
private val asyncLib = "BRAMCore"
@@ -27,7 +29,7 @@ object BluespecGeneration {
private val ehrLib = "Ehr"
private def getRequiredTopLibs: List[BImport] = List(clientLib, connLib, lockLib, memLib, verilogLib, combLib, asyncLib).map(l => BImport(l))
- private def getRequiredModLibs: List[BImport] = List(fifoLib, specFifoLib, queueLib, lockLib, memLib, verilogLib, specLib, combLib, ehrLib).map(l => BImport(l))
+ private def getRequiredModLibs: List[BImport] = List(fifoLib, stgFifoLib, specFifoLib, queueLib, lockLib, memLib, verilogLib, specLib, combLib, ehrLib).map(l => BImport(l))
class BluespecProgramGenerator(prog: Prog, stageInfo: Map[Id, List[PStage]], pinfo: ProgInfo,
debug: Boolean = false, bsInts: BluespecInterfaces, funcmodname: String = "Functions",
@@ -399,7 +401,7 @@ object BluespecGeneration {
private val outputData = BVar("data", translator.toType(mod.ret.getOrElse(TVoid())))
private val outputQueue = BVar("outputQueue", bsInts.getOutputQType(threadIdVar.typ, outputData.typ))
//Registers for exceptions
- private val globalExnFlag = BVar("_globalExnFlag", bsInts.getEhrType(2, BBool))
+ private val globalExnFlag = BVar("_globalExnFlag", bsInts.getRegType(BBool))
//Data types for passing between stages
private val edgeStructInfo = getEdgeStructInfo(otherStages, addTId = true, addSpecId = mod.maybeSpec)
//First stage should have exactly one input edge by definition
@@ -416,7 +418,7 @@ object BluespecGeneration {
es ++ s.inEdges ++ s.outEdges
})
val edgeParams: EdgeInfo = allEdges.foldLeft(Map[PipelineEdge, BVar]())((m, e) => {
- m + (e -> BVar(genParamName(e), bsInts.getFifoType(edgeMap(e))))
+ m + (e -> BVar(genParamName(e), bsInts.getStgFifoType(edgeMap(e))))
})
//Generate map from existing module parameter names to BSV variables
private val modParams: ModInfo = mod.modules.foldLeft[ModInfo](ListMap())((vars, m) => {
@@ -593,11 +595,17 @@ object BluespecGeneration {
val queueStmts = getEdgeQueueStmts(stg, stg.allEdges)
val blockingConds = getBlockingConds(stg.getCmds)
val recvConds = getRecvConds(stg.getCmds)
+ val exnDisjointConds = getExnKillConds(stg.getCmds, true)
+ val exnConds = if (exnDisjointConds.isEmpty) {
+ List[BExpr](globalExnFlag)
+ } else {
+ exnDisjointConds
+ }
val debugStmt = if (debug) {
BDisplay(Some(mod.name.v + ":Thread %d:Executing Stage " + stg.name + " %t"),
List(translator.toBSVVar(threadIdVar), BTime))
} else BEmpty
- BRuleDef( genParamName(stg) + "_execute", blockingConds ++ recvConds,
+ BRuleDef( genParamName(stg) + "_execute", (if(is_excepting(mod)) exnConds else List[BExpr]()) ++ blockingConds ++ recvConds,
writeCmdDecls ++ writeCmdStmts ++ queueStmts :+ debugStmt)
}
@@ -610,30 +618,38 @@ object BluespecGeneration {
*/
private def getStageKillRules(stg: PStage, is_spec: Boolean, is_excepting: Boolean): List[BRuleDef] = {
val misspecKillConds = getMisspecKillConds(stg.getCmds)
- val exnKillConds = getExnKillConds(stg.getCmds)
+ val exnKillConds = getExnKillConds(stg.getCmds, false)
+ val exnDisjointConds = getExnKillConds(stg.getCmds, true)
val recvConds = getRecvConds(stg.getCmds)
val misspecDebugStmt = if (debug) {
BDisplay(Some(mod.name.v + ":SpecId %d: Killing Stage (on Misspec)" + stg.name + "%t"),
List(getSpecIdVal, BTime))
} else { BEmpty }
val exnDebugStmt = if (debug) {
- BDisplay(Some(mod.name.v + "Killing Stage (on Exception)" + stg.name),
- List())
+ BDisplay(Some(mod.name.v + " Killing Stage (on Exception)" + "%t"),
+ List(BTime))
} else { BEmpty }
val deqStmts = getEdgeQueueStmts(stg, stg.inEdges) ++ getRecvCmds(stg.getCmds)
- val freeStmt = BExprStmt(bsInts.getSpecFree(specTable, getSpecIdVal))
- val misspecKillRule = Some(BRuleDef( genParamName(stg) + "_kill_on_misspec", misspecKillConds ++ recvConds, deqStmts :+ freeStmt :+ misspecDebugStmt))
- val exnKillRule = Some(BRuleDef(genParamName(stg) + "_kill_on_exn", exnKillConds, deqStmts :+ exnDebugStmt))
-
+ val freeStmt = if (!misspecKillConds.isEmpty) {
+ BExprStmt(bsInts.getSpecFree(specTable, getSpecIdVal))
+ } else { BEmpty }
+ val misspecKillRule = Some(BRuleDef(genParamName(stg) + "_kill_on_misspec", exnDisjointConds ++ misspecKillConds ++ recvConds, deqStmts :+ freeStmt :+ misspecDebugStmt))
+ val exnKillRule = Some(BRuleDef(genParamName(stg) + "_kill_on_exn", exnKillConds, deqStmts :+ freeStmt :+ exnDebugStmt))
var resultingKillRules = List[BRuleDef]()
if (misspecKillRule.isDefined && is_spec && !misspecKillConds.isEmpty) resultingKillRules = resultingKillRules :+ misspecKillRule.get
- if (exnKillRule.isDefined && is_excepting && !exnKillConds.isEmpty) resultingKillRules = resultingKillRules :+ exnKillRule.get
+ // if (exnKillRule.isDefined && is_excepting && !exnKillConds.isEmpty) resultingKillRules = resultingKillRules :+ exnKillRule.get
resultingKillRules
}
- private def getExnKillConds(cmds: Iterable[Command]): List[BExpr] = {
+ private def getExnKillConds(cmds: Iterable[Command], disjoint_cond: Boolean): List[BExpr] = {
cmds.foldLeft(List[BExpr]())((l, c) => c match {
- case IStageClear() => l :+ BVectorAccess(globalExnFlag, BIndConst(1))
+ case ICheckExn() => {
+ if (disjoint_cond) {
+ l :+ BUOp("!", globalExnFlag)
+ } else {
+ l :+ globalExnFlag
+ }
+ }
case _ => l
})
}
@@ -659,9 +675,6 @@ object BluespecGeneration {
} else {
l
}
- case IStageClear() =>
- val disjointCond = BUOp("!", BVectorAccess(globalExnFlag, BIndConst(1)))
- l :+ disjointCond
case _ => l
})
}
@@ -704,7 +717,7 @@ object BluespecGeneration {
} else {
l
}
- case im@IMemWrite(mem, addr, data, _, _, isAtomic) if isAtomic =>
+ case im@IMemWrite(mem, addr, data, writeMask, _, _, isAtomic) if isAtomic =>
val methodInfo = LockImplementation.getCanAtomicWrite(mem, addr, data, im.portNum)
if (methodInfo.isDefined) {
l :+ translateMethod(getLockName(mem), methodInfo.get)
@@ -834,6 +847,16 @@ object BluespecGeneration {
})
}
+ private def getInEdgeClearStmts(s: PStage, es: Iterable[PipelineEdge],
+ args: Option[Iterable[BExpr]] = None): List[BStatement] = {
+ es.foldLeft(List[BStatement]())((l, e) => {
+ if (e.to == s) {
+ val stmt = BExprStmt(bsInts.getFifoClear(edgeParams(e)))
+ l :+ stmt
+ } else { l }
+ })
+ }
+
/**
*
* @param stg The stage to compile
@@ -906,7 +929,7 @@ object BluespecGeneration {
if (mod.isRecursive) { bsInts.getNBFifo } else { bsInts.getBypassFifo })
val edgeFifos = allEdges.foldLeft(Map[PipelineEdge, BModInst]())((m, e) => {
if (e != startEdge) {
- m + (e -> BModInst(edgeParams(e), bsInts.getFifo))
+ m + (e -> BModInst(edgeParams(e), bsInts.getStgFifo))
} else {
m
}
@@ -939,8 +962,7 @@ object BluespecGeneration {
bsInts.getReg(BZero))
//Instantiate Exception Register
- val globalExnInst = BModInst(globalExnFlag, bsInts.getEhr(BBoolLit(false)))
-
+ val globalExnInst = BModInst(globalExnFlag, bsInts.getReg(BBoolLit(false)))
//Instantiate the speculation table if the module is speculative
val specInst = if (mod.maybeSpec) BModInst(specTable, bsInts.getSpecTable) else BEmpty
var stmts: List[BStatement] = startFifo +:
@@ -1036,7 +1058,7 @@ object BluespecGeneration {
private def getCombinationalDeclaration(cmd: Command): Option[BDecl] = cmd match {
case CAssign(lhs, _) => Some(BDecl(translator.toVar(lhs), None))
case IMemSend(_, _, _, _, _, _, outH, _) if outH.isDefined => Some(BDecl(translator.toVar(outH.get), None))
- case IMemWrite(_, _, _, _, outH, _) if outH.isDefined => Some(BDecl(translator.toVar(outH.get), None))
+ case IMemWrite(_, _, _, _, _, outH, _) if outH.isDefined => Some(BDecl(translator.toVar(outH.get), None))
case IMemRecv(_, _, data) => data match {
case Some(v) => Some(BDecl(translator.toVar(v), None))
case None => None
@@ -1082,7 +1104,7 @@ object BluespecGeneration {
case CExpr(exp) => Some(BExprStmt(translator.toExpr(exp)))
case IMemSend(_, _, _, _, _, inH, outH, _) if inH.isDefined && outH.isDefined =>
Some(BAssign(translator.toVar(outH.get), translator.toExpr(inH.get)))
- case IMemWrite(_, _, _, inH, outH, _) if inH.isDefined && outH.isDefined =>
+ case IMemWrite(_, _, _, _, inH, outH, _) if inH.isDefined && outH.isDefined =>
Some(BAssign(translator.toVar(outH.get), translator.toExpr(inH.get)))
case IMemRecv(mem: Id, handle: EVar, data: Option[EVar]) => data match {
case Some(v) => Some(BAssign(translator.toVar(v),
@@ -1231,7 +1253,7 @@ object BluespecGeneration {
//This is an effectful op b/c is modifies the mem queue its reading from
case IMemRecv(mem: Id, handle: EVar, _: Option[EVar]) =>
Some(BExprStmt(bsInts.getMemResp(modParams(mem), translator.toVar(handle), cmd.portNum, isLockedMemory(mem))))
- case IMemWrite(mem, addr, data, lHandle, _, isAtomic) =>
+ case IMemWrite(mem, addr, data, writeMask, lHandle, _, isAtomic) =>
val portNum = mem.typ.get match {
case memType: TLockedMemType => if (memType.limpl.usesWritePortNum) cmd.portNum else None
case _ => None //In the future we may allow unlocked mems with port annotations
@@ -1239,7 +1261,7 @@ object BluespecGeneration {
Some(BExprStmt(
if (isLockedMemory(mem)) {
//ask lock for its translation
- translateMethod(modParams(mem), LockImplementation.getWriteInfo(mem, addr, lHandle, data, portNum, isAtomic).get)
+ translateMethod(modParams(mem), LockImplementation.getWriteInfo(mem, addr, lHandle, data, writeMask, portNum, isAtomic).get)
} else {
//use unlocked translation
bsInts.getUnlockedCombWrite(modParams(mem), translator.toExpr(addr), translator.toExpr(data), portNum)
@@ -1282,21 +1304,25 @@ object BluespecGeneration {
} else {
None
}
- case IAbort(mem) =>
- val abortInfo = LockImplementation.getAbortInfo(mem)
- if (abortInfo.isDefined && abortInfo.get.doesModify) {
- val abortMethod = translateMethod(getLockName(mem), abortInfo.get)
- Some(BExprStmt(abortMethod))
- } else {
- None
- }
+ case IAbort(mem) => mem.typ.get match {
+ case TMemType(_, _, Latency.Asynchronous, writeLatency, readPorts, writePorts) => Some(BExprStmt(
+ bsInts.getMemClear(modParams(mem), true, isLockedMemory(mem)).get))
+ case TMemType(_, _, _ , writeLatency, readPorts, writePorts) => None
+ case _ =>
+ val abortInfo = LockImplementation.getAbortInfo(mem)
+ if (abortInfo.isDefined && abortInfo.get.doesModify) {
+ val abortMethod = translateMethod(getLockName(mem), abortInfo.get)
+ Some(BExprStmt(abortMethod))
+ } else {
+ None
+ }
+ }
case ISpecClear() =>
val clearStmt = BExprStmt(bsInts.getSpecClear(specTable))
Some(clearStmt)
case IAssignLock(handle, src, _) => Some(
BAssign(translator.toVar(handle), translator.toExpr(src))
)
-
case cl@IReleaseLock(mem, _) =>
val methodInfo = LockImplementation.getReleaseInfo(cl)
if (methodInfo.isDefined && methodInfo.get.doesModify) {
@@ -1394,8 +1420,9 @@ object BluespecGeneration {
case CAssign(_, _) => None
case CExpr(_) => None
case CEmpty() => None
- case IStageClear() => Some(BStmtSeq(getFIFOClears().map(mi => BExprStmt(mi))))
- case ISetGlobalExnFlag(state) => Some(BVectorAssign(BVectorAccess(globalExnFlag, BIndConst(0)), BBoolLit(state)))
+ case ICheckExn() => None
+ case IFifoClear() => Some(BStmtSeq(getFIFOClears().map(mi => BExprStmt(mi))))
+ case ISetGlobalExnFlag(state) => Some(BModAssign(globalExnFlag, BBoolLit(state)))
case _: InternalCommand => throw UnexpectedCommand(cmd)
case CRecv(_, _) => throw UnexpectedCommand(cmd)
case CSeq(_, _) => throw UnexpectedCommand(cmd)
@@ -1445,7 +1472,8 @@ object BluespecGeneration {
otherStages.foldLeft(None: Option[PStage])((result, st) => {
var stgIsFound = st.getCmds.foldLeft(false)((found, c) => {
c match {
- case IStageClear() => true
+ case ICondCommand(_, cs) => found || cs.contains(ICheckExn())
+ case ICheckExn() => true
case _ => found
}
})
@@ -1461,16 +1489,14 @@ object BluespecGeneration {
findFirstExceptStg() match {
case Some(st) => {
var resultList = List[BMethodInvoke]()
- var unvisited = st.preds
+ var unvisited = Set[PStage](st)
var visited = Set[PStage]()
var currVisit = st
while(unvisited.nonEmpty){
currVisit = unvisited.head
visited += currVisit
- currVisit.outEdges.foreach(e => {
- if(e.to != st) {
- resultList = resultList.appended(bsInts.getFifoClear(edgeParams(e)))
- }
+ currVisit.inEdges.foreach(e => {
+ resultList = resultList.appended(bsInts.getFifoClear(edgeParams(e)))
})
currVisit.preds.foreach(pred => {
if(!visited.contains(pred)){
diff --git a/src/main/scala/pipedsl/codegen/bsv/BluespecInterfaces.scala b/src/main/scala/pipedsl/codegen/bsv/BluespecInterfaces.scala
index 3f0f3e3a..0bfb35e4 100644
--- a/src/main/scala/pipedsl/codegen/bsv/BluespecInterfaces.scala
+++ b/src/main/scala/pipedsl/codegen/bsv/BluespecInterfaces.scala
@@ -1,3 +1,4 @@
+/* BluespecInterfaces.scala */
package pipedsl.codegen.bsv
import BSVSyntax._
@@ -101,6 +102,8 @@ class BluespecInterfaces() {
private val fifoEnqueueMethodName = "enq"
private val fifoFirstMethodName = "first"
+ private val fifoStgModuleName = "mkFIFOF"
+
private val lockHandleName = "LockId"
private val chkpointHandleName = "LockId"
@@ -297,11 +300,15 @@ class BluespecInterfaces() {
def getFifoType(typ: BSVType): BInterface = {
BInterface(fifoType, List(BVar("elemtyp", typ)))
}
+ def getStgFifoType(typ: BSVType): BInterface = {
+ BInterface(fifoType, List(BVar("elemtyp", typ)))
+ }
def getOutputQType(ttyp: BSVType, dtyp: BSVType): BInterface = {
BInterface("OutputQ", List(BVar("tagtyp", ttyp), BVar("datatyp", dtyp)));
}
def getFifo: BModule = BModule(fifoModuleName, List())
def getNBFifo: BModule = BModule(fifoNBModuleName, List())
+ def getStgFifo: BModule = BModule(fifoStgModuleName, List())
def getBypassFifo: BModule = BModule("mkBypassFIFOF", List())
def getOutputQ(init: BExpr): BModule = BModule("mkOutputFIFOF", List(init))
def getFifoDeq(f: BVar): BMethodInvoke = {
diff --git a/src/main/scala/pipedsl/codegen/bsv/ConstraintsToBluespec.scala b/src/main/scala/pipedsl/codegen/bsv/ConstraintsToBluespec.scala
index e208d5b3..93e7dade 100644
--- a/src/main/scala/pipedsl/codegen/bsv/ConstraintsToBluespec.scala
+++ b/src/main/scala/pipedsl/codegen/bsv/ConstraintsToBluespec.scala
@@ -1,3 +1,4 @@
+/* ConstraintsToBluespec.scala */
package pipedsl.codegen.bsv
import pipedsl.common.Constraints._
diff --git a/src/main/scala/pipedsl/common/CommandLineParser.scala b/src/main/scala/pipedsl/common/CommandLineParser.scala
index ca65ba50..448d64b6 100644
--- a/src/main/scala/pipedsl/common/CommandLineParser.scala
+++ b/src/main/scala/pipedsl/common/CommandLineParser.scala
@@ -1,3 +1,4 @@
+/* CommandLineParser.scala */
package pipedsl.common
import java.io.File
diff --git a/src/main/scala/pipedsl/common/Constraints.scala b/src/main/scala/pipedsl/common/Constraints.scala
index 12bf8bbc..bdd72cce 100644
--- a/src/main/scala/pipedsl/common/Constraints.scala
+++ b/src/main/scala/pipedsl/common/Constraints.scala
@@ -1,3 +1,4 @@
+/* Constraints.scala */
package pipedsl.common
import pipedsl.common.Syntax.{EIndAdd, EIndConst, EIndSub, EIndex, Id, TBitWidth, TNamedType}
diff --git a/src/main/scala/pipedsl/common/DAGSyntax.scala b/src/main/scala/pipedsl/common/DAGSyntax.scala
index d24c2532..828b7f80 100644
--- a/src/main/scala/pipedsl/common/DAGSyntax.scala
+++ b/src/main/scala/pipedsl/common/DAGSyntax.scala
@@ -1,3 +1,4 @@
+/* DAGSyntax.scala */
package pipedsl.common
import pipedsl.common.Errors.UnexpectedCommand
diff --git a/src/main/scala/pipedsl/common/Dataflow.scala b/src/main/scala/pipedsl/common/Dataflow.scala
index 80122cb2..fa66c849 100644
--- a/src/main/scala/pipedsl/common/Dataflow.scala
+++ b/src/main/scala/pipedsl/common/Dataflow.scala
@@ -1,3 +1,4 @@
+/* Dataflow.scala */
package pipedsl.common
import DAGSyntax._
diff --git a/src/main/scala/pipedsl/common/Errors.scala b/src/main/scala/pipedsl/common/Errors.scala
index e6d13bce..f16fb1e5 100644
--- a/src/main/scala/pipedsl/common/Errors.scala
+++ b/src/main/scala/pipedsl/common/Errors.scala
@@ -1,3 +1,4 @@
+/* Errors.scala */
package pipedsl.common
import scala.util.parsing.input.{NoPosition, Position, Positional}
@@ -241,4 +242,8 @@ object Errors {
case class NoWriteReleaseInBody(p :Position) extends RuntimeException(
withPos("No release writes in the main body!", p)
)
+
+ case class MustThrowWithExnPipe(p :Position) extends RuntimeException(
+ withPos("Must have at least one throw for a module with defined exception handler", p)
+ )
}
diff --git a/src/main/scala/pipedsl/common/LockImplementation.scala b/src/main/scala/pipedsl/common/LockImplementation.scala
index 4c189301..083b591d 100644
--- a/src/main/scala/pipedsl/common/LockImplementation.scala
+++ b/src/main/scala/pipedsl/common/LockImplementation.scala
@@ -1,9 +1,12 @@
+/* LockImplementation.scala */
package pipedsl.common
+import pipedsl.codegen.bsv.BSVSyntax.BPack
import pipedsl.common.Errors.{MissingType, UnexpectedLockImpl}
import pipedsl.common.Locks.{General, LockGranularity, Specific}
import pipedsl.common.Syntax.Latency.{Combinational, Latency, Sequential}
import pipedsl.common.Syntax._
+import pipedsl.codegen.bsv.BluespecInterfaces
object LockImplementation {
@@ -30,6 +33,7 @@ object LockImplementation {
private val dataType = TNamedType(Id("data"))
private val handleType = TNamedType(Id("handle"))
private val checkType = TNamedType(Id("checkHandle"))
+ private val maskType = TNamedType(Id("wmask"))
//Lock Object Method Names
private val canResName = "canRes"
private val canResReadName = canResName + "_r"
@@ -234,10 +238,10 @@ object LockImplementation {
}
}
- def getWriteInfo(mem: Id, addr: Expr, inHandle: Option[Expr], data: Expr, portNum: Option[Int], isAtomic: Boolean): Option[MethodInfo] = {
+ def getWriteInfo(mem: Id, addr: Expr, inHandle: Option[Expr], data: Expr, writeMask: Option[Expr], portNum: Option[Int], isAtomic: Boolean): Option[MethodInfo] = {
val interface = getLockImplFromMemTyp(mem)
val (funTyp, latency) = getAccess(interface, Some(LockWrite), isAtomic).get
- val args = getArgs(funTyp, Some(addr), inHandle, Some(data))
+ val args = getArgs(funTyp, Some(addr), inHandle, Some(data), writeMask)
val methodName = getAccessName(Some(LockWrite), isAtomic).v + toPortString(portNum)
Some(MethodInfo(methodName, latency != Combinational, args))
}
@@ -286,6 +290,7 @@ object LockImplementation {
def getAbortInfo(mem: Id): Option[MethodInfo] = {
val interface = getLockImplFromMemTyp(mem)
+ println(interface)
getAbort(interface) match {
case Some(_) =>
val methodName = (if(interface.hasLockSubInterface) lockIntStr else "") + abortName
@@ -302,13 +307,14 @@ object LockImplementation {
e
}
private def getArgs(fun: TFun, addr: Option[Expr] = None,
- handle: Option[Expr] = None, data: Option[Expr] = None): List[Expr] = {
+ handle: Option[Expr] = None, data: Option[Expr] = None, writeMask: Option[Expr] = None): List[Expr] = {
fun.args.foldLeft(List[Expr]())((l, argTyp) => {
argTyp match {
//TODO throw better exception if missing arg
case t: TNamedType if t == dataType => l :+ data.get
case t: TNamedType if t == addrType => l :+ addr.get
case t: TNamedType if t == handleType => l :+ extractHandle(handle.get)
+ case t: TNamedType if t == maskType && writeMask.isDefined => l :+ writeMask.get
case _ => l //should be unreachable TODO throw badly formatted type
}
})
@@ -428,6 +434,8 @@ object LockImplementation {
//LSQ doesn't need a separate lock id so use this to differentiate
def useUniqueLockId(): Boolean = true
+ def canSilentWrite(): Boolean = false
+
def getLockIdSize: Int = defaultLockHandleSize
def getChkIdSize(lidSize: Int): Option[Int] = None
@@ -490,6 +498,8 @@ object LockImplementation {
val parent = super.getType
TObject(queueLockName, List(),
parent.methods ++ Map(
+ Id(writeName) -> (TFun(List(addrType, dataType, maskType), TVoid()), Combinational),
+ Id(atomicAccessName) -> (TFun(List(addrType), TVoid()), Combinational),
Id(checkpointName) -> (TFun(List(), checkType), Sequential),
Id(rollbackName) -> (TFun(List(checkType), TVoid()), Sequential),
Id(abortName) -> (TFun(List(), TVoid()), Sequential)
@@ -505,6 +515,7 @@ object LockImplementation {
override def getModInstArgs(m: TMemType, szParams: List[Int]): List[Int] = List()
+ override def canSilentWrite(): Boolean = true
//Checkpoint id must equal the lock id size
override def getChkIdSize(lidSize: Int): Option[Int] = Some(lidSize)
}
@@ -668,7 +679,8 @@ object LockImplementation {
val parent = super.getType
TObject(Id("CheckpointRF"), List(), parent.methods ++ Map(
Id(checkpointName) -> (TFun(List(), checkType), Sequential),
- Id(rollbackName) -> (TFun(List(checkType), TVoid()), Sequential)
+ Id(rollbackName) -> (TFun(List(checkType), TVoid()), Sequential),
+ Id(abortName) -> (TFun(List(), TVoid()), Sequential)
))
}
//TODO make more parameterizable
diff --git a/src/main/scala/pipedsl/common/Locks.scala b/src/main/scala/pipedsl/common/Locks.scala
index 145c0008..ed34eb9f 100644
--- a/src/main/scala/pipedsl/common/Locks.scala
+++ b/src/main/scala/pipedsl/common/Locks.scala
@@ -1,3 +1,4 @@
+/* Locks.scala */
package pipedsl.common
import pipedsl.common.DAGSyntax.PStage
diff --git a/src/main/scala/pipedsl/common/MemoryInputParser.scala b/src/main/scala/pipedsl/common/MemoryInputParser.scala
index 971043b8..edc0b439 100644
--- a/src/main/scala/pipedsl/common/MemoryInputParser.scala
+++ b/src/main/scala/pipedsl/common/MemoryInputParser.scala
@@ -1,3 +1,4 @@
+/* MemoryInputParser.scala */
package pipedsl.common
import scala.collection.immutable
diff --git a/src/main/scala/pipedsl/common/PrettyPrinter.scala b/src/main/scala/pipedsl/common/PrettyPrinter.scala
index b50c9913..26098c9e 100644
--- a/src/main/scala/pipedsl/common/PrettyPrinter.scala
+++ b/src/main/scala/pipedsl/common/PrettyPrinter.scala
@@ -1,3 +1,4 @@
+/* PrettyPrinter.scala */
package pipedsl.common
import java.io.{File, FileOutputStream, OutputStreamWriter}
@@ -130,7 +131,7 @@ class PrettyPrinter(output: Option[File]) {
case Syntax.CExcept(args) => ins + "except(" + args.map(printExprToString).foldLeft("")((acc, elem) => acc + ", " + elem) + ");"
case Syntax.CCheckSpec(isBlk) => ins + (if (isBlk) "spec_barrier();" else "spec_check();")
case Syntax.IAbort(mem) => ins + "abort(" + mem +");"
- case Syntax.IStageClear() => ins + "clearOnExn();"
+ case Syntax.ICheckExn() => ins + "clearStgOnExn();"
case Syntax.ISpecClear() => ins + "spectable.clear();"
case Syntax.ISetGlobalExnFlag(state) => ins + "setGlobalExnFlag(" + state +");"
case Syntax.IReleaseLock(mem, inHandle) => ins + "release(" + mem + ");"
diff --git a/src/main/scala/pipedsl/common/ProgInfo.scala b/src/main/scala/pipedsl/common/ProgInfo.scala
index 8aab1f3f..5be416de 100644
--- a/src/main/scala/pipedsl/common/ProgInfo.scala
+++ b/src/main/scala/pipedsl/common/ProgInfo.scala
@@ -1,3 +1,4 @@
+/* ProgInfo.scala */
package pipedsl.common
import pipedsl.common.Locks.LockGranularity
diff --git a/src/main/scala/pipedsl/common/Security.scala b/src/main/scala/pipedsl/common/Security.scala
index 58cc95d1..93b24a45 100644
--- a/src/main/scala/pipedsl/common/Security.scala
+++ b/src/main/scala/pipedsl/common/Security.scala
@@ -1,3 +1,4 @@
+/* Security.scala */
package pipedsl.common
import scala.util.parsing.input.Positional
diff --git a/src/main/scala/pipedsl/common/Syntax.scala b/src/main/scala/pipedsl/common/Syntax.scala
index c56a548b..d1e167e6 100644
--- a/src/main/scala/pipedsl/common/Syntax.scala
+++ b/src/main/scala/pipedsl/common/Syntax.scala
@@ -1,3 +1,4 @@
+/* Syntax.scala */
package pipedsl.common
import scala.util.parsing.input.{Position, Positional}
import Errors._
@@ -647,11 +648,13 @@ object Syntax {
case class CSplit(cases: List[CaseObj], default: Command) extends Command
case class CEmpty() extends Command
case class CExcept(args: List[Expr]) extends Command
+ case class CCatch(mod: Id, onCatch: Command) extends Command
sealed trait InternalCommand extends Command
case class IAbort(mem: Id) extends InternalCommand
- case class IStageClear() extends InternalCommand
+ case class IFifoClear() extends InternalCommand
+ case class ICheckExn() extends InternalCommand
case class ISpecClear() extends InternalCommand
case class ISetGlobalExnFlag(state: Boolean) extends InternalCommand
case class ICondCommand(cond: Expr, cs: List[Command]) extends InternalCommand
@@ -667,7 +670,7 @@ object Syntax {
}
case class IMemRecv(mem: Id, handle: EVar, data: Option[EVar]) extends InternalCommand with LockInfoAnnotation
//used for sequential memories that don't commit writes immediately but don't send a response
- case class IMemWrite(mem: Id, addr: EVar, data: EVar,
+ case class IMemWrite(mem: Id, addr: EVar, data: EVar, writeMask: Option[Expr],
inHandle: Option[EVar], outHandle: Option[EVar], isAtomic: Boolean) extends InternalCommand with LockInfoAnnotation
case class ICheckLockOwned(mem: LockArg, inHandle: EVar, outHandle :EVar) extends InternalCommand with LockInfoAnnotation
case class IReserveLock(outHandle: EVar, mem: LockArg) extends InternalCommand with LockInfoAnnotation
diff --git a/src/main/scala/pipedsl/common/Utilities.scala b/src/main/scala/pipedsl/common/Utilities.scala
index 5e2376fc..24f25c9e 100644
--- a/src/main/scala/pipedsl/common/Utilities.scala
+++ b/src/main/scala/pipedsl/common/Utilities.scala
@@ -1,3 +1,4 @@
+/* Utilities.scala */
package pipedsl.common
import com.microsoft.z3.{AST => Z3AST, BoolExpr => Z3BoolExpr, Context => Z3Context}
@@ -84,6 +85,7 @@ object Utilities {
case IUpdate(specId, value, originalSpec) => getUsedVars(value) ++ getUsedVars(originalSpec) + specId
case Syntax.CEmpty() => Set()
case CExcept(args) => args.foldLeft(Set[Id]())((set, arg) => set.union(getUsedVars(arg)))
+ case CCatch(m, c) => Set()
case _ => throw UnexpectedCommand(c)
}
@@ -178,8 +180,13 @@ object Utilities {
Set()
})
case IMemRecv(_, handle, _) => Set(handle.id)
- case IMemWrite(_, addr, data, inHandle, _, _) =>
- Set(addr.id, data.id).union(inHandle.map(h => Set(h.id)).getOrElse(Set()))
+ case IMemWrite(_, addr, data, writeMask, inHandle, _, _) =>
+ Set(addr.id, data.id).union(inHandle.map(h => Set(h.id)).getOrElse(Set())) ++ (
+ if (writeMask.isDefined) {
+ getUsedVars(writeMask.get)
+ } else {
+ Set()
+ })
case IRecv(handle, _, _) => Set(handle.id)
case ISend(_, _, args) => args.map(a => a.id).toSet
case IReserveLock(_, larg) => larg.evar match {
@@ -197,10 +204,11 @@ object Utilities {
case None => Set()
})
case ILockNoOp(_) => Set()
- case IStageClear() => Set()
+ case ICheckExn() => Set()
case ISpecClear() => Set()
case ISetGlobalExnFlag(_) => Set()
case IAbort(_) => Set()
+ case IFifoClear() => Set()
case CLockStart(_) => Set()
case CLockEnd(_) => Set()
case CSpecCall(handle, _, args) => args.foldLeft(Set(handle.id))((s, a) => s ++ getUsedVars(a))
@@ -214,6 +222,7 @@ object Utilities {
case CInvalidate(handle, cHandles) => Set(handle.id) ++ cHandles.map(v => v.id)
case CCheckSpec(_) => Set()
case CEmpty() => Set()
+ case CCatch(m, c) => Set()
}
/**
diff --git a/src/main/scala/pipedsl/passes/AddCheckpointHandlesPass.scala b/src/main/scala/pipedsl/passes/AddCheckpointHandlesPass.scala
index 2bbb252b..f7cabd8f 100644
--- a/src/main/scala/pipedsl/passes/AddCheckpointHandlesPass.scala
+++ b/src/main/scala/pipedsl/passes/AddCheckpointHandlesPass.scala
@@ -1,3 +1,4 @@
+/* AddCheckpointHandlesPass.scala */
package pipedsl.passes
import pipedsl.common.Syntax._
diff --git a/src/main/scala/pipedsl/passes/AddEdgeValuePass.scala b/src/main/scala/pipedsl/passes/AddEdgeValuePass.scala
index cb8a4f25..36c2b5ad 100644
--- a/src/main/scala/pipedsl/passes/AddEdgeValuePass.scala
+++ b/src/main/scala/pipedsl/passes/AddEdgeValuePass.scala
@@ -1,3 +1,4 @@
+/* AddEdgeValuePass.scala */
package pipedsl.passes
import pipedsl.common.Dataflow._
diff --git a/src/main/scala/pipedsl/passes/AddVerifyValuesPass.scala b/src/main/scala/pipedsl/passes/AddVerifyValuesPass.scala
index cc484ed2..7678ddbd 100644
--- a/src/main/scala/pipedsl/passes/AddVerifyValuesPass.scala
+++ b/src/main/scala/pipedsl/passes/AddVerifyValuesPass.scala
@@ -1,3 +1,4 @@
+/* AddVerifyValuesPass.scala */
package pipedsl.passes
import pipedsl.common.Errors.MissingPredictionValues
diff --git a/src/main/scala/pipedsl/passes/BindModuleTypes.scala b/src/main/scala/pipedsl/passes/BindModuleTypes.scala
index 7aae8ed0..bead1b32 100644
--- a/src/main/scala/pipedsl/passes/BindModuleTypes.scala
+++ b/src/main/scala/pipedsl/passes/BindModuleTypes.scala
@@ -1,3 +1,4 @@
+/* BindModuleTypes.scala */
package pipedsl.passes
import pipedsl.common.Syntax._
diff --git a/src/main/scala/pipedsl/passes/CanonicalizePass.scala b/src/main/scala/pipedsl/passes/CanonicalizePass.scala
index a62938b5..3f72939f 100644
--- a/src/main/scala/pipedsl/passes/CanonicalizePass.scala
+++ b/src/main/scala/pipedsl/passes/CanonicalizePass.scala
@@ -1,3 +1,4 @@
+/* CanonicalizePass.scala */
package pipedsl.passes
import pipedsl.common.Syntax._
@@ -116,6 +117,7 @@ class CanonicalizePass() extends CommandPass[Command] with ModulePass[ModuleDef]
case CEmpty() => c
case CExcept(args) => val (nargs, nc) = extractCastVars(args)
CSeq(nc, CExcept(nargs).setPos(c.pos))
+ case CCatch(m, oc) => c
case _: InternalCommand => c
}
diff --git a/src/main/scala/pipedsl/passes/CheckExcepting.scala b/src/main/scala/pipedsl/passes/CheckExcepting.scala
index 8da0283a..950c8790 100644
--- a/src/main/scala/pipedsl/passes/CheckExcepting.scala
+++ b/src/main/scala/pipedsl/passes/CheckExcepting.scala
@@ -1,3 +1,4 @@
+/* CheckExcepting.scala */
//package pipedsl.passes
//
//import pipedsl.common.Errors.{ReleaseInExnBlock, ReleaseWhenMaybeExcepting}
diff --git a/src/main/scala/pipedsl/passes/CollapseStagesPass.scala b/src/main/scala/pipedsl/passes/CollapseStagesPass.scala
index c50a1769..4fe7e284 100644
--- a/src/main/scala/pipedsl/passes/CollapseStagesPass.scala
+++ b/src/main/scala/pipedsl/passes/CollapseStagesPass.scala
@@ -1,3 +1,4 @@
+/* CollapseStagesPass.scala */
package pipedsl.passes
import pipedsl.common.DAGSyntax._
diff --git a/src/main/scala/pipedsl/passes/ConvertAsyncPass.scala b/src/main/scala/pipedsl/passes/ConvertAsyncPass.scala
index 6a420874..f2d2bb15 100644
--- a/src/main/scala/pipedsl/passes/ConvertAsyncPass.scala
+++ b/src/main/scala/pipedsl/passes/ConvertAsyncPass.scala
@@ -1,8 +1,10 @@
+/* ConvertAsyncPass.scala */
package pipedsl.passes
import pipedsl.common.Syntax._
import pipedsl.common.DAGSyntax.PStage
import pipedsl.common.Errors.{UnexpectedExpr, UnexpectedType}
+import pipedsl.common.LockImplementation
import pipedsl.common.Utilities.flattenStageList
import pipedsl.passes.Passes.StagePass
@@ -76,12 +78,12 @@ class ConvertAsyncPass(modName: Id) extends StagePass[List[PStage]] {
recv.portNum = c.portNum
(send, recv)
case _ :TMemType =>
- val write = IMemWrite(mem, index, data, inHandle, outHandle, isAtomic).setPos(e.pos)
+ val write = IMemWrite(mem, index, data, wm, inHandle, outHandle, isAtomic).setPos(e.pos)
write.memOpType = e.memOpType
write.granularity = e.granularity
write.portNum = c.portNum
(write, CEmpty())
- case TLockedMemType(TMemType(_, _, _, Latency.Asynchronous, _, _),_, _) =>
+ case TLockedMemType(TMemType(_, _, _, Latency.Asynchronous, _, _),_, lock) if !lock.canSilentWrite() =>
val handle = freshMessage(mem)
val send = IMemSend(handle, writeMask = wm, mem, Some(data), index, inHandle, outHandle, isAtomic)
val recv = IMemRecv(mem, handle, None)
@@ -94,8 +96,13 @@ class ConvertAsyncPass(modName: Id) extends StagePass[List[PStage]] {
(send, recv)
//if the memory is sequential we don't use handle since it
//is assumed to complete at the end of the cycle
- case TLockedMemType(_,_,_) =>
- val write = IMemWrite(mem, index, data, inHandle, outHandle, isAtomic).setPos(e.pos)
+ case TLockedMemType(TMemType(_, _, _, lat, _, _),_, lock) =>
+ val newwm = wm match {
+ case _: Expr => wm
+ case _ if lat == Latency.Asynchronous => Some(EInt(1, 2, -1))
+ case _ => None
+ }
+ val write = IMemWrite(mem, index, data, newwm, inHandle, outHandle, isAtomic).setPos(e.pos)
write.memOpType = e.memOpType
write.granularity = e.granularity
write.portNum = c.portNum
diff --git a/src/main/scala/pipedsl/passes/ExnTranslationPass.scala b/src/main/scala/pipedsl/passes/ExnTranslationPass.scala
index 3336f493..45271459 100644
--- a/src/main/scala/pipedsl/passes/ExnTranslationPass.scala
+++ b/src/main/scala/pipedsl/passes/ExnTranslationPass.scala
@@ -1,3 +1,4 @@
+/* ExnTranslationPass.scala */
package pipedsl.passes
import pipedsl.common.Syntax._
@@ -22,7 +23,7 @@ class ExnTranslationPass extends ModulePass[ModuleDef] with ProgPass[Prog]{
}
}
- override def run(p: Prog): Prog = p.copy(moddefs = p.moddefs.map(m => run(m)))
+ override def run(p: Prog): Prog = p.copy(moddefs = p.moddefs.map(m => run(m).copyMeta(m)))
def addExnVars(m: ModuleDef): ModuleDef =
{
@@ -32,7 +33,6 @@ class ExnTranslationPass extends ModulePass[ModuleDef] with ProgPass[Prog]{
case ExceptFull(args, c) =>
var arg_count = 0
args.foreach(arg => {
-
arg.typ match {
case Some(t: Type) =>
val newExnArgId = Id("_exnArg_"+arg_count.toString())
@@ -49,17 +49,17 @@ class ExnTranslationPass extends ModulePass[ModuleDef] with ProgPass[Prog]{
case ExceptEmpty() => CEmpty()
}
- m.copy(body = convertPrimitives(m.body), commit_blk = m.commit_blk, except_blk = m.except_blk).copyMeta(m)
+ m.copy(body = CSeq(ICheckExn(), convertBody(m.body)), commit_blk = m.commit_blk, except_blk = m.except_blk).copyMeta(m)
}
- def convertPrimitives(c: Command): Command = {
+ def convertBody(c: Command): Command = {
c match {
- case CSeq(c1, c2) => CSeq(convertPrimitives(c1), convertPrimitives(c2)).copyMeta(c)
- case CIf(cond, cons, alt) => CIf(cond, convertPrimitives(cons), convertPrimitives(alt)).copyMeta(c)
- case CTBar(c1, c2) => CTBar(convertPrimitives(c1), convertPrimitives(c2)).copyMeta(c)
+ case CSeq(c1, c2) => CSeq(convertBody(c1), convertBody(c2)).copyMeta(c)
+ case CIf(cond, cons, alt) => CIf(cond, convertBody(cons), convertBody(alt)).copyMeta(c)
+ case CTBar(c1, c2) => CTBar(convertBody(c1), CSeq(ICheckExn(), convertBody(c2))).copyMeta(c)
case CSplit(cases, default) =>
- val newCases = cases.map(c => CaseObj(c.cond, convertPrimitives(c.body)))
- CSplit(newCases, convertPrimitives(default)).copyMeta(c)
+ val newCases = cases.map(c => CaseObj(c.cond, convertBody(c.body)))
+ CSplit(newCases, convertBody(default)).copyMeta(c)
case CExcept(args) =>
val setLocalErrFlag = CAssign(localExnFlag, EBool(true)).copyMeta(c)
var arg_count = 0
@@ -100,11 +100,11 @@ class ExnTranslationPass extends ModulePass[ModuleDef] with ProgPass[Prog]{
def convertExnArgsId(e: Expr): Expr = {
e match {
- case EIsValid(ex) => EIsValid(convertExnArgsId(ex))
- case EFromMaybe(ex) => EFromMaybe(convertExnArgsId(ex))
- case EToMaybe(ex) => EToMaybe(convertExnArgsId(ex))
- case EUop(op, ex) => EUop(op, convertExnArgsId(ex))
- case EBinop(op, e1, e2) => EBinop(op, convertExnArgsId(e1), convertExnArgsId(e2))
+ case EIsValid(ex) => EIsValid(convertExnArgsId(ex)).setPos(e.pos)
+ case EFromMaybe(ex) => EFromMaybe(convertExnArgsId(ex)).setPos(e.pos)
+ case EToMaybe(ex) => EToMaybe(convertExnArgsId(ex)).setPos(e.pos)
+ case EUop(op, ex) => EUop(op, convertExnArgsId(ex)).setPos(e.pos)
+ case EBinop(op, e1, e2) => EBinop(op, convertExnArgsId(e1), convertExnArgsId(e2)).setPos(e.pos)
case EApp(func, args) => {
val newArgs = args.foldLeft(List[Expr]())((l, arg) => {
arg match {
@@ -114,7 +114,7 @@ class ExnTranslationPass extends ModulePass[ModuleDef] with ProgPass[Prog]{
case _ => l :+ arg
}
})
- EApp(func, newArgs)
+ EApp(func, newArgs).setPos(e.pos)
}
case ECall(mod, name, args, isAtomic) => {
val newArgs = args.foldLeft(List[Expr]())((l, arg) => {
@@ -125,9 +125,9 @@ class ExnTranslationPass extends ModulePass[ModuleDef] with ProgPass[Prog]{
case _ => l :+ arg
}
})
- ECall(mod, name, newArgs, isAtomic)
+ ECall(mod, name, newArgs, isAtomic).setPos(e.pos)
}
- case ECast(ctyp, e) => ECast(ctyp, convertExnArgsId(e))
+ case ECast(ctyp, e) => ECast(ctyp, convertExnArgsId(e)).setPos(e.pos)
case EVar(id) => exnArgApplyMap.getOrElse(id, e).setPos(e.pos)
case _ => e
}
@@ -139,27 +139,31 @@ class ExnTranslationPass extends ModulePass[ModuleDef] with ProgPass[Prog]{
case _ => CEmpty()
}
val except_stmts = m.except_blk match {
- case ExceptFull(_, c) =>
- val unsetGlobalExnFlag = ISetGlobalExnFlag(false)
- val abortStmts = m.modules.foldLeft(CSeq(IStageClear(), CEmpty()))((c, mod) =>
- mod.typ match {
- case TLockedMemType(mem, _, _) => CSeq(c, IAbort(mod.name))
- case _ => CSeq(c, CEmpty())
- })
- CTBar(abortStmts, CSeq(c, unsetGlobalExnFlag))
+ case ExceptFull(_, c) => c
case ExceptEmpty() => CEmpty()
}
- val setGlobalExnFlag = ISetGlobalExnFlag(true)
+
+ val abortStmts = m.modules.foldLeft(CSeq(CEmpty(), CEmpty()))((c, mod) =>
+ mod.typ match {
+ case TLockedMemType(mem, _, _) => CSeq(c, IAbort(mod.name))
+ case TMemType(_, _, _, _, _, _) => CSeq(c, IAbort(mod.name))
+ case _ => CSeq(c, CEmpty())
+ })
+
+ println(abortStmts)
val initLocalErrFlag = CAssign(localExnFlag, EBool(false)).copyMeta(m.body)
- val clearSpecTable = if (m.maybeSpec) {
- ISpecClear()
- } else {
- CEmpty()
- }
- val finalBlocks = CIf(localExnFlag, CTBar(CSeq(setGlobalExnFlag, clearSpecTable), except_stmts), commit_stmts)
- val newBody = CSeq(initLocalErrFlag, CSeq(m.body,finalBlocks))
+ val setGlobalExnFlag = ISetGlobalExnFlag(true)
+ val unsetGlobalExnFlag = ISetGlobalExnFlag(false)
+
+ val clearSpecTable = if (m.maybeSpec) ISpecClear() else CEmpty()
+ val clearFifos = IFifoClear()
+
+ val exnRollbackStmts = CTBar(setGlobalExnFlag, CSeq(CSeq(abortStmts, clearSpecTable), clearFifos))
+ val translatedExnBlock = CTBar(exnRollbackStmts, CSeq(except_stmts, unsetGlobalExnFlag))
+ val finalBlocks = CIf(localExnFlag, translatedExnBlock, commit_stmts)
+ val newBody = CSeq(initLocalErrFlag, CSeq(m.body, finalBlocks))
//TODO require memory or module types
- m.copy(body = newBody, commit_blk = m.commit_blk, except_blk = m.except_blk).copyMeta(m)
+ m.copy(body = newBody, commit_blk = None, except_blk = m.except_blk).copyMeta(m)
}
}
diff --git a/src/main/scala/pipedsl/passes/ExpandCatchPass.scala b/src/main/scala/pipedsl/passes/ExpandCatchPass.scala
new file mode 100644
index 00000000..fa841bde
--- /dev/null
+++ b/src/main/scala/pipedsl/passes/ExpandCatchPass.scala
@@ -0,0 +1,35 @@
+package pipedsl.passes
+
+import pipedsl.common.Syntax._
+import pipedsl.passes.Passes.{ModulePass, ProgPass}
+
+class ExpandCatchPass extends ModulePass[ModuleDef] with ProgPass[Prog]{
+ override def run(m: ModuleDef): ModuleDef =
+ {
+ if(is_excepting(m)){
+ m.copy(body = expandCatch(m.body), commit_blk = m.commit_blk, except_blk = m.except_blk).copyMeta(m)
+ } else {
+ m
+ }
+ }
+ override def run(p: Prog): Prog = p.copy(moddefs = p.moddefs.map(m => run(m).copyMeta(m)))
+
+ def expandCatch(c: Command): Command = {
+ c match {
+ case CSeq(c1, c2) => CSeq(expandCatch(c1), expandCatch(c2)).copyMeta(c)
+ case CTBar(c1, c2) => CTBar(expandCatch(c1), expandCatch(c2)).copyMeta(c)
+ case CSplit(cases, default) =>
+ val newCases = cases.map(c => CaseObj(c.cond, expandCatch(c.body)))
+ CSplit(newCases, expandCatch(default)).copyMeta(c)
+ case CCatch(mod, onCatch) => {
+ val is_interrupt = EVar(Id("is_interrupt")).setPos(c.pos)
+ is_interrupt.typ = Some(TBool())
+ is_interrupt.id.typ = is_interrupt.typ
+ val get_req = CAssign(is_interrupt, ECall(mod, Some(Id("req")), List[Expr](EVar(Id("pc"))), true))
+ val ack = CExpr(ECall(mod, Some(Id("ack")), List[Expr](EVar(Id("pc"))), false))
+ CSeq(get_req, CIf(is_interrupt, CSeq(ack, onCatch), CEmpty()))
+ }
+ case _ => c
+ }
+ }
+}
diff --git a/src/main/scala/pipedsl/passes/LockEliminationPass.scala b/src/main/scala/pipedsl/passes/LockEliminationPass.scala
index 08b92a29..260c15d6 100644
--- a/src/main/scala/pipedsl/passes/LockEliminationPass.scala
+++ b/src/main/scala/pipedsl/passes/LockEliminationPass.scala
@@ -1,3 +1,4 @@
+/* LockEliminationPass.scala */
package pipedsl.passes
import pipedsl.common.DAGSyntax.{IfStage, PStage}
diff --git a/src/main/scala/pipedsl/passes/LockOpTranslationPass.scala b/src/main/scala/pipedsl/passes/LockOpTranslationPass.scala
index 0cabb517..251ffb2a 100644
--- a/src/main/scala/pipedsl/passes/LockOpTranslationPass.scala
+++ b/src/main/scala/pipedsl/passes/LockOpTranslationPass.scala
@@ -1,3 +1,4 @@
+/* LockOpTranslationPass.scala */
package pipedsl.passes
import pipedsl.common.Locks._
diff --git a/src/main/scala/pipedsl/passes/LockRegionInferencePass.scala b/src/main/scala/pipedsl/passes/LockRegionInferencePass.scala
index c19d57ab..9ca062a3 100644
--- a/src/main/scala/pipedsl/passes/LockRegionInferencePass.scala
+++ b/src/main/scala/pipedsl/passes/LockRegionInferencePass.scala
@@ -1,3 +1,4 @@
+/* LockRegionInferencePass.scala */
package pipedsl.passes
import pipedsl.common.Locks.Reserved
diff --git a/src/main/scala/pipedsl/passes/MarkNonRecursiveModulePass.scala b/src/main/scala/pipedsl/passes/MarkNonRecursiveModulePass.scala
index 09c3d245..352505c4 100644
--- a/src/main/scala/pipedsl/passes/MarkNonRecursiveModulePass.scala
+++ b/src/main/scala/pipedsl/passes/MarkNonRecursiveModulePass.scala
@@ -1,3 +1,4 @@
+/* MarkNonRecursiveModulePass.scala */
package pipedsl.passes
import pipedsl.common.Syntax._
diff --git a/src/main/scala/pipedsl/passes/Passes.scala b/src/main/scala/pipedsl/passes/Passes.scala
index bb26cc68..e0ec312f 100644
--- a/src/main/scala/pipedsl/passes/Passes.scala
+++ b/src/main/scala/pipedsl/passes/Passes.scala
@@ -1,3 +1,4 @@
+/* Passes.scala */
package pipedsl.passes
import pipedsl.common.DAGSyntax.PStage
diff --git a/src/main/scala/pipedsl/passes/PredicateGenerator.scala b/src/main/scala/pipedsl/passes/PredicateGenerator.scala
index fe898bb9..31489e10 100644
--- a/src/main/scala/pipedsl/passes/PredicateGenerator.scala
+++ b/src/main/scala/pipedsl/passes/PredicateGenerator.scala
@@ -1,3 +1,4 @@
+/* PredicateGenerator.scala */
package pipedsl.passes
import com.microsoft.z3.{AST => Z3AST, BoolExpr => Z3BoolExpr, Context => Z3Context, Expr => Z3Expr}
diff --git a/src/main/scala/pipedsl/passes/RemoveReentrantPass.scala b/src/main/scala/pipedsl/passes/RemoveReentrantPass.scala
index a10816f4..95eac3fe 100644
--- a/src/main/scala/pipedsl/passes/RemoveReentrantPass.scala
+++ b/src/main/scala/pipedsl/passes/RemoveReentrantPass.scala
@@ -1,3 +1,4 @@
+/* RemoveReentrantPass.scala */
package pipedsl.passes
import pipedsl.common.DAGSyntax.PStage
diff --git a/src/main/scala/pipedsl/passes/RemoveTimingPass.scala b/src/main/scala/pipedsl/passes/RemoveTimingPass.scala
index 5f013838..26eb44a2 100644
--- a/src/main/scala/pipedsl/passes/RemoveTimingPass.scala
+++ b/src/main/scala/pipedsl/passes/RemoveTimingPass.scala
@@ -1,3 +1,4 @@
+/* RemoveTimingPass.scala */
package pipedsl.passes
import pipedsl.common.Syntax._
diff --git a/src/main/scala/pipedsl/passes/SimplifyRecvPass.scala b/src/main/scala/pipedsl/passes/SimplifyRecvPass.scala
index cbf97313..04bace35 100644
--- a/src/main/scala/pipedsl/passes/SimplifyRecvPass.scala
+++ b/src/main/scala/pipedsl/passes/SimplifyRecvPass.scala
@@ -1,3 +1,4 @@
+/* SimplifyRecvPass.scala */
package pipedsl.passes
import Passes.{CommandPass, ModulePass, ProgPass}
diff --git a/src/main/scala/pipedsl/passes/SplitStagesPass.scala b/src/main/scala/pipedsl/passes/SplitStagesPass.scala
index 653188d2..fd037512 100644
--- a/src/main/scala/pipedsl/passes/SplitStagesPass.scala
+++ b/src/main/scala/pipedsl/passes/SplitStagesPass.scala
@@ -1,3 +1,4 @@
+/* SplitStagesPass.scala */
package pipedsl.passes
import pipedsl.common.DAGSyntax.{IfStage, PStage, PipelineEdge}
diff --git a/src/main/scala/pipedsl/typechecker/AnalysisProvider.scala b/src/main/scala/pipedsl/typechecker/AnalysisProvider.scala
index 495d3b1e..4534c492 100644
--- a/src/main/scala/pipedsl/typechecker/AnalysisProvider.scala
+++ b/src/main/scala/pipedsl/typechecker/AnalysisProvider.scala
@@ -1,3 +1,4 @@
+/* AnalysisProvider.scala */
package pipedsl.typechecker
import pipedsl.common.Syntax.Prog
diff --git a/src/main/scala/pipedsl/typechecker/BaseTypeChecker.scala b/src/main/scala/pipedsl/typechecker/BaseTypeChecker.scala
index 0b10dc07..7d0f59b3 100644
--- a/src/main/scala/pipedsl/typechecker/BaseTypeChecker.scala
+++ b/src/main/scala/pipedsl/typechecker/BaseTypeChecker.scala
@@ -1,3 +1,4 @@
+/* BaseTypeChecker.scala */
package pipedsl.typechecker
import pipedsl.common.Errors._
@@ -400,6 +401,7 @@ object BaseTypeChecker extends TypeChecks[Id, Type] {
mtyp match {
case TModType(inputs, _, _, _) =>
if (inputs.length != args.length) {
+ print(args)
throw ArgLengthMismatch(c.pos, inputs.length, args.length)
}
if (inputs.length != preds.length) {
diff --git a/src/main/scala/pipedsl/typechecker/CheckpointChecker.scala b/src/main/scala/pipedsl/typechecker/CheckpointChecker.scala
index b204702e..f40ba3af 100644
--- a/src/main/scala/pipedsl/typechecker/CheckpointChecker.scala
+++ b/src/main/scala/pipedsl/typechecker/CheckpointChecker.scala
@@ -1,3 +1,4 @@
+/* CheckpointChecker.scala */
package pipedsl.typechecker
import com.microsoft.z3.{AST => Z3AST, BoolExpr => Z3BoolExpr, Context => Z3Context, Solver => Z3Solver, Status => Z3Status}
diff --git a/src/main/scala/pipedsl/typechecker/Environments.scala b/src/main/scala/pipedsl/typechecker/Environments.scala
index ecfb5887..8f4106c0 100644
--- a/src/main/scala/pipedsl/typechecker/Environments.scala
+++ b/src/main/scala/pipedsl/typechecker/Environments.scala
@@ -1,3 +1,4 @@
+/* Environments.scala */
package pipedsl.typechecker
import com.microsoft.z3.{AST => Z3AST, BoolExpr => Z3BoolExpr, Context => Z3Context}
@@ -69,7 +70,8 @@ object Environments {
override def add(name: Id, typ: Type): Environment[Id, Type] = typeMap.get(name) match {
case Some(t) => throw AlreadyBoundType(name.pos, name.v, t, typ)
- case None => this.copy(typeMap = typeMap + (name -> typ))
+ case None =>
+ this.copy(typeMap = typeMap + (name -> typ))
}
override def remove(name: Id): Environment[Id, Type] = {
TypeEnv(this.typeMap - name)
diff --git a/src/main/scala/pipedsl/typechecker/FinalblocksConstraintChecker.scala b/src/main/scala/pipedsl/typechecker/FinalblocksConstraintChecker.scala
index d4bf2b52..6997aaf4 100644
--- a/src/main/scala/pipedsl/typechecker/FinalblocksConstraintChecker.scala
+++ b/src/main/scala/pipedsl/typechecker/FinalblocksConstraintChecker.scala
@@ -1,3 +1,4 @@
+/* FinalblocksConstraintChecker.scala */
package pipedsl.typechecker
import pipedsl.common.Syntax._
@@ -19,7 +20,7 @@ object FinalblocksConstraintChecker {
m.except_blk match {
case ExceptEmpty() => checkNormBody(m.body)
case ExceptFull(_, c) =>
- checkExBody(m.body)
+ if(!checkExBody(m.body)) throw MustThrowWithExnPipe(c.pos)
checkCommit(m.commit_blk.get)
checkExceptingBlock(c)
}
@@ -43,14 +44,16 @@ object FinalblocksConstraintChecker {
}
- private def checkExBody(c :Command) :Unit = c match {
- case CSeq(c1, c2) => checkExBody(c1); checkExBody(c2)
- case CTBar(c1, c2) => checkExBody(c1); checkExBody(c2)
- case CIf(_, cons, alt) => checkExBody(cons); checkExBody(alt)
- case CRecv(EMemAccess(mem, _, _, _, _, isAtomic), _) if isAtomic || !isLockedMemory(mem)=> throw NoCommittingWriteInBody(c.pos)
+ private def checkExBody(c :Command) : Boolean = c match {
+ case CSeq(c1, c2) => checkExBody(c1) || checkExBody(c2)
+ case CTBar(c1, c2) => checkExBody(c1) || checkExBody(c2)
+ case CIf(_, cons, alt) => checkExBody(cons) || checkExBody(alt)
+ // TODO: (PDL Exception) Add Async Locked Memory for CheckpointQueue
+ case CRecv(EMemAccess(mem, _, _, _, _, isAtomic), _) if isAtomic && !isLockedMemory(mem)=> throw NoCommittingWriteInBody(c.pos)
case c@CLockOp(mem, Released, _, _, _) if c.memOpType.contains(LockWrite) || c.granularity == General => throw NoWriteReleaseInBody(c.pos)
- case CSplit(cases, default) => checkExBody(default); cases.foreach(co => checkExBody(co.body))
- case _ => ()
+ case CSplit(cases, default) => checkExBody(default) || cases.foldLeft(false) { (acc, co) => acc || checkExBody(co.body) }
+ case CExcept(_) => true
+ case _ => false
}
private def checkExceptingBlock(c :Command) :Unit = checkNoThrow(c, PreCall)
diff --git a/src/main/scala/pipedsl/typechecker/FunctionConstraintChecker.scala b/src/main/scala/pipedsl/typechecker/FunctionConstraintChecker.scala
index e9ae51ee..fbc27ab1 100644
--- a/src/main/scala/pipedsl/typechecker/FunctionConstraintChecker.scala
+++ b/src/main/scala/pipedsl/typechecker/FunctionConstraintChecker.scala
@@ -1,3 +1,4 @@
+/* FunctionConstraintChecker.scala */
package pipedsl.typechecker
import com.microsoft.z3.{Status, Context => Z3Context, Solver => Z3Solver}
diff --git a/src/main/scala/pipedsl/typechecker/LatencyChecker.scala b/src/main/scala/pipedsl/typechecker/LatencyChecker.scala
index 2cfc5aa1..272b214c 100644
--- a/src/main/scala/pipedsl/typechecker/LatencyChecker.scala
+++ b/src/main/scala/pipedsl/typechecker/LatencyChecker.scala
@@ -1,3 +1,4 @@
+/* LatencyChecker.scala */
/*
package pipedsl.typechecker
diff --git a/src/main/scala/pipedsl/typechecker/LinearExecutionChecker.scala b/src/main/scala/pipedsl/typechecker/LinearExecutionChecker.scala
index 79a4e93b..43ae9343 100644
--- a/src/main/scala/pipedsl/typechecker/LinearExecutionChecker.scala
+++ b/src/main/scala/pipedsl/typechecker/LinearExecutionChecker.scala
@@ -1,3 +1,4 @@
+/* LinearExecutionChecker.scala */
package pipedsl.typechecker
import com.microsoft.z3.{
diff --git a/src/main/scala/pipedsl/typechecker/LockConstraintChecker.scala b/src/main/scala/pipedsl/typechecker/LockConstraintChecker.scala
index 62cc0862..7bb025e3 100644
--- a/src/main/scala/pipedsl/typechecker/LockConstraintChecker.scala
+++ b/src/main/scala/pipedsl/typechecker/LockConstraintChecker.scala
@@ -1,3 +1,4 @@
+/* LockConstraintChecker.scala */
package pipedsl.typechecker
import com.microsoft.z3.{AST => Z3AST, BoolExpr => Z3BoolExpr, Context => Z3Context, Solver => Z3Solver, Status => Z3Status}
@@ -63,7 +64,8 @@ class LockConstraintChecker(lockMap: Map[Id, Set[LockArg]], lockGranularityMap:
override def checkModule(m: ModuleDef, env: Environment[LockArg, Z3AST]): Environment[LockArg, Z3AST] = {
checkChunk(m.name, m.extendedBody(), env)
- m.except_blk.foreach(checkChunk(m.name, _, env))
+ //TODO - Exn : add new rule
+// m.except_blk.foreach(checkChunk(m.name, _, env))
env
}
diff --git a/src/main/scala/pipedsl/typechecker/LockOperationTypeChecker.scala b/src/main/scala/pipedsl/typechecker/LockOperationTypeChecker.scala
index 3cb4f551..55f01bc0 100644
--- a/src/main/scala/pipedsl/typechecker/LockOperationTypeChecker.scala
+++ b/src/main/scala/pipedsl/typechecker/LockOperationTypeChecker.scala
@@ -1,3 +1,4 @@
+/* LockOperationTypeChecker.scala */
package pipedsl.typechecker;
import pipedsl.common.Errors.{IllegalMemoryAccessOperation, MalformedLockTypes, UnexpectedCase}
diff --git a/src/main/scala/pipedsl/typechecker/LockRegionChecker.scala b/src/main/scala/pipedsl/typechecker/LockRegionChecker.scala
index a47079a5..feab8bcf 100644
--- a/src/main/scala/pipedsl/typechecker/LockRegionChecker.scala
+++ b/src/main/scala/pipedsl/typechecker/LockRegionChecker.scala
@@ -1,3 +1,4 @@
+/* LockRegionChecker.scala */
package pipedsl.typechecker
import pipedsl.common.Errors.{IllegalLockAcquisition, InvalidLockState, UnexpectedCase}
diff --git a/src/main/scala/pipedsl/typechecker/LockReleaseChecker.scala b/src/main/scala/pipedsl/typechecker/LockReleaseChecker.scala
index 1b0feb23..d5925210 100644
--- a/src/main/scala/pipedsl/typechecker/LockReleaseChecker.scala
+++ b/src/main/scala/pipedsl/typechecker/LockReleaseChecker.scala
@@ -1,3 +1,4 @@
+/* LockReleaseChecker.scala */
package pipedsl.typechecker
import pipedsl.common.Errors.IllegalOOOLockRelease
diff --git a/src/main/scala/pipedsl/typechecker/LockWellformedChecker.scala b/src/main/scala/pipedsl/typechecker/LockWellformedChecker.scala
index 831f560e..9a5857d0 100644
--- a/src/main/scala/pipedsl/typechecker/LockWellformedChecker.scala
+++ b/src/main/scala/pipedsl/typechecker/LockWellformedChecker.scala
@@ -1,3 +1,4 @@
+/* LockWellformedChecker.scala */
package pipedsl.typechecker
import pipedsl.common.Errors.MalformedLockTypes
diff --git a/src/main/scala/pipedsl/typechecker/PortChecker.scala b/src/main/scala/pipedsl/typechecker/PortChecker.scala
index 1133730f..b23057eb 100644
--- a/src/main/scala/pipedsl/typechecker/PortChecker.scala
+++ b/src/main/scala/pipedsl/typechecker/PortChecker.scala
@@ -1,3 +1,4 @@
+/* PortChecker.scala */
package pipedsl.typechecker
import pipedsl.common.{Locks, Syntax, Errors}
diff --git a/src/main/scala/pipedsl/typechecker/SpeculationChecker.scala b/src/main/scala/pipedsl/typechecker/SpeculationChecker.scala
index 73dac724..ab94a4c3 100644
--- a/src/main/scala/pipedsl/typechecker/SpeculationChecker.scala
+++ b/src/main/scala/pipedsl/typechecker/SpeculationChecker.scala
@@ -1,3 +1,4 @@
+/* SpeculationChecker.scala */
package pipedsl.typechecker
import com.microsoft.z3.{AST => Z3AST, BoolExpr => Z3BoolExpr, Context => Z3Context, Solver => Z3Solver, Status => Z3Status}
@@ -126,9 +127,10 @@ class SpeculationChecker(val ctx: Z3Context) extends TypeChecks[Id, Z3AST] {
//TODO error that actually says something about checkpoints
throw IllegalSpeculativeOperation(c.pos, NonSpeculative.toString)
}
- if (op == Released && (t.isEmpty || t.get == LockWrite) && s != NonSpeculative) {
- throw IllegalSpeculativeOperation(c.pos, NonSpeculative.toString)
- }
+// TODO - Exn: Fix this check
+// if (op == Released && (t.isEmpty || t.get == LockWrite) && s != NonSpeculative) {
+// throw IllegalSpeculativeOperation(c.pos, NonSpeculative.toString)
+// }
//shouldn't do any potentially speculative lock ops w/o checking first
if (s == Unknown) {
throw IllegalSpeculativeOperation(c.pos, Speculative.toString)
diff --git a/src/main/scala/pipedsl/typechecker/Subtypes.scala b/src/main/scala/pipedsl/typechecker/Subtypes.scala
index 498d79fe..7d8cafb1 100644
--- a/src/main/scala/pipedsl/typechecker/Subtypes.scala
+++ b/src/main/scala/pipedsl/typechecker/Subtypes.scala
@@ -1,3 +1,4 @@
+/* Subtypes.scala */
package pipedsl.typechecker
import pipedsl.common.Syntax._
diff --git a/src/main/scala/pipedsl/typechecker/TimingTypeChecker.scala b/src/main/scala/pipedsl/typechecker/TimingTypeChecker.scala
index 546bc29a..80b8c32b 100644
--- a/src/main/scala/pipedsl/typechecker/TimingTypeChecker.scala
+++ b/src/main/scala/pipedsl/typechecker/TimingTypeChecker.scala
@@ -1,3 +1,4 @@
+/* TimingTypeChecker.scala */
package pipedsl.typechecker
import pipedsl.common.Syntax._
@@ -331,8 +332,8 @@ object TimingTypeChecker extends TypeChecks[Id, Type] {
//calling another pipe
case None => Asynchronous
}
- case EVar(id) => if(!vars(id) && isRhs && !(id == is_excepting_var)) {
- throw UnavailableArgUse(e.pos, id.toString) }
+ case EVar(id) => if(!vars(id) && isRhs && !(id == is_excepting_var)) {throw UnavailableArgUse(e.pos, id.toString) }
+ //TODO - exn remove above line and fix this: throw UnavailableArgUse(e.pos, id.toString) }
//TODO make this error message more clear about what's wrong when these are lock handle vars
else { Combinational }
case ECast(_, exp) => checkExpr(exp, vars, isRhs)
diff --git a/src/main/scala/pipedsl/typechecker/TypeChecker.scala b/src/main/scala/pipedsl/typechecker/TypeChecker.scala
index 170c738b..69b30870 100644
--- a/src/main/scala/pipedsl/typechecker/TypeChecker.scala
+++ b/src/main/scala/pipedsl/typechecker/TypeChecker.scala
@@ -1,3 +1,4 @@
+/* TypeChecker.scala */
package pipedsl.typechecker
import pipedsl.common.Syntax._
diff --git a/src/main/scala/pipedsl/typechecker/TypeInferenceWrapper.scala b/src/main/scala/pipedsl/typechecker/TypeInferenceWrapper.scala
index 673c0148..d32592e0 100644
--- a/src/main/scala/pipedsl/typechecker/TypeInferenceWrapper.scala
+++ b/src/main/scala/pipedsl/typechecker/TypeInferenceWrapper.scala
@@ -1,3 +1,4 @@
+/* TypeInferenceWrapper.scala */
package pipedsl.typechecker
import pipedsl.common.{Errors, Syntax}
@@ -230,7 +231,7 @@ object TypeInferenceWrapper
case ces@CirExprStmt(ce) => val (_, nv, nce) = checkCirExpr(ce, tenv)
(nv, ces.copy(ce = nce).setPos(ces.pos))
}
-
+ // TODO - EXN: This need rewrite and fix bugs
def checkModule(m: ModuleDef, env: TypeEnv): (Environment[Id, Type], ModuleDef) =
{
val inputTypes = m.inputs.map(p => p.typ)
@@ -249,8 +250,9 @@ object TypeInferenceWrapper
val (fixed_except, final_subst) = m.except_blk match
{
case ExceptEmpty() => (ExceptEmpty(), subst1)
- //TODO IMPROVE PRECISION OF OUT_ENV, SUBST
- case ExceptFull(args, c) => checkCommand(c, args.foldLeft(pipeEnv)((env, id) => env.add(id, id.typ.get).asInstanceOf[TypeEnv]), subst) |>
+ //TODO - EXN: IMPROVE PRECISION OF OUT_ENV, SUBST
+ case ExceptFull(args, c) =>
+ checkCommand(c, args.foldLeft(pipeEnv)((env, id) => env.add(id, id.typ.get).asInstanceOf[TypeEnv]), subst) |>
{case (cmd, _, s) => (ExceptFull(args, cmd), s)}
}
val hash = mutable.HashMap.from(final_subst)
@@ -357,6 +359,7 @@ object TypeInferenceWrapper
case b => throw UnexpectedType(mem.id.pos, c.toString, "Memory or Module Type", b)
}
case CEmpty() => (c, env, sub)
+ case CCatch(_, oc) => checkCommand(oc, env, sub)
case CExcept(args) => (c, env, sub) //TODO IMPLEMENT
case cr@CReturn(exp) =>
val (s, t, e, fixed) = infer(env, exp)
diff --git a/src/test/scala/pipedsl/CSplitSuite.scala b/src/test/scala/pipedsl/CSplitSuite.scala
index 1bac9c18..73bdbef1 100644
--- a/src/test/scala/pipedsl/CSplitSuite.scala
+++ b/src/test/scala/pipedsl/CSplitSuite.scala
@@ -1,3 +1,4 @@
+/* CSplitSuite.scala */
package pipedsl
import org.scalatest.funsuite.AnyFunSuite
diff --git a/src/test/scala/pipedsl/ExceptionSuite.scala b/src/test/scala/pipedsl/ExceptionSuite.scala
index d74efe2b..979f9ef7 100644
--- a/src/test/scala/pipedsl/ExceptionSuite.scala
+++ b/src/test/scala/pipedsl/ExceptionSuite.scala
@@ -1,3 +1,4 @@
+/* ExceptionSuite.scala */
package pipedsl
import org.scalatest.funsuite.AnyFunSuite
diff --git a/src/test/scala/pipedsl/LockMergeSuite.scala b/src/test/scala/pipedsl/LockMergeSuite.scala
index 382439b8..4e7d5124 100644
--- a/src/test/scala/pipedsl/LockMergeSuite.scala
+++ b/src/test/scala/pipedsl/LockMergeSuite.scala
@@ -1,3 +1,4 @@
+/* LockMergeSuite.scala */
package pipedsl
import org.scalatest.funsuite.AnyFunSuite
diff --git a/src/test/scala/pipedsl/LockTypecheckSuite.scala b/src/test/scala/pipedsl/LockTypecheckSuite.scala
index ffc52762..41b6b948 100644
--- a/src/test/scala/pipedsl/LockTypecheckSuite.scala
+++ b/src/test/scala/pipedsl/LockTypecheckSuite.scala
@@ -1,3 +1,4 @@
+/* LockTypecheckSuite.scala */
package pipedsl
import org.scalatest.funsuite.AnyFunSuite
diff --git a/src/test/scala/pipedsl/MainSuite.scala b/src/test/scala/pipedsl/MainSuite.scala
index 1a57c835..6c6c5405 100644
--- a/src/test/scala/pipedsl/MainSuite.scala
+++ b/src/test/scala/pipedsl/MainSuite.scala
@@ -1,3 +1,4 @@
+/* MainSuite.scala */
package pipedsl
import java.io.File
diff --git a/src/test/scala/pipedsl/MiscSimulationSuite.scala b/src/test/scala/pipedsl/MiscSimulationSuite.scala
index 88ebaffd..8c258203 100644
--- a/src/test/scala/pipedsl/MiscSimulationSuite.scala
+++ b/src/test/scala/pipedsl/MiscSimulationSuite.scala
@@ -1,3 +1,4 @@
+/* MiscSimulationSuite.scala */
package pipedsl
import org.scalatest.funsuite.AnyFunSuite
diff --git a/src/test/scala/pipedsl/RegisterRenamingSuite.scala b/src/test/scala/pipedsl/RegisterRenamingSuite.scala
index 696f6719..b291ed28 100644
--- a/src/test/scala/pipedsl/RegisterRenamingSuite.scala
+++ b/src/test/scala/pipedsl/RegisterRenamingSuite.scala
@@ -1,3 +1,4 @@
+/* RegisterRenamingSuite.scala */
package pipedsl
import org.scalatest.funsuite.AnyFunSuite
diff --git a/src/test/scala/pipedsl/RiscSuite.scala b/src/test/scala/pipedsl/RiscSuite.scala
index f1f07106..96c570b6 100644
--- a/src/test/scala/pipedsl/RiscSuite.scala
+++ b/src/test/scala/pipedsl/RiscSuite.scala
@@ -1,3 +1,4 @@
+/* RiscSuite.scala */
package pipedsl
import org.scalatest.funsuite.AnyFunSuite
@@ -39,5 +40,6 @@ class RiscSuite extends AnyFunSuite {
testBlueSpecSim(testFolder, t, None, simInputs, Some(s + ".simsol"))
}
})
+
})
}
diff --git a/src/test/scala/pipedsl/SpeculationSuite.scala b/src/test/scala/pipedsl/SpeculationSuite.scala
index e70a5d21..db7c86cd 100644
--- a/src/test/scala/pipedsl/SpeculationSuite.scala
+++ b/src/test/scala/pipedsl/SpeculationSuite.scala
@@ -1,3 +1,4 @@
+/* SpeculationSuite.scala */
package pipedsl
import org.scalatest.funsuite.AnyFunSuite
diff --git a/src/test/scala/pipedsl/TypeAutoCastSuite.scala b/src/test/scala/pipedsl/TypeAutoCastSuite.scala
index 7049a449..d5636233 100644
--- a/src/test/scala/pipedsl/TypeAutoCastSuite.scala
+++ b/src/test/scala/pipedsl/TypeAutoCastSuite.scala
@@ -1,3 +1,4 @@
+/* TypeAutoCastSuite.scala */
package pipedsl
import org.scalatest.funsuite.AnyFunSuite
diff --git a/src/test/scala/pipedsl/package.scala b/src/test/scala/pipedsl/package.scala
index a9f43b30..811874dd 100644
--- a/src/test/scala/pipedsl/package.scala
+++ b/src/test/scala/pipedsl/package.scala
@@ -1,3 +1,4 @@
+/* package.scala */
import java.io.File
import java.nio.file.Paths
diff --git a/src/test/tests/autocastTests/autocast-basic-pass.pdl b/src/test/tests/autocastTests/autocast-basic-pass.pdl
index 28c7bc04..c88b20e7 100644
--- a/src/test/tests/autocastTests/autocast-basic-pass.pdl
+++ b/src/test/tests/autocastTests/autocast-basic-pass.pdl
@@ -1,3 +1,4 @@
+// autocast-basic-pass.pdl
def helper1(a: int<32>, b:bool, c: String): int<32> {
d = a + 1<16>;
e = b && false;
diff --git a/src/test/tests/autocastTests/risc-pipe-spec.pdl b/src/test/tests/autocastTests/risc-pipe-spec.pdl
index 9e7b4adf..9b331ac2 100644
--- a/src/test/tests/autocastTests/risc-pipe-spec.pdl
+++ b/src/test/tests/autocastTests/risc-pipe-spec.pdl
@@ -1,3 +1,4 @@
+// risc-pipe-spec.pdl
def mul(arg1: int<32>, arg2: int<32>, op: uint<3>): int<32> {
uint<32> mag1 = cast(mag(arg1), uint<32>);
uint<32> mag2 = cast(mag(arg2), uint<32>);
diff --git a/src/test/tests/autocastTests/type-inference-basic-pass.pdl b/src/test/tests/autocastTests/type-inference-basic-pass.pdl
index cdc50f37..d0311360 100644
--- a/src/test/tests/autocastTests/type-inference-basic-pass.pdl
+++ b/src/test/tests/autocastTests/type-inference-basic-pass.pdl
@@ -1,3 +1,4 @@
+// type-inference-basic-pass.pdl
def helper1(a: int<32>, b:bool, c: String): int<32> {
d = a + 1<32>;
diff --git a/src/test/tests/autocastTests/type-inference-bit-width-tests.pdl b/src/test/tests/autocastTests/type-inference-bit-width-tests.pdl
index 21410330..9f439464 100644
--- a/src/test/tests/autocastTests/type-inference-bit-width-tests.pdl
+++ b/src/test/tests/autocastTests/type-inference-bit-width-tests.pdl
@@ -1,3 +1,4 @@
+// type-inference-bit-width-tests.pdl
def helper1(a: int<32>, b:bool, c: String): int<32> {
d = a + 1;
diff --git a/src/test/tests/autocastTests/type-inference-fail-base-type.pdl b/src/test/tests/autocastTests/type-inference-fail-base-type.pdl
index 72889371..9cb9cdf4 100644
--- a/src/test/tests/autocastTests/type-inference-fail-base-type.pdl
+++ b/src/test/tests/autocastTests/type-inference-fail-base-type.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-base-type.pdl
pipe test1(input: int<32>)[rf: int<32>[32]] {
a = input + 2<32>;
if (a) {
diff --git a/src/test/tests/autocastTests/type-inference-fail-bit-too-small-memAccessToosmall.pdl b/src/test/tests/autocastTests/type-inference-fail-bit-too-small-memAccessToosmall.pdl
index dd313404..0843f4ff 100644
--- a/src/test/tests/autocastTests/type-inference-fail-bit-too-small-memAccessToosmall.pdl
+++ b/src/test/tests/autocastTests/type-inference-fail-bit-too-small-memAccessToosmall.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-bit-too-small-memAccessToosmall.pdl
pipe test6()[rf: int<32>[32]] {
int<64> a = 6 * 6;
diff --git a/src/test/tests/autocastTests/type-inference-fail-bit-too-small-minus.pdl b/src/test/tests/autocastTests/type-inference-fail-bit-too-small-minus.pdl
index 1149577f..d419151d 100644
--- a/src/test/tests/autocastTests/type-inference-fail-bit-too-small-minus.pdl
+++ b/src/test/tests/autocastTests/type-inference-fail-bit-too-small-minus.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-bit-too-small-minus.pdl
pipe test6()[] {
a = 6 - 6;
diff --git a/src/test/tests/autocastTests/type-inference-fail-bit-too-small-mult.pdl b/src/test/tests/autocastTests/type-inference-fail-bit-too-small-mult.pdl
index 737be003..e0a85b87 100644
--- a/src/test/tests/autocastTests/type-inference-fail-bit-too-small-mult.pdl
+++ b/src/test/tests/autocastTests/type-inference-fail-bit-too-small-mult.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-bit-too-small-mult.pdl
pipe test6()[] {
a = 6 * 6;
diff --git a/src/test/tests/autocastTests/type-inference-fail-bit-too-small-plus.pdl b/src/test/tests/autocastTests/type-inference-fail-bit-too-small-plus.pdl
index deabf477..8b0e693d 100644
--- a/src/test/tests/autocastTests/type-inference-fail-bit-too-small-plus.pdl
+++ b/src/test/tests/autocastTests/type-inference-fail-bit-too-small-plus.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-bit-too-small-plus.pdl
pipe test6()[] {
a = 6 + 6;
diff --git a/src/test/tests/autocastTests/type-inference-fail-boolBinOp.pdl b/src/test/tests/autocastTests/type-inference-fail-boolBinOp.pdl
index 3a302da6..974eca9f 100644
--- a/src/test/tests/autocastTests/type-inference-fail-boolBinOp.pdl
+++ b/src/test/tests/autocastTests/type-inference-fail-boolBinOp.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-boolBinOp.pdl
pipe test1(input: int<32>)[rf: int<32>[32]] {
a = input;
diff --git a/src/test/tests/autocastTests/type-inference-fail-call-args.pdl b/src/test/tests/autocastTests/type-inference-fail-call-args.pdl
index 379def08..61f88a55 100644
--- a/src/test/tests/autocastTests/type-inference-fail-call-args.pdl
+++ b/src/test/tests/autocastTests/type-inference-fail-call-args.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-call-args.pdl
pipe test10(a: bool, b: int<32>)[rf: int<32>[32]]: int<32> {
output(5<32>);
}
diff --git a/src/test/tests/autocastTests/type-inference-fail-call.pdl b/src/test/tests/autocastTests/type-inference-fail-call.pdl
index 6bc02fad..09d7de24 100644
--- a/src/test/tests/autocastTests/type-inference-fail-call.pdl
+++ b/src/test/tests/autocastTests/type-inference-fail-call.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-call.pdl
pipe test10(a: bool, b: int<32>)[rf: int<32>[32]]: int<32> {
output(5<32>);
}
diff --git a/src/test/tests/autocastTests/type-inference-fail-eqBinOp.pdl b/src/test/tests/autocastTests/type-inference-fail-eqBinOp.pdl
index 0d4bae05..bf44b5e9 100644
--- a/src/test/tests/autocastTests/type-inference-fail-eqBinOp.pdl
+++ b/src/test/tests/autocastTests/type-inference-fail-eqBinOp.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-eqBinOp.pdl
pipe test1(input: int<32>)[rf: int<32>[32]] {
a = true;
b = a == input;
diff --git a/src/test/tests/autocastTests/type-inference-fail-func-app-arg.pdl b/src/test/tests/autocastTests/type-inference-fail-func-app-arg.pdl
index c2bb8609..7c811ae6 100644
--- a/src/test/tests/autocastTests/type-inference-fail-func-app-arg.pdl
+++ b/src/test/tests/autocastTests/type-inference-fail-func-app-arg.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-func-app-arg.pdl
def func(a: bool, b: int<32>): bool {
return b;
}
diff --git a/src/test/tests/autocastTests/type-inference-fail-funcApp.pdl b/src/test/tests/autocastTests/type-inference-fail-funcApp.pdl
index f69d3e87..57730ebc 100644
--- a/src/test/tests/autocastTests/type-inference-fail-funcApp.pdl
+++ b/src/test/tests/autocastTests/type-inference-fail-funcApp.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-funcApp.pdl
def func(a: bool, b: int<32>): bool {
return b;
}
diff --git a/src/test/tests/autocastTests/type-inference-fail-numBinOp.pdl b/src/test/tests/autocastTests/type-inference-fail-numBinOp.pdl
index 3096b3d3..20697e4d 100644
--- a/src/test/tests/autocastTests/type-inference-fail-numBinOp.pdl
+++ b/src/test/tests/autocastTests/type-inference-fail-numBinOp.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-numBinOp.pdl
pipe test1(input: int<32>)[rf: int<32>[32]] {
a = true;
b = a + a;
diff --git a/src/test/tests/autocastTests/type-inference-fail-ternary.pdl b/src/test/tests/autocastTests/type-inference-fail-ternary.pdl
index e635be6e..f1f6f027 100644
--- a/src/test/tests/autocastTests/type-inference-fail-ternary.pdl
+++ b/src/test/tests/autocastTests/type-inference-fail-ternary.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-ternary.pdl
pipe test1(input: int<32>)[rf: int<32>[32]] {
a = true;
b = input;
diff --git a/src/test/tests/branchesCheck/branch-1.pdl b/src/test/tests/branchesCheck/branch-1.pdl
index 1161510d..04fda858 100644
--- a/src/test/tests/branchesCheck/branch-1.pdl
+++ b/src/test/tests/branchesCheck/branch-1.pdl
@@ -1,3 +1,4 @@
+// branch-1.pdl
pipe test(inarg: int<32>)[rf: int<32>[5]] {
start(rf);
diff --git a/src/test/tests/branchesCheck/branch-2.pdl b/src/test/tests/branchesCheck/branch-2.pdl
index 600f0410..fb16b4c1 100644
--- a/src/test/tests/branchesCheck/branch-2.pdl
+++ b/src/test/tests/branchesCheck/branch-2.pdl
@@ -1,3 +1,4 @@
+// branch-2.pdl
pipe test(inarg: int<32>)[rf: int<32>[5]] {
start(rf);
if (inarg{0:0} == 1) {
diff --git a/src/test/tests/branchesCheck/branch-3.pdl b/src/test/tests/branchesCheck/branch-3.pdl
index 9a35e83c..c813443b 100644
--- a/src/test/tests/branchesCheck/branch-3.pdl
+++ b/src/test/tests/branchesCheck/branch-3.pdl
@@ -1,3 +1,4 @@
+// branch-3.pdl
pipe test(cond: uint<2>, addr: uint<16>)[mem: int<32>[16]]: bool {
start(mem);
if (cond == 0) {
diff --git a/src/test/tests/branchesCheck/nested-1.pdl b/src/test/tests/branchesCheck/nested-1.pdl
index 64a3fb2f..9f7f1b6c 100644
--- a/src/test/tests/branchesCheck/nested-1.pdl
+++ b/src/test/tests/branchesCheck/nested-1.pdl
@@ -1,3 +1,4 @@
+// nested-1.pdl
pipe test(inarg: int<32>)[] {
if (inarg{0:0} == 1) {
if (inarg{1:1} == 0) {
diff --git a/src/test/tests/branchesCheck/nested-2.pdl b/src/test/tests/branchesCheck/nested-2.pdl
index 6e6a46ad..dd5e14b4 100644
--- a/src/test/tests/branchesCheck/nested-2.pdl
+++ b/src/test/tests/branchesCheck/nested-2.pdl
@@ -1,3 +1,4 @@
+// nested-2.pdl
pipe test(inarg: uint<32>)[] {
if (cast (inarg{0:0}, bool)) {
if (inarg{1:1} == u0) {
diff --git a/src/test/tests/branchesCheck/nested-branches-1.pdl b/src/test/tests/branchesCheck/nested-branches-1.pdl
index 0c55d066..365d609c 100644
--- a/src/test/tests/branchesCheck/nested-branches-1.pdl
+++ b/src/test/tests/branchesCheck/nested-branches-1.pdl
@@ -1,3 +1,4 @@
+// nested-branches-1.pdl
pipe multi_stg_mul(a1: int<32>, a2: int<32>)[]: int<32> {
int<32> rr = a1{15:0} * a2{15:0};
int<32> rl = a1{15:0} * a2{31:16};
diff --git a/src/test/tests/branchesCheck/split-1.pdl b/src/test/tests/branchesCheck/split-1.pdl
index 47ad0a52..ce7f852b 100644
--- a/src/test/tests/branchesCheck/split-1.pdl
+++ b/src/test/tests/branchesCheck/split-1.pdl
@@ -1,3 +1,4 @@
+// split-1.pdl
pipe test(inarg: int<32>)[] {
split {
case: (inarg{1:0} == 0<2>) {
diff --git a/src/test/tests/branchesCheck/split-2.pdl b/src/test/tests/branchesCheck/split-2.pdl
index 8888eb46..6586fd2c 100644
--- a/src/test/tests/branchesCheck/split-2.pdl
+++ b/src/test/tests/branchesCheck/split-2.pdl
@@ -1,3 +1,4 @@
+// split-2.pdl
pipe test(inarg: int<32>)[rf: int<32>[5](Queue)] {
start(rf);
int<2> cond = inarg{1:0};
diff --git a/src/test/tests/branchesCheck/split-3.pdl b/src/test/tests/branchesCheck/split-3.pdl
index ca3cc544..c57f5792 100644
--- a/src/test/tests/branchesCheck/split-3.pdl
+++ b/src/test/tests/branchesCheck/split-3.pdl
@@ -1,3 +1,4 @@
+// split-3.pdl
pipe test(inarg: int<32>)[rf: int<32>[5](Queue)] {
start(rf);
int<2> cond = inarg{1:0};
diff --git a/src/test/tests/branchesCheck/split-4.pdl b/src/test/tests/branchesCheck/split-4.pdl
index ab6028f8..0c06ebee 100644
--- a/src/test/tests/branchesCheck/split-4.pdl
+++ b/src/test/tests/branchesCheck/split-4.pdl
@@ -1,3 +1,4 @@
+// split-4.pdl
pipe test(inarg: int<32>)[rf: int<32>[5](Queue)] {
start(rf);
int<2> cond = inarg{1:0};
diff --git a/src/test/tests/exception/exn-recovery-spec.pdl b/src/test/tests/exception/exn-recovery-spec.pdl
index 52160cce..45ac90c0 100644
--- a/src/test/tests/exception/exn-recovery-spec.pdl
+++ b/src/test/tests/exception/exn-recovery-spec.pdl
@@ -1,5 +1,6 @@
+// exn-recovery-spec.pdl
//Expect 5 Success, 1 Exception, 1 Success post recovery
-exn-pipe cpu(pc :uint<16>)[acc :uint<4>[0](CheckpointQueue)] :uint<4> {
+exn-pipe cpu(pc :uint<16>)[acc :uint<8>[0](CheckpointQueue)] :uint<4> {
spec_check();
start(acc);
reserve(acc);
@@ -9,14 +10,18 @@ exn-pipe cpu(pc :uint<16>)[acc :uint<4>[0](CheckpointQueue)] :uint<4> {
spec_check();
s <- speccall cpu(pc + 1);
---
- spec_barrier();
+ spec_check();
block(acc);
- acc_val = acc[0];
+ acc_val <- acc[0];
+ ---
+ spec_check();
acc[0] <- acc_val + 1;
+ ---
+ spec_barrier();
if(acc_val == 6)
{
invalidate(s);
- except(u0<4>);
+ throw(u0<4>);
} else {
if(acc_val == 3)
{
@@ -31,7 +36,6 @@ exn-pipe cpu(pc :uint<16>)[acc :uint<4>[0](CheckpointQueue)] :uint<4> {
}
}
}
- ---
commit:
release(acc);
print("no exn at PC == %d! with acc_val of %d", pc, acc_val);
@@ -51,7 +55,7 @@ except(arg: uint<4>):
circuit {
ti = memory(uint<8>, 16);
- acc = register(uint<4>, 0);
+ acc = memory(uint<8>, 0);
locked = CheckpointQueue(acc);
c = new cpu[locked];
call c(u1<16>);
diff --git a/src/test/tests/exception/exn-recovery.pdl b/src/test/tests/exception/exn-recovery.pdl
index b7c78526..ed62abc2 100644
--- a/src/test/tests/exception/exn-recovery.pdl
+++ b/src/test/tests/exception/exn-recovery.pdl
@@ -1,3 +1,4 @@
+// exn-recovery.pdl
//Expect 5 Success, 1 Exception, 1 Success post recovery
exn-pipe cpu(pc :uint<16>)[acc :uint<4>[0](CheckpointQueue)] :uint<4> {
start(acc);
@@ -7,17 +8,23 @@ exn-pipe cpu(pc :uint<16>)[acc :uint<4>[0](CheckpointQueue)] :uint<4> {
block(acc);
acc_val = acc[0];
acc[0] <- acc_val + 1;
- if(acc_val == 10){
- output(0);
- } else {
- call cpu(pc + 1);
+ bool done = pc == u16<16>;
+ if (!done) {
+ call cpu(pc + 1);
}
---
- if(acc_val == 6)
- {
- except(u0<4>);
+ if(done){
+ output(0);
+ //print("Output called at PC == %d", pc);
+ } else {
+ if(acc_val == 6)
+ {
+ throw(u0<4>);
+ }
+ else{
+ //do nothing
+ }
}
- ---
commit:
release(acc);
print("no exn at PC == %d! with acc_val of %d", pc, acc_val);
@@ -31,7 +38,7 @@ except(arg: uint<4>):
acc[0] <- 9;
---
release(acc);
- call cpu(pc + 1);
+ call cpu(pc + 5);
}
diff --git a/src/test/tests/exception/exn-simple-chkp.pdl b/src/test/tests/exception/exn-simple-chkp.pdl
new file mode 100644
index 00000000..5cce8ed1
--- /dev/null
+++ b/src/test/tests/exception/exn-simple-chkp.pdl
@@ -0,0 +1,32 @@
+// exn-simple.pdl
+//Expect 5 Success, 1 Exception
+exn-pipe cpu(pc :uint<16>)[acc :uint<4>[0](CheckpointQueue)] :uint<4> {
+ start(acc);
+ reserve(acc);
+ end(acc);
+ ---
+ block(acc);
+ acc_val = acc[0];
+ acc[0] <- acc_val + 1;
+ call cpu(pc + 1);
+ ---
+ if(acc_val == 6)
+ {
+ throw(u0<4>);
+ }
+commit:
+ release(acc);
+ print("no exn at PC == %d! with acc_val of %d", pc, acc_val);
+except(arg :uint<4>):
+ print("exception at PC == %d! with arg: %d", pc, arg);
+ output(1);
+}
+
+
+circuit {
+ ti = memory(uint<8>, 16);
+ acc = register(uint<4>, 0);
+ locked = CheckpointQueue(acc);
+ c = new cpu[locked];
+ call c(u1<16>);
+}
diff --git a/src/test/tests/exception/exn-simple-spec.pdl b/src/test/tests/exception/exn-simple-spec.pdl
index 94b6a09b..074813f9 100644
--- a/src/test/tests/exception/exn-simple-spec.pdl
+++ b/src/test/tests/exception/exn-simple-spec.pdl
@@ -1,5 +1,6 @@
+// exn-simple-spec.pdl
//Expected Success
-exn-pipe cpu(pc :uint<16>)[acc :uint<4>[0](CheckpointQueue)] :uint<4> {
+exn-pipe cpu(pc :uint<16>)[acc :uint<8>[0](CheckpointQueue)] :uint<4> {
spec_check();
start(acc);
reserve(acc);
@@ -11,11 +12,13 @@ exn-pipe cpu(pc :uint<16>)[acc :uint<4>[0](CheckpointQueue)] :uint<4> {
---
spec_check();
block(acc);
- acc_val = acc[0];
+ acc_val <- acc[0];
+ ---
+ spec_check();
acc[0] <- acc_val + 1;
- if(acc_val == 6)
+ if(acc_val == u6<8>)
{
- except(u0<4>);
+ throw(u0<4>);
}
---
spec_barrier();
@@ -31,19 +34,22 @@ exn-pipe cpu(pc :uint<16>)[acc :uint<4>[0](CheckpointQueue)] :uint<4> {
verify(s, pc + 1);
}
}
- ---
commit:
release(acc);
print("no exn at PC == %d! with acc_val of %d", pc, acc_val);
except(arg: uint<4>):
print("exception at PC == %d! with arg: %d", pc, arg);
+ ---
+ exn_acc_val <- acc[0];
+ ---
+ print(exn_acc_val);
output(1);
}
circuit {
ti = memory(uint<8>, 16);
- acc = register(uint<4>, 0);
+ acc = memory(uint<8>, 0);
locked = CheckpointQueue(acc);
c = new cpu[locked];
call c(u1<16>);
diff --git a/src/test/tests/exception/exn-simple.pdl b/src/test/tests/exception/exn-simple.pdl
index 426bc48b..5cce8ed1 100644
--- a/src/test/tests/exception/exn-simple.pdl
+++ b/src/test/tests/exception/exn-simple.pdl
@@ -1,3 +1,4 @@
+// exn-simple.pdl
//Expect 5 Success, 1 Exception
exn-pipe cpu(pc :uint<16>)[acc :uint<4>[0](CheckpointQueue)] :uint<4> {
start(acc);
@@ -11,9 +12,8 @@ exn-pipe cpu(pc :uint<16>)[acc :uint<4>[0](CheckpointQueue)] :uint<4> {
---
if(acc_val == 6)
{
- except(u0<4>);
+ throw(u0<4>);
}
- ---
commit:
release(acc);
print("no exn at PC == %d! with acc_val of %d", pc, acc_val);
diff --git a/src/test/tests/exception/memInputs/acc b/src/test/tests/exception/memInputs/acc
new file mode 100644
index 00000000..5b290d00
--- /dev/null
+++ b/src/test/tests/exception/memInputs/acc
@@ -0,0 +1 @@
+00000000
diff --git a/src/test/tests/exception/solutions/exn-recovery.simsol b/src/test/tests/exception/solutions/exn-recovery.simsol
index 1afe3744..d0004bba 100644
--- a/src/test/tests/exception/solutions/exn-recovery.simsol
+++ b/src/test/tests/exception/solutions/exn-recovery.simsol
@@ -5,4 +5,8 @@ no exn at PC == 4! with acc_val of 3
no exn at PC == 5! with acc_val of 4
no exn at PC == 6! with acc_val of 5
exception at PC == 7! with arg: 0
-no exn at PC == 8! with acc_val of 9
+no exn at PC == 12! with acc_val of 9
+no exn at PC == 13! with acc_val of 10
+no exn at PC == 14! with acc_val of 11
+no exn at PC == 15! with acc_val of 12
+no exn at PC == 16! with acc_val of 13
\ No newline at end of file
diff --git a/src/test/tests/histogram/histogram.pdl b/src/test/tests/histogram/histogram.pdl
index 622b74e6..f47b0855 100644
--- a/src/test/tests/histogram/histogram.pdl
+++ b/src/test/tests/histogram/histogram.pdl
@@ -1,3 +1,4 @@
+// histogram.pdl
/*
n = 128
void histogram ( int feature [] , float weight [] , float hist [] , int n ) {
diff --git a/src/test/tests/histogram/histogram_bram.pdl b/src/test/tests/histogram/histogram_bram.pdl
index 8fb21d8b..c7e2b347 100644
--- a/src/test/tests/histogram/histogram_bram.pdl
+++ b/src/test/tests/histogram/histogram_bram.pdl
@@ -1,3 +1,4 @@
+// histogram_bram.pdl
/*
n = 128
void histogram ( int feature [] , float weight [] , float hist [] , int n ) {
diff --git a/src/test/tests/histogram/histogram_bram2.pdl b/src/test/tests/histogram/histogram_bram2.pdl
index 69b17c5f..bc86fa17 100644
--- a/src/test/tests/histogram/histogram_bram2.pdl
+++ b/src/test/tests/histogram/histogram_bram2.pdl
@@ -1,3 +1,4 @@
+// histogram_bram2.pdl
/*
n = 128
void histogram ( int feature [] , float weight [] , float hist [] , int n ) {
diff --git a/src/test/tests/histogram/histogram_nested.pdl b/src/test/tests/histogram/histogram_nested.pdl
index f58af2a5..aca96a7f 100644
--- a/src/test/tests/histogram/histogram_nested.pdl
+++ b/src/test/tests/histogram/histogram_nested.pdl
@@ -1,3 +1,4 @@
+// histogram_nested.pdl
/*
n = 128
void histogram ( int feature [] , float weight [] , float hist [] , int n ) {
diff --git a/src/test/tests/histogram/histogram_short.pdl b/src/test/tests/histogram/histogram_short.pdl
index 76284355..e2a5bbc8 100644
--- a/src/test/tests/histogram/histogram_short.pdl
+++ b/src/test/tests/histogram/histogram_short.pdl
@@ -1,3 +1,4 @@
+// histogram_short.pdl
/*
n = 128
void histogram ( int feature [] , float weight [] , float hist [] , int n ) {
diff --git a/src/test/tests/lockTests/lock-infer-1.pdl b/src/test/tests/lockTests/lock-infer-1.pdl
index 522cb6cd..6ad9d9fa 100644
--- a/src/test/tests/lockTests/lock-infer-1.pdl
+++ b/src/test/tests/lockTests/lock-infer-1.pdl
@@ -1,3 +1,4 @@
+// lock-infer-1.pdl
pipe ex1(in: bool)[r1: int<32>[5](Queue), r2: int<32>[5](Queue)] :bool {
uint<5> addr = u1<5>;
if (in) {
diff --git a/src/test/tests/lockTests/lock-infer-2.pdl b/src/test/tests/lockTests/lock-infer-2.pdl
index 0e19cd55..9a568ded 100644
--- a/src/test/tests/lockTests/lock-infer-2.pdl
+++ b/src/test/tests/lockTests/lock-infer-2.pdl
@@ -1,3 +1,4 @@
+// lock-infer-2.pdl
pipe ex2(in: bool)[rf: int<32>[5](Queue)] :bool {
uint<5> addr = u1<5>;
if (in) {
diff --git a/src/test/tests/lockTests/lock-infer-3.pdl b/src/test/tests/lockTests/lock-infer-3.pdl
index a6ad01e2..22d2008d 100644
--- a/src/test/tests/lockTests/lock-infer-3.pdl
+++ b/src/test/tests/lockTests/lock-infer-3.pdl
@@ -1,3 +1,4 @@
+// lock-infer-3.pdl
pipe ex4(inarg: int<32>)[rf: int<32>[5](Queue)] :int<32> {
uint<5> a1 = u0<5>;
diff --git a/src/test/tests/lockTests/lock-infer-4.pdl b/src/test/tests/lockTests/lock-infer-4.pdl
index badf4d54..70f966d4 100644
--- a/src/test/tests/lockTests/lock-infer-4.pdl
+++ b/src/test/tests/lockTests/lock-infer-4.pdl
@@ -1,3 +1,4 @@
+// lock-infer-4.pdl
pipe ex4(in: bool)[rf: int<32>[5](Queue)] :bool{
uint<5> addr = u1<5>;
reserve(rf[addr],R);
diff --git a/src/test/tests/lockTests/lock-merge-1.pdl b/src/test/tests/lockTests/lock-merge-1.pdl
index 83e34f3d..7f5af686 100644
--- a/src/test/tests/lockTests/lock-merge-1.pdl
+++ b/src/test/tests/lockTests/lock-merge-1.pdl
@@ -1,3 +1,4 @@
+// lock-merge-1.pdl
pipe ex1(in: bool)[r1: int<32>[5](Queue), r2: int<32>[5](Queue)] :bool {
start(r1);
start(r2);
diff --git a/src/test/tests/lockTests/lock-merge-2.pdl b/src/test/tests/lockTests/lock-merge-2.pdl
index 83c9fc98..a25ffbba 100644
--- a/src/test/tests/lockTests/lock-merge-2.pdl
+++ b/src/test/tests/lockTests/lock-merge-2.pdl
@@ -1,3 +1,4 @@
+// lock-merge-2.pdl
pipe ex2(in: bool)[rf: int<32>[5](Queue)] :bool {
start(rf);
uint<5> addr = u1<5>;
diff --git a/src/test/tests/lockTests/lock-merge-3.pdl b/src/test/tests/lockTests/lock-merge-3.pdl
index 4170177e..beaab0ed 100644
--- a/src/test/tests/lockTests/lock-merge-3.pdl
+++ b/src/test/tests/lockTests/lock-merge-3.pdl
@@ -1,3 +1,4 @@
+// lock-merge-3.pdl
pipe ex4(inarg: int<32>)[rf: int<32>[5](Queue)] :int<32> {
start(rf);
diff --git a/src/test/tests/lockTests/lock-merge-4.pdl b/src/test/tests/lockTests/lock-merge-4.pdl
index bf990a07..0a4a6b7f 100644
--- a/src/test/tests/lockTests/lock-merge-4.pdl
+++ b/src/test/tests/lockTests/lock-merge-4.pdl
@@ -1,3 +1,4 @@
+// lock-merge-4.pdl
pipe ex4(in: bool)[rf: int<32>[5](Queue)] :bool{
start(rf);
uint<5> addr = u1<5>;
diff --git a/src/test/tests/matpow/matpow.pdl b/src/test/tests/matpow/matpow.pdl
index 84aeb432..d78d666d 100644
--- a/src/test/tests/matpow/matpow.pdl
+++ b/src/test/tests/matpow/matpow.pdl
@@ -1,3 +1,4 @@
+// matpow.pdl
/*
void matrix_power( inout_int_t x[20][20], in_int_t row[20], in_int_t col[20], in_int_t a[20] )
{
diff --git a/src/test/tests/matpow/matpow_alt.pdl b/src/test/tests/matpow/matpow_alt.pdl
index 03a229f5..08868a39 100644
--- a/src/test/tests/matpow/matpow_alt.pdl
+++ b/src/test/tests/matpow/matpow_alt.pdl
@@ -1,3 +1,4 @@
+// matpow_alt.pdl
/*
void matrix_power( inout_int_t x[20][20], in_int_t row[20], in_int_t col[20], in_int_t a[20] )
{
diff --git a/src/test/tests/matpow/matpow_bram.pdl b/src/test/tests/matpow/matpow_bram.pdl
index 1451992e..74e9ef69 100644
--- a/src/test/tests/matpow/matpow_bram.pdl
+++ b/src/test/tests/matpow/matpow_bram.pdl
@@ -1,3 +1,4 @@
+// matpow_bram.pdl
/*
void matrix_power( inout_int_t x[20][20], in_int_t row[20], in_int_t col[20], in_int_t a[20] )
{
diff --git a/src/test/tests/multiExec/multiexec.pdl b/src/test/tests/multiExec/multiexec.pdl
index 121dbfb2..279bd0ca 100644
--- a/src/test/tests/multiExec/multiexec.pdl
+++ b/src/test/tests/multiExec/multiexec.pdl
@@ -1,3 +1,4 @@
+// multiexec.pdl
pipe multi_stg_mul(a1: int<32>, a2: int<32>)[]: int<32> {
int<32> rr = a1{15:0} * a2{15:0};
int<32> rl = a1{15:0} * a2{31:16};
diff --git a/src/test/tests/multiExec/multiexec_alt.pdl b/src/test/tests/multiExec/multiexec_alt.pdl
index 00e922bb..7e704e42 100644
--- a/src/test/tests/multiExec/multiexec_alt.pdl
+++ b/src/test/tests/multiExec/multiexec_alt.pdl
@@ -1,3 +1,4 @@
+// multiexec_alt.pdl
pipe multi_stg_mul(a1: int<32>, a2: int<32>)[]: int<32> {
int<32> rr = a1{15:0} * a2{15:0};
int<32> rl = a1{15:0} * a2{31:16};
diff --git a/src/test/tests/multiExec/multiexec_split.pdl b/src/test/tests/multiExec/multiexec_split.pdl
index 92f19bd3..033484d8 100644
--- a/src/test/tests/multiExec/multiexec_split.pdl
+++ b/src/test/tests/multiExec/multiexec_split.pdl
@@ -1,3 +1,4 @@
+// multiexec_split.pdl
pipe multi_stg_mul(a1: int<32>, a2: int<32>)[]: int<32> {
int<32> rr = a1{15:0} * a2{15:0};
int<32> rl = a1{15:0} * a2{31:16};
diff --git a/src/test/tests/registerRenamingTests/3-stg-lsq.pdl b/src/test/tests/registerRenamingTests/3-stg-lsq.pdl
index c98eb772..5c76638e 100644
--- a/src/test/tests/registerRenamingTests/3-stg-lsq.pdl
+++ b/src/test/tests/registerRenamingTests/3-stg-lsq.pdl
@@ -1,3 +1,4 @@
+// 3-stg-lsq.pdl
pipe test(pc: uint<32>)[rf: int<32>[5](LSQ)]: bool {
uint<5> rs1 = pc{4:0};
uint<5> rd = rs1 - u1<5>;
diff --git a/src/test/tests/registerRenamingTests/3-stg-pipe.pdl b/src/test/tests/registerRenamingTests/3-stg-pipe.pdl
index f161733e..b6694f17 100644
--- a/src/test/tests/registerRenamingTests/3-stg-pipe.pdl
+++ b/src/test/tests/registerRenamingTests/3-stg-pipe.pdl
@@ -1,3 +1,4 @@
+// 3-stg-pipe.pdl
pipe test(pc: uint<32>)[rf: int<32>[5](RenameRF)]: bool {
uint<5> rs1 = pc{4:0};
uint<5> rd = rs1 - u1<5>;
diff --git a/src/test/tests/registerRenamingTests/lock-wrong-type-nested-fail.pdl b/src/test/tests/registerRenamingTests/lock-wrong-type-nested-fail.pdl
index ea82bfa6..37cf0f40 100644
--- a/src/test/tests/registerRenamingTests/lock-wrong-type-nested-fail.pdl
+++ b/src/test/tests/registerRenamingTests/lock-wrong-type-nested-fail.pdl
@@ -1,3 +1,4 @@
+// lock-wrong-type-nested-fail.pdl
pipe test3(input: uint<32>)[rf: int<32>[5]] {
uint<5> rs1 = input{0:4};
uint<5> rs2 = input{5:9};
diff --git a/src/test/tests/registerRenamingTests/lock-wrong-type-read-write-fail.pdl b/src/test/tests/registerRenamingTests/lock-wrong-type-read-write-fail.pdl
index 6cef0698..f4553c21 100644
--- a/src/test/tests/registerRenamingTests/lock-wrong-type-read-write-fail.pdl
+++ b/src/test/tests/registerRenamingTests/lock-wrong-type-read-write-fail.pdl
@@ -1,3 +1,4 @@
+// lock-wrong-type-read-write-fail.pdl
pipe test3(input: uint<32>)[rf: int<32>[5]] {
uint<5> rs1 = input{0:4};
uint<5> rs2 = input{5:9};
diff --git a/src/test/tests/registerRenamingTests/lock-wrong-type-write-read-fail.pdl b/src/test/tests/registerRenamingTests/lock-wrong-type-write-read-fail.pdl
index 96053a53..1c560e4a 100644
--- a/src/test/tests/registerRenamingTests/lock-wrong-type-write-read-fail.pdl
+++ b/src/test/tests/registerRenamingTests/lock-wrong-type-write-read-fail.pdl
@@ -1,3 +1,4 @@
+// lock-wrong-type-write-read-fail.pdl
pipe test3(input: uint<32>)[rf: int<32>[5]] {
uint<5> rs1 = input{0:4};
uint<5> rs2 = input{5:9};
diff --git a/src/test/tests/registerRenamingTests/validLockTypes.pdl b/src/test/tests/registerRenamingTests/validLockTypes.pdl
index d7fe0a74..d77784c8 100644
--- a/src/test/tests/registerRenamingTests/validLockTypes.pdl
+++ b/src/test/tests/registerRenamingTests/validLockTypes.pdl
@@ -1,3 +1,4 @@
+// validLockTypes.pdl
//Expected Success
pipe test1(tinput: uint<32>)[rf: int<32>[5]] {
uint<5> rs1 = tinput{4:0};
diff --git a/src/test/tests/risc-pipe/risc-pipe-3stg.pdl b/src/test/tests/risc-pipe/risc-pipe-3stg.pdl
index 342278f0..34c63164 100644
--- a/src/test/tests/risc-pipe/risc-pipe-3stg.pdl
+++ b/src/test/tests/risc-pipe/risc-pipe-3stg.pdl
@@ -1,3 +1,4 @@
+// risc-pipe-3stg.pdl
def mul(arg1: int<32>, arg2: int<32>, op: uint<3>): int<32> {
uint<32> mag1 = cast(mag(arg1), uint<32>);
uint<32> mag2 = cast(mag(arg2), uint<32>);
diff --git a/src/test/tests/risc-pipe/risc-pipe-cache.pdl b/src/test/tests/risc-pipe/risc-pipe-cache.pdl
index a8628f55..3cc26c96 100644
--- a/src/test/tests/risc-pipe/risc-pipe-cache.pdl
+++ b/src/test/tests/risc-pipe/risc-pipe-cache.pdl
@@ -1,3 +1,4 @@
+// risc-pipe-cache.pdl
def alu(arg1: int<32>, arg2: int<32>, op: uint<3>, flip: bool): int<32> {
uint<5> shamt = cast(arg2{4:0}, uint<5>);
if (op == u0<3>) { //000 == ADD , flip == sub
diff --git a/src/test/tests/risc-pipe/risc-pipe-pldi-5-stg.pdl b/src/test/tests/risc-pipe/risc-pipe-pldi-5-stg.pdl
new file mode 100644
index 00000000..b8aa42d7
--- /dev/null
+++ b/src/test/tests/risc-pipe/risc-pipe-pldi-5-stg.pdl
@@ -0,0 +1,276 @@
+def alu(arg1: int<32>, arg2: int<32>, op: uint<3>, flip: bool): int<32> {
+ uint<5> shamt = cast(arg2{4:0}, uint<5>);
+ if (op == u0<3>) { //000 == ADD , flip == sub
+ if (!flip) {
+ return arg1 + arg2;
+ } else {
+ return arg1 - arg2;
+ }
+ } else {
+ if (op == u1<3>) { //001 == SLL
+ return arg1 << shamt;
+ } else {
+ if (op == u2<3>) { //010 == SLT
+ return (arg1 < arg2) ? 1<32> : 0<32>;
+ } else {
+ if (op == u3<3>) { //011 == SLTU
+ uint<32> un1 = cast(arg1, uint<32>);
+ uint<32> un2 = cast(arg2, uint<32>);
+ return (un1 < un2) ? 1<32> : 0<32>;
+ } else {
+ if (op == u4<3>) { //100 == XOR
+ return arg1 ^ arg2;
+ } else {
+ if (op == u5<3>) { //101 == SRL / SRA
+ if (!flip) {
+ return cast((cast(arg1, uint<32>)) >> shamt, int<32>); //SRL
+ } else {
+ return arg1 >> shamt; //SRA
+ }
+ } else {
+ if (op == u6<3>) { //110 == OR
+ return arg1 | arg2;
+ } else { //111 == AND
+ return arg1 & arg2;
+ }}}}}}}
+
+}
+
+//true if taking branch
+def br(op:uint<3>, arg1:int<32>, arg2:int<32>): bool {
+ bool eq = arg1 == arg2;
+ bool lt = arg1 < arg2;
+ uint<32> un1 = cast(arg1, uint<32>);
+ uint<32> un2 = cast(arg2, uint<32>);
+ bool ltu = un1 < un2;
+ if (op == u0<3>) { //BEQ
+ return eq;
+ } else {
+ if (op == u1<3>) { //BNE
+ return !eq;
+ } else {
+ if (op == u4<3>) { //BLT
+ return lt;
+ } else {
+ if (op == u5<3>) { //BGE
+ return !lt;
+ } else {
+ if (op == u6<3>) { //BLTU
+ return ltu;
+ } else {
+ if (op == u7<3>) { //BGEU
+ return !ltu;
+ } else {
+ return false;
+ }}}}}}
+}
+
+
+def storeMask(off: uint<2>, op: uint<3>): uint<4> {
+ if (op == u0<3>) { //SB
+ return (u0b0001<4> << off);
+ } else {
+ if (op == u1<3>) { //SH
+ uint<2> shamt = off{1:1} ++ u0<1>;
+ return (u0b0011<4> << shamt);
+ } else { //SW
+ return u0b1111<4>;
+ }}
+}
+
+def maskLoad(data: int<32>, op: uint<3>, start: uint<2>): int<32> {
+ //start == offset in bytes, need to multiply by 8
+ uint<5> boff = start ++ u0<3>;
+ int<32> tmp = data >> boff;
+ uint<8> bdata = cast(tmp, uint<8>);
+ uint<16> hdata = cast(tmp, uint<16>);
+
+ if (op == u0<3>) { //LB
+ return cast(bdata, int<32>);
+ } else {
+ if (op == u1<3>) { //LH
+ return cast(hdata, int<32>);
+ } else {
+ if (op == u2<3>) { //LW
+ return data;
+ } else {
+ if (op == u4<3>) { //LBU
+ uint<32> zext = cast(bdata, uint<32>);
+ return cast(zext, int<32>);
+ } else {
+ if (op == u5<3>) { //LHU
+ uint<32> zext = cast(hdata, uint<32>);
+ return cast(zext, int<32>);
+ } else {
+ return 0<32>;
+ }}}}}
+}
+
+pipe cpu(pc: int<32>)[rf: int<32>[5](BypassRF), imem: int<32>[32], dmem: int<32>[32]]: bool {
+ spec_check();
+ start(imem);
+ uint<32> pcaddr = cast(pc, uint<32>);
+ int<32> insn <- imem[pcaddr];
+ end(imem);
+ s <- speccall cpu(pc + 1<32>);
+ ---
+ spec_barrier();
+ //This OPCODE is J Self and thus we're using it to signal termination
+ bool done = insn == 0x0000006f<32>;
+ int<7> opcode = insn{6:0};
+ uint<5> rs1 = cast(insn{19:15}, uint<5>);
+ uint<5> rs2 = cast(insn{24:20}, uint<5>);
+ uint<5> rd = cast(insn{11:7}, uint<5>);
+ uint<7> funct7 = cast(insn{31:25}, uint<7>);
+ uint<3> funct3 = cast(insn{14:12}, uint<3>);
+ int<1> flipBit = insn{30:30};
+ int<32> immI = cast(insn{31:20}, int<32>);
+ int<32> immS = cast((insn{31:25} ++ insn{11:7}), int<32>);
+ int<13> immBTmp = insn{31:31} ++ insn{7:7} ++ insn{30:25} ++ insn{11:8} ++ 0<1>;
+ int<32> immB = cast(immBTmp, int<32>);
+ int<21> immJTmp = insn{31:31} ++ insn{19:12} ++ insn{20:20} ++ insn{30:21} ++ 0<1>;
+ int<32> immJ = cast(immJTmp, int<32>);
+ int<12> immJRTmp = insn{31:20};
+ int<32> immJR = cast(immJRTmp, int<32>);
+ int<32> immU = insn{31:12} ++ 0<12>;
+ uint<3> doAdd = u0<3>;
+ bool isOpImm = opcode == 0b0010011<7>;
+ bool flip = (!isOpImm) && (flipBit == 1<1>);
+ bool isLui = opcode == 0b0110111<7>;
+ bool isAui = opcode == 0b0010111<7>;
+ bool isOp = opcode == 0b0110011<7>;
+ bool isJal = opcode == 0b1101111<7>;
+ bool isJalr = opcode == 0b1100111<7>;
+ bool isBranch = opcode == 0b1100011<7>;
+ bool isStore = opcode == 0b0100011<7>;
+ bool isLoad = opcode == 0b0000011<7>;
+ bool needrs1 = !isJal;
+ bool needrs2 = isOp || isBranch || isStore || isJalr;
+ bool writerd = (rd != u0<5>) && (isOp || isOpImm || isLoad || isJal || isJalr || isLui || isAui);
+ bool notBranch = (!isBranch) && (!isJal) && (!isJalr);
+ start(rf);
+ if (needrs1) {
+ reserve(rf[rs1], R);
+ }
+ if (needrs2) {
+ reserve(rf[rs2], R);
+ }
+ if (writerd) {
+ reserve(rf[rd], W);
+ }
+ end(rf);
+ bool useRf1 = (!isAui) && (!isLui);
+ int<32> alu_arg1_tmp = (isAui) ? (pc << 2) : 0<32>;
+ bool useRf2 = (!isAui) && (!isLui) && (!isStore) && (!isOpImm) && (!isLoad) && (!isJalr);
+ int<32> alu_arg2_tmp = (isAui || isLui) ? immU : ((isStore) ? immS : ((isOpImm || isLoad) ? immI : ((isJalr) ? immJR : 0<32>)));
+ int<32> pcOff = ((isBranch) ? immB : immJ) >> 2;
+ ---
+ if (needrs1) {
+ block(rf[rs1]);
+ int<32> rf1 = rf[rs1];
+ release(rf[rs1]);
+ } else {
+ int<32> rf1 = 0<32>;
+ }
+ if (needrs2) {
+ block(rf[rs2]);
+ int<32> rf2 = rf[rs2];
+ release(rf[rs2]);
+ } else {
+ int<32> rf2 = 0<32>;
+ }
+
+ int<32> alu_arg1 = (useRf1) ? rf1 : alu_arg1_tmp;
+ int<32> alu_arg2 = (useRf2) ? rf2 : alu_arg2_tmp;
+ bool take = br(funct3, alu_arg1, alu_arg2);
+ int<32> tmppc = pc + 1<32>;
+ if (!done) {
+ if ((isBranch && take) || isJal || isJalr) {
+ invalidate(s);
+ } else {
+ verify(s, tmppc);
+ }} else {
+ invalidate(s);
+ }
+ bool alu_flip = (isStore || isLoad || isAui || isLui) ? false : flip;
+ uint<3> alu_funct3 = (isStore || isLoad || isAui || isLui) ? doAdd : funct3;
+ int<32> alu_res = alu(alu_arg1, alu_arg2, alu_funct3, alu_flip);
+ int<32> linkpc = tmppc << 2;
+ int<32> rddata = (isJal || isJalr) ? linkpc : alu_res;
+ int<32> takePc = pc + pcOff;
+ split {
+ case: (isBranch) {
+ int<32> npc = (take) ? (takePc) : (tmppc);
+ }
+ case: (isJal) {
+ int<32> npc = takePc;
+ }
+ case: (isJalr) {
+ int<32> npc = alu_res >> 2;
+ }
+ default: {
+ int<32> npc = tmppc;
+ }
+ }
+ if ((!done)) {
+ if ((isBranch && take) || isJal || isJalr) {
+ call cpu(npc);
+ }
+ }
+ int<32> stdata = rf2;
+ ---
+ if (writerd && (!isLoad)) {
+ block(rf[rd]);
+ rf[rd] <- rddata;
+ }
+ uint<32> tmpaddr = cast(rddata, uint<32>);
+ uint<32> memaddr = (tmpaddr >> 2);
+ uint<2> boff = cast(alu_res{1:0}, uint<2>);
+ start(dmem);
+ split {
+ case: (isLoad) {
+ uint<32> raddr = memaddr;
+ int<32> wdata <- dmem[raddr];
+ }
+ case: (isStore) {
+ uint<32> waddr = memaddr;
+ //use bottom bits of data and place in correct offset
+ //shift by boff*8
+ uint<5> nboff = boff ++ u0<3>;
+ dmem[waddr, storeMask(boff, funct3)] <- (stdata << nboff);
+ int<32> wdata <- 0<32>;
+ }
+ default: {
+ int<32> wdata <- 0<32>;
+ }
+ }
+ end(dmem);
+ ---
+ print("PC: %h", pc << 2);
+ print("INSN: %h", insn);
+ if (writerd && isLoad) {
+ block(rf[rd]);
+ int<32> insnout = maskLoad(wdata, funct3, boff);
+ rf[rd] <- insnout;
+ } else {
+ int<32> insnout = rddata;
+ }
+ if (writerd) {
+ print("Writing %d to r%d", insnout, rd);
+ }
+ ---
+ if (writerd) {
+ release(rf[rd]);
+ }
+ if (done) {
+ output(true);
+ }
+}
+
+circuit {
+ ti = memory(int<32>, 32);
+ td = memory(int<32>, 32);
+ rf = rflock BypassRF(int<32>, 5, 8);
+ c = new cpu[rf, ti, td];
+ call c(0<32>);
+}
\ No newline at end of file
diff --git a/src/test/tests/risc-pipe/risc-pipe-spec-bypass-bht.pdl b/src/test/tests/risc-pipe/risc-pipe-spec-bypass-bht.pdl
index 48973476..b05c2039 100644
--- a/src/test/tests/risc-pipe/risc-pipe-spec-bypass-bht.pdl
+++ b/src/test/tests/risc-pipe/risc-pipe-spec-bypass-bht.pdl
@@ -1,3 +1,4 @@
+// risc-pipe-spec-bypass-bht.pdl
extern BHT {
method req(pc: int, skip: int, take: int): int;
method upd(pc: int, taken: bool): ();
diff --git a/src/test/tests/risc-pipe/risc-pipe-spec-exn-1.pdl b/src/test/tests/risc-pipe/risc-pipe-spec-exn-1.pdl
new file mode 100644
index 00000000..d2817a97
--- /dev/null
+++ b/src/test/tests/risc-pipe/risc-pipe-spec-exn-1.pdl
@@ -0,0 +1,370 @@
+// risc-pipe-spec-write.pdl
+extern BHT {
+ method req(pc: int, skip: int, take: int): int;
+ method upd(pc: int, taken: bool): ();
+}
+
+def mul(arg1: int<32>, arg2: int<32>, op: uint<3>): int<32> {
+ uint<32> mag1 = cast(mag(arg1), uint<32>);
+ uint<32> mag2 = cast(mag(arg2), uint<32>);
+ //MULHU => positive sign always
+ int<32> s1 = (op == u3<3>) ? 1<32> : sign(arg1);
+ //MULHU/MULHSU => positive sign always
+ int<32> s2 = (op >= u2<3>) ? 1<32> : sign(arg2);
+ int<64> magRes = cast((mag1 * mag2), int<64>);
+ int<64> m = (s1 == s2) ? (magRes) : -(magRes);
+ if (op == u0<3>) { //MUL
+ return m{31:0};
+ } else {
+ return m{63:32};
+ }
+}
+
+def alu(arg1: int<32>, arg2: int<32>, op: uint<3>, flip: bool): int<32> {
+ uint<5> shamt = cast(arg2{4:0}, uint<5>);
+ if (op == u0<3>) { //000 == ADD , flip == sub
+ if (!flip) {
+ return arg1 + arg2;
+ } else {
+ return arg1 - arg2;
+ }
+ } else {
+ if (op == u1<3>) { //001 == SLL
+ return arg1 << shamt;
+ } else {
+ if (op == u2<3>) { //010 == SLT
+ return (arg1 < arg2) ? 1<32> : 0<32>;
+ } else {
+ if (op == u3<3>) { //011 == SLTU
+ uint<32> un1 = cast(arg1, uint<32>);
+ uint<32> un2 = cast(arg2, uint<32>);
+ return (un1 < un2) ? 1<32> : 0<32>;
+ } else {
+ if (op == u4<3>) { //100 == XOR
+ return arg1 ^ arg2;
+ } else {
+ if (op == u5<3>) { //101 == SRL / SRA
+ if (!flip) {
+ return cast((cast(arg1, uint<32>)) >> shamt, int<32>); //SRL
+ } else {
+ return arg1 >> shamt; //SRA
+ }
+ } else {
+ if (op == u6<3>) { //110 == OR
+ return arg1 | arg2;
+ } else { //111 == AND
+ return arg1 & arg2;
+ }}}}}}}
+
+}
+
+//true if taking branch
+def br(op:uint<3>, arg1:int<32>, arg2:int<32>): bool {
+ if (op == u0<3>) { //BEQ
+ return (arg1 == arg2);
+ } else {
+ if (op == u1<3>) { //BNE
+ return (arg1 != arg2);
+ } else {
+ if (op == u4<3>) { //BLT
+ return (arg1 < arg2);
+ } else {
+ if (op == u5<3>) { //BGE
+ return (arg1 >= arg2);
+ } else {
+ if (op == u6<3>) { //BLTU
+ uint<32> un1 = cast(arg1, uint<32>);
+ uint<32> un2 = cast(arg2, uint<32>);
+ return (un1 < un2);
+ } else {
+ if (op == u7<3>) { //BGEU
+ uint<32> un1 = cast(arg1, uint<32>);
+ uint<32> un2 = cast(arg2, uint<32>);
+ return(un1 >= un2);
+ } else {
+ return false;
+ }}}}}}
+}
+
+
+def storeMask(off: uint<2>, op: uint<3>): uint<4> {
+ if (op == u0<3>) { //SB
+ return (u0b0001<4> << off);
+ } else {
+ if (op == u1<3>) { //SH
+ uint<2> shamt = off{1:1} ++ u0<1>;
+ return (u0b0011<4> << shamt);
+ } else { //SW
+ return u0b1111<4>;
+ }}
+}
+
+def maskLoad(data: int<32>, op: uint<3>, start: uint<2>): int<32> {
+ //start == offset in bytes, need to multiply by 8
+ uint<5> boff = start ++ u0<3>;
+ int<32> tmp = data >> boff;
+ uint<8> bdata = cast(tmp, uint<8>);
+ uint<16> hdata = cast(tmp, uint<16>);
+
+ if (op == u0<3>) { //LB
+ return cast(bdata, int<32>);
+ } else {
+ if (op == u1<3>) { //LH
+ return cast(hdata, int<32>);
+ } else {
+ if (op == u2<3>) { //LW
+ return data;
+ } else {
+ if (op == u4<3>) { //LBU
+ uint<32> zext = cast(bdata, uint<32>);
+ return cast(zext, int<32>);
+ } else {
+ if (op == u5<3>) { //LHU
+ uint<32> zext = cast(hdata, uint<32>);
+ return cast(zext, int<32>);
+ } else {
+ return 0<32>;
+ }}}}}
+}
+
+pipe multi_stg_div(num: uint<32>, denom: uint<32>, quot: uint<32>, acc: uint<32>, cnt: uint<5>, retQuot: bool)[]: uint<32> {
+ uint<32> tmp = acc{30:0} ++ num{31:31};
+ uint<32> na = (tmp >= denom) ? (tmp - denom) : (tmp);
+ uint<32> nq = (tmp >= denom) ? ((quot << 1){31:1} ++ u1<1>) : (quot << 1);
+ uint<32> nnum = num << 1;
+ bool done = (cnt == u31<5>);
+ if (done) {
+ output( (retQuot) ? nq : na );
+ } else {
+ call multi_stg_div(nnum, denom, nq, na, cnt + u1<5>, retQuot);
+ }
+}
+
+
+exn-pipe cpu(pc: int<16>)[rf: int<32>[5](CheckpointRF), imem: int<32>[16], dmem: int<32>[16], div: multi_stg_div, bht: BHT, csrf: int<32>[2]]: bool {
+ spec_check();
+ start(imem);
+ uint<16> pcaddr = cast(pc, uint<16>);
+ int<32> insn <- imem[pcaddr];
+ end(imem);
+ s <- speccall cpu(pc + 1<16>);
+ ---
+ //This OPCODE is J Self and thus we're using it to signal termination
+ bool done = insn == 0x0000006f<32>;
+ int<7> opcode = insn{6:0};
+ uint<5> rs1 = cast(insn{19:15}, uint<5>);
+ uint<5> rs2 = cast(insn{24:20}, uint<5>);
+ uint<5> rd = cast(insn{11:7}, uint<5>);
+ uint<7> funct7 = cast(insn{31:25}, uint<7>);
+ uint<3> funct3 = cast(insn{14:12}, uint<3>);
+ int<1> flipBit = insn{30:30};
+ int<32> immI = cast(insn{31:20}, int<32>);
+ int<32> immS = cast((insn{31:25} ++ insn{11:7}), int<32>);
+ int<13> immBTmp = insn{31:31} ++ insn{7:7} ++ insn{30:25} ++ insn{11:8} ++ 0<1>;
+ int<16> immB = cast(immBTmp, int<16>);
+ int<21> immJTmp = insn{31:31} ++ insn{19:12} ++ insn{20:20} ++ insn{30:21} ++ 0<1>;
+ int<32> immJ = cast(immJTmp, int<32>);
+ int<12> immJRTmp = insn{31:20};
+ int<16> immJR = cast(immJRTmp, int<16>);
+ int<32> immU = insn{31:12} ++ 0<12>;
+ uint<3> doAdd = u0<3>;
+ bool isOpImm = opcode == 0b0010011<7>;
+ bool flip = (!isOpImm) && (flipBit == 1<1>);
+ bool isLui = opcode == 0b0110111<7>;
+ bool isAui = opcode == 0b0010111<7>;
+ bool isOp = opcode == 0b0110011<7>;
+ bool isJal = opcode == 0b1101111<7>;
+ bool isJalr = opcode == 0b1100111<7>;
+ bool isBranch = opcode == 0b1100011<7>;
+ bool isStore = opcode == 0b0100011<7>;
+ bool isLoad = opcode == 0b0000011<7>;
+ bool isMDiv = (funct7 == u1<7>) && isOp;
+ bool isDiv = isMDiv && (funct3 >= u4<3>);
+ bool isMul = isMDiv && (funct3 < u4<3>);
+ bool isSystem = opcode == 0b1110011<7>;
+ bool isEcall = isSystem && (immI == 0<32>);
+ bool isMret = isSystem && (funct7 == u24<7>) && (rs2 == u2<5>);
+ bool needrs1 = !isJal;
+ bool needrs2 = isOp || isBranch || isStore || isJalr;
+ bool writerd = (rd != u0<5>) && (isOp || isOpImm || isLoad || isJal || isJalr || isLui || isAui);
+ spec_check();
+ bool notBranch = (!isBranch) && (!isJal) && (!isJalr);
+ if (!done) {
+ if (notBranch) {
+ s2 <- s;
+ } else {
+ if (isBranch) {
+ s2 <- update(s, bht.req(pc, immB, 1<16>));
+ } else {
+ s2 <- s;
+ invalidate(s);
+ }}} else { s2 <- s; invalidate(s); }
+ if (isEcall){
+ throw(u8<4>);
+ }
+ if (isMret){
+ throw(u3<4>);
+ }
+ start(rf);
+ if (!done && (notBranch || isBranch)) { checkpoint(rf); }
+ if (needrs1) {
+ reserve(rf[rs1], R);
+ }
+ if (needrs2) {
+ reserve(rf[rs2], R);
+ }
+ if (writerd) {
+ reserve(rf[rd], W);
+ }
+ end(rf);
+ ---
+ spec_check();
+ if (needrs1) {
+ block(rf[rs1]);
+ int<32> rf1 = rf[rs1];
+ release(rf[rs1]);
+ } else {
+ int<32> rf1 = 0<32>;
+ }
+ if (needrs2) {
+ block(rf[rs2]);
+ int<32> rf2 = rf[rs2];
+ release(rf[rs2]);
+ } else {
+ int<32> rf2 = 0<32>;
+ }
+ bool take = br(funct3, rf1, rf2);
+ if (isBranch) {
+ //divide by 4 b/c we count instructions not bytes
+ int<16> offpc = pc + (immB >> 2);
+ int<16> npc = (take) ? (offpc) : (pc + 1<16>);
+ } else {
+ if (isJal) {
+ //divide by 4 since it counts bytes instead of insns
+ int<32> npc32 = cast(pc, int<32>) + (immJ >> 2);
+ int<16> npc = npc32{15:0};
+ } else {
+ if (isJalr) {
+ int<16> npc = (rf1{15:0} + immJR) >> 2;
+ } else {
+ int<16> npc = pc + 1<16>;
+ }}}
+ int<32> alu_arg1 = (isAui) ? ((0<16> ++ pc) << 2) : rf1;
+ int<32> alu_arg2 = (isAui) ? immU : ((isStore) ? immS : ((isOpImm || isLoad) ? immI : rf2));
+ bool alu_flip = (isStore || isLoad || isAui) ? false : flip;
+ uint<3> alu_funct3 = (isStore || isLoad || isAui) ? doAdd : funct3;
+ int<32> alu_res = alu(alu_arg1, alu_arg2, alu_funct3, alu_flip);
+ int<16> tmppc = pc + 1<16>;
+ int<32> linkpc = 0<16> ++ (tmppc << 2);
+ int<32> mulres = mul(rf1, rf2, funct3);
+ if (writerd && (!isLoad) && (!isDiv)) {
+ block(rf[rd]);
+ int<32> rddata = (isLui) ? immU : ((isMul) ? mulres : ((isJal || isJalr) ? linkpc : alu_res));
+ rf[rd] <- rddata;
+ } else {
+ int<32> rddata = 0<32>;
+ }
+ ---
+ spec_barrier(); //delayed just to force writes to happen speculatively
+ if (!done) {
+ if (!notBranch) {
+ if (isBranch) {
+ verify(s2, npc) { bht.upd(pc, take) };
+ } else {
+ call cpu(npc);
+ }
+ } else {
+ verify(s, pc + 1<16>);
+ }
+ }
+
+ if (isDiv) {
+ int<32> sdividend = sign(rf1);
+ //For REM, ignore sign of divisor
+ int<32> sdivisor = (funct3 == u6<3>) ? 1<32> : sign(rf2);
+ bool isSignedDiv = ((funct3 == u4<3>) || (funct3 == u6<3>));
+ uint<32> dividend = (isSignedDiv) ? cast(mag(rf1), uint<32>) : cast(rf1, uint<32>);
+ uint<32> divisor = (isSignedDiv) ? cast(mag(rf2), uint<32>) : cast(rf2, uint<32>);
+ bool retQuot = funct3 <= u5<3>;
+ bool invertRes <- isSignedDiv && (sdividend != sdivisor);
+ uint<32> udivout <- call div(dividend, divisor, u0<32>, u0<32>, u0<5>, retQuot);
+ } else {
+ bool invertRes <- false;
+ uint<32> udivout <- u0<32>;
+ }
+ uint<32> tmpaddr = cast(alu_res, uint<32>);
+ uint<16> memaddr = (tmpaddr >> 2){15:0};
+ uint<2> boff = cast(alu_res{1:0}, uint<2>);
+ start(dmem);
+ split {
+ case: (isLoad) {
+ uint<16> raddr = memaddr;
+ int<32> wdata <- dmem[raddr];
+ }
+ case: (isStore) {
+ uint<16> waddr = memaddr;
+ //use bottom bits of data and place in correct offset
+ //shift by boff*8
+ uint<5> nboff = boff ++ u0<3>;
+ dmem[waddr, storeMask(boff, funct3)] <- (rf2 << nboff);
+ int<32> wdata <- 0<32>;
+ }
+ default: {
+ int<32> wdata <- 0<32>;
+ }
+ }
+ end(dmem);
+ ---
+ print("PC: %h", pc << 2);
+ print("INSN: %h", insn);
+ if (writerd) {
+ if (isLoad) {
+ block(rf[rd]);
+ int<32> insnout = maskLoad(wdata, funct3, boff);
+ rf[rd] <- insnout;
+ } else {
+ if (isDiv) {
+ block(rf[rd]);
+ int<32> divout = (invertRes) ? -(cast(udivout, int<32>)) : cast(udivout, int<32>);
+ int<32> insnout = divout;
+ rf[rd] <- insnout;
+ } else {
+ int<32> insnout = rddata;
+ }}
+ print("Writing %d to r%d", insnout, rd);
+ }
+ ---
+commit:
+ if (writerd) {
+ release(rf[rd]);
+ }
+ if (done) { output(true); }
+except(exncode: uint<4>): // mepc = csrf[0], mtvec = csrf[1], mcause = csrf[2]
+ print("exception at PC == %d! with exncode: %d", pc, exncode);
+ start(csrf);
+ if (exncode == u8<4>){
+ csrf[0] <- cast(pc, int<32>); // write to mepc
+ int<32> csrret = csrf[1]; // read from mtvec
+ int<16> npc = csrret{15:0};
+ } else { if (exncode == u3<4>){
+ int<32> csrret = csrf[0]; // read from mepc
+ int<16> npc = csrret{15:0} + 1;
+ } else { int<16> npc = pc + 1; }}
+ ---
+ csrf[2] <- cast(exncode, int<32>); // write to mcause
+ end(csrf);
+ ---
+ print("GOTO PC: %d", npc);
+ call cpu(npc);
+}
+
+circuit {
+ ti = memory(int<32>, 16);
+ td = memory(int<32>, 16);
+ rf = rflock CheckpointRF(int<32>, 5, 64);
+ csrf = regfile(int<32>, 2);
+ div = new multi_stg_div[];
+ b = new BHT<16>[](4);
+ c = new cpu[rf, ti, td, div, b, csrf];
+ call c(0<16>);
+}
\ No newline at end of file
diff --git a/src/test/tests/risc-pipe/risc-pipe-spec-exn-2.pdl b/src/test/tests/risc-pipe/risc-pipe-spec-exn-2.pdl
new file mode 100644
index 00000000..1ef051fa
--- /dev/null
+++ b/src/test/tests/risc-pipe/risc-pipe-spec-exn-2.pdl
@@ -0,0 +1,419 @@
+// risc-pipe-spec-write.pdl
+extern BHT {
+ method req(pc: int, skip: int, take: int): int;
+ method upd(pc: int, taken: bool): ();
+}
+
+def csr_map(csrAddr: uint<12>): uint<5> {
+ if (csrAddr == 0x300) { //mstatus: Machine status register
+ return u0<5>; } else {
+ if (csrAddr == 0x301) { //misa: ISA and extensions
+ return u1<5>; } else {
+ if (csrAddr == 0x302) { //medeleg: Machine exception delegation register
+ return u2<5>; } else {
+ if (csrAddr == 0x303) { //mideleg: Machine interrupt delegation register
+ return u3<5>; } else {
+ if (csrAddr == 0x304) { //mie: Machine interrupt-enable register
+ return u4<5>; } else {
+ if (csrAddr == 0x305) { //mtvec: Machine trap-handler base address
+ return u5<5>; } else {
+ if (csrAddr == 0x340) { //mscratch: Scratch register for machine trap handlers
+ return u6<5>; } else {
+ if (csrAddr == 0x341) { //mepc: Machine exception program counter
+ return u7<5>; } else {
+ if (csrAddr == 0x342) { //mcause: Machine trap cause
+ return u8<5>; } else {
+ if (csrAddr == 0x343) { //mtval: Machine bad address or instruction
+ return u9<5>; } else {
+ if (csrAddr == 0x344) { //mip: Machine interrupt pending
+ return u10<5>; } else {
+ if (csrAddr == 0x34A) { //mtinst: Machine trap instruction (transformed)
+ return u11<5>; } else {
+ return u31<5>;}}}}}}}}}}}}
+}
+
+def mul(arg1: int<32>, arg2: int<32>, op: uint<3>): int<32> {
+ uint<32> mag1 = cast(mag(arg1), uint<32>);
+ uint<32> mag2 = cast(mag(arg2), uint<32>);
+ //MULHU => positive sign always
+ int<32> s1 = (op == u3<3>) ? 1<32> : sign(arg1);
+ //MULHU/MULHSU => positive sign always
+ int<32> s2 = (op >= u2<3>) ? 1<32> : sign(arg2);
+ int<64> magRes = cast((mag1 * mag2), int<64>);
+ int<64> m = (s1 == s2) ? (magRes) : -(magRes);
+ if (op == u0<3>) { //MUL
+ return m{31:0};
+ } else {
+ return m{63:32};
+ }
+}
+
+def alu(arg1: int<32>, arg2: int<32>, op: uint<3>, flip: bool): int<32> {
+ uint<5> shamt = cast(arg2{4:0}, uint<5>);
+ if (op == u0<3>) { //000 == ADD , flip == sub
+ if (!flip) {
+ return arg1 + arg2;
+ } else {
+ return arg1 - arg2;
+ }
+ } else {
+ if (op == u1<3>) { //001 == SLL
+ return arg1 << shamt;
+ } else {
+ if (op == u2<3>) { //010 == SLT
+ return (arg1 < arg2) ? 1<32> : 0<32>;
+ } else {
+ if (op == u3<3>) { //011 == SLTU
+ uint<32> un1 = cast(arg1, uint<32>);
+ uint<32> un2 = cast(arg2, uint<32>);
+ return (un1 < un2) ? 1<32> : 0<32>;
+ } else {
+ if (op == u4<3>) { //100 == XOR
+ return arg1 ^ arg2;
+ } else {
+ if (op == u5<3>) { //101 == SRL / SRA
+ if (!flip) {
+ return cast((cast(arg1, uint<32>)) >> shamt, int<32>); //SRL
+ } else {
+ return arg1 >> shamt; //SRA
+ }
+ } else {
+ if (op == u6<3>) { //110 == OR
+ return arg1 | arg2;
+ } else { //111 == AND
+ return arg1 & arg2;
+ }}}}}}}
+
+}
+
+//true if taking branch
+def br(op:uint<3>, arg1:int<32>, arg2:int<32>): bool {
+ if (op == u0<3>) { //BEQ
+ return (arg1 == arg2);
+ } else {
+ if (op == u1<3>) { //BNE
+ return (arg1 != arg2);
+ } else {
+ if (op == u4<3>) { //BLT
+ return (arg1 < arg2);
+ } else {
+ if (op == u5<3>) { //BGE
+ return (arg1 >= arg2);
+ } else {
+ if (op == u6<3>) { //BLTU
+ uint<32> un1 = cast(arg1, uint<32>);
+ uint<32> un2 = cast(arg2, uint<32>);
+ return (un1 < un2);
+ } else {
+ if (op == u7<3>) { //BGEU
+ uint<32> un1 = cast(arg1, uint<32>);
+ uint<32> un2 = cast(arg2, uint<32>);
+ return(un1 >= un2);
+ } else {
+ return false;
+ }}}}}}
+}
+
+
+def storeMask(off: uint<2>, op: uint<3>): uint<4> {
+ if (op == u0<3>) { //SB
+ return (u0b0001<4> << off);
+ } else {
+ if (op == u1<3>) { //SH
+ uint<2> shamt = off{1:1} ++ u0<1>;
+ return (u0b0011<4> << shamt);
+ } else { //SW
+ return u0b1111<4>;
+ }}
+}
+
+def maskLoad(data: int<32>, op: uint<3>, start: uint<2>): int<32> {
+ //start == offset in bytes, need to multiply by 8
+ uint<5> boff = start ++ u0<3>;
+ int<32> tmp = data >> boff;
+ uint<8> bdata = cast(tmp, uint<8>);
+ uint<16> hdata = cast(tmp, uint<16>);
+
+ if (op == u0<3>) { //LB
+ return cast(bdata, int<32>);
+ } else {
+ if (op == u1<3>) { //LH
+ return cast(hdata, int<32>);
+ } else {
+ if (op == u2<3>) { //LW
+ return data;
+ } else {
+ if (op == u4<3>) { //LBU
+ uint<32> zext = cast(bdata, uint<32>);
+ return cast(zext, int<32>);
+ } else {
+ if (op == u5<3>) { //LHU
+ uint<32> zext = cast(hdata, uint<32>);
+ return cast(zext, int<32>);
+ } else {
+ return 0<32>;
+ }}}}}
+}
+
+pipe multi_stg_div(num: uint<32>, denom: uint<32>, quot: uint<32>, acc: uint<32>, cnt: uint<5>, retQuot: bool)[]: uint<32> {
+ uint<32> tmp = acc{30:0} ++ num{31:31};
+ uint<32> na = (tmp >= denom) ? (tmp - denom) : (tmp);
+ uint<32> nq = (tmp >= denom) ? ((quot << 1){31:1} ++ u1<1>) : (quot << 1);
+ uint<32> nnum = num << 1;
+ bool done = (cnt == u31<5>);
+ if (done) {
+ output( (retQuot) ? nq : na );
+ } else {
+ call multi_stg_div(nnum, denom, nq, na, cnt + u1<5>, retQuot);
+ }
+}
+
+exn-pipe cpu(pc: int<16>)[rf: int<32>[5](CheckpointRF), imem: int<32>[16], dmem: int<32>[16], div: multi_stg_div, bht: BHT, csrf: int<32>[5]]: bool {
+ spec_check();
+ start(imem);
+ uint<16> pcaddr = cast(pc, uint<16>);
+ int<32> insn <- imem[pcaddr];
+ end(imem);
+ s <- speccall cpu(pc + 1<16>);
+ ---
+ //This OPCODE is J Self and thus we're using it to signal termination
+ bool done = insn == 0x0000006f<32>;
+ int<7> opcode = insn{6:0};
+ uint<5> rs1 = cast(insn{19:15}, uint<5>);
+ uint<5> rs2 = cast(insn{24:20}, uint<5>);
+ uint<5> rd = cast(insn{11:7}, uint<5>);
+ uint<7> funct7 = cast(insn{31:25}, uint<7>);
+ uint<3> funct3 = cast(insn{14:12}, uint<3>);
+ int<1> flipBit = insn{30:30};
+ int<32> immI = cast(insn{31:20}, int<32>);
+ int<32> immS = cast((insn{31:25} ++ insn{11:7}), int<32>);
+ int<13> immBTmp = insn{31:31} ++ insn{7:7} ++ insn{30:25} ++ insn{11:8} ++ 0<1>;
+ int<16> immB = cast(immBTmp, int<16>);
+ int<21> immJTmp = insn{31:31} ++ insn{19:12} ++ insn{20:20} ++ insn{30:21} ++ 0<1>;
+ int<32> immJ = cast(immJTmp, int<32>);
+ int<12> immJRTmp = insn{31:20};
+ int<16> immJR = cast(immJRTmp, int<16>);
+ int<32> immU = insn{31:12} ++ 0<12>;
+ uint<3> doAdd = u0<3>;
+ bool isOpImm = opcode == 0b0010011<7>;
+ bool flip = (!isOpImm) && (flipBit == 1<1>);
+ bool isLui = opcode == 0b0110111<7>;
+ bool isAui = opcode == 0b0010111<7>;
+ bool isOp = opcode == 0b0110011<7>;
+ bool isJal = opcode == 0b1101111<7>;
+ bool isJalr = opcode == 0b1100111<7>;
+ bool isBranch = opcode == 0b1100011<7>;
+ bool isStore = opcode == 0b0100011<7>;
+ bool isLoad = opcode == 0b0000011<7>;
+ bool isMDiv = (funct7 == u1<7>) && isOp;
+ bool isDiv = isMDiv && (funct3 >= u4<3>);
+ bool isMul = isMDiv && (funct3 < u4<3>);
+ bool isCsr = opcode == 0b1110011<7>;
+ bool needrs1 = !isJal;
+ bool needrs2 = isOp || isBranch || isStore || isJalr;
+ bool writerd = (rd != u0<5>) && (isOp || isOpImm || isLoad || isJal || isJalr || isLui || isAui);
+ spec_check();
+ bool notBranch = (!isBranch) && (!isJal) && (!isJalr);
+ if (!done) {
+ if (notBranch) {
+ s2 <- s;
+ } else {
+ if (isBranch) {
+ s2 <- update(s, bht.req(pc, immB, 1<16>));
+ } else {
+ s2 <- s;
+ invalidate(s);
+ }}} else { s2 <- s; invalidate(s); }
+ if (isCsr){
+ throw(u15<4>, insn);
+ }
+ start(rf);
+ if (!done && (notBranch || isBranch)) { checkpoint(rf); }
+ if (needrs1) {
+ reserve(rf[rs1], R);
+ }
+ if (needrs2) {
+ reserve(rf[rs2], R);
+ }
+ if (writerd) {
+ reserve(rf[rd], W);
+ }
+ end(rf);
+ ---
+ spec_check();
+ if (needrs1) {
+ block(rf[rs1]);
+ int<32> rf1 = rf[rs1];
+ release(rf[rs1]);
+ } else {
+ int<32> rf1 = 0<32>;
+ }
+ if (needrs2) {
+ block(rf[rs2]);
+ int<32> rf2 = rf[rs2];
+ release(rf[rs2]);
+ } else {
+ int<32> rf2 = 0<32>;
+ }
+ bool take = br(funct3, rf1, rf2);
+ if (isBranch) {
+ //divide by 4 b/c we count instructions not bytes
+ int<16> offpc = pc + (immB >> 2);
+ int<16> npc = (take) ? (offpc) : (pc + 1<16>);
+ } else {
+ if (isJal) {
+ //divide by 4 since it counts bytes instead of insns
+ int<32> npc32 = cast(pc, int<32>) + (immJ >> 2);
+ int<16> npc = npc32{15:0};
+ } else {
+ if (isJalr) {
+ int<16> npc = (rf1{15:0} + immJR) >> 2;
+ } else {
+ int<16> npc = pc + 1<16>;
+ }}}
+ int<32> alu_arg1 = (isAui) ? ((0<16> ++ pc) << 2) : rf1;
+ int<32> alu_arg2 = (isAui) ? immU : ((isStore) ? immS : ((isOpImm || isLoad) ? immI : rf2));
+ bool alu_flip = (isStore || isLoad || isAui) ? false : flip;
+ uint<3> alu_funct3 = (isStore || isLoad || isAui) ? doAdd : funct3;
+ int<32> alu_res = alu(alu_arg1, alu_arg2, alu_funct3, alu_flip);
+ int<16> tmppc = pc + 1<16>;
+ int<32> linkpc = 0<16> ++ (tmppc << 2);
+ int<32> mulres = mul(rf1, rf2, funct3);
+ if (writerd && (!isLoad) && (!isDiv)) {
+ block(rf[rd]);
+ int<32> rddata = (isLui) ? immU : ((isMul) ? mulres : ((isJal || isJalr) ? linkpc : alu_res));
+ rf[rd] <- rddata;
+ } else {
+ int<32> rddata = 0<32>;
+ }
+ ---
+ spec_barrier(); //delayed just to force writes to happen speculatively
+ if (!done) {
+ if (!notBranch) {
+ if (isBranch) {
+ verify(s2, npc) { bht.upd(pc, take) };
+ } else {
+ call cpu(npc);
+ }
+ } else {
+ verify(s, pc + 1<16>);
+ }
+ }
+
+ if (isDiv) {
+ int<32> sdividend = sign(rf1);
+ //For REM, ignore sign of divisor
+ int<32> sdivisor = (funct3 == u6<3>) ? 1<32> : sign(rf2);
+ bool isSignedDiv = ((funct3 == u4<3>) || (funct3 == u6<3>));
+ uint<32> dividend = (isSignedDiv) ? cast(mag(rf1), uint<32>) : cast(rf1, uint<32>);
+ uint<32> divisor = (isSignedDiv) ? cast(mag(rf2), uint<32>) : cast(rf2, uint<32>);
+ bool retQuot = funct3 <= u5<3>;
+ bool invertRes <- isSignedDiv && (sdividend != sdivisor);
+ uint<32> udivout <- call div(dividend, divisor, u0<32>, u0<32>, u0<5>, retQuot);
+ } else {
+ bool invertRes <- false;
+ uint<32> udivout <- u0<32>;
+ }
+ uint<32> tmpaddr = cast(alu_res, uint<32>);
+ uint<16> memaddr = (tmpaddr >> 2){15:0};
+ uint<2> boff = cast(alu_res{1:0}, uint<2>);
+ start(dmem);
+ split {
+ case: (isLoad) {
+ uint<16> raddr = memaddr;
+ int<32> wdata <- dmem[raddr];
+ }
+ case: (isStore) {
+ uint<16> waddr = memaddr;
+ //use bottom bits of data and place in correct offset
+ //shift by boff*8
+ uint<5> nboff = boff ++ u0<3>;
+ dmem[waddr, storeMask(boff, funct3)] <- (rf2 << nboff);
+ int<32> wdata <- 0<32>;
+ }
+ default: {
+ int<32> wdata <- 0<32>;
+ }
+ }
+ end(dmem);
+ ---
+ print("PC: %h", pc << 2);
+ print("INSN: %h", insn);
+ if (writerd) {
+ if (isLoad) {
+ block(rf[rd]);
+ int<32> insnout = maskLoad(wdata, funct3, boff);
+ rf[rd] <- insnout;
+ } else {
+ if (isDiv) {
+ block(rf[rd]);
+ int<32> divout = (invertRes) ? -(cast(udivout, int<32>)) : cast(udivout, int<32>);
+ int<32> insnout = divout;
+ rf[rd] <- insnout;
+ } else {
+ int<32> insnout = rddata;
+ }}
+ print("Writing %d to r%d", insnout, rd);
+ }
+ ---
+commit:
+ if (writerd) {
+ release(rf[rd]);
+ }
+ if (done) { output(true); }
+except(exncode: uint<4>, insn: int<32>):
+ print("exception at PC == %d! with exncode: %d", pc, exncode);
+ start(csrf);
+ start(rf);
+ uint<5> rs1_exn = cast(insn{19:15}, uint<5>);
+ uint<5> rd_exn = cast(insn{11:7}, uint<5>);
+ uint<12> csr_addr = cast(insn{31:20}, uint<12>);
+ uint<3> funct3_exn = cast(insn{14:12}, uint<3>);
+ bool isCsrrw = (funct3_exn == u1<3>);
+ bool isCsrrs = (funct3_exn == u2<3>);
+ bool isCsrrc = (funct3_exn == u3<3>);
+ if (exncode == u15<4>){ // Decode CSR instruction
+ reserve(rf[rs1_exn], R);
+ reserve(rf[rd_exn], W);
+ }
+ end(rf);
+ ---
+ uint<5> csr_idx = csr_map(csr_addr);
+ int<32> old_csr_val = csrf[csr_idx];
+ if (exncode == u15<4>){ // CSR instruction
+ block(rf[rs1_exn]);
+ int<32> rf1_val = rf[rs1_exn];
+ release(rf[rs1_exn]);
+ if (isCsrrw){
+ csrf[csr_idx] <- rf1_val;
+ } else { if (isCsrrs) {
+ int<32> masked_val = rf1_val | old_csr_val;
+ csrf[csr_idx] <- masked_val;
+ } else { if (isCsrrc) {
+ int<32> masked_val = (~rf1_val) & old_csr_val;
+ csrf[csr_idx] <- masked_val;
+ }}}
+ int<16> npc = pc + 1;
+ } else { int<16> npc = pc + 1; }
+ end(csrf);
+ ---
+ if (exncode == u15<4>){ // RF writeback
+ block(rf[rd_exn]);
+ rf[rd_exn] <- old_csr_val;
+ release(rf[rd_exn]);
+ }
+ ---
+ print("GOTO PC: %d", npc);
+ call cpu(npc);
+}
+
+circuit {
+ ti = memory(int<32>, 16);
+ td = memory(int<32>, 16);
+ rf = rflock CheckpointRF(int<32>, 5, 64);
+ csrf = regfile(int<32>, 5);
+ div = new multi_stg_div[];
+ b = new BHT<16>[](4);
+ c = new cpu[rf, ti, td, div, b, csrf];
+ call c(0<16>);
+}
\ No newline at end of file
diff --git a/src/test/tests/risc-pipe/risc-pipe-spec-exn-3.pdl b/src/test/tests/risc-pipe/risc-pipe-spec-exn-3.pdl
new file mode 100644
index 00000000..03a20ec8
--- /dev/null
+++ b/src/test/tests/risc-pipe/risc-pipe-spec-exn-3.pdl
@@ -0,0 +1,392 @@
+// risc-pipe-spec-write.pdl
+extern BHT {
+ method req(pc: int, skip: int, take: int): int;
+ method upd(pc: int, taken: bool): ();
+}
+
+def mul(arg1: int<32>, arg2: int<32>, op: uint<3>): int<32> {
+ uint<32> mag1 = cast(mag(arg1), uint<32>);
+ uint<32> mag2 = cast(mag(arg2), uint<32>);
+ //MULHU => positive sign always
+ int<32> s1 = (op == u3<3>) ? 1<32> : sign(arg1);
+ //MULHU/MULHSU => positive sign always
+ int<32> s2 = (op >= u2<3>) ? 1<32> : sign(arg2);
+ int<64> magRes = cast((mag1 * mag2), int<64>);
+ int<64> m = (s1 == s2) ? (magRes) : -(magRes);
+ if (op == u0<3>) { //MUL
+ return m{31:0};
+ } else {
+ return m{63:32};
+ }
+}
+
+def alu(arg1: int<32>, arg2: int<32>, op: uint<3>, flip: bool): int<32> {
+ uint<5> shamt = cast(arg2{4:0}, uint<5>);
+ if (op == u0<3>) { //000 == ADD , flip == sub
+ if (!flip) {
+ return arg1 + arg2;
+ } else {
+ return arg1 - arg2;
+ }
+ } else {
+ if (op == u1<3>) { //001 == SLL
+ return arg1 << shamt;
+ } else {
+ if (op == u2<3>) { //010 == SLT
+ return (arg1 < arg2) ? 1<32> : 0<32>;
+ } else {
+ if (op == u3<3>) { //011 == SLTU
+ uint<32> un1 = cast(arg1, uint<32>);
+ uint<32> un2 = cast(arg2, uint<32>);
+ return (un1 < un2) ? 1<32> : 0<32>;
+ } else {
+ if (op == u4<3>) { //100 == XOR
+ return arg1 ^ arg2;
+ } else {
+ if (op == u5<3>) { //101 == SRL / SRA
+ if (!flip) {
+ return cast((cast(arg1, uint<32>)) >> shamt, int<32>); //SRL
+ } else {
+ return arg1 >> shamt; //SRA
+ }
+ } else {
+ if (op == u6<3>) { //110 == OR
+ return arg1 | arg2;
+ } else { //111 == AND
+ return arg1 & arg2;
+ }}}}}}}
+
+}
+
+//true if taking branch
+def br(op:uint<3>, arg1:int<32>, arg2:int<32>): bool {
+ if (op == u0<3>) { //BEQ
+ return (arg1 == arg2);
+ } else {
+ if (op == u1<3>) { //BNE
+ return (arg1 != arg2);
+ } else {
+ if (op == u4<3>) { //BLT
+ return (arg1 < arg2);
+ } else {
+ if (op == u5<3>) { //BGE
+ return (arg1 >= arg2);
+ } else {
+ if (op == u6<3>) { //BLTU
+ uint<32> un1 = cast(arg1, uint<32>);
+ uint<32> un2 = cast(arg2, uint<32>);
+ return (un1 < un2);
+ } else {
+ if (op == u7<3>) { //BGEU
+ uint<32> un1 = cast(arg1, uint<32>);
+ uint<32> un2 = cast(arg2, uint<32>);
+ return(un1 >= un2);
+ } else {
+ return false;
+ }}}}}}
+}
+
+
+def storeMask(off: uint<2>, op: uint<3>): uint<4> {
+ if (op == u0<3>) { //SB
+ return (u0b0001<4> << off);
+ } else {
+ if (op == u1<3>) { //SH
+ uint<2> shamt = off{1:1} ++ u0<1>;
+ return (u0b0011<4> << shamt);
+ } else { //SW
+ return u0b1111<4>;
+ }}
+}
+
+def maskLoad(data: int<32>, op: uint<3>, start: uint<2>): int<32> {
+ //start == offset in bytes, need to multiply by 8
+ uint<5> boff = start ++ u0<3>;
+ int<32> tmp = data >> boff;
+ uint<8> bdata = cast(tmp, uint<8>);
+ uint<16> hdata = cast(tmp, uint<16>);
+
+ if (op == u0<3>) { //LB
+ return cast(bdata, int<32>);
+ } else {
+ if (op == u1<3>) { //LH
+ return cast(hdata, int<32>);
+ } else {
+ if (op == u2<3>) { //LW
+ return data;
+ } else {
+ if (op == u4<3>) { //LBU
+ uint<32> zext = cast(bdata, uint<32>);
+ return cast(zext, int<32>);
+ } else {
+ if (op == u5<3>) { //LHU
+ uint<32> zext = cast(hdata, uint<32>);
+ return cast(zext, int<32>);
+ } else {
+ return 0<32>;
+ }}}}}
+}
+
+pipe multi_stg_div(num: uint<32>, denom: uint<32>, quot: uint<32>, acc: uint<32>, cnt: uint<5>, retQuot: bool)[]: uint<32> {
+ uint<32> tmp = acc{30:0} ++ num{31:31};
+ uint<32> na = (tmp >= denom) ? (tmp - denom) : (tmp);
+ uint<32> nq = (tmp >= denom) ? ((quot << 1){31:1} ++ u1<1>) : (quot << 1);
+ uint<32> nnum = num << 1;
+ bool done = (cnt == u31<5>);
+ if (done) {
+ output( (retQuot) ? nq : na );
+ } else {
+ call multi_stg_div(nnum, denom, nq, na, cnt + u1<5>, retQuot);
+ }
+}
+
+
+exn-pipe cpu(pc: int<16>)[rf: int<32>[5](CheckpointRF), imem: int<32>[16], dmem: int<32>[16], div: multi_stg_div, bht: BHT, csrf: int<32>[3]]: bool {
+ spec_check();
+ start(imem);
+ uint<16> pcaddr = cast(pc, uint<16>);
+ int<32> insn <- imem[pcaddr];
+ end(imem);
+ s <- speccall cpu(pc + 1<16>);
+ ---
+ //This OPCODE is J Self and thus we're using it to signal termination
+ bool done = insn == 0x0000006f<32>;
+ int<7> opcode = insn{6:0};
+ uint<5> rs1 = cast(insn{19:15}, uint<5>);
+ uint<5> rs2 = cast(insn{24:20}, uint<5>);
+ uint<5> rd = cast(insn{11:7}, uint<5>);
+ uint<7> funct7 = cast(insn{31:25}, uint<7>);
+ uint<3> funct3 = cast(insn{14:12}, uint<3>);
+ int<1> flipBit = insn{30:30};
+ int<32> immI = cast(insn{31:20}, int<32>);
+ int<32> immS = cast((insn{31:25} ++ insn{11:7}), int<32>);
+ int<13> immBTmp = insn{31:31} ++ insn{7:7} ++ insn{30:25} ++ insn{11:8} ++ 0<1>;
+ int<16> immB = cast(immBTmp, int<16>);
+ int<21> immJTmp = insn{31:31} ++ insn{19:12} ++ insn{20:20} ++ insn{30:21} ++ 0<1>;
+ int<32> immJ = cast(immJTmp, int<32>);
+ int<12> immJRTmp = insn{31:20};
+ int<16> immJR = cast(immJRTmp, int<16>);
+ int<32> immU = insn{31:12} ++ 0<12>;
+ uint<3> doAdd = u0<3>;
+ bool isOpImm = opcode == 0b0010011<7>;
+ bool flip = (!isOpImm) && (flipBit == 1<1>);
+ bool isLui = opcode == 0b0110111<7>;
+ bool isAui = opcode == 0b0010111<7>;
+ bool isOp = opcode == 0b0110011<7>;
+ bool isJal = opcode == 0b1101111<7>;
+ bool isJalr = opcode == 0b1100111<7>;
+ bool isBranch = opcode == 0b1100011<7>;
+ bool isStore = opcode == 0b0100011<7>;
+ bool isLoad = opcode == 0b0000011<7>;
+ bool isMDiv = (funct7 == u1<7>) && isOp;
+ bool isDiv = isMDiv && (funct3 >= u4<3>);
+ bool isMul = isMDiv && (funct3 < u4<3>);
+ bool isSystem = opcode == 0b1110011<7>;
+ bool isEcall = isSystem && (immI == 0<32>);
+ bool isMret = isSystem && (funct7 == u24<7>) && (rs2 == u2<5>);
+ bool needrs1 = !isJal;
+ bool needrs2 = isOp || isBranch || isStore || isJalr;
+ bool writerd = (rd != u0<5>) && (isOp || isOpImm || isLoad || isJal || isJalr || isLui || isAui);
+ spec_check();
+ bool notBranch = (!isBranch) && (!isJal) && (!isJalr);
+ if (!done) {
+ if (notBranch) {
+ s2 <- s;
+ } else {
+ if (isBranch) {
+ s2 <- update(s, bht.req(pc, immB, 1<16>));
+ } else {
+ s2 <- s;
+ invalidate(s);
+ }}} else { s2 <- s; invalidate(s); }
+ if (isEcall){
+ throw(0, u8<4>);
+ }
+ if (isMret){
+ throw(0, u3<4>);
+ }
+ start(rf);
+ if (!done && (notBranch || isBranch)) { checkpoint(rf); }
+ if (needrs1) {
+ reserve(rf[rs1], R);
+ }
+ if (needrs2) {
+ reserve(rf[rs2], R);
+ }
+ if (writerd) {
+ reserve(rf[rd], W);
+ }
+ end(rf);
+ ---
+ spec_check();
+ if (needrs1) {
+ block(rf[rs1]);
+ int<32> rf1 = rf[rs1];
+ release(rf[rs1]);
+ } else {
+ int<32> rf1 = 0<32>;
+ }
+ if (needrs2) {
+ block(rf[rs2]);
+ int<32> rf2 = rf[rs2];
+ release(rf[rs2]);
+ } else {
+ int<32> rf2 = 0<32>;
+ }
+ bool take = br(funct3, rf1, rf2);
+ if (isBranch) {
+ //divide by 4 b/c we count instructions not bytes
+ int<16> offpc = pc + (immB >> 2);
+ int<16> npc = (take) ? (offpc) : (pc + 1<16>);
+ } else {
+ if (isJal) {
+ //divide by 4 since it counts bytes instead of insns
+ int<32> npc32 = cast(pc, int<32>) + (immJ >> 2);
+ int<16> npc = npc32{15:0};
+ } else {
+ if (isJalr) {
+ int<16> npc = (rf1{15:0} + immJR) >> 2;
+ } else {
+ int<16> npc = pc + 1<16>;
+ }}}
+ int<32> alu_arg1 = (isAui) ? ((0<16> ++ pc) << 2) : rf1;
+ int<32> alu_arg2 = (isAui) ? immU : ((isStore) ? immS : ((isOpImm || isLoad) ? immI : rf2));
+ bool alu_flip = (isStore || isLoad || isAui) ? false : flip;
+ uint<3> alu_funct3 = (isStore || isLoad || isAui) ? doAdd : funct3;
+ int<32> alu_res = alu(alu_arg1, alu_arg2, alu_funct3, alu_flip);
+ int<16> tmppc = pc + 1<16>;
+ int<32> linkpc = 0<16> ++ (tmppc << 2);
+ int<32> mulres = mul(rf1, rf2, funct3);
+ if (writerd && (!isLoad) && (!isDiv)) {
+ block(rf[rd]);
+ int<32> rddata = (isLui) ? immU : ((isMul) ? mulres : ((isJal || isJalr) ? linkpc : alu_res));
+ rf[rd] <- rddata;
+ } else {
+ int<32> rddata = 0<32>;
+ }
+ ---
+ spec_barrier(); //delayed just to force writes to happen speculatively
+ if (!done) {
+ if (!notBranch) {
+ if (isBranch) {
+ verify(s2, npc) { bht.upd(pc, take) };
+ } else {
+ call cpu(npc);
+ }
+ } else {
+ verify(s, pc + 1<16>);
+ }
+ }
+
+ if (isDiv) {
+ int<32> sdividend = sign(rf1);
+ //For REM, ignore sign of divisor
+ int<32> sdivisor = (funct3 == u6<3>) ? 1<32> : sign(rf2);
+ bool isSignedDiv = ((funct3 == u4<3>) || (funct3 == u6<3>));
+ uint<32> dividend = (isSignedDiv) ? cast(mag(rf1), uint<32>) : cast(rf1, uint<32>);
+ uint<32> divisor = (isSignedDiv) ? cast(mag(rf2), uint<32>) : cast(rf2, uint<32>);
+ bool retQuot = funct3 <= u5<3>;
+ bool invertRes <- isSignedDiv && (sdividend != sdivisor);
+ uint<32> udivout <- call div(dividend, divisor, u0<32>, u0<32>, u0<5>, retQuot);
+ } else {
+ bool invertRes <- false;
+ uint<32> udivout <- u0<32>;
+ }
+ uint<32> tmpaddr = cast(alu_res, uint<32>);
+ uint<16> memaddr = (tmpaddr >> 2){15:0};
+ uint<2> boff = cast(alu_res{1:0}, uint<2>);
+ start(dmem);
+ split {
+ case: (isLoad) {
+ uint<16> raddr = memaddr;
+ int<32> wdata <- dmem[raddr];
+ }
+ case: (isStore) {
+ uint<16> waddr = memaddr;
+ //use bottom bits of data and place in correct offset
+ //shift by boff*8
+ uint<5> nboff = boff ++ u0<3>;
+ dmem[waddr, storeMask(boff, funct3)] <- (rf2 << nboff);
+ int<32> wdata <- 0<32>;
+ }
+ default: {
+ int<32> wdata <- 0<32>;
+ }
+ }
+ end(dmem);
+ ---
+ print("PC: %h", pc << 2);
+ print("INSN: %h", insn);
+ if (writerd) {
+ if (isLoad) {
+ block(rf[rd]);
+ int<32> insnout = maskLoad(wdata, funct3, boff);
+ rf[rd] <- insnout;
+ } else {
+ if (isDiv) {
+ block(rf[rd]);
+ int<32> divout = (invertRes) ? -(cast(udivout, int<32>)) : cast(udivout, int<32>);
+ int<32> insnout = divout;
+ rf[rd] <- insnout;
+ } else {
+ int<32> insnout = rddata;
+ }}
+ print("Writing %d to r%d", insnout, rd);
+ }
+ int<32> enable = csrf[4];
+ ---
+ int<32> pending = csrf[3];
+ int<32> masked_pending = pending | enable;
+ bool isExtInt = (masked_pending{11:11} == 1<1>);
+ if (isExtInt) {
+ throw(1, u11<4>);
+ }
+commit:
+ if (writerd) {
+ release(rf[rd]);
+ }
+ if (done) { output(true); }
+except(is_interrupt: uint<1>, exncode: uint<4>): // mepc = csrf[0], mtvec = csrf[1], mcause = csrf[2]
+ print("exception at PC == %d! with exncode: %d", pc, exncode);
+ start(csrf); // mip = csrf[3], mie = csrf[4], mstatus = csrf[5]
+ bool isStartContext = (is_interrupt == u1<1>) || exncode == u8<4>;
+ bool isRestoreContext = (exncode == u3<4>);
+ if (isStartContext) {
+ csrf[0] <- cast(pc, int<32>); // write to mepc
+ int<32> csrret = csrf[1]; // read from mtvec
+ int<16> npc = csrret{15:0};
+ } else { if (isRestoreContext) {
+ int<32> csrret = csrf[0]; // read from mepc
+ int<16> npc = csrret{15:0} + 1;
+ } else { int<16> npc = pc + 1; }}
+ ---
+ int<32> oldmcause = csrf[2];
+ bool wasHandlingInterrupt = oldmcause{31:31} == 1;
+ int<32> newmcause = cast(is_interrupt, int<1>) ++ cast(exncode, int<31>);
+ if (isStartContext) {
+ csrf[2] <- cast(newmcause, int<32>); // write to mcause
+ } else { if (isRestoreContext) { csrf[4] <- 1<32>; }} // enable mie
+ ---
+ if (isStartContext && (is_interrupt == u1<1>)) {
+ csrf[4] <- 0<32>; // disable mie
+ } else { if (isRestoreContext && wasHandlingInterrupt) {
+ int<32> oldmip = csrf[3];
+ int<32> newmip = oldmip{31:12} ++ 0<1> ++ oldmip{10:0};
+ csrf[3] <- newmip; // unset mip
+ }}
+ end(csrf);
+ ---
+ print("GOTO PC: %d", npc);
+ call cpu(npc);
+}
+
+circuit {
+ ti = memory(int<32>, 16);
+ td = memory(int<32>, 16);
+ rf = rflock CheckpointRF(int<32>, 5, 64);
+ csrf = regfile(int<32>, 3);
+ div = new multi_stg_div[];
+ b = new BHT<16>[](4);
+ c = new cpu[rf, ti, td, div, b, csrf];
+ call c(0<16>);
+}
\ No newline at end of file
diff --git a/src/test/tests/risc-pipe/risc-pipe-spec-exn-4.pdl b/src/test/tests/risc-pipe/risc-pipe-spec-exn-4.pdl
new file mode 100644
index 00000000..5be8d3f1
--- /dev/null
+++ b/src/test/tests/risc-pipe/risc-pipe-spec-exn-4.pdl
@@ -0,0 +1,359 @@
+// risc-pipe-spec-write.pdl
+extern BHT {
+ method req(pc: int, skip: int, take: int): int;
+ method upd(pc: int, taken: bool): ();
+}
+
+def mul(arg1: int<32>, arg2: int<32>, op: uint<3>): int<32> {
+ uint<32> mag1 = cast(mag(arg1), uint<32>);
+ uint<32> mag2 = cast(mag(arg2), uint<32>);
+ //MULHU => positive sign always
+ int<32> s1 = (op == u3<3>) ? 1<32> : sign(arg1);
+ //MULHU/MULHSU => positive sign always
+ int<32> s2 = (op >= u2<3>) ? 1<32> : sign(arg2);
+ int<64> magRes = cast((mag1 * mag2), int<64>);
+ int<64> m = (s1 == s2) ? (magRes) : -(magRes);
+ if (op == u0<3>) { //MUL
+ return m{31:0};
+ } else {
+ return m{63:32};
+ }
+}
+
+def alu(arg1: int<32>, arg2: int<32>, op: uint<3>, flip: bool): int<32> {
+ uint<5> shamt = cast(arg2{4:0}, uint<5>);
+ if (op == u0<3>) { //000 == ADD , flip == sub
+ if (!flip) {
+ return arg1 + arg2;
+ } else {
+ return arg1 - arg2;
+ }
+ } else {
+ if (op == u1<3>) { //001 == SLL
+ return arg1 << shamt;
+ } else {
+ if (op == u2<3>) { //010 == SLT
+ return (arg1 < arg2) ? 1<32> : 0<32>;
+ } else {
+ if (op == u3<3>) { //011 == SLTU
+ uint<32> un1 = cast(arg1, uint<32>);
+ uint<32> un2 = cast(arg2, uint<32>);
+ return (un1 < un2) ? 1<32> : 0<32>;
+ } else {
+ if (op == u4<3>) { //100 == XOR
+ return arg1 ^ arg2;
+ } else {
+ if (op == u5<3>) { //101 == SRL / SRA
+ if (!flip) {
+ return cast((cast(arg1, uint<32>)) >> shamt, int<32>); //SRL
+ } else {
+ return arg1 >> shamt; //SRA
+ }
+ } else {
+ if (op == u6<3>) { //110 == OR
+ return arg1 | arg2;
+ } else { //111 == AND
+ return arg1 & arg2;
+ }}}}}}}
+
+}
+
+//true if taking branch
+def br(op:uint<3>, arg1:int<32>, arg2:int<32>): bool {
+ if (op == u0<3>) { //BEQ
+ return (arg1 == arg2);
+ } else {
+ if (op == u1<3>) { //BNE
+ return (arg1 != arg2);
+ } else {
+ if (op == u4<3>) { //BLT
+ return (arg1 < arg2);
+ } else {
+ if (op == u5<3>) { //BGE
+ return (arg1 >= arg2);
+ } else {
+ if (op == u6<3>) { //BLTU
+ uint<32> un1 = cast(arg1, uint<32>);
+ uint<32> un2 = cast(arg2, uint<32>);
+ return (un1 < un2);
+ } else {
+ if (op == u7<3>) { //BGEU
+ uint<32> un1 = cast(arg1, uint<32>);
+ uint<32> un2 = cast(arg2, uint<32>);
+ return(un1 >= un2);
+ } else {
+ return false;
+ }}}}}}
+}
+
+
+def storeMask(off: uint<2>, op: uint<3>): uint<4> {
+ if (op == u0<3>) { //SB
+ return (u0b0001<4> << off);
+ } else {
+ if (op == u1<3>) { //SH
+ uint<2> shamt = off{1:1} ++ u0<1>;
+ return (u0b0011<4> << shamt);
+ } else { //SW
+ return u0b1111<4>;
+ }}
+}
+
+def maskLoad(data: int<32>, op: uint<3>, start: uint<2>): int<32> {
+ //start == offset in bytes, need to multiply by 8
+ uint<5> boff = start ++ u0<3>;
+ int<32> tmp = data >> boff;
+ uint<8> bdata = cast(tmp, uint<8>);
+ uint<16> hdata = cast(tmp, uint<16>);
+
+ if (op == u0<3>) { //LB
+ return cast(bdata, int<32>);
+ } else {
+ if (op == u1<3>) { //LH
+ return cast(hdata, int<32>);
+ } else {
+ if (op == u2<3>) { //LW
+ return data;
+ } else {
+ if (op == u4<3>) { //LBU
+ uint<32> zext = cast(bdata, uint<32>);
+ return cast(zext, int<32>);
+ } else {
+ if (op == u5<3>) { //LHU
+ uint<32> zext = cast(hdata, uint<32>);
+ return cast(zext, int<32>);
+ } else {
+ return 0<32>;
+ }}}}}
+}
+
+pipe multi_stg_div(num: uint<32>, denom: uint<32>, quot: uint<32>, acc: uint<32>, cnt: uint<5>, retQuot: bool)[]: uint<32> {
+ uint<32> tmp = acc{30:0} ++ num{31:31};
+ uint<32> na = (tmp >= denom) ? (tmp - denom) : (tmp);
+ uint<32> nq = (tmp >= denom) ? ((quot << 1){31:1} ++ u1<1>) : (quot << 1);
+ uint<32> nnum = num << 1;
+ bool done = (cnt == u31<5>);
+ if (done) {
+ output( (retQuot) ? nq : na );
+ } else {
+ call multi_stg_div(nnum, denom, nq, na, cnt + u1<5>, retQuot);
+ }
+}
+
+exn-pipe cpu(pc: int<16>)[rf: int<32>[5](CheckpointRF), imem: int<32>[16], dmem: int<32>[16], div: multi_stg_div, bht: BHT, csrf: int<32>[1]]: bool {
+ spec_check();
+ start(imem);
+ uint<16> pcaddr = cast(pc, uint<16>);
+ int<32> insn <- imem[pcaddr];
+ end(imem);
+ s <- speccall cpu(pc + 1<16>);
+ ---
+ //This OPCODE is J Self and thus we're using it to signal termination
+ bool done = insn == 0x0000006f<32>;
+ int<7> opcode = insn{6:0};
+ uint<5> rs1 = cast(insn{19:15}, uint<5>);
+ uint<5> rs2 = cast(insn{24:20}, uint<5>);
+ uint<5> rd = cast(insn{11:7}, uint<5>);
+ uint<7> funct7 = cast(insn{31:25}, uint<7>);
+ uint<3> funct3 = cast(insn{14:12}, uint<3>);
+ int<1> flipBit = insn{30:30};
+ int<32> immI = cast(insn{31:20}, int<32>);
+ int<32> immS = cast((insn{31:25} ++ insn{11:7}), int<32>);
+ int<13> immBTmp = insn{31:31} ++ insn{7:7} ++ insn{30:25} ++ insn{11:8} ++ 0<1>;
+ int<16> immB = cast(immBTmp, int<16>);
+ int<21> immJTmp = insn{31:31} ++ insn{19:12} ++ insn{20:20} ++ insn{30:21} ++ 0<1>;
+ int<32> immJ = cast(immJTmp, int<32>);
+ int<12> immJRTmp = insn{31:20};
+ int<16> immJR = cast(immJRTmp, int<16>);
+ int<32> immU = insn{31:12} ++ 0<12>;
+ uint<3> doAdd = u0<3>;
+ bool isOpImm = opcode == 0b0010011<7>;
+ bool flip = (!isOpImm) && (flipBit == 1<1>);
+ bool isLui = opcode == 0b0110111<7>;
+ bool isAui = opcode == 0b0010111<7>;
+ bool isOp = opcode == 0b0110011<7>;
+ bool isJal = opcode == 0b1101111<7>;
+ bool isJalr = opcode == 0b1100111<7>;
+ bool isBranch = opcode == 0b1100011<7>;
+ bool isStore = opcode == 0b0100011<7>;
+ bool isLoad = opcode == 0b0000011<7>;
+ bool isMDiv = (funct7 == u1<7>) && isOp;
+ bool isDiv = isMDiv && (funct3 >= u4<3>);
+ bool isMul = isMDiv && (funct3 < u4<3>);
+ bool needrs1 = !isJal;
+ bool needrs2 = isOp || isBranch || isStore || isJalr;
+ bool writerd = (rd != u0<5>) && (isOp || isOpImm || isLoad || isJal || isJalr || isLui || isAui);
+ bool isExcluded = isJalr || isJal || isBranch;
+ bool isInvalid = (opcode <= 0<7>);
+ if (isInvalid && !isExcluded){
+ throw(u0<4>); // Fatal and terminate exec if illegal instr
+ }
+ spec_check();
+ bool notBranch = (!isBranch) && (!isJal) && (!isJalr);
+ if (!done) {
+ if (notBranch) {
+ s2 <- s;
+ } else {
+ if (isBranch) {
+ s2 <- update(s, bht.req(pc, immB, 1<16>));
+ } else {
+ s2 <- s;
+ invalidate(s);
+ }}} else { s2 <- s; invalidate(s); }
+ start(rf);
+ if (!done && (notBranch || isBranch)) { checkpoint(rf); }
+ if (needrs1) {
+ reserve(rf[rs1], R);
+ }
+ if (needrs2) {
+ reserve(rf[rs2], R);
+ }
+ if (writerd) {
+ reserve(rf[rd], W);
+ }
+ end(rf);
+ ---
+ spec_check();
+ if (needrs1) {
+ block(rf[rs1]);
+ int<32> rf1 = rf[rs1];
+ release(rf[rs1]);
+ } else {
+ int<32> rf1 = 0<32>;
+ }
+ if (needrs2) {
+ block(rf[rs2]);
+ int<32> rf2 = rf[rs2];
+ release(rf[rs2]);
+ } else {
+ int<32> rf2 = 0<32>;
+ }
+ bool take = br(funct3, rf1, rf2);
+ if (isBranch) {
+ //divide by 4 b/c we count instructions not bytes
+ int<16> offpc = pc + (immB >> 2);
+ int<16> npc = (take) ? (offpc) : (pc + 1<16>);
+ } else {
+ if (isJal) {
+ //divide by 4 since it counts bytes instead of insns
+ int<32> npc32 = cast(pc, int<32>) + (immJ >> 2);
+ int<16> npc = npc32{15:0};
+ } else {
+ if (isJalr) {
+ int<16> npc = (rf1{15:0} + immJR) >> 2;
+ } else {
+ int<16> npc = pc + 1<16>;
+ }}}
+ int<32> alu_arg1 = (isAui) ? ((0<16> ++ pc) << 2) : rf1;
+ int<32> alu_arg2 = (isAui) ? immU : ((isStore) ? immS : ((isOpImm || isLoad) ? immI : rf2));
+ bool alu_flip = (isStore || isLoad || isAui) ? false : flip;
+ uint<3> alu_funct3 = (isStore || isLoad || isAui) ? doAdd : funct3;
+ int<32> alu_res = alu(alu_arg1, alu_arg2, alu_funct3, alu_flip);
+ int<16> tmppc = pc + 1<16>;
+ int<32> linkpc = 0<16> ++ (tmppc << 2);
+ int<32> mulres = mul(rf1, rf2, funct3);
+ if (writerd && (!isLoad) && (!isDiv)) {
+ block(rf[rd]);
+ int<32> rddata = (isLui) ? immU : ((isMul) ? mulres : ((isJal || isJalr) ? linkpc : alu_res));
+ rf[rd] <- rddata;
+ } else {
+ int<32> rddata = 0<32>;
+ }
+ ---
+ spec_barrier(); //delayed just to force writes to happen speculatively
+ if (!done) {
+ if (!notBranch) {
+ if (isBranch) {
+ verify(s2, npc) { bht.upd(pc, take) };
+ } else {
+ call cpu(npc);
+ }
+ } else {
+ verify(s, pc + 1<16>);
+ }
+ }
+
+ if (isDiv) {
+ int<32> sdividend = sign(rf1);
+ //For REM, ignore sign of divisor
+ int<32> sdivisor = (funct3 == u6<3>) ? 1<32> : sign(rf2);
+ bool isSignedDiv = ((funct3 == u4<3>) || (funct3 == u6<3>));
+ uint<32> dividend = (isSignedDiv) ? cast(mag(rf1), uint<32>) : cast(rf1, uint<32>);
+ uint<32> divisor = (isSignedDiv) ? cast(mag(rf2), uint<32>) : cast(rf2, uint<32>);
+ bool retQuot = funct3 <= u5<3>;
+ bool invertRes <- isSignedDiv && (sdividend != sdivisor);
+ uint<32> udivout <- call div(dividend, divisor, u0<32>, u0<32>, u0<5>, retQuot);
+ } else {
+ bool invertRes <- false;
+ uint<32> udivout <- u0<32>;
+ }
+ uint<32> tmpaddr = cast(alu_res, uint<32>);
+ uint<16> memaddr = (tmpaddr >> 2){15:0};
+ uint<2> boff = cast(alu_res{1:0}, uint<2>);
+ start(dmem);
+ split {
+ case: (isLoad) {
+ uint<16> raddr = memaddr;
+ int<32> wdata <- dmem[raddr];
+ }
+ case: (isStore) {
+ uint<16> waddr = memaddr;
+ //use bottom bits of data and place in correct offset
+ //shift by boff*8
+ uint<5> nboff = boff ++ u0<3>;
+ dmem[waddr, storeMask(boff, funct3)] <- (rf2 << nboff);
+ int<32> wdata <- 0<32>;
+ }
+ default: {
+ int<32> wdata <- 0<32>;
+ }
+ }
+ end(dmem);
+ ---
+ print("PC: %h", pc << 2);
+ print("INSN: %h", insn);
+ if (writerd) {
+ if (isLoad) {
+ block(rf[rd]);
+ int<32> insnout = maskLoad(wdata, funct3, boff);
+ rf[rd] <- insnout;
+ } else {
+ if (isDiv) {
+ block(rf[rd]);
+ int<32> divout = (invertRes) ? -(cast(udivout, int<32>)) : cast(udivout, int<32>);
+ int<32> insnout = divout;
+ rf[rd] <- insnout;
+ } else {
+ int<32> insnout = rddata;
+ }}
+ print("Writing %d to r%d", insnout, rd);
+ }
+ ---
+commit:
+ if (writerd) {
+ release(rf[rd]);
+ }
+ if (done) { output(true); }
+except(exncode: uint<4>):
+ print("exception at PC == %d! with exncode: %d", pc, exncode);
+ start(csrf);
+ csrf[0] <- cast(exncode, int<32>); // Store Exncode
+ ---
+ csrf[1] <- cast(pc, int<32>); // Store ErrPC
+ end(csrf);
+ ---
+ if (exncode == u0<4>){
+ output(false); // Terminate execution
+ } else { call cpu(pc + 1<16>); }
+}
+
+circuit {
+ ti = memory(int<32>, 16);
+ td = memory(int<32>, 16);
+ rf = rflock CheckpointRF(int<32>, 5, 64);
+ csrf = regfile(int<32>, 1);
+ div = new multi_stg_div[];
+ b = new BHT<16>[](4);
+ c = new cpu[rf, ti, td, div, b, csrf];
+ call c(0<16>);
+}
\ No newline at end of file
diff --git a/src/test/tests/risc-pipe/risc-pipe-spec-exn-5.pdl b/src/test/tests/risc-pipe/risc-pipe-spec-exn-5.pdl
new file mode 100644
index 00000000..17d6675a
--- /dev/null
+++ b/src/test/tests/risc-pipe/risc-pipe-spec-exn-5.pdl
@@ -0,0 +1,362 @@
+// risc-pipe-spec-write.pdl
+extern BHT {
+ method req(pc: int, skip: int, take: int): int;
+ method upd(pc: int, taken: bool): ();
+}
+
+def mul(arg1: int<32>, arg2: int<32>, op: uint<3>): int<32> {
+ uint<32> mag1 = cast(mag(arg1), uint<32>);
+ uint<32> mag2 = cast(mag(arg2), uint<32>);
+ //MULHU => positive sign always
+ int<32> s1 = (op == u3<3>) ? 1<32> : sign(arg1);
+ //MULHU/MULHSU => positive sign always
+ int<32> s2 = (op >= u2<3>) ? 1<32> : sign(arg2);
+ int<64> magRes = cast((mag1 * mag2), int<64>);
+ int<64> m = (s1 == s2) ? (magRes) : -(magRes);
+ if (op == u0<3>) { //MUL
+ return m{31:0};
+ } else {
+ return m{63:32};
+ }
+}
+
+def alu(arg1: int<32>, arg2: int<32>, op: uint<3>, flip: bool): int<32> {
+ uint<5> shamt = cast(arg2{4:0}, uint<5>);
+ if (op == u0<3>) { //000 == ADD , flip == sub
+ if (!flip) {
+ return arg1 + arg2;
+ } else {
+ return arg1 - arg2;
+ }
+ } else {
+ if (op == u1<3>) { //001 == SLL
+ return arg1 << shamt;
+ } else {
+ if (op == u2<3>) { //010 == SLT
+ return (arg1 < arg2) ? 1<32> : 0<32>;
+ } else {
+ if (op == u3<3>) { //011 == SLTU
+ uint<32> un1 = cast(arg1, uint<32>);
+ uint<32> un2 = cast(arg2, uint<32>);
+ return (un1 < un2) ? 1<32> : 0<32>;
+ } else {
+ if (op == u4<3>) { //100 == XOR
+ return arg1 ^ arg2;
+ } else {
+ if (op == u5<3>) { //101 == SRL / SRA
+ if (!flip) {
+ return cast((cast(arg1, uint<32>)) >> shamt, int<32>); //SRL
+ } else {
+ return arg1 >> shamt; //SRA
+ }
+ } else {
+ if (op == u6<3>) { //110 == OR
+ return arg1 | arg2;
+ } else { //111 == AND
+ return arg1 & arg2;
+ }}}}}}}
+
+}
+
+//true if taking branch
+def br(op:uint<3>, arg1:int<32>, arg2:int<32>): bool {
+ if (op == u0<3>) { //BEQ
+ return (arg1 == arg2);
+ } else {
+ if (op == u1<3>) { //BNE
+ return (arg1 != arg2);
+ } else {
+ if (op == u4<3>) { //BLT
+ return (arg1 < arg2);
+ } else {
+ if (op == u5<3>) { //BGE
+ return (arg1 >= arg2);
+ } else {
+ if (op == u6<3>) { //BLTU
+ uint<32> un1 = cast(arg1, uint<32>);
+ uint<32> un2 = cast(arg2, uint<32>);
+ return (un1 < un2);
+ } else {
+ if (op == u7<3>) { //BGEU
+ uint<32> un1 = cast(arg1, uint<32>);
+ uint<32> un2 = cast(arg2, uint<32>);
+ return(un1 >= un2);
+ } else {
+ return false;
+ }}}}}}
+}
+
+
+def storeMask(off: uint<2>, op: uint<3>): uint<4> {
+ if (op == u0<3>) { //SB
+ return (u0b0001<4> << off);
+ } else {
+ if (op == u1<3>) { //SH
+ uint<2> shamt = off{1:1} ++ u0<1>;
+ return (u0b0011<4> << shamt);
+ } else { //SW
+ return u0b1111<4>;
+ }}
+}
+
+def maskLoad(data: int<32>, op: uint<3>, start: uint<2>): int<32> {
+ //start == offset in bytes, need to multiply by 8
+ uint<5> boff = start ++ u0<3>;
+ int<32> tmp = data >> boff;
+ uint<8> bdata = cast(tmp, uint<8>);
+ uint<16> hdata = cast(tmp, uint<16>);
+
+ if (op == u0<3>) { //LB
+ return cast(bdata, int<32>);
+ } else {
+ if (op == u1<3>) { //LH
+ return cast(hdata, int<32>);
+ } else {
+ if (op == u2<3>) { //LW
+ return data;
+ } else {
+ if (op == u4<3>) { //LBU
+ uint<32> zext = cast(bdata, uint<32>);
+ return cast(zext, int<32>);
+ } else {
+ if (op == u5<3>) { //LHU
+ uint<32> zext = cast(hdata, uint<32>);
+ return cast(zext, int<32>);
+ } else {
+ return 0<32>;
+ }}}}}
+}
+
+pipe multi_stg_div(num: uint<32>, denom: uint<32>, quot: uint<32>, acc: uint<32>, cnt: uint<5>, retQuot: bool)[]: uint<32> {
+ uint<32> tmp = acc{30:0} ++ num{31:31};
+ uint<32> na = (tmp >= denom) ? (tmp - denom) : (tmp);
+ uint<32> nq = (tmp >= denom) ? ((quot << 1){31:1} ++ u1<1>) : (quot << 1);
+ uint<32> nnum = num << 1;
+ bool done = (cnt == u31<5>);
+ if (done) {
+ output( (retQuot) ? nq : na );
+ } else {
+ call multi_stg_div(nnum, denom, nq, na, cnt + u1<5>, retQuot);
+ }
+}
+
+exn-pipe cpu(pc: int<16>)[rf: int<32>[5](CheckpointRF), imem: int<32>[16], dmem: int<32>[16], div: multi_stg_div, bht: BHT, csrf: int<32>[1]]: bool {
+ spec_check();
+ start(imem);
+ uint<16> pcaddr = cast(pc, uint<16>);
+ int<32> insn <- imem[pcaddr];
+ end(imem);
+ s <- speccall cpu(pc + 1<16>);
+ ---
+ //This OPCODE is J Self and thus we're using it to signal termination
+ bool done = insn == 0x0000006f<32>;
+ int<7> opcode = insn{6:0};
+ uint<5> rs1 = cast(insn{19:15}, uint<5>);
+ uint<5> rs2 = cast(insn{24:20}, uint<5>);
+ uint<5> rd = cast(insn{11:7}, uint<5>);
+ uint<7> funct7 = cast(insn{31:25}, uint<7>);
+ uint<3> funct3 = cast(insn{14:12}, uint<3>);
+ int<1> flipBit = insn{30:30};
+ int<32> immI = cast(insn{31:20}, int<32>);
+ int<32> immS = cast((insn{31:25} ++ insn{11:7}), int<32>);
+ int<13> immBTmp = insn{31:31} ++ insn{7:7} ++ insn{30:25} ++ insn{11:8} ++ 0<1>;
+ int<16> immB = cast(immBTmp, int<16>);
+ int<21> immJTmp = insn{31:31} ++ insn{19:12} ++ insn{20:20} ++ insn{30:21} ++ 0<1>;
+ int<32> immJ = cast(immJTmp, int<32>);
+ int<12> immJRTmp = insn{31:20};
+ int<16> immJR = cast(immJRTmp, int<16>);
+ int<32> immU = insn{31:12} ++ 0<12>;
+ uint<3> doAdd = u0<3>;
+ bool isOpImm = opcode == 0b0010011<7>;
+ bool flip = (!isOpImm) && (flipBit == 1<1>);
+ bool isLui = opcode == 0b0110111<7>;
+ bool isAui = opcode == 0b0010111<7>;
+ bool isOp = opcode == 0b0110011<7>;
+ bool isJal = opcode == 0b1101111<7>;
+ bool isJalr = opcode == 0b1100111<7>;
+ bool isBranch = opcode == 0b1100011<7>;
+ bool isStore = opcode == 0b0100011<7>;
+ bool isLoad = opcode == 0b0000011<7>;
+ bool isMDiv = (funct7 == u1<7>) && isOp;
+ bool isDiv = isMDiv && (funct3 >= u4<3>);
+ bool isMul = isMDiv && (funct3 < u4<3>);
+ bool needrs1 = !isJal;
+ bool needrs2 = isOp || isBranch || isStore || isJalr;
+ bool writerd = (rd != u0<5>) && (isOp || isOpImm || isLoad || isJal || isJalr || isLui || isAui);
+ bool isExcluded = isJalr || isJal || isBranch;
+ bool isInvalid = (opcode <= 0<7>);
+ if (isInvalid && !isExcluded){
+ throw(u0<4>); // Fatal and terminate exec if illegal instr
+ }
+ spec_check();
+ bool notBranch = (!isBranch) && (!isJal) && (!isJalr);
+ if (!done) {
+ if (notBranch) {
+ s2 <- s;
+ } else {
+ if (isBranch) {
+ s2 <- update(s, bht.req(pc, immB, 1<16>));
+ } else {
+ s2 <- s;
+ invalidate(s);
+ }}} else { s2 <- s; invalidate(s); }
+ start(rf);
+ if (!done && (notBranch || isBranch)) { checkpoint(rf); }
+ if (needrs1) {
+ reserve(rf[rs1], R);
+ }
+ if (needrs2) {
+ reserve(rf[rs2], R);
+ }
+ if (writerd) {
+ reserve(rf[rd], W);
+ }
+ end(rf);
+ ---
+ spec_check();
+ if (needrs1) {
+ block(rf[rs1]);
+ int<32> rf1 = rf[rs1];
+ release(rf[rs1]);
+ } else {
+ int<32> rf1 = 0<32>;
+ }
+ if (needrs2) {
+ block(rf[rs2]);
+ int<32> rf2 = rf[rs2];
+ release(rf[rs2]);
+ } else {
+ int<32> rf2 = 0<32>;
+ }
+ bool take = br(funct3, rf1, rf2);
+ if (isBranch) {
+ //divide by 4 b/c we count instructions not bytes
+ int<16> offpc = pc + (immB >> 2);
+ int<16> npc = (take) ? (offpc) : (pc + 1<16>);
+ } else {
+ if (isJal) {
+ //divide by 4 since it counts bytes instead of insns
+ int<32> npc32 = cast(pc, int<32>) + (immJ >> 2);
+ int<16> npc = npc32{15:0};
+ } else {
+ if (isJalr) {
+ int<16> npc = (rf1{15:0} + immJR) >> 2;
+ } else {
+ int<16> npc = pc + 1<16>;
+ }}}
+ int<32> alu_arg1 = (isAui) ? ((0<16> ++ pc) << 2) : rf1;
+ int<32> alu_arg2 = (isAui) ? immU : ((isStore) ? immS : ((isOpImm || isLoad) ? immI : rf2));
+ bool alu_flip = (isStore || isLoad || isAui) ? false : flip;
+ uint<3> alu_funct3 = (isStore || isLoad || isAui) ? doAdd : funct3;
+ int<32> alu_res = alu(alu_arg1, alu_arg2, alu_funct3, alu_flip);
+ int<16> tmppc = pc + 1<16>;
+ int<32> linkpc = 0<16> ++ (tmppc << 2);
+ int<32> mulres = mul(rf1, rf2, funct3);
+ if (writerd && (!isLoad) && (!isDiv)) {
+ block(rf[rd]);
+ int<32> rddata = (isLui) ? immU : ((isMul) ? mulres : ((isJal || isJalr) ? linkpc : alu_res));
+ rf[rd] <- rddata;
+ } else {
+ int<32> rddata = 0<32>;
+ }
+ ---
+ spec_barrier(); //delayed just to force writes to happen speculatively
+ if (!done) {
+ if (!notBranch) {
+ if (isBranch) {
+ verify(s2, npc) { bht.upd(pc, take) };
+ } else {
+ call cpu(npc);
+ }
+ } else {
+ verify(s, pc + 1<16>);
+ }
+ }
+
+ if (isDiv) {
+ int<32> sdividend = sign(rf1);
+ //For REM, ignore sign of divisor
+ int<32> sdivisor = (funct3 == u6<3>) ? 1<32> : sign(rf2);
+ bool isSignedDiv = ((funct3 == u4<3>) || (funct3 == u6<3>));
+ uint<32> dividend = (isSignedDiv) ? cast(mag(rf1), uint<32>) : cast(rf1, uint<32>);
+ uint<32> divisor = (isSignedDiv) ? cast(mag(rf2), uint<32>) : cast(rf2, uint<32>);
+ bool retQuot = funct3 <= u5<3>;
+ bool invertRes <- isSignedDiv && (sdividend != sdivisor);
+ uint<32> udivout <- call div(dividend, divisor, u0<32>, u0<32>, u0<5>, retQuot);
+ } else {
+ bool invertRes <- false;
+ uint<32> udivout <- u0<32>;
+ }
+ uint<32> tmpaddr = cast(alu_res, uint<32>);
+ uint<16> memaddr = (tmpaddr >> 2){15:0};
+ if (memaddr == u65535<16>){ // Some random address that leads to Fatal state if R/W
+ throw(u1<4>);
+ }
+ uint<2> boff = cast(alu_res{1:0}, uint<2>);
+ start(dmem);
+ split {
+ case: (isLoad) {
+ uint<16> raddr = memaddr;
+ int<32> wdata <- dmem[raddr];
+ }
+ case: (isStore) {
+ uint<16> waddr = memaddr;
+ //use bottom bits of data and place in correct offset
+ //shift by boff*8
+ uint<5> nboff = boff ++ u0<3>;
+ dmem[waddr, storeMask(boff, funct3)] <- (rf2 << nboff);
+ int<32> wdata <- 0<32>;
+ }
+ default: {
+ int<32> wdata <- 0<32>;
+ }
+ }
+ end(dmem);
+ ---
+ print("PC: %h", pc << 2);
+ print("INSN: %h", insn);
+ if (writerd) {
+ if (isLoad) {
+ block(rf[rd]);
+ int<32> insnout = maskLoad(wdata, funct3, boff);
+ rf[rd] <- insnout;
+ } else {
+ if (isDiv) {
+ block(rf[rd]);
+ int<32> divout = (invertRes) ? -(cast(udivout, int<32>)) : cast(udivout, int<32>);
+ int<32> insnout = divout;
+ rf[rd] <- insnout;
+ } else {
+ int<32> insnout = rddata;
+ }}
+ print("Writing %d to r%d", insnout, rd);
+ }
+ ---
+commit:
+ if (writerd) {
+ release(rf[rd]);
+ }
+ if (done) { output(true); }
+except(exncode: uint<4>):
+ print("exception at PC == %d! with exncode: %d", pc, exncode);
+ start(csrf);
+ csrf[0] <- cast(exncode, int<32>); // Store Exncode
+ ---// using 2 write port version
+ csrf[1] <- cast(pc, int<32>); // Store ErrPC
+ end(csrf);
+ ---
+ if ((exncode == u0<4>) || (exncode == u1<4>)){
+ output(false); // Terminate execution
+ } else { call cpu(pc + 1<16>); }
+}
+
+circuit {
+ ti = memory(int<32>, 16);
+ td = memory(int<32>, 16);
+ rf = rflock CheckpointRF(int<32>, 5, 64);
+ csrf = regfile(int<32>, 1);
+ div = new multi_stg_div[];
+ b = new BHT<16>[](4);
+ c = new cpu[rf, ti, td, div, b, csrf];
+ call c(0<16>);
+}
\ No newline at end of file
diff --git a/src/test/tests/risc-pipe/risc-pipe-spec-exn.pdl b/src/test/tests/risc-pipe/risc-pipe-spec-exn.pdl
new file mode 100644
index 00000000..28726b2d
--- /dev/null
+++ b/src/test/tests/risc-pipe/risc-pipe-spec-exn.pdl
@@ -0,0 +1,476 @@
+// risc-pipe-spec-write.pdl
+extern BHT {
+ method req(pc: int, skip: int, take: int): int;
+ method upd(pc: int, taken: bool): ();
+}
+
+// hardware interrupt controller
+extern TimingInterruptController {
+ method req(pc: int): bool;
+ method ack(pc: int): ();
+}
+
+def csr_map(csrAddr: uint<12>): uint<5> {
+ if (csrAddr == 0x300) { //mstatus: Machine status register
+ return u0<5>; } else {
+ if (csrAddr == 0x301) { //misa: ISA and extensions
+ return u1<5>; } else {
+ if (csrAddr == 0x302) { //medeleg: Machine exception delegation register
+ return u2<5>; } else {
+ if (csrAddr == 0x303) { //mideleg: Machine interrupt delegation register
+ return u3<5>; } else {
+ if (csrAddr == 0x304) { //mie: Machine interrupt-enable register
+ return u4<5>; } else {
+ if (csrAddr == 0x305) { //mtvec: Machine trap-handler base address
+ return u5<5>; } else {
+ if (csrAddr == 0x340) { //mscratch: Scratch register for machine trap handlers
+ return u6<5>; } else {
+ if (csrAddr == 0x341) { //mepc: Machine exception program counter
+ return u7<5>; } else {
+ if (csrAddr == 0x342) { //mcause: Machine trap cause
+ return u8<5>; } else {
+ if (csrAddr == 0x343) { //mtval: Machine bad address or instruction
+ return u9<5>; } else {
+ if (csrAddr == 0x344) { //mip: Machine interrupt pending
+ return u10<5>; } else {
+ if (csrAddr == 0x34A) { //mtinst: Machine trap instruction (transformed)
+ return u11<5>; } else {
+ return u31<5>;}}}}}}}}}}}}
+}
+
+def mul(arg1: int<32>, arg2: int<32>, op: uint<3>): int<32> {
+ uint<32> mag1 = cast(mag(arg1), uint<32>);
+ uint<32> mag2 = cast(mag(arg2), uint<32>);
+ //MULHU => positive sign always
+ int<32> s1 = (op == u3<3>) ? 1<32> : sign(arg1);
+ //MULHU/MULHSU => positive sign always
+ int<32> s2 = (op >= u2<3>) ? 1<32> : sign(arg2);
+ int<64> magRes = cast((mag1 * mag2), int<64>);
+ int<64> m = (s1 == s2) ? (magRes) : -(magRes);
+ if (op == u0<3>) { //MUL
+ return m{31:0};
+ } else {
+ return m{63:32};
+ }
+}
+
+def alu(arg1: int<32>, arg2: int<32>, op: uint<3>, flip: bool): int<32> {
+ uint<5> shamt = cast(arg2{4:0}, uint<5>);
+ if (op == u0<3>) { //000 == ADD , flip == sub
+ if (!flip) {
+ return arg1 + arg2;
+ } else {
+ return arg1 - arg2;
+ }
+ } else {
+ if (op == u1<3>) { //001 == SLL
+ return arg1 << shamt;
+ } else {
+ if (op == u2<3>) { //010 == SLT
+ return (arg1 < arg2) ? 1<32> : 0<32>;
+ } else {
+ if (op == u3<3>) { //011 == SLTU
+ uint<32> un1 = cast(arg1, uint<32>);
+ uint<32> un2 = cast(arg2, uint<32>);
+ return (un1 < un2) ? 1<32> : 0<32>;
+ } else {
+ if (op == u4<3>) { //100 == XOR
+ return arg1 ^ arg2;
+ } else {
+ if (op == u5<3>) { //101 == SRL / SRA
+ if (!flip) {
+ return cast((cast(arg1, uint<32>)) >> shamt, int<32>); //SRL
+ } else {
+ return arg1 >> shamt; //SRA
+ }
+ } else {
+ if (op == u6<3>) { //110 == OR
+ return arg1 | arg2;
+ } else { //111 == AND
+ return arg1 & arg2;
+ }}}}}}}
+
+}
+
+//true if taking branch
+def br(op:uint<3>, arg1:int<32>, arg2:int<32>): bool {
+ if (op == u0<3>) { //BEQ
+ return (arg1 == arg2);
+ } else {
+ if (op == u1<3>) { //BNE
+ return (arg1 != arg2);
+ } else {
+ if (op == u4<3>) { //BLT
+ return (arg1 < arg2);
+ } else {
+ if (op == u5<3>) { //BGE
+ return (arg1 >= arg2);
+ } else {
+ if (op == u6<3>) { //BLTU
+ uint<32> un1 = cast(arg1, uint<32>);
+ uint<32> un2 = cast(arg2, uint<32>);
+ return (un1 < un2);
+ } else {
+ if (op == u7<3>) { //BGEU
+ uint<32> un1 = cast(arg1, uint<32>);
+ uint<32> un2 = cast(arg2, uint<32>);
+ return(un1 >= un2);
+ } else {
+ return false;
+ }}}}}}
+}
+
+
+def storeMask(off: uint<2>, op: uint<3>): uint<4> {
+ if (op == u0<3>) { //SB
+ return (u0b0001<4> << off);
+ } else {
+ if (op == u1<3>) { //SH
+ uint<2> shamt = off{1:1} ++ u0<1>;
+ return (u0b0011<4> << shamt);
+ } else { //SW
+ return u0b1111<4>;
+ }}
+}
+
+def maskLoad(data: int<32>, op: uint<3>, start: uint<2>): int<32> {
+ //start == offset in bytes, need to multiply by 8
+ uint<5> boff = start ++ u0<3>;
+ int<32> tmp = data >> boff;
+ uint<8> bdata = cast(tmp, uint<8>);
+ uint<16> hdata = cast(tmp, uint<16>);
+
+ if (op == u0<3>) { //LB
+ return cast(bdata, int<32>);
+ } else {
+ if (op == u1<3>) { //LH
+ return cast(hdata, int<32>);
+ } else {
+ if (op == u2<3>) { //LW
+ return data;
+ } else {
+ if (op == u4<3>) { //LBU
+ uint<32> zext = cast(bdata, uint<32>);
+ return cast(zext, int<32>);
+ } else {
+ if (op == u5<3>) { //LHU
+ uint<32> zext = cast(hdata, uint<32>);
+ return cast(zext, int<32>);
+ } else {
+ return 0<32>;
+ }}}}}
+}
+
+pipe multi_stg_div(num: uint<32>, denom: uint<32>, quot: uint<32>, acc: uint<32>, cnt: uint<5>, retQuot: bool)[]: uint<32> {
+ uint<32> tmp = acc{30:0} ++ num{31:31};
+ uint<32> na = (tmp >= denom) ? (tmp - denom) : (tmp);
+ uint<32> nq = (tmp >= denom) ? ((quot << 1){31:1} ++ u1<1>) : (quot << 1);
+ uint<32> nnum = num << 1;
+ bool done = (cnt == u31<5>);
+ if (done) {
+ output( (retQuot) ? nq : na );
+ } else {
+ call multi_stg_div(nnum, denom, nq, na, cnt + u1<5>, retQuot);
+ }
+}
+
+// 0 is U-Mode, 3 is M-mode
+// exn-pipe cpu(pc: int<16>)[rf: int<32>[5](CheckpointRF), csrf: int<32>[5], imem: int<32>[16], dmem: int<32>[16], div: multi_stg_div, bht: BHT, irc: TimingInterruptController, acc: uint<4>[0](CheckpointQueue)]: bool {
+exn-pipe cpu(pc: int<16>)[rf: int<32>[5](CheckpointRF), csrf: int<32>[5], imem: int<32>[16], dmem: int<32>[16], div: multi_stg_div, bht: BHT, acc: uint<4>[0](CheckpointQueue)]: bool {
+ spec_check();
+ start(imem);
+ uint<16> pcaddr = cast(pc, uint<16>);
+ int<32> insn <- imem[pcaddr];
+ end(imem);
+ //print("PC %d -> Stg 0", pc);
+ s <- speccall cpu(pc + 1<16>);
+ ---
+ //This OPCODE is J Self and thus we're using it to signal termination
+ spec_check();
+ bool done = insn == 0x0000006f<32>;
+ //print("PC %d -> Stg 1, insn %h, done? %b", pc, insn, done);
+ int<7> opcode = insn{6:0};
+ uint<5> rs1 = cast(insn{19:15}, uint<5>);
+ uint<5> rs2 = cast(insn{24:20}, uint<5>);
+ uint<5> rd = cast(insn{11:7}, uint<5>);
+ uint<7> funct7 = cast(insn{31:25}, uint<7>);
+ uint<3> funct3 = cast(insn{14:12}, uint<3>);
+ uint<12> csrAddr = cast(insn{31:20}, uint<12>);
+ int<1> flipBit = insn{30:30};
+ int<32> immI = cast(insn{31:20}, int<32>);
+ int<32> immS = cast((insn{31:25} ++ insn{11:7}), int<32>);
+ int<13> immBTmp = insn{31:31} ++ insn{7:7} ++ insn{30:25} ++ insn{11:8} ++ 0<1>;
+ int<16> immB = cast(immBTmp, int<16>);
+ int<21> immJTmp = insn{31:31} ++ insn{19:12} ++ insn{20:20} ++ insn{30:21} ++ 0<1>;
+ int<32> immJ = cast(immJTmp, int<32>);
+ int<12> immJRTmp = insn{31:20};
+ int<16> immJR = cast(immJRTmp, int<16>);
+ int<32> immU = insn{31:12} ++ 0<12>;
+ uint<3> doAdd = u0<3>;
+ bool isOpImm = opcode == 0b0010011<7>;
+ bool flip = (!isOpImm) && (flipBit == 1<1>);
+ bool isLui = opcode == 0b0110111<7>;
+ bool isAui = opcode == 0b0010111<7>;
+ bool isOp = opcode == 0b0110011<7>;
+ bool isJal = opcode == 0b1101111<7>;
+ bool isJalr = opcode == 0b1100111<7>;
+ bool isBranch = opcode == 0b1100011<7>;
+ bool isStore = opcode == 0b0100011<7>;
+ bool isLoad = opcode == 0b0000011<7>;
+ bool isCsr = opcode == 0b1110011<7>;
+ bool isSystem = opcode == 0b1110011<7>;
+ bool isCsrrw = isCsr && (funct3 == u1<3>);
+ bool isCsrrs = isCsr && (funct3 == u2<3>);
+ bool isCsrrc = isCsr && (funct3 == u3<3>);
+ bool isEcall = isSystem && (immI == 0<32>);
+ bool isEbreak = isSystem && (immI == 1<32>);
+ bool isMret = isSystem && (funct7 == u24<7>) && (rs2 == u2<5>);
+ bool isMDiv = (funct7 == u1<7>) && isOp;
+ bool isDiv = isMDiv && (funct3 >= u4<3>);
+ bool isMul = isMDiv && (funct3 < u4<3>);
+ bool needrs1 = !isJal;
+ bool needrs2 = isOp || isBranch || isStore || isJalr;
+ bool writerd = (rd != u0<5>) && (isOp || isOpImm || isLoad || isJal || isJalr || isLui || isAui || isCsrrw);
+ // if (isCsr){
+ // acquire(csrlock);
+ // } else {
+ // wait(csrlock);
+ // }
+ //print("PC %d -> Stg 2, insn %h, done? %b", pc, insn, done);
+ bool notBranch = (!isBranch) && (!isJal) && (!isJalr);
+ if (!done) {
+ if (notBranch) {
+ s2 <- s;
+ } else {
+ if (isBranch) {
+ s2 <- update(s, bht.req(pc, immB, 1<16>));
+ } else {
+ s2 <- s;
+ invalidate(s);
+ }}} else { s2 <- s; invalidate(s); }
+ if (isEcall){
+ throw(false, u8<4>);
+ }
+ if (isMret){
+ throw(false, u3<4>);
+ }
+ start(rf);
+ if (!done && (notBranch || isBranch)) { checkpoint(rf); }
+ if (needrs1) {
+ reserve(rf[rs1], R);
+ }
+ if (needrs2) {
+ reserve(rf[rs2], R);
+ }
+ if (writerd) {
+ reserve(rf[rd], W);
+ }
+ end(rf);
+// uint<5> ridx = csr_map(csrAddr);
+// uint<5> widx = csr_map(csrAddr);
+ ---
+ //print("PC %d -> Stg 2", pc);
+ spec_check();
+// if(isCsrrs){
+// int<32> oldCsrVal = csrf[ridx];
+// }
+ if (needrs1) {
+ block(rf[rs1]);
+ int<32> rf1 = rf[rs1];
+ release(rf[rs1]); // Read locks doesn't matter
+ } else {
+ int<32> rf1 = 0<32>;
+ }
+ if (needrs2) {
+ block(rf[rs2]);
+ int<32> rf2 = rf[rs2];
+ release(rf[rs2]);
+ } else {
+ int<32> rf2 = 0<32>;
+ }
+ bool take = br(funct3, rf1, rf2);
+ if (isBranch) {
+ //divide by 4 b/c we count instructions not bytes
+ int<16> offpc = pc + (immB >> 2);
+ int<16> npc = (take) ? (offpc) : (pc + 1<16>);
+ } else {
+ if (isJal) {
+ //divide by 4 since it counts bytes instead of insns
+ int<32> npc32 = cast(pc, int<32>) + (immJ >> 2);
+ int<16> npc = npc32{15:0};
+ } else {
+ if (isJalr) {
+ int<16> npc = (rf1{15:0} + immJR) >> 2;
+ } else {
+ int<16> npc = pc + 1<16>;
+ }}}
+ int<32> alu_arg1 = (isAui) ? ((0<16> ++ pc) << 2) : rf1;
+ int<32> alu_arg2 = (isAui) ? immU : ((isStore) ? immS : ((isOpImm || isLoad) ? immI : rf2));
+ bool alu_flip = (isStore || isLoad || isAui) ? false : flip;
+ uint<3> alu_funct3 = (isStore || isLoad || isAui) ? doAdd : funct3;
+ int<32> alu_res = alu(alu_arg1, alu_arg2, alu_funct3, alu_flip);
+ int<16> tmppc = pc + 1<16>;
+ int<32> linkpc = 0<16> ++ (tmppc << 2);
+ int<32> mulres = mul(rf1, rf2, funct3);
+ if (writerd && (!isLoad) && (!isDiv)) {
+ block(rf[rd]);
+ int<32> rddata = (isLui) ? immU : ((isMul) ? mulres : ((isJal || isJalr) ? linkpc : alu_res));
+ rf[rd] <- rddata;
+ } else {
+ int<32> rddata = 0<32>;
+ }
+ ---
+ //print("PC %d -> Stg 3", pc);
+ spec_barrier(); //delayed just to force writes to happen speculatively
+ if (!done) {
+ if (!notBranch) {
+ if (isBranch) {
+ verify(s2, npc) { bht.upd(pc, take) };
+ } else {
+ call cpu(npc);
+ }
+ } else {
+ verify(s, pc + 1<16>);
+ }
+ }
+
+ if (isDiv) {
+ int<32> sdividend = sign(rf1);
+ //For REM, ignore sign of divisor
+ int<32> sdivisor = (funct3 == u6<3>) ? 1<32> : sign(rf2);
+ bool isSignedDiv = ((funct3 == u4<3>) || (funct3 == u6<3>));
+ uint<32> dividend = (isSignedDiv) ? cast(mag(rf1), uint<32>) : cast(rf1, uint<32>);
+ uint<32> divisor = (isSignedDiv) ? cast(mag(rf2), uint<32>) : cast(rf2, uint<32>);
+ bool retQuot = funct3 <= u5<3>;
+ bool invertRes <- isSignedDiv && (sdividend != sdivisor);
+ uint<32> udivout <- call div(dividend, divisor, u0<32>, u0<32>, u0<5>, retQuot);
+ } else {
+ bool invertRes <- false;
+ uint<32> udivout <- u0<32>;
+ }
+ uint<32> tmpaddr = cast(alu_res, uint<32>);
+ uint<16> memaddr = (tmpaddr >> 2){15:0};
+ uint<2> boff = cast(alu_res{1:0}, uint<2>);
+ start(dmem);
+ split {
+ case: (isLoad) {
+ uint<16> raddr = memaddr;
+ int<32> wdata <- dmem[raddr];
+ }
+ case: (isStore) {
+ uint<16> waddr = memaddr;
+ //use bottom bits of data and place in correct offset
+ //shift by boff*8
+ uint<5> nboff = boff ++ u0<3>;
+ dmem[waddr, storeMask(boff, funct3)] <- (rf2 << nboff);
+ int<32> wdata <- 0<32>;
+ }
+ default: {
+ int<32> wdata <- 0<32>;
+ }
+ }
+ end(dmem);
+ ---
+ //print("PC %d -> Stg 4", pc);
+ print("PC: %h", pc << 2);
+ print("INSN: %h", insn);
+ if (writerd) {
+ if (isLoad) {
+ block(rf[rd]);
+ int<32> insnout = maskLoad(wdata, funct3, boff);
+ rf[rd] <- insnout;
+ } else {
+ if (isDiv) {
+ block(rf[rd]);
+ int<32> divout = (invertRes) ? -(cast(udivout, int<32>)) : cast(udivout, int<32>);
+ int<32> insnout = divout;
+ rf[rd] <- insnout;
+ } else {
+ int<32> insnout = rddata;
+ }}
+ print("Writing %d to r%d", insnout, rd);
+ }
+// if (isCsrrw) {
+// csrf[widx] <- rf1;
+// }
+
+ // print("reaching pre-commit stage for pc %d", pc);
+ // print(irc.req(pc));
+ // catch(irc){throw(true, u1<4>)};
+ // This gets expanded to:
+
+ // bool is_interrupt = irc.req(pc);
+ // if (is_interrupt) {
+ // throw(true, exncode);
+ // irc.ack(pc);
+ // }
+ // Can change return value of req to be exncode
+---
+commit:
+// release(acc);
+ if (writerd) {
+ release(rf[rd]);
+ //print("written to rd %d at pc %d", rd, pc);
+ }
+ // print("Committing PC == %d", pc);
+// if(isCsr){
+// release(csrlock);
+// }
+ if (done) { output(true); }
+except(interrupt: bool, exncode: uint<4>):
+ // mem.abort
+ // spec.abort
+ // fifos.abort
+ // IF - DC - EX - if(!exceptional) Commit - if(exceptional) Except
+ print("exception at PC == %d! with exncode: %d", pc, exncode);
+ ---
+ start(csrf);
+ if (!interrupt && exncode == u8<4>){ // 8 is ecall
+ uint<5> rdidx = u5<5>; // 5 is mtvec
+ print("ECALL");
+ } else {
+ if (!interrupt && exncode == u3<4>){ // 3 is mret
+ uint<5> rdidx = u7<5>; // 7 is mepc
+ print("MRET");
+ } else {
+ if (interrupt) {uint<5> rdidx = u7<5>;}
+ uint<5> rdidx = u0<5>; // undefined
+ }}
+ int<32> csrret = csrf[rdidx];
+ int<16> tmppc = csrret{15:0};
+ if (exncode == u8<4>){
+ int<16> npc = tmppc; // Goto handler address
+ } else {
+ if (exncode == u3<4>){
+ int<16> npc = tmppc + 1<16>; // Goto exceptional instruction address
+ } else {
+ int<16> npc = pc + 1<16>;
+ }
+ }
+ ---
+ uint<5> mepcidx = u7<5>; // 7 is mepc
+ csrf[mepcidx] <- cast(pc, int<32>); //write pc to mpec
+ ---
+ uint<5> mcauseidx = u8<5>; // 8 is mcause
+ csrf[mcauseidx] <- cast(exncode, int<32>); //write pc to mpec
+ end(csrf);
+ ---
+ print("GOTO PC: %d", npc);
+ call cpu(npc);
+}
+
+circuit {
+ ti = memory(int<32>, 16);
+ td = memory(int<32>, 16);
+ rf = rflock CheckpointRF(int<32>, 5, 64);
+ csrf = regfile(int<32>, 5);
+ acc = register(uint<4>, 0);
+ locked = CheckpointQueue(acc);
+ div = new multi_stg_div[];
+ b = new BHT<16>[](4);
+ //irc = new TimingInterruptController<16>[]();
+ //c = new cpu[rf, csrf, ti, td, div, b, irc, locked];
+ c = new cpu[rf, csrf, ti, td, div, b, locked];
+
+ call c(0<16>);
+}
\ No newline at end of file
diff --git a/src/test/tests/risc-pipe/risc-pipe-spec-rename-bht.pdl b/src/test/tests/risc-pipe/risc-pipe-spec-rename-bht.pdl
index a0ad485d..e33e6632 100644
--- a/src/test/tests/risc-pipe/risc-pipe-spec-rename-bht.pdl
+++ b/src/test/tests/risc-pipe/risc-pipe-spec-rename-bht.pdl
@@ -1,3 +1,4 @@
+// risc-pipe-spec-rename-bht.pdl
extern BHT {
method req(pc: int, skip: int, take: int): int;
method upd(pc: int, taken: bool): ();
diff --git a/src/test/tests/risc-pipe/risc-pipe-spec-rename-ooo-infer.pdl b/src/test/tests/risc-pipe/risc-pipe-spec-rename-ooo-infer.pdl
index 1d8e6bb2..b549446d 100644
--- a/src/test/tests/risc-pipe/risc-pipe-spec-rename-ooo-infer.pdl
+++ b/src/test/tests/risc-pipe/risc-pipe-spec-rename-ooo-infer.pdl
@@ -1,3 +1,4 @@
+// risc-pipe-spec-rename-ooo-infer.pdl
extern BHT {
method req(pc: int, skip: int, take: int): int;
method upd(pc: int, taken: bool): ();
diff --git a/src/test/tests/risc-pipe/risc-pipe-spec-rename-ooo.pdl b/src/test/tests/risc-pipe/risc-pipe-spec-rename-ooo.pdl
index d928bafa..8f3b8161 100644
--- a/src/test/tests/risc-pipe/risc-pipe-spec-rename-ooo.pdl
+++ b/src/test/tests/risc-pipe/risc-pipe-spec-rename-ooo.pdl
@@ -1,3 +1,4 @@
+// risc-pipe-spec-rename-ooo.pdl
extern BHT {
method req(pc: int, skip: int, take: int): int;
method upd(pc: int, taken: bool): ();
diff --git a/src/test/tests/risc-pipe/risc-pipe-spec-write-2.pdl b/src/test/tests/risc-pipe/risc-pipe-spec-write-2.pdl
index bccf398b..4b746f89 100644
--- a/src/test/tests/risc-pipe/risc-pipe-spec-write-2.pdl
+++ b/src/test/tests/risc-pipe/risc-pipe-spec-write-2.pdl
@@ -1,3 +1,4 @@
+// risc-pipe-spec-write-2.pdl
extern BHT {
method req(pc: int, skip: int, take: int): int;
method upd(pc: int, taken: bool): ();
diff --git a/src/test/tests/risc-pipe/risc-pipe-spec-write-infer.pdl b/src/test/tests/risc-pipe/risc-pipe-spec-write-infer.pdl
index 4cb07645..dc833643 100644
--- a/src/test/tests/risc-pipe/risc-pipe-spec-write-infer.pdl
+++ b/src/test/tests/risc-pipe/risc-pipe-spec-write-infer.pdl
@@ -1,3 +1,4 @@
+// risc-pipe-spec-write-infer.pdl
extern BHT {
method req(pc: int, skip: int, take: int): int;
method upd(pc: int, taken: bool): ();
diff --git a/src/test/tests/risc-pipe/risc-pipe-spec-write.pdl b/src/test/tests/risc-pipe/risc-pipe-spec-write.pdl
index c36b366b..0c7cb83b 100644
--- a/src/test/tests/risc-pipe/risc-pipe-spec-write.pdl
+++ b/src/test/tests/risc-pipe/risc-pipe-spec-write.pdl
@@ -1,3 +1,4 @@
+// risc-pipe-spec-write.pdl
extern BHT {
method req(pc: int, skip: int, take: int): int;
method upd(pc: int, taken: bool): ();
@@ -140,7 +141,7 @@ pipe multi_stg_div(num: uint<32>, denom: uint<32>, quot: uint<32>, acc: uint<32>
}
-pipe cpu(pc: int<16>)[rf: int<32>[5](CheckpointRF), imem: int<32>[16], dmem: int<32>[16], div: multi_stg_div, bht: BHT]: bool {
+pipe cpu(pc: int<16>)[rf: int<32>[5](CheckpointRF), imem: int<32>[16], dmem: int<32>[16](CheckpointQueue), div: multi_stg_div, bht: BHT]: bool {
spec_check();
start(imem);
uint<16> pcaddr = cast(pc, uint<16>);
@@ -254,6 +255,13 @@ pipe cpu(pc: int<16>)[rf: int<32>[5](CheckpointRF), imem: int<32>[16]
} else {
int<32> rddata = 0<32>;
}
+ uint<32> tmpaddr = cast(alu_res, uint<32>);
+ uint<16> memaddr = (tmpaddr >> 2){15:0};
+ start(dmem);
+ if (isLoad || isStore){
+ reserve(dmem);
+ }
+ end(dmem);
---
spec_barrier(); //delayed just to force writes to happen speculatively
if (!done) {
@@ -282,16 +290,16 @@ pipe cpu(pc: int<16>)[rf: int<32>[5](CheckpointRF), imem: int<32>[16]
bool invertRes <- false;
uint<32> udivout <- u0<32>;
}
- uint<32> tmpaddr = cast(alu_res, uint<32>);
- uint<16> memaddr = (tmpaddr >> 2){15:0};
+
uint<2> boff = cast(alu_res{1:0}, uint<2>);
- start(dmem);
split {
- case: (isLoad) {
- uint<16> raddr = memaddr;
- int<32> wdata <- dmem[raddr];
+ case: (isLoad) {
+ block(dmem);
+ uint<16> raddr = memaddr;
+ int<32> wdata <- dmem[raddr];
}
case: (isStore) {
+ block(dmem);
uint<16> waddr = memaddr;
//use bottom bits of data and place in correct offset
//shift by boff*8
@@ -303,13 +311,12 @@ pipe cpu(pc: int<16>)[rf: int<32>[5](CheckpointRF), imem: int<32>[16]
int<32> wdata <- 0<32>;
}
}
- end(dmem);
---
print("PC: %h", pc << 2);
print("INSN: %h", insn);
if (writerd) {
if (isLoad) {
- block(rf[rd]);
+ block(rf[rd]);
int<32> insnout = maskLoad(wdata, funct3, boff);
rf[rd] <- insnout;
} else {
@@ -326,7 +333,10 @@ pipe cpu(pc: int<16>)[rf: int<32>[5](CheckpointRF), imem: int<32>[16]
---
if (writerd) {
release(rf[rd]);
- }
+ }
+ if (isStore || isLoad) {
+ release(dmem);
+ }
if (done) { output(true); }
}
@@ -336,6 +346,7 @@ circuit {
rf = rflock CheckpointRF(int<32>, 5, 64);
div = new multi_stg_div[];
b = new BHT<16>[](4);
- c = new cpu[rf, ti, td, div, b];
+ lockedtd = CheckpointQueue(td);
+ c = new cpu[rf, ti, lockedtd, div, b];
call c(0<16>);
}
\ No newline at end of file
diff --git a/src/test/tests/risc-pipe/risc-pipe-spec.pdl b/src/test/tests/risc-pipe/risc-pipe-spec.pdl
index 35cb0d82..e81748e8 100644
--- a/src/test/tests/risc-pipe/risc-pipe-spec.pdl
+++ b/src/test/tests/risc-pipe/risc-pipe-spec.pdl
@@ -1,3 +1,4 @@
+// risc-pipe-spec.pdl
def mul(arg1: int<32>, arg2: int<32>, op: uint<3>): int<32> {
uint<32> mag1 = cast(mag(arg1), uint<32>);
uint<32> mag2 = cast(mag(arg2), uint<32>);
@@ -233,7 +234,7 @@ pipe cpu(pc: int<16>)[rf: int<32>[5](FAQueue), imem: int<32>[16](Queu
}
---
split {
- case: (isLui) {
+ case: (isLui) {
int<32> alu_res = immU;
}
case: (isAui) {
@@ -252,7 +253,7 @@ pipe cpu(pc: int<16>)[rf: int<32>[5](FAQueue), imem: int<32>[16](Queu
}
}
split {
- case: (isStore) {
+ case: (isStore) {
//addresses also are word-sized
int<32> tmp = immS + rf1;
uint<32> ctmp = cast(tmp, uint<32>);
@@ -269,7 +270,7 @@ pipe cpu(pc: int<16>)[rf: int<32>[5](FAQueue), imem: int<32>[16](Queu
default: {
uint<16> memaddr = u0<16>;
uint<2> boff = u0<2>;
- }
+ }
}
---
start(dmem);
diff --git a/src/test/tests/risc-pipe/risc-pipe.pdl b/src/test/tests/risc-pipe/risc-pipe.pdl
index 79e37636..09c3e84a 100644
--- a/src/test/tests/risc-pipe/risc-pipe.pdl
+++ b/src/test/tests/risc-pipe/risc-pipe.pdl
@@ -1,3 +1,4 @@
+// risc-pipe.pdl
def mul(arg1: int<32>, arg2: int<32>, op: uint<3>): int<32> {
uint<32> mag1 = cast(mag(arg1), uint<32>);
uint<32> mag2 = cast(mag(arg2), uint<32>);
diff --git a/src/test/tests/risc-pipe/solutions/risc-pipe-spec-exn.typechecksol b/src/test/tests/risc-pipe/solutions/risc-pipe-spec-exn.typechecksol
new file mode 100644
index 00000000..9fb4ec93
--- /dev/null
+++ b/src/test/tests/risc-pipe/solutions/risc-pipe-spec-exn.typechecksol
@@ -0,0 +1 @@
+Passed
\ No newline at end of file
diff --git a/src/test/tests/simtests/unlocked-reg.pdl b/src/test/tests/simtests/unlocked-reg.pdl
index c9e3cdcb..65193fcf 100644
--- a/src/test/tests/simtests/unlocked-reg.pdl
+++ b/src/test/tests/simtests/unlocked-reg.pdl
@@ -1,3 +1,4 @@
+// unlocked-reg.pdl
//Expected Success
pipe unlock(tinput: int<32>)[rf: int<32>[0]]: bool {
spec_check();
diff --git a/src/test/tests/speculation/3-stg-pipe-spec-2.pdl b/src/test/tests/speculation/3-stg-pipe-spec-2.pdl
index 941ad62b..701265be 100644
--- a/src/test/tests/speculation/3-stg-pipe-spec-2.pdl
+++ b/src/test/tests/speculation/3-stg-pipe-spec-2.pdl
@@ -1,3 +1,4 @@
+// 3-stg-pipe-spec-2.pdl
pipe cpu(pc: int<8>)[rf: int<32>[5](RenameRF), imem: int<32>[8]]: bool {
spec_check(); //nonblocking check
start(imem);
diff --git a/src/test/tests/speculation/3-stg-pipe-spec-3.pdl b/src/test/tests/speculation/3-stg-pipe-spec-3.pdl
index 30d1d7bc..2e3b5de7 100644
--- a/src/test/tests/speculation/3-stg-pipe-spec-3.pdl
+++ b/src/test/tests/speculation/3-stg-pipe-spec-3.pdl
@@ -1,3 +1,4 @@
+// 3-stg-pipe-spec-3.pdl
pipe cpu(pc: int<8>)[rf: int<32>[5](FAQueue), imem: int<32>[8]]: bool {
spec_check(); //nonblocking check
start(imem);
diff --git a/src/test/tests/speculation/3-stg-pipe-spec.pdl b/src/test/tests/speculation/3-stg-pipe-spec.pdl
index 88166546..c43f5a65 100644
--- a/src/test/tests/speculation/3-stg-pipe-spec.pdl
+++ b/src/test/tests/speculation/3-stg-pipe-spec.pdl
@@ -1,3 +1,4 @@
+// 3-stg-pipe-spec.pdl
pipe cpu(pc: int<8>)[rf: int<32>[5](RenameRF), imem: int<32>[8]]: bool {
spec_check(); //nonblocking check
start(imem);
diff --git a/src/test/tests/speculation/3-stg-pipe.pdl b/src/test/tests/speculation/3-stg-pipe.pdl
index 87ed4ace..1945d315 100644
--- a/src/test/tests/speculation/3-stg-pipe.pdl
+++ b/src/test/tests/speculation/3-stg-pipe.pdl
@@ -1,3 +1,4 @@
+// 3-stg-pipe.pdl
pipe cpu(pc: int<8>)[rf: int<32>[5](RenameRF), imem: int<32>[8]]: bool {
start(imem);
int<32> insn <- imem[cast(pc, uint<8>)];
diff --git a/src/test/tests/speculation/bad-spec-1.pdl b/src/test/tests/speculation/bad-spec-1.pdl
index fb3bd485..fca97ce6 100644
--- a/src/test/tests/speculation/bad-spec-1.pdl
+++ b/src/test/tests/speculation/bad-spec-1.pdl
@@ -1,3 +1,4 @@
+// bad-spec-1.pdl
pipe cpu(pc: int<8>)[rf: int<32>[5](RenameRF), imem: int<32>[8]]: bool {
spec_check(); //nonblocking check
start(imem);
diff --git a/src/test/tests/speculation/bad-spec-2.pdl b/src/test/tests/speculation/bad-spec-2.pdl
index 60b48359..6b35ac2e 100644
--- a/src/test/tests/speculation/bad-spec-2.pdl
+++ b/src/test/tests/speculation/bad-spec-2.pdl
@@ -1,3 +1,4 @@
+// bad-spec-2.pdl
pipe cpu(pc: int<8>)[rf: int<32>[5](RenameRF), imem: int<32>[8]]: bool {
spec_check(); //nonblocking check
start(imem);
diff --git a/src/test/tests/speculation/bad-spec-3.pdl b/src/test/tests/speculation/bad-spec-3.pdl
index ab482353..f095286d 100644
--- a/src/test/tests/speculation/bad-spec-3.pdl
+++ b/src/test/tests/speculation/bad-spec-3.pdl
@@ -1,3 +1,4 @@
+// bad-spec-3.pdl
pipe cpu(pc: int<8>)[rf: int<32>[5](RenameRF), imem: int<32>[8]]: bool {
spec_check(); //nonblocking check
start(imem);
diff --git a/src/test/tests/speculation/bad-spec-4.pdl b/src/test/tests/speculation/bad-spec-4.pdl
index fdf7485f..137cf73b 100644
--- a/src/test/tests/speculation/bad-spec-4.pdl
+++ b/src/test/tests/speculation/bad-spec-4.pdl
@@ -1,3 +1,4 @@
+// bad-spec-4.pdl
pipe cpu(pc: int<8>)[rf: int<32>[5](RenameRF), imem: int<32>[8]]: bool {
//spec_check(); //nonblocking check
//missing nonblocking check
diff --git a/src/test/tests/speculation/bad-spec-5.pdl b/src/test/tests/speculation/bad-spec-5.pdl
index d8020098..3547e3ae 100644
--- a/src/test/tests/speculation/bad-spec-5.pdl
+++ b/src/test/tests/speculation/bad-spec-5.pdl
@@ -1,3 +1,4 @@
+// bad-spec-5.pdl
pipe cpu(pc: int<8>)[rf: int<32>[5](RenameRF), imem: int<32>[8]]: bool {
//spec_check(); //nonblocking check
//missing nonblocking check
diff --git a/src/test/tests/speculation/spec-write-2.pdl b/src/test/tests/speculation/spec-write-2.pdl
index 9ac5d9da..4e66937a 100644
--- a/src/test/tests/speculation/spec-write-2.pdl
+++ b/src/test/tests/speculation/spec-write-2.pdl
@@ -1,3 +1,4 @@
+// spec-write-2.pdl
pipe testwrite(pc: int<8>)[rf: int<32>[5](CheckpointQueue), imem: int<32>[8]]: bool {
spec_check();
start(imem);
diff --git a/src/test/tests/speculation/spec-write-fail.pdl b/src/test/tests/speculation/spec-write-fail.pdl
index 54a79bdd..54d1c681 100644
--- a/src/test/tests/speculation/spec-write-fail.pdl
+++ b/src/test/tests/speculation/spec-write-fail.pdl
@@ -1,3 +1,4 @@
+// spec-write-fail.pdl
pipe testwrite(pc: int<32>)[rf: int<32>[5](CheckpointQueue), imem: int<40>[8]]: bool {
spec_check();
start(imem);
diff --git a/src/test/tests/speculation/spec-write-fail2.pdl b/src/test/tests/speculation/spec-write-fail2.pdl
index ebf9e812..721385c0 100644
--- a/src/test/tests/speculation/spec-write-fail2.pdl
+++ b/src/test/tests/speculation/spec-write-fail2.pdl
@@ -1,3 +1,4 @@
+// spec-write-fail2.pdl
pipe testwrite(pc: int<32>)[rf: int<32>[5](CheckpointQueue), imem: int<40>[8]]: bool {
spec_check();
start(imem);
diff --git a/src/test/tests/speculation/spec-write-fail3.pdl b/src/test/tests/speculation/spec-write-fail3.pdl
index 73a078eb..1aa38ca3 100644
--- a/src/test/tests/speculation/spec-write-fail3.pdl
+++ b/src/test/tests/speculation/spec-write-fail3.pdl
@@ -1,3 +1,4 @@
+// spec-write-fail3.pdl
pipe testwrite(pc: int<32>)[rf: int<32>[5](CheckpointQueue), imem: int<40>[8]]: bool {
spec_check();
start(imem);
diff --git a/src/test/tests/speculation/spec-write-infer.pdl b/src/test/tests/speculation/spec-write-infer.pdl
index ad5ce938..083b4aed 100644
--- a/src/test/tests/speculation/spec-write-infer.pdl
+++ b/src/test/tests/speculation/spec-write-infer.pdl
@@ -1,3 +1,4 @@
+// spec-write-infer.pdl
pipe testwrite(pc: int<32>)[rf: int<32>[5](CheckpointQueue), imem: int<40>[8]]: bool {
spec_check();
start(imem);
diff --git a/src/test/tests/speculation/spec-write.pdl b/src/test/tests/speculation/spec-write.pdl
index 20850641..a547a951 100644
--- a/src/test/tests/speculation/spec-write.pdl
+++ b/src/test/tests/speculation/spec-write.pdl
@@ -1,3 +1,4 @@
+// spec-write.pdl
pipe testwrite(pc: int<32>)[rf: int<32>[5](CheckpointQueue), imem: int<40>[8]]: bool {
spec_check();
start(imem);
diff --git a/src/test/tests/speculation/unnecessary-checkpoint.pdl b/src/test/tests/speculation/unnecessary-checkpoint.pdl
index 3785c6b9..5ddd9404 100644
--- a/src/test/tests/speculation/unnecessary-checkpoint.pdl
+++ b/src/test/tests/speculation/unnecessary-checkpoint.pdl
@@ -1,3 +1,4 @@
+// unnecessary-checkpoint.pdl
pipe cpu(pc: int<8>)[rf: int<32>[5](CheckpointRF), imem: int<32>[8]]: bool {
start(imem);
int<32> insn <- imem[cast(pc, uint<8>)];
diff --git a/src/test/tests/typecheckTests/acquire-in-expr-fail.pdl b/src/test/tests/typecheckTests/acquire-in-expr-fail.pdl
index fbcba745..b2f1d4b1 100644
--- a/src/test/tests/typecheckTests/acquire-in-expr-fail.pdl
+++ b/src/test/tests/typecheckTests/acquire-in-expr-fail.pdl
@@ -1,3 +1,4 @@
+// acquire-in-expr-fail.pdl
//Expected Fail
pipe test6(input: int<32>)[rf: int<32>[5]] {
start(rf);
diff --git a/src/test/tests/typecheckTests/acquire-in-expr.pdl b/src/test/tests/typecheckTests/acquire-in-expr.pdl
index 9f900ac6..197b8e40 100644
--- a/src/test/tests/typecheckTests/acquire-in-expr.pdl
+++ b/src/test/tests/typecheckTests/acquire-in-expr.pdl
@@ -1,3 +1,4 @@
+// acquire-in-expr.pdl
//Expected Success
pipe test6(input: int<32>)[rf: int<32>[5](Queue)] {
start(rf);
diff --git a/src/test/tests/typecheckTests/boolean-mishap.pdl b/src/test/tests/typecheckTests/boolean-mishap.pdl
index e357c28b..1e93a94d 100644
--- a/src/test/tests/typecheckTests/boolean-mishap.pdl
+++ b/src/test/tests/typecheckTests/boolean-mishap.pdl
@@ -1,3 +1,4 @@
+// boolean-mishap.pdl
pipe mistake(input: int<32>)[rf: int<32>[5]] {
bool a = input{0:0};
bool b = input{1:1};
diff --git a/src/test/tests/typecheckTests/double-call-fail.pdl b/src/test/tests/typecheckTests/double-call-fail.pdl
index ef71f188..a6b73777 100644
--- a/src/test/tests/typecheckTests/double-call-fail.pdl
+++ b/src/test/tests/typecheckTests/double-call-fail.pdl
@@ -1,3 +1,4 @@
+// double-call-fail.pdl
//cannot call twice in same pipe
pipe call2(input: int<32>)[rf: int<32>[5]] {
start(rf);
diff --git a/src/test/tests/typecheckTests/double-call-guarded.pdl b/src/test/tests/typecheckTests/double-call-guarded.pdl
index 2e3dba48..fb4fd46c 100644
--- a/src/test/tests/typecheckTests/double-call-guarded.pdl
+++ b/src/test/tests/typecheckTests/double-call-guarded.pdl
@@ -1,3 +1,4 @@
+// double-call-guarded.pdl
pipe call_guard(input: int<32>)[rf: int<32>[5](Queue)] {
start(rf);
reserve(rf);
diff --git a/src/test/tests/typecheckTests/exn-basic.pdl b/src/test/tests/typecheckTests/exn-basic.pdl
index f6bd5b0f..11330731 100644
--- a/src/test/tests/typecheckTests/exn-basic.pdl
+++ b/src/test/tests/typecheckTests/exn-basic.pdl
@@ -1,3 +1,4 @@
+// exn-basic.pdl
exn-pipe cpu(pc :uint<16>)[acc :uint<4>[0](Queue), oth :uint<4>[0](Queue)] :uint<4> {
reserve(acc);
---
diff --git a/src/test/tests/typecheckTests/exn-no-end-after-call.pdl b/src/test/tests/typecheckTests/exn-no-end-after-call.pdl
index 6d8243d0..cf01b48c 100644
--- a/src/test/tests/typecheckTests/exn-no-end-after-call.pdl
+++ b/src/test/tests/typecheckTests/exn-no-end-after-call.pdl
@@ -1,3 +1,4 @@
+// exn-no-end-after-call.pdl
exn-pipe cpu(pc :uint<16>)[acc :uint<4>[0](Queue), oth :uint<4>[0](Queue)] :uint<4> {
reserve(acc);
---
diff --git a/src/test/tests/typecheckTests/exn-no-release-main.pdl b/src/test/tests/typecheckTests/exn-no-release-main.pdl
index dd63bb80..1dc7090d 100644
--- a/src/test/tests/typecheckTests/exn-no-release-main.pdl
+++ b/src/test/tests/typecheckTests/exn-no-release-main.pdl
@@ -1,3 +1,4 @@
+// exn-no-release-main.pdl
exn-pipe cpu(pc :uint<16>)[acc :uint<4>[0](Queue), oth :uint<4>[0](Queue)] :uint<4> {
reserve(acc);
---
diff --git a/src/test/tests/typecheckTests/exn-no-throw-commit.pdl b/src/test/tests/typecheckTests/exn-no-throw-commit.pdl
index e7aa08d6..804b2641 100644
--- a/src/test/tests/typecheckTests/exn-no-throw-commit.pdl
+++ b/src/test/tests/typecheckTests/exn-no-throw-commit.pdl
@@ -1,3 +1,4 @@
+// exn-no-throw-commit.pdl
exn-pipe cpu(pc :uint<16>)[acc :uint<4>[0](Queue), oth :uint<4>[0](Queue)] :uint<4> {
reserve(acc);
---
diff --git a/src/test/tests/typecheckTests/exn-no-throw-except.pdl b/src/test/tests/typecheckTests/exn-no-throw-except.pdl
index f4115bb4..38b9e0c2 100644
--- a/src/test/tests/typecheckTests/exn-no-throw-except.pdl
+++ b/src/test/tests/typecheckTests/exn-no-throw-except.pdl
@@ -1,3 +1,4 @@
+// exn-no-throw-except.pdl
exn-pipe cpu(pc :uint<16>)[acc :uint<4>[0](Queue), oth :uint<4>[0](Queue)] :uint<4> {
reserve(acc);
---
diff --git a/src/test/tests/typecheckTests/exn-no-throw-normal.pdl b/src/test/tests/typecheckTests/exn-no-throw-normal.pdl
index 161111a1..a8ba6b14 100644
--- a/src/test/tests/typecheckTests/exn-no-throw-normal.pdl
+++ b/src/test/tests/typecheckTests/exn-no-throw-normal.pdl
@@ -1,3 +1,4 @@
+// exn-no-throw-normal.pdl
pipe cpu(pc :uint<16>)[acc :uint<4>[0](Queue), oth :uint<4>[0](Queue)] :uint<4> {
reserve(acc);
---
diff --git a/src/test/tests/typecheckTests/exn-no-unlocked-write-main.pdl b/src/test/tests/typecheckTests/exn-no-unlocked-write-main.pdl
index 5d660687..757be875 100644
--- a/src/test/tests/typecheckTests/exn-no-unlocked-write-main.pdl
+++ b/src/test/tests/typecheckTests/exn-no-unlocked-write-main.pdl
@@ -1,3 +1,4 @@
+// exn-no-unlocked-write-main.pdl
exn-pipe cpu(pc :uint<16>)[acc :uint<4>[0](Queue), oth :uint<4>[0](Queue), abc :uint<8>[16] ] :uint<4> {
start(abc);
abc[pc] <- 4;
diff --git a/src/test/tests/typecheckTests/extern-synch-fail.pdl b/src/test/tests/typecheckTests/extern-synch-fail.pdl
index 7c71407d..096c4b8a 100644
--- a/src/test/tests/typecheckTests/extern-synch-fail.pdl
+++ b/src/test/tests/typecheckTests/extern-synch-fail.pdl
@@ -1,3 +1,4 @@
+// extern-synch-fail.pdl
extern myExt {
method mySyncMethod(a :int<32>) :int<32>;
method myCombMethod(a :int<32>) :int<32>;
diff --git a/src/test/tests/typecheckTests/extern_pass.pdl b/src/test/tests/typecheckTests/extern_pass.pdl
index d4238c42..8a55d636 100644
--- a/src/test/tests/typecheckTests/extern_pass.pdl
+++ b/src/test/tests/typecheckTests/extern_pass.pdl
@@ -1,3 +1,4 @@
+// extern_pass.pdl
extern myExt {
method mySyncMethod(a :int<32>) :int<32>;
method myCombMethod(a :int<32>) :int<32>;
diff --git a/src/test/tests/typecheckTests/generic-bht-fail.pdl b/src/test/tests/typecheckTests/generic-bht-fail.pdl
index 7d5b7e34..597f9c84 100644
--- a/src/test/tests/typecheckTests/generic-bht-fail.pdl
+++ b/src/test/tests/typecheckTests/generic-bht-fail.pdl
@@ -1,3 +1,4 @@
+// generic-bht-fail.pdl
extern BHT {
method req(pc: int, skip: int, take: int): int;
method upd(pc: int, taken: bool): ();
diff --git a/src/test/tests/typecheckTests/generic-bht.pdl b/src/test/tests/typecheckTests/generic-bht.pdl
index a0ad485d..d107bdb8 100644
--- a/src/test/tests/typecheckTests/generic-bht.pdl
+++ b/src/test/tests/typecheckTests/generic-bht.pdl
@@ -1,3 +1,4 @@
+// generic-bht.pdl
extern BHT {
method req(pc: int, skip: int, take: int): int;
method upd(pc: int, taken: bool): ();
diff --git a/src/test/tests/typecheckTests/generic_adder.pdl b/src/test/tests/typecheckTests/generic_adder.pdl
index 9c60fce5..b3e69f88 100644
--- a/src/test/tests/typecheckTests/generic_adder.pdl
+++ b/src/test/tests/typecheckTests/generic_adder.pdl
@@ -1,3 +1,4 @@
+// generic_adder.pdl
def adder(x :int, y :int) :int
{
return x + y;
diff --git a/src/test/tests/typecheckTests/generic_adder_unsigned.pdl b/src/test/tests/typecheckTests/generic_adder_unsigned.pdl
index f9dec48d..a229e258 100644
--- a/src/test/tests/typecheckTests/generic_adder_unsigned.pdl
+++ b/src/test/tests/typecheckTests/generic_adder_unsigned.pdl
@@ -1,3 +1,4 @@
+// generic_adder_unsigned.pdl
def adder(x :uint, y :uint) :int
{
return cast(x + y, int);
diff --git a/src/test/tests/typecheckTests/generic_func_fail.pdl b/src/test/tests/typecheckTests/generic_func_fail.pdl
index cd562211..3e399db8 100644
--- a/src/test/tests/typecheckTests/generic_func_fail.pdl
+++ b/src/test/tests/typecheckTests/generic_func_fail.pdl
@@ -1,3 +1,4 @@
+// generic_func_fail.pdl
def indexing(x :int, y :int) :int<6>
{
return x{J - 1:0};
diff --git a/src/test/tests/typecheckTests/generic_funcs_pass.pdl b/src/test/tests/typecheckTests/generic_funcs_pass.pdl
index 9daaae43..a79f2930 100644
--- a/src/test/tests/typecheckTests/generic_funcs_pass.pdl
+++ b/src/test/tests/typecheckTests/generic_funcs_pass.pdl
@@ -1,3 +1,4 @@
+// generic_funcs_pass.pdl
def fixed_1(inpt :int<10>) :bool
{
shamt = cast(inpt{4:0}, uint<5>);
diff --git a/src/test/tests/typecheckTests/generic_funcs_passz3.pdl b/src/test/tests/typecheckTests/generic_funcs_passz3.pdl
index e33594cc..d8271fd3 100644
--- a/src/test/tests/typecheckTests/generic_funcs_passz3.pdl
+++ b/src/test/tests/typecheckTests/generic_funcs_passz3.pdl
@@ -1,3 +1,4 @@
+// generic_funcs_passz3.pdl
def extract(inpt :uint<32>) :bool
{
diff --git a/src/test/tests/typecheckTests/generic_unify_fail.pdl b/src/test/tests/typecheckTests/generic_unify_fail.pdl
index 26abcd7a..4858a1db 100644
--- a/src/test/tests/typecheckTests/generic_unify_fail.pdl
+++ b/src/test/tests/typecheckTests/generic_unify_fail.pdl
@@ -1,3 +1,4 @@
+// generic_unify_fail.pdl
def adder(x :int, y :int) :int
{
return x + y;
diff --git a/src/test/tests/typecheckTests/input-smt-fail.pdl b/src/test/tests/typecheckTests/input-smt-fail.pdl
index f9db0238..a5271630 100644
--- a/src/test/tests/typecheckTests/input-smt-fail.pdl
+++ b/src/test/tests/typecheckTests/input-smt-fail.pdl
@@ -1,3 +1,4 @@
+// input-smt-fail.pdl
pipe should_fail(input : int<32>)[]
{
if(input{1:1} == 1)
diff --git a/src/test/tests/typecheckTests/lock-acquire-in-split-case.pdl b/src/test/tests/typecheckTests/lock-acquire-in-split-case.pdl
index 06e2edb4..5a7e7c03 100644
--- a/src/test/tests/typecheckTests/lock-acquire-in-split-case.pdl
+++ b/src/test/tests/typecheckTests/lock-acquire-in-split-case.pdl
@@ -1,3 +1,4 @@
+// lock-acquire-in-split-case.pdl
pipe test22(input: uint<32>, randomBool: bool, randomBool2: bool)[rf: int<32>[5](Queue)] {
start(rf);
split {
diff --git a/src/test/tests/typecheckTests/lock-fail-acquire-before-access.pdl b/src/test/tests/typecheckTests/lock-fail-acquire-before-access.pdl
index c9072d52..36379eec 100644
--- a/src/test/tests/typecheckTests/lock-fail-acquire-before-access.pdl
+++ b/src/test/tests/typecheckTests/lock-fail-acquire-before-access.pdl
@@ -1,3 +1,4 @@
+// lock-fail-acquire-before-access.pdl
pipe test6(input: uint<32>)[rf: int<32>[5]] {
start(rf);
diff --git a/src/test/tests/typecheckTests/lock-fail-branch-acquire.pdl b/src/test/tests/typecheckTests/lock-fail-branch-acquire.pdl
index 16542ffe..b570f116 100644
--- a/src/test/tests/typecheckTests/lock-fail-branch-acquire.pdl
+++ b/src/test/tests/typecheckTests/lock-fail-branch-acquire.pdl
@@ -1,3 +1,4 @@
+// lock-fail-branch-acquire.pdl
pipe test1(input: int<32>)[rf: int<32>[5]] {
start(rf);
if (input{0:0} == 1) {
diff --git a/src/test/tests/typecheckTests/lock-fail-branch-release.pdl b/src/test/tests/typecheckTests/lock-fail-branch-release.pdl
index d101186f..29c69364 100644
--- a/src/test/tests/typecheckTests/lock-fail-branch-release.pdl
+++ b/src/test/tests/typecheckTests/lock-fail-branch-release.pdl
@@ -1,3 +1,4 @@
+// lock-fail-branch-release.pdl
pipe test3(input: int<32>)[rf: int<32>[5]] {
start(rf);
acquire(rf);
diff --git a/src/test/tests/typecheckTests/lock-fail-double-write.pdl b/src/test/tests/typecheckTests/lock-fail-double-write.pdl
index 8f506d7a..37f9cc44 100644
--- a/src/test/tests/typecheckTests/lock-fail-double-write.pdl
+++ b/src/test/tests/typecheckTests/lock-fail-double-write.pdl
@@ -1,3 +1,4 @@
+// lock-fail-double-write.pdl
pipe test3(input: uint<32>)[rf: int<32>[5], m:int<32>[5]] {
uint<5> rs1 = input{0:4};
uint<5> rs2 = input{5:9};
diff --git a/src/test/tests/typecheckTests/lock-fail-no-acquire-before-release.pdl b/src/test/tests/typecheckTests/lock-fail-no-acquire-before-release.pdl
index d3775348..e2b45ce8 100644
--- a/src/test/tests/typecheckTests/lock-fail-no-acquire-before-release.pdl
+++ b/src/test/tests/typecheckTests/lock-fail-no-acquire-before-release.pdl
@@ -1,3 +1,4 @@
+// lock-fail-no-acquire-before-release.pdl
pipe test7(input: int<32>)[rf: int<32>[5]] {
start(rf);
diff --git a/src/test/tests/typecheckTests/lock-fail-no-acquire-in-split-case.pdl b/src/test/tests/typecheckTests/lock-fail-no-acquire-in-split-case.pdl
index 053ddd4f..d9ab1a2d 100644
--- a/src/test/tests/typecheckTests/lock-fail-no-acquire-in-split-case.pdl
+++ b/src/test/tests/typecheckTests/lock-fail-no-acquire-in-split-case.pdl
@@ -1,3 +1,4 @@
+// lock-fail-no-acquire-in-split-case.pdl
pipe test22(input: int<32>, randomBool: bool, randomBool2: bool)[rf: int<32>[5]] {
start(rf);
split {
diff --git a/src/test/tests/typecheckTests/lock-fail-no-default-acquire-split.pdl b/src/test/tests/typecheckTests/lock-fail-no-default-acquire-split.pdl
index 84cb835e..adcaa388 100644
--- a/src/test/tests/typecheckTests/lock-fail-no-default-acquire-split.pdl
+++ b/src/test/tests/typecheckTests/lock-fail-no-default-acquire-split.pdl
@@ -1,3 +1,4 @@
+// lock-fail-no-default-acquire-split.pdl
pipe test21(input: int<32>, randomBool: bool, randomBool2: bool)[rf: int<32>[5]] {
start(rf);
split {
diff --git a/src/test/tests/typecheckTests/lock-fail-read-after-writes-branch.pdl b/src/test/tests/typecheckTests/lock-fail-read-after-writes-branch.pdl
index b9bb0746..02e6252b 100644
--- a/src/test/tests/typecheckTests/lock-fail-read-after-writes-branch.pdl
+++ b/src/test/tests/typecheckTests/lock-fail-read-after-writes-branch.pdl
@@ -1,3 +1,4 @@
+// lock-fail-read-after-writes-branch.pdl
//Expected Fail
pipe test3(input: uint<32>)[rf: int<32>[5]] {
uint<5> rs1 = input{0:4};
diff --git a/src/test/tests/typecheckTests/lock-fail-read-after-writes-release.pdl b/src/test/tests/typecheckTests/lock-fail-read-after-writes-release.pdl
index b9bb0746..fa654cd8 100644
--- a/src/test/tests/typecheckTests/lock-fail-read-after-writes-release.pdl
+++ b/src/test/tests/typecheckTests/lock-fail-read-after-writes-release.pdl
@@ -1,3 +1,4 @@
+// lock-fail-read-after-writes-release.pdl
//Expected Fail
pipe test3(input: uint<32>)[rf: int<32>[5]] {
uint<5> rs1 = input{0:4};
diff --git a/src/test/tests/typecheckTests/lock-fail-reads-after-writes.pdl b/src/test/tests/typecheckTests/lock-fail-reads-after-writes.pdl
index 6e2b7354..5f38657d 100644
--- a/src/test/tests/typecheckTests/lock-fail-reads-after-writes.pdl
+++ b/src/test/tests/typecheckTests/lock-fail-reads-after-writes.pdl
@@ -1,3 +1,4 @@
+// lock-fail-reads-after-writes.pdl
//Expected Fail
pipe test3(input: uint<32>)[rf: int<32>[5]] {
uint<5> rs1 = input{0:4};
diff --git a/src/test/tests/typecheckTests/lock-fail-reserve-without-write.pdl b/src/test/tests/typecheckTests/lock-fail-reserve-without-write.pdl
index fd00b84d..b3db7255 100644
--- a/src/test/tests/typecheckTests/lock-fail-reserve-without-write.pdl
+++ b/src/test/tests/typecheckTests/lock-fail-reserve-without-write.pdl
@@ -1,3 +1,4 @@
+// lock-fail-reserve-without-write.pdl
//Expected Success
pipe test3(input: uint<32>)[rf: int<32>[5], m:int<32>[5]] {
uint<5> rs1 = input{0:4};
diff --git a/src/test/tests/typecheckTests/lock-fail-top-branch.pdl b/src/test/tests/typecheckTests/lock-fail-top-branch.pdl
index b807b76b..e3671f83 100644
--- a/src/test/tests/typecheckTests/lock-fail-top-branch.pdl
+++ b/src/test/tests/typecheckTests/lock-fail-top-branch.pdl
@@ -1,3 +1,4 @@
+// lock-fail-top-branch.pdl
pipe test16(input: int<32>)[rf: int<32>[5]] {
int<32> y = 3<32>;
diff --git a/src/test/tests/typecheckTests/lock-fail-wrong-branch-acquire.pdl b/src/test/tests/typecheckTests/lock-fail-wrong-branch-acquire.pdl
index e5dbfe42..669c7685 100644
--- a/src/test/tests/typecheckTests/lock-fail-wrong-branch-acquire.pdl
+++ b/src/test/tests/typecheckTests/lock-fail-wrong-branch-acquire.pdl
@@ -1,3 +1,4 @@
+// lock-fail-wrong-branch-acquire.pdl
pipe test18(input: int<32>, randomBool: bool, randomBool2: bool)[rf: int<32>[5]] {
bool a = true;
bool b = false;
diff --git a/src/test/tests/typecheckTests/lock-release-OOO-different-address-fail.pdl b/src/test/tests/typecheckTests/lock-release-OOO-different-address-fail.pdl
index e3bb00ef..e1e91255 100644
--- a/src/test/tests/typecheckTests/lock-release-OOO-different-address-fail.pdl
+++ b/src/test/tests/typecheckTests/lock-release-OOO-different-address-fail.pdl
@@ -1,3 +1,4 @@
+// lock-release-OOO-different-address-fail.pdl
//Expected Fail
pipe test3(input: uint<32>)[rf: int<32>[5]] {
uint<5> rs1 = input{0:4};
diff --git a/src/test/tests/typecheckTests/lock-release-OOO-fail.pdl b/src/test/tests/typecheckTests/lock-release-OOO-fail.pdl
index 955f981a..311df403 100644
--- a/src/test/tests/typecheckTests/lock-release-OOO-fail.pdl
+++ b/src/test/tests/typecheckTests/lock-release-OOO-fail.pdl
@@ -1,3 +1,4 @@
+// lock-release-OOO-fail.pdl
//Expected Fail
pipe test3(input: uint<32>)[rf: int<32>[5]] {
uint<5> rs1 = input{0:4};
diff --git a/src/test/tests/typecheckTests/lock-release-OOO-nested-branches-fail.pdl b/src/test/tests/typecheckTests/lock-release-OOO-nested-branches-fail.pdl
index d4a17165..1ab2c657 100644
--- a/src/test/tests/typecheckTests/lock-release-OOO-nested-branches-fail.pdl
+++ b/src/test/tests/typecheckTests/lock-release-OOO-nested-branches-fail.pdl
@@ -1,3 +1,4 @@
+// lock-release-OOO-nested-branches-fail.pdl
//Expected Fail
pipe test3(input: uint<32>)[rf: int<32>[5]] {
uint<5> rs1 = input{0:4};
diff --git a/src/test/tests/typecheckTests/lock-release-OOO-nested-if-fail.pdl b/src/test/tests/typecheckTests/lock-release-OOO-nested-if-fail.pdl
index 23002833..e70f816b 100644
--- a/src/test/tests/typecheckTests/lock-release-OOO-nested-if-fail.pdl
+++ b/src/test/tests/typecheckTests/lock-release-OOO-nested-if-fail.pdl
@@ -1,3 +1,4 @@
+// lock-release-OOO-nested-if-fail.pdl
//Expected Fail
pipe test3(input: uint<32>)[rf: int<32>[5]] {
uint<5> rs1 = input{0:4};
diff --git a/src/test/tests/typecheckTests/lock-release-OOO-split-fail.pdl b/src/test/tests/typecheckTests/lock-release-OOO-split-fail.pdl
index dc2a0c1a..5812166e 100644
--- a/src/test/tests/typecheckTests/lock-release-OOO-split-fail.pdl
+++ b/src/test/tests/typecheckTests/lock-release-OOO-split-fail.pdl
@@ -1,3 +1,4 @@
+// lock-release-OOO-split-fail.pdl
//Expected Fail
pipe test3(input: uint<32>)[rf: int<32>[5]] {
uint<5> rs1 = input{0:4};
diff --git a/src/test/tests/typecheckTests/lock-success-read-write-order.pdl b/src/test/tests/typecheckTests/lock-success-read-write-order.pdl
index 1295499b..15a4015e 100644
--- a/src/test/tests/typecheckTests/lock-success-read-write-order.pdl
+++ b/src/test/tests/typecheckTests/lock-success-read-write-order.pdl
@@ -1,3 +1,4 @@
+// lock-success-read-write-order.pdl
//Expected Success
pipe test3(input: uint<32>)[rf: int<32>[5](RenameRF), m:int<32>[5](RenameRF)] {
uint<5> rs1 = input{4:0};
diff --git a/src/test/tests/typecheckTests/lock-tests-general.pdl b/src/test/tests/typecheckTests/lock-tests-general.pdl
index 29fb707c..25fd3649 100644
--- a/src/test/tests/typecheckTests/lock-tests-general.pdl
+++ b/src/test/tests/typecheckTests/lock-tests-general.pdl
@@ -1,3 +1,4 @@
+// lock-tests-general.pdl
// Expected Success
pipe test2(input: int<32>)[rf: int<32>[5](Queue)] {
start(rf);
diff --git a/src/test/tests/typecheckTests/lock-tests-specific.pdl b/src/test/tests/typecheckTests/lock-tests-specific.pdl
index bb57a4e3..291a863e 100644
--- a/src/test/tests/typecheckTests/lock-tests-specific.pdl
+++ b/src/test/tests/typecheckTests/lock-tests-specific.pdl
@@ -1,3 +1,4 @@
+// lock-tests-specific.pdl
//Expected Success
pipe test1(input: uint<32>)[rf: int<32>[5](Queue)] {
uint<5> rs1 = input{0:4};
diff --git a/src/test/tests/typecheckTests/lock-wellformedness-fail.pdl b/src/test/tests/typecheckTests/lock-wellformedness-fail.pdl
index 0c4980e3..e78a18ac 100644
--- a/src/test/tests/typecheckTests/lock-wellformedness-fail.pdl
+++ b/src/test/tests/typecheckTests/lock-wellformedness-fail.pdl
@@ -1,3 +1,4 @@
+// lock-wellformedness-fail.pdl
pipe test1(input: uint<32>)[rf: int<32>[5]] {
uint<5> rs2 = input{13:9};
if (input{0:0} == u1) {
diff --git a/src/test/tests/typecheckTests/missing-one-fail.pdl b/src/test/tests/typecheckTests/missing-one-fail.pdl
index 9ca9b1dd..fc03bda7 100644
--- a/src/test/tests/typecheckTests/missing-one-fail.pdl
+++ b/src/test/tests/typecheckTests/missing-one-fail.pdl
@@ -1,3 +1,4 @@
+// missing-one-fail.pdl
pipe quad_call(input: int<32>)[rf: int<32>[5]]
{
bool a = input{0:0};
diff --git a/src/test/tests/typecheckTests/more_generic_tests.pdl b/src/test/tests/typecheckTests/more_generic_tests.pdl
index ec97f65b..c352c9bf 100644
--- a/src/test/tests/typecheckTests/more_generic_tests.pdl
+++ b/src/test/tests/typecheckTests/more_generic_tests.pdl
@@ -1,3 +1,4 @@
+// more_generic_tests.pdl
// def error(inpt :int<10>) :bool
// {
// shamt = cast(inpt{4:0}, uint<5>);
diff --git a/src/test/tests/typecheckTests/nested_generic.pdl b/src/test/tests/typecheckTests/nested_generic.pdl
index ab13071b..a3d08079 100644
--- a/src/test/tests/typecheckTests/nested_generic.pdl
+++ b/src/test/tests/typecheckTests/nested_generic.pdl
@@ -1,3 +1,4 @@
+// nested_generic.pdl
def iden(a :int) :int
{
return a;
diff --git a/src/test/tests/typecheckTests/pipe-lock-fail1.pdl b/src/test/tests/typecheckTests/pipe-lock-fail1.pdl
index 7fc4e8a6..be5980c0 100644
--- a/src/test/tests/typecheckTests/pipe-lock-fail1.pdl
+++ b/src/test/tests/typecheckTests/pipe-lock-fail1.pdl
@@ -1,3 +1,4 @@
+// pipe-lock-fail1.pdl
pipe cache(addr: uint<5>, data: int<32>)[dmem: int<32>[5](Queue)]: bool {
//spec_check();
start(dmem);
diff --git a/src/test/tests/typecheckTests/pipe-lock-fail2.pdl b/src/test/tests/typecheckTests/pipe-lock-fail2.pdl
index 48878382..499d35a8 100644
--- a/src/test/tests/typecheckTests/pipe-lock-fail2.pdl
+++ b/src/test/tests/typecheckTests/pipe-lock-fail2.pdl
@@ -1,3 +1,4 @@
+// pipe-lock-fail2.pdl
pipe cache(addr: uint<5>, data: int<32>)[dmem: int<32>[5](Queue)]: bool {
//spec_check();
start(dmem);
diff --git a/src/test/tests/typecheckTests/pipe-lock.pdl b/src/test/tests/typecheckTests/pipe-lock.pdl
index 4883c71c..07de4c8b 100644
--- a/src/test/tests/typecheckTests/pipe-lock.pdl
+++ b/src/test/tests/typecheckTests/pipe-lock.pdl
@@ -1,3 +1,4 @@
+// pipe-lock.pdl
pipe cache(addr: uint<5>, data: int<32>)[dmem: int<32>[5](Queue)]: bool {
//spec_check();
start(dmem);
diff --git a/src/test/tests/typecheckTests/quad-call-disjoint.pdl b/src/test/tests/typecheckTests/quad-call-disjoint.pdl
index 90341ad5..9b9b4034 100644
--- a/src/test/tests/typecheckTests/quad-call-disjoint.pdl
+++ b/src/test/tests/typecheckTests/quad-call-disjoint.pdl
@@ -1,3 +1,4 @@
+// quad-call-disjoint.pdl
pipe quad_call(input: uint<32>)[rf: int<32>[5]] {
bool a = input{0:0};
bool b = input{1:1};
diff --git a/src/test/tests/typecheckTests/risc-pipe-spec-generic.pdl b/src/test/tests/typecheckTests/risc-pipe-spec-generic.pdl
index 74db42a1..d5d04ed4 100644
--- a/src/test/tests/typecheckTests/risc-pipe-spec-generic.pdl
+++ b/src/test/tests/typecheckTests/risc-pipe-spec-generic.pdl
@@ -1,3 +1,4 @@
+// risc-pipe-spec-generic.pdl
def mul(arg1: int<32>, arg2: int<32>, op: uint<3>): int<32> {
uint<32> mag1 = cast(mag(arg1), uint<32>);
uint<32> mag2 = cast(mag(arg2), uint<32>);
diff --git a/src/test/tests/typecheckTests/signedInts.pdl b/src/test/tests/typecheckTests/signedInts.pdl
index 66b38c4c..33bea80f 100644
--- a/src/test/tests/typecheckTests/signedInts.pdl
+++ b/src/test/tests/typecheckTests/signedInts.pdl
@@ -1,3 +1,4 @@
+// signedInts.pdl
//Expected Success
pipe signtest(input: int<8>)[]: bool {
int<8> x = input + 1<8>;
diff --git a/src/test/tests/typecheckTests/superscalar-fail.pdl b/src/test/tests/typecheckTests/superscalar-fail.pdl
index f66d71ec..b3b8a1d9 100644
--- a/src/test/tests/typecheckTests/superscalar-fail.pdl
+++ b/src/test/tests/typecheckTests/superscalar-fail.pdl
@@ -1,3 +1,4 @@
+// superscalar-fail.pdl
pipe pp(val: int<8>)[]:int<8>
{
int<8> a = val + 1<8>;
diff --git a/src/test/tests/typecheckTests/type-inference-basic-pass.pdl b/src/test/tests/typecheckTests/type-inference-basic-pass.pdl
index 42533572..82e6686f 100644
--- a/src/test/tests/typecheckTests/type-inference-basic-pass.pdl
+++ b/src/test/tests/typecheckTests/type-inference-basic-pass.pdl
@@ -1,3 +1,4 @@
+// type-inference-basic-pass.pdl
def helper1(a: int<32>, b:bool, c: String): int<32> {
d = a + 1<32>;
diff --git a/src/test/tests/typecheckTests/type-inference-bit-width-tests.pdl b/src/test/tests/typecheckTests/type-inference-bit-width-tests.pdl
index 5b5a1470..f51662da 100644
--- a/src/test/tests/typecheckTests/type-inference-bit-width-tests.pdl
+++ b/src/test/tests/typecheckTests/type-inference-bit-width-tests.pdl
@@ -1,3 +1,4 @@
+// type-inference-bit-width-tests.pdl
def helper1(a: int<32>, b:bool, c: String): int<32> {
d = a + 1;
diff --git a/src/test/tests/typecheckTests/type-inference-fail-base-type.pdl b/src/test/tests/typecheckTests/type-inference-fail-base-type.pdl
index 72889371..9cb9cdf4 100644
--- a/src/test/tests/typecheckTests/type-inference-fail-base-type.pdl
+++ b/src/test/tests/typecheckTests/type-inference-fail-base-type.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-base-type.pdl
pipe test1(input: int<32>)[rf: int<32>[32]] {
a = input + 2<32>;
if (a) {
diff --git a/src/test/tests/typecheckTests/type-inference-fail-bit-too-small-memAccessToosmall.pdl b/src/test/tests/typecheckTests/type-inference-fail-bit-too-small-memAccessToosmall.pdl
index dd313404..0843f4ff 100644
--- a/src/test/tests/typecheckTests/type-inference-fail-bit-too-small-memAccessToosmall.pdl
+++ b/src/test/tests/typecheckTests/type-inference-fail-bit-too-small-memAccessToosmall.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-bit-too-small-memAccessToosmall.pdl
pipe test6()[rf: int<32>[32]] {
int<64> a = 6 * 6;
diff --git a/src/test/tests/typecheckTests/type-inference-fail-bit-too-small-minus.pdl b/src/test/tests/typecheckTests/type-inference-fail-bit-too-small-minus.pdl
index 1149577f..d419151d 100644
--- a/src/test/tests/typecheckTests/type-inference-fail-bit-too-small-minus.pdl
+++ b/src/test/tests/typecheckTests/type-inference-fail-bit-too-small-minus.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-bit-too-small-minus.pdl
pipe test6()[] {
a = 6 - 6;
diff --git a/src/test/tests/typecheckTests/type-inference-fail-bit-too-small-mult.pdl b/src/test/tests/typecheckTests/type-inference-fail-bit-too-small-mult.pdl
index 737be003..e0a85b87 100644
--- a/src/test/tests/typecheckTests/type-inference-fail-bit-too-small-mult.pdl
+++ b/src/test/tests/typecheckTests/type-inference-fail-bit-too-small-mult.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-bit-too-small-mult.pdl
pipe test6()[] {
a = 6 * 6;
diff --git a/src/test/tests/typecheckTests/type-inference-fail-bit-too-small-plus.pdl b/src/test/tests/typecheckTests/type-inference-fail-bit-too-small-plus.pdl
index deabf477..8b0e693d 100644
--- a/src/test/tests/typecheckTests/type-inference-fail-bit-too-small-plus.pdl
+++ b/src/test/tests/typecheckTests/type-inference-fail-bit-too-small-plus.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-bit-too-small-plus.pdl
pipe test6()[] {
a = 6 + 6;
diff --git a/src/test/tests/typecheckTests/type-inference-fail-boolBinOp.pdl b/src/test/tests/typecheckTests/type-inference-fail-boolBinOp.pdl
index 3a302da6..974eca9f 100644
--- a/src/test/tests/typecheckTests/type-inference-fail-boolBinOp.pdl
+++ b/src/test/tests/typecheckTests/type-inference-fail-boolBinOp.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-boolBinOp.pdl
pipe test1(input: int<32>)[rf: int<32>[32]] {
a = input;
diff --git a/src/test/tests/typecheckTests/type-inference-fail-call-args.pdl b/src/test/tests/typecheckTests/type-inference-fail-call-args.pdl
index 379def08..61f88a55 100644
--- a/src/test/tests/typecheckTests/type-inference-fail-call-args.pdl
+++ b/src/test/tests/typecheckTests/type-inference-fail-call-args.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-call-args.pdl
pipe test10(a: bool, b: int<32>)[rf: int<32>[32]]: int<32> {
output(5<32>);
}
diff --git a/src/test/tests/typecheckTests/type-inference-fail-call.pdl b/src/test/tests/typecheckTests/type-inference-fail-call.pdl
index 6bc02fad..09d7de24 100644
--- a/src/test/tests/typecheckTests/type-inference-fail-call.pdl
+++ b/src/test/tests/typecheckTests/type-inference-fail-call.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-call.pdl
pipe test10(a: bool, b: int<32>)[rf: int<32>[32]]: int<32> {
output(5<32>);
}
diff --git a/src/test/tests/typecheckTests/type-inference-fail-eqBinOp.pdl b/src/test/tests/typecheckTests/type-inference-fail-eqBinOp.pdl
index 0d4bae05..bf44b5e9 100644
--- a/src/test/tests/typecheckTests/type-inference-fail-eqBinOp.pdl
+++ b/src/test/tests/typecheckTests/type-inference-fail-eqBinOp.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-eqBinOp.pdl
pipe test1(input: int<32>)[rf: int<32>[32]] {
a = true;
b = a == input;
diff --git a/src/test/tests/typecheckTests/type-inference-fail-func-app-arg.pdl b/src/test/tests/typecheckTests/type-inference-fail-func-app-arg.pdl
index c2bb8609..7c811ae6 100644
--- a/src/test/tests/typecheckTests/type-inference-fail-func-app-arg.pdl
+++ b/src/test/tests/typecheckTests/type-inference-fail-func-app-arg.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-func-app-arg.pdl
def func(a: bool, b: int<32>): bool {
return b;
}
diff --git a/src/test/tests/typecheckTests/type-inference-fail-funcApp.pdl b/src/test/tests/typecheckTests/type-inference-fail-funcApp.pdl
index f69d3e87..57730ebc 100644
--- a/src/test/tests/typecheckTests/type-inference-fail-funcApp.pdl
+++ b/src/test/tests/typecheckTests/type-inference-fail-funcApp.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-funcApp.pdl
def func(a: bool, b: int<32>): bool {
return b;
}
diff --git a/src/test/tests/typecheckTests/type-inference-fail-numBinOp.pdl b/src/test/tests/typecheckTests/type-inference-fail-numBinOp.pdl
index 3096b3d3..20697e4d 100644
--- a/src/test/tests/typecheckTests/type-inference-fail-numBinOp.pdl
+++ b/src/test/tests/typecheckTests/type-inference-fail-numBinOp.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-numBinOp.pdl
pipe test1(input: int<32>)[rf: int<32>[32]] {
a = true;
b = a + a;
diff --git a/src/test/tests/typecheckTests/type-inference-fail-ternary.pdl b/src/test/tests/typecheckTests/type-inference-fail-ternary.pdl
index e635be6e..f1f6f027 100644
--- a/src/test/tests/typecheckTests/type-inference-fail-ternary.pdl
+++ b/src/test/tests/typecheckTests/type-inference-fail-ternary.pdl
@@ -1,3 +1,4 @@
+// type-inference-fail-ternary.pdl
pipe test1(input: int<32>)[rf: int<32>[32]] {
a = true;
b = input;
diff --git a/src/test/tests/typecheckTests/unlocked-mem-1.pdl b/src/test/tests/typecheckTests/unlocked-mem-1.pdl
index 5373d6b5..f0098c84 100644
--- a/src/test/tests/typecheckTests/unlocked-mem-1.pdl
+++ b/src/test/tests/typecheckTests/unlocked-mem-1.pdl
@@ -1,3 +1,4 @@
+// unlocked-mem-1.pdl
//Expected Success
pipe unlock(input: int<32>)[rf: int<32>[5]] {
spec_check();
diff --git a/src/test/tests/typecheckTests/unlocked-mem-fail-1.pdl b/src/test/tests/typecheckTests/unlocked-mem-fail-1.pdl
index e2eaeb24..727e8714 100644
--- a/src/test/tests/typecheckTests/unlocked-mem-fail-1.pdl
+++ b/src/test/tests/typecheckTests/unlocked-mem-fail-1.pdl
@@ -1,3 +1,4 @@
+// unlocked-mem-fail-1.pdl
//Expected Success
pipe unlock(input: int<32>)[rf: int<32>[5]] {
start(rf);
diff --git a/src/test/tests/typecheckTests/unlocked-mem-fail.pdl b/src/test/tests/typecheckTests/unlocked-mem-fail.pdl
index e6c96a44..68b07011 100644
--- a/src/test/tests/typecheckTests/unlocked-mem-fail.pdl
+++ b/src/test/tests/typecheckTests/unlocked-mem-fail.pdl
@@ -1,3 +1,4 @@
+// unlocked-mem-fail.pdl
//Expected Fail
pipe unlock(input: int<32>)[rf: int<32>[5]] {
spec_check();
diff --git a/src/test/tests/typecheckTests/unlocked-mem.pdl b/src/test/tests/typecheckTests/unlocked-mem.pdl
index 1ee5d08c..7d0082fd 100644
--- a/src/test/tests/typecheckTests/unlocked-mem.pdl
+++ b/src/test/tests/typecheckTests/unlocked-mem.pdl
@@ -1,3 +1,4 @@
+// unlocked-mem.pdl
//Expected Success
pipe unlock(input: int<32>)[rf: int<32>[5]] {
start(rf);
diff --git a/src/test/tests/typecheckTests/unlocked-reg.pdl b/src/test/tests/typecheckTests/unlocked-reg.pdl
index dbf6b2e0..104887b8 100644
--- a/src/test/tests/typecheckTests/unlocked-reg.pdl
+++ b/src/test/tests/typecheckTests/unlocked-reg.pdl
@@ -1,3 +1,4 @@
+// unlocked-reg.pdl
//Expected Success
pipe unlock(tinput: int<32>)[rf: int<32>[0]] {
spec_check();