#!/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=64
maroc3_pool=pools.pool("maroc3")
maroc3_bs_length=829
#************************* BITSTREAM MANIPULATION FUNCTIONS ***************
# **************************************************************************
# Powerpulsing bandgap
# **************************************************************************
def extract_pp_bandgap(maroc3):
return maroc3["bitstream_bin"][0:1]
[docs]def set_pp_bandgap_maroc3(maroc3_id,value):
"Activate (ON or 1) or desactivate (OFF or 0) power pulsing (pp) for bandgap"
return common_roc.apply_to_roc(maroc3_pool,maroc3_id,extract_pp_bandgap,common_roc.on_off_bit,"pp_bandgap",0,value)
# **************************************************************************
# Powerpulsing DACs
# **************************************************************************
def extract_pp_dacs(maroc3):
return maroc3["bitstream_bin"][1:2]
[docs]def set_pp_dacs_maroc3(maroc3_id,value):
"Activate (ON or 1) or desactivate (OFF or 0) power pulsing (pp) for all DACs"
return common_roc.apply_to_roc(maroc3_pool,maroc3_id,extract_pp_dacs,common_roc.on_off_bit,"pp_dacs",1,value)
# **************************************************************************
# Small DAC
# **************************************************************************
def extract_small_dac(maroc3):
return maroc3["bitstream_bin"][2:3]
[docs]def set_small_dac_maroc3(maroc3_id,value):
"Decrease (ON or 1) or not (OFF or 0) the slope of DAC0 to have better accuracy."
return common_roc.apply_to_roc(maroc3_pool,maroc3_id,extract_small_dac,common_roc.on_off_bit,"small_dac",2,value)
# **************************************************************************
# DAC values
# **************************************************************************
def extract_dac0(maroc3):
return str(int(maroc3["bitstream_bin"][13:23],2))
def set_dac0_reg(maroc3,value):
if value!="undef":
return common_roc.apply_mask(maroc3,13,common_roc.split_bin(int(value),10))
return 1,"ok"
[docs]def set_dac0_maroc3(maroc3_id,value):
"Set DAC0 (first discriminator) *value* (integer in 10-bit)"
return common_roc.apply_to_roc(maroc3_pool,maroc3_id,extract_dac0,set_dac0_reg,"dac0",value)
# **************************************************************************
def extract_dac1(maroc3):
return str(int(maroc3["bitstream_bin"][3:13],2))
def set_dac1_reg(maroc3,value):
if value!="undef":
return common_roc.apply_mask(maroc3,3,common_roc.split_bin(int(value),10))
return 1,"ok"
[docs]def set_dac1_maroc3(maroc3_id,value):
"Set DAC1 (second discriminator) *value* (integer in 10-bit)"
return common_roc.apply_to_roc(maroc3_pool,maroc3_id,extract_dac1,set_dac1_reg,"dac1",value)
# **************************************************************************
# Wilkinson ADC
# **************************************************************************
def extract_data_output_wlk(maroc3):
return maroc3["bitstream_bin"][23:24]
[docs]def set_data_output_wlk_maroc3(maroc3_id,value):
"Enable (ON or 1) or disable (OFF or 0) data output. Must be OFF to use the Wilkinson ADC"
return common_roc.apply_to_roc(maroc3_pool,maroc3_id,extract_data_output_wlk,common_roc.on_off_bit,"data_output_wlk",23,value)
# **************************************************************************
def extract_inv_start_counter_wlk(maroc3):
return maroc3["bitstream_bin"][24:25]
[docs]def set_inv_start_counter_wlk_maroc3(maroc3_id,value):
"Set the start counter polarity switching"
return common_roc.apply_to_roc(maroc3_pool,maroc3_id,extract_inv_start_counter_wlk,common_roc.on_off_bit,"inv_start_counter_wlk",24,value)
# **************************************************************************
def extract_ramp_8bit_wlk(maroc3):
return maroc3["bitstream_bin"][25:26]
[docs]def set_ramp_8bit_wlk_maroc3(maroc3_id,value):
"Set 8bit ramp slope"
return common_roc.apply_to_roc(maroc3_pool,maroc3_id,extract_ramp_8bit_wlk,common_roc.on_off_bit,"ramp_8bit_wlk",25,value)
# **************************************************************************
def extract_ramp_10bit_wlk(maroc3):
return maroc3["bitstream_bin"][26:27]
[docs]def set_ramp_10bit_wlk_maroc3(maroc3_id,value):
"Set 10bit ramp slope"
return common_roc.apply_to_roc(maroc3_pool,maroc3_id,extract_ramp_10bit_wlk,common_roc.on_off_bit,"ramp_10bit_wlk",26,value)
# **************************************************************************
# Discriminator outputs
# **************************************************************************
def extract_disallow_trig_or1_chans(maroc3):
return common_roc.extract_bit_chans(maroc3,28,2,1)
def disallow_trig_or1(maroc3,chan):
return common_roc.on_off_bit(maroc3,28+(63-chan)*2,1)
[docs]def disallow_trig_or1_chans_maroc3(maroc3_id,chans):
"Mask channels *chans* (no trigger output) on the first discriminator (OR1)"
retcode,res=common_roc.apply_to_chans(maroc3_pool,maroc3_id,chans,extract_disallow_trig_or1_chans,disallow_trig_or1,"disallow_trig_or1_chans")
if retcode==0:
return 0,res
maroc3=maroc3_pool.get(maroc3_id)
maroc3["allow_trig_or1_chans"]=extract_allow_trig_or1_chans(maroc3)
return 1,"ok"
# **************************************************************************
def extract_allow_trig_or1_chans(maroc3):
return common_roc.extract_bit_chans(maroc3,28,2,0)
def allow_trig_or1(maroc3,chan):
return common_roc.on_off_bit(maroc3,28+(63-chan)*2,0)
[docs]def allow_trig_or1_chans_maroc3(maroc3_id,chans):
"Unmask channels *chans* (trigger output visible) on the first discriminator (OR1)"
retcode,res=common_roc.apply_to_chans(maroc3_pool,maroc3_id,chans,extract_allow_trig_or1_chans,allow_trig_or1,"allow_trig_or1_chans")
if retcode==0:
return 0,res
maroc3=maroc3_pool.get(maroc3_id)
maroc3["disallow_trig_or1_chans"]=extract_disallow_trig_or1_chans(maroc3)
return 1,"ok"
# **************************************************************************
def extract_disallow_trig_or2_chans(maroc3):
return common_roc.extract_bit_chans(maroc3,27,2,1)
def disallow_trig_or2(maroc3,chan):
return common_roc.on_off_bit(maroc3,27+(63-chan)*2,1)
[docs]def disallow_trig_or2_chans_maroc3(maroc3_id,chans):
"Mask channels *chans* (no trigger output) on the first discriminator (OR2)"
retcode,res=common_roc.apply_to_chans(maroc3_pool,maroc3_id,chans,extract_disallow_trig_or2_chans,disallow_trig_or2,"disallow_trig_or2_chans")
if retcode==0:
return 0,res
maroc3=maroc3_pool.get(maroc3_id)
maroc3["allow_trig_or2_chans"]=extract_allow_trig_or2_chans(maroc3)
return 1,"ok"
# **************************************************************************
def extract_allow_trig_or2_chans(maroc3):
return common_roc.extract_bit_chans(maroc3,27,2,0)
def allow_trig_or2(maroc3,chan):
return common_roc.on_off_bit(maroc3,27+(63-chan)*2,0)
[docs]def allow_trig_or2_chans_maroc3(maroc3_id,chans):
"Unmask channels *chans* (trigger output visible) on the first discriminator (OR2)"
retcode,res=common_roc.apply_to_chans(maroc3_pool,maroc3_id,chans,extract_allow_trig_or2_chans,allow_trig_or2,"allow_trig_or2_chans")
if retcode==0:
return 0,res
maroc3=maroc3_pool.get(maroc3_id)
maroc3["disallow_trig_or2_chans"]=extract_disallow_trig_or2_chans(maroc3)
return 1,"ok"
# **************************************************************************
# 33 bits 156 to 188
# **************************************************************************
def extract_from_156_to_188(maroc3):
return "0b"+maroc3["bitstream_bin"][156:189]
def set_from_156_to_188_reg(maroc3,value):
if value!="undef":
retcode,res=common_roc.load_str(value,33)
if retcode==0:
return 0,"Error reading value to be applied: %s"%(res)
value_bin=res
return common_roc.apply_mask(maroc3,156,value_bin)
return 1,"ok"
[docs]def set_from_156_to_188_maroc3(maroc3_id,value):
"Set value of the 33bits ranging from the bit 156 to 188. *value* has bitstream format (hexadecimal preceded by 0x, binary by 0b or decimal integer."
return common_roc.apply_to_roc(maroc3_pool,maroc3_id,extract_from_156_to_188,set_from_156_to_188_reg,"from_156_to_188",value)
# **************************************************************************
# Preamps gains
# **************************************************************************
def set_preamp_gain(maroc3,chan,value):
return common_roc.apply_mask(maroc3,190+(63-chan)*9,common_roc.split_bin(value,8))
[docs]def set_preamp_gain_chans_maroc3(maroc3_id,chans,value):
"Set preamp gain for channels *chans*. 8-bit *value*"
return common_roc.apply_to_chans(maroc3_pool,maroc3_id,chans,None,set_preamp_gain,"undef",value)
# **************************************************************************
def extract_enable_sum_chans(maroc3):
return common_roc.extract_bit_chans(maroc3,189,9,1)
def enable_sum(maroc3,chan):
return common_roc.on_off_bit(maroc3,189+(63-chan)*9,1)
[docs]def enable_sum_chans_maroc3(maroc3_id,chans):
"Enable signal from channel *chan* for sum"
retcode,res=common_roc.apply_to_chans(maroc3_pool,maroc3_id,chans,extract_enable_sum_chans,enable_sum,"enable_sum_chans")
if retcode==0:
return 0,res
maroc3=maroc3_pool.get(maroc3_id)
maroc3["disable_sum_chans"]=extract_disable_sum_chans(maroc3)
return 1,"ok"
# **************************************************************************
def extract_disable_sum_chans(maroc3):
return common_roc.extract_bit_chans(maroc3,189,9,0)
def disable_sum(maroc3,chan):
return common_roc.on_off_bit(maroc3,189+(63-chan)*9,0)
[docs]def disable_sum_chans_maroc3(maroc3_id,chans):
"Disable signal from channel *chan* for sum"
retcode,res=common_roc.apply_to_chans(maroc3_pool,maroc3_id,chans,extract_disable_sum_chans,disable_sum,"disable_sum_chans")
if retcode==0:
return 0,res
maroc3=maroc3_pool.get(maroc3_id)
maroc3["enable_sum_chans"]=extract_enable_sum_chans(maroc3)
return 1,"ok"
# **************************************************************************
# Ctest input
# **************************************************************************
def extract_enable_ctest_chans(maroc3):
return common_roc.extract_bit_chans(maroc3,765,1,1)
def enable_ctest(maroc3,chan):
return common_roc.on_off_bit(maroc3,765+(63-chan),1)
[docs]def enable_ctest_chans_maroc3(maroc3_id,chans):
"Enable signal from channel *chan* in Ctest input"
retcode,res=common_roc.apply_to_chans(maroc3_pool,maroc3_id,chans,extract_enable_ctest_chans,enable_ctest,"enable_ctest_chans")
if retcode==0:
return 0,res
maroc3=maroc3_pool.get(maroc3_id)
maroc3["disable_ctest_chans"]=extract_disable_ctest_chans(maroc3)
return 1,"ok"
# **************************************************************************
def extract_disable_ctest_chans(maroc3):
return common_roc.extract_bit_chans(maroc3,765,1,0)
def disable_ctest(maroc3,chan):
return common_roc.on_off_bit(maroc3,765+(63-chan),0)
[docs]def disable_ctest_chans_maroc3(maroc3_id,chans):
"Disable signal from channel *chan* in Ctest input"
retcode,res=common_roc.apply_to_chans(maroc3_pool,maroc3_id,chans,extract_disable_ctest_chans,disable_ctest,"disable_ctest_chans")
if retcode==0:
return 0,res
maroc3=maroc3_pool.get(maroc3_id)
maroc3["enable_ctest_chans"]=extract_enable_ctest_chans(maroc3)
return 1,"ok"
#********************************** GENERAL PUBLIC FUNCTIONS ***************
[docs]def dump_sc_maroc3(maroc3_id):
"Returns bitstream of *maroc3_id* in binary format"
try:
maroc3=maroc3_pool.get(maroc3_id)
except Exception as e:
return 0,str(e)
#return the bitstream
bitstream=maroc3["bitstream_bin"] if not maroc3["missing"] else ""
print("bitstream length: %d"%(len(bitstream)))
bitstream="0"*107 + bitstream
print("padding to match spiroc length... (using spiroc DIF firmware)")
print("bitstream length: %d"%(len(bitstream)))
return 1,bitstream
[docs]def set_missing_maroc3(maroc3_id,missing):
"Set maroc3 missing state"
try:
maroc3=maroc3_pool.get(maroc3_id)
except Exception as e:
return 0,str(e)
maroc3["missing"]=1 if missing=="1" else 0
return 1,"ok"
#****************************** PHASES *************************************
[docs]def init_maroc3(maroc3_id):
"Initialize a maroc3"
maroc3_pool.new(maroc3_id,{"missing":0})
return 1,"ok"
[docs]def deinit_maroc3(maroc3_id):
"Deinitialize *maroc3_id*"
try:
maroc3=maroc3_pool.get(maroc3_id)
except Exception as e:
return 1,str(e)
maroc3_pool.remove(maroc3_id)
return 1,"ok"
[docs]def config_maroc3(maroc3_id,file,bitstream,pp_bandgap,pp_dacs,small_dac,dac0,dac1,data_output_wlk,inv_start_counter_wlk,ramp_8bit_wlk,ramp_10bit_wlk,from_156_to_188,allow_trig_or1_chans,disallow_trig_or1_chans,allow_trig_or2_chans,disallow_trig_or2_chans,enable_sum_chans,disable_sum_chans,enable_ctest_chans,disable_ctest_chans):
"Prepare the bitstream for configuring a chip"
try:
maroc3=maroc3_pool.get(maroc3_id)
except Exception as e:
return 0,str(e)
#empty the bitstream
maroc3["bitstream_bin"]=""
#load bitstream
if bitstream!="undef":
retcode,res=common_roc.load_str(bitstream,maroc3_bs_length)
if retcode==0:
return 0,"cant parse bitstream: %s"%(res)
maroc3["bitstream_bin"]=res
#load bitstream from file
if file!="undef":
retcode,res=common_roc.load_file(file,maroc3_bs_length)
if retcode==0:
return 0,"cant open config file: %s"%(res)
maroc3["bitstream_bin"]=res
if maroc3["bitstream_bin"]=="":
return 0,"no bitstream defined for maroc3 %s"%(maroc3_id)
# set pp gandagp
retcode,res=set_pp_bandgap_maroc3(maroc3_id,pp_bandgap)
if retcode==0:
return 0,res
# set pp dacs
retcode,res=set_pp_dacs_maroc3(maroc3_id,pp_dacs)
if retcode==0:
return 0,res
# set small dac value
retcode,res=set_small_dac_maroc3(maroc3_id,small_dac)
if retcode==0:
return 0,res
# set dac0 value
retcode,res=set_dac0_maroc3(maroc3_id,dac0)
if retcode==0:
return 0,res
# set dac1 value
retcode,res=set_dac1_maroc3(maroc3_id,dac1)
if retcode==0:
return 0,res
# set Wilkinson data output
retcode,res=set_data_output_wlk_maroc3(maroc3_id,data_output_wlk)
if retcode==0:
return 0,res
# set Wilkinson invert counter
retcode,res=set_inv_start_counter_wlk_maroc3(maroc3_id,inv_start_counter_wlk)
if retcode==0:
return 0,res
# set 8bit Wilkinson ramp
retcode,res=set_ramp_8bit_wlk_maroc3(maroc3_id,ramp_8bit_wlk)
if retcode==0:
return 0,res
# set 10bit Wilkinson ramp
retcode,res=set_ramp_10bit_wlk_maroc3(maroc3_id,ramp_10bit_wlk)
if retcode==0:
return 0,res
# set bits from 156 to 188 (33bits)
retcode,res=set_from_156_to_188_maroc3(maroc3_id,from_156_to_188)
if retcode==0:
return 0,res
# allow OR1 trigger in channels
retcode,res=allow_trig_or1_chans_maroc3(maroc3_id,allow_trig_or1_chans)
if retcode==0:
return 0,res
# disallow OR1 trigger in channels
retcode,res=disallow_trig_or1_chans_maroc3(maroc3_id,disallow_trig_or1_chans)
if retcode==0:
return 0,res
# allow OR2 trigger in channels
retcode,res=allow_trig_or2_chans_maroc3(maroc3_id,allow_trig_or2_chans)
if retcode==0:
return 0,res
# disallow OR2 trigger in channels
retcode,res=disallow_trig_or2_chans_maroc3(maroc3_id,disallow_trig_or2_chans)
if retcode==0:
return 0,res
# enable signal from channels for sum
retcode,res=enable_sum_chans_maroc3(maroc3_id,enable_sum_chans)
if retcode==0:
return 0,res
# disable signal from channels for sum
retcode,res=disable_sum_chans_maroc3(maroc3_id,disable_sum_chans)
if retcode==0:
return 0,res
# enable signal from channel for Ctest input
retcode,res=enable_ctest_chans_maroc3(maroc3_id,enable_ctest_chans)
if retcode==0:
return 0,res
# disable signal from channel for Ctest input
retcode,res=disable_ctest_chans_maroc3(maroc3_id,disable_ctest_chans)
if retcode==0:
return 0,res
#update the bitstream in cmod
common_roc.update_bitstream(maroc3)
return 1,"ok"
[docs]def get_param_maroc3(maroc3_id,param_name):
"parameter extraction"
return common_roc.get_param_roc(maroc3_pool,maroc3_id,param_name)