Skip to content
Permalink
Browse files

Pulpino (#141)

* progress on pulpino noc integration. HandshakeVR fixes in AXI.
  • Loading branch information...
jameshegarty committed Apr 2, 2019
1 parent cfddeab commit ba4691bd904a12c9196800191c08b8184dcbc114
@@ -1,3 +1,9 @@
[submodule "modules/bsg_ip_cores"]
path = modules/bsg_ip_cores
url = https://bitbucket.org/taylor-bsg/bsg_ip_cores.git
[submodule "modules/axi_node"]
path = modules/axi_node
url = https://github.com/pulp-platform/axi_node.git
[submodule "modules/axi_size_conv"]
path = modules/axi_size_conv
url = https://github.com/pulp-platform/axi_size_conv.git
@@ -1 +1 @@
82961
84049
@@ -1 +1 @@
524293
524295
@@ -1 +1 @@
1037
1039
@@ -1 +1 @@
3889
3891
@@ -1,8 +1,7 @@
BUILDDIR ?= out

# soc_flipWrite.lua
SRCS_SOC = soc_simple.lua soc_simple_uniform.lua soc_2in.lua soc_convgen.lua soc_convgenTaps.lua soc_flip.lua soc_15x15.lua soc_15x15x15.lua soc_flipWrite.lua soc_regin.lua soc_regout.lua soc_convtest.lua soc_read.lua soc_redu1024.lua soc_redu2048.lua soc_redu4096.lua soc_redu8192.lua soc_redu16384.lua soc_redu32768.lua soc_sort.lua soc_filterseq.lua soc_filterseq8.lua soc_unaligned.lua soc_underflow.lua soc_parread.lua soc_tokencounter.lua soc_arbiter.lua soc_readlen.lua

SRCS_SOC = soc_simple.lua soc_simple_uniform.lua soc_2in.lua soc_convgen.lua soc_convgenTaps.lua soc_flip.lua soc_15x15.lua soc_15x15x15.lua soc_flipWrite.lua soc_regin.lua soc_regout.lua soc_convtest.lua soc_read.lua soc_redu1024.lua soc_redu2048.lua soc_redu4096.lua soc_redu8192.lua soc_redu16384.lua soc_redu32768.lua soc_sort.lua soc_filterseq.lua soc_filterseq8.lua soc_unaligned.lua soc_underflow.lua soc_parread.lua soc_tokencounter.lua soc_arbiter.lua soc_readlen.lua

VERILATOR_SOC = $(patsubst %.lua,$(BUILDDIR)/%.verilatorSOC.bit,$(SRCS_SOC))
VERILATOR_SOC += $(patsubst %.lua,$(BUILDDIR)/%.verilatorSOC.raw,$(SRCS_SOC))
@@ -20,6 +19,15 @@ BJUMP += $(patsubst %.lua,$(BUILDDIR)/%.verilatorSOC.correct.txt,$(SRCS_BJUMP))
BJUMP += $(patsubst %.lua,$(BUILDDIR)/%.verilatorSOC.regcorrect.txt,$(SRCS_BJUMP))
BJUMP += $(patsubst %.lua,$(BUILDDIR)/%.verilatorSOC.cyclescorrect.txt,$(SRCS_BJUMP))

SRCS_PULPINO = soc_pulpino_noc.lua

PULPINO = $(patsubst %.lua,$(BUILDDIR)/%.verilatorSOC.bit,$(SRCS_PULPINO))
PULPINO += $(patsubst %.lua,$(BUILDDIR)/%.verilatorSOC.raw,$(SRCS_PULPINO))
PULPINO += $(patsubst %.lua,$(BUILDDIR)/%.verilatorSOC.bmp,$(SRCS_PULPINO))
PULPINO += $(patsubst %.lua,$(BUILDDIR)/%.verilatorSOC.correct.txt,$(SRCS_PULPINO))
PULPINO += $(patsubst %.lua,$(BUILDDIR)/%.verilatorSOC.regcorrect.txt,$(SRCS_PULPINO))
PULPINO += $(patsubst %.lua,$(BUILDDIR)/%.verilatorSOC.cyclescorrect.txt,$(SRCS_PULPINO))

ZU9VIVADOSOCBITS = $(patsubst %.lua,$(BUILDDIR)/%.zu9vivadoSOC.bit,$(SRCS_SOC))

ZU9VIVADOSOC = $(ZU9VIVADOSOCBITS)
@@ -29,7 +37,7 @@ ZU9VIVADOSOC += $(patsubst %.lua,$(BUILDDIR)/%.zu9vivadoSOC.correct.txt,$(SRCS_S
ZU9VIVADOSOC += $(patsubst %.lua,$(BUILDDIR)/%.zu9vivadoSOC.regcorrect.txt,$(SRCS_SOC))

SRCS = $(wildcard *.lua)
SRCS := $(filter-out pyramid_core.lua harris_core.lua sift_core.lua sift_core_hw.lua campipe_core.lua descriptor_core.lua stereo_core.lua stereo_tr_core.lua lk_core.lua lk_tr_core.lua $(SRCS_BJUMP) $(SRCS_SOC),$(SRCS))
SRCS := $(filter-out pyramid_core.lua harris_core.lua sift_core.lua sift_core_hw.lua campipe_core.lua descriptor_core.lua stereo_core.lua stereo_tr_core.lua lk_core.lua lk_tr_core.lua $(SRCS_BJUMP) $(SRCS_PULPINO) $(SRCS_SOC),$(SRCS))
METADATA = $(patsubst %.lua,$(BUILDDIR)/%.metadata.lua,$(SRCS))

RIGEL_VERILATOR_INCLUDE ?= $(shell pkg-config --variable=includedir verilator)
@@ -264,6 +272,10 @@ bjump: $(BJUMP)
touch $(BUILDDIR)/bjump_done.txt
date

pulpino: $(PULPINO)
touch $(BUILDDIR)/pulpino_done.txt
date

isim: $(ISIM)

stats: $(STATS)
@@ -0,0 +1,44 @@
local R = require "rigel"
local Pulpino = require "pulpino"
local J = require "common"
local Zynq = require "zynq"
local SOC = require "soc"
local SDF = require "sdf"
local C = require "examplescommon"
local G = require "generators"
local types = require "types"
local harness = require "harnessSOC"

zynqNOC = Zynq.SimpleNOC():instantiate("ZynqNOC")
zynqNOC.extern=true

local noc = Pulpino.AXIInterconnect(3,2):instantiate("pulpinoNOC")
local regs = SOC.axiRegs( {}, SDF{1,(128*64)/8}, noc.readSource1, noc.readSink1, noc.writeSource1, noc.writeSink1 ):instantiate("regs")

local IP_plus200 = C.linearPipeline({G.AXIReadBurst{ "frame_128.raw", {128,32}, types.u8, 8, noc.read1, SDF{1,(128*32)/8} },G.HS{G.Map{G.Add{200}}},G.AXIWriteBurst{"out/soc_simple",noc.write1}},"IP_plus100")

local Inv = G.Module{"Inv",types.u(8),SDF{1,1},function(i) return G.Sub(R.c(255,types.u8),i) end}

local IP_inv = C.linearPipeline({G.AXIReadBurst{ "frame_128.raw", {128,32}, types.u8, 8, noc.read2, SDF{1,(128*32)/8} },G.HS{G.Map{Inv}},G.AXIWriteBurst{"out/soc_simple",noc.write2}},"IP_inv")

local PTop = G.Module{"PTop",
function(i)
local st = G.FanOut{2}(regs:start(i))
local done_plus200, done_inv = IP_plus200(st[0]), IP_inv(st[1])
done_plus200 = G.FIFO{128}(done_plus200)
done_inv = G.FIFO{128}(done_inv)

-- zynq noc master ports are 32bit, but our slave is 64, so resize
local noc_read0_32 = Pulpino.AXIReadBusResize(noc.read0,32,64)
local noc_write0_32 = Pulpino.AXIWriteBusResize(noc.write0,32,64)

return R.statements{
regs:done(G.FanIn(done_plus200,done_inv)),
noc:readSink0(zynqNOC:read(noc:readSource0())),
noc:writeSink0(zynqNOC:write(noc:writeSource0())),
zynqNOC:readSink(noc_read0_32(zynqNOC:readSource())),
zynqNOC:writeSink(noc_write0_32(zynqNOC:writeSource()))
}
end}

harness(PTop)
@@ -13,7 +13,7 @@ local function vrange(ty,idx,base)
return "["..tostring(vbase(ty,idx+1)+base-1)..":"..tostring(vbase(ty,idx)+base).."]"
end

AXI.ReadAddress = types.Handshake(types.tuple{
AXI.ReadAddressTuple = types.tuple{
types.bits(32), -- ARADDR
types.bits(4), -- ARLEN
types.bits(2), -- ARSIZE
@@ -22,7 +22,9 @@ AXI.ReadAddress = types.Handshake(types.tuple{
types.bits(3), -- ARPROT
types.bits(4), -- ARCACHE
types.bool() -- ARLOCK
})
}

AXI.ReadAddress = types.HandshakeVR(AXI.ReadAddressTuple)

AXI.ReadAddress64 = AXI.ReadAddress
AXI.ReadAddressIdx={araddr=0,arlen=1,arsize=2,arburst=3,arid=4,arprot=5,arcache=6,arlock=7}
@@ -31,7 +33,7 @@ for k,v in pairs(AXI.ReadAddressIdx) do AXI.ReadAddressVSelect[k] = vrange(types

AXI.ReadData = J.memoize(function(bits)
assert(type(bits)=="number")
return types.Handshake(types.tuple{
return types.HandshakeVR(types.tuple{
types.bits(bits), -- RDATA
types.bool(), -- RLAST
types.bits(2), -- RRESP
@@ -71,8 +73,9 @@ end)

AXI.WriteDataIdx = {wdata=0,wstrb=1,wlast=2,wid=3}

AXI.WriteIssue = J.memoize(function(bits) return types.HandshakeTuple{AXI.WriteAddress,AXI.WriteData(bits)} end)
AXI.WriteIssue = J.memoize(function(bits) return types.HandshakeVRTuple{AXI.WriteAddress,AXI.WriteData(bits)} end)
AXI.WriteIssue64 = AXI.WriteIssue(64)
AXI.WriteIssue32 = AXI.WriteIssue(32)

-- verilog bit select
AXI.WriteIssueVSelect = J.memoize(function(bits)
@@ -84,13 +87,14 @@ end)

AXI.WriteResponse = J.memoize(function(bits)
assert(type(bits)=="number")
return types.Handshake(types.tuple{
return types.HandshakeVR(types.tuple{
types.bits(2), -- BRESP
types.bits(12) -- BID
})
end)

AXI.WriteResponse64 = AXI.WriteResponse(64)
AXI.WriteResponse32 = AXI.WriteResponse(32)

AXI.WriteResponseIdx = {bresp=0,bid=1}
AXI.WriteResponseVSelect = J.memoize(function(bits)
Submodule axi_node added at 6338af
Submodule axi_size_conv added at 48888f
@@ -1024,10 +1024,17 @@ C.fifo = memoize(function(ty,size,nostall,csimOnly,VRLoad,X)
err( csimOnly==nil or type(csimOnly)=="boolean", "C.fifo: csimOnly must be boolean")
err( VRLoad==nil or type(VRLoad)=="boolean","C.fifo: VRLoad should be boolean")
err( X==nil, "C.fifo: too many arguments" )
err( ty~=types.null(), "C.fifo: NYI - FIFO of 0 bit type" )
--err( ty~=types.null(), "C.fifo: NYI - FIFO of 0 bit type" )

local inp = R.input(R.Handshake(ty))
local regs = {R.instantiate("f1",RM.fifo(ty,size,nostall,nil,nil,nil,csimOnly,VRLoad))}
local inp, regs
if ty:verilogBits()==0 then
inp = R.input(types.HandshakeTrigger)
regs = {R.instantiate("f1",RM.triggerFIFO())}
else
inp = R.input(R.Handshake(ty))
regs = {R.instantiate("f1",RM.fifo(ty,size,nostall,nil,nil,nil,csimOnly,VRLoad))}
end

local st = R.applyMethod("s1",regs[1],"store",inp)
local ld = R.applyMethod("l1",regs[1],"load")
return RM.lambda("C_FIFO_"..tostring(ty).."_size"..tostring(size).."_nostall"..tostring(nostall).."_VR"..tostring(VRLoad), inp, R.statements{ld,st}, regs, "C.fifo", {size=size} )
@@ -1677,6 +1684,7 @@ function C.linearPipeline( t, modulename, rate, instances, X )
err(type(t)=="table" and J.keycount(t)==#t, "C.linearPipeline: input must be array")
for k,v in ipairs(t) do err(R.isFunction(v), "C.linearPipeline: input must be table of Rigel modules (idx "..k..")") end

err( R.isPlainFunction(t[1]) or R.isInstanceCallsite(t[1]),"C.linearPipeline: first function in pipe must have known type (ie must not be a generator). fn: "..tostring(t[1]) )
local inp = R.input( t[1].inputType, rate )
local out = inp

@@ -1689,12 +1697,14 @@ end

-- Hacky module for internal use: just convert a Handshake to a HandshakeFramed
C.handshakeToHandshakeFramed = memoize(
function(A,mixed,dims,X)
function( A, mixed, dims, X )
err( type(dims)=="table", "handshakeToHandshakeFramed: dims should be table")
err( type(mixed)=="boolean", "handshakeToHandshakeFramed: mixed should be bool")
assert(X==nil)
err(R.isHandshake(A),"handshakeToHandshakeFramed: input should be handshake")
local res = {inputType=A,outputType=types.HandshakeFramed(A.params.A,mixed,dims),sdfInput=SDF{1,1},sdfOutput=SDF{1,1},stateful=false}
res.name=J.sanitize("HandshakeToHandshakeFramed_"..tostring(A))
local nm = "HandshakeToHandshakeFramed_"..tostring(A).."_mixed"..tostring(mixed).."_dims"..tostring(dims)
res.name=J.sanitize(nm)

function res.makeSystolic()
local sm = Ssugar.moduleConstructor(res.name):onlyWire(true)
@@ -2154,5 +2164,30 @@ C.VerilogFile = J.memoize(function(filename,dependencyList)

return R.newModule(J.sanitize(filename),{process=res},false,makeSystolic,nil)
end)

-- you should only use this if it's safe! (on the output of fns)
C.VRtoRVRaw = J.memoize(function(A)
err( types.isBasic(A), "expected basic type" )
local res = {inputType=types.HandshakeVR(A),outputType=types.Handshake(A),sdfInput=SDF{1,1},sdfOutput=SDF{1,1},stateful=false}
res.name = J.sanitize("VRtoRVRaw_"..tostring(A))

function res.makeSystolic()
local sm = Ssugar.moduleConstructor(res.name):onlyWire(true)
local r = S.parameter("ready_downstream",types.bool())
sm:addFunction( S.lambda("ready", r, r, "ready") )
local I = S.parameter("process_input", R.lower(types.Handshake(A)) )
sm:addFunction( S.lambda("process",I,I,"process_output") )
return sm
end

return rigel.newFunction(res)
end)

-- fn should be HSVR, and this wraps to return a plain HS function
C.LiftVRtoRV = J.memoize(function(fn)
err( types.isHandshakeVR(fn.inputType), "LiftVRtoRV: fn input should be HandshakeVR, but is: "..tostring(fn.inputType) )
err( types.isHandshakeVR(fn.outputType), "LiftVRtoRV: fn output should be HandshakeVR" )
return C.linearPipeline({C.fifo(types.extractData(fn.inputType),128,nil,nil,true),fn,C.VRtoRVRaw(types.extractData(fn.outputType))},"LiftVRtoRV_"..fn.name)
end)

return C
@@ -84,8 +84,13 @@ end)

generators.FanIn = R.newFunctionGenerator("generators","FanIn",{"type","rate"},{"bool"},
function(args)
J.err( R.isHandshakeTuple(args.type), "FanIn: expected handshake tuple input, but is: "..tostring(args.type))
return RM.packTuple(args.type.params.list,args.bool)
if R.isHandshakeTuple(args.type) then
return RM.packTuple(args.type.params.list,args.bool)
elseif R.isHandshakeTriggerArray(args.type) then
return RM.packTuple(J.broadcast(types.null(),args.type.params.W*args.type.params.H),args.bool)
else
J.err(false, "FanIn: expected handshake tuple input, but is: "..tostring(args.type))
end
end)

generators.FIFO = R.newFunctionGenerator("generators","FIFO",{"type","number","rate"},{"bool"},
Oops, something went wrong.

0 comments on commit ba4691b

Please sign in to comment.
You can’t perform that action at this time.