Skip to content

Commit

Permalink
removed analytic fifo sizing to remove the dependency from the fifo s…
Browse files Browse the repository at this point in the history
…izing PR
  • Loading branch information
lstasytis committed Sep 18, 2024
1 parent 337dced commit fc901e5
Showing 1 changed file with 6 additions and 332 deletions.
338 changes: 6 additions & 332 deletions src/finn/custom_op/fpgadataflow/streamingdatawidthconverter.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,6 @@ def get_folded_output_shape(self, ind=0):
new_shape.append(i)
new_shape.append(int(ochannels // oelems))
new_shape.append(oelems)

# reintroduce the resizing, this is the true final shape
# we expect from the RTL
# new_shape[-1] += resize

return tuple(new_shape)

def get_number_output_values(self):
Expand Down Expand Up @@ -220,337 +215,16 @@ def execute_node(self, context, graph):


def get_exp_cycles(self):

out_shape = self.get_nodeattr("out_shape")
out_width = self.get_nodeattr("outWidth")
out_els = out_width / self.get_input_datatype().bitwidth()
# highly conservative estimate, since in the worst case we assume
# one additional cycle spent for each word when we have a passthrough
# situation of identical input and output word counts.
num_out_words = int(np.prod(self.get_folded_output_shape()[-2:-1]))

in_shape = self.get_nodeattr("in_shape")
in_width = self.get_nodeattr("inWidth")
in_els = in_width / self.get_input_datatype().bitwidth()
num_in_words = int(np.prod(self.get_folded_input_shape()[-2:-1]))

numReps = int(np.prod(self.get_folded_input_shape()[:2]))

ratio = max(in_width,out_width) / min(in_width,out_width)
words = max(num_in_words,num_out_words)
max_words = max(num_in_words,num_out_words)
min_words = min(num_in_words,num_out_words)

exp_cycles = words + min_words
exp_cycles = max_words + min_words

return int(exp_cycles)


def prepare_kwargs_for_characteristic_fx(self):

numInWords = int(np.prod(self.get_folded_input_shape()[-2:-1]))
numOutWords = int(np.prod(self.get_folded_output_shape()[-2:-1]))
numReps = int(np.prod(self.get_folded_input_shape()[:1]))

inWidth = self.get_nodeattr("inWidth")
outWidth = self.get_nodeattr("outWidth")



kwargs = (numInWords,numOutWords,inWidth,outWidth,numReps)

# assert True==False
return kwargs



def characteristic_fx_input(self, txns, cycles, counter, kwargs):

(numInWords,numOutWords,inWidth,outWidth,numReps) = kwargs




# HYPER PARAMETERS WHICH MAY CHANGE OVER TIME
windup_clocks_up_convert_input = 4


windup_clocks_down_convert_input = 3


windup_clocks_down_convert_output = 4
windup_clocks_equal_convert_output = 3



if numInWords < windup_clocks_up_convert_input:
windup_clocks_up_convert_input = numInWords

if numInWords < windup_clocks_down_convert_input:
windup_clocks_down_convert_input = numInWords



if numOutWords < windup_clocks_down_convert_output:
windup_clocks_down_convert_output = numOutWords



if numOutWords < windup_clocks_equal_convert_output:
windup_clocks_equal_convert_output = numOutWords


# calculation to adjust for padding or cropping adding latency


if outWidth > inWidth:
higher = outWidth
lower = inWidth
else:
higher = inWidth
lower = outWidth

if higher % lower != 0:
if numInWords*inWidth > numOutWords*outWidth:
crop = True
pad = False
else:
cropping = False
pad = True

else:
crop = False
pad = False


# first input period
tracker = 0
maximum = numReps*numInWords

if numReps > 1:
# loop windup
for i in range(2):
txns.append(counter)
counter+=1
cycles+=1
tracker+=1

for j in range(0,numReps):
for i in range(0,numInWords):
if tracker < maximum:
txns.append(counter)
counter+=1
cycles+=1
tracker+=1
for i in range(0,1):
txns.append(counter)
cycles+=1

return txns, cycles, counter



def characteristic_fx_output(self, txns, cycles, counter, kwargs):

(numInWords,numOutWords,inWidth,outWidth,numReps) = kwargs





# HYPER PARAMETERS WHICH MAY CHANGE
windup_clocks_up_convert_input = 3
windup_clocks_down_convert_input = 2


windup_clocks_down_convert_output = 3
windup_clocks_equal_convert_output = 2



if numInWords < windup_clocks_up_convert_input:
windup_clocks_up_convert_input = numInWords

if numInWords < windup_clocks_down_convert_input:
windup_clocks_down_convert_input = numInWords



if numOutWords < windup_clocks_down_convert_output:
windup_clocks_down_convert_output = numOutWords



if numOutWords < windup_clocks_equal_convert_output:
windup_clocks_equal_convert_output = numOutWords




# calculation to adjust for padding or cropping adding latency


if outWidth > inWidth:
higher = outWidth
lower = inWidth
else:
higher = inWidth
lower = outWidth

if higher % lower != 0:
if numInWords*inWidth > numOutWords*outWidth:
crop = True
pad = False
else:
cropping = False
pad = True

else:
crop = False
pad = False



# windup period
if inWidth == outWidth:
clock = windup_clocks_equal_convert_output
else:
clock = windup_clocks_up_convert_input
for i in range(0,clock):
txns.append(counter)
cycles+=1
# padding +=1

# first input period

if pad:
offset = 2
else:
offset = 1


remainder = 0


for k in range(numReps):

# windup
txns.append(counter)
cycles+=1

for i in range(0,numOutWords):
for j in range(0,int(np.floor(outWidth/inWidth))):
if j != 0:
txns.append(counter)
cycles +=1
remainder += inWidth
# padding +=1



if pad and remainder < outWidth:
print(remainder)
txns.append(counter)
remainder += inWidth
cycles +=1

txns.append(counter)
cycles +=1

counter+=1
remainder -= outWidth


return txns, cycles, counter


def derive_characteristic_fxns(self, period):
n_inps = np.prod(self.get_folded_input_shape()[:-1])
io_dict = {
"inputs": {
"in0": [0 for i in range(n_inps)],
},
"outputs": {"out": []},
}

ignore = self.get_nodeattr("ipgen_ignore")
if ignore == 0: # this node is being derived using RTLSIM
# RTL-based flow
super().derive_characteristic_fxns(period, override_rtlsim_dict=io_dict)
return



# Analytical flow

txns_in = {key: [] for (key, value) in io_dict["inputs"].items() if "in" in key}
txns_out = {key: [] for (key, value) in io_dict["outputs"].items() if "out" in key}

all_txns_in = np.empty((len(txns_in.keys()), 2 * period), dtype=np.int32)
all_txns_out = np.empty((len(txns_out.keys()), 2 * period), dtype=np.int32)


self.set_nodeattr("io_chrc_period",period)




txn_in = []
txn_out = []


# INPUT

counter = 0
padding = 0


kwargs = self.prepare_kwargs_for_characteristic_fx()


# first period
cycles = 0
txn_in, cycles, counter = self.characteristic_fx_input(txn_in,cycles,counter,kwargs)

txn_in += [counter] * (period-cycles)
padding+=(period*-cycles)


# second period
cycles = period
txn_in, cycles, counter = self.characteristic_fx_input(txn_in,cycles,counter,kwargs)


#for i in range(cycles,period*2):
# txn_in.append(counter)
#pads = (period*2-cycles)

txn_in += [counter] * (period*2-cycles)
padding+=(period*2-cycles)

# final assignments
all_txns_in[0, :] = np.array(txn_in)
self.set_nodeattr("io_chrc_in", all_txns_in)
self.set_nodeattr("io_chrc_pads_in", padding)


# OUTPUT

counter = 0
cycles = 0
padding = 0


txn_out, cycles, counter = self.characteristic_fx_output(txn_out,cycles,counter,kwargs)


txn_out += [counter] * (period-cycles)
padding += (period*-cycles)

cycles = period

txn_out, cycles, counter = self.characteristic_fx_output(txn_out,cycles,counter,kwargs)

txn_out += [counter] * (period*2-cycles)
padding+=(period*2-cycles)


all_txns_out[0, :] = np.array(txn_out)
self.set_nodeattr("io_chrc_out", all_txns_out)
self.set_nodeattr("io_chrc_pads_out", padding)

0 comments on commit fc901e5

Please sign in to comment.