Source code for yellow_blocks.adc16

from .yellow_block import YellowBlock
from verilog import VerilogModule
from constraints import PortConstraint, ClockConstraint

[docs]class adc16(YellowBlock):
[docs] def initialize(self): # num_units is the number of ADC chips # board_count is the number of boards self.num_units = 4*self.board_count if self.zdok_rev == 2: self.num_clocks = self.board_count else: raise NotImplementedError("adc16 not yet supported for zdok revisions other that 1") # The zdok revision 1 case is not completely implemented (it should be ok up till # physical constraint generation) so barf here. self.clock_freq = self.sample_rate self.add_source('adc16_interface') self.add_source('wb_adc16_controller') self.add_source('wb_bram') self.provides = ['adc0_clk','adc0_clk90', 'adc0_clk180', 'adc0_clk270'] self.requires = ['user_clk'] if self.board_count == 2: self.exc_requires = ['zdok0', 'zdok1'] elif self.board_count == 1: self.exc_requires = ['zdok0'] else: raise NotImplementedError("ADC16 not supported for board counts other than 1 or 2")
[docs] def modify_top(self,top): module = 'adc16_interface' inst = VerilogModule(entity=module, name=self.fullname) inst.add_parameter('G_NUM_CLOCKS', int(self.num_clocks)) inst.add_parameter('G_ZDOK_REV', int(self.zdok_rev)) inst.add_parameter('G_NUM_UNITS', int(self.num_units)) # ports which go to simulink inst.add_port('a1', self.fullname+'_a1') inst.add_port('a2', self.fullname+'_a2') inst.add_port('a3', self.fullname+'_a3') inst.add_port('a4', self.fullname+'_a4') inst.add_port('b1', self.fullname+'_b1') inst.add_port('b2', self.fullname+'_b2') inst.add_port('b3', self.fullname+'_b3') inst.add_port('b4', self.fullname+'_b4') inst.add_port('c1', self.fullname+'_c1') inst.add_port('c2', self.fullname+'_c2') inst.add_port('c3', self.fullname+'_c3') inst.add_port('c4', self.fullname+'_c4') inst.add_port('d1', self.fullname+'_d1') inst.add_port('d2', self.fullname+'_d2') inst.add_port('d3', self.fullname+'_d3') inst.add_port('d4', self.fullname+'_d4') inst.add_port('e1', self.fullname+'_e1') inst.add_port('e2', self.fullname+'_e2') inst.add_port('e3', self.fullname+'_e3') inst.add_port('e4', self.fullname+'_e4') inst.add_port('f1', self.fullname+'_f1') inst.add_port('f2', self.fullname+'_f2') inst.add_port('f3', self.fullname+'_f3') inst.add_port('f4', self.fullname+'_f4') inst.add_port('g1', self.fullname+'_g1') inst.add_port('g2', self.fullname+'_g2') inst.add_port('g3', self.fullname+'_g3') inst.add_port('g4', self.fullname+'_g4') inst.add_port('h1', self.fullname+'_h1') inst.add_port('h2', self.fullname+'_h2') inst.add_port('h3', self.fullname+'_h3') inst.add_port('h4', self.fullname+'_h4') top.add_signal(self.fullname+'_a1', width=8) top.add_signal(self.fullname+'_a2', width=8) top.add_signal(self.fullname+'_a3', width=8) top.add_signal(self.fullname+'_a4', width=8) top.add_signal(self.fullname+'_b1', width=8) top.add_signal(self.fullname+'_b2', width=8) top.add_signal(self.fullname+'_b3', width=8) top.add_signal(self.fullname+'_b4', width=8) top.add_signal(self.fullname+'_c1', width=8) top.add_signal(self.fullname+'_c2', width=8) top.add_signal(self.fullname+'_c3', width=8) top.add_signal(self.fullname+'_c4', width=8) top.add_signal(self.fullname+'_d1', width=8) top.add_signal(self.fullname+'_d2', width=8) top.add_signal(self.fullname+'_d3', width=8) top.add_signal(self.fullname+'_d4', width=8) top.add_signal(self.fullname+'_e1', width=8) top.add_signal(self.fullname+'_e2', width=8) top.add_signal(self.fullname+'_e3', width=8) top.add_signal(self.fullname+'_e4', width=8) top.add_signal(self.fullname+'_f1', width=8) top.add_signal(self.fullname+'_f2', width=8) top.add_signal(self.fullname+'_f3', width=8) top.add_signal(self.fullname+'_f4', width=8) top.add_signal(self.fullname+'_g1', width=8) top.add_signal(self.fullname+'_g2', width=8) top.add_signal(self.fullname+'_g3', width=8) top.add_signal(self.fullname+'_g4', width=8) top.add_signal(self.fullname+'_h1', width=8) top.add_signal(self.fullname+'_h2', width=8) top.add_signal(self.fullname+'_h3', width=8) top.add_signal(self.fullname+'_h4', width=8) # ports which go to the wb controller. Any ports which don't go to top level need # corresponding signals to be added to top.v inst.add_port('fabric_clk', 'adc0_clk') inst.add_port('fabric_clk_90', 'adc0_clk90') inst.add_port('fabric_clk_180', 'adc0_clk180') inst.add_port('fabric_clk_270', 'adc0_clk270') top.add_signal('adc0_clk') top.add_signal('adc0_clk_90') top.add_signal('adc0_clk_180') top.add_signal('adc0_clk_270') inst.add_port('reset', 'adc16_reset') inst.add_port('iserdes_bitslip', 'adc16_iserdes_bitslip') top.add_signal('adc16_reset') top.add_signal('adc16_iserdes_bitslip', width=64) inst.add_port('delay_rst', 'adc16_delay_rst') inst.add_port('delay_tap', 'adc16_delay_tap') top.add_signal('adc16_delay_rst', width=64) top.add_signal('adc16_delay_tap', width=5) inst.add_port('snap_req', 'adc16_snap_req') inst.add_port('snap_we', 'adc16_snap_we') inst.add_port('snap_addr', 'adc16_snap_addr') top.add_signal('adc16_snap_req', width=1) top.add_signal('adc16_snap_we', width=1) top.add_signal('adc16_snap_addr', width=10) inst.add_port('locked', 'adc16_locked') top.add_signal('adc16_locked', width=2) # Now the external ports, which need corresponding ports adding to top.v if self.zdok_rev == 2: inst.add_port('clk_frame_p', '0') inst.add_port('clk_frame_n', '0') else: inst.add_port('clk_frame_p', 'adc16_clk_frame_p') top.add_port('clk_frame_p', 'in', width=int(self.num_units)) inst.add_port('clk_frame_n', 'adc16_clk_frame_n') top.add_port('clk_frame_n', 'in', width=int(self.num_units)) inst.add_port('clk_line_p', 'adc16_clk_line_p') inst.add_port('clk_line_n', 'adc16_clk_line_n') inst.add_port('ser_a_p', 'adc16_ser_a_p') inst.add_port('ser_a_n', 'adc16_ser_a_n') inst.add_port('ser_b_p', 'adc16_ser_b_p') inst.add_port('ser_b_n', 'adc16_ser_b_n') top.add_port('adc16_clk_line_p', 'in', width=self.num_clocks) top.add_port('adc16_clk_line_n', 'in', width=self.num_clocks) top.add_port('adc16_ser_a_p', 'in', width=4*self.num_units) top.add_port('adc16_ser_a_n', 'in', width=4*self.num_units) top.add_port('adc16_ser_b_p', 'in', width=4*self.num_units) top.add_port('adc16_ser_b_n', 'in', width=4*self.num_units) top.add_instance(inst) # wb controller wbctrl = VerilogModule(entity='wb_adc16_controller', name='wb_adc16_controller') wbctrl.add_parameter('G_ROACH2_REV', int(self.roach2_rev)) wbctrl.add_parameter('G_ZDOK_REV', int(self.zdok_rev)) wbctrl.add_parameter('G_NUM_UNITS', int(self.num_units)) # These are top-level ports -- they don't need signal declarations, # but they do need ports added to the top-level wbctrl.add_port('adc0_adc3wire_csn1', 'adc0_adc3wire_csn1') wbctrl.add_port('adc0_adc3wire_csn2', 'adc0_adc3wire_csn2') wbctrl.add_port('adc0_adc3wire_csn3', 'adc0_adc3wire_csn3') wbctrl.add_port('adc0_adc3wire_csn4', 'adc0_adc3wire_csn4') wbctrl.add_port('adc0_adc3wire_sdata','adc0_adc3wire_sdata') wbctrl.add_port('adc0_adc3wire_sclk', 'adc0_adc3wire_sclk') top.add_port('adc0_adc3wire_csn1', 'out') top.add_port('adc0_adc3wire_csn2', 'out') top.add_port('adc0_adc3wire_csn3', 'out') top.add_port('adc0_adc3wire_csn4', 'out') top.add_port('adc0_adc3wire_sdata','out') top.add_port('adc0_adc3wire_sclk', 'out') if self.num_units > 4: wbctrl.add_port('adc1_adc3wire_csn1', 'adc1_adc3wire_csn1') wbctrl.add_port('adc1_adc3wire_csn2', 'adc1_adc3wire_csn2') wbctrl.add_port('adc1_adc3wire_csn3', 'adc1_adc3wire_csn3') wbctrl.add_port('adc1_adc3wire_csn4', 'adc1_adc3wire_csn4') wbctrl.add_port('adc1_adc3wire_sdata','adc1_adc3wire_sdata') wbctrl.add_port('adc1_adc3wire_sclk', 'adc1_adc3wire_sclk') top.add_port('adc1_adc3wire_csn1', 'out') top.add_port('adc1_adc3wire_csn2', 'out') top.add_port('adc1_adc3wire_csn3', 'out') top.add_port('adc1_adc3wire_csn4', 'out') top.add_port('adc1_adc3wire_sdata','out') top.add_port('adc1_adc3wire_sclk', 'out') else: wbctrl.add_port('adc1_adc3wire_csn1', '') wbctrl.add_port('adc1_adc3wire_csn2', '') wbctrl.add_port('adc1_adc3wire_csn3', '') wbctrl.add_port('adc1_adc3wire_csn4', '') wbctrl.add_port('adc1_adc3wire_sdata','') wbctrl.add_port('adc1_adc3wire_sclk', '') # internal connections to the adc controller. We have already declared the corresponding # signals earlier. wbctrl.add_port('adc16_reset','adc16_reset') wbctrl.add_port('adc16_iserdes_bitslip','adc16_iserdes_bitslip') wbctrl.add_port('adc16_delay_rst', 'adc16_delay_rst') wbctrl.add_port('adc16_delay_tap', 'adc16_delay_tap') wbctrl.add_port('adc16_snap_req', 'adc16_snap_req') wbctrl.add_port('adc16_locked', 'adc16_locked') # and finally the wb interface wbctrl.add_wb_interface(nbytes=2**16) top.add_instance(wbctrl) snap_chan = ['a','b','c','d','e','f','g','h'] for k in range(self.num_units): # Embedded wb-RAM din = self.fullname+'_%s'%snap_chan[k] wbram = VerilogModule(entity='wb_bram', name='adc16_wb_ram%d'%k) wbram.add_parameter('LOG_USER_WIDTH','5') wbram.add_parameter('USER_ADDR_BITS','10') wbram.add_parameter('N_REGISTERS','2') wbram.add_wb_interface(nbytes=4*2**10) wbram.add_port('user_clk','user_clk', parent_sig=False) wbram.add_port('user_addr','adc16_snap_addr') wbram.add_port('user_din','{%s1, %s2, %s3, %s4}'%(din,din,din,din)) wbram.add_port('user_we','adc16_snap_we') wbram.add_port('user_dout','') top.add_instance(wbram)
[docs] def gen_constraints(self): cons = [] # ADC SPI interface cons.append(PortConstraint('adc0_adc3wire_csn1', 'zdok0', iogroup_index=21)) cons.append(PortConstraint('adc0_adc3wire_csn2', 'zdok0', iogroup_index=41)) cons.append(PortConstraint('adc0_adc3wire_csn3', 'zdok0', iogroup_index=3)) cons.append(PortConstraint('adc0_adc3wire_csn4', 'zdok0', iogroup_index=40)) cons.append(PortConstraint('adc0_adc3wire_sdata', 'zdok0', iogroup_index=20)) cons.append(PortConstraint('adc0_adc3wire_sclk', 'zdok0', iogroup_index=2)) # SPI interface for the second zdok, if we're using it... if self.num_units > 4: cons.append(PortConstraint('adc1_adc3wire_csn1', 'zdok1', iogroup_index=21)) cons.append(PortConstraint('adc1_adc3wire_csn2', 'zdok1', iogroup_index=41)) cons.append(PortConstraint('adc1_adc3wire_csn3', 'zdok1', iogroup_index=3)) cons.append(PortConstraint('adc1_adc3wire_csn4', 'zdok1', iogroup_index=40)) cons.append(PortConstraint('adc1_adc3wire_sdata', 'zdok1', iogroup_index=20)) cons.append(PortConstraint('adc1_adc3wire_sclk', 'zdok1', iogroup_index=2)) cons.append(PortConstraint('adc16_clk_line_p', 'zdok0_p', iogroup_index=39)) cons.append(PortConstraint('adc16_clk_line_n', 'zdok0_n', iogroup_index=39)) # older zdok revisions need a frame clock... #ZDOK pins. ZDOK differential index # 'a' signals # D7 23 # F5 32 # C5 12 # A5 2 # D11 25 # F9 34 # C9 14 # F7 33 # F15 37 # A15 7 # C13 16 # A13 6 # A19 9 # C19 19 # D17 28 # A17 8 # 'b' signals # C7 13 # A7 3 # D5 22 # F3 31 # C11 15 # A11 5 # D9 24 # A9 4 # D15 27 # F13 36 # D13 26 # F11 35 # D19 29 # C17 18 # F17 38 # C15 17 a_group = [ 23, 32, 12, 2, 25, 34, 14, 33, 37, 7, 16, 6, 9, 19, 28, 8, ] b_group = [ 13, 3, 22, 31, 15, 5, 24, 4, 27, 36, 26, 35, 29, 18, 38, 17, ] cons.append(PortConstraint('adc16_ser_a_p', 'zdok0_p', port_index=list(range(16)), iogroup_index=a_group)) cons.append(PortConstraint('adc16_ser_a_n', 'zdok0_n', port_index=list(range(16)), iogroup_index=a_group)) cons.append(PortConstraint('adc16_ser_b_p', 'zdok0_p', port_index=list(range(16)), iogroup_index=b_group)) cons.append(PortConstraint('adc16_ser_b_n', 'zdok0_n', port_index=list(range(16)), iogroup_index=b_group)) if self.num_units > 4: cons.append(PortConstraint('adc16_ser_a_p', 'zdok1_p', port_index=list(range(16,32)), iogroup_index=a_group)) cons.append(PortConstraint('adc16_ser_a_n', 'zdok1_n', port_index=list(range(16,32)), iogroup_index=a_group)) cons.append(PortConstraint('adc16_ser_b_p', 'zdok1_p', port_index=list(range(16,32)), iogroup_index=b_group)) cons.append(PortConstraint('adc16_ser_b_n', 'zdok1_n', port_index=list(range(16,32)), iogroup_index=b_group)) # clock constraint with variable period cons.append(ClockConstraint('adc16_clk_line_p', name='adc_clk', freq=self.clock_freq)) return cons