#!/usr/bin/env python2
# -*- coding: utf-8 -*-
#
# Copyright 2012-2017 Frédéric Magniette, Miguel Rubio-Roy
# This file is part of Pyrame.
#
# Pyrame is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrame is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrame. If not, see <http://www.gnu.org/licenses/>
import pools,common_roc
def init():
common_roc.nb_chans=36
spiroc2b_pool=pools.pool("spiroc2b")
spiroc2b_bs_length=929
#************************* BITSTREAM MANIPULATION FUNCTIONS ***************
# **************************************************************************
# trigger threshold
# **************************************************************************
def extract_gtrigger(spiroc2b):
return str(int(spiroc2b["bitstream_bin"][239:249][::-1],2))
def set_gtrigger_reg(spiroc2b,gtrigger):
if gtrigger!="undef":
return common_roc.apply_inv_mask(spiroc2b,239,common_roc.split_bin(int(gtrigger),10))
return 1,"ok"
[docs]def set_gtrigger_spiroc2b(spiroc2b_id,gtrigger):
"set the trigger threshold of a spiroc2b. *value* is 10-bit integer"
return common_roc.apply_to_roc(spiroc2b_pool,spiroc2b_id,extract_gtrigger,set_gtrigger_reg,"gtrigger",gtrigger)
# **************************************************************************
# chipid
# **************************************************************************
[docs]def set_chipid(spiroc2b_id,spiroc2b):
"set the chipid of a spiroc2b chip on its bitstream"
idbin=common_roc.split_bin(common_roc.bin2gray(int(spiroc2b["chipid"])),8)
return common_roc.apply_to_roc(spiroc2b_pool,spiroc2b_id,None,common_roc.apply_mask,"undef",905,idbin)
[docs]def set_chipid_param_spiroc2b(spiroc2b_id,chipid):
"set the chipid of a spiroc2b chip on the pool"
try:
spiroc2b=spiroc2b_pool.get(spiroc2b_id)
except Exception as e:
return 0,str(e)
if chipid!="undef":
spiroc2b["chipid"]=chipid
return 1,"ok"
[docs]def get_chipid_spiroc2b(spiroc2b_id):
"get the chipid of a spiroc2b"
try:
spiroc2b=spiroc2b_pool.get(spiroc2b_id)
except Exception as e:
return 0,str(e)
return 1,"chipid=%s"%(spiroc2b["chipid"])
# **************************************************************************
# triggers
# **************************************************************************
def extract_allow_trig_chans(spiroc2b):
return common_roc.extract_bit_chans(spiroc2b,178,1,0,False)
def allow_trig(spiroc2b,chan):
return common_roc.apply_mask(spiroc2b,178+chan,common_roc.split_bin(0,1))
[docs]def allow_trig_chans_spiroc2b(spiroc2b_id,chans):
"allow trigger on channels. *chans* is a list of channels"
retcode,res=common_roc.apply_to_chans(spiroc2b_pool,spiroc2b_id,chans,extract_allow_trig_chans,allow_trig,"allow_trig_chans")
if retcode==0:
return 0,res
spiroc2b=spiroc2b_pool.get(spiroc2b_id)
spiroc2b["disallow_trig_chans"]=extract_disallow_trig_chans(spiroc2b)
return 1,"ok"
# **************************************************************************
def extract_disallow_trig_chans(spiroc2b):
return common_roc.extract_bit_chans(spiroc2b,178,1,1,False)
def disallow_trig(spiroc2b,chan):
return common_roc.apply_mask(spiroc2b,178+chan,common_roc.split_bin(1,1))
[docs]def disallow_trig_chans_spiroc2b(spiroc2b_id,chans):
"disallow trigger on channels. *chans* is a list of channels"
retcode,res=common_roc.apply_to_chans(spiroc2b_pool,spiroc2b_id,chans,extract_disallow_trig_chans,disallow_trig,"disallow_trig_chans")
if retcode==0:
return 0,res
spiroc2b=spiroc2b_pool.get(spiroc2b_id)
spiroc2b["allow_trig_chans"]=extract_allow_trig_chans(spiroc2b)
return 1,"ok"
# **************************************************************************
# TDC External
# **************************************************************************
def extract_tdc_ext(spiroc2b):
return spiroc2b["bitstream_bin"][927:928]
[docs]def set_tdc_ext_spiroc2b(spiroc2b_id,value):
"Activate (ON or 1) or desactivate (OFF or 0) tdc_ext signal"
return common_roc.apply_to_roc(spiroc2b_pool,spiroc2b_id,extract_tdc_ext,common_roc.on_off_bit,"tdc_ext",927,value)
# **************************************************************************
# Input 8-bit DAC
# **************************************************************************
def set_input_dac(spiroc2b,chan,value):
if value!="undef":
return common_roc.apply_inv_mask(spiroc2b,572+9*(35-chan)+1,common_roc.split_bin(int(value),8))
return 1,"ok"
# **************************************************************************
def extract_enable_input_dac_chans(spiroc2b):
return common_roc.extract_bit_chans(spiroc2b,572,9,1)
def enable_input_dac(spiroc2b,chan):
return common_roc.apply_mask(spiroc2b,572+9*(35-chan),common_roc.split_bin(1,1))
# **************************************************************************
def extract_disable_input_dac_chans(spiroc2b):
return common_roc.extract_bit_chans(spiroc2b,572,9,0)
def disable_input_dac(spiroc2b,chan):
return common_roc.apply_mask(spiroc2b,572+9*(35-chan),common_roc.split_bin(0,1))
# **************************************************************************
# Enable/disable preamp
# **************************************************************************
def extract_enable_preamp_chans(spiroc2b):
return common_roc.extract_bit_chans(spiroc2b,268,8,0)
def enable_preamp_chan(spiroc2b,chan):
return common_roc.apply_mask(spiroc2b,267+8*(35-chan)+1,common_roc.split_bin(0,1))
[docs]def enable_preamp_chans_spiroc2b(spiroc2b_id,chans):
"enable preamp of channels. *chans* is a list of channels"
retcode,res=common_roc.apply_to_chans(spiroc2b_pool,spiroc2b_id,chans,extract_enable_preamp_chans,enable_preamp_chan,"enable_preamp_chans")
if retcode==0:
return 0,res
spiroc2b=spiroc2b_pool.get(spiroc2b_id)
spiroc2b["disable_preamp_chans"]=extract_disable_preamp_chans(spiroc2b)
return 1,"ok"
# **************************************************************************
def extract_disable_preamp_chans(spiroc2b):
return common_roc.extract_bit_chans(spiroc2b,268,8,1)
def disable_preamp_chan(spiroc2b,chan):
return common_roc.apply_mask(spiroc2b,267+8*(35-chan)+1,common_roc.split_bin(1,1))
[docs]def disable_preamp_chans_spiroc2b(spiroc2b_id,chans):
"disable preamp of channels. *chans* is a list of channels"
retcode,res=common_roc.apply_to_chans(spiroc2b_pool,spiroc2b_id,chans,extract_disable_preamp_chans,disable_preamp_chan,"disable_preamp_chans")
if retcode==0:
return 0,res
spiroc2b=spiroc2b_pool.get(spiroc2b_id)
spiroc2b["enable_preamp_chans"]=extract_enable_preamp_chans(spiroc2b)
return 1,"ok"
# **************************************************************************
# Enable/disable backup SCA
# **************************************************************************
def extract_bak_sca(spiroc2b):
return spiroc2b["bitstream_bin"][254:255]
[docs]def set_bak_sca_spiroc2b(spiroc2b_id,value):
"Activate (ON or 1) or desactivate (OFF or 0) backup SCA"
return common_roc.apply_to_roc(spiroc2b_pool,spiroc2b_id,extract_bak_sca,common_roc.on_off_bit,"bak_sca",254,value)
# **************************************************************************
# Delay for trigger signals
# **************************************************************************
def extract_trigger_delay(spiroc2b):
return str(int(spiroc2b["bitstream_bin"][170:176][::-1],2))
def set_trigger_delay_reg(spiroc2b,value):
if value!="undef":
return common_roc.apply_inv_mask(spiroc2b,170,common_roc.split_bin(int(value),6))
return 1,"ok"
[docs]def set_trigger_delay_spiroc2b(spiroc2b_id,value):
"set the delay for the trigger signals. *value* is a 6-bit integer"
return common_roc.apply_to_roc(spiroc2b_pool,spiroc2b_id,extract_trigger_delay,set_trigger_delay_reg,"trigger_delay",value)
# **************************************************************************
# Discriminator DAC threshold adjustment
# **************************************************************************
def set_discri_dac(spiroc2b,chan,value):
if value!="undef":
return common_roc.apply_mask(spiroc2b,26+4*chan,common_roc.split_bin(int(value),4))
return 1,"ok"
[docs]def set_discri_dac_chans_spiroc2b(spiroc2b_id,chans,value):
"set discriminator DAC threshold of channels. *value* is a 4-bit integer. *chans* is a list of channels"
return common_roc.apply_to_chans(spiroc2b_pool,spiroc2b_id,chans,None,set_discri_dac,"undef",value)
# **************************************************************************
# Delay for valid_hold signals
# **************************************************************************
def extract_valid_hold_delay(spiroc2b):
return str(int(spiroc2b["bitstream_bin"][16:22][::-1],2))
def set_valid_hold_delay_reg(spiroc2b,value):
if value!="undef":
return common_roc.apply_inv_mask(spiroc2b,16,common_roc.split_bin(int(value),6))
return 1,"ok"
[docs]def set_valid_hold_delay_spiroc2b(spiroc2b_id,value):
"set the delay for the valid_hold signals. *value* is a 6-bit integer"
return common_roc.apply_to_roc(spiroc2b_pool,spiroc2b_id,extract_valid_hold_delay,set_valid_hold_delay_reg,"valid_hold_delay",value)
# **************************************************************************
# Delay for rst_column signals
# **************************************************************************
def extract_rst_column_delay(spiroc2b):
return str(int(spiroc2b["bitstream_bin"][9:15][::-1],2))
def set_rst_column_delay_reg(spiroc2b,value):
if value!="undef":
return common_roc.apply_inv_mask(spiroc2b,9,common_roc.split_bin(int(value),6))
return 1,"ok"
[docs]def set_rst_column_delay_spiroc2b(spiroc2b_id,value):
"set the delay for the rst_column signals. *value* is a 6-bit integer"
return common_roc.apply_to_roc(spiroc2b_pool,spiroc2b_id,extract_rst_column_delay,set_rst_column_delay_reg,"rst_column_delay",value)
#********************************** GENERAL PUBLIC FUNCTIONS ***************
[docs]def dump_sc_spiroc2b(spiroc2b_id):
"Returns bitstream of *spiroc2b_id* in binary format"
try:
spiroc2b=spiroc2b_pool.get(spiroc2b_id)
except Exception as e:
return 0,str(e)
#return the bitstream
bitstream=spiroc2b["bitstream_bin"] if not spiroc2b["missing"] else ""
return 1,bitstream
[docs]def set_missing_spiroc2b(spiroc2b_id,missing):
"Set spiroc2b missing state"
try:
spiroc2b=spiroc2b_pool.get(spiroc2b_id)
except Exception as e:
return 0,str(e)
spiroc2b["missing"]=1 if missing=="1" else 0
return 1,"ok"
#****************************** PHASES *************************************
[docs]def init_spiroc2b(spiroc2b_id):
"Initialize a spiroc2b"
spiroc2b_pool.new(spiroc2b_id,{"missing":0})
return 1,"ok"
[docs]def deinit_spiroc2b(spiroc2b_id):
"Deinitialize *spiroc2b_id*"
try:
spiroc2b=spiroc2b_pool.get(spiroc2b_id)
except Exception as e:
return 1,str(e)
spiroc2b_pool.remove(spiroc2b_id)
return 1,"ok"
[docs]def config_spiroc2b(spiroc2b_id,file,bitstream,gtrigger,allow_trig_chans,disallow_trig_chans,enable_preamp_chans,disable_preamp_chans,enable_input_dac_chans,disable_input_dac_chans,bak_sca,rst_column_delay,tdc_ext,trigger_delay,valid_hold_delay):
"prepare the bitstream for configuring a chip"
try:
spiroc2b=spiroc2b_pool.get(spiroc2b_id)
except Exception as e:
return 0,str(e)
#empty the bitstream
spiroc2b["bitstream_bin"]=""
#load bitstream
if bitstream!="undef":
retcode,res=common_roc.load_str(bitstream,spiroc2b_bs_length)
if retcode==0:
return 0,"cant parse bitstream: %s"%(res)
spiroc2b["bitstream_bin"]=res
#load bitstream from file
if file!="undef":
retcode,res=common_roc.load_file(file,spiroc2b_bs_length)
if retcode==0:
return 0,"cant open config file: %s"%(res)
spiroc2b["bitstream_bin"]=res
if spiroc2b["bitstream_bin"]=="":
return 0,"no bitstream defined for spiroc2b %s"%(spiroc2b_id)
#set chip id
retcode,res=set_chipid(spiroc2b_id,spiroc2b)
if retcode==0:
return 0,"cant set chipid: %s"%(res)
#set global trigger threshold
retcode,res=set_gtrigger_spiroc2b(spiroc2b_id,gtrigger)
if retcode==0:
return 0,"cant set trigger threshold: %s"%(res)
# allows to trigger
retcode,res=allow_trig_chans_spiroc2b(spiroc2b_id,allow_trig_chans)
if retcode==0:
return 0,"cant allow to trigger nomasktrig: %s"%(res)
# disallows to trigger
retcode,res=disallow_trig_chans_spiroc2b(spiroc2b_id,disallow_trig_chans)
if retcode==0:
return 0,"cant disallow to trigger masktrig: %s"%(res)
# enable preamps
retcode,res=enable_preamp_chans_spiroc2b(spiroc2b_id,enable_preamp_chans)
if retcode==0:
return 0,"cant enable preamp: %s"%(res)
# disable preamps
retcode,res=disable_preamp_chans_spiroc2b(spiroc2b_id,disable_preamp_chans)
if retcode==0:
return 0,"cant enable preamp: %s"%(res)
# enable input DAC
retcode,res=enable_input_dac_chans_spiroc2b(spiroc2b_id,enable_input_dac_chans)
if retcode==0:
return 0,"cant enable input DAC: %s"%(res)
# disable input DAC
retcode,res=disable_input_dac_chans_spiroc2b(spiroc2b_id,disable_input_dac_chans)
if retcode==0:
return 0,"cant enable input DAC: %s"%(res)
# set backup SCA
retcode,res=set_bak_sca_spiroc2b(spiroc2b_id,bak_sca)
if retcode==0:
return 0,"cant set backup SCA: %s"%(res)
# set rst_column delay
retcode,res=set_rst_column_delay_spiroc2b(spiroc2b_id,rst_column_delay)
if retcode==0:
return 0,"cant set rst_column delay: %s"%(res)
# set trigger delay
retcode,res=set_trigger_delay_spiroc2b(spiroc2b_id,trigger_delay)
if retcode==0:
return 0,"cant set trigger delay: %s"%(res)
# set valid_hold delay
retcode,res=set_valid_hold_delay_spiroc2b(spiroc2b_id,valid_hold_delay)
if retcode==0:
return 0,"cant set valid_hold delay: %s"%(res)
# set TDC ext
retcode,res=set_tdc_ext_spiroc2b(spiroc2b_id,tdc_ext)
if retcode==0:
return 0,"cant set TDC ext: %s"%(res)
#update the bitstream in cmod
common_roc.update_bitstream(spiroc2b)
return 1,"ok"
[docs]def get_param_spiroc2b(spiroc2b_id,param_name):
"parameter extraction"
return common_roc.get_param_roc(spiroc2b_pool,spiroc2b_id,param_name)