diff --git a/misc/fixed_new.lua b/misc/fixed_new.lua index 44db979..ef2b248 100644 --- a/misc/fixed_new.lua +++ b/misc/fixed_new.lua @@ -119,6 +119,11 @@ function fixed.parameter( name, ty ) return fixed.new{kind="parameter",name=name, type=ty,inputs={},loc=getloc()} end +function fixed.readGlobal( glob ) + err( R.isGlobal(glob),"fixed.readGlobal: global should be a rigel global" ) + return fixed.new{ kind="readGlobal", global=glob, type=glob.type, inputs={}, loc=getloc() } +end + function fixed.constant( value ) err(type(value)=="number" or type(value)=="boolean","fixed.constant must be number or bool") @@ -370,6 +375,8 @@ end function fixedNewASTFunctions:toSystolic() local instances = {} local resetStats = {} + local sideChannels = {} + local globals = {} local inp local res = self:visitEach( function( n, args ) @@ -505,8 +512,12 @@ function fixedNewASTFunctions:toSystolic() res = S.cast(res, n:underlyingType() ) elseif n.kind=="addMSBs" or n.kind=="removeMSBs" then res = S.cast(args[1], n:underlyingType() ) + elseif n.kind=="readGlobal" then + res = S.readSideChannel(n.global.systolicValue) + sideChannels[n.global.systolicValue] = 1 + globals[n.global] = 1 else - print(n.kind) + print("fixed_new NYI:",n.kind) assert(false) end @@ -522,7 +533,7 @@ function fixedNewASTFunctions:toSystolic() end --end - return res, inp, instances, resetStats + return res, inp, instances, resetStats, sideChannels, globals end fixed.hists = {} @@ -535,31 +546,34 @@ function fixedNewASTFunctions:toRigelModule(name,X) assert(type(name)=="string") assert(X==nil) - local out, inp, instances, resetStats = self:toSystolic() + local out, inp, instances, resetStats, sideChannels, globals = self:toSystolic() err(out.type==self.type,"toRigelModule type mismatch "..tostring(out.type).." "..tostring(self.type)) local tfn - local res = {kind="fixed", inputType=inp.type, outputType=out.type,delay=0, sdfInput={{1,1}},sdfOutput={{1,1}}} + local res = {kind="fixed", inputType=inp.type, outputType=out.type,delay=0, sdfInput={{1,1}},sdfOutput={{1,1}}, stateful=false, globals=globals} if terralib~=nil then res.terraModule=fixedTerra.toDarkroom(self,name) end res.name = name - local sys = Ssugar.moduleConstructor(name) - for _,v in ipairs(instances) do sys:add(v) end - local CE = S.CE("process_CE") - sys:addFunction( S.lambda("process",inp,out,"process_output",nil,nil,CE ) ) - - if #resetStats>0 then - res.stateful=true - sys:addFunction( S.lambda("reset",S.parameter("r",types.null()),nil,"ro",resetStats,S.parameter("reset",types.bool())) ) - else - res.stateful=false + function res.makeSystolic() + local sys = Ssugar.moduleConstructor(name) + for _,v in ipairs(instances) do sys:add(v) end + for k,_ in pairs(sideChannels) do sys:addSideChannel(k) end + local CE = S.CE("process_CE") + sys:addFunction( S.lambda("process",inp,out,"process_output",nil,nil,CE ) ) + + if #resetStats>0 then + res.stateful=true + sys:addFunction( S.lambda("reset",S.parameter("r",types.null()),nil,"ro",resetStats,S.parameter("reset",types.bool())) ) + else + res.stateful=false + end + + sys:complete() + + return sys end - - sys:complete() - - res.systolicModule = sys return R.newFunction(res) end diff --git a/modules/soc.lua b/modules/soc.lua index 4b4f091..35b09b2 100644 --- a/modules/soc.lua +++ b/modules/soc.lua @@ -41,7 +41,7 @@ SOC.axiRegs = J.memoize(function(tab,port) J.err( type(k)=="string", "axiRegs: key must be string" ) J.err( types.isType(v[1]), "axiRegs: first key must be type" ) J.err( v[1]:toCPUType()==v[1], "axiRegs: NYI - input type must be a CPU type" ) - J.err( v[1]:verilogBits()%32==0, "axiRegs: NYI - input type must be 32bit aligned") + J.err( v[1]:verilogBits()<32 or v[1]:verilogBits()%32==0, "axiRegs: NYI - input type must be 32bit aligned") v[1]:checkLuaValue(v[2]) NREG = NREG + (v[1]:verilogBits()/32) @@ -1241,7 +1241,8 @@ SOC.readBurst = J.memoize(function(filename,W,H,ty,V,X) J.err( types.isType(ty), "readBurst: type must be type") J.err(ty:verilogBits()%8==0,"NYI - readBurst currently required byte-aligned data") local nbytes = W*H*(ty:verilogBits()/8) - J.err( nbytes%128==0,"NYI - readBurst requires 128 aligned size" ) + J.err( nbytes%8==0,"NYI - readBurst requires 8-byte aligned size" ) + --J.err( nbytes%128==0,"NYI - readBurst requires 128-byte aligned size" ) J.err( V==nil or type(V)=="number", "readBurst: V must be number or nil") if V==nil then V=0 end J.err(X==nil, "readBurst: too many arguments") @@ -1255,7 +1256,15 @@ SOC.readBurst = J.memoize(function(filename,W,H,ty,V,X) globalMetadata["MAXI"..SOC.currentMAXIReadPort.."_read_address"] = SOC.currentAddr local inp = R.input(R.HandshakeTrigger) - local out = SOC.axiBurstReadN(filename,nbytes,SOC.currentMAXIReadPort,SOC.currentAddr)(inp) + + local readBytes = J.upToNearest(128,nbytes) + local out = SOC.axiBurstReadN(filename,readBytes,SOC.currentMAXIReadPort,SOC.currentAddr)(inp) + + if readBytes~=nbytes then + out = RM.makeHandshake(C.arrayop(types.bits(64),1))(out) + out = RM.liftHandshake(RM.liftDecimate(RM.cropSeq(types.bits(64),readBytes/8,1,1,0,(readBytes-nbytes)/8,0,0)))(out) + out = RM.makeHandshake(C.index(types.array2d(types.bits(64),1),0))(out) + end local outBits = ty:verilogBits()*math.max(V,1) @@ -1282,7 +1291,7 @@ SOC.readBurst = J.memoize(function(filename,W,H,ty,V,X) local res = RM.lambda("ReadBurst_Wf"..W.."_H"..H.."_v"..V.."_port"..SOC.currentMAXIReadPort.."_addr"..SOC.currentAddr.."_"..tostring(ty),inp,out,nil,nil,nil,globalMetadata) SOC.currentMAXIReadPort = SOC.currentMAXIReadPort+1 - SOC.currentAddr = SOC.currentAddr+nbytes + SOC.currentAddr = SOC.currentAddr+readBytes return res end) @@ -1348,7 +1357,7 @@ SOC.writeBurst = J.memoize(function(filename,W,H,ty,V,X) J.err( types.isType(ty), "writeBurst: type must be type") J.err(ty:verilogBits()%8==0,"NYI - writeBurst currently required byte-aligned data") local nbytes = W*H*(ty:verilogBits()/8) - J.err( nbytes%128==0,"NYI - writeBurst requires 128 byte aligned size (input bytes is: "..nbytes..")" ) + J.err( nbytes%8==0,"NYI - writeBurst requires 8-byte aligned size (input bytes is: "..nbytes..")" ) J.err( V==nil or type(V)=="number", "writeBurst: V must be number or nil") if V==nil then V=1 end J.err(X==nil, "writeBurst: too many arguments") @@ -1382,8 +1391,15 @@ SOC.writeBurst = J.memoize(function(filename,W,H,ty,V,X) else out = RM.makeHandshake(C.cast(itype,types.bits(64)))(out) end + + local writeBytes = J.upToNearest(128,nbytes) + if writeBytes~=nbytes then + out = RM.makeHandshake(C.arrayop(types.bits(64),1))(out) + out = RM.liftHandshake(RM.padSeq(types.bits(64),nbytes/8,1,1,0,(writeBytes-nbytes)/8,0,0,0))(out) + out = RM.makeHandshake(C.index(types.array2d(types.bits(64),1),0))(out) + end - out = SOC.axiBurstWriteN(filename,nbytes,SOC.currentMAXIWritePort,SOC.currentAddr)(out) + out = SOC.axiBurstWriteN(filename,writeBytes,SOC.currentMAXIWritePort,SOC.currentAddr)(out) local res = RM.lambda("WriteBurst_W"..W.."_H"..H.."_v"..V.."_port"..SOC.currentMAXIWritePort.."_addr"..SOC.currentAddr.."_"..tostring(ty),inp,out,nil,nil,nil,globalMetadata) diff --git a/platform/verilatorSOC/harness.cpp b/platform/verilatorSOC/harness.cpp index 1765ded..aac2d4d 100644 --- a/platform/verilatorSOC/harness.cpp +++ b/platform/verilatorSOC/harness.cpp @@ -201,8 +201,10 @@ int main(int argc, char** argv) { bool doneBitSet = false; unsigned int cyclesToDoneSignal = -1; + int cooldownCycles = 1000; // run for a few extra cycles after the done bit is set, to make sure nothing crazy happens + bool cooldownPrinted = false; - while (!Verilated::gotFinish() && cycle0)) { if(CLK){ if(verbose){ std::cout << "------------------------------------ START CYCLE " << cycle << ", ROUND " << round << " (" << ((float)cycle/(float)(simCycles+simCyclesSlack))*100.f << "%) -----------------------" << std::endl;} // feed data in @@ -241,6 +243,15 @@ int main(int argc, char** argv) { doneBitSet=false; } } + + if(doneBitSet && cooldownCycles>0){ + if(!cooldownPrinted){ + printf("Start Cooldown\n"); + cooldownPrinted = true; + } + + cooldownCycles--; + } int pct = (cycle*100)/totalCycles; if(pct>lastPct){ diff --git a/src/systolic.lua b/src/systolic.lua index a0f8c38..e7d7554 100644 --- a/src/systolic.lua +++ b/src/systolic.lua @@ -1311,6 +1311,7 @@ function systolicASTFunctions:toVerilog( module ) elseif n.kind=="vectorSelect" then finalResult = "(("..args[1]..")?("..args[2].."):("..args[3].."))" elseif n.kind=="readSideChannel" then + J.err( module.sideChannels[n.sideChannel]~=nil,"readSideChannel: side channel named '"..n.sideChannel.name.."' is not attached to module?") finalResult = n.sideChannel.name else print(n.kind) diff --git a/src/types.lua b/src/types.lua index 5c10a61..612bf46 100644 --- a/src/types.lua +++ b/src/types.lua @@ -634,6 +634,10 @@ function TypeFunctions:valueToHex(v) elseif self:isUint() then local res = string.format("%0"..tostring(self.precision/4).."x",v) return res + elseif self:isInt() then + err(v>=0,"NYI - signed int <0") + local res = string.format("%0"..tostring(self.precision/4).."x",v) + return res else err(false,":valueToHex NYI - "..tostring(self)) end