#!/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=32
easiroc_pool=pools.pool("easiroc")
easiroc_bs_length=456
#************************* BITSTREAM MANIPULATION FUNCTIONS ***************
# **************************************************************************
# D OUTPUT
# **************************************************************************
def extract_d_output(easiroc):
return easiroc["bitstream_bin"][6:7]
[docs]def set_d_output_easiroc(easiroc_id,value):
"Enable digital multiplexed output (Hit mux out)"
return common_roc.apply_to_roc(easiroc_pool,easiroc_id,extract_d_output,common_roc.on_off_bit,"d_output",6,value)
# **************************************************************************
# GTRIGGER
# **************************************************************************
def extract_gtrigger(easiroc):
return str(int(easiroc["bitstream_bin"][20:30],2))
def set_gtrigger_reg(easiroc,gtrigger):
if gtrigger!="undef":
return common_roc.apply_mask(easiroc,20,common_roc.split_bin(int(gtrigger),10))
return 1,"ok"
[docs]def set_gtrigger_easiroc(easiroc_id,gtrigger):
"Set 10-bit DAC code"
return common_roc.apply_to_roc(easiroc_pool,easiroc_id,extract_gtrigger,set_gtrigger_reg,"gtrigger",gtrigger)
# **************************************************************************
# High gain and low gain tau
# **************************************************************************
def extract_hg_tau(easiroc):
return str(175-(25*int(easiroc["bitstream_bin"][71:74][::-1],2)))+"ns"
def set_hg_tau_reg(easiroc,hg_tau):
if hg_tau!="undef":
if not hg_tau.endswith("ns"):
return 0,"high-gain time constant must end with ns units"
hg_tau=int(hg_tau[:-2])
if (hg_tau % 25)==0 and hg_tau>=25 and hg_tau<=175:
hg_tau=(175-hg_tau)/25
return common_roc.apply_inv_mask(easiroc,71,common_roc.split_bin(hg_tau,3))
else:
return 0,"high-gain time constant must be a multiple of 25ns between 25 and 175ns"
return 1,"ok"
[docs]def set_hg_tau_easiroc(easiroc_id,hg_tau):
"Set high-gain time constant in ns. Must be multiple of 25ns between 25 and 175ns"
return common_roc.apply_to_roc(easiroc_pool,easiroc_id,extract_hg_tau,set_hg_tau_reg,"hg_tau",hg_tau)
# **************************************************************************
def extract_lg_tau(easiroc):
return str(175-(25*int(easiroc["bitstream_bin"][76:79],2)))+"ns"
def set_lg_tau_reg(easiroc,lg_tau):
if lg_tau!="undef":
if not lg_tau.endswith("ns"):
return 0,"low-gain time constant must end with ns units"
lg_tau=int(lg_tau[:-2])
if (lg_tau % 25)==0 and lg_tau>=25 and lg_tau<=175:
lg_tau=(175-lg_tau)/25
return common_roc.apply_mask(easiroc,76,common_roc.split_bin(lg_tau,3))
else:
return 0,"low-gain time constant must be a multiple of 25ns between 25 and 175ns"
return 1,"ok"
[docs]def set_lg_tau_easiroc(easiroc_id,lg_tau):
"Set low-gain time constant in ns. Must be multiple of 25ns between 25 and 175ns"
return common_roc.apply_to_roc(easiroc_pool,easiroc_id,extract_lg_tau,set_lg_tau_reg,"lg_tau",lg_tau)
# **************************************************************************
# High gain compensation capacity
# **************************************************************************
def extract_hg_comp_capa(easiroc):
return str(7.5-(int(easiroc["bitstream_bin"][157:161],2)/2.0))+"pF"
def set_hg_comp_capa_reg(easiroc,hg_comp_capa):
if hg_comp_capa!="undef":
if not hg_comp_capa.endswith("pF"):
return 0,"high-gain preamp compensation capacitance must end with pF units"
hg_comp_capa=float(hg_comp_capa[:-2])
if hg_comp_capa>=0 and hg_comp_capa<=7.5:
hg_comp_capa=int(2 * (7.5 - hg_comp_capa))
return common_roc.apply_mask(easiroc,157,common_roc.split_bin(hg_comp_capa,4))
else:
return 0,"high-gain preamp compensation capacitance must be a multiple of 0.5pF between 0 and 7.5"
return 1,"ok"
[docs]def set_hg_comp_capa_easiroc(easiroc_id,hg_comp_capa):
"Set high-gain preamp compensation capacitance in pF. Must be a multiple of 0.5pF between 0 and 7.5."
return common_roc.apply_to_roc(easiroc_pool,easiroc_id,extract_hg_comp_capa,set_hg_comp_capa_reg,"hg_comp_capa",hg_comp_capa)
# **************************************************************************
# High gain feedback capacity
# **************************************************************************
def extract_hg_fb_capa(easiroc):
return str((int(easiroc["bitstream_bin"][153:157][::-1],2))/10.0)+"pF"
def set_hg_fb_capa_reg(easiroc,hg_fb_capa):
if hg_fb_capa!="undef":
if not hg_fb_capa.endswith("pF"):
return 0,"high-gain preamp feedback capacitance must end with pF units"
hg_fb_capa=float(hg_fb_capa[:-2])
if hg_fb_capa>=0 and hg_fb_capa<=1.5:
hg_fb_capa=int(10 * hg_fb_capa)
return common_roc.apply_inv_mask(easiroc,153,common_roc.split_bin(hg_fb_capa,4))
else:
return 0,"high-gain preamp feedback capacitance must be a multiple of 0.1pF between 0 and 1.5pF"
return 1,"ok"
[docs]def set_hg_fb_capa_easiroc(easiroc_id,hg_fb_capa):
"Set high-gain preamp feedback capacitance in pF. Must be a multiple of 0.1pF between 0 and 1.5pF"
return common_roc.apply_to_roc(easiroc_pool,easiroc_id,extract_hg_fb_capa,set_hg_fb_capa_reg,"hg_fb_capa",hg_fb_capa)
# **************************************************************************
# Low gain compensation capacity
# **************************************************************************
def extract_lg_comp_capa(easiroc):
return str(7.5-(int(easiroc["bitstream_bin"][145:149][::-1],2)/2.0))+"pF"
def set_lg_comp_capa_reg(easiroc,lg_comp_capa):
if lg_comp_capa!="undef":
if not lg_comp_capa.endswith("pF"):
return 0,"low-gain preamp compensation capacitance must end with pF units"
lg_comp_capa=float(lg_comp_capa[:-2])
if lg_comp_capa>=0 and lg_comp_capa<=7.5:
lg_comp_capa=int(2 * (7.5-lg_comp_capa))
return common_roc.apply_inv_mask(easiroc,145,common_roc.split_bin(lg_comp_capa,4))
else:
return 0,"low-gain preamp compensation capacitance must be a multiple of 0.5pF between 0 and 7.5pF"
return 1,"ok"
[docs]def set_lg_comp_capa_easiroc(easiroc_id,lg_comp_capa):
"Set low-gain preamp compensation capacitance in pF. Must be a multiple of 0.5pF between 0 and 7.5pF."
return common_roc.apply_to_roc(easiroc_pool,easiroc_id,extract_lg_comp_capa,set_lg_comp_capa_reg,"lg_comp_capa",lg_comp_capa)
# **************************************************************************
# Low gain feedback capacity
# **************************************************************************
def extract_lg_fb_capa(easiroc):
return str((15-int(easiroc["bitstream_bin"][149:153][::-1],2))/10.0)+"pF"
def set_lg_fb_capa_reg(easiroc,lg_fb_capa):
if lg_fb_capa!="undef":
if not lg_fb_capa.endswith("pF"):
return 0,"low-gain preamp feedback capacitance must end with pF units"
lg_fb_capa=float(lg_fb_capa[:-2])
if lg_fb_capa>=0 and lg_fb_capa<=1.5:
lg_fb_capa=int(15 - 10 * lg_fb_capa)
return common_roc.apply_inv_mask(easiroc,149,common_roc.split_bin(lg_fb_capa,4))
else:
return 0,"low-gain preamp feedback capacitance must be a multiple of 0.1pF between 0 and 1.5pF"
return 1,"ok"
[docs]def set_lg_fb_capa_easiroc(easiroc_id,lg_fb_capa):
"Set low-gain preamp feedback capacitance in pF. Must be a multiple of 0.1pF between 0pF and 1.5pF"
return common_roc.apply_to_roc(easiroc_pool,easiroc_id,extract_lg_fb_capa,set_lg_fb_capa_reg,"lg_fb_capa",lg_fb_capa)
# **************************************************************************
# Low gain preamp bias
# **************************************************************************
def extract_lg_preamp_bias(easiroc,xml_value=True):
bit=easiroc["bitstream_bin"][165:166]
if xml_value:
if bit=="0":
return "high"
if bit=="1":
return "weak"
return bit
def set_lg_preamp_bias_reg(easiroc,value):
if value!="undef":
if value=="high":
value="0"
elif value=="weak":
value="1"
else:
return 0,"invalid state of lg preamp bias (high/weak): %s"%(value)
return common_roc.apply_mask(easiroc,165,value)
return 1,"ok"
[docs]def set_lg_preamp_bias_easiroc(easiroc_id,value):
"Set low gain preamp bias to high"
return common_roc.apply_to_roc(easiroc_pool,easiroc_id,extract_lg_preamp_bias,set_lg_preamp_bias_reg,"lg_preamp_bias",value)
# **************************************************************************
# Input DAC Data
# **************************************************************************
def set_input_dac(easiroc,chan,value):
if value!="undef":
return common_roc.apply_mask(easiroc,166+288-9*(chan+1)+1,common_roc.split_bin(value,8))
return 1,"ok"
# **************************************************************************
def extract_enable_input_dac_chans(easiroc):
return common_roc.extract_bit_chans(easiroc,166,9,1)
def enable_input_dac_chan(easiroc,chan):
return common_roc.on_off_bit(easiroc,166+288-9*(chan+1),1)
# **************************************************************************
def extract_disable_input_dac_chans(easiroc):
return common_roc.extract_bit_chans(easiroc,166,9,0)
def disable_input_dac_chan(easiroc,chan):
return common_roc.on_off_bit(easiroc,166+288-9*(chan+1),0)
#********************************** GENERAL PUBLIC FUNCTIONS ***************
[docs]def dump_sc_easiroc(easiroc_id):
"Returns bitstream of *easiroc_id* in binary format"
try:
easiroc=easiroc_pool.get(easiroc_id)
except Exception as e:
return 0,str(e)
#return the bitstream
bitstream=easiroc["bitstream_bin"] if not easiroc["missing"] else ""
return 1,bitstream
[docs]def set_missing_easiroc(easiroc_id,missing):
"Set easiroc missing state"
try:
easiroc=easiroc_pool.get(easiroc_id)
except Exception as e:
return 0,str(e)
easiroc["missing"]=1 if missing=="1" else 0
return 1,"ok"
[docs]def explain_sc_easiroc(easiroc_id):
"Give meaningful strings of the configurable portions of the bitstream"
try:
easiroc=easiroc_pool.get(easiroc_id)
except Exception as e:
return 0,str(e)
d_output=extract_d_output(easiroc)
print("Digital multiplexed output (hit mux out): " + d_output)
gtrigger=extract_gtrigger(easiroc)
print("10-bit DAC=%s"%(gtrigger))
hg_tau=extract_hg_tau(easiroc)
print("High gain shaper time constant=%s"%(hg_tau))
lg_tau=extract_hg_tau(easiroc)
print("Low gain shaper time constant=%s"%(lg_tau))
lg_comp_capa=extract_lg_comp_capa(easiroc)
print("Low gain preamp compensation capacitances=%s"%(lg_comp_capa))
lg_fb_capa=extract_lg_fb_capa(easiroc)
print("Low gain preamp feedback capacitances=%s"%(lg_fb_capa))
hg_fb_capa=extract_hg_fb_capa(easiroc)
print("High gain preamp feedback capacitances=%s"%(hg_fb_capa))
hg_comp_capa=extract_hg_comp_capa(easiroc)
print("High gain preamp compensation capacitances=%s"%(hg_comp_capa))
lg_preamp_bias=extract_lg_preamp_bias(easiroc)
print("Low gain preamp bias: %s"%(lg_preamp_bias))
return 1,"ok"
#****************************** PHASES *************************************
[docs]def init_easiroc(easiroc_id):
"Initialize an easiroc"
easiroc_pool.new(easiroc_id,{"missing":0})
return 1,"ok"
[docs]def deinit_easiroc(easiroc_id):
"Deinitialize *easiroc_id*"
try:
easiroc=easiroc_pool.get(easiroc_id)
except Exception as e:
return 1,str(e)
easiroc_pool.remove(easiroc_id)
return 1,"ok"
[docs]def config_easiroc(easiroc_id,file,bitstream,d_output,gtrigger,hg_tau,lg_tau,hg_comp_capa,hg_fb_capa,lg_comp_capa,lg_fb_capa,lg_preamp_bias,enable_input_dac_chans,disable_input_dac_chans):
"Prepare the bitstream for configuring a chip"
try:
easiroc=easiroc_pool.get(easiroc_id)
except Exception as e:
return 0,str(e)
#empty the bitstream
easiroc["bitstream_bin"]=""
#load bitstream
if bitstream!="undef":
retcode,res=common_roc.load_str(bitstream,easiroc_bs_length)
if retcode==0:
return 0,"cant parse bitstream: %s"%(res)
easiroc["bitstream_bin"]=res
#load bitstream from file
if file!="undef":
retcode,res=common_roc.load_file(file,easiroc_bs_length)
if retcode==0:
return 0,"cant open config file: %s"%(res)
easiroc["bitstream_bin"]=res
if easiroc["bitstream_bin"]=="":
return 0,"no bitstream defined for easiroc %s"%(easiroc_id)
retcode,res=set_d_output_easiroc(easiroc_id,d_output)
if retcode==0:
return 0,res
retcode,res=set_gtrigger_easiroc(easiroc_id,gtrigger)
if retcode==0:
return 0,res
retcode,res=set_hg_tau_easiroc(easiroc_id,hg_tau)
if retcode==0:
return 0,res
retcode,res=set_lg_tau_easiroc(easiroc_id,lg_tau)
if retcode==0:
return 0,res
retcode,res=set_hg_comp_capa_easiroc(easiroc_id,hg_comp_capa)
if retcode==0:
return 0,res
retcode,res=set_hg_fb_capa_easiroc(easiroc_id,hg_fb_capa)
if retcode==0:
return 0,res
retcode,res=set_lg_comp_capa_easiroc(easiroc_id,lg_comp_capa)
if retcode==0:
return 0,res
retcode,res=set_lg_fb_capa_easiroc(easiroc_id,lg_fb_capa)
if retcode==0:
return 0,res
retcode,res=set_lg_preamp_bias_easiroc(easiroc_id,lg_preamp_bias)
if retcode==0:
return 0,res
retcode,res=enable_input_dac_chans_easiroc(easiroc_id,enable_input_dac_chans)
if retcode==0:
return 0,res
retcode,res=disable_input_dac_chans_easiroc(easiroc_id,disable_input_dac_chans)
if retcode==0:
return 0,res
#update the bitstream in cmod
common_roc.update_bitstream(easiroc)
return 1,"ok"
[docs]def get_param_easiroc(easiroc_id,param_name):
"parameter extraction"
return common_roc.get_param_roc(easiroc_pool,easiroc_id,param_name)