def sim_command_pipeline(pars_obj): global test_decimal_shift, theta_decimal_shift #------------------ Initializing Pipeline depths --------------- NB_PIPELINE_STAGES = 5 DATAWIDTH = 32 #-------------- Simulation Initialisations --------------------- reset = Signal(bool(1)) clk = Signal(bool(0)) elapsed_time = Signal(0) clkgen = clk_driver(elapsed_time, clk, period=20) #---------------------------------------------------------------- #----------------- Initializing Pipeline Streams ---------------- # --- Pipeline Pars pars = OperandPipelinePars() pars.NB_PIPELINE_STAGES = NB_PIPELINE_STAGES pars.DATAWIDTH = DATAWIDTH pars.CHANNEL_WIDTH = 2 global floatDataBus if (True == floatDataBus): pars.INIT_DATA = 0.0 # requires floating point computation else: pars.INIT_DATA = 0 # requires intbv computation # --- Initializing Pipeline A pipe_inpA = PipelineST(pars.DATAWIDTH, pars.CHANNEL_WIDTH, pars.INIT_DATA) pipe_outA = PipelineST(pars.DATAWIDTH, pars.CHANNEL_WIDTH, pars.INIT_DATA) operand_a = OperandPipeline() ioA = OperandPipelineIo() ioA(pars) # --- Initializing Pipeline B pipe_inpB = PipelineST(pars.DATAWIDTH, pars.CHANNEL_WIDTH, pars.INIT_DATA) pipe_outB = PipelineST(pars.DATAWIDTH, pars.CHANNEL_WIDTH, pars.INIT_DATA) operand_b = OperandPipeline() ioB = OperandPipelineIo() ioB(pars) # --- Initializing Command Pipeline pipe_multRes = PipelineST(pars.DATAWIDTH, pars.CHANNEL_WIDTH, pars.INIT_DATA) multcmdFile = '../tests/mult_pipeline.list' parsMult = CommandPipelinePars() parsMult.DATAWIDTH = pars.DATAWIDTH parsMult.CHANNEL_WIDTH = pars.CHANNEL_WIDTH parsMult.INIT_DATA = pars.INIT_DATA parsMult.STAGE_NB = 1 parsMult(parsMult, multcmdFile) multPipe = CommandPipeline() ioMult = CommandPipelineIo() ioMult(pars) # ---- Initializing Accumulator Block pipe_out_acc = PipelineST(pars.DATAWIDTH, pars.CHANNEL_WIDTH, pars.INIT_DATA) parsAcc = AccumulatorPars() parsAcc.DATAWIDTH = pars.DATAWIDTH parsAcc.CHANNEL_WIDTH = pars.CHANNEL_WIDTH parsAcc.INIT_DATA = pars.INIT_DATA global LEN_THETA parsAcc.NB_ACCUMULATIONS = LEN_THETA accuPipe = Accumulator() accuPipe(parsAcc) # ---- Initializing Activation Block parsActiv = ActivationPars() parsActiv.DATAWIDTH = 3 # 0 or 1 for classification parsActiv.CHANNEL_WIDTH = pars.CHANNEL_WIDTH parsActiv.INIT_DATA = pars.INIT_DATA pipe_out_activ = PipelineST(pars.DATAWIDTH, pars.CHANNEL_WIDTH, pars.INIT_DATA) activPipe = Activation() activPipe(parsActiv) #---------------------------------------------------------------- #----------------- Connecting Pipeline Blocks ------------------- inst = [] inst.append( operand_a.block_connect(pars, reset, clk, pipe_inpA, pipe_outA, ioA)) inst.append( operand_b.block_connect(pars, reset, clk, pipe_inpB, pipe_outB, ioB)) #---------------------------------------------------------------- #----------------- Connecting Command Pipeline ------------------- # Mult Pipeline inst.append( multPipe.block_connect(parsMult, reset, clk, ioA, ioB, pipe_multRes, ioMult)) #---------------------------------------------------------------- #----------------- Connecting Accumulator -------------- # Accu inst.append( accuPipe.block_connect(parsAcc, reset, clk, 0, pipe_multRes, pipe_out_acc)) #---------------------------------------------------------------- #----------------- Connecting Activation -------------- # Simple Step Activation function inst.append( activPipe.block_step_connect(parsActiv, reset, clk, pipe_out_acc, pipe_out_activ)) #---------------------------------------------------------------- #----------------- Logistic Regression Test File ------------------- lr_test_file = "../tests/ex2data1.txt" lr_theta_file = "../tests/theta1.txt" #--- Loading Test and Theta Values test_file_list = [] theta_file_list = [] nb_training_examples = 0 # Loading test data with open(lr_test_file, 'r') as f: d0 = 1.0 # Always first element is 1 for line in f: #print line d1, d2, y = line.split(',') d0 = round(float(d0), DEF_ROUND) d1 = round(float(d1), DEF_ROUND) d2 = round(float(d2), DEF_ROUND) test_file_list.extend([d0, d1, d2]) label.extend([int(y)]) nb_training_examples += 1 #loading theta with open(lr_theta_file, 'r') as f: t0, t1, t2 = (f.read().split('\n')[0]).split(',') t0 = round(float(t0), DEF_ROUND) t1 = round(float(t1), DEF_ROUND) t2 = round(float(t2), DEF_ROUND) for i in range(nb_training_examples): theta_file_list.extend([t0, t1, t2]) # exp10 shifts done for theta and test data as per requirements when intbv used if (False == floatDataBus): test_file_list = [ int(i * (10**test_decimal_shift)) for i in test_file_list ] theta_file_list = [ int(i * (10**theta_decimal_shift)) for i in theta_file_list ] #print test_file_list #print theta_file_list #---------------------------------------------------------------- #----------------- Shift Enable for pipeData ------------------- shiftEn_i = Signal(bool(0)) @always(clk.posedge, reset.posedge) def shift_signal(): if reset: shiftEn_i.next = 1 else: shiftEn_i.next = not shiftEn_i @always_comb def shiftOperand_signal(): ioB.shiftEn_i.next = shiftEn_i ioA.shiftEn_i.next = shiftEn_i #---------------------------------------------------------------- #----------------- Reset For the Module -------------------- @always(clk.posedge) def stimulus(): if elapsed_time == 40: reset.next = 0 #---------------------------------------------------------------- #----------------- Input Data for the Modules -------------------- @always_comb def transmit_data_process(): global line_nb if (shiftEn_i == 1 and nbTA == nbTB and nbTA < MAX_NB_TRANSFERS): pipe_inpA.data.next = (test_file_list[line_nb]) pipe_inpA.valid.next = 1 pipe_inpB.data.next = (theta_file_list[line_nb]) pipe_inpB.valid.next = 1 line_nb += 1 else: pipe_inpA.valid.next = 0 pipe_inpB.valid.next = 0 #---------------------------------------------------------------- #----------------- Storing Transmitted Data -------------------- @always(clk.posedge, reset.posedge) def trans_dataA_process(): global trans_dataA, trans_dataB, nbTA if reset == 1: pass elif (pipe_inpA.valid == 1 and nbTA < MAX_NB_TRANSFERS): nbTA += 1 trans_dataA.extend([pipe_inpA.data]) @always(clk.posedge, reset.posedge) def trans_dataB_process(): global trans_dataA, trans_dataB, nbTB if reset == 1: pass elif (pipe_inpB.valid == 1 and nbTB < MAX_NB_TRANSFERS): nbTB += 1 trans_dataB.extend([pipe_inpB.data]) #---------------------------------------------------------------- #----------------- Storing Received Data ----------------------- @always(clk.posedge) def receive_data_process(): global recv_data, nbR, acc_out # Collecting multiplier data if (pipe_multRes.valid == 1): if (False == floatDataBus): mult_out = pipe_multRes.data else: mult_out = (round(pipe_multRes.data, DEF_ROUND)) recv_data.extend([mult_out]) # Collecting Activation Data if (pipe_out_activ.valid == 1): nbR += LEN_THETA predict = int(pipe_out_activ.data) prediction_res.extend([predict]) if __debug__: print(" prediction: {:d}".format(predict)) if (nbR == MAX_NB_TRANSFERS): raise StopSimulation( "Simulation Finished in %d clks: In total " % now() + str(MAX_NB_TRANSFERS) + " data words received") # Collecting Accumulator Data if (pipe_out_acc.valid == 1): acc_out = pipe_out_acc.data #prob=(1.0/(1+ (math.exp(-1.0*acc_out) ))) # Sigmoid activation Function if __debug__: if (False == floatDataBus): print("{0:d} Acc: {1:d} ".format(int(nbR / LEN_THETA + 1), int(acc_out), i=DEF_ROUND), end=' ') else: print("{0:d} Acc: {1:0.{i}f}".format(int(nbR / LEN_THETA + 1), float(acc_out), i=DEF_ROUND), end=' ') if (False == floatDataBus): acc_out_list.extend([int(acc_out)]) else: acc_out_list.extend([round(acc_out, DEF_ROUND)]) #print "nbR:" + str(nbR) #---------------------------------------------------------------- #----------------- Max Simulation Time Exit Condition ----------- @always(clk.posedge) def simulation_time_check(): sim_time_now = now() if (sim_time_now > MAX_SIM_TIME): raise StopSimulation( "Warning! Simulation Exited upon reaching max simulation time of " + str(MAX_SIM_TIME) + " clocks") #---------------------------------------------------------------- return instances()
def lr_top(pars, reset, clk, pipe_inpA, pipe_inpB, pipe_out_activ): #----------------- Initializing Pipeline Streams ---------------- # --- Initializing Pipeline A pipe_outA = PipelineST(pars.DATAWIDTH,pars.CHANNEL_WIDTH,pars.INIT_DATA) operand_a=OperandPipeline() ioA=OperandPipelineIo() ioA(pars) # --- Initializing Pipeline B pipe_outB = PipelineST(pars.DATAWIDTH,pars.CHANNEL_WIDTH,pars.INIT_DATA) operand_b=OperandPipeline() ioB=OperandPipelineIo() ioB(pars) # --- Initializing Command Pipeline pipe_multRes = PipelineST(pars.DATAWIDTH,pars.CHANNEL_WIDTH,pars.INIT_DATA) multcmdFile='tb/tests/mult_pipeline.list' parsMult= CommandPipelinePars() parsMult.DATAWIDTH= pars.DATAWIDTH parsMult.CHANNEL_WIDTH = pars.CHANNEL_WIDTH parsMult.INIT_DATA = pars.INIT_DATA parsMult.STAGE_NB = 1 parsMult(parsMult,multcmdFile) multPipe=CommandPipeline() ioMult=CommandPipelineIo() ioMult(pars) # ---- Initializing Accumulator Block pipe_out_acc = PipelineST(pars.DATAWIDTH,pars.CHANNEL_WIDTH,pars.INIT_DATA) parsAcc= AccumulatorPars() parsAcc.DATAWIDTH= pars.DATAWIDTH parsAcc.CHANNEL_WIDTH = pars.CHANNEL_WIDTH parsAcc.INIT_DATA = pars.INIT_DATA parsAcc.NB_ACCUMULATIONS = pars.LEN_THETA accuPipe= Accumulator() accuPipe(parsAcc) # ---- Initializing Activation Block parsActiv= ActivationPars() parsActiv.DATAWIDTH= 3 # 0 or 1 for classification parsActiv.CHANNEL_WIDTH = pars.CHANNEL_WIDTH parsActiv.INIT_DATA = pars.INIT_DATA activPipe= Activation() activPipe(parsActiv) #---------------------------------------------------------------- #----------------- Connecting Pipeline Blocks ------------------- trainingData=(operand_a.block_connect(pars, reset, clk, pipe_inpA, pipe_outA, ioA)) theta=(operand_b.block_connect(pars, reset, clk, pipe_inpB, pipe_outB, ioB)) #---------------------------------------------------------------- #----------------- Connecting Command Pipeline ------------------- # Mult Pipeline command=(multPipe.block_connect(parsMult, reset, clk, ioA, ioB, pipe_multRes, ioMult)) #---------------------------------------------------------------- #----------------- Connecting Accumulator -------------- # Accu acc_reset=Signal(bool(0)) accumulator=(accuPipe.block_connect(parsAcc, reset, clk, acc_reset, pipe_multRes, pipe_out_acc)) #---------------------------------------------------------------- #----------------- Connecting Activation -------------- # Simple Step Activation function activation=(activPipe.block_step_connect(parsActiv, reset, clk, pipe_out_acc, pipe_out_activ )) #---------------------------------------------------------------- return instances()