TTL gate

Purpose of this module:

  • Generate gate signal for SPD, level TTL 3.3V out of FPGA (level is converted on Bread70 for SPD)
  • Duty cycle > 5ns
  • Delay full range 12.5ns, fine delay in 100ps step

Port descriptions

Signals nameInterfaceDirInit statusDescription
axil signalss_axilIO-standard axilite interface for r/w registers
s_axil_aclkClockI15MHzclock for axil interface
s_axil_aresetnResetI-reset for axil interface, active LOW
clk240ClockI240MHzclock to generate gate signal
clk80ClockI80MHzclock for fine delay this gate signal
pps_i-I-PPS from WRS
ttl_rstResetI-reset for logic, active HIGH
pulse_n/p-O-output to pins
pulse_rep_n/p-O-output to pins, without fine delay

User parameters

ParameterValueDescription
C_S_Axil_Addr_Width8Address width of axil interface
C_S_Axil_Data_Width32Address width of axil interface
DELAY FORMATCOUNTDelay format for ODELAY3
DELAY TYPEVARIABLEDelay type for ODELAY3
DELAY VALUE50need to be between 45-65 taps for IDELAY3 calibrates correctly
REFCLK FRE300refclk for IDELAY3 and ODELAY3, default
UPDATE MODEASYNCupdate by logic control

Axil registers

  • Base address: 0x0001_5000
  • Offset address slv_reg(n) : 4*n

slv_reg0 - R/W Access - Trigger Control

BitsSignal nameHW WireAction/ValueDescription
31:1---Reserved 0
0ttl_trigger_enstep_oen_steppull 0-1-0.Stay HIGH long enough
coresponding resolution
trigger fine delay master

For example:

  • Set fine delay tapes = 500 in software
  • Resolution = 500*16 = 8000 (80MHz periods) = 0.1ms
  • Trigger should stay HIGH longer than 0.1ms

This works the same for slave 1 and slave 2 cascaded to master

slv_reg1 - R/W Access - Configuration

BitsSignal nameHW WireAction/ValueDescription
31:23--Reserved 0
22:19ttl_params_oduty_valSet duty cycle width, 1 step is 1 period of 240MHz
18:15ttl_params_odelay_valSet tune step, 1 step is 1 period of 240MHz
14:1ttl_params_oresolutionmax is 8192Set length of fine delay step on master ODELAY3
0ttl_params_oincrease_en1: increase
0: decrease
Set fine delay direction on master ODELAY3

The resolution is in unit of [80MHz period]

  • Maximum fine delay tap: 512
  • Require 16 clk cycles for each tap
  • Resolution = 512*16 = 8192

slv_reg2 - R/W Access - Trigger Control

BitsSignal nameHW WireAction/ValueDescription
31:1---Reserved 0
0ttl_params_en_ottl_params_en_opull 0-1Enable register update

slv_reg3 - R/W Access - Configuration

BitsSignal nameHW WireAction/ValueDescription
31--Reserved 0
30:17ttl_params_slv_oresolution_slv2max is 8192Set length of fine delay step on slave 2 ODELAY3
16ttl_params_slv_oincrease_en_slv21: increase
0: decrease
Set fine delay direction on slave 2 ODELAY3
14:1ttl_params_slv_oresolution_slv1max is 8192Set length of fine delay step on slave 1 ODELAY3
0ttl_params_slv_oincrease_en_slv11: increase
0: decrease
Set fine delay direction on slave 1 ODELAY3

slv_reg4 - R/W Access - Trigger Control

BitsSignal nameHW WireAction/ValueDescription
31:1---Reserved 0
0ttl_trigger_enstep_slv1_oen_step_slv1pull 0-1-0.Stay HIGH long enough
coresponding resolution
trigger fine delay slave 1

slv_reg5 - R/W Access - Trigger Control

BitsSignal nameHW WireAction/ValueDescription
31:1---Reserved 0
0ttl_trigger_enstep_slv2_oen_step_slv2pull 0-1-0.Stay HIGH long enough
coresponding resolution
trigger fine delay slave 2

Software control

Generate signal

  • Clock domain: 240 MHz
  • Trigger PPS and align the pulse to PPS
  • Change duty and tune delay the pulse with duty_val and delay_val
  • Output will be fed into fine delay

These are the base functions allow to set registers, generate signal, change duty cycle and tune delay

def ttl_reset():
    Write(0x0001200c,0x01)
    Write(0x0001200c,0x00)
    time.sleep(2)
def calculate_delay(duty, tune, fine, inc):
    fine_clock_num = fine*16
    transfer = duty<<19|tune<<15|fine_clock_num<<1|inc
    transfer_bin = bin(transfer)
    transfer_hex = hex(transfer)
    return transfer_hex
def write_delay_master(duty, tune, fine, inc):
    Base_Add = 0x00015004 
    transfer = calculate_delay(duty, tune, fine, inc)
    Write(Base_Add,transfer)
def write_delay_slaves(fine1, inc1, fine2, inc2):
    Base_Add = 0x0001500c
    transfer = (fine2*16)<<17|inc2<<16|(fine1*16)<<1|inc1
    Write(Base_Add, hex(transfer))
def params_en():
    Base_Add = 0x0015008
    Write(Base_Add,0x00)
    Write(Base_Add,0x01)

Fine delay

AMD support ODELAYE3 primitives to delay a signal in ps step, full range is 1,25ns. Read UG974 and UG571 for more details

Tune delay step is around 4,16ns. So, I choose Cascade configuration for ODELAYE3

  • DELAY_FORMAT = COUNT
  • DELAY_TYPE = VARIABLE
  • UPDATE_MODE = ASYNC

Trigger the fine delay on master and 2 slaves, every trigger will shift your signal fine [taps] set in write_delay_* function

def trigger_fine_master():
    Base_Add = 0x00015000
    Write(Base_Add, 0x0)
    Write(Base_Add, 0x1)
    time.sleep(0.02)
    Write(Base_Add, 0x0)
    print("Trigger master done")
def trigger_fine_slv1():
    Base_Add = 0x00015000
    Write(Base_Add + 16, 0x0)
    Write(Base_Add + 16, 0x1)
    time.sleep(0.02)
    Write(Base_Add + 16, 0x0)
    print("Trigger slave1 done")
def trigger_fine_slv2():
    Base_Add = 0x00015000
    Write(Base_Add + 20, 0x0)
    Write(Base_Add + 20, 0x1)
    time.sleep(0.02)
    Write(Base_Add + 20, 0x0)
    print("Trigger slave2 done")