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();