├── .gitattributes ├── README.md ├── chipfail-glitcher.srcs ├── constrs_1 │ └── CmodA7_B.xdc ├── sim_1 │ └── new │ │ └── top_tb.v └── sources_1 │ ├── ip │ └── clk_wiz_0 │ │ ├── clk_wiz_0.dcp │ │ ├── clk_wiz_0.v │ │ ├── clk_wiz_0.veo │ │ ├── clk_wiz_0.xci │ │ ├── clk_wiz_0.xdc │ │ ├── clk_wiz_0.xml │ │ ├── clk_wiz_0_board.xdc │ │ ├── clk_wiz_0_clk_wiz.v │ │ ├── clk_wiz_0_ooc.xdc │ │ ├── clk_wiz_0_sim_netlist.v │ │ ├── clk_wiz_0_sim_netlist.vhdl │ │ ├── clk_wiz_0_stub.v │ │ ├── clk_wiz_0_stub.vhdl │ │ ├── doc │ │ └── clk_wiz_v6_0_changelog.txt │ │ ├── mmcm_pll_drp_func_7s_mmcm.vh │ │ ├── mmcm_pll_drp_func_7s_pll.vh │ │ ├── mmcm_pll_drp_func_us_mmcm.vh │ │ ├── mmcm_pll_drp_func_us_pll.vh │ │ ├── mmcm_pll_drp_func_us_plus_mmcm.vh │ │ └── mmcm_pll_drp_func_us_plus_pll.vh │ └── new │ ├── delay.v │ ├── pulse.v │ ├── top.v │ ├── trigger.v │ ├── uart_definitions.v │ ├── uart_rx.v │ ├── uart_tx.v │ └── uint32_receiver.v ├── chipfail-glitcher.xpr ├── jupyter └── chipfail-glitcher.ipynb └── payloads ├── build.sh ├── samd21_glitch.asm └── saml11_glitch.asm /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Chip.Fail 2 | 3 | Please visit our [website](https://chip.fail/) for details and bare with us while we get our documentation under way. -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/constrs_1/CmodA7_B.xdc: -------------------------------------------------------------------------------- 1 | ## This file is a general .xdc for the CmodA7 rev. B 2 | ## To use it in a project: 3 | ## - uncomment the lines corresponding to used pins 4 | ## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project 5 | 6 | ## 12 MHz Clock Signal 7 | set_property -dict { PACKAGE_PIN L17 IOSTANDARD LVCMOS33 } [get_ports { sys_clk }]; #IO_L12P_T1_MRCC_14 Sch=gclk 8 | create_clock -period 83.330 -name sys_clk_pin -waveform {0.000 41.660} -add [get_ports sys_clk] 9 | 10 | ## LEDs 11 | set_property -dict { PACKAGE_PIN A17 IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; #IO_L12N_T1_MRCC_16 Sch=led[1] 12 | set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L13P_T2_MRCC_16 Sch=led[2] 13 | 14 | ## RGB LED 15 | set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVCMOS33 } [get_ports { rgb[0] }]; #IO_L14N_T2_SRCC_16 Sch=led0_b 16 | set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVCMOS33 } [get_ports { rgb[1] }]; #IO_L13N_T2_MRCC_16 Sch=led0_g 17 | set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { rgb[2] }]; #IO_L14P_T2_SRCC_16 Sch=led0_r 18 | 19 | ## Buttons 20 | set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { btn[0] }]; #IO_L19N_T3_VREF_16 Sch=btn[0] 21 | set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVCMOS33 } [get_ports { btn[1] }]; #IO_L19P_T3_16 Sch=btn[1] 22 | 23 | ## Pmod Header JA 24 | #set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { ja[0] }]; #IO_L5N_T0_D07_14 Sch=ja[1] 25 | #set_property -dict { PACKAGE_PIN G19 IOSTANDARD LVCMOS33 } [get_ports { ja[1] }]; #IO_L4N_T0_D05_14 Sch=ja[2] 26 | #set_property -dict { PACKAGE_PIN N18 IOSTANDARD LVCMOS33 } [get_ports { ja[2] }]; #IO_L9P_T1_DQS_14 Sch=ja[3] 27 | #set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { ja[3] }]; #IO_L8P_T1_D11_14 Sch=ja[4] 28 | #set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { ja[4] }]; #IO_L5P_T0_D06_14 Sch=ja[7] 29 | #set_property -dict { PACKAGE_PIN H19 IOSTANDARD LVCMOS33 } [get_ports { ja[5] }]; #IO_L4P_T0_D04_14 Sch=ja[8] 30 | #set_property -dict { PACKAGE_PIN J19 IOSTANDARD LVCMOS33 } [get_ports { ja[6] }]; #IO_L6N_T0_D08_VREF_14 Sch=ja[9] 31 | #set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { ja[7] }]; #IO_L8N_T1_D12_14 Sch=ja[10] 32 | 33 | ## Analog XADC Pins 34 | ## Only declare these if you want to use pins 15 and 16 as single ended analog inputs. pin 15 -> vaux4, pin16 -> vaux12 35 | #set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports { xa_n[0] }]; #IO_L1N_T0_AD4N_35 Sch=ain_n[15] 36 | #set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports { xa_p[0] }]; #IO_L1P_T0_AD4P_35 Sch=ain_p[15] 37 | #set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports { xa_n[1] }]; #IO_L2N_T0_AD12N_35 Sch=ain_n[16] 38 | #set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { xa_p[1] }]; #IO_L2P_T0_AD12P_35 Sch=ain_p[16] 39 | 40 | ## GPIO Pins 41 | ## Pins 15 and 16 should remain commented if using them as analog inputs 42 | 43 | # Map GPIOs into an array so we can read them 44 | set_property -dict { PACKAGE_PIN M3 IOSTANDARD LVCMOS33 } [get_ports { gpio[0] }]; #IO_L8N_T1_AD14N_35 Sch=pio[01] 45 | set_property -dict { PACKAGE_PIN L3 IOSTANDARD LVCMOS33 } [get_ports { gpio[1] }]; #IO_L8P_T1_AD14P_35 Sch=pio[02] 46 | set_property -dict { PACKAGE_PIN A16 IOSTANDARD LVCMOS33 } [get_ports { gpio[2] }]; #IO_L12P_T1_MRCC_16 Sch=pio[03] 47 | set_property -dict { PACKAGE_PIN K3 IOSTANDARD LVCMOS33 } [get_ports { gpio[3] }]; #IO_L7N_T1_AD6N_35 Sch=pio[04] 48 | set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { gpio[4] }]; #IO_L11P_T1_SRCC_16 Sch=pio[05] 49 | set_property -dict { PACKAGE_PIN H1 IOSTANDARD LVCMOS33 } [get_ports { gpio[5] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=pio[06] 50 | set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVCMOS33 } [get_ports { gpio[6] }]; #IO_L6N_T0_VREF_16 Sch=pio[07] 51 | set_property -dict { PACKAGE_PIN B15 IOSTANDARD LVCMOS33 } [get_ports { gpio[7] }]; #IO_L11N_T1_SRCC_16 Sch=pio[08] 52 | #set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVCMOS33 } [get_ports { pio9 }]; #IO_L6P_T0_16 Sch=pio[09] 53 | #set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS33 } [get_ports { pio10 }]; #IO_L7P_T1_AD6P_35 Sch=pio[10] 54 | #set_property -dict { PACKAGE_PIN J1 IOSTANDARD LVCMOS33 } [get_ports { pio11 }]; #IO_L3N_T0_DQS_AD5N_35 Sch=pio[11] 55 | #set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { pio12 }]; #IO_L5P_T0_AD13P_35 Sch=pio[12] 56 | #set_property -dict { PACKAGE_PIN L1 IOSTANDARD LVCMOS33 } [get_ports { pio13 }]; #IO_L6N_T0_VREF_35 Sch=pio[13] 57 | #set_property -dict { PACKAGE_PIN L2 IOSTANDARD LVCMOS33 } [get_ports { pio14 }]; #IO_L5N_T0_AD13N_35 Sch=pio[14] 58 | #set_property -dict { PACKAGE_PIN M1 IOSTANDARD LVCMOS33 } [get_ports { pio17 }]; #IO_L9N_T1_DQS_AD7N_35 Sch=pio[17] 59 | #set_property -dict { PACKAGE_PIN N3 IOSTANDARD LVCMOS33 } [get_ports { pio18 }]; #IO_L12P_T1_MRCC_35 Sch=pio[18] 60 | #set_property -dict { PACKAGE_PIN P3 IOSTANDARD LVCMOS33 } [get_ports { pio19 }]; #IO_L12N_T1_MRCC_35 Sch=pio[19] 61 | #set_property -dict { PACKAGE_PIN M2 IOSTANDARD LVCMOS33 } [get_ports { pio20 }]; #IO_L9P_T1_DQS_AD7P_35 Sch=pio[20] 62 | #set_property -dict { PACKAGE_PIN N1 IOSTANDARD LVCMOS33 } [get_ports { pio21 }]; #IO_L10N_T1_AD15N_35 Sch=pio[21] 63 | #set_property -dict { PACKAGE_PIN N2 IOSTANDARD LVCMOS33 } [get_ports { pio22 }]; #IO_L10P_T1_AD15P_35 Sch=pio[22] 64 | #set_property -dict { PACKAGE_PIN P1 IOSTANDARD LVCMOS33 } [get_ports { pio23 }]; #IO_L19N_T3_VREF_35 Sch=pio[23] 65 | #set_property -dict { PACKAGE_PIN R3 IOSTANDARD LVCMOS33 } [get_ports { pio26 }]; #IO_L2P_T0_34 Sch=pio[26] 66 | #set_property -dict { PACKAGE_PIN T3 IOSTANDARD LVCMOS33 } [get_ports { pio27 }]; #IO_L2N_T0_34 Sch=pio[27] 67 | #set_property -dict { PACKAGE_PIN R2 IOSTANDARD LVCMOS33 } [get_ports { pio28 }]; #IO_L1P_T0_34 Sch=pio[28] 68 | #set_property -dict { PACKAGE_PIN T1 IOSTANDARD LVCMOS33 } [get_ports { pio29 }]; #IO_L3P_T0_DQS_34 Sch=pio[29] 69 | #set_property -dict { PACKAGE_PIN T2 IOSTANDARD LVCMOS33 } [get_ports { pio30 }]; #IO_L1N_T0_34 Sch=pio[30] 70 | #set_property -dict { PACKAGE_PIN U1 IOSTANDARD LVCMOS33 } [get_ports { pio31 }]; #IO_L3N_T0_DQS_34 Sch=pio[31] 71 | #set_property -dict { PACKAGE_PIN W2 IOSTANDARD LVCMOS33 } [get_ports { pio32 }]; #IO_L5N_T0_34 Sch=pio[32] 72 | #set_property -dict { PACKAGE_PIN V2 IOSTANDARD LVCMOS33 } [get_ports { pio33 }]; #IO_L5P_T0_34 Sch=pio[33] 73 | #set_property -dict { PACKAGE_PIN W3 IOSTANDARD LVCMOS33 } [get_ports { pio34 }]; #IO_L6N_T0_VREF_34 Sch=pio[34] 74 | #set_property -dict { PACKAGE_PIN V3 IOSTANDARD LVCMOS33 } [get_ports { pio35 }]; #IO_L6P_T0_34 Sch=pio[35] 75 | #set_property -dict { PACKAGE_PIN W5 IOSTANDARD LVCMOS33 } [get_ports { pio36 }]; #IO_L12P_T1_MRCC_34 Sch=pio[36] 76 | #set_property -dict { PACKAGE_PIN V4 IOSTANDARD LVCMOS33 } [get_ports { pio37 }]; #IO_L11N_T1_SRCC_34 Sch=pio[37] 77 | #set_property -dict { PACKAGE_PIN U4 IOSTANDARD LVCMOS33 } [get_ports { pio38 }]; #IO_L11P_T1_SRCC_34 Sch=pio[38] 78 | #set_property -dict { PACKAGE_PIN V5 IOSTANDARD LVCMOS33 } [get_ports { pio39 }]; #IO_L16N_T2_34 Sch=pio[39] 79 | #set_property -dict { PACKAGE_PIN W4 IOSTANDARD LVCMOS33 } [get_ports { pio40 }]; #IO_L12N_T1_MRCC_34 Sch=pio[40] 80 | #set_property -dict { PACKAGE_PIN U5 IOSTANDARD LVCMOS33 } [get_ports { pio41 }]; #IO_L16P_T2_34 Sch=pio[41] 81 | #set_property -dict { PACKAGE_PIN U2 IOSTANDARD LVCMOS33 } [get_ports { pio42 }]; #IO_L9N_T1_DQS_34 Sch=pio[42] 82 | #set_property -dict { PACKAGE_PIN W6 IOSTANDARD LVCMOS33 } [get_ports { pio43 }]; #IO_L13N_T2_MRCC_34 Sch=pio[43] 83 | #set_property -dict { PACKAGE_PIN U3 IOSTANDARD LVCMOS33 } [get_ports { pio44 }]; #IO_L9P_T1_DQS_34 Sch=pio[44] 84 | #set_property -dict { PACKAGE_PIN U7 IOSTANDARD LVCMOS33 } [get_ports { pio45 }]; #IO_L19P_T3_34 Sch=pio[45] 85 | 86 | # PIO46 is our trigger input 87 | set_property -dict { PACKAGE_PIN W7 IOSTANDARD LVCMOS33 } [get_ports { trigger_in }]; #IO_L13P_T2_MRCC_34 Sch=pio[46] 88 | 89 | # PIO47 is our power out 90 | set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS33 } [get_ports { power_out }]; #IO_L14P_T2_SRCC_34 Sch=pio[47] 91 | # PIO48 is our glitch out 92 | set_property -dict { PACKAGE_PIN V8 IOSTANDARD LVCMOS33 } [get_ports { glitch_out }]; #IO_L14N_T2_SRCC_34 Sch=pio[48] 93 | 94 | ## UART 95 | set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { uart_rxd_out }]; #IO_L7N_T1_D10_14 Sch=uart_rxd_out 96 | set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { uart_txd_in }]; #IO_L7P_T1_D09_14 Sch=uart_txd_in 97 | 98 | ## Crypto 1 Wire Interface 99 | #set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { crypto_sda }]; #IO_0_14 Sch=crypto_sda 100 | 101 | ## QSPI 102 | #set_property -dict { PACKAGE_PIN K19 IOSTANDARD LVCMOS33 } [get_ports { qspi_cs }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_cs 103 | #set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[0] }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_dq[0] 104 | #set_property -dict { PACKAGE_PIN D19 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[1] }]; #IO_L1N_T0_D01_DIN_14 Sch=qspi_dq[1] 105 | #set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[2] }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2] 106 | #set_property -dict { PACKAGE_PIN F18 IOSTANDARD LVCMOS33 } [get_ports { qspi_dq[3] }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3] 107 | 108 | ## Cellular RAM 109 | #set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[0] }]; #IO_L11P_T1_SRCC_14 Sch=sram- a[0] 110 | #set_property -dict { PACKAGE_PIN M19 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[1] }]; #IO_L11N_T1_SRCC_14 Sch=sram- a[1] 111 | #set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[2] }]; #IO_L12N_T1_MRCC_14 Sch=sram- a[2] 112 | #set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[3] }]; #IO_L13P_T2_MRCC_14 Sch=sram- a[3] 113 | #set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[4] }]; #IO_L13N_T2_MRCC_14 Sch=sram- a[4] 114 | #set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[5] }]; #IO_L14P_T2_SRCC_14 Sch=sram- a[5] 115 | #set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[6] }]; #IO_L14N_T2_SRCC_14 Sch=sram- a[6] 116 | #set_property -dict { PACKAGE_PIN W19 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[7] }]; #IO_L16N_T2_A15_D31_14 Sch=sram- a[7] 117 | #set_property -dict { PACKAGE_PIN U19 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[8] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=sram- a[8] 118 | #set_property -dict { PACKAGE_PIN V19 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[9] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=sram- a[9] 119 | #set_property -dict { PACKAGE_PIN W18 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[10] }]; #IO_L16P_T2_CSI_B_14 Sch=sram- a[10] 120 | #set_property -dict { PACKAGE_PIN T17 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[11] }]; #IO_L17P_T2_A14_D30_14 Sch=sram- a[11] 121 | #set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[12] }]; #IO_L17N_T2_A13_D29_14 Sch=sram- a[12] 122 | #set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[13] }]; #IO_L18P_T2_A12_D28_14 Sch=sram- a[13] 123 | #set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[14] }]; #IO_L18N_T2_A11_D27_14 Sch=sram- a[14] 124 | #set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[15] }]; #IO_L19P_T3_A10_D26_14 Sch=sram- a[15] 125 | #set_property -dict { PACKAGE_PIN W16 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[16] }]; #IO_L20P_T3_A08_D24_14 Sch=sram- a[16] 126 | #set_property -dict { PACKAGE_PIN W17 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[17] }]; #IO_L20N_T3_A07_D23_14 Sch=sram- a[17] 127 | #set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { MemAdr[18] }]; #IO_L21P_T3_DQS_14 Sch=sram- a[18] 128 | #set_property -dict { PACKAGE_PIN W15 IOSTANDARD LVCMOS33 } [get_ports { MemDB[0] }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=sram-dq[0] 129 | #set_property -dict { PACKAGE_PIN W13 IOSTANDARD LVCMOS33 } [get_ports { MemDB[1] }]; #IO_L22P_T3_A05_D21_14 Sch=sram-dq[1] 130 | #set_property -dict { PACKAGE_PIN W14 IOSTANDARD LVCMOS33 } [get_ports { MemDB[2] }]; #IO_L22N_T3_A04_D20_14 Sch=sram-dq[2] 131 | #set_property -dict { PACKAGE_PIN U15 IOSTANDARD LVCMOS33 } [get_ports { MemDB[3] }]; #IO_L23P_T3_A03_D19_14 Sch=sram-dq[3] 132 | #set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { MemDB[4] }]; #IO_L23N_T3_A02_D18_14 Sch=sram-dq[4] 133 | #set_property -dict { PACKAGE_PIN V13 IOSTANDARD LVCMOS33 } [get_ports { MemDB[5] }]; #IO_L24P_T3_A01_D17_14 Sch=sram-dq[5] 134 | #set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { MemDB[6] }]; #IO_L24N_T3_A00_D16_14 Sch=sram-dq[6] 135 | #set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { MemDB[7] }]; #IO_25_14 Sch=sram-dq[7] 136 | #set_property -dict { PACKAGE_PIN P19 IOSTANDARD LVCMOS33 } [get_ports { RamOEn }]; #IO_L10P_T1_D14_14 Sch=sram-oe 137 | #set_property -dict { PACKAGE_PIN R19 IOSTANDARD LVCMOS33 } [get_ports { RamWEn }]; #IO_L10N_T1_D15_14 Sch=sram-we 138 | #set_property -dict { PACKAGE_PIN N19 IOSTANDARD LVCMOS33 } [get_ports { RamCEn }]; #IO_L9N_T1_DQS_D13_14 Sch=sram-ce 139 | 140 | 141 | set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design] 142 | set_property BITSTREAM.CONFIG.CONFIGRATE 33 [current_design] 143 | set_property CONFIG_MODE SPIx4 [current_design] 144 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sim_1/new/top_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | 4 | module top_tb( 5 | 6 | ); 7 | 8 | 9 | reg clk; 10 | reg [7:0] data = 8'd64; 11 | reg enable = 1'b1; 12 | reg rst = 1'b0; 13 | always 14 | begin 15 | clk = 1'b1; 16 | #10; 17 | clk = 1'b0; 18 | #10; 19 | end 20 | 21 | wire [1:0] led; 22 | wire uart_tx; 23 | 24 | //top t1( 25 | // .sys_clk(clk), 26 | // .led(led), 27 | // .uart_txd_in(uart_tx) 28 | //); 29 | 30 | //module top( 31 | // input sys_clk, 32 | // output [1:0]led, // Led outputs 33 | // output uart_txd_in // UART TX (strange txd_in name by Digilent) 34 | // ); 35 | 36 | // Clock 37 | wire main_clk; 38 | // Generate a 100MHz clock from the external 12MHz clock 39 | clk_wiz_0 clock_generator 40 | ( 41 | // Clock out ports 42 | .main_clk(main_clk), // output main_clk 43 | // Clock in ports 44 | .clk_in1(clk)); // input clk_in1 45 | 46 | 47 | 48 | uart_tx tx1( 49 | .clk(main_clk), 50 | .reset(rst), 51 | .data(data), 52 | .enable(enable), 53 | .tx(uart_tx) 54 | ); 55 | 56 | top t( 57 | .sys_clk(clk), 58 | .uart_txd_in(uart_tx) 59 | ); 60 | 61 | 62 | 63 | 64 | //uart_rx rx1( 65 | // .clk(clk), 66 | // .reset(rst), 67 | // .rx(tx1.tx) 68 | //); 69 | 70 | endmodule 71 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/clk_wiz_0.dcp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chipfail/chipfail-glitcher/906574521b6c4a16188bcb93ef5e295e033e7100/chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/clk_wiz_0.dcp -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/clk_wiz_0.v: -------------------------------------------------------------------------------- 1 | 2 | // file: clk_wiz_0.v 3 | // 4 | // (c) Copyright 2008 - 2013 Xilinx, Inc. All rights reserved. 5 | // 6 | // This file contains confidential and proprietary information 7 | // of Xilinx, Inc. and is protected under U.S. and 8 | // international copyright and other intellectual property 9 | // laws. 10 | // 11 | // DISCLAIMER 12 | // This disclaimer is not a license and does not grant any 13 | // rights to the materials distributed herewith. Except as 14 | // otherwise provided in a valid license issued to you by 15 | // Xilinx, and to the maximum extent permitted by applicable 16 | // law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND 17 | // WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES 18 | // AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING 19 | // BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- 20 | // INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and 21 | // (2) Xilinx shall not be liable (whether in contract or tort, 22 | // including negligence, or under any other theory of 23 | // liability) for any loss or damage of any kind or nature 24 | // related to, arising under or in connection with these 25 | // materials, including for any direct, or any indirect, 26 | // special, incidental, or consequential loss or damage 27 | // (including loss of data, profits, goodwill, or any type of 28 | // loss or damage suffered as a result of any action brought 29 | // by a third party) even if such damage or loss was 30 | // reasonably foreseeable or Xilinx had been advised of the 31 | // possibility of the same. 32 | // 33 | // CRITICAL APPLICATIONS 34 | // Xilinx products are not designed or intended to be fail- 35 | // safe, or for use in any application requiring fail-safe 36 | // performance, such as life-support or safety devices or 37 | // systems, Class III medical devices, nuclear facilities, 38 | // applications related to the deployment of airbags, or any 39 | // other applications that could lead to death, personal 40 | // injury, or severe property or environmental damage 41 | // (individually and collectively, "Critical 42 | // Applications"). Customer assumes the sole risk and 43 | // liability of any use of Xilinx products in Critical 44 | // Applications, subject only to applicable laws and 45 | // regulations governing limitations on product liability. 46 | // 47 | // THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS 48 | // PART OF THIS FILE AT ALL TIMES. 49 | // 50 | //---------------------------------------------------------------------------- 51 | // User entered comments 52 | //---------------------------------------------------------------------------- 53 | // None 54 | // 55 | //---------------------------------------------------------------------------- 56 | // Output Output Phase Duty Cycle Pk-to-Pk Phase 57 | // Clock Freq (MHz) (degrees) (%) Jitter (ps) Error (ps) 58 | //---------------------------------------------------------------------------- 59 | // main_clk___100.000______0.000______50.0______479.872____668.310 60 | // 61 | //---------------------------------------------------------------------------- 62 | // Input Clock Freq (MHz) Input Jitter (UI) 63 | //---------------------------------------------------------------------------- 64 | // __primary__________12.000____________0.010 65 | 66 | `timescale 1ps/1ps 67 | 68 | (* CORE_GENERATION_INFO = "clk_wiz_0,clk_wiz_v6_0_3_0_0,{component_name=clk_wiz_0,use_phase_alignment=true,use_min_o_jitter=false,use_max_i_jitter=false,use_dyn_phase_shift=false,use_inclk_switchover=false,use_dyn_reconfig=false,enable_axi=0,feedback_source=FDBK_AUTO,PRIMITIVE=MMCM,num_out_clk=1,clkin1_period=83.333,clkin2_period=10.0,use_power_down=false,use_reset=false,use_locked=false,use_inclk_stopped=false,feedback_type=SINGLE,CLOCK_MGR_TYPE=NA,manual_override=false}" *) 69 | 70 | module clk_wiz_0 71 | ( 72 | // Clock out ports 73 | output main_clk, 74 | // Clock in ports 75 | input clk_in1 76 | ); 77 | 78 | clk_wiz_0_clk_wiz inst 79 | ( 80 | // Clock out ports 81 | .main_clk(main_clk), 82 | // Clock in ports 83 | .clk_in1(clk_in1) 84 | ); 85 | 86 | endmodule 87 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/clk_wiz_0.veo: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // (c) Copyright 2008 - 2013 Xilinx, Inc. All rights reserved. 4 | // 5 | // This file contains confidential and proprietary information 6 | // of Xilinx, Inc. and is protected under U.S. and 7 | // international copyright and other intellectual property 8 | // laws. 9 | // 10 | // DISCLAIMER 11 | // This disclaimer is not a license and does not grant any 12 | // rights to the materials distributed herewith. Except as 13 | // otherwise provided in a valid license issued to you by 14 | // Xilinx, and to the maximum extent permitted by applicable 15 | // law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND 16 | // WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES 17 | // AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING 18 | // BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- 19 | // INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and 20 | // (2) Xilinx shall not be liable (whether in contract or tort, 21 | // including negligence, or under any other theory of 22 | // liability) for any loss or damage of any kind or nature 23 | // related to, arising under or in connection with these 24 | // materials, including for any direct, or any indirect, 25 | // special, incidental, or consequential loss or damage 26 | // (including loss of data, profits, goodwill, or any type of 27 | // loss or damage suffered as a result of any action brought 28 | // by a third party) even if such damage or loss was 29 | // reasonably foreseeable or Xilinx had been advised of the 30 | // possibility of the same. 31 | // 32 | // CRITICAL APPLICATIONS 33 | // Xilinx products are not designed or intended to be fail- 34 | // safe, or for use in any application requiring fail-safe 35 | // performance, such as life-support or safety devices or 36 | // systems, Class III medical devices, nuclear facilities, 37 | // applications related to the deployment of airbags, or any 38 | // other applications that could lead to death, personal 39 | // injury, or severe property or environmental damage 40 | // (individually and collectively, "Critical 41 | // Applications"). Customer assumes the sole risk and 42 | // liability of any use of Xilinx products in Critical 43 | // Applications, subject only to applicable laws and 44 | // regulations governing limitations on product liability. 45 | // 46 | // THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS 47 | // PART OF THIS FILE AT ALL TIMES. 48 | // 49 | //---------------------------------------------------------------------------- 50 | // User entered comments 51 | //---------------------------------------------------------------------------- 52 | // None 53 | // 54 | //---------------------------------------------------------------------------- 55 | // Output Output Phase Duty Cycle Pk-to-Pk Phase 56 | // Clock Freq (MHz) (degrees) (%) Jitter (ps) Error (ps) 57 | //---------------------------------------------------------------------------- 58 | // main_clk___100.000______0.000______50.0______479.872____668.310 59 | // 60 | //---------------------------------------------------------------------------- 61 | // Input Clock Freq (MHz) Input Jitter (UI) 62 | //---------------------------------------------------------------------------- 63 | // __primary__________12.000____________0.010 64 | 65 | // The following must be inserted into your Verilog file for this 66 | // core to be instantiated. Change the instance name and port connections 67 | // (in parentheses) to your own signal names. 68 | 69 | //----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG 70 | 71 | clk_wiz_0 instance_name 72 | ( 73 | // Clock out ports 74 | .main_clk(main_clk), // output main_clk 75 | // Clock in ports 76 | .clk_in1(clk_in1)); // input clk_in1 77 | // INST_TAG_END ------ End INSTANTIATION Template --------- 78 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/clk_wiz_0.xdc: -------------------------------------------------------------------------------- 1 | 2 | # file: clk_wiz_0.xdc 3 | # 4 | # (c) Copyright 2008 - 2013 Xilinx, Inc. All rights reserved. 5 | # 6 | # This file contains confidential and proprietary information 7 | # of Xilinx, Inc. and is protected under U.S. and 8 | # international copyright and other intellectual property 9 | # laws. 10 | # 11 | # DISCLAIMER 12 | # This disclaimer is not a license and does not grant any 13 | # rights to the materials distributed herewith. Except as 14 | # otherwise provided in a valid license issued to you by 15 | # Xilinx, and to the maximum extent permitted by applicable 16 | # law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND 17 | # WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES 18 | # AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING 19 | # BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- 20 | # INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and 21 | # (2) Xilinx shall not be liable (whether in contract or tort, 22 | # including negligence, or under any other theory of 23 | # liability) for any loss or damage of any kind or nature 24 | # related to, arising under or in connection with these 25 | # materials, including for any direct, or any indirect, 26 | # special, incidental, or consequential loss or damage 27 | # (including loss of data, profits, goodwill, or any type of 28 | # loss or damage suffered as a result of any action brought 29 | # by a third party) even if such damage or loss was 30 | # reasonably foreseeable or Xilinx had been advised of the 31 | # possibility of the same. 32 | # 33 | # CRITICAL APPLICATIONS 34 | # Xilinx products are not designed or intended to be fail- 35 | # safe, or for use in any application requiring fail-safe 36 | # performance, such as life-support or safety devices or 37 | # systems, Class III medical devices, nuclear facilities, 38 | # applications related to the deployment of airbags, or any 39 | # other applications that could lead to death, personal 40 | # injury, or severe property or environmental damage 41 | # (individually and collectively, "Critical 42 | # Applications"). Customer assumes the sole risk and 43 | # liability of any use of Xilinx products in Critical 44 | # Applications, subject only to applicable laws and 45 | # regulations governing limitations on product liability. 46 | # 47 | # THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS 48 | # PART OF THIS FILE AT ALL TIMES. 49 | # 50 | 51 | # Input clock periods. These duplicate the values entered for the 52 | # input clocks. You can use these to time your system. If required 53 | # commented constraints can be used in the top level xdc 54 | #---------------------------------------------------------------- 55 | # Connect to input port when clock capable pin is selected for input 56 | create_clock -period 83.333 [get_ports clk_in1] 57 | set_input_jitter [get_clocks -of_objects [get_ports clk_in1]] 0.83333 58 | 59 | 60 | set_property PHASESHIFT_MODE WAVEFORM [get_cells -hierarchical *adv*] 61 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/clk_wiz_0_board.xdc: -------------------------------------------------------------------------------- 1 | #--------------------Physical Constraints----------------- 2 | 3 | set_property BOARD_PIN {clk} [get_ports clk_in1] 4 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/clk_wiz_0_clk_wiz.v: -------------------------------------------------------------------------------- 1 | 2 | // file: clk_wiz_0.v 3 | // 4 | // (c) Copyright 2008 - 2013 Xilinx, Inc. All rights reserved. 5 | // 6 | // This file contains confidential and proprietary information 7 | // of Xilinx, Inc. and is protected under U.S. and 8 | // international copyright and other intellectual property 9 | // laws. 10 | // 11 | // DISCLAIMER 12 | // This disclaimer is not a license and does not grant any 13 | // rights to the materials distributed herewith. Except as 14 | // otherwise provided in a valid license issued to you by 15 | // Xilinx, and to the maximum extent permitted by applicable 16 | // law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND 17 | // WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES 18 | // AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING 19 | // BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- 20 | // INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and 21 | // (2) Xilinx shall not be liable (whether in contract or tort, 22 | // including negligence, or under any other theory of 23 | // liability) for any loss or damage of any kind or nature 24 | // related to, arising under or in connection with these 25 | // materials, including for any direct, or any indirect, 26 | // special, incidental, or consequential loss or damage 27 | // (including loss of data, profits, goodwill, or any type of 28 | // loss or damage suffered as a result of any action brought 29 | // by a third party) even if such damage or loss was 30 | // reasonably foreseeable or Xilinx had been advised of the 31 | // possibility of the same. 32 | // 33 | // CRITICAL APPLICATIONS 34 | // Xilinx products are not designed or intended to be fail- 35 | // safe, or for use in any application requiring fail-safe 36 | // performance, such as life-support or safety devices or 37 | // systems, Class III medical devices, nuclear facilities, 38 | // applications related to the deployment of airbags, or any 39 | // other applications that could lead to death, personal 40 | // injury, or severe property or environmental damage 41 | // (individually and collectively, "Critical 42 | // Applications"). Customer assumes the sole risk and 43 | // liability of any use of Xilinx products in Critical 44 | // Applications, subject only to applicable laws and 45 | // regulations governing limitations on product liability. 46 | // 47 | // THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS 48 | // PART OF THIS FILE AT ALL TIMES. 49 | // 50 | //---------------------------------------------------------------------------- 51 | // User entered comments 52 | //---------------------------------------------------------------------------- 53 | // None 54 | // 55 | //---------------------------------------------------------------------------- 56 | // Output Output Phase Duty Cycle Pk-to-Pk Phase 57 | // Clock Freq (MHz) (degrees) (%) Jitter (ps) Error (ps) 58 | //---------------------------------------------------------------------------- 59 | // main_clk___100.000______0.000______50.0______479.872____668.310 60 | // 61 | //---------------------------------------------------------------------------- 62 | // Input Clock Freq (MHz) Input Jitter (UI) 63 | //---------------------------------------------------------------------------- 64 | // __primary__________12.000____________0.010 65 | 66 | `timescale 1ps/1ps 67 | 68 | module clk_wiz_0_clk_wiz 69 | 70 | (// Clock in ports 71 | // Clock out ports 72 | output main_clk, 73 | input clk_in1 74 | ); 75 | // Input buffering 76 | //------------------------------------ 77 | wire clk_in1_clk_wiz_0; 78 | wire clk_in2_clk_wiz_0; 79 | IBUF clkin1_ibufg 80 | (.O (clk_in1_clk_wiz_0), 81 | .I (clk_in1)); 82 | 83 | 84 | 85 | 86 | // Clocking PRIMITIVE 87 | //------------------------------------ 88 | 89 | // Instantiation of the MMCM PRIMITIVE 90 | // * Unused inputs are tied off 91 | // * Unused outputs are labeled unused 92 | 93 | wire main_clk_clk_wiz_0; 94 | wire clk_out2_clk_wiz_0; 95 | wire clk_out3_clk_wiz_0; 96 | wire clk_out4_clk_wiz_0; 97 | wire clk_out5_clk_wiz_0; 98 | wire clk_out6_clk_wiz_0; 99 | wire clk_out7_clk_wiz_0; 100 | 101 | wire [15:0] do_unused; 102 | wire drdy_unused; 103 | wire psdone_unused; 104 | wire locked_int; 105 | wire clkfbout_clk_wiz_0; 106 | wire clkfbout_buf_clk_wiz_0; 107 | wire clkfboutb_unused; 108 | wire clkout0b_unused; 109 | wire clkout1_unused; 110 | wire clkout1b_unused; 111 | wire clkout2_unused; 112 | wire clkout2b_unused; 113 | wire clkout3_unused; 114 | wire clkout3b_unused; 115 | wire clkout4_unused; 116 | wire clkout5_unused; 117 | wire clkout6_unused; 118 | wire clkfbstopped_unused; 119 | wire clkinstopped_unused; 120 | 121 | MMCME2_ADV 122 | #(.BANDWIDTH ("OPTIMIZED"), 123 | .CLKOUT4_CASCADE ("FALSE"), 124 | .COMPENSATION ("ZHOLD"), 125 | .STARTUP_WAIT ("FALSE"), 126 | .DIVCLK_DIVIDE (1), 127 | .CLKFBOUT_MULT_F (62.500), 128 | .CLKFBOUT_PHASE (0.000), 129 | .CLKFBOUT_USE_FINE_PS ("FALSE"), 130 | .CLKOUT0_DIVIDE_F (7.500), 131 | .CLKOUT0_PHASE (0.000), 132 | .CLKOUT0_DUTY_CYCLE (0.500), 133 | .CLKOUT0_USE_FINE_PS ("FALSE"), 134 | .CLKIN1_PERIOD (83.333)) 135 | mmcm_adv_inst 136 | // Output clocks 137 | ( 138 | .CLKFBOUT (clkfbout_clk_wiz_0), 139 | .CLKFBOUTB (clkfboutb_unused), 140 | .CLKOUT0 (main_clk_clk_wiz_0), 141 | .CLKOUT0B (clkout0b_unused), 142 | .CLKOUT1 (clkout1_unused), 143 | .CLKOUT1B (clkout1b_unused), 144 | .CLKOUT2 (clkout2_unused), 145 | .CLKOUT2B (clkout2b_unused), 146 | .CLKOUT3 (clkout3_unused), 147 | .CLKOUT3B (clkout3b_unused), 148 | .CLKOUT4 (clkout4_unused), 149 | .CLKOUT5 (clkout5_unused), 150 | .CLKOUT6 (clkout6_unused), 151 | // Input clock control 152 | .CLKFBIN (clkfbout_buf_clk_wiz_0), 153 | .CLKIN1 (clk_in1_clk_wiz_0), 154 | .CLKIN2 (1'b0), 155 | // Tied to always select the primary input clock 156 | .CLKINSEL (1'b1), 157 | // Ports for dynamic reconfiguration 158 | .DADDR (7'h0), 159 | .DCLK (1'b0), 160 | .DEN (1'b0), 161 | .DI (16'h0), 162 | .DO (do_unused), 163 | .DRDY (drdy_unused), 164 | .DWE (1'b0), 165 | // Ports for dynamic phase shift 166 | .PSCLK (1'b0), 167 | .PSEN (1'b0), 168 | .PSINCDEC (1'b0), 169 | .PSDONE (psdone_unused), 170 | // Other control and status signals 171 | .LOCKED (locked_int), 172 | .CLKINSTOPPED (clkinstopped_unused), 173 | .CLKFBSTOPPED (clkfbstopped_unused), 174 | .PWRDWN (1'b0), 175 | .RST (1'b0)); 176 | 177 | // Clock Monitor clock assigning 178 | //-------------------------------------- 179 | // Output buffering 180 | //----------------------------------- 181 | 182 | BUFG clkf_buf 183 | (.O (clkfbout_buf_clk_wiz_0), 184 | .I (clkfbout_clk_wiz_0)); 185 | 186 | 187 | 188 | 189 | 190 | 191 | BUFG clkout1_buf 192 | (.O (main_clk), 193 | .I (main_clk_clk_wiz_0)); 194 | 195 | 196 | 197 | 198 | endmodule 199 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/clk_wiz_0_ooc.xdc: -------------------------------------------------------------------------------- 1 | 2 | # file: clk_wiz_0_ooc.xdc 3 | # 4 | # (c) Copyright 2008 - 2013 Xilinx, Inc. All rights reserved. 5 | # 6 | # This file contains confidential and proprietary information 7 | # of Xilinx, Inc. and is protected under U.S. and 8 | # international copyright and other intellectual property 9 | # laws. 10 | # 11 | # DISCLAIMER 12 | # This disclaimer is not a license and does not grant any 13 | # rights to the materials distributed herewith. Except as 14 | # otherwise provided in a valid license issued to you by 15 | # Xilinx, and to the maximum extent permitted by applicable 16 | # law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND 17 | # WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES 18 | # AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING 19 | # BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- 20 | # INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and 21 | # (2) Xilinx shall not be liable (whether in contract or tort, 22 | # including negligence, or under any other theory of 23 | # liability) for any loss or damage of any kind or nature 24 | # related to, arising under or in connection with these 25 | # materials, including for any direct, or any indirect, 26 | # special, incidental, or consequential loss or damage 27 | # (including loss of data, profits, goodwill, or any type of 28 | # loss or damage suffered as a result of any action brought 29 | # by a third party) even if such damage or loss was 30 | # reasonably foreseeable or Xilinx had been advised of the 31 | # possibility of the same. 32 | # 33 | # CRITICAL APPLICATIONS 34 | # Xilinx products are not designed or intended to be fail- 35 | # safe, or for use in any application requiring fail-safe 36 | # performance, such as life-support or safety devices or 37 | # systems, Class III medical devices, nuclear facilities, 38 | # applications related to the deployment of airbags, or any 39 | # other applications that could lead to death, personal 40 | # injury, or severe property or environmental damage 41 | # (individually and collectively, "Critical 42 | # Applications"). Customer assumes the sole risk and 43 | # liability of any use of Xilinx products in Critical 44 | # Applications, subject only to applicable laws and 45 | # regulations governing limitations on product liability. 46 | # 47 | # THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS 48 | # PART OF THIS FILE AT ALL TIMES. 49 | # 50 | 51 | ################# 52 | #DEFAULT CLOCK CONSTRAINTS 53 | 54 | ############################################################ 55 | # Clock Period Constraints # 56 | ############################################################ 57 | #create_clock -period 83.333 [get_ports clk_in1] 58 | 59 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/clk_wiz_0_sim_netlist.v: -------------------------------------------------------------------------------- 1 | // Copyright 1986-2019 Xilinx, Inc. All Rights Reserved. 2 | // -------------------------------------------------------------------------------- 3 | // Tool Version: Vivado v.2019.1 (win64) Build 2552052 Fri May 24 14:49:42 MDT 2019 4 | // Date : Sat Aug 3 17:03:39 2019 5 | // Host : DESKTOP-TFPC34Q running 64-bit major release (build 9200) 6 | // Command : write_verilog -force -mode funcsim 7 | // C:/Users/Thomas/Documents/GitHub/chipfail-glitcher/chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/clk_wiz_0_sim_netlist.v 8 | // Design : clk_wiz_0 9 | // Purpose : This verilog netlist is a functional simulation representation of the design and should not be modified 10 | // or synthesized. This netlist cannot be used for SDF annotated simulation. 11 | // Device : xc7a35tcpg236-1 12 | // -------------------------------------------------------------------------------- 13 | `timescale 1 ps / 1 ps 14 | 15 | (* NotValidForBitStream *) 16 | module clk_wiz_0 17 | (main_clk, 18 | clk_in1); 19 | output main_clk; 20 | input clk_in1; 21 | 22 | (* IBUF_LOW_PWR *) wire clk_in1; 23 | wire main_clk; 24 | 25 | clk_wiz_0_clk_wiz_0_clk_wiz inst 26 | (.clk_in1(clk_in1), 27 | .main_clk(main_clk)); 28 | endmodule 29 | 30 | (* ORIG_REF_NAME = "clk_wiz_0_clk_wiz" *) 31 | module clk_wiz_0_clk_wiz_0_clk_wiz 32 | (main_clk, 33 | clk_in1); 34 | output main_clk; 35 | input clk_in1; 36 | 37 | wire clk_in1; 38 | wire clk_in1_clk_wiz_0; 39 | wire clkfbout_buf_clk_wiz_0; 40 | wire clkfbout_clk_wiz_0; 41 | wire main_clk; 42 | wire main_clk_clk_wiz_0; 43 | wire NLW_mmcm_adv_inst_CLKFBOUTB_UNCONNECTED; 44 | wire NLW_mmcm_adv_inst_CLKFBSTOPPED_UNCONNECTED; 45 | wire NLW_mmcm_adv_inst_CLKINSTOPPED_UNCONNECTED; 46 | wire NLW_mmcm_adv_inst_CLKOUT0B_UNCONNECTED; 47 | wire NLW_mmcm_adv_inst_CLKOUT1_UNCONNECTED; 48 | wire NLW_mmcm_adv_inst_CLKOUT1B_UNCONNECTED; 49 | wire NLW_mmcm_adv_inst_CLKOUT2_UNCONNECTED; 50 | wire NLW_mmcm_adv_inst_CLKOUT2B_UNCONNECTED; 51 | wire NLW_mmcm_adv_inst_CLKOUT3_UNCONNECTED; 52 | wire NLW_mmcm_adv_inst_CLKOUT3B_UNCONNECTED; 53 | wire NLW_mmcm_adv_inst_CLKOUT4_UNCONNECTED; 54 | wire NLW_mmcm_adv_inst_CLKOUT5_UNCONNECTED; 55 | wire NLW_mmcm_adv_inst_CLKOUT6_UNCONNECTED; 56 | wire NLW_mmcm_adv_inst_DRDY_UNCONNECTED; 57 | wire NLW_mmcm_adv_inst_LOCKED_UNCONNECTED; 58 | wire NLW_mmcm_adv_inst_PSDONE_UNCONNECTED; 59 | wire [15:0]NLW_mmcm_adv_inst_DO_UNCONNECTED; 60 | 61 | (* BOX_TYPE = "PRIMITIVE" *) 62 | BUFG clkf_buf 63 | (.I(clkfbout_clk_wiz_0), 64 | .O(clkfbout_buf_clk_wiz_0)); 65 | (* BOX_TYPE = "PRIMITIVE" *) 66 | (* CAPACITANCE = "DONT_CARE" *) 67 | (* IBUF_DELAY_VALUE = "0" *) 68 | (* IFD_DELAY_VALUE = "AUTO" *) 69 | IBUF #( 70 | .IOSTANDARD("DEFAULT")) 71 | clkin1_ibufg 72 | (.I(clk_in1), 73 | .O(clk_in1_clk_wiz_0)); 74 | (* BOX_TYPE = "PRIMITIVE" *) 75 | BUFG clkout1_buf 76 | (.I(main_clk_clk_wiz_0), 77 | .O(main_clk)); 78 | (* BOX_TYPE = "PRIMITIVE" *) 79 | MMCME2_ADV #( 80 | .BANDWIDTH("OPTIMIZED"), 81 | .CLKFBOUT_MULT_F(62.500000), 82 | .CLKFBOUT_PHASE(0.000000), 83 | .CLKFBOUT_USE_FINE_PS("FALSE"), 84 | .CLKIN1_PERIOD(83.333000), 85 | .CLKIN2_PERIOD(0.000000), 86 | .CLKOUT0_DIVIDE_F(7.500000), 87 | .CLKOUT0_DUTY_CYCLE(0.500000), 88 | .CLKOUT0_PHASE(0.000000), 89 | .CLKOUT0_USE_FINE_PS("FALSE"), 90 | .CLKOUT1_DIVIDE(1), 91 | .CLKOUT1_DUTY_CYCLE(0.500000), 92 | .CLKOUT1_PHASE(0.000000), 93 | .CLKOUT1_USE_FINE_PS("FALSE"), 94 | .CLKOUT2_DIVIDE(1), 95 | .CLKOUT2_DUTY_CYCLE(0.500000), 96 | .CLKOUT2_PHASE(0.000000), 97 | .CLKOUT2_USE_FINE_PS("FALSE"), 98 | .CLKOUT3_DIVIDE(1), 99 | .CLKOUT3_DUTY_CYCLE(0.500000), 100 | .CLKOUT3_PHASE(0.000000), 101 | .CLKOUT3_USE_FINE_PS("FALSE"), 102 | .CLKOUT4_CASCADE("FALSE"), 103 | .CLKOUT4_DIVIDE(1), 104 | .CLKOUT4_DUTY_CYCLE(0.500000), 105 | .CLKOUT4_PHASE(0.000000), 106 | .CLKOUT4_USE_FINE_PS("FALSE"), 107 | .CLKOUT5_DIVIDE(1), 108 | .CLKOUT5_DUTY_CYCLE(0.500000), 109 | .CLKOUT5_PHASE(0.000000), 110 | .CLKOUT5_USE_FINE_PS("FALSE"), 111 | .CLKOUT6_DIVIDE(1), 112 | .CLKOUT6_DUTY_CYCLE(0.500000), 113 | .CLKOUT6_PHASE(0.000000), 114 | .CLKOUT6_USE_FINE_PS("FALSE"), 115 | .COMPENSATION("ZHOLD"), 116 | .DIVCLK_DIVIDE(1), 117 | .IS_CLKINSEL_INVERTED(1'b0), 118 | .IS_PSEN_INVERTED(1'b0), 119 | .IS_PSINCDEC_INVERTED(1'b0), 120 | .IS_PWRDWN_INVERTED(1'b0), 121 | .IS_RST_INVERTED(1'b0), 122 | .REF_JITTER1(0.010000), 123 | .REF_JITTER2(0.010000), 124 | .SS_EN("FALSE"), 125 | .SS_MODE("CENTER_HIGH"), 126 | .SS_MOD_PERIOD(10000), 127 | .STARTUP_WAIT("FALSE")) 128 | mmcm_adv_inst 129 | (.CLKFBIN(clkfbout_buf_clk_wiz_0), 130 | .CLKFBOUT(clkfbout_clk_wiz_0), 131 | .CLKFBOUTB(NLW_mmcm_adv_inst_CLKFBOUTB_UNCONNECTED), 132 | .CLKFBSTOPPED(NLW_mmcm_adv_inst_CLKFBSTOPPED_UNCONNECTED), 133 | .CLKIN1(clk_in1_clk_wiz_0), 134 | .CLKIN2(1'b0), 135 | .CLKINSEL(1'b1), 136 | .CLKINSTOPPED(NLW_mmcm_adv_inst_CLKINSTOPPED_UNCONNECTED), 137 | .CLKOUT0(main_clk_clk_wiz_0), 138 | .CLKOUT0B(NLW_mmcm_adv_inst_CLKOUT0B_UNCONNECTED), 139 | .CLKOUT1(NLW_mmcm_adv_inst_CLKOUT1_UNCONNECTED), 140 | .CLKOUT1B(NLW_mmcm_adv_inst_CLKOUT1B_UNCONNECTED), 141 | .CLKOUT2(NLW_mmcm_adv_inst_CLKOUT2_UNCONNECTED), 142 | .CLKOUT2B(NLW_mmcm_adv_inst_CLKOUT2B_UNCONNECTED), 143 | .CLKOUT3(NLW_mmcm_adv_inst_CLKOUT3_UNCONNECTED), 144 | .CLKOUT3B(NLW_mmcm_adv_inst_CLKOUT3B_UNCONNECTED), 145 | .CLKOUT4(NLW_mmcm_adv_inst_CLKOUT4_UNCONNECTED), 146 | .CLKOUT5(NLW_mmcm_adv_inst_CLKOUT5_UNCONNECTED), 147 | .CLKOUT6(NLW_mmcm_adv_inst_CLKOUT6_UNCONNECTED), 148 | .DADDR({1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0}), 149 | .DCLK(1'b0), 150 | .DEN(1'b0), 151 | .DI({1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0}), 152 | .DO(NLW_mmcm_adv_inst_DO_UNCONNECTED[15:0]), 153 | .DRDY(NLW_mmcm_adv_inst_DRDY_UNCONNECTED), 154 | .DWE(1'b0), 155 | .LOCKED(NLW_mmcm_adv_inst_LOCKED_UNCONNECTED), 156 | .PSCLK(1'b0), 157 | .PSDONE(NLW_mmcm_adv_inst_PSDONE_UNCONNECTED), 158 | .PSEN(1'b0), 159 | .PSINCDEC(1'b0), 160 | .PWRDWN(1'b0), 161 | .RST(1'b0)); 162 | endmodule 163 | `ifndef GLBL 164 | `define GLBL 165 | `timescale 1 ps / 1 ps 166 | 167 | module glbl (); 168 | 169 | parameter ROC_WIDTH = 100000; 170 | parameter TOC_WIDTH = 0; 171 | 172 | //-------- STARTUP Globals -------------- 173 | wire GSR; 174 | wire GTS; 175 | wire GWE; 176 | wire PRLD; 177 | tri1 p_up_tmp; 178 | tri (weak1, strong0) PLL_LOCKG = p_up_tmp; 179 | 180 | wire PROGB_GLBL; 181 | wire CCLKO_GLBL; 182 | wire FCSBO_GLBL; 183 | wire [3:0] DO_GLBL; 184 | wire [3:0] DI_GLBL; 185 | 186 | reg GSR_int; 187 | reg GTS_int; 188 | reg PRLD_int; 189 | 190 | //-------- JTAG Globals -------------- 191 | wire JTAG_TDO_GLBL; 192 | wire JTAG_TCK_GLBL; 193 | wire JTAG_TDI_GLBL; 194 | wire JTAG_TMS_GLBL; 195 | wire JTAG_TRST_GLBL; 196 | 197 | reg JTAG_CAPTURE_GLBL; 198 | reg JTAG_RESET_GLBL; 199 | reg JTAG_SHIFT_GLBL; 200 | reg JTAG_UPDATE_GLBL; 201 | reg JTAG_RUNTEST_GLBL; 202 | 203 | reg JTAG_SEL1_GLBL = 0; 204 | reg JTAG_SEL2_GLBL = 0 ; 205 | reg JTAG_SEL3_GLBL = 0; 206 | reg JTAG_SEL4_GLBL = 0; 207 | 208 | reg JTAG_USER_TDO1_GLBL = 1'bz; 209 | reg JTAG_USER_TDO2_GLBL = 1'bz; 210 | reg JTAG_USER_TDO3_GLBL = 1'bz; 211 | reg JTAG_USER_TDO4_GLBL = 1'bz; 212 | 213 | assign (strong1, weak0) GSR = GSR_int; 214 | assign (strong1, weak0) GTS = GTS_int; 215 | assign (weak1, weak0) PRLD = PRLD_int; 216 | 217 | initial begin 218 | GSR_int = 1'b1; 219 | PRLD_int = 1'b1; 220 | #(ROC_WIDTH) 221 | GSR_int = 1'b0; 222 | PRLD_int = 1'b0; 223 | end 224 | 225 | initial begin 226 | GTS_int = 1'b1; 227 | #(TOC_WIDTH) 228 | GTS_int = 1'b0; 229 | end 230 | 231 | endmodule 232 | `endif 233 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/clk_wiz_0_sim_netlist.vhdl: -------------------------------------------------------------------------------- 1 | -- Copyright 1986-2019 Xilinx, Inc. All Rights Reserved. 2 | -- -------------------------------------------------------------------------------- 3 | -- Tool Version: Vivado v.2019.1 (win64) Build 2552052 Fri May 24 14:49:42 MDT 2019 4 | -- Date : Sat Aug 3 17:03:39 2019 5 | -- Host : DESKTOP-TFPC34Q running 64-bit major release (build 9200) 6 | -- Command : write_vhdl -force -mode funcsim 7 | -- C:/Users/Thomas/Documents/GitHub/chipfail-glitcher/chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/clk_wiz_0_sim_netlist.vhdl 8 | -- Design : clk_wiz_0 9 | -- Purpose : This VHDL netlist is a functional simulation representation of the design and should not be modified or 10 | -- synthesized. This netlist cannot be used for SDF annotated simulation. 11 | -- Device : xc7a35tcpg236-1 12 | -- -------------------------------------------------------------------------------- 13 | library IEEE; 14 | use IEEE.STD_LOGIC_1164.ALL; 15 | library UNISIM; 16 | use UNISIM.VCOMPONENTS.ALL; 17 | entity clk_wiz_0_clk_wiz_0_clk_wiz is 18 | port ( 19 | main_clk : out STD_LOGIC; 20 | clk_in1 : in STD_LOGIC 21 | ); 22 | attribute ORIG_REF_NAME : string; 23 | attribute ORIG_REF_NAME of clk_wiz_0_clk_wiz_0_clk_wiz : entity is "clk_wiz_0_clk_wiz"; 24 | end clk_wiz_0_clk_wiz_0_clk_wiz; 25 | 26 | architecture STRUCTURE of clk_wiz_0_clk_wiz_0_clk_wiz is 27 | signal clk_in1_clk_wiz_0 : STD_LOGIC; 28 | signal clkfbout_buf_clk_wiz_0 : STD_LOGIC; 29 | signal clkfbout_clk_wiz_0 : STD_LOGIC; 30 | signal main_clk_clk_wiz_0 : STD_LOGIC; 31 | signal NLW_mmcm_adv_inst_CLKFBOUTB_UNCONNECTED : STD_LOGIC; 32 | signal NLW_mmcm_adv_inst_CLKFBSTOPPED_UNCONNECTED : STD_LOGIC; 33 | signal NLW_mmcm_adv_inst_CLKINSTOPPED_UNCONNECTED : STD_LOGIC; 34 | signal NLW_mmcm_adv_inst_CLKOUT0B_UNCONNECTED : STD_LOGIC; 35 | signal NLW_mmcm_adv_inst_CLKOUT1_UNCONNECTED : STD_LOGIC; 36 | signal NLW_mmcm_adv_inst_CLKOUT1B_UNCONNECTED : STD_LOGIC; 37 | signal NLW_mmcm_adv_inst_CLKOUT2_UNCONNECTED : STD_LOGIC; 38 | signal NLW_mmcm_adv_inst_CLKOUT2B_UNCONNECTED : STD_LOGIC; 39 | signal NLW_mmcm_adv_inst_CLKOUT3_UNCONNECTED : STD_LOGIC; 40 | signal NLW_mmcm_adv_inst_CLKOUT3B_UNCONNECTED : STD_LOGIC; 41 | signal NLW_mmcm_adv_inst_CLKOUT4_UNCONNECTED : STD_LOGIC; 42 | signal NLW_mmcm_adv_inst_CLKOUT5_UNCONNECTED : STD_LOGIC; 43 | signal NLW_mmcm_adv_inst_CLKOUT6_UNCONNECTED : STD_LOGIC; 44 | signal NLW_mmcm_adv_inst_DRDY_UNCONNECTED : STD_LOGIC; 45 | signal NLW_mmcm_adv_inst_LOCKED_UNCONNECTED : STD_LOGIC; 46 | signal NLW_mmcm_adv_inst_PSDONE_UNCONNECTED : STD_LOGIC; 47 | signal NLW_mmcm_adv_inst_DO_UNCONNECTED : STD_LOGIC_VECTOR ( 15 downto 0 ); 48 | attribute BOX_TYPE : string; 49 | attribute BOX_TYPE of clkf_buf : label is "PRIMITIVE"; 50 | attribute BOX_TYPE of clkin1_ibufg : label is "PRIMITIVE"; 51 | attribute CAPACITANCE : string; 52 | attribute CAPACITANCE of clkin1_ibufg : label is "DONT_CARE"; 53 | attribute IBUF_DELAY_VALUE : string; 54 | attribute IBUF_DELAY_VALUE of clkin1_ibufg : label is "0"; 55 | attribute IFD_DELAY_VALUE : string; 56 | attribute IFD_DELAY_VALUE of clkin1_ibufg : label is "AUTO"; 57 | attribute BOX_TYPE of clkout1_buf : label is "PRIMITIVE"; 58 | attribute BOX_TYPE of mmcm_adv_inst : label is "PRIMITIVE"; 59 | begin 60 | clkf_buf: unisim.vcomponents.BUFG 61 | port map ( 62 | I => clkfbout_clk_wiz_0, 63 | O => clkfbout_buf_clk_wiz_0 64 | ); 65 | clkin1_ibufg: unisim.vcomponents.IBUF 66 | generic map( 67 | IOSTANDARD => "DEFAULT" 68 | ) 69 | port map ( 70 | I => clk_in1, 71 | O => clk_in1_clk_wiz_0 72 | ); 73 | clkout1_buf: unisim.vcomponents.BUFG 74 | port map ( 75 | I => main_clk_clk_wiz_0, 76 | O => main_clk 77 | ); 78 | mmcm_adv_inst: unisim.vcomponents.MMCME2_ADV 79 | generic map( 80 | BANDWIDTH => "OPTIMIZED", 81 | CLKFBOUT_MULT_F => 62.500000, 82 | CLKFBOUT_PHASE => 0.000000, 83 | CLKFBOUT_USE_FINE_PS => false, 84 | CLKIN1_PERIOD => 83.333000, 85 | CLKIN2_PERIOD => 0.000000, 86 | CLKOUT0_DIVIDE_F => 7.500000, 87 | CLKOUT0_DUTY_CYCLE => 0.500000, 88 | CLKOUT0_PHASE => 0.000000, 89 | CLKOUT0_USE_FINE_PS => false, 90 | CLKOUT1_DIVIDE => 1, 91 | CLKOUT1_DUTY_CYCLE => 0.500000, 92 | CLKOUT1_PHASE => 0.000000, 93 | CLKOUT1_USE_FINE_PS => false, 94 | CLKOUT2_DIVIDE => 1, 95 | CLKOUT2_DUTY_CYCLE => 0.500000, 96 | CLKOUT2_PHASE => 0.000000, 97 | CLKOUT2_USE_FINE_PS => false, 98 | CLKOUT3_DIVIDE => 1, 99 | CLKOUT3_DUTY_CYCLE => 0.500000, 100 | CLKOUT3_PHASE => 0.000000, 101 | CLKOUT3_USE_FINE_PS => false, 102 | CLKOUT4_CASCADE => false, 103 | CLKOUT4_DIVIDE => 1, 104 | CLKOUT4_DUTY_CYCLE => 0.500000, 105 | CLKOUT4_PHASE => 0.000000, 106 | CLKOUT4_USE_FINE_PS => false, 107 | CLKOUT5_DIVIDE => 1, 108 | CLKOUT5_DUTY_CYCLE => 0.500000, 109 | CLKOUT5_PHASE => 0.000000, 110 | CLKOUT5_USE_FINE_PS => false, 111 | CLKOUT6_DIVIDE => 1, 112 | CLKOUT6_DUTY_CYCLE => 0.500000, 113 | CLKOUT6_PHASE => 0.000000, 114 | CLKOUT6_USE_FINE_PS => false, 115 | COMPENSATION => "ZHOLD", 116 | DIVCLK_DIVIDE => 1, 117 | IS_CLKINSEL_INVERTED => '0', 118 | IS_PSEN_INVERTED => '0', 119 | IS_PSINCDEC_INVERTED => '0', 120 | IS_PWRDWN_INVERTED => '0', 121 | IS_RST_INVERTED => '0', 122 | REF_JITTER1 => 0.010000, 123 | REF_JITTER2 => 0.010000, 124 | SS_EN => "FALSE", 125 | SS_MODE => "CENTER_HIGH", 126 | SS_MOD_PERIOD => 10000, 127 | STARTUP_WAIT => false 128 | ) 129 | port map ( 130 | CLKFBIN => clkfbout_buf_clk_wiz_0, 131 | CLKFBOUT => clkfbout_clk_wiz_0, 132 | CLKFBOUTB => NLW_mmcm_adv_inst_CLKFBOUTB_UNCONNECTED, 133 | CLKFBSTOPPED => NLW_mmcm_adv_inst_CLKFBSTOPPED_UNCONNECTED, 134 | CLKIN1 => clk_in1_clk_wiz_0, 135 | CLKIN2 => '0', 136 | CLKINSEL => '1', 137 | CLKINSTOPPED => NLW_mmcm_adv_inst_CLKINSTOPPED_UNCONNECTED, 138 | CLKOUT0 => main_clk_clk_wiz_0, 139 | CLKOUT0B => NLW_mmcm_adv_inst_CLKOUT0B_UNCONNECTED, 140 | CLKOUT1 => NLW_mmcm_adv_inst_CLKOUT1_UNCONNECTED, 141 | CLKOUT1B => NLW_mmcm_adv_inst_CLKOUT1B_UNCONNECTED, 142 | CLKOUT2 => NLW_mmcm_adv_inst_CLKOUT2_UNCONNECTED, 143 | CLKOUT2B => NLW_mmcm_adv_inst_CLKOUT2B_UNCONNECTED, 144 | CLKOUT3 => NLW_mmcm_adv_inst_CLKOUT3_UNCONNECTED, 145 | CLKOUT3B => NLW_mmcm_adv_inst_CLKOUT3B_UNCONNECTED, 146 | CLKOUT4 => NLW_mmcm_adv_inst_CLKOUT4_UNCONNECTED, 147 | CLKOUT5 => NLW_mmcm_adv_inst_CLKOUT5_UNCONNECTED, 148 | CLKOUT6 => NLW_mmcm_adv_inst_CLKOUT6_UNCONNECTED, 149 | DADDR(6 downto 0) => B"0000000", 150 | DCLK => '0', 151 | DEN => '0', 152 | DI(15 downto 0) => B"0000000000000000", 153 | DO(15 downto 0) => NLW_mmcm_adv_inst_DO_UNCONNECTED(15 downto 0), 154 | DRDY => NLW_mmcm_adv_inst_DRDY_UNCONNECTED, 155 | DWE => '0', 156 | LOCKED => NLW_mmcm_adv_inst_LOCKED_UNCONNECTED, 157 | PSCLK => '0', 158 | PSDONE => NLW_mmcm_adv_inst_PSDONE_UNCONNECTED, 159 | PSEN => '0', 160 | PSINCDEC => '0', 161 | PWRDWN => '0', 162 | RST => '0' 163 | ); 164 | end STRUCTURE; 165 | library IEEE; 166 | use IEEE.STD_LOGIC_1164.ALL; 167 | library UNISIM; 168 | use UNISIM.VCOMPONENTS.ALL; 169 | entity clk_wiz_0 is 170 | port ( 171 | main_clk : out STD_LOGIC; 172 | clk_in1 : in STD_LOGIC 173 | ); 174 | attribute NotValidForBitStream : boolean; 175 | attribute NotValidForBitStream of clk_wiz_0 : entity is true; 176 | end clk_wiz_0; 177 | 178 | architecture STRUCTURE of clk_wiz_0 is 179 | begin 180 | inst: entity work.clk_wiz_0_clk_wiz_0_clk_wiz 181 | port map ( 182 | clk_in1 => clk_in1, 183 | main_clk => main_clk 184 | ); 185 | end STRUCTURE; 186 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/clk_wiz_0_stub.v: -------------------------------------------------------------------------------- 1 | // Copyright 1986-2019 Xilinx, Inc. All Rights Reserved. 2 | // -------------------------------------------------------------------------------- 3 | // Tool Version: Vivado v.2019.1 (win64) Build 2552052 Fri May 24 14:49:42 MDT 2019 4 | // Date : Sat Aug 3 17:03:39 2019 5 | // Host : DESKTOP-TFPC34Q running 64-bit major release (build 9200) 6 | // Command : write_verilog -force -mode synth_stub 7 | // C:/Users/Thomas/Documents/GitHub/chipfail-glitcher/chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/clk_wiz_0_stub.v 8 | // Design : clk_wiz_0 9 | // Purpose : Stub declaration of top-level module interface 10 | // Device : xc7a35tcpg236-1 11 | // -------------------------------------------------------------------------------- 12 | 13 | // This empty module with port declaration file causes synthesis tools to infer a black box for IP. 14 | // The synthesis directives are for Synopsys Synplify support to prevent IO buffer insertion. 15 | // Please paste the declaration into a Verilog source file or add the file as an additional source. 16 | module clk_wiz_0(main_clk, clk_in1) 17 | /* synthesis syn_black_box black_box_pad_pin="main_clk,clk_in1" */; 18 | output main_clk; 19 | input clk_in1; 20 | endmodule 21 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/clk_wiz_0_stub.vhdl: -------------------------------------------------------------------------------- 1 | -- Copyright 1986-2019 Xilinx, Inc. All Rights Reserved. 2 | -- -------------------------------------------------------------------------------- 3 | -- Tool Version: Vivado v.2019.1 (win64) Build 2552052 Fri May 24 14:49:42 MDT 2019 4 | -- Date : Sat Aug 3 17:03:39 2019 5 | -- Host : DESKTOP-TFPC34Q running 64-bit major release (build 9200) 6 | -- Command : write_vhdl -force -mode synth_stub 7 | -- C:/Users/Thomas/Documents/GitHub/chipfail-glitcher/chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/clk_wiz_0_stub.vhdl 8 | -- Design : clk_wiz_0 9 | -- Purpose : Stub declaration of top-level module interface 10 | -- Device : xc7a35tcpg236-1 11 | -- -------------------------------------------------------------------------------- 12 | library IEEE; 13 | use IEEE.STD_LOGIC_1164.ALL; 14 | 15 | entity clk_wiz_0 is 16 | Port ( 17 | main_clk : out STD_LOGIC; 18 | clk_in1 : in STD_LOGIC 19 | ); 20 | 21 | end clk_wiz_0; 22 | 23 | architecture stub of clk_wiz_0 is 24 | attribute syn_black_box : boolean; 25 | attribute black_box_pad_pin : string; 26 | attribute syn_black_box of stub : architecture is true; 27 | attribute black_box_pad_pin of stub : architecture is "main_clk,clk_in1"; 28 | begin 29 | end; 30 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/doc/clk_wiz_v6_0_changelog.txt: -------------------------------------------------------------------------------- 1 | 2019.1: 2 | * Version 6.0 (Rev. 3) 3 | * Bug Fix: Internal GUI fixes 4 | * Other: New family support added 5 | 6 | 2018.3.1: 7 | * Version 6.0 (Rev. 2) 8 | * No changes 9 | 10 | 2018.3: 11 | * Version 6.0 (Rev. 2) 12 | * Bug Fix: Made input source independent for primary and secondary clock 13 | * Other: New family support added 14 | 15 | 2018.2: 16 | * Version 6.0 (Rev. 1) 17 | * Bug Fix: Removed vco freq check when Primitive is None 18 | * Other: New family support added 19 | 20 | 2018.1: 21 | * Version 6.0 22 | * Bug Fix: Bug fixes in Dynamic Reconfiguration feature and Write DRP feature 23 | * Bug Fix: Bug fixes for connection issue for s_axi_aresetn pin in IPI 24 | * Feature Enhancement: The default value of USE_PHASE_ALIGMENT is updated to false for UltraScale and UltraScale+ devices. Phase Alignment feature uses extra clock routes in UltraScale and UltraScale+ designs when MMCMs are used. These routing resources are wasted when user do not understand when phase alignment is really needed. Now, implementation tools can use these extra clock routing resources for high fanout signals. 25 | * Feature Enhancement: A column "Max. freq of buffer" is added in the Output Clock table which shows the maximum frequency that the selected output buffer can support 26 | * Other: DRCs added for invalid input values in Override mode 27 | 28 | 2017.4: 29 | * Version 5.4 (Rev. 3) 30 | * Bug Fix: Internal GUI issues are fixed for COMPENSATION mode as INTERNAL 31 | * Bug Fix: Fixed issue in dynamic reconfiguration of fractional values of M in MMCME3, MMCME4 32 | 33 | 2017.3: 34 | * Version 5.4 (Rev. 2) 35 | * General: Internal GUI changes. No effect on the customer design. Added support for aspartan7 devices 36 | 37 | 2017.2: 38 | * Version 5.4 (Rev. 1) 39 | * General: Internal GUI changes. No effect on the customer design. 40 | 41 | 2017.1: 42 | * Version 5.4 43 | * Port Change: Minor version upgrade. CLR pins are added to the pin list when selected buffer is BUFGCEDIV for ultrascale and ultrascale plus devices. 44 | * Other: Added support for new zynq ultrascale plus devices. 45 | 46 | 2016.4: 47 | * Version 5.3 (Rev. 3) 48 | * Bug Fix: Internal GUI issues are fixed. 49 | 50 | 2016.3: 51 | * Version 5.3 (Rev. 2) 52 | * Feature Enhancement: Added new option "Auto" under PRIMITIVE selection for ultrascale and above devices. This option allows the Wizard to instantiate appropriate primitive for the user inputs. 53 | * Feature Enhancement: Added Matched Routing Option for better timing solutions. 54 | * Feature Enhancement: Options 'Buffer' and 'Buffer_with_CE' are added to the buffer selection list. 55 | * Other: Source HDL files are concatenated into a single file to speed up synthesis and simulation. No changes required by the user 56 | * Other: Added support for Spartan7 devices. 57 | 58 | 2016.2: 59 | * Version 5.3 (Rev. 1) 60 | * Internal register bit update, no effect on customer designs. 61 | 62 | 2016.1: 63 | * Version 5.3 64 | * Added Clock Monitor Feature as part of clocking wizard 65 | * DRP registers can be directly written through AXI without resource utilization 66 | * Changes to HDL library management to support Vivado IP simulation library 67 | 68 | 2015.4.2: 69 | * Version 5.2 (Rev. 1) 70 | * No changes 71 | 72 | 2015.4.1: 73 | * Version 5.2 (Rev. 1) 74 | * No changes 75 | 76 | 2015.4: 77 | * Version 5.2 (Rev. 1) 78 | * Internal device family change, no functional changes 79 | 80 | 2015.3: 81 | * Version 5.2 82 | * IP revision number added to HDL module, library, and include file names, to support designs with both locked and upgraded IP instances 83 | * Port Renaming tab is hidden in the GUI in IP Integrator as this feature is not supported 84 | * Phase alignment feature is removed for ultrascale PLL as primitve has limited capabilities of supporting this feature 85 | * When clocking wizard is targetted on a board part, the frequency values that gets propagated to primary and secondary clocks are displayed in floating number format 86 | * Example design and simulation files are delivered in verilog only 87 | 88 | 2015.2.1: 89 | * Version 5.1 (Rev. 6) 90 | * No changes 91 | 92 | 2015.2: 93 | * Version 5.1 (Rev. 6) 94 | * No changes 95 | 96 | 2015.1: 97 | * Version 5.1 (Rev. 6) 98 | * Updated mmcm_pll_filter_lookup and mmcm_pll_lock_lookup functions in the header file for 7-Series and UltraScale devices 99 | * Supported devices and production status are now determined automatically, to simplify support for future devices 100 | 101 | 2014.4.1: 102 | * Version 5.1 (Rev. 5) 103 | * No changes 104 | 105 | 2014.4: 106 | * Version 5.1 (Rev. 5) 107 | * Internal device family change, no functional changes 108 | * updates related to the source selection based on board interface for zed board 109 | 110 | 2014.3: 111 | * Version 5.1 (Rev. 4) 112 | * Option added to enable dynamic phase and duty cycle for resource optimization in AXI4-Lite interface 113 | 114 | 2014.2: 115 | * Version 5.1 (Rev. 3) 116 | * Updated for AXI4-Lite interface locked status register address and bit mapping to align with the pg065 117 | 118 | 2014.1: 119 | * Version 5.1 (Rev. 2) 120 | * Updated to use inverted output CLKOUTB 0-3 of Clocking Primitive based on requested 180 phase w.r.t. previous clock 121 | * Internal device family name change, no functional changes 122 | 123 | 2013.4: 124 | * Version 5.1 (Rev. 1) 125 | * Added support for Ultrascale devices 126 | * Updated Board Flow GUI to select the clock interfaces 127 | * Fixed issue with Stub file parameter error for BUFR output driver 128 | 129 | 2013.3: 130 | * Version 5.1 131 | * Added AXI4-Lite interface to dynamically reconfigure MMCM/PLL 132 | * Improved safe clock logic to remove glitches on clock outputs for odd multiples of input clock frequencies 133 | * Fixed precision issues between displayed and actual frequencies 134 | * Added tool tips to GUI 135 | * Added Jitter and Phase error values to IP properties 136 | * Added support for Cadence IES and Synopsys VCS simulators 137 | * Reduced warnings in synthesis and simulation 138 | * Enhanced support for IP Integrator 139 | 140 | 2013.2: 141 | * Version 5.0 (Rev. 1) 142 | * Fixed issue with clock constraints for multiple instances of clocking wizard 143 | * Updated Life-Cycle status of devices 144 | 145 | 2013.1: 146 | * Version 5.0 147 | * Lower case ports for Verilog 148 | * Added Safe Clock Startup and Clock Sequencing 149 | 150 | (c) Copyright 2008 - 2019 Xilinx, Inc. All rights reserved. 151 | 152 | This file contains confidential and proprietary information 153 | of Xilinx, Inc. and is protected under U.S. and 154 | international copyright and other intellectual property 155 | laws. 156 | 157 | DISCLAIMER 158 | This disclaimer is not a license and does not grant any 159 | rights to the materials distributed herewith. Except as 160 | otherwise provided in a valid license issued to you by 161 | Xilinx, and to the maximum extent permitted by applicable 162 | law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND 163 | WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES 164 | AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING 165 | BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- 166 | INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and 167 | (2) Xilinx shall not be liable (whether in contract or tort, 168 | including negligence, or under any other theory of 169 | liability) for any loss or damage of any kind or nature 170 | related to, arising under or in connection with these 171 | materials, including for any direct, or any indirect, 172 | special, incidental, or consequential loss or damage 173 | (including loss of data, profits, goodwill, or any type of 174 | loss or damage suffered as a result of any action brought 175 | by a third party) even if such damage or loss was 176 | reasonably foreseeable or Xilinx had been advised of the 177 | possibility of the same. 178 | 179 | CRITICAL APPLICATIONS 180 | Xilinx products are not designed or intended to be fail- 181 | safe, or for use in any application requiring fail-safe 182 | performance, such as life-support or safety devices or 183 | systems, Class III medical devices, nuclear facilities, 184 | applications related to the deployment of airbags, or any 185 | other applications that could lead to death, personal 186 | injury, or severe property or environmental damage 187 | (individually and collectively, "Critical 188 | Applications"). Customer assumes the sole risk and 189 | liability of any use of Xilinx products in Critical 190 | Applications, subject only to applicable laws and 191 | regulations governing limitations on product liability. 192 | 193 | THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS 194 | PART OF THIS FILE AT ALL TIMES. 195 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/mmcm_pll_drp_func_7s_pll.vh: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Company: Xilinx 4 | // Engineer: Jim Tatsukawa, Karl Kurbjun and Carl Ribbing 5 | // Date: 7/30/2014 6 | // Design Name: PLLE2 DRP 7 | // Module Name: plle2_drp_func.h 8 | // Version: 2.00 9 | // Target Devices: 7 Series || PLL 10 | // Tool versions: 2014.3 11 | // Description: This header provides the functions necessary to 12 | // calculate the DRP register values for the V6 PLL. 13 | // Updated for CR663854. 14 | // 15 | // Disclaimer: XILINX IS PROVIDING THIS DESIGN, CODE, OR 16 | // INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING 17 | // PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY 18 | // PROVIDING THIS DESIGN, CODE, OR INFORMATION AS 19 | // ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, 20 | // APPLICATION OR STANDARD, XILINX IS MAKING NO 21 | // REPRESENTATION THAT THIS IMPLEMENTATION IS FREE 22 | // FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE 23 | // RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY 24 | // REQUIRE FOR YOUR IMPLEMENTATION. XILINX 25 | // EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH 26 | // RESPECT TO THE ADEQUACY OF THE IMPLEMENTATION, 27 | // INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR 28 | // REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE 29 | // FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES 30 | // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 31 | // PURPOSE. 32 | // 33 | // (c) Copyright 2009-2010 Xilinx, Inc. 34 | // All rights reserved. 35 | // 36 | /////////////////////////////////////////////////////////////////////////////// 37 | 38 | // These are user functions that should not be modified. Changes to the defines 39 | // or code within the functions may alter the accuracy of the calculations. 40 | 41 | // Define debug to provide extra messages durring elaboration 42 | //`define DEBUG 1 43 | 44 | // FRAC_PRECISION describes the width of the fractional portion of the fixed 45 | // point numbers. These should not be modified, they are for development 46 | // only 47 | `define FRAC_PRECISION 10 48 | // FIXED_WIDTH describes the total size for fixed point calculations(int+frac). 49 | // Warning: L.50 and below will not calculate properly with FIXED_WIDTHs 50 | // greater than 32 51 | `define FIXED_WIDTH 32 52 | 53 | // This function takes a fixed point number and rounds it to the nearest 54 | // fractional precision bit. 55 | function [`FIXED_WIDTH:1] round_frac 56 | ( 57 | // Input is (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point number 58 | input [`FIXED_WIDTH:1] decimal, 59 | 60 | // This describes the precision of the fraction, for example a value 61 | // of 1 would modify the fractional so that instead of being a .16 62 | // fractional, it would be a .1 (rounded to the nearest 0.5 in turn) 63 | input [`FIXED_WIDTH:1] precision 64 | ); 65 | 66 | begin 67 | 68 | `ifdef DEBUG 69 | $display("round_frac - decimal: %h, precision: %h", decimal, precision); 70 | `endif 71 | // If the fractional precision bit is high then round up 72 | if( decimal[(`FRAC_PRECISION-precision)] == 1'b1) begin 73 | round_frac = decimal + (1'b1 << (`FRAC_PRECISION-precision)); 74 | end else begin 75 | round_frac = decimal; 76 | end 77 | `ifdef DEBUG 78 | $display("round_frac: %h", round_frac); 79 | `endif 80 | end 81 | endfunction 82 | 83 | // This function calculates high_time, low_time, w_edge, and no_count 84 | // of a non-fractional counter based on the divide and duty cycle 85 | // 86 | // NOTE: high_time and low_time are returned as integers between 0 and 63 87 | // inclusive. 64 should equal 6'b000000 (in other words it is okay to 88 | // ignore the overflow) 89 | function [13:0] mmcm_pll_divider 90 | ( 91 | input [7:0] divide, // Max divide is 128 92 | input [31:0] duty_cycle // Duty cycle is multiplied by 100,000 93 | ); 94 | 95 | reg [`FIXED_WIDTH:1] duty_cycle_fix; 96 | 97 | // High/Low time is initially calculated with a wider integer to prevent a 98 | // calculation error when it overflows to 64. 99 | reg [6:0] high_time; 100 | reg [6:0] low_time; 101 | reg w_edge; 102 | reg no_count; 103 | 104 | reg [`FIXED_WIDTH:1] temp; 105 | 106 | begin 107 | // Duty Cycle must be between 0 and 1,000 108 | if(duty_cycle <=0 || duty_cycle >= 100000) begin 109 | `ifndef SYNTHESIS 110 | $display("ERROR: duty_cycle: %d is invalid", duty_cycle); 111 | `endif 112 | $finish; 113 | end 114 | 115 | // Convert to FIXED_WIDTH-FRAC_PRECISION.FRAC_PRECISION fixed point 116 | duty_cycle_fix = (duty_cycle << `FRAC_PRECISION) / 100_000; 117 | 118 | `ifdef DEBUG 119 | $display("duty_cycle_fix: %h", duty_cycle_fix); 120 | `endif 121 | 122 | // If the divide is 1 nothing needs to be set except the no_count bit. 123 | // Other values are dummies 124 | if(divide == 7'h01) begin 125 | high_time = 7'h01; 126 | w_edge = 1'b0; 127 | low_time = 7'h01; 128 | no_count = 1'b1; 129 | end else begin 130 | temp = round_frac(duty_cycle_fix*divide, 1); 131 | 132 | // comes from above round_frac 133 | high_time = temp[`FRAC_PRECISION+7:`FRAC_PRECISION+1]; 134 | // If the duty cycle * divide rounded is .5 or greater then this bit 135 | // is set. 136 | w_edge = temp[`FRAC_PRECISION]; // comes from round_frac 137 | 138 | // If the high time comes out to 0, it needs to be set to at least 1 139 | // and w_edge set to 0 140 | if(high_time == 7'h00) begin 141 | high_time = 7'h01; 142 | w_edge = 1'b0; 143 | end 144 | 145 | if(high_time == divide) begin 146 | high_time = divide - 1; 147 | w_edge = 1'b1; 148 | end 149 | 150 | // Calculate low_time based on the divide setting and set no_count to 151 | // 0 as it is only used when divide is 1. 152 | low_time = divide - high_time; 153 | no_count = 1'b0; 154 | end 155 | 156 | // Set the return value. 157 | mmcm_pll_divider = {w_edge,no_count,high_time[5:0],low_time[5:0]}; 158 | end 159 | endfunction 160 | 161 | // This function calculates mx, delay_time, and phase_mux 162 | // of a non-fractional counter based on the divide and phase 163 | // 164 | // NOTE: The only valid value for the MX bits is 2'b00 to ensure the coarse mux 165 | // is used. 166 | function [10:0] mmcm_pll_phase 167 | ( 168 | // divide must be an integer (use fractional if not) 169 | // assumed that divide already checked to be valid 170 | input [7:0] divide, // Max divide is 128 171 | 172 | // Phase is given in degrees (-360,000 to 360,000) 173 | input signed [31:0] phase 174 | ); 175 | 176 | reg [`FIXED_WIDTH:1] phase_in_cycles; 177 | reg [`FIXED_WIDTH:1] phase_fixed; 178 | reg [1:0] mx; 179 | reg [5:0] delay_time; 180 | reg [2:0] phase_mux; 181 | 182 | reg [`FIXED_WIDTH:1] temp; 183 | 184 | begin 185 | `ifdef DEBUG 186 | $display("mmcm_pll_phase-divide:%d,phase:%d", 187 | divide, phase); 188 | `endif 189 | 190 | if ((phase < -360000) || (phase > 360000)) begin 191 | `ifndef SYNTHESIS 192 | $display("ERROR: phase of $phase is not between -360000 and 360000"); 193 | `endif 194 | $finish; 195 | end 196 | 197 | // If phase is less than 0, convert it to a positive phase shift 198 | // Convert to (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point 199 | if(phase < 0) begin 200 | phase_fixed = ( (phase + 360000) << `FRAC_PRECISION ) / 1000; 201 | end else begin 202 | phase_fixed = ( phase << `FRAC_PRECISION ) / 1000; 203 | end 204 | 205 | // Put phase in terms of decimal number of vco clock cycles 206 | phase_in_cycles = ( phase_fixed * divide ) / 360; 207 | 208 | `ifdef DEBUG 209 | $display("phase_in_cycles: %h", phase_in_cycles); 210 | `endif 211 | 212 | 213 | temp = round_frac(phase_in_cycles, 3); 214 | 215 | // set mx to 2'b00 that the phase mux from the VCO is enabled 216 | mx = 2'b00; 217 | phase_mux = temp[`FRAC_PRECISION:`FRAC_PRECISION-2]; 218 | delay_time = temp[`FRAC_PRECISION+6:`FRAC_PRECISION+1]; 219 | 220 | `ifdef DEBUG 221 | $display("temp: %h", temp); 222 | `endif 223 | 224 | // Setup the return value 225 | mmcm_pll_phase={mx, phase_mux, delay_time}; 226 | end 227 | endfunction 228 | 229 | // This function takes the divide value and outputs the necessary lock values 230 | function [39:0] mmcm_pll_lock_lookup 231 | ( 232 | input [6:0] divide // Max divide is 64 233 | ); 234 | 235 | reg [2559:0] lookup; 236 | 237 | begin 238 | lookup = { 239 | // This table is composed of: 240 | // LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt 241 | 40'b00110_00110_1111101000_1111101001_0000000001, 242 | 40'b00110_00110_1111101000_1111101001_0000000001, 243 | 40'b01000_01000_1111101000_1111101001_0000000001, 244 | 40'b01011_01011_1111101000_1111101001_0000000001, 245 | 40'b01110_01110_1111101000_1111101001_0000000001, 246 | 40'b10001_10001_1111101000_1111101001_0000000001, 247 | 40'b10011_10011_1111101000_1111101001_0000000001, 248 | 40'b10110_10110_1111101000_1111101001_0000000001, 249 | 40'b11001_11001_1111101000_1111101001_0000000001, 250 | 40'b11100_11100_1111101000_1111101001_0000000001, 251 | 40'b11111_11111_1110000100_1111101001_0000000001, 252 | 40'b11111_11111_1100111001_1111101001_0000000001, 253 | 40'b11111_11111_1011101110_1111101001_0000000001, 254 | 40'b11111_11111_1010111100_1111101001_0000000001, 255 | 40'b11111_11111_1010001010_1111101001_0000000001, 256 | 40'b11111_11111_1001110001_1111101001_0000000001, 257 | 40'b11111_11111_1000111111_1111101001_0000000001, 258 | 40'b11111_11111_1000100110_1111101001_0000000001, 259 | 40'b11111_11111_1000001101_1111101001_0000000001, 260 | 40'b11111_11111_0111110100_1111101001_0000000001, 261 | 40'b11111_11111_0111011011_1111101001_0000000001, 262 | 40'b11111_11111_0111000010_1111101001_0000000001, 263 | 40'b11111_11111_0110101001_1111101001_0000000001, 264 | 40'b11111_11111_0110010000_1111101001_0000000001, 265 | 40'b11111_11111_0110010000_1111101001_0000000001, 266 | 40'b11111_11111_0101110111_1111101001_0000000001, 267 | 40'b11111_11111_0101011110_1111101001_0000000001, 268 | 40'b11111_11111_0101011110_1111101001_0000000001, 269 | 40'b11111_11111_0101000101_1111101001_0000000001, 270 | 40'b11111_11111_0101000101_1111101001_0000000001, 271 | 40'b11111_11111_0100101100_1111101001_0000000001, 272 | 40'b11111_11111_0100101100_1111101001_0000000001, 273 | 40'b11111_11111_0100101100_1111101001_0000000001, 274 | 40'b11111_11111_0100010011_1111101001_0000000001, 275 | 40'b11111_11111_0100010011_1111101001_0000000001, 276 | 40'b11111_11111_0100010011_1111101001_0000000001, 277 | 40'b11111_11111_0011111010_1111101001_0000000001, 278 | 40'b11111_11111_0011111010_1111101001_0000000001, 279 | 40'b11111_11111_0011111010_1111101001_0000000001, 280 | 40'b11111_11111_0011111010_1111101001_0000000001, 281 | 40'b11111_11111_0011111010_1111101001_0000000001, 282 | 40'b11111_11111_0011111010_1111101001_0000000001, 283 | 40'b11111_11111_0011111010_1111101001_0000000001, 284 | 40'b11111_11111_0011111010_1111101001_0000000001, 285 | 40'b11111_11111_0011111010_1111101001_0000000001, 286 | 40'b11111_11111_0011111010_1111101001_0000000001, 287 | 40'b11111_11111_0011111010_1111101001_0000000001, 288 | 40'b11111_11111_0011111010_1111101001_0000000001, 289 | 40'b11111_11111_0011111010_1111101001_0000000001, 290 | 40'b11111_11111_0011111010_1111101001_0000000001, 291 | 40'b11111_11111_0011111010_1111101001_0000000001, 292 | 40'b11111_11111_0011111010_1111101001_0000000001, 293 | 40'b11111_11111_0011111010_1111101001_0000000001, 294 | 40'b11111_11111_0011111010_1111101001_0000000001, 295 | 40'b11111_11111_0011111010_1111101001_0000000001, 296 | 40'b11111_11111_0011111010_1111101001_0000000001, 297 | 40'b11111_11111_0011111010_1111101001_0000000001, 298 | 40'b11111_11111_0011111010_1111101001_0000000001, 299 | 40'b11111_11111_0011111010_1111101001_0000000001, 300 | 40'b11111_11111_0011111010_1111101001_0000000001, 301 | 40'b11111_11111_0011111010_1111101001_0000000001, 302 | 40'b11111_11111_0011111010_1111101001_0000000001, 303 | 40'b11111_11111_0011111010_1111101001_0000000001, 304 | 40'b11111_11111_0011111010_1111101001_0000000001 305 | }; 306 | 307 | // Set lookup_entry with the explicit bits from lookup with a part select 308 | mmcm_pll_lock_lookup = lookup[ ((64-divide)*40) +: 40]; 309 | `ifdef DEBUG 310 | $display("lock_lookup: %b", mmcm_pll_lock_lookup); 311 | `endif 312 | end 313 | endfunction 314 | 315 | // This function takes the divide value and the bandwidth setting of the PLL 316 | // and outputs the digital filter settings necessary. 317 | function [9:0] mmcm_pll_filter_lookup 318 | ( 319 | input [6:0] divide, // Max divide is 64 320 | input [8*9:0] BANDWIDTH 321 | ); 322 | 323 | reg [639:0] lookup_low; 324 | reg [639:0] lookup_high; 325 | 326 | reg [9:0] lookup_entry; 327 | 328 | begin 329 | lookup_low = { 330 | // CP_RES_LFHF 331 | 10'b0010_1111_00, 332 | 10'b0010_1111_00, 333 | 10'b0010_0111_00, 334 | 10'b0010_1101_00, 335 | 10'b0010_0101_00, 336 | 10'b0010_0101_00, 337 | 10'b0010_1001_00, 338 | 10'b0010_1110_00, 339 | 10'b0010_1110_00, 340 | 10'b0010_0001_00, 341 | 10'b0010_0001_00, 342 | 10'b0010_0110_00, 343 | 10'b0010_0110_00, 344 | 10'b0010_0110_00, 345 | 10'b0010_0110_00, 346 | 10'b0010_1010_00, 347 | 10'b0010_1010_00, 348 | 10'b0010_1010_00, 349 | 10'b0010_1010_00, 350 | 10'b0010_1100_00, 351 | 10'b0010_1100_00, 352 | 10'b0010_1100_00, 353 | 10'b0010_1100_00, 354 | 10'b0010_1100_00, 355 | 10'b0010_1100_00, 356 | 10'b0010_1100_00, 357 | 10'b0010_1100_00, 358 | 10'b0010_1100_00, 359 | 10'b0010_1100_00, 360 | 10'b0010_1100_00, 361 | 10'b0010_0010_00, 362 | 10'b0010_0010_00, 363 | 10'b0010_0010_00, 364 | 10'b0010_0010_00, 365 | 10'b0010_0010_00, 366 | 10'b0010_0010_00, 367 | 10'b0010_0010_00, 368 | 10'b0010_0010_00, 369 | 10'b0010_0010_00, 370 | 10'b0010_0010_00, 371 | 10'b0011_1100_00, 372 | 10'b0011_1100_00, 373 | 10'b0011_1100_00, 374 | 10'b0011_1100_00, 375 | 10'b0011_1100_00, 376 | 10'b0011_1100_00, 377 | 10'b0011_1100_00, 378 | 10'b0010_0100_00, 379 | 10'b0010_0100_00, 380 | 10'b0010_0100_00, 381 | 10'b0010_0100_00, 382 | 10'b0010_0100_00, 383 | 10'b0010_0100_00, 384 | 10'b0010_0100_00, 385 | 10'b0010_0100_00, 386 | 10'b0010_0100_00, 387 | 10'b0010_0100_00, 388 | 10'b0010_0100_00, 389 | 10'b0010_0100_00, 390 | 10'b0010_0100_00, 391 | 10'b0010_0100_00, 392 | 10'b0010_0100_00, 393 | 10'b0010_0100_00, 394 | 10'b0010_0100_00 395 | }; 396 | 397 | lookup_high = { 398 | // CP_RES_LFHF 399 | 10'b0011_0111_00, 400 | 10'b0011_0111_00, 401 | 10'b0101_1111_00, 402 | 10'b0111_1111_00, 403 | 10'b0111_1011_00, 404 | 10'b1101_0111_00, 405 | 10'b1110_1011_00, 406 | 10'b1110_1101_00, 407 | 10'b1111_1101_00, 408 | 10'b1111_0111_00, 409 | 10'b1111_1011_00, 410 | 10'b1111_1101_00, 411 | 10'b1111_0011_00, 412 | 10'b1110_0101_00, 413 | 10'b1111_0101_00, 414 | 10'b1111_0101_00, 415 | 10'b1111_0101_00, 416 | 10'b1111_0101_00, 417 | 10'b0111_0110_00, 418 | 10'b0111_0110_00, 419 | 10'b0111_0110_00, 420 | 10'b0111_0110_00, 421 | 10'b0101_1100_00, 422 | 10'b0101_1100_00, 423 | 10'b0101_1100_00, 424 | 10'b1100_0001_00, 425 | 10'b1100_0001_00, 426 | 10'b1100_0001_00, 427 | 10'b1100_0001_00, 428 | 10'b1100_0001_00, 429 | 10'b1100_0001_00, 430 | 10'b1100_0001_00, 431 | 10'b1100_0001_00, 432 | 10'b0100_0010_00, 433 | 10'b0100_0010_00, 434 | 10'b0100_0010_00, 435 | 10'b0010_1000_00, 436 | 10'b0010_1000_00, 437 | 10'b0010_1000_00, 438 | 10'b0011_0100_00, 439 | 10'b0010_1000_00, 440 | 10'b0010_1000_00, 441 | 10'b0010_1000_00, 442 | 10'b0010_1000_00, 443 | 10'b0010_1000_00, 444 | 10'b0010_1000_00, 445 | 10'b0010_1000_00, 446 | 10'b0010_1000_00, 447 | 10'b0010_1000_00, 448 | 10'b0010_1000_00, 449 | 10'b0010_1000_00, 450 | 10'b0010_1000_00, 451 | 10'b0010_1000_00, 452 | 10'b0100_1100_00, 453 | 10'b0100_1100_00, 454 | 10'b0100_1100_00, 455 | 10'b0100_1100_00, 456 | 10'b0100_1100_00, 457 | 10'b0100_1100_00, 458 | 10'b0100_1100_00, 459 | 10'b0010_0100_00, 460 | 10'b0010_0100_00, 461 | 10'b0010_0100_00, 462 | 10'b0010_0100_00 463 | }; 464 | 465 | // Set lookup_entry with the explicit bits from lookup with a part select 466 | if(BANDWIDTH == "LOW") begin 467 | // Low Bandwidth 468 | mmcm_pll_filter_lookup = lookup_low[ ((64-divide)*10) +: 10]; 469 | end else begin 470 | // High or optimized bandwidth 471 | mmcm_pll_filter_lookup = lookup_high[ ((64-divide)*10) +: 10]; 472 | end 473 | 474 | `ifdef DEBUG 475 | $display("filter_lookup: %b", mmcm_pll_filter_lookup); 476 | `endif 477 | end 478 | endfunction 479 | 480 | // This function takes in the divide, phase, and duty cycle 481 | // setting to calculate the upper and lower counter registers. 482 | function [37:0] mmcm_pll_count_calc 483 | ( 484 | input [7:0] divide, // Max divide is 128 485 | input signed [31:0] phase, 486 | input [31:0] duty_cycle // Multiplied by 100,000 487 | ); 488 | 489 | reg [13:0] div_calc; 490 | reg [16:0] phase_calc; 491 | 492 | begin 493 | `ifdef DEBUG 494 | $display("mmcm_pll_count_calc- divide:%h, phase:%d, duty_cycle:%d", 495 | divide, phase, duty_cycle); 496 | `endif 497 | 498 | // w_edge[13], no_count[12], high_time[11:6], low_time[5:0] 499 | div_calc = mmcm_pll_divider(divide, duty_cycle); 500 | // mx[10:9], pm[8:6], dt[5:0] 501 | phase_calc = mmcm_pll_phase(divide, phase); 502 | 503 | // Return value is the upper and lower address of counter 504 | // Upper address is: 505 | // RESERVED [31:26] 506 | // MX [25:24] 507 | // EDGE [23] 508 | // NOCOUNT [22] 509 | // DELAY_TIME [21:16] 510 | // Lower Address is: 511 | // PHASE_MUX [15:13] 512 | // RESERVED [12] 513 | // HIGH_TIME [11:6] 514 | // LOW_TIME [5:0] 515 | 516 | `ifdef DEBUG 517 | $display("div:%d dc:%d phase:%d ht:%d lt:%d ed:%d nc:%d mx:%d dt:%d pm:%d", 518 | divide, duty_cycle, phase, div_calc[11:6], div_calc[5:0], 519 | div_calc[13], div_calc[12], 520 | phase_calc[16:15], phase_calc[5:0], phase_calc[14:12]); 521 | `endif 522 | 523 | mmcm_pll_count_calc = 524 | { 525 | // Upper Address 526 | 6'h00, phase_calc[10:9], div_calc[13:12], phase_calc[5:0], 527 | // Lower Address 528 | phase_calc[8:6], 1'b0, div_calc[11:0] 529 | }; 530 | end 531 | endfunction 532 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/mmcm_pll_drp_func_us_mmcm.vh: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Company: Xilinx 4 | // Engineer: Jim Tatsukawa 5 | // Date: 7/30/2014 6 | // Design Name: MMCME2 DRP 7 | // Module Name: mmcme2_drp_func.h 8 | // Version: 1.04 9 | // Target Devices: UltraScale Architecture || MMCM 10 | // Tool versions: 2014.3 11 | // Description: This header provides the functions necessary to 12 | // calculate the DRP register values for the V6 MMCM. 13 | // 14 | // Revision Notes: 3/22 - Updating lookup_low/lookup_high (CR) 15 | // 4/13 - Fractional divide function in mmcm_frac_count_calc function. CRS610807 16 | // 17 | // Disclaimer: XILINX IS PROVIDING THIS DESIGN, CODE, OR 18 | // INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING 19 | // PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY 20 | // PROVIDING THIS DESIGN, CODE, OR INFORMATION AS 21 | // ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, 22 | // APPLICATION OR STANDARD, XILINX IS MAKING NO 23 | // REPRESENTATION THAT THIS IMPLEMENTATION IS FREE 24 | // FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE 25 | // RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY 26 | // REQUIRE FOR YOUR IMPLEMENTATION. XILINX 27 | // EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH 28 | // RESPECT TO THE ADEQUACY OF THE IMPLEMENTATION, 29 | // INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR 30 | // REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE 31 | // FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES 32 | // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 33 | // PURPOSE. 34 | // 35 | // (c) Copyright 2009-2010 Xilinx, Inc. 36 | // All rights reserved. 37 | // 38 | /////////////////////////////////////////////////////////////////////////////// 39 | 40 | // These are user functions that should not be modified. Changes to the defines 41 | // or code within the functions may alter the accuracy of the calculations. 42 | 43 | // Define debug to provide extra messages durring elaboration 44 | //`define DEBUG 1 45 | 46 | // FRAC_PRECISION describes the width of the fractional portion of the fixed 47 | // point numbers. These should not be modified, they are for development 48 | // only 49 | `define FRAC_PRECISION 10 50 | // FIXED_WIDTH describes the total size for fixed point calculations(int+frac). 51 | // Warning: L.50 and below will not calculate properly with FIXED_WIDTHs 52 | // greater than 32 53 | `define FIXED_WIDTH 32 54 | 55 | // This function takes a fixed point number and rounds it to the nearest 56 | // fractional precision bit. 57 | function [`FIXED_WIDTH:1] round_frac 58 | ( 59 | // Input is (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point number 60 | input [`FIXED_WIDTH:1] decimal, 61 | 62 | // This describes the precision of the fraction, for example a value 63 | // of 1 would modify the fractional so that instead of being a .16 64 | // fractional, it would be a .1 (rounded to the nearest 0.5 in turn) 65 | input [`FIXED_WIDTH:1] precision 66 | ); 67 | 68 | begin 69 | 70 | `ifdef DEBUG 71 | $display("round_frac - decimal: %h, precision: %h", decimal, precision); 72 | `endif 73 | // If the fractional precision bit is high then round up 74 | if( decimal[(`FRAC_PRECISION-precision)] == 1'b1) begin 75 | round_frac = decimal + (1'b1 << (`FRAC_PRECISION-precision)); 76 | end else begin 77 | round_frac = decimal; 78 | end 79 | `ifdef DEBUG 80 | $display("round_frac: %h", round_frac); 81 | `endif 82 | end 83 | endfunction 84 | 85 | // This function calculates high_time, low_time, w_edge, and no_count 86 | // of a non-fractional counter based on the divide and duty cycle 87 | // 88 | // NOTE: high_time and low_time are returned as integers between 0 and 63 89 | // inclusive. 64 should equal 6'b000000 (in other words it is okay to 90 | // ignore the overflow) 91 | function [13:0] mmcm_pll_divider 92 | ( 93 | input [7:0] divide, // Max divide is 128 94 | input [31:0] duty_cycle // Duty cycle is multiplied by 100,000 95 | ); 96 | 97 | reg [`FIXED_WIDTH:1] duty_cycle_fix; 98 | 99 | // High/Low time is initially calculated with a wider integer to prevent a 100 | // calculation error when it overflows to 64. 101 | reg [6:0] high_time; 102 | reg [6:0] low_time; 103 | reg w_edge; 104 | reg no_count; 105 | 106 | reg [`FIXED_WIDTH:1] temp; 107 | 108 | begin 109 | // Duty Cycle must be between 0 and 1,000 110 | if(duty_cycle <=0 || duty_cycle >= 100000) begin 111 | `ifndef SYNTHESIS 112 | $display("ERROR: duty_cycle: %d is invalid", duty_cycle); 113 | `endif 114 | $finish; 115 | end 116 | 117 | // Convert to FIXED_WIDTH-FRAC_PRECISION.FRAC_PRECISION fixed point 118 | duty_cycle_fix = (duty_cycle << `FRAC_PRECISION) / 100_000; 119 | 120 | `ifdef DEBUG 121 | $display("duty_cycle_fix: %h", duty_cycle_fix); 122 | `endif 123 | 124 | // If the divide is 1 nothing needs to be set except the no_count bit. 125 | // Other values are dummies 126 | if(divide == 7'h01) begin 127 | high_time = 7'h01; 128 | w_edge = 1'b0; 129 | low_time = 7'h01; 130 | no_count = 1'b1; 131 | end else begin 132 | temp = round_frac(duty_cycle_fix*divide, 1); 133 | 134 | // comes from above round_frac 135 | high_time = temp[`FRAC_PRECISION+7:`FRAC_PRECISION+1]; 136 | // If the duty cycle * divide rounded is .5 or greater then this bit 137 | // is set. 138 | w_edge = temp[`FRAC_PRECISION]; // comes from round_frac 139 | 140 | // If the high time comes out to 0, it needs to be set to at least 1 141 | // and w_edge set to 0 142 | if(high_time == 7'h00) begin 143 | high_time = 7'h01; 144 | w_edge = 1'b0; 145 | end 146 | 147 | if(high_time == divide) begin 148 | high_time = divide - 1; 149 | w_edge = 1'b1; 150 | end 151 | 152 | // Calculate low_time based on the divide setting and set no_count to 153 | // 0 as it is only used when divide is 1. 154 | low_time = divide - high_time; 155 | no_count = 1'b0; 156 | end 157 | 158 | // Set the return value. 159 | mmcm_pll_divider = {w_edge,no_count,high_time[5:0],low_time[5:0]}; 160 | end 161 | endfunction 162 | 163 | // This function calculates mx, delay_time, and phase_mux 164 | // of a non-fractional counter based on the divide and phase 165 | // 166 | // NOTE: The only valid value for the MX bits is 2'b00 to ensure the coarse mux 167 | // is used. 168 | function [10:0] mmcm_pll_phase 169 | ( 170 | // divide must be an integer (use fractional if not) 171 | // assumed that divide already checked to be valid 172 | input [7:0] divide, // Max divide is 128 173 | 174 | // Phase is given in degrees (-360,000 to 360,000) 175 | input signed [31:0] phase 176 | ); 177 | 178 | reg [`FIXED_WIDTH:1] phase_in_cycles; 179 | reg [`FIXED_WIDTH:1] phase_fixed; 180 | reg [1:0] mx; 181 | reg [5:0] delay_time; 182 | reg [2:0] phase_mux; 183 | 184 | reg [`FIXED_WIDTH:1] temp; 185 | 186 | begin 187 | `ifdef DEBUG 188 | $display("mmcm_pll_phase-divide:%d,phase:%d", 189 | divide, phase); 190 | `endif 191 | 192 | if ((phase < -360000) || (phase > 360000)) begin 193 | `ifndef SYNTHESIS 194 | $display("ERROR: phase of $phase is not between -360000 and 360000"); 195 | `endif 196 | $finish; 197 | end 198 | 199 | // If phase is less than 0, convert it to a positive phase shift 200 | // Convert to (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point 201 | if(phase < 0) begin 202 | phase_fixed = ( (phase + 360000) << `FRAC_PRECISION ) / 1000; 203 | end else begin 204 | phase_fixed = ( phase << `FRAC_PRECISION ) / 1000; 205 | end 206 | 207 | // Put phase in terms of decimal number of vco clock cycles 208 | phase_in_cycles = ( phase_fixed * divide ) / 360; 209 | 210 | `ifdef DEBUG 211 | $display("phase_in_cycles: %h", phase_in_cycles); 212 | `endif 213 | 214 | 215 | temp = round_frac(phase_in_cycles, 3); 216 | 217 | // set mx to 2'b00 that the phase mux from the VCO is enabled 218 | mx = 2'b00; 219 | phase_mux = temp[`FRAC_PRECISION:`FRAC_PRECISION-2]; 220 | delay_time = temp[`FRAC_PRECISION+6:`FRAC_PRECISION+1]; 221 | 222 | `ifdef DEBUG 223 | $display("temp: %h", temp); 224 | `endif 225 | 226 | // Setup the return value 227 | mmcm_pll_phase={mx, phase_mux, delay_time}; 228 | end 229 | endfunction 230 | 231 | // This function takes the divide value and outputs the necessary lock values 232 | function [39:0] mmcm_pll_lock_lookup 233 | ( 234 | input [6:0] divide // Max divide is 64 235 | ); 236 | 237 | reg [2559:0] lookup; 238 | 239 | begin 240 | lookup = { 241 | // This table is composed of: 242 | // LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt 243 | 40'b00110_00110_1111101000_1111101001_0000000001, 244 | 40'b00110_00110_1111101000_1111101001_0000000001, 245 | 40'b01000_01000_1111101000_1111101001_0000000001, 246 | 40'b01011_01011_1111101000_1111101001_0000000001, 247 | 40'b01110_01110_1111101000_1111101001_0000000001, 248 | 40'b10001_10001_1111101000_1111101001_0000000001, 249 | 40'b10011_10011_1111101000_1111101001_0000000001, 250 | 40'b10110_10110_1111101000_1111101001_0000000001, 251 | 40'b11001_11001_1111101000_1111101001_0000000001, 252 | 40'b11100_11100_1111101000_1111101001_0000000001, 253 | 40'b11111_11111_1110000100_1111101001_0000000001, 254 | 40'b11111_11111_1100111001_1111101001_0000000001, 255 | 40'b11111_11111_1011101110_1111101001_0000000001, 256 | 40'b11111_11111_1010111100_1111101001_0000000001, 257 | 40'b11111_11111_1010001010_1111101001_0000000001, 258 | 40'b11111_11111_1001110001_1111101001_0000000001, 259 | 40'b11111_11111_1000111111_1111101001_0000000001, 260 | 40'b11111_11111_1000100110_1111101001_0000000001, 261 | 40'b11111_11111_1000001101_1111101001_0000000001, 262 | 40'b11111_11111_0111110100_1111101001_0000000001, 263 | 40'b11111_11111_0111011011_1111101001_0000000001, 264 | 40'b11111_11111_0111000010_1111101001_0000000001, 265 | 40'b11111_11111_0110101001_1111101001_0000000001, 266 | 40'b11111_11111_0110010000_1111101001_0000000001, 267 | 40'b11111_11111_0110010000_1111101001_0000000001, 268 | 40'b11111_11111_0101110111_1111101001_0000000001, 269 | 40'b11111_11111_0101011110_1111101001_0000000001, 270 | 40'b11111_11111_0101011110_1111101001_0000000001, 271 | 40'b11111_11111_0101000101_1111101001_0000000001, 272 | 40'b11111_11111_0101000101_1111101001_0000000001, 273 | 40'b11111_11111_0100101100_1111101001_0000000001, 274 | 40'b11111_11111_0100101100_1111101001_0000000001, 275 | 40'b11111_11111_0100101100_1111101001_0000000001, 276 | 40'b11111_11111_0100010011_1111101001_0000000001, 277 | 40'b11111_11111_0100010011_1111101001_0000000001, 278 | 40'b11111_11111_0100010011_1111101001_0000000001, 279 | 40'b11111_11111_0011111010_1111101001_0000000001, 280 | 40'b11111_11111_0011111010_1111101001_0000000001, 281 | 40'b11111_11111_0011111010_1111101001_0000000001, 282 | 40'b11111_11111_0011111010_1111101001_0000000001, 283 | 40'b11111_11111_0011111010_1111101001_0000000001, 284 | 40'b11111_11111_0011111010_1111101001_0000000001, 285 | 40'b11111_11111_0011111010_1111101001_0000000001, 286 | 40'b11111_11111_0011111010_1111101001_0000000001, 287 | 40'b11111_11111_0011111010_1111101001_0000000001, 288 | 40'b11111_11111_0011111010_1111101001_0000000001, 289 | 40'b11111_11111_0011111010_1111101001_0000000001, 290 | 40'b11111_11111_0011111010_1111101001_0000000001, 291 | 40'b11111_11111_0011111010_1111101001_0000000001, 292 | 40'b11111_11111_0011111010_1111101001_0000000001, 293 | 40'b11111_11111_0011111010_1111101001_0000000001, 294 | 40'b11111_11111_0011111010_1111101001_0000000001, 295 | 40'b11111_11111_0011111010_1111101001_0000000001, 296 | 40'b11111_11111_0011111010_1111101001_0000000001, 297 | 40'b11111_11111_0011111010_1111101001_0000000001, 298 | 40'b11111_11111_0011111010_1111101001_0000000001, 299 | 40'b11111_11111_0011111010_1111101001_0000000001, 300 | 40'b11111_11111_0011111010_1111101001_0000000001, 301 | 40'b11111_11111_0011111010_1111101001_0000000001, 302 | 40'b11111_11111_0011111010_1111101001_0000000001, 303 | 40'b11111_11111_0011111010_1111101001_0000000001, 304 | 40'b11111_11111_0011111010_1111101001_0000000001, 305 | 40'b11111_11111_0011111010_1111101001_0000000001, 306 | 40'b11111_11111_0011111010_1111101001_0000000001 307 | }; 308 | 309 | // Set lookup_entry with the explicit bits from lookup with a part select 310 | mmcm_pll_lock_lookup = lookup[ ((64-divide)*40) +: 40]; 311 | `ifdef DEBUG 312 | $display("lock_lookup: %b", mmcm_pll_lock_lookup); 313 | `endif 314 | end 315 | endfunction 316 | 317 | // This function takes the divide value and the bandwidth setting of the MMCM 318 | // and outputs the digital filter settings necessary. 319 | function [9:0] mmcm_pll_filter_lookup 320 | ( 321 | input [6:0] divide, // Max divide is 64 322 | input [8*9:0] BANDWIDTH 323 | ); 324 | 325 | reg [639:0] lookup_low; 326 | reg [639:0] lookup_high; 327 | 328 | reg [9:0] lookup_entry; 329 | 330 | begin 331 | lookup_low = { 332 | // CP_RES_LFHF 333 | 10'b0010_1111_11, 334 | 10'b0010_1111_11, 335 | 10'b0010_1111_11, 336 | 10'b0010_1111_11, 337 | 10'b0010_1111_11, 338 | 10'b0010_1111_11, 339 | 10'b0010_0111_11, 340 | 10'b0010_0111_11, 341 | 10'b0010_0111_11, 342 | 10'b0010_1101_11, 343 | 10'b0010_1101_11, 344 | 10'b0010_1101_11, 345 | 10'b0010_0011_11, 346 | 10'b0010_0101_11, 347 | 10'b0010_0101_11, 348 | 10'b0010_0101_11, 349 | 10'b0010_1001_11, 350 | 10'b0010_1001_11, 351 | 10'b0010_1110_11, 352 | 10'b0010_1110_11, 353 | 10'b0010_1110_11, 354 | 10'b0010_1110_11, 355 | 10'b0010_1110_11, 356 | 10'b0010_1110_11, 357 | 10'b0010_0001_11, 358 | 10'b0010_0001_11, 359 | 10'b0010_0001_11, 360 | 10'b0010_0001_11, 361 | 10'b0010_0001_11, 362 | 10'b0010_0110_11, 363 | 10'b0010_0110_11, 364 | 10'b0010_0110_11, 365 | 10'b0010_0110_11, 366 | 10'b0010_0110_11, 367 | 10'b0010_0110_11, 368 | 10'b0010_0110_11, 369 | 10'b0010_0110_11, 370 | 10'b0010_0110_11, 371 | 10'b0010_0110_11, 372 | 10'b0010_1010_11, 373 | 10'b0010_1010_11, 374 | 10'b0010_1010_11, 375 | 10'b0010_1010_11, 376 | 10'b0010_1010_11, 377 | 10'b0010_1010_11, 378 | 10'b0010_1010_11, 379 | 10'b0010_1010_11, 380 | 10'b0010_1100_11, 381 | 10'b0010_1100_11, 382 | 10'b0010_1100_11, 383 | 10'b0010_1100_11, 384 | 10'b0010_1100_11, 385 | 10'b0010_1100_11, 386 | 10'b0010_1100_11, 387 | 10'b0010_1100_11, 388 | 10'b0010_1100_11, 389 | 10'b0010_1100_11, 390 | 10'b0010_1100_11, 391 | 10'b0010_1100_11, 392 | 10'b0010_1100_11, 393 | 10'b0010_1100_11, 394 | 10'b0010_1100_11, 395 | 10'b0010_1100_11, 396 | 10'b0010_1100_11 397 | }; 398 | 399 | lookup_high = { 400 | // CP_RES_LFHF 401 | 10'b0010_1111_11, 402 | 10'b0010_1111_11, 403 | 10'b0010_1011_11, 404 | 10'b0011_1111_11, 405 | 10'b0100_1111_11, 406 | 10'b0100_1111_11, 407 | 10'b0101_1111_11, 408 | 10'b0110_1111_11, 409 | 10'b0111_1111_11, 410 | 10'b0111_1111_11, 411 | 10'b1100_1111_11, 412 | 10'b1101_1111_11, 413 | 10'b1110_1111_11, 414 | 10'b1111_1111_11, 415 | 10'b1111_1111_11, 416 | 10'b1110_0111_11, 417 | 10'b1110_1011_11, 418 | 10'b1111_0111_11, 419 | 10'b1111_1011_11, 420 | 10'b1111_1011_11, 421 | 10'b1110_1101_11, 422 | 10'b1111_1101_11, 423 | 10'b1111_1101_11, 424 | 10'b1111_0011_11, 425 | 10'b1111_0011_11, 426 | 10'b1111_0011_11, 427 | 10'b1110_0101_11, 428 | 10'b1110_0101_11, 429 | 10'b1110_0101_11, 430 | 10'b1111_0101_11, 431 | 10'b1111_0101_11, 432 | 10'b1111_0101_11, 433 | 10'b1111_1001_11, 434 | 10'b1111_1001_11, 435 | 10'b1111_1001_11, 436 | 10'b1111_1001_11, 437 | 10'b1111_1001_11, 438 | 10'b1110_1110_11, 439 | 10'b1110_1110_11, 440 | 10'b1110_1110_11, 441 | 10'b1110_1110_11, 442 | 10'b1111_1110_11, 443 | 10'b1111_1110_11, 444 | 10'b1111_1110_11, 445 | 10'b1111_1110_11, 446 | 10'b1111_1110_11, 447 | 10'b1111_1110_11, 448 | 10'b1111_1110_11, 449 | 10'b1110_0001_11, 450 | 10'b1110_0001_11, 451 | 10'b1110_0001_11, 452 | 10'b1110_0001_11, 453 | 10'b1110_0001_11, 454 | 10'b1100_0110_11, 455 | 10'b1100_0110_11, 456 | 10'b1100_0110_11, 457 | 10'b1100_0110_11, 458 | 10'b1100_0110_11, 459 | 10'b1100_0110_11, 460 | 10'b1100_0110_11, 461 | 10'b1100_1010_11, 462 | 10'b1100_1010_11, 463 | 10'b1100_1010_11, 464 | 10'b1100_1010_11 465 | }; 466 | 467 | // Set lookup_entry with the explicit bits from lookup with a part select 468 | if(BANDWIDTH == "LOW") begin 469 | // Low Bandwidth 470 | mmcm_pll_filter_lookup = lookup_low[ ((64-divide)*10) +: 10]; 471 | end else begin 472 | // High or optimized bandwidth 473 | mmcm_pll_filter_lookup = lookup_high[ ((64-divide)*10) +: 10]; 474 | end 475 | 476 | `ifdef DEBUG 477 | $display("filter_lookup: %b", mmcm_pll_filter_lookup); 478 | `endif 479 | end 480 | endfunction 481 | 482 | // This function takes in the divide, phase, and duty cycle 483 | // setting to calculate the upper and lower counter registers. 484 | function [37:0] mmcm_pll_count_calc 485 | ( 486 | input [7:0] divide, // Max divide is 128 487 | input signed [31:0] phase, 488 | input [31:0] duty_cycle // Multiplied by 100,000 489 | ); 490 | 491 | reg [13:0] div_calc; 492 | reg [16:0] phase_calc; 493 | 494 | begin 495 | `ifdef DEBUG 496 | $display("mmcm_pll_count_calc- divide:%h, phase:%d, duty_cycle:%d", 497 | divide, phase, duty_cycle); 498 | `endif 499 | 500 | // w_edge[13], no_count[12], high_time[11:6], low_time[5:0] 501 | div_calc = mmcm_pll_divider(divide, duty_cycle); 502 | // mx[10:9], pm[8:6], dt[5:0] 503 | phase_calc = mmcm_pll_phase(divide, phase); 504 | 505 | // Return value is the upper and lower address of counter 506 | // Upper address is: 507 | // RESERVED [31:26] 508 | // MX [25:24] 509 | // EDGE [23] 510 | // NOCOUNT [22] 511 | // DELAY_TIME [21:16] 512 | // Lower Address is: 513 | // PHASE_MUX [15:13] 514 | // RESERVED [12] 515 | // HIGH_TIME [11:6] 516 | // LOW_TIME [5:0] 517 | 518 | `ifdef DEBUG 519 | $display("div:%d dc:%d phase:%d ht:%d lt:%d ed:%d nc:%d mx:%d dt:%d pm:%d", 520 | divide, duty_cycle, phase, div_calc[11:6], div_calc[5:0], 521 | div_calc[13], div_calc[12], 522 | phase_calc[16:15], phase_calc[5:0], phase_calc[14:12]); 523 | `endif 524 | 525 | mmcm_pll_count_calc = 526 | { 527 | // Upper Address 528 | 6'h00, phase_calc[10:9], div_calc[13:12], phase_calc[5:0], 529 | // Lower Address 530 | phase_calc[8:6], 1'b0, div_calc[11:0] 531 | }; 532 | end 533 | endfunction 534 | 535 | 536 | // This function takes in the divide, phase, and duty cycle 537 | // setting to calculate the upper and lower counter registers. 538 | // for fractional multiply/divide functions. 539 | // 540 | // 541 | function [37:0] mmcm_frac_count_calc 542 | ( 543 | input [7:0] divide, // Max divide is 128 544 | input signed [31:0] phase, 545 | input [31:0] duty_cycle, // Multiplied by 1,000 546 | input [9:0] frac // Multiplied by 1000 547 | ); 548 | 549 | //Required for fractional divide calculations 550 | reg [7:0] lt_frac; 551 | reg [7:0] ht_frac; 552 | 553 | reg /*[7:0]*/ wf_fall_frac; 554 | reg /*[7:0]*/ wf_rise_frac; 555 | 556 | reg [31:0] a; 557 | reg [7:0] pm_rise_frac_filtered ; 558 | reg [7:0] pm_fall_frac_filtered ; 559 | reg [7:0] clkout0_divide_int; 560 | reg [2:0] clkout0_divide_frac; 561 | reg [7:0] even_part_high; 562 | reg [7:0] even_part_low; 563 | 564 | reg [7:0] odd; 565 | reg [7:0] odd_and_frac; 566 | 567 | reg [7:0] pm_fall; 568 | reg [7:0] pm_rise; 569 | reg [7:0] dt; 570 | reg [7:0] dt_int; 571 | reg [63:0] dt_calc; 572 | 573 | reg [7:0] pm_rise_frac; 574 | reg [7:0] pm_fall_frac; 575 | 576 | reg [31:0] a_per_in_octets; 577 | reg [31:0] a_phase_in_cycles; 578 | 579 | parameter precision = 0.125; 580 | 581 | reg [31:0] phase_fixed; // changed to 31:0 from 32:1 jt 5/2/11 582 | reg [31: 0] phase_pos; 583 | reg [31: 0] phase_vco; 584 | reg [31:0] temp;// changed to 31:0 from 32:1 jt 5/2/11 585 | reg [13:0] div_calc; 586 | reg [16:0] phase_calc; 587 | 588 | begin 589 | `ifdef DEBUG 590 | $display("mmcm_frac_count_calc- divide:%h, phase:%d, duty_cycle:%d", 591 | divide, phase, duty_cycle); 592 | `endif 593 | 594 | //convert phase to fixed 595 | if ((phase < -360000) || (phase > 360000)) begin 596 | `ifndef SYNTHESIS 597 | $display("ERROR: phase of $phase is not between -360000 and 360000"); 598 | `endif 599 | $finish; 600 | end 601 | 602 | 603 | // Return value is 604 | // Transfer data 605 | // RESERVED [37:36] 606 | // FRAC_TIME [35:33] 607 | // FRAC_WF_FALL [32] 608 | // Upper address is: 609 | // RESERVED [31:26] 610 | // MX [25:24] 611 | // EDGE [23] 612 | // NOCOUNT [22] 613 | // DELAY_TIME [21:16] 614 | // Lower Address is: 615 | // PHASE_MUX [15:13] 616 | // RESERVED [12] 617 | // HIGH_TIME [11:6] 618 | // LOW_TIME [5:0] 619 | 620 | 621 | 622 | clkout0_divide_frac = frac / 125; 623 | clkout0_divide_int = divide; 624 | 625 | even_part_high = clkout0_divide_int >> 1;//$rtoi(clkout0_divide_int / 2); 626 | even_part_low = even_part_high; 627 | 628 | odd = clkout0_divide_int - even_part_high - even_part_low; 629 | odd_and_frac = (8*odd) + clkout0_divide_frac; 630 | 631 | lt_frac = even_part_high - (odd_and_frac <= 9);//IF(odd_and_frac>9,even_part_high, even_part_high - 1) 632 | ht_frac = even_part_low - (odd_and_frac <= 8);//IF(odd_and_frac>8,even_part_low, even_part_low- 1) 633 | 634 | pm_fall = {odd[6:0],2'b00} + {6'h00, clkout0_divide_frac[2:1]}; // using >> instead of clkout0_divide_frac / 2 635 | pm_rise = 0; //0 636 | 637 | wf_fall_frac = ((odd_and_frac >=2) && (odd_and_frac <=9)) || ((clkout0_divide_frac == 1) && (clkout0_divide_int == 2));//CRS610807 638 | wf_rise_frac = (odd_and_frac >=1) && (odd_and_frac <=8);//IF(odd_and_frac>=1,IF(odd_and_frac <= 8,1,0),0) 639 | 640 | 641 | 642 | //Calculate phase in fractional cycles 643 | a_per_in_octets = (8 * divide) + (frac / 125) ; 644 | a_phase_in_cycles = (phase+10) * a_per_in_octets / 360000 ;//Adding 1 due to rounding errors 645 | pm_rise_frac = (a_phase_in_cycles[7:0] ==8'h00)?8'h00:a_phase_in_cycles[7:0] - {a_phase_in_cycles[7:3],3'b000}; 646 | 647 | dt_calc = ((phase+10) * a_per_in_octets / 8 )/360000 ;//TRUNC(phase* divide / 360); //or_simply (a_per_in_octets / 8) 648 | dt = dt_calc[7:0]; 649 | 650 | pm_rise_frac_filtered = (pm_rise_frac >=8) ? (pm_rise_frac ) - 8: pm_rise_frac ; //((phase_fixed * (divide + frac / 1000)) / 360) - {pm_rise_frac[7:3],3'b000};//$rtoi(clkout0_phase * clkout0_divide / 45);//a; 651 | 652 | dt_int = dt + (& pm_rise_frac[7:4]); //IF(pm_rise_overwriting>7,dt+1,dt) 653 | pm_fall_frac = pm_fall + pm_rise_frac; 654 | pm_fall_frac_filtered = pm_fall + pm_rise_frac - {pm_fall_frac[7:3], 3'b000}; 655 | 656 | div_calc = mmcm_pll_divider(divide, duty_cycle); //Use to determine edge[7], no count[6] 657 | phase_calc = mmcm_pll_phase(divide, phase);// returns{mx[1:0], phase_mux[2:0], delay_time[5:0]} 658 | 659 | mmcm_frac_count_calc[37:0] = 660 | { 2'b00, pm_fall_frac_filtered[2:0], wf_fall_frac, 661 | 1'b0, clkout0_divide_frac[2:0], 1'b1, wf_rise_frac, phase_calc[10:9], div_calc[13:12], dt[5:0], 662 | pm_rise_frac_filtered[2], pm_rise_frac_filtered[1], pm_rise_frac_filtered[0], 1'b0, ht_frac[5:0], lt_frac[5:0] 663 | } ; 664 | 665 | `ifdef DEBUG 666 | $display("-%d.%d p%d>> :DADDR_9_15 frac30to28.frac_en.wf_r_frac.dt:%b%d%d_%b:DADDR_7_13 pm_f_frac_filtered_29to27.wf_f_frac_26:%b%d:DADDR_8_14.pm_r_frac_filt_15to13.ht_frac.lt_frac:%b%b%b:", divide, frac, phase, clkout0_divide_frac, 1, wf_rise_frac, dt, pm_fall_frac_filtered, wf_fall_frac, pm_rise_frac_filtered, ht_frac, lt_frac); 667 | `endif 668 | 669 | end 670 | endfunction 671 | 672 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/mmcm_pll_drp_func_us_pll.vh: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Company: Xilinx 4 | // Engineer: Jim Tatsukawa 5 | // Date: 6/15/2015 6 | // Design Name: PLLE3 DRP 7 | // Module Name: plle3_drp_func.h 8 | // Version: 1.10 9 | // Target Devices: UltraScale Architecture 10 | // Tool versions: 2015.1 11 | // Description: This header provides the functions necessary to 12 | // calculate the DRP register values for the V6 PLL. 13 | // 14 | // Revision Notes: 8/11 - PLLE3 updated for PLLE3 file 4564419 15 | // Revision Notes: 6/15 - pll_filter_lookup fixed for max M of 19 16 | // PM_Rise bits have been removed for PLLE3 17 | // 18 | // Disclaimer: XILINX IS PROVIDING THIS DESIGN, CODE, OR 19 | // INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING 20 | // PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY 21 | // PROVIDING THIS DESIGN, CODE, OR INFORMATION AS 22 | // ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, 23 | // APPLICATION OR STANDARD, XILINX IS MAKING NO 24 | // REPRESENTATION THAT THIS IMPLEMENTATION IS FREE 25 | // FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE 26 | // RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY 27 | // REQUIRE FOR YOUR IMPLEMENTATION. XILINX 28 | // EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH 29 | // RESPECT TO THE ADEQUACY OF THE IMPLEMENTATION, 30 | // INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR 31 | // REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE 32 | // FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES 33 | // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 34 | // PURPOSE. 35 | // 36 | // (c) Copyright 2009-2010 Xilinx, Inc. 37 | // All rights reserved. 38 | // 39 | /////////////////////////////////////////////////////////////////////////////// 40 | 41 | // These are user functions that should not be modified. Changes to the defines 42 | // or code within the functions may alter the accuracy of the calculations. 43 | 44 | // Define debug to provide extra messages durring elaboration 45 | //`define DEBUG 1 46 | 47 | // FRAC_PRECISION describes the width of the fractional portion of the fixed 48 | // point numbers. These should not be modified, they are for development 49 | // only 50 | `define FRAC_PRECISION 10 51 | // FIXED_WIDTH describes the total size for fixed point calculations(int+frac). 52 | // Warning: L.50 and below will not calculate properly with FIXED_WIDTHs 53 | // greater than 32 54 | `define FIXED_WIDTH 32 55 | 56 | // This function takes a fixed point number and rounds it to the nearest 57 | // fractional precision bit. 58 | function [`FIXED_WIDTH:1] round_frac 59 | ( 60 | // Input is (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point number 61 | input [`FIXED_WIDTH:1] decimal, 62 | 63 | // This describes the precision of the fraction, for example a value 64 | // of 1 would modify the fractional so that instead of being a .16 65 | // fractional, it would be a .1 (rounded to the nearest 0.5 in turn) 66 | input [`FIXED_WIDTH:1] precision 67 | ); 68 | 69 | begin 70 | 71 | `ifdef DEBUG 72 | $display("round_frac - decimal: %h, precision: %h", decimal, precision); 73 | `endif 74 | // If the fractional precision bit is high then round up 75 | if( decimal[(`FRAC_PRECISION-precision)] == 1'b1) begin 76 | round_frac = decimal + (1'b1 << (`FRAC_PRECISION-precision)); 77 | end else begin 78 | round_frac = decimal; 79 | end 80 | `ifdef DEBUG 81 | $display("round_frac: %h", round_frac); 82 | `endif 83 | end 84 | endfunction 85 | 86 | // This function calculates high_time, low_time, w_edge, and no_count 87 | // of a non-fractional counter based on the divide and duty cycle 88 | // 89 | // NOTE: high_time and low_time are returned as integers between 0 and 63 90 | // inclusive. 64 should equal 6'b000000 (in other words it is okay to 91 | // ignore the overflow) 92 | function [13:0] mmcm_pll_divider 93 | ( 94 | input [7:0] divide, // Max divide is 128 95 | input [31:0] duty_cycle // Duty cycle is multiplied by 100,000 96 | ); 97 | 98 | reg [`FIXED_WIDTH:1] duty_cycle_fix; 99 | 100 | // High/Low time is initially calculated with a wider integer to prevent a 101 | // calculation error when it overflows to 64. 102 | reg [6:0] high_time; 103 | reg [6:0] low_time; 104 | reg w_edge; 105 | reg no_count; 106 | 107 | reg [`FIXED_WIDTH:1] temp; 108 | 109 | begin 110 | // Duty Cycle must be between 0 and 1,000 111 | if(duty_cycle <=0 || duty_cycle >= 100000) begin 112 | `ifndef SYNTHESIS 113 | $display("ERROR: duty_cycle: %d is invalid", duty_cycle); 114 | `endif 115 | $finish; 116 | end 117 | 118 | // Convert to FIXED_WIDTH-FRAC_PRECISION.FRAC_PRECISION fixed point 119 | duty_cycle_fix = (duty_cycle << `FRAC_PRECISION) / 100_000; 120 | 121 | `ifdef DEBUG 122 | $display("duty_cycle_fix: %h", duty_cycle_fix); 123 | `endif 124 | 125 | // If the divide is 1 nothing needs to be set except the no_count bit. 126 | // Other values are dummies 127 | if(divide == 7'h01) begin 128 | high_time = 7'h01; 129 | w_edge = 1'b0; 130 | low_time = 7'h01; 131 | no_count = 1'b1; 132 | end else begin 133 | temp = round_frac(duty_cycle_fix*divide, 1); 134 | 135 | // comes from above round_frac 136 | high_time = temp[`FRAC_PRECISION+7:`FRAC_PRECISION+1]; 137 | // If the duty cycle * divide rounded is .5 or greater then this bit 138 | // is set. 139 | w_edge = temp[`FRAC_PRECISION]; // comes from round_frac 140 | 141 | // If the high time comes out to 0, it needs to be set to at least 1 142 | // and w_edge set to 0 143 | if(high_time == 7'h00) begin 144 | high_time = 7'h01; 145 | w_edge = 1'b0; 146 | end 147 | 148 | if(high_time == divide) begin 149 | high_time = divide - 1; 150 | w_edge = 1'b1; 151 | end 152 | 153 | // Calculate low_time based on the divide setting and set no_count to 154 | // 0 as it is only used when divide is 1. 155 | low_time = divide - high_time; 156 | no_count = 1'b0; 157 | end 158 | 159 | // Set the return value. 160 | mmcm_pll_divider = {w_edge,no_count,high_time[5:0],low_time[5:0]}; 161 | end 162 | endfunction 163 | 164 | // This function calculates mx, delay_time, and phase_mux 165 | // of a non-fractional counter based on the divide and phase 166 | // 167 | // NOTE: The only valid value for the MX bits is 2'b00 to ensure the coarse mux 168 | // is used. 169 | function [10:0] mmcm_pll_phase 170 | ( 171 | // divide must be an integer (use fractional if not) 172 | // assumed that divide already checked to be valid 173 | input [7:0] divide, // Max divide is 128 174 | 175 | // Phase is given in degrees (-360,000 to 360,000) 176 | input signed [31:0] phase 177 | ); 178 | 179 | reg [`FIXED_WIDTH:1] phase_in_cycles; 180 | reg [`FIXED_WIDTH:1] phase_fixed; 181 | reg [1:0] mx; 182 | reg [5:0] delay_time; 183 | reg [2:0] phase_mux; 184 | 185 | reg [`FIXED_WIDTH:1] temp; 186 | 187 | begin 188 | `ifdef DEBUG 189 | $display("mmcm_pll_phase-divide:%d,phase:%d", 190 | divide, phase); 191 | `endif 192 | 193 | if ((phase < -360000) || (phase > 360000)) begin 194 | `ifndef SYNTHESIS 195 | $display("ERROR: phase of $phase is not between -360000 and 360000"); 196 | `endif 197 | $finish; 198 | end 199 | 200 | // If phase is less than 0, convert it to a positive phase shift 201 | // Convert to (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point 202 | if(phase < 0) begin 203 | phase_fixed = ( (phase + 360000) << `FRAC_PRECISION ) / 1000; 204 | end else begin 205 | phase_fixed = ( phase << `FRAC_PRECISION ) / 1000; 206 | end 207 | 208 | // Put phase in terms of decimal number of vco clock cycles 209 | phase_in_cycles = ( phase_fixed * divide ) / 360; 210 | 211 | `ifdef DEBUG 212 | $display("phase_in_cycles: %h", phase_in_cycles); 213 | `endif 214 | 215 | 216 | temp = round_frac(phase_in_cycles, 3); 217 | 218 | // set mx to 2'b00 that the phase mux from the VCO is enabled 219 | mx = 2'b00; 220 | phase_mux = temp[`FRAC_PRECISION:`FRAC_PRECISION-2]; 221 | delay_time = temp[`FRAC_PRECISION+6:`FRAC_PRECISION+1]; 222 | 223 | `ifdef DEBUG 224 | $display("temp: %h", temp); 225 | `endif 226 | 227 | // Setup the return value 228 | mmcm_pll_phase={mx, phase_mux, delay_time}; 229 | end 230 | endfunction 231 | 232 | // This function takes the divide value and outputs the necessary lock values 233 | function [39:0] mmcm_pll_lock_lookup 234 | ( 235 | input [6:0] divide // Max divide is 64 236 | ); 237 | 238 | reg [759:0] lookup; 239 | 240 | begin 241 | lookup = { 242 | // This table is composed of: 243 | // LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt 244 | 40'b00110_00110_1111101000_1111101001_0000000001, //1 245 | 40'b00110_00110_1111101000_1111101001_0000000001, //2 246 | 40'b01000_01000_1111101000_1111101001_0000000001, //3 247 | 40'b01011_01011_1111101000_1111101001_0000000001, //4 248 | 40'b01110_01110_1111101000_1111101001_0000000001, //5 249 | 40'b10001_10001_1111101000_1111101001_0000000001, //6 250 | 40'b10011_10011_1111101000_1111101001_0000000001, //7 251 | 40'b10110_10110_1111101000_1111101001_0000000001, //8 252 | 40'b11001_11001_1111101000_1111101001_0000000001, //9 253 | 40'b11100_11100_1111101000_1111101001_0000000001, //10 254 | 40'b11111_11111_1110000100_1111101001_0000000001, //11 255 | 40'b11111_11111_1100111001_1111101001_0000000001, //12 256 | 40'b11111_11111_1011101110_1111101001_0000000001, //13 257 | 40'b11111_11111_1010111100_1111101001_0000000001, //14 258 | 40'b11111_11111_1010001010_1111101001_0000000001, //15 259 | 40'b11111_11111_1001110001_1111101001_0000000001, //16 260 | 40'b11111_11111_1000111111_1111101001_0000000001, //17 261 | 40'b11111_11111_1000100110_1111101001_0000000001, //18 262 | 40'b11111_11111_1000001101_1111101001_0000000001 //19 263 | 264 | }; 265 | 266 | // Set lookup_entry with the explicit bits from lookup with a part select 267 | mmcm_pll_lock_lookup = lookup[ ((19-divide)*40) +: 40]; 268 | `ifdef DEBUG 269 | $display("lock_lookup: %b", mmcm_pll_lock_lookup); 270 | `endif 271 | end 272 | endfunction 273 | 274 | // This function takes the divide value and the bandwidth setting of the PLL 275 | // and outputs the digital filter settings necessary. Removing bandwidth setting for PLLE3. 276 | function [9:0] mmcm_pll_filter_lookup 277 | ( 278 | input [6:0] divide // Max divide is 19 279 | ); 280 | 281 | reg [639:0] lookup; 282 | reg [9:0] lookup_entry; 283 | 284 | begin 285 | 286 | lookup = { 287 | // CP_RES_LFHF 288 | 10'b0010_1111_01, //1 289 | 10'b0010_0011_11, //2 290 | 10'b0011_0011_11, //3 291 | 10'b0010_0001_11, //4 292 | 10'b0010_0110_11, //5 293 | 10'b0010_1010_11, //6 294 | 10'b0010_1010_11, //7 295 | 10'b0011_0110_11, //8 296 | 10'b0010_1100_11, //9 297 | 10'b0010_1100_11, //10 298 | 10'b0010_1100_11, //11 299 | 10'b0010_0010_11, //12 300 | 10'b0011_1100_11, //13 301 | 10'b0011_1100_11, //14 302 | 10'b0011_1100_11, //15 303 | 10'b0011_1100_11, //16 304 | 10'b0011_0010_11, //17 305 | 10'b0011_0010_11, //18 306 | 10'b0011_0010_11 //19 307 | }; 308 | 309 | mmcm_pll_filter_lookup = lookup [ ((19-divide)*10) +: 10]; 310 | 311 | `ifdef DEBUG 312 | $display("filter_lookup: %b", mmcm_pll_filter_lookup); 313 | `endif 314 | end 315 | endfunction 316 | 317 | // This function set the CLKOUTPHY divide settings to match 318 | // the desired CLKOUTPHY_MODE setting. To create VCO_X2, then 319 | // the CLKOUTPHY will be set to 2'b00 since the VCO is internally 320 | // doubled and 2'b00 will represent divide by 1. Similarly "VCO" // will need to divide the doubled clock VCO clock frequency by // 2 therefore 2'b01 will match a divide by 2.And VCO_HALF will // need to divide the doubled VCO by 4, therefore 2'b10 321 | function [9:0] mmcm_pll_clkoutphy_calc 322 | ( 323 | input [8*9:0] CLKOUTPHY_MODE 324 | ); 325 | 326 | if(CLKOUTPHY_MODE == "VCO_X2") begin 327 | mmcm_pll_clkoutphy_calc= 2'b00; 328 | end else if(CLKOUTPHY_MODE == "VCO") begin 329 | mmcm_pll_clkoutphy_calc= 2'b01; 330 | end else if(CLKOUTPHY_MODE == "CLKIN") begin 331 | mmcm_pll_clkoutphy_calc= 2'b11; 332 | end else begin // Assume "VCO_HALF" 333 | mmcm_pll_clkoutphy_calc= 2'b10; 334 | end 335 | 336 | endfunction 337 | 338 | 339 | // This function takes in the divide, phase, and duty cycle 340 | // setting to calculate the upper and lower counter registers. 341 | function [37:0] mmcm_pll_count_calc 342 | ( 343 | input [7:0] divide, // Max divide is 128 344 | input signed [31:0] phase, 345 | input [31:0] duty_cycle // Multiplied by 100,000 346 | ); 347 | 348 | reg [13:0] div_calc; 349 | reg [16:0] phase_calc; 350 | 351 | begin 352 | `ifdef DEBUG 353 | $display("mmcm_pll_count_calc- divide:%h, phase:%d, duty_cycle:%d", 354 | divide, phase, duty_cycle); 355 | `endif 356 | 357 | // w_edge[13], no_count[12], high_time[11:6], low_time[5:0] 358 | div_calc = mmcm_pll_divider(divide, duty_cycle); 359 | // mx[10:9], pm[8:6], dt[5:0] 360 | phase_calc = mmcm_pll_phase(divide, phase); 361 | 362 | // Return value is the upper and lower address of counter 363 | // Upper address is: 364 | // RESERVED [31:26] 365 | // MX [25:24] 366 | // EDGE [23] 367 | // NOCOUNT [22] 368 | // DELAY_TIME [21:16] 369 | // Lower Address is: 370 | // PHASE_MUX [15:13] 371 | // RESERVED [12] 372 | // HIGH_TIME [11:6] 373 | // LOW_TIME [5:0] 374 | 375 | `ifdef DEBUG 376 | $display("div:%d dc:%d phase:%d ht:%d lt:%d ed:%d nc:%d mx:%d dt:%d pm:%d", 377 | divide, duty_cycle, phase, div_calc[11:6], div_calc[5:0], 378 | div_calc[13], div_calc[12], 379 | phase_calc[16:15], phase_calc[5:0], 3'b000);//Removed PM_Rise bits 380 | `endif 381 | 382 | mmcm_pll_count_calc = 383 | { 384 | // Upper Address 385 | 6'h00, phase_calc[10:9], div_calc[13:12], phase_calc[5:0], 386 | // Lower Address 387 | phase_calc[8:6], 1'b0, div_calc[11:0] 388 | }; 389 | end 390 | endfunction 391 | 392 | 393 | // This function takes in the divide, phase, and duty cycle 394 | // setting to calculate the upper and lower counter registers. 395 | // for fractional multiply/divide functions. 396 | // 397 | // 398 | function [37:0] mmcm_pll_frac_count_calc 399 | ( 400 | input [7:0] divide, // Max divide is 128 401 | input signed [31:0] phase, 402 | input [31:0] duty_cycle, // Multiplied by 1,000 403 | input [9:0] frac // Multiplied by 1000 404 | ); 405 | 406 | //Required for fractional divide calculations 407 | reg [7:0] lt_frac; 408 | reg [7:0] ht_frac; 409 | 410 | reg /*[7:0]*/ wf_fall_frac; 411 | reg /*[7:0]*/ wf_rise_frac; 412 | 413 | reg [31:0] a; 414 | reg [7:0] pm_rise_frac_filtered ; 415 | reg [7:0] pm_fall_frac_filtered ; 416 | reg [7:0] clkout0_divide_int; 417 | reg [2:0] clkout0_divide_frac; 418 | reg [7:0] even_part_high; 419 | reg [7:0] even_part_low; 420 | 421 | reg [7:0] odd; 422 | reg [7:0] odd_and_frac; 423 | 424 | reg [7:0] pm_fall; 425 | reg [7:0] pm_rise; 426 | reg [7:0] dt; 427 | reg [7:0] dt_int; 428 | reg [63:0] dt_calc; 429 | 430 | reg [7:0] pm_rise_frac; 431 | reg [7:0] pm_fall_frac; 432 | 433 | reg [31:0] a_per_in_octets; 434 | reg [31:0] a_phase_in_cycles; 435 | 436 | parameter precision = 0.125; 437 | 438 | reg [31:0] phase_fixed; // changed to 31:0 from 32:1 jt 5/2/11 439 | reg [31: 0] phase_pos; 440 | reg [31: 0] phase_vco; 441 | reg [31:0] temp;// changed to 31:0 from 32:1 jt 5/2/11 442 | reg [13:0] div_calc; 443 | reg [16:0] phase_calc; 444 | 445 | begin 446 | `ifdef DEBUG 447 | $display("mmcm_pll_frac_count_calc- divide:%h, phase:%d, duty_cycle:%d", 448 | divide, phase, duty_cycle); 449 | `endif 450 | 451 | //convert phase to fixed 452 | if ((phase < -360000) || (phase > 360000)) begin 453 | `ifndef SYNTHESIS 454 | $display("ERROR: phase of $phase is not between -360000 and 360000"); 455 | `endif 456 | $finish; 457 | end 458 | 459 | 460 | // Return value is 461 | // Transfer data 462 | // RESERVED [37:36] 463 | // FRAC_TIME [35:33] 464 | // FRAC_WF_FALL [32] 465 | // Upper address is: 466 | // RESERVED [31:26] 467 | // MX [25:24] 468 | // EDGE [23] 469 | // NOCOUNT [22] 470 | // DELAY_TIME [21:16] 471 | // Lower Address is: 472 | // PHASE_MUX [15:13] 473 | // RESERVED [12] 474 | // HIGH_TIME [11:6] 475 | // LOW_TIME [5:0] 476 | 477 | 478 | 479 | clkout0_divide_frac = frac / 125; 480 | clkout0_divide_int = divide; 481 | 482 | even_part_high = clkout0_divide_int >> 1;//$rtoi(clkout0_divide_int / 2); 483 | even_part_low = even_part_high; 484 | 485 | odd = clkout0_divide_int - even_part_high - even_part_low; 486 | odd_and_frac = (8*odd) + clkout0_divide_frac; 487 | 488 | lt_frac = even_part_high - (odd_and_frac <= 9);//IF(odd_and_frac>9,even_part_high, even_part_high - 1) 489 | ht_frac = even_part_low - (odd_and_frac <= 8);//IF(odd_and_frac>8,even_part_low, even_part_low- 1) 490 | 491 | pm_fall = {odd[6:0],2'b00} + {6'h00, clkout0_divide_frac[2:1]}; // using >> instead of clkout0_divide_frac / 2 492 | pm_rise = 0; //0 493 | 494 | wf_fall_frac = (odd_and_frac >=2) && (odd_and_frac <=9);//IF(odd_and_frac>=2,IF(odd_and_frac <= 9,1,0),0) 495 | wf_rise_frac = (odd_and_frac >=1) && (odd_and_frac <=8);//IF(odd_and_frac>=1,IF(odd_and_frac <= 8,1,0),0) 496 | 497 | 498 | 499 | //Calculate phase in fractional cycles 500 | a_per_in_octets = (8 * divide) + (frac / 125) ; 501 | a_phase_in_cycles = (phase+10) * a_per_in_octets / 360000 ;//Adding 1 due to rounding errors 502 | pm_rise_frac = (a_phase_in_cycles[7:0] ==8'h00)?8'h00:a_phase_in_cycles[7:0] - {a_phase_in_cycles[7:3],3'b000}; 503 | 504 | dt_calc = ((phase+10) * a_per_in_octets / 8 )/360000 ;//TRUNC(phase* divide / 360); //or_simply (a_per_in_octets / 8) 505 | dt = dt_calc[7:0]; 506 | 507 | pm_rise_frac_filtered = (pm_rise_frac >=8) ? (pm_rise_frac ) - 8: pm_rise_frac ; //((phase_fixed * (divide + frac / 1000)) / 360) - {pm_rise_frac[7:3],3'b000};//$rtoi(clkout0_phase * clkout0_divide / 45);//a; 508 | 509 | dt_int = dt + (& pm_rise_frac[7:4]); //IF(pm_rise_overwriting>7,dt+1,dt) 510 | pm_fall_frac = pm_fall + pm_rise_frac; 511 | pm_fall_frac_filtered = pm_fall + pm_rise_frac - {pm_fall_frac[7:3], 3'b000}; 512 | 513 | div_calc = mmcm_pll_divider(divide, duty_cycle); //Use to determine edge[7], no count[6] 514 | phase_calc = mmcm_pll_phase(divide, phase);// returns{mx[1:0], phase_mux[2:0], delay_time[5:0]} 515 | 516 | mmcm_pll_frac_count_calc[37:0] = 517 | { 2'b00, pm_fall_frac_filtered[2:0], wf_fall_frac, 518 | 1'b0, clkout0_divide_frac[2:0], 1'b1, wf_rise_frac, phase_calc[10:9], div_calc[13:12], dt[5:0], 519 | 3'b000, 1'b0, ht_frac[5:0], lt_frac[5:0] //Removed PM_Rise bits 520 | // pm_rise_frac_filtered[2], pm_rise_frac_filtered[1], pm_rise_frac_filtered[0], 1'b0, ht_frac[5:0], lt_frac[5:0] 521 | } ; 522 | 523 | `ifdef DEBUG 524 | $display("-%d.%d p%d>> :DADDR_9_15 frac30to28.frac_en.wf_r_frac.dt:%b%d%d_%b:DADDR_7_13 pm_f_frac_filtered_29to27.wf_f_frac_26:%b%d:DADDR_8_14.pm_r_frac_filt_15to13.ht_frac.lt_frac:%b%b%b:", divide, frac, phase, clkout0_divide_frac, 1, wf_rise_frac, dt, pm_fall_frac_filtered, wf_fall_frac, 3'b000, ht_frac, lt_frac); 525 | `endif 526 | 527 | end 528 | endfunction 529 | 530 | 531 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/ip/clk_wiz_0/mmcm_pll_drp_func_us_plus_pll.vh: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Company: Xilinx 4 | // Engineer: Jim Tatsukawa, Ralf Krueger, updated for Ultrascale+ 5 | // Date: 6/15/2015 6 | // Design Name: PLLE4 DRP 7 | // Module Name: plle4_drp_func.h 8 | // Version: 2.0 9 | // Target Devices: UltraScale+ Architecture 10 | // Tool versions: 2017.1 11 | // Description: This header provides the functions necessary to 12 | // calculate the DRP register values for the V6 PLL. 13 | // 14 | // Revision Notes: 8/11 - PLLE3 updated for PLLE3 file 4564419 15 | // Revision Notes: 6/15 - pll_filter_lookup fixed for max M of 19 16 | // M_Rise bits have been removed for PLLE3 17 | // Revision Notes: 2/28/17 - pll_filter_lookup and CPRES updated for 18 | // Ultrascale+ and for max M of 21 19 | // 20 | // Disclaimer: XILINX IS PROVIDING THIS DESIGN, CODE, OR 21 | // INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING 22 | // PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY 23 | // PROVIDING THIS DESIGN, CODE, OR INFORMATION AS 24 | // ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, 25 | // APPLICATION OR STANDARD, XILINX IS MAKING NO 26 | // REPRESENTATION THAT THIS IMPLEMENTATION IS FREE 27 | // FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE 28 | // RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY 29 | // REQUIRE FOR YOUR IMPLEMENTATION. XILINX 30 | // EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH 31 | // RESPECT TO THE ADEQUACY OF THE IMPLEMENTATION, 32 | // INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR 33 | // REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE 34 | // FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES 35 | // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 36 | // PURPOSE. 37 | // 38 | // (c) Copyright 2009-2017 Xilinx, Inc. 39 | // All rights reserved. 40 | // 41 | /////////////////////////////////////////////////////////////////////////////// 42 | 43 | // These are user functions that should not be modified. Changes to the defines 44 | // or code within the functions may alter the accuracy of the calculations. 45 | 46 | // Define debug to provide extra messages durring elaboration 47 | //`define DEBUG 1 48 | 49 | // FRAC_PRECISION describes the width of the fractional portion of the fixed 50 | // point numbers. These should not be modified, they are for development 51 | // only 52 | `define FRAC_PRECISION 10 53 | // FIXED_WIDTH describes the total size for fixed point calculations(int+frac). 54 | // Warning: L.50 and below will not calculate properly with FIXED_WIDTHs 55 | // greater than 32 56 | `define FIXED_WIDTH 32 57 | 58 | // This function takes a fixed point number and rounds it to the nearest 59 | // fractional precision bit. 60 | function [`FIXED_WIDTH:1] round_frac 61 | ( 62 | // Input is (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point number 63 | input [`FIXED_WIDTH:1] decimal, 64 | 65 | // This describes the precision of the fraction, for example a value 66 | // of 1 would modify the fractional so that instead of being a .16 67 | // fractional, it would be a .1 (rounded to the nearest 0.5 in turn) 68 | input [`FIXED_WIDTH:1] precision 69 | ); 70 | 71 | begin 72 | 73 | `ifdef DEBUG 74 | $display("round_frac - decimal: %h, precision: %h", decimal, precision); 75 | `endif 76 | // If the fractional precision bit is high then round up 77 | if( decimal[(`FRAC_PRECISION-precision)] == 1'b1) begin 78 | round_frac = decimal + (1'b1 << (`FRAC_PRECISION-precision)); 79 | end else begin 80 | round_frac = decimal; 81 | end 82 | `ifdef DEBUG 83 | $display("round_frac: %h", round_frac); 84 | `endif 85 | end 86 | endfunction 87 | 88 | // This function calculates high_time, low_time, w_edge, and no_count 89 | // of a non-fractional counter based on the divide and duty cycle 90 | // 91 | // NOTE: high_time and low_time are returned as integers between 0 and 63 92 | // inclusive. 64 should equal 6'b000000 (in other words it is okay to 93 | // ignore the overflow) 94 | function [13:0] mmcm_pll_divider 95 | ( 96 | input [7:0] divide, // Max divide is 128 97 | input [31:0] duty_cycle // Duty cycle is multiplied by 100,000 98 | ); 99 | 100 | reg [`FIXED_WIDTH:1] duty_cycle_fix; 101 | 102 | // High/Low time is initially calculated with a wider integer to prevent a 103 | // calculation error when it overflows to 64. 104 | reg [6:0] high_time; 105 | reg [6:0] low_time; 106 | reg w_edge; 107 | reg no_count; 108 | 109 | reg [`FIXED_WIDTH:1] temp; 110 | 111 | begin 112 | // Duty Cycle must be between 0 and 1,000 113 | if(duty_cycle <=0 || duty_cycle >= 100000) begin 114 | `ifndef SYNTHESIS 115 | $display("ERROR: duty_cycle: %d is invalid", duty_cycle); 116 | `endif 117 | $finish; 118 | end 119 | 120 | // Convert to FIXED_WIDTH-FRAC_PRECISION.FRAC_PRECISION fixed point 121 | duty_cycle_fix = (duty_cycle << `FRAC_PRECISION) / 100_000; 122 | 123 | `ifdef DEBUG 124 | $display("duty_cycle_fix: %h", duty_cycle_fix); 125 | `endif 126 | 127 | // If the divide is 1 nothing needs to be set except the no_count bit. 128 | // Other values are dummies 129 | if(divide == 7'h01) begin 130 | high_time = 7'h01; 131 | w_edge = 1'b0; 132 | low_time = 7'h01; 133 | no_count = 1'b1; 134 | end else begin 135 | temp = round_frac(duty_cycle_fix*divide, 1); 136 | 137 | // comes from above round_frac 138 | high_time = temp[`FRAC_PRECISION+7:`FRAC_PRECISION+1]; 139 | // If the duty cycle * divide rounded is .5 or greater then this bit 140 | // is set. 141 | w_edge = temp[`FRAC_PRECISION]; // comes from round_frac 142 | 143 | // If the high time comes out to 0, it needs to be set to at least 1 144 | // and w_edge set to 0 145 | if(high_time == 7'h00) begin 146 | high_time = 7'h01; 147 | w_edge = 1'b0; 148 | end 149 | 150 | if(high_time == divide) begin 151 | high_time = divide - 1; 152 | w_edge = 1'b1; 153 | end 154 | 155 | // Calculate low_time based on the divide setting and set no_count to 156 | // 0 as it is only used when divide is 1. 157 | low_time = divide - high_time; 158 | no_count = 1'b0; 159 | end 160 | 161 | // Set the return value. 162 | mmcm_pll_divider = {w_edge,no_count,high_time[5:0],low_time[5:0]}; 163 | end 164 | endfunction 165 | 166 | // This function calculates mx, delay_time, and phase_mux 167 | // of a non-fractional counter based on the divide and phase 168 | // 169 | // NOTE: The only valid value for the MX bits is 2'b00 to ensure the coarse mux 170 | // is used. 171 | function [10:0] mmcm_pll_phase 172 | ( 173 | // divide must be an integer (use fractional if not) 174 | // assumed that divide already checked to be valid 175 | input [7:0] divide, // Max divide is 128 176 | 177 | // Phase is given in degrees (-360,000 to 360,000) 178 | input signed [31:0] phase 179 | ); 180 | 181 | reg [`FIXED_WIDTH:1] phase_in_cycles; 182 | reg [`FIXED_WIDTH:1] phase_fixed; 183 | reg [1:0] mx; 184 | reg [5:0] delay_time; 185 | reg [2:0] phase_mux; 186 | 187 | reg [`FIXED_WIDTH:1] temp; 188 | 189 | begin 190 | `ifdef DEBUG 191 | $display("pll_phase-divide:%d,phase:%d", 192 | divide, phase); 193 | `endif 194 | 195 | if ((phase < -360000) || (phase > 360000)) begin 196 | `ifndef SYNTHESIS 197 | $display("ERROR: phase of $phase is not between -360000 and 360000"); 198 | `endif 199 | $finish; 200 | end 201 | 202 | // If phase is less than 0, convert it to a positive phase shift 203 | // Convert to (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point 204 | if(phase < 0) begin 205 | phase_fixed = ( (phase + 360000) << `FRAC_PRECISION ) / 1000; 206 | end else begin 207 | phase_fixed = ( phase << `FRAC_PRECISION ) / 1000; 208 | end 209 | 210 | // Put phase in terms of decimal number of vco clock cycles 211 | phase_in_cycles = ( phase_fixed * divide ) / 360; 212 | 213 | `ifdef DEBUG 214 | $display("phase_in_cycles: %h", phase_in_cycles); 215 | `endif 216 | 217 | 218 | temp = round_frac(phase_in_cycles, 3); 219 | 220 | // set mx to 2'b00 that the phase mux from the VCO is enabled 221 | mx = 2'b00; 222 | phase_mux = temp[`FRAC_PRECISION:`FRAC_PRECISION-2]; 223 | delay_time = temp[`FRAC_PRECISION+6:`FRAC_PRECISION+1]; 224 | 225 | `ifdef DEBUG 226 | $display("temp: %h", temp); 227 | `endif 228 | 229 | // Setup the return value 230 | mmcm_pll_phase={mx, phase_mux, delay_time}; 231 | end 232 | endfunction 233 | 234 | // This function takes the divide value and outputs the necessary lock values 235 | function [39:0] mmcm_pll_lock_lookup 236 | ( 237 | input [6:0] divide // Max divide is 21 238 | ); 239 | 240 | reg [839:0] lookup; 241 | 242 | begin 243 | lookup = { 244 | // This table is composed of: 245 | // LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt 246 | 40'b00110_00110_1111101000_1111101001_0000000001, //1 illegal in Ultrascale+ 247 | 40'b00110_00110_1111101000_1111101001_0000000001, //2 248 | 40'b01000_01000_1111101000_1111101001_0000000001, //3 249 | 40'b01011_01011_1111101000_1111101001_0000000001, //4 250 | 40'b01110_01110_1111101000_1111101001_0000000001, //5 251 | 40'b10001_10001_1111101000_1111101001_0000000001, //6 252 | 40'b10011_10011_1111101000_1111101001_0000000001, //7 253 | 40'b10110_10110_1111101000_1111101001_0000000001, //8 254 | 40'b11001_11001_1111101000_1111101001_0000000001, //9 255 | 40'b11100_11100_1111101000_1111101001_0000000001, //10 256 | 40'b11111_11111_1110000100_1111101001_0000000001, //11 257 | 40'b11111_11111_1100111001_1111101001_0000000001, //12 258 | 40'b11111_11111_1011101110_1111101001_0000000001, //13 259 | 40'b11111_11111_1010111100_1111101001_0000000001, //14 260 | 40'b11111_11111_1010001010_1111101001_0000000001, //15 261 | 40'b11111_11111_1001110001_1111101001_0000000001, //16 262 | 40'b11111_11111_1000111111_1111101001_0000000001, //17 263 | 40'b11111_11111_1000100110_1111101001_0000000001, //18 264 | 40'b11111_11111_1000001101_1111101001_0000000001, //19 265 | 40'b11111_11111_0111110100_1111101001_0000000001, //20 266 | 40'b11111_11111_0111011011_1111101001_0000000001 //21 267 | }; 268 | 269 | // Set lookup_entry with the explicit bits from lookup with a part select 270 | mmcm_pll_lock_lookup = lookup[ ((21-divide)*40) +: 40]; 271 | `ifdef DEBUG 272 | $display("lock_lookup: %b", pll_lock_lookup); 273 | `endif 274 | end 275 | endfunction 276 | 277 | // This function takes the divide value and the bandwidth setting of the PLL 278 | // and outputs the digital filter settings necessary. Removing bandwidth setting for PLLE3. 279 | function [9:0] mmcm_pll_filter_lookup 280 | ( 281 | input [6:0] divide // Max divide is 21 282 | ); 283 | 284 | reg [209:0] lookup; 285 | reg [9:0] lookup_entry; 286 | 287 | begin 288 | 289 | lookup = { 290 | // CP_RES_LFHF 291 | 10'b0011_0111_11, //1 not legal in Ultrascale+ 292 | 10'b0011_0111_11, //2 293 | 10'b0011_0011_11, //3 294 | 10'b0011_1001_11, //4 295 | 10'b0011_0001_11, //5 296 | 10'b0100_1110_11, //6 297 | 10'b0011_0110_11, //7 298 | 10'b0011_1010_11, //8 299 | 10'b0111_1001_11, //9 300 | 10'b0111_1001_11, //10 301 | 10'b0101_0110_11, //11 302 | 10'b1100_0101_11, //12 303 | 10'b0101_1010_11, //13 304 | 10'b0110_0110_11, //14 305 | 10'b0110_1010_11, //15 306 | 10'b0111_0110_11, //16 307 | 10'b1111_0101_11, //17 308 | 10'b1100_0110_11, //18 309 | 10'b1110_0001_11, //19 310 | 10'b1101_0110_11, //20 311 | 10'b1111_0001_11 //21 312 | }; 313 | 314 | mmcm_pll_filter_lookup = lookup [ ((21-divide)*10) +: 10]; 315 | 316 | `ifdef DEBUG 317 | $display("filter_lookup: %b", pll_filter_lookup); 318 | `endif 319 | end 320 | endfunction 321 | 322 | // This function set the CLKOUTPHY divide settings to match 323 | // the desired CLKOUTPHY_MODE setting. To create VCO_X2, then 324 | // the CLKOUTPHY will be set to 2'b00 since the VCO is internally 325 | // doubled and 2'b00 will represent divide by 1. Similarly "VCO" 326 | // will need to divide the doubled clock VCO clock frequency by 327 | // 2 therefore 2'b01 will match a divide by 2.And VCO_HALF will 328 | // need to divide the doubled VCO by 4, therefore 2'b10 329 | function [9:0] mmcm_pll_clkoutphy_calc 330 | ( 331 | input [8*9:0] CLKOUTPHY_MODE 332 | ); 333 | 334 | if(CLKOUTPHY_MODE == "VCO_X2") begin 335 | mmcm_pll_clkoutphy_calc= 2'b00; 336 | end else if(CLKOUTPHY_MODE == "VCO") begin 337 | mmcm_pll_clkoutphy_calc= 2'b01; 338 | end else if(CLKOUTPHY_MODE == "CLKIN") begin 339 | mmcm_pll_clkoutphy_calc= 2'b11; 340 | end else begin // Assume "VCO_HALF" 341 | mmcm_pll_clkoutphy_calc= 2'b10; 342 | end 343 | 344 | endfunction 345 | 346 | 347 | // This function takes in the divide, phase, and duty cycle 348 | // setting to calculate the upper and lower counter registers. 349 | function [37:0] mmcm_pll_count_calc 350 | ( 351 | input [7:0] divide, // Max divide is 128 352 | input signed [31:0] phase, 353 | input [31:0] duty_cycle // Multiplied by 100,000 354 | ); 355 | 356 | reg [13:0] div_calc; 357 | reg [16:0] phase_calc; 358 | 359 | begin 360 | `ifdef DEBUG 361 | $display("pll_count_calc- divide:%h, phase:%d, duty_cycle:%d", 362 | divide, phase, duty_cycle); 363 | `endif 364 | 365 | // w_edge[13], no_count[12], high_time[11:6], low_time[5:0] 366 | div_calc = mmcm_pll_divider(divide, duty_cycle); 367 | // mx[10:9], pm[8:6], dt[5:0] 368 | phase_calc = mmcm_pll_phase(divide, phase); 369 | 370 | // Return value is the upper and lower address of counter 371 | // Upper address is: 372 | // RESERVED [31:26] 373 | // MX [25:24] 374 | // EDGE [23] 375 | // NOCOUNT [22] 376 | // DELAY_TIME [21:16] 377 | // Lower Address is: 378 | // PHASE_MUX [15:13] 379 | // RESERVED [12] 380 | // HIGH_TIME [11:6] 381 | // LOW_TIME [5:0] 382 | 383 | `ifdef DEBUG 384 | $display("div:%d dc:%d phase:%d ht:%d lt:%d ed:%d nc:%d mx:%d dt:%d pm:%d", 385 | divide, duty_cycle, phase, div_calc[11:6], div_calc[5:0], 386 | div_calc[13], div_calc[12], 387 | phase_calc[16:15], phase_calc[5:0], 3'b000); //Removed PM_Rise bits 388 | `endif 389 | 390 | mmcm_pll_count_calc = 391 | { 392 | // Upper Address 393 | 6'h00, phase_calc[10:9], div_calc[13:12], phase_calc[5:0], 394 | // Lower Address 395 | phase_calc[8:6], 1'b0, div_calc[11:0] 396 | }; 397 | end 398 | endfunction 399 | 400 | 401 | // This function takes in the divide, phase, and duty cycle 402 | // setting to calculate the upper and lower counter registers. 403 | // for fractional multiply/divide functions. 404 | // 405 | // 406 | function [37:0] mmcm_pll_frac_count_calc 407 | ( 408 | input [7:0] divide, // Max divide is 128 409 | input signed [31:0] phase, 410 | input [31:0] duty_cycle, // Multiplied by 1,000 411 | input [9:0] frac // Multiplied by 1000 412 | ); 413 | 414 | //Required for fractional divide calculations 415 | reg [7:0] lt_frac; 416 | reg [7:0] ht_frac; 417 | 418 | reg /*[7:0]*/ wf_fall_frac; 419 | reg /*[7:0]*/ wf_rise_frac; 420 | 421 | reg [31:0] a; 422 | reg [7:0] pm_rise_frac_filtered ; 423 | reg [7:0] pm_fall_frac_filtered ; 424 | reg [7:0] clkout0_divide_int; 425 | reg [2:0] clkout0_divide_frac; 426 | reg [7:0] even_part_high; 427 | reg [7:0] even_part_low; 428 | 429 | reg [7:0] odd; 430 | reg [7:0] odd_and_frac; 431 | 432 | reg [7:0] pm_fall; 433 | reg [7:0] pm_rise; 434 | reg [7:0] dt; 435 | reg [7:0] dt_int; 436 | reg [63:0] dt_calc; 437 | 438 | reg [7:0] pm_rise_frac; 439 | reg [7:0] pm_fall_frac; 440 | 441 | reg [31:0] a_per_in_octets; 442 | reg [31:0] a_phase_in_cycles; 443 | 444 | parameter precision = 0.125; 445 | 446 | reg [31:0] phase_fixed; // changed to 31:0 from 32:1 jt 5/2/11 447 | reg [31: 0] phase_pos; 448 | reg [31: 0] phase_vco; 449 | reg [31:0] temp;// changed to 31:0 from 32:1 jt 5/2/11 450 | reg [13:0] div_calc; 451 | reg [16:0] phase_calc; 452 | 453 | begin 454 | `ifdef DEBUG 455 | $display("pll_frac_count_calc- divide:%h, phase:%d, duty_cycle:%d", 456 | divide, phase, duty_cycle); 457 | `endif 458 | 459 | //convert phase to fixed 460 | if ((phase < -360000) || (phase > 360000)) begin 461 | `ifndef SYNTHESIS 462 | $display("ERROR: phase of $phase is not between -360000 and 360000"); 463 | `endif 464 | $finish; 465 | end 466 | 467 | 468 | // Return value is 469 | // Transfer data 470 | // RESERVED [37:36] 471 | // FRAC_TIME [35:33] 472 | // FRAC_WF_FALL [32] 473 | // Upper address is: 474 | // RESERVED [31:26] 475 | // MX [25:24] 476 | // EDGE [23] 477 | // NOCOUNT [22] 478 | // DELAY_TIME [21:16] 479 | // Lower Address is: 480 | // PHASE_MUX [15:13] 481 | // RESERVED [12] 482 | // HIGH_TIME [11:6] 483 | // LOW_TIME [5:0] 484 | 485 | 486 | 487 | clkout0_divide_frac = frac / 125; 488 | clkout0_divide_int = divide; 489 | 490 | even_part_high = clkout0_divide_int >> 1;//$rtoi(clkout0_divide_int / 2); 491 | even_part_low = even_part_high; 492 | 493 | odd = clkout0_divide_int - even_part_high - even_part_low; 494 | odd_and_frac = (8*odd) + clkout0_divide_frac; 495 | 496 | lt_frac = even_part_high - (odd_and_frac <= 9);//IF(odd_and_frac>9,even_part_high, even_part_high - 1) 497 | ht_frac = even_part_low - (odd_and_frac <= 8);//IF(odd_and_frac>8,even_part_low, even_part_low- 1) 498 | 499 | pm_fall = {odd[6:0],2'b00} + {6'h00, clkout0_divide_frac[2:1]}; // using >> instead of clkout0_divide_frac / 2 500 | pm_rise = 0; //0 501 | 502 | wf_fall_frac = (odd_and_frac >=2) && (odd_and_frac <=9);//IF(odd_and_frac>=2,IF(odd_and_frac <= 9,1,0),0) 503 | wf_rise_frac = (odd_and_frac >=1) && (odd_and_frac <=8);//IF(odd_and_frac>=1,IF(odd_and_frac <= 8,1,0),0) 504 | 505 | 506 | 507 | //Calculate phase in fractional cycles 508 | a_per_in_octets = (8 * divide) + (frac / 125) ; 509 | a_phase_in_cycles = (phase+10) * a_per_in_octets / 360000 ;//Adding 1 due to rounding errors 510 | pm_rise_frac = (a_phase_in_cycles[7:0] ==8'h00)?8'h00:a_phase_in_cycles[7:0] - {a_phase_in_cycles[7:3],3'b000}; 511 | 512 | dt_calc = ((phase+10) * a_per_in_octets / 8 )/360000 ;//TRUNC(phase* divide / 360); //or_simply (a_per_in_octets / 8) 513 | dt = dt_calc[7:0]; 514 | 515 | pm_rise_frac_filtered = (pm_rise_frac >=8) ? (pm_rise_frac ) - 8: pm_rise_frac ; //((phase_fixed * (divide + frac / 1000)) / 360) - {pm_rise_frac[7:3],3'b000};//$rtoi(clkout0_phase * clkout0_divide / 45);//a; 516 | 517 | dt_int = dt + (& pm_rise_frac[7:4]); //IF(pm_rise_overwriting>7,dt+1,dt) 518 | pm_fall_frac = pm_fall + pm_rise_frac; 519 | pm_fall_frac_filtered = pm_fall + pm_rise_frac - {pm_fall_frac[7:3], 3'b000}; 520 | 521 | div_calc = mmcm_pll_divider(divide, duty_cycle); //Use to determine edge[7], no count[6] 522 | phase_calc = mmcm_pll_phase(divide, phase);// returns{mx[1:0], phase_mux[2:0], delay_time[5:0]} 523 | 524 | mmcm_pll_frac_count_calc[37:0] = 525 | { 2'b00, pm_fall_frac_filtered[2:0], wf_fall_frac, 526 | 1'b0, clkout0_divide_frac[2:0], 1'b1, wf_rise_frac, phase_calc[10:9], div_calc[13:12], dt[5:0], 527 | 3'b000, 1'b0, ht_frac[5:0], lt_frac[5:0] //Removed PM_Rise bits 528 | } ; 529 | 530 | `ifdef DEBUG 531 | $display("-%d.%d p%d>> :DADDR_9_15 frac30to28.frac_en.wf_r_frac.dt:%b%d%d_%b:DADDR_7_13 pm_f_frac_filtered_29to27.wf_f_frac_26:%b%d:DADDR_8_14.pm_r_frac_filt_15to13.ht_frac.lt_frac:%b%b%b:", divide, frac, phase, clkout0_divide_frac, 1, wf_rise_frac, dt, pm_fall_frac_filtered, wf_fall_frac, 3'b000, ht_frac, lt_frac); 532 | `endif 533 | 534 | end 535 | endfunction 536 | 537 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/new/delay.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | 4 | module delay( 5 | input clk, 6 | input reset, 7 | input enable, 8 | input [31:0] length, 9 | output reg done, 10 | output reg [1:0] state = 4'd0 11 | ); 12 | 13 | parameter STATE_IDLE = 2'd0; 14 | parameter STATE_DELAY = 2'd1; 15 | 16 | reg [31:0] counter = 32'd0; 17 | 18 | 19 | always @(posedge clk) 20 | begin 21 | // default assignments 22 | state <= state; 23 | counter <= counter; 24 | done <= 1'd0; 25 | 26 | if(reset) 27 | begin 28 | counter <= 32'd0; 29 | state <= STATE_IDLE; 30 | end 31 | else 32 | begin 33 | case(state) 34 | STATE_IDLE: 35 | begin 36 | if(enable) 37 | begin 38 | counter <= 32'd0; 39 | state <= STATE_DELAY; 40 | end 41 | end 42 | STATE_DELAY: 43 | begin 44 | counter <= counter + 1; 45 | if(counter == length) 46 | begin 47 | done <= 1'd1; 48 | state <= STATE_IDLE; 49 | end 50 | end 51 | endcase 52 | end 53 | end 54 | 55 | endmodule 56 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/new/pulse.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | 4 | module pulse( 5 | input clk, 6 | input reset, 7 | input enable, 8 | input [31:0] length, 9 | output reg pulse = 1'd0, 10 | output reg done = 1'd0, 11 | output reg [1:0] state = 2'd0 12 | ); 13 | 14 | reg [31:0] counter = 32'd0; 15 | 16 | parameter STATE_IDLE = 2'd0; 17 | parameter STATE_PULSE = 2'd1; 18 | 19 | always @(posedge clk) 20 | begin 21 | // default assignments 22 | state <= state; 23 | counter <= counter; 24 | pulse <= 1'd0; 25 | done <= 1'd0; 26 | 27 | if(reset) 28 | begin 29 | counter <= 32'd0; 30 | state <= STATE_IDLE; 31 | end 32 | else 33 | begin 34 | case(state) 35 | STATE_IDLE: 36 | begin 37 | if(enable) 38 | begin 39 | counter <= 32'd0; 40 | state <= STATE_PULSE; 41 | pulse <= 1'd1; 42 | end 43 | end 44 | STATE_PULSE: 45 | begin 46 | counter <= counter + 1; 47 | pulse <= 1'd1; 48 | if(counter == length) 49 | begin 50 | done <= 1'd1; 51 | state <= STATE_IDLE; 52 | end 53 | end 54 | endcase 55 | end 56 | end 57 | 58 | endmodule 59 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/new/top.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module top( 4 | input sys_clk, 5 | output [1:0] led, // Led outputs 6 | output [2:0] rgb, // RGB led 7 | input [1:0] btn, // buttons 8 | input [7:0] gpio, // GPIOs 9 | input uart_txd_in, // This is the RX input.. thanks for the naming digilent :D 10 | output uart_rxd_out, // This is the TX output 11 | 12 | input trigger_in, 13 | output power_out, 14 | output glitch_out 15 | ); 16 | 17 | // Clock 18 | wire main_clk; 19 | // Generate a 100MHz clock from the external 12MHz clock 20 | clk_wiz_0 clock_generator 21 | ( 22 | // Clock out ports 23 | .main_clk(main_clk), // output main_clk 24 | // Clock in ports 25 | .clk_in1(sys_clk)); // input clk_in1 26 | 27 | 28 | // deal with fucking meta stability 29 | reg uart_rxd_stable = 1'd0; 30 | always @(posedge main_clk) 31 | begin 32 | uart_rxd_stable <= uart_txd_in; 33 | end 34 | 35 | // Used to reset all modules (not fully functional currently) 36 | // TODO add debouncer for button 37 | reg reset = 1'd0; 38 | 39 | // Main UART transmitter 40 | reg tx_enable = 1'd0; 41 | reg [7:0] tx_data = 8'd67; 42 | wire tx_ready; 43 | uart_tx tx1( 44 | .clk(main_clk), 45 | .reset(reset), 46 | .data(tx_data), 47 | .enable(tx_enable), 48 | .tx(uart_rxd_out), 49 | .ready(tx_ready) 50 | ); 51 | 52 | // Main UART receiver 53 | wire [7:0] rx_data; 54 | wire rx_valid; 55 | uart_rx rx1( 56 | .clk(main_clk), 57 | .reset(reset), 58 | .data(rx_data), 59 | .rx(uart_rxd_stable), 60 | .valid(rx_valid) 61 | ); 62 | 63 | // COMMANDS 64 | // power cycle the target (B) 65 | parameter CMD_POWER_CYCLE = 8'd66; 66 | // set the duration of the glitch pulse (uint32) (C) 67 | parameter CMD_SET_GLITCH_PULSE = 8'd67; 68 | // set the duration of the delay between the trigger input and the glitch (uint32) (D) 69 | parameter CMD_SET_DELAY = 8'd68; 70 | // set the duration of the pulse used to reset the device (uint32) (E) 71 | parameter CMD_SET_POWER_PULSE = 8'd69; 72 | // execute glitch (wait for trigger, wait for $delay, send glitch pulse) (F) 73 | parameter CMD_GLITCH = 8'd70; 74 | // read the 8 gpio pins. returns a single byte with the states of the IOs (G) 75 | parameter CMD_READ_GPIO = 8'd71; 76 | // enable or disable the powercycle before glitching. (bool/single byte 0 or 1) (H) 77 | parameter CMD_ENABLE_GLITCH_POWER_CYCLE = 8'd72; 78 | // returns the state of power pulse, trigger, delay, glitch pulse 79 | parameter CMD_GET_STATE = 8'd73; 80 | 81 | 82 | // STATES 83 | // Wait for a single command on UART 84 | // white 85 | parameter STATE_WAIT_COMMAND = 8'd0; 86 | // Wait for 4 bytes on UART that set the glitch pulse 87 | // purple 88 | parameter STATE_SET_GLITCH_PULSE = 8'd2; 89 | // Wait for 4 bytes on UART that set the delay 90 | // red 91 | parameter STATE_SET_DELAY = 8'd3; 92 | // Wait for 4 bytes on UART that set the power cycle duration 93 | // cyan 94 | parameter STATE_SET_POWER_PULSE = 8'd4; 95 | // Wait for 1 byte on UART that sets whether the target is power cycled before glitch 96 | // green 97 | parameter STATE_ENABLE_GLITCH_POWER_CYCLE = 8'd5; 98 | // Wait for the power cycle to be over. 99 | // blue 100 | parameter STATE_WAIT_POWER_CYCLE = 8'd6; 101 | 102 | reg [7:0] state = STATE_WAIT_COMMAND; 103 | 104 | // Receiver for receiving uint32 via serial 105 | reg u32_rec_enable = 1'd0; 106 | wire u32_rec_valid; 107 | wire [31:0] u32_rec_data; 108 | uint32_receiver u32_rec( 109 | .clk(main_clk), 110 | .reset(reset), 111 | .uart_data(rx_data), 112 | .uart_valid(rx_valid), 113 | .data(u32_rec_data), 114 | .data_valid(u32_rec_valid), 115 | .enable(u32_rec_enable) 116 | ); 117 | 118 | // Variables used by the glitcher 119 | reg [31:0] glitch_pulse_length = 32'd0; 120 | reg [31:0] glitch_delay_length = 32'd0; 121 | reg [31:0] power_pulse_length = 32'd0; 122 | // whether the device should be powercycled before glitching 123 | reg glitch_power_cycle = 1'd0; 124 | // Indicate current state on RGB led 125 | assign rgb = state[2:0]; 126 | 127 | 128 | // power pulse 129 | // only used in glitch chain if glitch_power_cycle is 1 130 | reg power_pulse_enable = 1'd0; 131 | wire power_pulse_pulse; 132 | wire power_pulse_done; 133 | // Used to output diagnostics via UART 134 | wire [1:0] power_pulse_state; 135 | pulse power_pulse( 136 | .clk(main_clk), 137 | .reset(reset), 138 | .enable(power_pulse_enable), 139 | .length(power_pulse_length), 140 | .pulse(power_pulse_pulse), 141 | .done(power_pulse_done), 142 | .state(power_pulse_state) 143 | ); 144 | 145 | // trigger 146 | reg glitch_trigger_enable = 1'b0; 147 | // Used to disable the entire trigger during a power-cycle-only 148 | reg disable_trigger = 1'b0; 149 | wire glitch_trigger_enable_mixed = ((power_pulse_done && glitch_power_cycle) || glitch_trigger_enable) && ~disable_trigger; 150 | reg [31:0] glitch_trigger_length = 32'd255; 151 | wire glitch_trigger_triggered; 152 | wire [1:0] glitch_trigger_state; 153 | 154 | trigger glitch_trigger( 155 | .clk(main_clk), 156 | .reset(reset), 157 | .enable(glitch_trigger_enable_mixed), 158 | .in(trigger_in), 159 | .trigger_length(glitch_trigger_length), 160 | .triggered(glitch_trigger_triggered), 161 | .state(glitch_trigger_state) 162 | ); 163 | 164 | // glitch delay 165 | wire glitch_delay_done; 166 | wire [1:0] glitch_delay_state; 167 | delay glitch_delay( 168 | .clk(main_clk), 169 | .reset(reset), 170 | .enable(glitch_trigger_triggered), 171 | .length(glitch_delay_length), 172 | .done(glitch_delay_done), 173 | .state(glitch_delay_state) 174 | ); 175 | 176 | 177 | // glitch pulse 178 | // mix our manual glitch enable with the output from the delay 179 | wire glitch_pulse_pulse; 180 | wire glitch_pulse_done; 181 | wire [1:0] glitch_pulse_state; 182 | pulse glitch_pulse( 183 | .clk(main_clk), 184 | .reset(reset), 185 | .enable(glitch_delay_done), 186 | .length(glitch_pulse_length), 187 | .pulse(glitch_pulse_pulse), 188 | .done(glitch_pulse_done), 189 | .state(glitch_pulse_state) 190 | ); 191 | 192 | assign led[0] = power_pulse_pulse; 193 | assign led[1] = glitch_pulse_pulse; 194 | assign power_out = power_pulse_pulse; 195 | // We also pull glitch high when power resetting to make sure we don't accidentally keep the core on 196 | assign glitch_out = power_pulse_pulse || glitch_pulse_pulse; 197 | 198 | always @(posedge main_clk) 199 | begin 200 | // default assignments 201 | u32_rec_enable <= 1'd0; 202 | glitch_pulse_length <= glitch_pulse_length; 203 | glitch_delay_length <= glitch_delay_length; 204 | power_pulse_length <= power_pulse_length; 205 | power_pulse_enable <= 1'd0; 206 | glitch_power_cycle <= glitch_power_cycle; 207 | 208 | glitch_trigger_enable <= 1'd0; 209 | disable_trigger <= disable_trigger; 210 | 211 | state <= state; 212 | tx_enable <= 1'b0; 213 | 214 | case(state) 215 | STATE_WAIT_COMMAND: 216 | begin 217 | if(rx_valid) 218 | begin 219 | case(rx_data) 220 | CMD_SET_GLITCH_PULSE: 221 | begin 222 | state <= STATE_SET_GLITCH_PULSE; 223 | u32_rec_enable <= 1'd1; 224 | end 225 | CMD_SET_DELAY: 226 | begin 227 | state <= STATE_SET_DELAY; 228 | u32_rec_enable <= 1'd1; 229 | end 230 | CMD_SET_POWER_PULSE: 231 | begin 232 | state <= STATE_SET_POWER_PULSE; 233 | u32_rec_enable <= 1'd1; 234 | end 235 | CMD_READ_GPIO: 236 | begin 237 | tx_data <= gpio; 238 | tx_enable <= 1'b1; 239 | end 240 | CMD_ENABLE_GLITCH_POWER_CYCLE: 241 | begin 242 | state <= STATE_ENABLE_GLITCH_POWER_CYCLE; 243 | end 244 | CMD_GLITCH: 245 | begin 246 | // If glitch with power cycle is enabled we 247 | // use the power pulse to start the glitch 248 | // (which will then in turn start the trigger) 249 | if(glitch_power_cycle == 1'b1) 250 | begin 251 | power_pulse_enable <= 1'b1; 252 | end 253 | else 254 | // Otherwise we directly enable the trigger 255 | begin 256 | glitch_trigger_enable <= 1'b1; 257 | end 258 | end 259 | CMD_POWER_CYCLE: 260 | begin 261 | power_pulse_enable <= 1'b1; 262 | disable_trigger <= 1'b1; 263 | state <= STATE_WAIT_POWER_CYCLE; 264 | end 265 | CMD_GET_STATE: 266 | begin 267 | tx_data <= {power_pulse_state, glitch_trigger_state, glitch_delay_state, glitch_pulse_state}; 268 | tx_enable <= 1'b1; 269 | end 270 | 271 | endcase 272 | end 273 | 274 | end 275 | STATE_SET_GLITCH_PULSE: 276 | begin 277 | if(u32_rec_valid) 278 | begin 279 | glitch_pulse_length <= u32_rec_data; 280 | state <= STATE_WAIT_COMMAND; 281 | end 282 | end 283 | STATE_SET_DELAY: 284 | begin 285 | if(u32_rec_valid) 286 | begin 287 | glitch_delay_length <= u32_rec_data; 288 | state <= STATE_WAIT_COMMAND; 289 | end 290 | end 291 | STATE_SET_POWER_PULSE: 292 | begin 293 | if(u32_rec_valid) 294 | begin 295 | power_pulse_length <= u32_rec_data; 296 | state <= STATE_WAIT_COMMAND; 297 | end 298 | end 299 | STATE_ENABLE_GLITCH_POWER_CYCLE: 300 | begin 301 | if(rx_valid) 302 | begin 303 | glitch_power_cycle <= rx_data[0]; 304 | state <= STATE_WAIT_COMMAND; 305 | end 306 | end 307 | STATE_WAIT_POWER_CYCLE: 308 | begin 309 | if(power_pulse_done) 310 | begin 311 | disable_trigger <= 1'b0; 312 | state <= STATE_WAIT_COMMAND; 313 | end 314 | end 315 | endcase 316 | end 317 | 318 | 319 | endmodule 320 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/new/trigger.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module trigger( 4 | input clk, 5 | input reset, 6 | input enable, 7 | input in, 8 | input [31:0] trigger_length, 9 | output reg triggered = 1'd0, 10 | output reg [1:0] state = 2'd0 11 | ); 12 | 13 | parameter STATE_IDLE = 2'd0; 14 | parameter STATE_WAIT_LOW = 2'd1; 15 | parameter STATE_TRIGGERING = 2'd2; 16 | 17 | reg [31:0] counter; 18 | 19 | always @(posedge clk) 20 | begin 21 | triggered <= 1'd0; 22 | counter <= counter; 23 | state <= state; 24 | if(reset) 25 | begin 26 | counter <= 1'd0; 27 | state <= STATE_IDLE; 28 | end 29 | else 30 | begin 31 | case(state) 32 | STATE_IDLE: 33 | begin 34 | if(enable) 35 | begin 36 | state <= STATE_WAIT_LOW; 37 | end 38 | end 39 | STATE_WAIT_LOW: 40 | begin 41 | if(in == 1'b0) 42 | begin 43 | state <= STATE_TRIGGERING; 44 | end 45 | end 46 | STATE_TRIGGERING: 47 | begin 48 | if(in) 49 | begin 50 | counter <= counter + 1; 51 | if(counter == trigger_length) 52 | begin 53 | triggered <= 1'd1; 54 | state <= STATE_IDLE; 55 | end 56 | end 57 | else 58 | begin 59 | counter <= 0; 60 | end 61 | end 62 | endcase 63 | 64 | end 65 | end 66 | 67 | endmodule 68 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/new/uart_definitions.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | // Definitons for the UART clockings 4 | `define SYSTEM_CLOCK 100_000_000 5 | 6 | // 115200 8N1 7 | `define UART_FULL_ETU (`SYSTEM_CLOCK/115200) 8 | `define UART_HALF_ETU ((`SYSTEM_CLOCK/115200)/2) -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/new/uart_rx.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "uart_definitions.v" 3 | 4 | 5 | module uart_rx( 6 | // System clock 7 | input wire clk, 8 | // Data input 9 | output reg [7:0] data, 10 | // Resets the entire module 11 | input wire reset, 12 | 13 | // The data line 14 | input wire rx, 15 | 16 | // Indicates the module is ready to receive 17 | output reg valid 18 | ); 19 | 20 | // States 21 | parameter STATE_IDLE = 4'd0; 22 | parameter STATE_START_BIT = 4'd1; 23 | parameter STATE_DATA_BITS = 4'd2; 24 | parameter STATE_STOP_BIT = 4'd3; 25 | 26 | // Hold state in this 27 | reg [3:0] state = STATE_IDLE; 28 | 29 | // The bit we are sending currently 30 | reg [3:0] current_bit = 4'd0; 31 | 32 | // Counter for baudrate 33 | reg [31:0] etu_counter = 32'd0; 34 | 35 | wire etu_full; 36 | wire etu_half; 37 | 38 | assign etu_full = (etu_counter == `UART_FULL_ETU); 39 | assign etu_half = (etu_counter == `UART_HALF_ETU); 40 | 41 | always @(posedge clk) 42 | begin 43 | if(reset == 1'b1) 44 | begin 45 | state <= STATE_IDLE; 46 | current_bit <= 4'd0; 47 | data <= 8'd0; 48 | end 49 | else // not resetting 50 | begin 51 | // default assignments 52 | valid <= 1'd0; 53 | data <= data; 54 | current_bit <= current_bit; 55 | state <= state; 56 | 57 | etu_counter <= etu_counter + 1; 58 | 59 | case(state) 60 | STATE_IDLE: 61 | begin 62 | // Start condition detected 63 | if(rx == 1'd0) 64 | begin 65 | state <= STATE_START_BIT; 66 | etu_counter <= 32'd0; 67 | current_bit <= 4'd0; 68 | end 69 | end 70 | STATE_START_BIT: 71 | begin 72 | if(etu_half) 73 | begin 74 | state <= STATE_DATA_BITS; 75 | etu_counter <= 32'd0; 76 | current_bit <= 32'd0; 77 | end 78 | end 79 | STATE_DATA_BITS: 80 | begin 81 | if(etu_full) 82 | begin 83 | data <= {rx, data[7:1]}; 84 | current_bit <= current_bit + 1; 85 | etu_counter <= 32'd0; 86 | if(current_bit == 4'd7) 87 | begin 88 | state <= STATE_STOP_BIT; 89 | end 90 | end 91 | end 92 | STATE_STOP_BIT: 93 | begin 94 | if(etu_full) 95 | begin 96 | valid <= 1'b1; 97 | state <= STATE_IDLE; 98 | etu_counter <= 32'd0; 99 | end 100 | end 101 | endcase 102 | end 103 | end 104 | 105 | endmodule 106 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/new/uart_tx.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "uart_definitions.v" 3 | 4 | module uart_tx( 5 | // System clock 6 | input wire clk, 7 | // Data input 8 | input wire [7:0] data, 9 | // Enable, pull high for one cycle to start sending 10 | input wire enable, 11 | // Resets the entire module 12 | input wire reset, 13 | 14 | // The data line 15 | output reg tx, 16 | // Indicates the module is ready to receive 17 | output reg ready = 1'b1 18 | ); 19 | 20 | 21 | 22 | // States 23 | parameter STATE_IDLE = 4'd0; 24 | parameter STATE_START_BIT = 4'd1; 25 | parameter STATE_DATA_BITS = 4'd2; 26 | parameter STATE_STOP_BIT = 4'd3; 27 | parameter STATE_DONE = 4'd5; 28 | 29 | // Hold state in this 30 | reg [3:0] state = STATE_IDLE; 31 | 32 | // The bit we are sending currently 33 | reg [3:0] current_bit = 4'd0; 34 | 35 | // Counter for baudrate 36 | reg [31:0] etu_counter = 32'd0; 37 | 38 | wire etu_full; 39 | wire etu_half; 40 | 41 | assign etu_full = (etu_counter == `UART_FULL_ETU); 42 | assign etu_half = (etu_counter == `UART_HALF_ETU); 43 | 44 | reg [7:0] data_local; 45 | 46 | always @(posedge clk) 47 | begin 48 | if(reset == 1'b1) 49 | begin 50 | state <= STATE_IDLE; 51 | current_bit <= 8'd0; 52 | tx <= 1'b1; 53 | end 54 | else 55 | begin 56 | // Default assignments 57 | tx <= tx; 58 | ready <= ready; 59 | state <= state; 60 | current_bit <= current_bit; 61 | data_local <= data_local; 62 | 63 | // Always count up the ETU counter 64 | etu_counter <= etu_counter + 1'd1; 65 | 66 | case(state) 67 | STATE_IDLE: 68 | begin 69 | // Our state is idle, but we just got an enable signal. Start sending! 70 | if(enable) 71 | begin 72 | data_local <= data; 73 | state <= STATE_DATA_BITS; 74 | tx <= 1'b0; 75 | ready <= 1'b0; 76 | current_bit <= 4'd0; 77 | // Start etu_counter 78 | etu_counter <= 32'd0; 79 | end 80 | else 81 | begin 82 | tx <= 1'b1; 83 | ready <= 1'b1; 84 | end 85 | end 86 | STATE_START_BIT: 87 | begin 88 | state <= STATE_DATA_BITS; 89 | etu_counter <= 32'd0; 90 | end 91 | STATE_DATA_BITS: 92 | begin 93 | if(etu_full) 94 | begin 95 | etu_counter <= 32'd0; 96 | tx <= data_local[0]; 97 | data_local <= {data_local[0], data_local[7:1]}; 98 | current_bit <= current_bit + 1'd1; 99 | if(current_bit == 3'd7) 100 | begin 101 | state <= STATE_STOP_BIT; 102 | end 103 | end 104 | end 105 | STATE_STOP_BIT: 106 | begin 107 | if(etu_full) 108 | begin 109 | tx <= 1'd1; 110 | etu_counter <= 32'd0; 111 | state <= STATE_DONE; 112 | end 113 | end 114 | STATE_DONE: 115 | begin 116 | if(etu_full) 117 | begin 118 | ready <= 1'b1; 119 | state <= STATE_IDLE; 120 | end 121 | end 122 | endcase 123 | end 124 | 125 | end 126 | 127 | 128 | 129 | 130 | endmodule 131 | -------------------------------------------------------------------------------- /chipfail-glitcher.srcs/sources_1/new/uint32_receiver.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module uint32_receiver( 4 | input clk, 5 | input reset, 6 | input enable, 7 | 8 | // UART data 9 | input [7:0] uart_data, 10 | input uart_valid, 11 | 12 | // The data received 13 | output reg [31:0] data, 14 | // Whether the current output on data is valid 15 | output reg data_valid = 1'b0 16 | ); 17 | 18 | parameter STATE_IDLE = 4'd0; 19 | parameter STATE_RECEIVING = 4'd1; 20 | 21 | reg [3:0] state = STATE_IDLE; 22 | 23 | reg [3:0] received_bytes = 4'd0; 24 | 25 | always @(posedge clk) 26 | begin 27 | // default assignments 28 | received_bytes <= received_bytes; 29 | state <= state; 30 | data_valid <= 1'b0; 31 | data <= data; 32 | if(reset) 33 | begin 34 | received_bytes <= 4'd0; 35 | state <= STATE_IDLE; 36 | end 37 | else 38 | begin 39 | case(state) 40 | STATE_IDLE: 41 | begin 42 | if(enable) 43 | begin 44 | received_bytes <= 4'd0; 45 | data_valid <= 4'd0; 46 | state <= STATE_RECEIVING; 47 | end 48 | end 49 | STATE_RECEIVING: 50 | begin 51 | if(uart_valid) 52 | begin 53 | data <= {data[23:0], uart_data}; 54 | received_bytes <= received_bytes + 1; 55 | if(received_bytes == 3) 56 | begin 57 | state <= STATE_IDLE; 58 | data_valid <= 1'b1; 59 | end 60 | end 61 | end 62 | endcase 63 | end 64 | end 65 | 66 | endmodule 67 | -------------------------------------------------------------------------------- /chipfail-glitcher.xpr: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 156 | 157 | 158 | 159 | 160 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 175 | 176 | 177 | 178 | 179 | 182 | 183 | 185 | 186 | 188 | 189 | 191 | 192 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | default_dashboard 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | -------------------------------------------------------------------------------- /jupyter/chipfail-glitcher.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Welcome to the chip.fail glitcher\n", 8 | "\n", 9 | "This Jupyter Notebook shows the configuration options and how to use the chip.fail glitcher.\n", 10 | "\n", 11 | "We start by configuring the path to the serial device of the FPGA. Note that the Cmod A7 shows up as two serial ports, you can figure out which one is the right one by trial and error." 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "SERIAL_DEVICE = \"/dev/tty.usbserial-210328A9FDC51\"" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "Next we set up the different parameters for the glitch:\n", 28 | "\n", 29 | "#### POWER_CYCLE_BEFORE_GLITCH\n", 30 | "\n", 31 | "Whether the DUT should be power-cycled before the test. Some devices are very slow to start up (for example the ESP32), and as such it makes more sense to try to glitch and endless loop.\n", 32 | "\n", 33 | "#### POWER_CYCLE_PULSE\n", 34 | "\n", 35 | "The duration for which the power-cycle pulse should be send, in 100_000_000th of a second\n", 36 | "\n", 37 | "#### DELAY_FROM - DELAY_TO\n", 38 | "\n", 39 | "The delay range from the trigger to the glitch that should be tested, in 100_000_000th of a second\n", 40 | "\n", 41 | "#### PULSE_FROM - PULSE_TO\n", 42 | "\n", 43 | "The duration range for the glitch pulse, in 100_000_000th of a second." 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": null, 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [ 52 | "POWER_CYCLE_BEFORE_GLITCH = False\n", 53 | "POWER_CYCLE_PULSE = 3_000 \n", 54 | "DELAY_FROM = 100_000\n", 55 | "DELAY_TO = 150_000\n", 56 | "PULSE_FROM = 1\n", 57 | "PULSE_TO = 100" 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "metadata": {}, 63 | "source": [ 64 | "Next, we import our basic requirements." 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": null, 70 | "metadata": {}, 71 | "outputs": [], 72 | "source": [ 73 | "import serial\n", 74 | "import struct\n", 75 | "from tqdm import tnrange, tqdm_notebook\n", 76 | "import time" 77 | ] 78 | }, 79 | { 80 | "cell_type": "markdown", 81 | "metadata": {}, 82 | "source": [ 83 | "In this part we define the commands that are implemented on the FPGA and open the serial device. We also establish some helper functions for interacting with the FPGA." 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": null, 89 | "metadata": {}, 90 | "outputs": [], 91 | "source": [ 92 | "device = serial.Serial(SERIAL_DEVICE, baudrate=115200)\n", 93 | "\n", 94 | "CMD_TOGGLE_LED = 65\n", 95 | "CMD_POWER_CYCLE = 66\n", 96 | "CMD_SET_GLITCH_PULSE = 67 # uint32\n", 97 | "CMD_SET_DELAY = 68 # uint32\n", 98 | "CMD_SET_POWER_PULSE = 69 # uint32\n", 99 | "CMD_GLITCH = 70\n", 100 | "CMD_READ_GPIO = 71\n", 101 | "CMD_ENABLE_GLITCH_POWER_CYCLE = 72 # bool/byte\n", 102 | "CMD_GET_STATE = 73 # Get state of device\n", 103 | "\n", 104 | "def cmd_toggle_led(device):\n", 105 | " device.write(chr(CMD_TOGGLE_LED).encode(\"ASCII\"))\n", 106 | "\n", 107 | "def cmd(device, command):\n", 108 | " device.write(chr(command).encode(\"ASCII\"))\n", 109 | "\n", 110 | "def cmd_uint32(device, command, u32):\n", 111 | " device.write(chr(command).encode(\"ASCII\"))\n", 112 | " data = struct.pack(\">L\", u32)\n", 113 | " device.write(data)\n", 114 | "\n", 115 | "def cmd_uint8(device, command, u8):\n", 116 | " device.write(chr(command).encode(\"ASCII\"))\n", 117 | " data = struct.pack(\"B\", u8)\n", 118 | " device.write(data)\n", 119 | "\n", 120 | "def cmd_read_uint8(device, command):\n", 121 | " device.write(chr(command).encode(\"ASCII\"))\n", 122 | " return device.read(1)[0]\n", 123 | "\n", 124 | "def parse_status(status):\n", 125 | " power_pulse_status = (status >> 6) & 0b11\n", 126 | " trigger_status = (status >> 4) & 0b11\n", 127 | " delay_status = (status >> 2) & 0b11\n", 128 | " glitch_pulse_status = status & 0b11\n", 129 | " print(\"Power pulse : \" + str(power_pulse_status))\n", 130 | " print(\"Trigger status: \" + str(trigger_status))\n", 131 | " print(\"Delay status : \" + str(delay_status))\n", 132 | " print(\"Glitch pulse : \" + str(glitch_pulse_status))" 133 | ] 134 | }, 135 | { 136 | "cell_type": "markdown", 137 | "metadata": {}, 138 | "source": [ 139 | "Lets see what the current state of the glitching logic is. This is useful to verify that the device is working and to ensure it does not need to be reset:" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": null, 145 | "metadata": {}, 146 | "outputs": [], 147 | "source": [ 148 | "status = cmd_read_uint8(device, CMD_GET_STATE)\n", 149 | "parse_status(status)" 150 | ] 151 | }, 152 | { 153 | "cell_type": "markdown", 154 | "metadata": {}, 155 | "source": [ 156 | "Here is a simple demo setup of a glitch, with the power pulse, the delay, and the glitch pulse set to 1 second each. If this is run, LED1 should light up for a second, then a trigger (from low to high) is expected on pin 46, then a delay of 1 second is executed and then finally a 1 second glitch-pulse will be put out on port 48/LED2." 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": null, 162 | "metadata": {}, 163 | "outputs": [], 164 | "source": [ 165 | "cmd_uint32(device, CMD_SET_POWER_PULSE, 100_000_000)\n", 166 | "cmd_uint32(device, CMD_SET_DELAY, 100_000_000)\n", 167 | "cmd_uint32(device, CMD_SET_GLITCH_PULSE, 100_000_000)\n", 168 | "cmd_uint8(device, CMD_ENABLE_GLITCH_POWER_CYCLE, 1)\n", 169 | "\n", 170 | "cmd(device, CMD_GLITCH)\n", 171 | "print(\"Step one, power pulse:\")\n", 172 | "status = cmd_read_uint8(device, CMD_GET_STATE)\n", 173 | "parse_status(status)\n", 174 | "time.sleep(1.1)\n", 175 | "\n", 176 | "print(\"Step two, trigger\")\n", 177 | "status = cmd_read_uint8(device, CMD_GET_STATE)\n", 178 | "parse_status(status)\n", 179 | "print(\"\\tWaiting for pin to go low...\")\n", 180 | "while(status == 0b00010000):\n", 181 | " status = cmd_read_uint8(device, CMD_GET_STATE)\n", 182 | "print(\"\\tWaiting for pin to go high...\")\n", 183 | "while(status == 0b00100000):\n", 184 | " status = cmd_read_uint8(device, CMD_GET_STATE)\n", 185 | "\n", 186 | "print(\"Step three, delay:\")\n", 187 | "status = cmd_read_uint8(device, CMD_GET_STATE)\n", 188 | "parse_status(status)\n", 189 | "time.sleep(1.1)\n", 190 | "print(\"Step four, glitch pulse:\")\n", 191 | "status = cmd_read_uint8(device, CMD_GET_STATE)\n", 192 | "parse_status(status)\n", 193 | "while(status == 0b00000001):\n", 194 | " status = cmd_read_uint8(device, CMD_GET_STATE)\n", 195 | "print(\"Done, if you get here it means everything is working!\")" 196 | ] 197 | }, 198 | { 199 | "cell_type": "code", 200 | "execution_count": null, 201 | "metadata": {}, 202 | "outputs": [], 203 | "source": [ 204 | "success = False\n", 205 | "for delay in tnrange(DELAY_FROM, DELAY_TO):\n", 206 | " cmd_uint32(device, CMD_SET_DELAY, delay)\n", 207 | " if success:\n", 208 | " break\n", 209 | " for pulse in tnrange(PULSE_FROM, PULSE_TO, leave=False):\n", 210 | " cmd_uint32(device, CMD_SET_GLITCH_PULSE, pulse)\n", 211 | " cmd(device, CMD_GLITCH)\n", 212 | " # Loop until the status is == 0, aka the glitch is done.\n", 213 | " # This avoids having to manually time the glitch :)\n", 214 | " while(cmd_read_uint8(device, CMD_GET_STATE)):\n", 215 | " pass\n", 216 | " # Check whether the glitch was successful!\n", 217 | " gpios = cmd_read_uint8(device, CMD_READ_GPIO)\n", 218 | " if(gpios):\n", 219 | " print(\"*** SUCCESS ***\")\n", 220 | " print(\"Delay: \" + str(delay))\n", 221 | " print(\"Pulse: \" + str(pulse))\n", 222 | " success = True\n", 223 | " break\n", 224 | " " 225 | ] 226 | }, 227 | { 228 | "cell_type": "code", 229 | "execution_count": null, 230 | "metadata": {}, 231 | "outputs": [], 232 | "source": [ 233 | "# Show status of IOs\n", 234 | "print(format(cmd_read_uint8(device, CMD_READ_GPIO), '#010b'))" 235 | ] 236 | }, 237 | { 238 | "cell_type": "code", 239 | "execution_count": null, 240 | "metadata": {}, 241 | "outputs": [], 242 | "source": [] 243 | }, 244 | { 245 | "cell_type": "code", 246 | "execution_count": null, 247 | "metadata": {}, 248 | "outputs": [], 249 | "source": [] 250 | } 251 | ], 252 | "metadata": { 253 | "kernelspec": { 254 | "display_name": "Python 3", 255 | "language": "python", 256 | "name": "python3" 257 | }, 258 | "language_info": { 259 | "codemirror_mode": { 260 | "name": "ipython", 261 | "version": 3 262 | }, 263 | "file_extension": ".py", 264 | "mimetype": "text/x-python", 265 | "name": "python", 266 | "nbconvert_exporter": "python", 267 | "pygments_lexer": "ipython3", 268 | "version": "3.7.3" 269 | } 270 | }, 271 | "nbformat": 4, 272 | "nbformat_minor": 2 273 | } 274 | -------------------------------------------------------------------------------- /payloads/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | TOOLCHAIN=arm-none-eabi- 3 | set -e 4 | 5 | if [ "$1" == "" ]; then 6 | echo "Need 1 argument (asm file)" 7 | exit 8 | fi 9 | 10 | ${TOOLCHAIN}as ${1} -o ${1}.o 11 | ${TOOLCHAIN}ld -o ${1}.elf -T saml11.ld ${1}.o 12 | ${TOOLCHAIN}objcopy ${1}.elf ${1}.hex -O ihex 13 | # rm ${1}.o ${1}.elf 14 | echo "Generated ${1}.hex" -------------------------------------------------------------------------------- /payloads/samd21_glitch.asm: -------------------------------------------------------------------------------- 1 | .cpu cortex-m0 2 | .thumb 3 | .code 16 4 | .global _start 5 | _start: 6 | # We don't care about the stack 7 | stacktop: .word 0x20000200 8 | 9 | # Just a ridiculous amount of int vectors 10 | .word reset 11 | .word reset 12 | .word reset 13 | .word reset 14 | .word reset 15 | .word reset 16 | .word reset 17 | .word reset 18 | .word reset 19 | .word reset 20 | .word reset 21 | .word reset 22 | .word reset 23 | .word reset 24 | .word reset 25 | .word reset 26 | .word reset 27 | .word reset 28 | .word reset 29 | .word reset 30 | .word reset 31 | .word reset 32 | .word reset 33 | .word reset 34 | .word reset 35 | .word reset 36 | .word reset 37 | .word reset 38 | .word reset 39 | .word reset 40 | .word reset 41 | .word reset 42 | .word reset 43 | .word reset 44 | .word reset 45 | .word reset 46 | .word reset 47 | .word reset 48 | .word reset 49 | .word reset 50 | .word reset 51 | 52 | .align 4 53 | 54 | .thumb_func 55 | reset: 56 | # Set the ports we use as output 57 | # According to https://cdn-shop.adafruit.com/product-files/2772/atmel-42181-sam-d21_datasheet.pdf 58 | # PORT is mapped to 0x41004400 59 | LDR r0, =0x41004400 60 | 61 | 62 | # Page 387: DIRSET is at offset 0x8 63 | # We are setting as output: PA18, 19, 22, and 23 64 | # PA18 = tft lite 65 | # PA19 = tft d/c 66 | # PA22 = red led 67 | # PA23 = green led 68 | 69 | # hex(((1<<6)|(1<<17)|(1<<22)|(1<<23))) 70 | # '0xc20040' 71 | 72 | 73 | # Load offset 74 | MOV r1, #8 75 | 76 | # Store DIRSET 77 | LDR r2, =0xc20040 78 | STR r2, [r0, r1] 79 | 80 | # Enable RED led, disable green 81 | # Enable PA18, disable PA19 82 | 83 | # For disabled LED we need to pull it high. 84 | # The others we leave low 85 | 86 | # hex((1 << 18) | (1<<23)) 87 | # 0x840000 88 | 89 | # Load OUTSET offset 0x18 90 | MOV r1, #0x18 91 | LDR r2, =0x400040 92 | STR r2, [r0, r1] 93 | 94 | # Lets loop! 95 | MOV r5, #4 96 | Loop: 97 | # This is the loop we are glitching: 98 | 99 | # Load byte at address 0 100 | LDR r4, [r5] 101 | # Compare it with 0xb1, which should be the value 102 | CMP r4, #0xb1 103 | BEQ Loop 104 | 105 | 106 | # WE GLITCHED! Turn on the christmas tree 107 | 108 | # OUTCLR 0x14 109 | #MOV r1, #0x14 110 | # Enable LEDs 111 | #LDR r2, =0xCC0000 112 | #STR r2, [r0, r1] 113 | 114 | # OUTSET 0x18 115 | MOV r1, #0x18 116 | # Enable D/C IO 117 | LDR r2, =0x820000 118 | STR r2, [r0, r1] 119 | 120 | B . 121 | 122 | .end 123 | -------------------------------------------------------------------------------- /payloads/saml11_glitch.asm: -------------------------------------------------------------------------------- 1 | # cortex-m23 is mandatory. GNU will generate invalid nops ... 2 | .cpu cortex-m23 3 | .thumb 4 | .code 16 5 | .global _start 6 | _start: 7 | # We don't care about the stack 8 | stacktop: .word 0x20000200 9 | 10 | # Just a ridiculous amount of int vectors 11 | .word reset 12 | .word reset 13 | .word reset 14 | .word reset 15 | .word reset 16 | .word reset 17 | .word reset 18 | .word reset 19 | .word reset 20 | .word reset 21 | .word reset 22 | .word reset 23 | .word reset 24 | .word reset 25 | .word reset 26 | .word reset 27 | .word reset 28 | .word reset 29 | .word reset 30 | .word reset 31 | .word reset 32 | .word reset 33 | .word reset 34 | .word reset 35 | .word reset 36 | .word reset 37 | .word reset 38 | .word reset 39 | .word reset 40 | .word reset 41 | .word reset 42 | .word reset 43 | .word reset 44 | .word reset 45 | .word reset 46 | .word reset 47 | .word reset 48 | .word reset 49 | .word reset 50 | .word reset 51 | .word reset 52 | 53 | .align 4 54 | 55 | .thumb_func 56 | reset: 57 | 58 | # Set the ports we use as output 59 | # According to http://ww1.microchip.com/downloads/en/DeviceDoc/SAM%20L10_L11_%20Family_Datasheet_DS60001513D.pdf 60 | # PORT is mapped to 0x40003000 61 | LDR r0, =0x40003200 62 | 63 | 64 | # Page 631: DIRSET is at offset 0x8 65 | # We are setting as output: PA18, 19, 22, and 23 66 | # PA18 = tft lite 67 | # PA19 = tft d/c 68 | # PA22 = red led 69 | # PA23 = green led 70 | 71 | # hex((1 << 18) | (1 << 19) | (1 << 22) | (1 << 23)) 72 | # '0xcc0000' 73 | 74 | # Load offset 75 | MOV r1, #8 76 | 77 | # Store DIRSET 78 | LDR r2, =0xcc0000 79 | STR r2, [r0, r1] 80 | 81 | # Enable RED led, disable green 82 | # Enable PA18, disable PA19 83 | 84 | # For disabled LED we need to pull it high. 85 | # The others we leave low 86 | 87 | # hex((1 << 18) | (1<<23)) 88 | # 0x840000 89 | 90 | # Load OUTSET offset 0x18 91 | MOV r1, #0x18 92 | LDR r2, =0x840000 93 | STR r2, [r0, r1] 94 | 95 | # Lets loop! 96 | MOV r5, #4 97 | Loop: 98 | # This is the loop we are glitching: 99 | 100 | # Load byte at address 0 101 | LDR r4, [r5] 102 | # Compare it with 0xb1, which should be the value 103 | CMP r4, #0xb1 104 | BEQ Loop 105 | 106 | 107 | # WE GLITCHED! Turn on the christmas tree 108 | 109 | # OUTCLR 0x14 110 | MOV r1, #0x14 111 | # Enable LEDs 112 | LDR r2, =0xCC0000 113 | STR r2, [r0, r1] 114 | 115 | # OUTSET 0x18 116 | MOV r1, #0x18 117 | # Enable D/C IO 118 | LDR r2, =0x80000 119 | STR r2, [r0, r1] 120 | 121 | B . 122 | 123 | .end 124 | --------------------------------------------------------------------------------