Просмотр исходного кода

Добавлен модуль-обертка для mmcm, добавлен модуль-приёмник данных от dsp, добавлен модуль синхронизации сигналов initRst в другие клоковые домены. Добавлены модули из референсного дизайна использования drp для динамической переконфигурации mmcm. Изменения в названиях сигналов в соответствии с соглашением о написании кода.

Stepan Churbanov 2 лет назад
Родитель
Сommit
523e805f66

+ 4 - 4
SRAM/QuadSPIm.v

@@ -31,10 +31,10 @@ reg startFlag;
 reg [2:0] ssCnt;
 reg Ss;
 reg SSr;
-reg [7:0] mosiReg0;
-reg [7:0] mosiReg1;
-reg [7:0] mosiReg2;
-reg [7:0] mosiReg3;
+reg [6:0] mosiReg0;
+reg [6:0] mosiReg1;
+reg [6:0] mosiReg2;
+reg [6:0] mosiReg3;
 reg [3:0] ssNum;
 reg [2:0] delayCnt;
 reg stopFlag;

+ 3 - 3
SRAM/RegMap.v

@@ -10,7 +10,7 @@ module RegMap #(
     input Rst_i,
     input wrEn_i,
     input rdEn_i,  
-    input [1:0] BE_i,        
+    input [1:0] SmcBe_i,        
 
 
     output   [CmdRegWidth/2-1:0] Spi0CtrlReg_o,
@@ -374,7 +374,7 @@ always @(posedge Clk_i) begin
     end
     else begin 
         if (!wrEn_i) begin 
-            case (BE_i)  
+            case (SmcBe_i)  
                 0 : begin 
                     case (Addr_i) 
                         Spi0CtrlAddr : begin 
@@ -929,7 +929,7 @@ always @(*) begin
     end
     else begin 
         if (!rdEn_i) begin 
-            case(BE_i) 
+            case(SmcBe_i) 
                 0 : begin 
                     case (Addr_i)
                         Spi0CtrlAddr : begin 

+ 67 - 81
constrs_1/new/S5443_3.xdc

@@ -1,82 +1,82 @@
 
 
 
-set_property PACKAGE_PIN C15 [get_ports {Addr_i[0]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Addr_i[0]}]
-set_property PACKAGE_PIN C13 [get_ports {Addr_i[1]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Addr_i[1]}]
-set_property PACKAGE_PIN D15 [get_ports {Addr_i[2]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Addr_i[2]}]
-set_property PACKAGE_PIN C14 [get_ports {Addr_i[3]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Addr_i[3]}]
-set_property PACKAGE_PIN E15 [get_ports {Addr_i[4]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Addr_i[4]}]
-set_property PACKAGE_PIN D13 [get_ports {Addr_i[5]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Addr_i[5]}]
-set_property PACKAGE_PIN F15 [get_ports {Addr_i[6]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Addr_i[6]}]
-set_property PACKAGE_PIN E14 [get_ports {Addr_i[7]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Addr_i[7]}]
-set_property PACKAGE_PIN J15 [get_ports {Addr_i[8]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Addr_i[8]}]
-set_property PACKAGE_PIN F14 [get_ports {Addr_i[9]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Addr_i[9]}]
-set_property PACKAGE_PIN K15 [get_ports {Addr_i[10]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Addr_i[10]}]
-
-
-
-set_property PACKAGE_PIN B15 [get_ports {Data_i[0]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Data_i[0]}]
-set_property PACKAGE_PIN B14 [get_ports {Data_i[1]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Data_i[1]}]
-set_property PACKAGE_PIN B11 [get_ports {Data_i[2]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Data_i[2]}]
-set_property PACKAGE_PIN B12 [get_ports {Data_i[3]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Data_i[3]}]
-set_property PACKAGE_PIN A12 [get_ports {Data_i[4]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Data_i[4]}]
-set_property PACKAGE_PIN B9 [get_ports {Data_i[5]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Data_i[5]}]
-set_property PACKAGE_PIN K14 [get_ports {Data_i[6]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Data_i[6]}]
-set_property PACKAGE_PIN A11 [get_ports {Data_i[7]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Data_i[7]}]
-set_property PACKAGE_PIN A6 [get_ports {Data_i[8]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Data_i[8]}]
-set_property PACKAGE_PIN A13 [get_ports {Data_i[9]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Data_i[9]}]
-set_property PACKAGE_PIN A10 [get_ports {Data_i[10]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Data_i[10]}]
-set_property PACKAGE_PIN B6 [get_ports {Data_i[11]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Data_i[11]}]
-set_property PACKAGE_PIN A5 [get_ports {Data_i[12]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Data_i[12]}]
-set_property PACKAGE_PIN B10 [get_ports {Data_i[13]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Data_i[13]}]
-set_property PACKAGE_PIN A8 [get_ports {Data_i[14]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Data_i[14]}]
-set_property PACKAGE_PIN A14 [get_ports {Data_i[15]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {Data_i[15]}]
+set_property PACKAGE_PIN C15 [get_ports {SmcAddr_i[0]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcAddr_i[0]}]
+set_property PACKAGE_PIN C13 [get_ports {SmcAddr_i[1]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcAddr_i[1]}]
+set_property PACKAGE_PIN D15 [get_ports {SmcAddr_i[2]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcAddr_i[2]}]
+set_property PACKAGE_PIN C14 [get_ports {SmcAddr_i[3]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcAddr_i[3]}]
+set_property PACKAGE_PIN E15 [get_ports {SmcAddr_i[4]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcAddr_i[4]}]
+set_property PACKAGE_PIN D13 [get_ports {SmcAddr_i[5]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcAddr_i[5]}]
+set_property PACKAGE_PIN F15 [get_ports {SmcAddr_i[6]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcAddr_i[6]}]
+set_property PACKAGE_PIN E14 [get_ports {SmcAddr_i[7]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcAddr_i[7]}]
+set_property PACKAGE_PIN J15 [get_ports {SmcAddr_i[8]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcAddr_i[8]}]
+set_property PACKAGE_PIN F14 [get_ports {SmcAddr_i[9]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcAddr_i[9]}]
+set_property PACKAGE_PIN K15 [get_ports {SmcAddr_i[10]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcAddr_i[10]}]
+
+
+
+set_property PACKAGE_PIN B15 [get_ports {SmcData_i[0]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcData_i[0]}]
+set_property PACKAGE_PIN B14 [get_ports {SmcData_i[1]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcData_i[1]}]
+set_property PACKAGE_PIN B11 [get_ports {SmcData_i[2]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcData_i[2]}]
+set_property PACKAGE_PIN B12 [get_ports {SmcData_i[3]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcData_i[3]}]
+set_property PACKAGE_PIN A12 [get_ports {SmcData_i[4]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcData_i[4]}]
+set_property PACKAGE_PIN B9 [get_ports {SmcData_i[5]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcData_i[5]}]
+set_property PACKAGE_PIN K14 [get_ports {SmcData_i[6]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcData_i[6]}]
+set_property PACKAGE_PIN A11 [get_ports {SmcData_i[7]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcData_i[7]}]
+set_property PACKAGE_PIN A6 [get_ports {SmcData_i[8]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcData_i[8]}]
+set_property PACKAGE_PIN A13 [get_ports {SmcData_i[9]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcData_i[9]}]
+set_property PACKAGE_PIN A10 [get_ports {SmcData_i[10]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcData_i[10]}]
+set_property PACKAGE_PIN B6 [get_ports {SmcData_i[11]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcData_i[11]}]
+set_property PACKAGE_PIN A5 [get_ports {SmcData_i[12]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcData_i[12]}]
+set_property PACKAGE_PIN B10 [get_ports {SmcData_i[13]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcData_i[13]}]
+set_property PACKAGE_PIN A8 [get_ports {SmcData_i[14]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcData_i[14]}]
+set_property PACKAGE_PIN A14 [get_ports {SmcData_i[15]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcData_i[15]}]
 
 
 
 set_property PACKAGE_PIN C6 [get_ports Led_o]
 set_property IOSTANDARD LVCMOS33 [get_ports Led_o]
 
-set_property PACKAGE_PIN A9 [get_ports writeEn_i]
-set_property IOSTANDARD LVCMOS33 [get_ports writeEn_i]
+set_property PACKAGE_PIN A9 [get_ports SmcAwe_i]
+set_property IOSTANDARD LVCMOS33 [get_ports SmcAwe_i]
 
-set_property PACKAGE_PIN C5 [get_ports readEn_i]
-set_property IOSTANDARD LVCMOS33 [get_ports readEn_i]
+set_property PACKAGE_PIN C5 [get_ports SmcAre_i]
+set_property IOSTANDARD LVCMOS33 [get_ports SmcAre_i]
 
-set_property PACKAGE_PIN C8 [get_ports outputEn_i]
-set_property IOSTANDARD LVCMOS33 [get_ports outputEn_i]
+set_property PACKAGE_PIN C8 [get_ports SmcAoe_i]
+set_property IOSTANDARD LVCMOS33 [get_ports SmcAoe_i]
 
-set_property PACKAGE_PIN L15 [get_ports {BE_i[1]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {BE_i[1]}]
-set_property PACKAGE_PIN L14 [get_ports {BE_i[0]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {BE_i[0]}]
+set_property PACKAGE_PIN L15 [get_ports {SmcBe_i[1]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcBe_i[1]}]
+set_property PACKAGE_PIN L14 [get_ports {SmcBe_i[0]}]
+set_property IOSTANDARD LVCMOS33 [get_ports {SmcBe_i[0]}]
 
 
 #==========================================================================
@@ -87,8 +87,6 @@ set_property PACKAGE_PIN K1 [get_ports {Sck_o[0]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Sck_o[0]}]
 set_property PACKAGE_PIN H1 [get_ports {Ss_o[0]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Ss_o[0]}]
-set_property PACKAGE_PIN K2 [get_ports {SsFlash_o[0]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {SsFlash_o[0]}]
 set_property PACKAGE_PIN J1 [get_ports {Mosi0_o[0]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Mosi0_o[0]}]
 set_property PACKAGE_PIN J3 [get_ports {Mosi1_o[0]}]
@@ -109,8 +107,6 @@ set_property PACKAGE_PIN N2 [get_ports {Sck_o[1]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Sck_o[1]}]
 set_property PACKAGE_PIN N4 [get_ports {Ss_o[1]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Ss_o[1]}]
-set_property PACKAGE_PIN P1 [get_ports {SsFlash_o[1]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {SsFlash_o[1]}]
 set_property PACKAGE_PIN N3 [get_ports {Mosi0_o[1]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Mosi0_o[1]}]
 set_property PACKAGE_PIN R2 [get_ports {Mosi1_o[1]}]
@@ -131,8 +127,6 @@ set_property PACKAGE_PIN E2 [get_ports {Sck_o[2]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Sck_o[2]}]
 set_property PACKAGE_PIN E1 [get_ports {Ss_o[2]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Ss_o[2]}]
-set_property PACKAGE_PIN F1 [get_ports {SsFlash_o[2]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {SsFlash_o[2]}]
 set_property PACKAGE_PIN D1 [get_ports {Mosi0_o[2]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Mosi0_o[2]}]
 set_property PACKAGE_PIN D2 [get_ports {Mosi1_o[2]}]
@@ -152,8 +146,6 @@ set_property PACKAGE_PIN R10 [get_ports {Sck_o[3]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Sck_o[3]}]
 set_property PACKAGE_PIN P10 [get_ports {Ss_o[3]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Ss_o[3]}]
-set_property PACKAGE_PIN N10 [get_ports {SsFlash_o[3]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {SsFlash_o[3]}]
 set_property PACKAGE_PIN N8 [get_ports {Mosi0_o[3]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Mosi0_o[3]}]
 set_property PACKAGE_PIN R8 [get_ports {Mosi1_o[3]}]
@@ -175,8 +167,6 @@ set_property PACKAGE_PIN R14 [get_ports {Sck_o[4]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Sck_o[4]}]
 set_property PACKAGE_PIN N14 [get_ports {Ss_o[4]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Ss_o[4]}]
-set_property PACKAGE_PIN P14 [get_ports {SsFlash_o[4]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {SsFlash_o[4]}]
 set_property PACKAGE_PIN R13 [get_ports {Mosi0_o[4]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Mosi0_o[4]}]
 set_property PACKAGE_PIN P12 [get_ports {Mosi1_o[4]}]
@@ -197,8 +187,6 @@ set_property PACKAGE_PIN P6 [get_ports {Sck_o[5]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Sck_o[5]}]
 set_property PACKAGE_PIN R5 [get_ports {Ss_o[5]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Ss_o[5]}]
-set_property PACKAGE_PIN R6 [get_ports {SsFlash_o[5]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {SsFlash_o[5]}]
 set_property PACKAGE_PIN R4 [get_ports {Mosi0_o[5]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Mosi0_o[5]}]
 set_property PACKAGE_PIN R3 [get_ports {Mosi1_o[5]}]
@@ -218,8 +206,6 @@ set_property PACKAGE_PIN B5 [get_ports {Sck_o[6]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Sck_o[6]}]
 set_property PACKAGE_PIN B3 [get_ports {Ss_o[6]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Ss_o[6]}]
-set_property PACKAGE_PIN A4 [get_ports {SsFlash_o[6]}]
-set_property IOSTANDARD LVCMOS33 [get_ports {SsFlash_o[6]}]
 set_property PACKAGE_PIN B1 [get_ports {Mosi0_o[6]}]
 set_property IOSTANDARD LVCMOS33 [get_ports {Mosi0_o[6]}]
 set_property PACKAGE_PIN C4 [get_ports {Mosi1_o[6]}]

+ 3 - 3
sources_1/new/DataFifo/DataFifoWrapper.v

@@ -10,7 +10,7 @@ module DataFifoWrapper
     input	WrClk_i,
 	input	RdClk_i,
     input	Rst_i,
-	input   readEn_i,
+	input   SmcAre_i,
 
 	input	ToFifoVal_i,
 	input	[CmdRegWidth-1:0]	ToFifoData_i,
@@ -39,8 +39,8 @@ DataFifo	DataFifo
 	.wr_clk		(WrClk_i), 
 	.rd_clk		(RdClk_i), 
 	.din		(ToFifoData_i), 
-	.wr_en		(!fullFlag && ToFifoVal_i), 
-	.rd_en		(!readEn_i && !emptyFlag), 
+	.wr_en		(ToFifoVal_i), 
+	.rd_en		(!SmcAre_i), 
 	.dout		(ToSpiData_o), 
 	.full		(fullFlag), 
 	.empty		(emptyFlag)

+ 133 - 0
sources_1/new/DspSmc/SmcRx.v

@@ -0,0 +1,133 @@
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+// Company: 
+// Engineer: 
+// 
+// Create Date: 10.10.2018 01:07:38
+// Design Name: 
+// Module Name: sram_ctrl2
+// Project Name: 
+// Target Devices: 
+// Tool Versions: 
+// Description: 
+// 
+// Dependencies: 
+// 
+// Revision:
+// Revision 0.01 - File Created
+// Additional Comments:
+// 
+//////////////////////////////////////////////////////////////////////////////////
+
+
+module	SmcRx
+#(
+	parameter	DataOutWidth	=	32,
+	parameter	DataInWidth		=	16,
+	parameter	AddrWidth		=	25
+)
+(
+	input	Clk_i,                       
+	input	RstN_i,                     
+	input	ForceRstN_i,                     
+
+	input	[DataInWidth-1:0]	SmcD_i,
+	input	[AddrWidth-1:0]	SmcA_i,
+	input	SmcAwe_i,
+	input	SmcAmsN_i,
+	input	SmcAoe_i,
+	input	SmcAre_i,	
+	input	[1:0]	SmcBe_i,	
+	
+	output	[DataOutWidth-1:0]	Data_o,
+	output	[AddrWidth-1:0]	Addr_o,
+	output	Val_o
+);
+
+//================================================================================
+//  REG/WIRE
+	
+	reg	[AddrWidth-1:0]	smcAddr;
+	reg	[DataInWidth-1:0]	smcData;
+	reg	val;
+	reg	valReg;
+	
+	reg	smcAwe;
+	reg	smcAweR;
+	reg	smcAweRR;
+	
+	reg	smcAmsN;
+	reg	smcAmsNR;
+	
+	wire	smcAweNeg	=	(!smcAweRR&smcAweR);
+	
+	
+	reg	[DataOutWidth-1:0]	dataOutReg;
+	reg	[AddrWidth-1:0]		addrDataReg;
+
+//================================================================================
+//  LOCALPARAM
+
+//================================================================================
+//  ASSIGNMENTS	
+	assign	Data_o	=	dataOutReg;
+	assign	Addr_o	=	addrDataReg;
+	assign	Val_o	=	valReg;
+	
+	
+//================================================================================
+//  CODING
+	
+always	@(posedge	Clk_i)	begin
+	if	(RstN_i&ForceRstN_i)	begin
+		smcAmsN		<=	SmcAmsN_i;
+		smcAmsNR	<=	smcAmsN;
+		
+		smcAwe		<=	SmcAwe_i;
+		smcAweR		<=	smcAwe;
+		smcAweRR	<=	smcAweR;
+	end	else	begin
+		smcAmsN		<=	0;
+		smcAmsNR	<=	0;
+		
+		smcAwe		<=	0;
+		smcAweR		<=	0;
+		smcAweRR	<=	0;
+	end
+end
+	
+always	@(posedge	Clk_i)	begin
+	if	(RstN_i&ForceRstN_i)	begin
+		if	(!smcAmsNR)	begin
+			if	(smcAweNeg)	begin
+				smcData	<=	SmcD_i;
+				smcAddr	<=	SmcA_i;
+				val		<=	1;
+			end	else	begin
+				val		<=	0;
+			end
+		end
+	end	else	begin
+		smcData	<=	0;
+		smcAddr	<=	0;
+		val		<=	0;
+	end
+end
+
+always	@(posedge	Clk_i)	begin
+	if	(RstN_i&ForceRstN_i)	begin
+		if	(val)	begin
+			addrDataReg	<=	smcAddr;
+			dataOutReg	<=	{dataOutReg[DataInWidth-1:0],smcData};
+			valReg	<=	val;
+		end	else	begin
+			valReg	<=	1'b0;
+		end
+	end	else	begin
+		dataOutReg	<=	0;
+		addrDataReg	<=	0;
+		valReg	<=	1'b0;
+	end
+end
+
+endmodule

+ 134 - 0
sources_1/new/MMCM/MmcmWrapper.v

@@ -0,0 +1,134 @@
+
+module MmcmWrapper 
+#(
+	parameter	SpiNum	=	7
+)
+(
+    input	Clk_i,
+    input	Rst_i,
+
+	output	[SpiNum-1:0]	SpiCLk_o
+);
+//================================================================================
+//	REG/WIRE
+//================================================================================
+	
+wire            clkfb_bufgout;
+wire            clkfb_bufgin;
+wire            clk0_bufgin;
+wire            clk0_bufgout;
+wire            clk1_bufgin;
+wire            clk1_bufgout;
+wire            clk2_bufgin;
+wire            clk2_bufgout;
+wire            clk3_bufgin;
+wire            clk3_bufgout;
+wire            clk4_bufgin;
+wire            clk4_bufgout;
+wire            clk5_bufgin;
+wire            clk5_bufgout;
+wire            clk6_bufgin;
+wire            clk6_bufgout;
+
+//================================================================================
+//	ASSIGNMENTS
+//================================================================================
+	
+//================================================================================
+//	LOCALPARAMS
+//================================================================================
+
+//================================================================================
+//	CODING
+//================================================================================
+
+MMCME2_ADV 
+#(
+   .BANDWIDTH           ("OPTIMIZED"),
+   .DIVCLK_DIVIDE       (1),
+   .CLKFBOUT_MULT_F     (10),
+   .CLKFBOUT_PHASE      (0.0),
+   .CLKFBOUT_USE_FINE_PS("FALSE"),
+   // .CLKIN1_PERIOD       (10.000),
+   .CLKIN1_PERIOD       (8.130081300813),
+   .CLKIN2_PERIOD       (10.000),
+   .CLKOUT0_DIVIDE_F    (12.3),
+   .CLKOUT0_DUTY_CYCLE  (0.5),
+   .CLKOUT0_PHASE       (0.0),
+   .CLKOUT0_USE_FINE_PS ("FALSE"),
+   .CLKOUT1_DIVIDE      (6),
+   .CLKOUT1_DUTY_CYCLE  (0.5),
+   .CLKOUT1_PHASE       (0.0),
+   .CLKOUT1_USE_FINE_PS ("FALSE"),
+   .CLKOUT2_DIVIDE      (6),
+   .CLKOUT2_DUTY_CYCLE  (0.5),
+   .CLKOUT2_PHASE       (0.0),
+   .CLKOUT2_USE_FINE_PS ("FALSE"),
+   .CLKOUT3_DIVIDE      (6),
+   .CLKOUT3_DUTY_CYCLE  (0.5),
+   .CLKOUT3_PHASE       (0.0),
+   .CLKOUT3_USE_FINE_PS ("FALSE"),
+   .CLKOUT4_DIVIDE      (6),
+   .CLKOUT4_DUTY_CYCLE  (0.5),
+   .CLKOUT4_PHASE       (0.0),
+   .CLKOUT4_USE_FINE_PS ("FALSE"),
+   .CLKOUT4_CASCADE     ("FALSE"),
+   .CLKOUT5_DIVIDE      (6),
+   .CLKOUT5_DUTY_CYCLE  (0.5),
+   .CLKOUT5_PHASE       (0.0),
+   .CLKOUT5_USE_FINE_PS ("FALSE"),
+   .CLKOUT6_DIVIDE      (6),
+   .CLKOUT6_DUTY_CYCLE  (0.5),
+   .CLKOUT6_PHASE       (0.0),
+   .CLKOUT6_USE_FINE_PS ("FALSE"),
+   .COMPENSATION        ("ZHOLD"),
+   .STARTUP_WAIT        ("FALSE")
+) 
+mmcme2_test_inst 
+(
+   .CLKFBOUT            (clkfb_bufgin),
+   .CLKFBOUTB           (),
+   .CLKFBSTOPPED        (),
+   .CLKINSTOPPED        (),
+   .CLKOUT0             (clk0_bufgin),
+   .CLKOUT0B            (),
+   .CLKOUT1             (clk1_bufgin),
+   .CLKOUT1B            (),
+   .CLKOUT2             (clk2_bufgin),
+   .CLKOUT2B            (),
+   .CLKOUT3             (clk3_bufgin),
+   .CLKOUT3B            (),
+   .CLKOUT4             (clk4_bufgin),
+   .CLKOUT5             (clk5_bufgin),
+   .CLKOUT6             (clk6_bufgin),
+   .DO                  (dout),
+   .DRDY                (drdy),
+   .DADDR               (daddr),
+   .DCLK                (dclk),
+   .DEN                 (den),
+   .DI                  (di),
+   .DWE                 (dwe),
+   .LOCKED              (LOCKED),
+   .CLKFBIN             (clkfb_bufgout),
+   .CLKIN1              (Clk_i),
+   .CLKIN2              (),
+   .CLKINSEL            (1'b1),
+   .PSDONE              (),
+   .PSCLK               (1'b0),
+   .PSEN                (1'b0),
+   .PSINCDEC            (1'b0),
+   .PWRDWN              (1'b0),
+   .RST                 (Rst_i)
+);
+
+BUFG BUFG_FB    (.O (clkfb_bufgout),    .I (clkfb_bufgin));
+BUFG BUFG_CLK0  (.O (SpiCLk_o[0]),     .I (clk0_bufgin));
+BUFG BUFG_CLK1  (.O (SpiCLk_o[1]),     .I (clk1_bufgin));
+BUFG BUFG_CLK2  (.O (SpiCLk_o[2]),     .I (clk2_bufgin));
+BUFG BUFG_CLK3  (.O (SpiCLk_o[3]),     .I (clk3_bufgin));
+BUFG BUFG_CLK4  (.O (SpiCLk_o[4]),     .I (clk4_bufgin));
+BUFG BUFG_CLK5  (.O (SpiCLk_o[5]),     .I (clk5_bufgin));
+BUFG BUFG_CLK6  (.O (SpiCLk_o[6]),     .I (clk6_bufgin));
+
+
+endmodule

+ 849 - 0
sources_1/new/MMCM/mmcme2_drp.v

@@ -0,0 +1,849 @@
+//-------------------------------------------------------------------------------------------
+//   ____  ____
+//  /   /\/   /
+// /___/  \  /
+// \   \   \/    � Copyright 2019 Xilinx, Inc. All rights reserved.
+//  \   \        This file contains confidential and proprietary information of Xilinx, Inc.
+//  /   /        and is protected under U.S. and international copyright and other
+// /___/   /\    intellectual property laws.
+// \   \  /  \
+//  \___\/\___\
+//
+//-------------------------------------------------------------------------------------------
+// Device:              7_Series
+// Author:              Tatsukawa, Kruger, Ribbing, Defossez
+// Entity Name:         mmcme2_drp
+// Purpose:             This calls the DRP register calculation functions and
+//                      provides a state machine to perform MMCM reconfiguration
+//                      based on the calculated values stored in a initialized
+//                      ROM.
+//                      7-Series MMCM is called:            MMCME2
+//                          Ultrascale MMCM is called:      MMCME3
+//                          UltrascalePlus MMCM is called:  MMCME4
+//                      MMCME3 attributes
+//                          CLKINx_PERIOD:      0.968 to 100.000 (x = 1 or 2)
+//                          REF_JITTERx:        0.001 to 0.999 (x = 1 or 2)
+//                          BANDWIDTH:          LOW, HIGH, OPTIMIZED and POSTCRC
+//                          COMPENSATION:       AUTO, ZHOLD, EXTERNAL, INTERNAL and BUF_IN
+//                          DIVCLK_DIVIDE:      1 to 106
+//                          CLKFBOUT_MULT_F:    2 to 64
+//                          CLKFBOUT_PHASE:     -360 to 360
+//                          CLKOUTn_DIVIDE:     1 to 128 (n = 0 to 6)
+//                          CLKOUTn_PHASE:      -360 to 360 (n = 0 to 6)
+//                          CLKOUTn_DUTY_CYCLE: 0.01 to 0.99 (n = 0 to 6)
+//
+// Tools:               Vivado_2019.1 or newer
+// Limitations:         None
+//
+// Vendor:              Xilinx Inc.
+// Version:             1.40
+// Filename:            mmcme3_drp.v
+// Date Created:        22-Oct-2014
+// Date Last Modified:  25-Jun-2019
+//-------------------------------------------------------------------------------------------
+// Disclaimer:
+//        This disclaimer is not a license and does not grant any rights to the materials
+//        distributed herewith. Except as otherwise provided in a valid license issued to you
+//        by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE MATERIALS
+//        ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL
+//        WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED
+//        TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR
+//        PURPOSE; and (2) Xilinx shall not be liable (whether in contract or tort, including
+//        negligence, or under any other theory of liability) for any loss or damage of any
+//        kind or nature related to, arising under or in connection with these materials,
+//        including for any direct, or any indirect, special, incidental, or consequential
+//        loss or damage (including loss of data, profits, goodwill, or any type of loss or
+//        damage suffered as a result of any action brought by a third party) even if such
+//        damage or loss was reasonably foreseeable or Xilinx had been advised of the
+//        possibility of the same.
+//
+// CRITICAL APPLICATIONS
+//        Xilinx products are not designed or intended to be fail-safe, or for use in any
+//        application requiring fail-safe performance, such as life-support or safety devices
+//        or systems, Class III medical devices, nuclear facilities, applications related to
+//        the deployment of airbags, or any other applications that could lead to death,
+//        personal injury, or severe property or environmental damage (individually and
+//        collectively, "Critical Applications"). Customer assumes the sole risk and
+//        liability of any use of Xilinx products in Critical Applications, subject only to
+//        applicable laws and regulations governing limitations on product liability.
+//
+// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
+//
+// Contact:    e-mail  hotline@xilinx.com        phone   + 1 800 255 7778
+//-------------------------------------------------------------------------------------------
+// Revision History:
+//  Rev: 13-Jan-2011 - Tatsukawa
+//      Updated ROM[18,41] LOCKED bitmask to 16'HFC00
+//  Rev: 30-May-2013 - Tatsukawa
+//      Adding Fractional support for CLKFBOUT_MULT_F, CLKOUT0_DIVIDE_F
+//  Rev: 30-Apr-2014 - Tatsukawa
+//      For fractional multiply changed order to enable fractional
+//      before the multiply is applied to prevent false VCO DRCs
+//      (e.g. DADDR 7'h15 must be set before updating 7'h14)
+//  Rev: 24-Oct-2014 - Ribbing
+//      Parameters have been added to clarify Reg1/Reg2/Shared registers
+//  Rev: 08-Jun-2015 - Kruger
+//      WAIT_LOCK update
+//  Rev: 02-May-2016 - Kruger
+//      Reordering FRAC_EN bits DADDR(7'h09, 7'h15)
+//      Registers before frac settings (7'h08, 7'h14)
+//  Rev: 19-Sep-2018 - Defossez
+//      Updated comments of BANDWIDTH.
+//      Corrected some typos.
+//  Rev: 25-Jun-2019 - Defossez
+//      Adding registering possibility for LOCKE signal.
+//-------------------------------------------------------------------------------------------
+//
+`timescale 1ps/1ps
+//
+module mmcme2_drp
+    #(
+        // Register the LOCKED signal with teh MMCME3_ADV input clock.
+        // The LOCKED_IN (LOCKED from the MMCME3_ADV) is fed into a register and then
+        // passed the LOCKED_OUT when REGISTER_LOCKED is set to "Reg" or when set to
+        // "NoReg" LOCKED_IN is just passed on to LOCKED_OUT without being registered.
+        parameter REGISTER_LOCKED       = "Reg",
+        // Use the registered LOCKED signal from the MMCME3 also for the DRP state machine.
+        parameter USE_REG_LOCKED        = "No",
+        // Possible/allowed combinations of above two parameters:
+        // | REGISTER_LOCKED | USE_REG_LOCKED |                                            |
+        // |-----------------|----------------|--------------------------------------------|
+        // |      "NoReg"    |     "No"       | LOCKED is just passed through mmcme3_drp   |
+        // |                 |                | and is used as is with the state machine   |
+        // |      "NoReg"    |     "Yes"      | NOT ALLOWED                                |
+        // |       "Reg"     |     "No"       | LOCKED is registered but the unregistered  |
+        // |                 |                | version is used for the state machine.     |
+        // |       "Reg"     |     "Yes"      | LOCKED is registered and the registered    |
+        // |                 |                | version is also used by the state machine. |
+        //
+        //***********************************************************************
+        // State 1 Parameters - These are for the first reconfiguration state.
+        //***********************************************************************
+        //
+        // These parameters have an effect on the feedback path. A change on
+        // these parameters will effect all of the clock outputs.
+        //
+        // The parameters are composed of:
+        //    _MULT: This can be from 2 to 64. It has an effect on the VCO
+        //          frequency which consequently, effects all of the clock
+        //          outputs.
+        //    _PHASE: This is the phase multiplied by 1000. For example if
+        //          a phase of 24.567 deg was desired the input value would be
+        //          24567. The range for the phase is from -360000 to 360000.
+        //    _FRAC: This can be from 0 to 875. This represents the fractional
+        //          divide multiplied by 1000.
+        //          M = _MULT + _FRAC / 1000
+        //          e.g. M=8.125
+        //               _MULT = 8
+        //               _FRAC = 125
+        //    _FRAC_EN: This indicates fractional divide has been enabled. If 1
+        //          then the fractional divide algorithm will be used to calculate
+        //          register settings. If 0 then default calculation to be used.
+        parameter S1_CLKFBOUT_MULT          = 5,
+        parameter S1_CLKFBOUT_PHASE         = 0,
+        parameter S1_CLKFBOUT_FRAC          = 125,
+        parameter S1_CLKFBOUT_FRAC_EN       = 1,
+        //
+        // The bandwidth parameter effects the phase error and the jitter filter
+        // capability of the MMCM. For more information on this parameter see the
+        // Device user guide.
+        // Possible values are: "LOW", "LOW_SS", "HIGH" and "OPTIMIZED"
+        parameter S1_BANDWIDTH              = "LOW",
+        //
+        // The divclk parameter allows the input clock to be divided before it
+        // reaches the phase and frequency comparator. This can be set between
+        // 1 and 128.
+        parameter S1_DIVCLK_DIVIDE          = 1,
+
+        // The following parameters describe the configuration that each clock
+        // output should have once the reconfiguration for state one has
+        // completed.
+        //
+        // The parameters are composed of:
+        //    _DIVIDE: This can be from 1 to 128
+        //    _PHASE: This is the phase multiplied by 1000. For example if
+        //          a phase of 24.567 deg was desired the input value would be
+        //          24567. The range for the phase is from -360000 to 360000.
+        //    _DUTY: This is the duty cycle multiplied by 100,000.  For example if
+        //          a duty cycle of .24567 was desired the input would be
+        //          24567.
+        //
+        parameter S1_CLKOUT0_DIVIDE         = 1,
+        parameter S1_CLKOUT0_PHASE          = 0,
+        parameter S1_CLKOUT0_DUTY           = 50000,
+        parameter S1_CLKOUT0_FRAC          = 125,
+        parameter S1_CLKOUT0_FRAC_EN       = 1,
+        //
+        parameter S1_CLKOUT1_DIVIDE         = 1,
+        parameter S1_CLKOUT1_PHASE          = 0,
+        parameter S1_CLKOUT1_DUTY           = 50000,
+        //
+        parameter S1_CLKOUT2_DIVIDE         = 1,
+        parameter S1_CLKOUT2_PHASE          = 0,
+        parameter S1_CLKOUT2_DUTY           = 50000,
+        //
+        parameter S1_CLKOUT3_DIVIDE         = 1,
+        parameter S1_CLKOUT3_PHASE          = 0,
+        parameter S1_CLKOUT3_DUTY           = 50000,
+        //
+        parameter S1_CLKOUT4_DIVIDE         = 1,
+        parameter S1_CLKOUT4_PHASE          = 0,
+        parameter S1_CLKOUT4_DUTY           = 50000,
+        //
+        parameter S1_CLKOUT5_DIVIDE         = 1,
+        parameter S1_CLKOUT5_PHASE          = 0,
+        parameter S1_CLKOUT5_DUTY           = 50000,
+        //
+        parameter S1_CLKOUT6_DIVIDE         = 1,
+        parameter S1_CLKOUT6_PHASE          = 0,
+        parameter S1_CLKOUT6_DUTY           = 50000,
+        //
+        //***********************************************************************
+        // State 2 Parameters - These are for the second reconfiguration state.
+        //***********************************************************************
+        //
+        // These parameters have an effect on the feedback path. A change on
+        // these parameters will effect all of the clock outputs.
+        //
+        // The parameters are composed of:
+        //    _MULT: This can be from 2 to 64. It has an effect on the VCO
+        //          frequency which consequently, effects all of the clock
+        //          outputs.
+        //    _PHASE: This is the phase multiplied by 1000. For example if
+        //          a phase of 24.567 deg was desired the input value would be
+        //          24567.  The range for the phase is from -360000 to 360000.
+        //    _FRAC: This can be from 0 to 875. This represents the fractional
+        //          divide multiplied by 1000.
+        //          M = _MULT + _FRAC / 1000
+        //          e.g. M=8.125
+        //               _MULT = 8
+        //               _FRAC = 125
+        //    _FRAC_EN: This indicates fractional divide has been enabled. If 1
+        //          then the fractional divide algorithm will be used to calculate
+        //          register settings. If 0 then default calculation to be used.
+        parameter S2_CLKFBOUT_MULT          = 1,
+        parameter S2_CLKFBOUT_PHASE         = 0,
+        parameter S2_CLKFBOUT_FRAC          = 125,
+        parameter S2_CLKFBOUT_FRAC_EN       = 1,
+        //
+        // The bandwidth parameter effects the phase error and the jitter filter
+        // capability of the MMCM. For more information on this parameter see the
+        // Device user guide.
+        // Possible values are: "LOW", "LOW_SS", "HIGH" and "OPTIMIZED"
+        parameter S2_BANDWIDTH              = "LOW",
+        //
+        // The divclk parameter allows the input clock to be divided before it
+        // reaches the phase and frequency comparator. This can be set between
+        // 1 and 128.
+        parameter S2_DIVCLK_DIVIDE          = 1,
+        //
+        // The following parameters describe the configuration that each clock
+        // output should have once the reconfiguration for state one has
+        // completed.
+        //
+        // The parameters are composed of:
+        //    _DIVIDE: This can be from 1 to 128
+        //    _PHASE: This is the phase multiplied by 1000. For example if
+        //          a phase of 24.567 deg was desired the input value would be
+        //          24567. The range for the phase is from -360000 to 360000
+        //    _DUTY: This is the duty cycle multiplied by 100,000. For example if
+        //          a duty cycle of .24567 was desired the input would be
+        //          24567.
+        //
+        parameter S2_CLKOUT0_DIVIDE         = 1,
+        parameter S2_CLKOUT0_PHASE          = 0,
+        parameter S2_CLKOUT0_DUTY           = 50000,
+        parameter S2_CLKOUT0_FRAC          = 125,
+        parameter S2_CLKOUT0_FRAC_EN       = 1,
+        //
+        parameter S2_CLKOUT1_DIVIDE         = 2,
+        parameter S2_CLKOUT1_PHASE          = 0,
+        parameter S2_CLKOUT1_DUTY           = 50000,
+        //
+        parameter S2_CLKOUT2_DIVIDE         = 3,
+        parameter S2_CLKOUT2_PHASE          = 0,
+        parameter S2_CLKOUT2_DUTY           = 50000,
+        //
+        parameter S2_CLKOUT3_DIVIDE         = 4,
+        parameter S2_CLKOUT3_PHASE          = 0,
+        parameter S2_CLKOUT3_DUTY           = 50000,
+        //
+        parameter S2_CLKOUT4_DIVIDE         = 5,
+        parameter S2_CLKOUT4_PHASE          = 0,
+        parameter S2_CLKOUT4_DUTY           = 50000,
+        //
+        parameter S2_CLKOUT5_DIVIDE         = 5,
+        parameter S2_CLKOUT5_PHASE          = 0,
+        parameter S2_CLKOUT5_DUTY           = 50000,
+        //
+        parameter S2_CLKOUT6_DIVIDE         = 5,
+        parameter S2_CLKOUT6_PHASE          = -90,
+        parameter S2_CLKOUT6_DUTY           = 50000
+    ) (
+        // These signals are controlled by user logic interface and are covered
+        // in more detail within the XAPP.
+        input             SADDR,
+        input             SEN,
+        input             SCLK,
+        input             RST,
+        output reg        SRDY,
+        //
+        // These signals are to be connected to the MMCM_ADV by port name.
+        // Their use matches the MMCM port description in the Device User Guide.
+        input      [15:0] DO,
+        input             DRDY,
+        input             LOCK_REG_CLK_IN,
+        input             LOCKED_IN,
+        output reg        DWE,
+        output reg        DEN,
+        output reg [6:0]  DADDR,
+        output reg [15:0] DI,
+        output            DCLK,
+        output reg        RST_MMCM,
+        output            LOCKED_OUT
+    );
+//----------------------------------------------------------------------------------------
+    //
+    wire        IntLocked;
+    wire        IntRstMmcm;
+    //
+    // 100 ps delay for behavioral simulations
+    localparam  TCQ = 100;
+
+    // Make sure the memory is implemented as distributed
+    (* rom_style = "distributed" *)
+    //
+    // ROM of:  39 bit word 64 words deep
+    reg [38:0]  rom [63:0];
+    reg [5:0]   rom_addr;
+    reg [38:0]  rom_do;
+    reg         next_srdy;
+    reg [5:0]   next_rom_addr;
+    reg [6:0]   next_daddr;
+    reg         next_dwe;
+    reg         next_den;
+    reg         next_rst_mmcm;
+    reg [15:0]  next_di;
+    //
+    // Insert a register in LOCKED or not depending on the value given to the parameters
+    // REGISTER_LOCKED. When REGISTER_LOCKED is set to "Reg" insert a register, when set
+    // to "NoReg" don't insert a register but just pass the LOCKED signal from input to
+    // output.
+    // Use or not, under USE_REG_LOCKED parameter control, the registered version of the
+    // LOCKED signal for the DRP state machine.
+    // Possible/allowed combinations of the two LOCKED related parameters:
+    //
+    // | REGISTER_LOCKED | USE_REG_LOCKED |                                            |
+    // |-----------------|----------------|--------------------------------------------|
+    // |      "NoReg"    |     "No"       | LOCKED is just passed through mmcme3_drp   |
+    // |                 |                | and is used as is with the state machine   |
+    // |      "NoReg"    |     "Yes"      | NOT ALLOWED                                |
+    // |       "Reg"     |     "No"       | LOCKED is registered but the unregistered  |
+    // |                 |                | version is used for the state machine.     |
+    // |       "Reg"     |     "Yes"      | LOCKED is registered and the registered    |
+    // |                 |                | version is also used by the state machine. |
+    //
+    generate
+        if (REGISTER_LOCKED == "NoReg" && USE_REG_LOCKED == "No") begin
+            assign LOCKED_OUT = LOCKED_IN;
+            assign IntLocked = LOCKED_IN;
+        end else if (REGISTER_LOCKED == "Reg" && USE_REG_LOCKED == "No") begin
+            FDRE #(
+                .INIT           (0),
+                .IS_C_INVERTED  (0),
+                .IS_D_INVERTED  (0),
+                .IS_R_INVERTED  (0)
+            ) mmcme3_drp_I_Fdrp (
+                .D      (LOCKED_IN),
+                .CE     (1'b1),
+                .R      (IntRstMmcm),
+                .C      (LOCK_REG_CLK_IN),
+                .Q      (LOCKED_OUT)
+            );
+            //
+            assign IntLocked = LOCKED_IN;
+        end else if (REGISTER_LOCKED == "Reg" && USE_REG_LOCKED == "Yes") begin
+            FDRE #(
+                .INIT           (0),
+                .IS_C_INVERTED  (0),
+                .IS_D_INVERTED  (0),
+                .IS_R_INVERTED  (0)
+            ) mmcme3_drp_I_Fdrp (
+                .D  (LOCKED_IN),
+                .CE (1'b1),
+                .R  (IntRstMmcm),
+                .C  (LOCK_REG_CLK_IN),
+                .Q  (LOCKED_OUT)
+            );
+            //
+            assign IntLocked = LOCKED_OUT;
+        end
+    endgenerate
+
+    // Integer used to initialize remainder of unused ROM
+    integer     ii;
+
+    // Pass SCLK to DCLK for the MMCM
+    assign DCLK = SCLK;
+     assign IntRstMmcm = RST_MMCM;
+
+    // Include the MMCM reconfiguration functions.  This contains the constant
+    // functions that are used in the calculations below.  This file is
+    // required.
+    `include "mmcme2_drp_func.h"
+
+    //**************************************************************************
+    // State 1 Calculations
+    //**************************************************************************
+    // Please see header for information.
+    localparam [37:0] S1_CLKFBOUT       =
+       mmcm_count_calc(S1_CLKFBOUT_MULT, S1_CLKFBOUT_PHASE, 50000);
+
+    localparam [37:0] S1_CLKFBOUT_FRAC_CALC       =
+       mmcm_frac_count_calc(S1_CLKFBOUT_MULT, S1_CLKFBOUT_PHASE, 50000, S1_CLKFBOUT_FRAC);
+
+    localparam [9:0]  S1_DIGITAL_FILT   =
+       mmcm_filter_lookup(S1_CLKFBOUT_MULT, S1_BANDWIDTH);
+
+    localparam [39:0] S1_LOCK           =
+       mmcm_lock_lookup(S1_CLKFBOUT_MULT);
+
+    localparam [37:0] S1_DIVCLK         =
+       mmcm_count_calc(S1_DIVCLK_DIVIDE, 0, 50000);
+
+    localparam [37:0] S1_CLKOUT0        =
+       mmcm_count_calc(S1_CLKOUT0_DIVIDE, S1_CLKOUT0_PHASE, S1_CLKOUT0_DUTY);
+       localparam [15:0] S1_CLKOUT0_REG1        = S1_CLKOUT0[15:0]; //See log file for 16 bit reporting of the register
+       localparam [15:0] S1_CLKOUT0_REG2        = S1_CLKOUT0[31:16]; //See log file for 16 bit reporting of the register
+
+    localparam [37:0] S1_CLKOUT0_FRAC_CALC        =
+       mmcm_frac_count_calc(S1_CLKOUT0_DIVIDE, S1_CLKOUT0_PHASE, 50000, S1_CLKOUT0_FRAC);
+        localparam [15:0] S1_CLKOUT0_FRAC_REG1        = S1_CLKOUT0_FRAC_CALC[15:0];  //See log file for 16 bit reporting of the register
+        localparam [15:0] S1_CLKOUT0_FRAC_REG2        = S1_CLKOUT0_FRAC_CALC[31:16];  //See log file for 16 bit reporting of the register
+        localparam [5:0] S1_CLKOUT0_FRAC_REGSHARED        = S1_CLKOUT0_FRAC_CALC[37:32];  //See log file for 16 bit reporting of the register
+
+    localparam [37:0] S1_CLKOUT1        =
+       mmcm_count_calc(S1_CLKOUT1_DIVIDE, S1_CLKOUT1_PHASE, S1_CLKOUT1_DUTY);
+        localparam [15:0] S1_CLKOUT1_REG1        = S1_CLKOUT1[15:0];  //See log file for 16 bit reporting of the register
+        localparam [15:0] S1_CLKOUT1_REG2        = S1_CLKOUT1[31:16];  //See log file for 16 bit reporting of the register
+
+    localparam [37:0] S1_CLKOUT2        =
+       mmcm_count_calc(S1_CLKOUT2_DIVIDE, S1_CLKOUT2_PHASE, S1_CLKOUT2_DUTY);
+       localparam [15:0] S1_CLKOUT2_REG1        = S1_CLKOUT2[15:0];  //See log file for 16 bit reporting of the register
+       localparam [15:0] S1_CLKOUT2_REG2        = S1_CLKOUT2[31:16];  //See log file for 16 bit reporting of the register
+
+    localparam [37:0] S1_CLKOUT3        =
+       mmcm_count_calc(S1_CLKOUT3_DIVIDE, S1_CLKOUT3_PHASE, S1_CLKOUT3_DUTY);
+       localparam [15:0] S1_CLKOUT3_REG1        = S1_CLKOUT3[15:0];  //See log file for 16 bit reporting of the register
+       localparam [15:0] S1_CLKOUT3_REG2        = S1_CLKOUT3[31:16];  //See log file for 16 bit reporting of the register
+
+    localparam [37:0] S1_CLKOUT4        =
+       mmcm_count_calc(S1_CLKOUT4_DIVIDE, S1_CLKOUT4_PHASE, S1_CLKOUT4_DUTY);
+       localparam [15:0] S1_CLKOUT4_REG1        = S1_CLKOUT4[15:0];  //See log file for 16 bit reporting of the register
+       localparam [15:0] S1_CLKOUT4_REG2        = S1_CLKOUT4[31:16];  //See log file for 16 bit reporting of the register
+
+    localparam [37:0] S1_CLKOUT5        =
+       mmcm_count_calc(S1_CLKOUT5_DIVIDE, S1_CLKOUT5_PHASE, S1_CLKOUT5_DUTY);
+       localparam [15:0] S1_CLKOUT5_REG1        = S1_CLKOUT5[15:0];  //See log file for 16 bit reporting of the register
+       localparam [15:0] S1_CLKOUT5_REG2        = S1_CLKOUT5[31:16];  //See log file for 16 bit reporting of the register
+
+    localparam [37:0] S1_CLKOUT6        =
+       mmcm_count_calc(S1_CLKOUT6_DIVIDE, S1_CLKOUT6_PHASE, S1_CLKOUT6_DUTY);
+       localparam [15:0] S1_CLKOUT6_REG1        = S1_CLKOUT6[15:0];  //See log file for 16 bit reporting of the register
+       localparam [15:0] S1_CLKOUT6_REG2        = S1_CLKOUT6[31:16]; //See log file for 16 bit reporting of the register
+
+    //**************************************************************************
+    // State 2 Calculations
+    //**************************************************************************
+    localparam [37:0] S2_CLKFBOUT       =
+       mmcm_count_calc(S2_CLKFBOUT_MULT, S2_CLKFBOUT_PHASE, 50000);
+
+    localparam [37:0] S2_CLKFBOUT_FRAC_CALC       =
+       mmcm_frac_count_calc(S2_CLKFBOUT_MULT, S2_CLKFBOUT_PHASE, 50000, S2_CLKFBOUT_FRAC);
+
+    localparam [9:0] S2_DIGITAL_FILT    =
+       mmcm_filter_lookup(S2_CLKFBOUT_MULT, S2_BANDWIDTH);
+
+    localparam [39:0] S2_LOCK           =
+       mmcm_lock_lookup(S2_CLKFBOUT_MULT);
+
+    localparam [37:0] S2_DIVCLK         =
+       mmcm_count_calc(S2_DIVCLK_DIVIDE, 0, 50000);
+
+    localparam [37:0] S2_CLKOUT0        =
+       mmcm_count_calc(S2_CLKOUT0_DIVIDE, S2_CLKOUT0_PHASE, S2_CLKOUT0_DUTY);
+       localparam [15:0] S2_CLKOUT0_REG1        = S2_CLKOUT0[15:0];  //See log file for 16 bit reporting of the register
+       localparam [15:0] S2_CLKOUT0_REG2        = S2_CLKOUT0[31:16]; //See log file for 16 bit reporting of the register
+
+    localparam [37:0] S2_CLKOUT0_FRAC_CALC        =
+       mmcm_frac_count_calc(S2_CLKOUT0_DIVIDE, S2_CLKOUT0_PHASE, 50000, S2_CLKOUT0_FRAC);
+       localparam [15:0] S2_CLKOUT0_FRAC_CALC_REG1        = S2_CLKOUT0_FRAC_CALC[15:0];  //See log file for 16 bit reporting of the register
+       localparam [15:0] S2_CLKOUT0_FRAC_CALC_REG2        = S2_CLKOUT0_FRAC_CALC[31:16]; //See log file for 16 bit reporting of the register
+       localparam [15:0] S2_CLKOUT0_FRAC_CALC_REGSHARED        = S2_CLKOUT0_FRAC_CALC[31:16]; //See log file for 16 bit reporting of the register
+
+    localparam [37:0] S2_CLKOUT1        =
+       mmcm_count_calc(S2_CLKOUT1_DIVIDE, S2_CLKOUT1_PHASE, S2_CLKOUT1_DUTY);
+       localparam [15:0] S2_CLKOUT1_REG1        = S2_CLKOUT1[15:0];  //See log file for 16 bit reporting of the register
+       localparam [15:0] S2_CLKOUT1_REG2        = S2_CLKOUT1[31:16]; //See log file for 16 bit reporting of the register
+
+    localparam [37:0] S2_CLKOUT2        =
+       mmcm_count_calc(S2_CLKOUT2_DIVIDE, S2_CLKOUT2_PHASE, S2_CLKOUT2_DUTY);
+       localparam [15:0] S2_CLKOUT2_REG1        = S2_CLKOUT2[15:0];  //See log file for 16 bit reporting of the register
+       localparam [15:0] S2_CLKOUT2_REG2        = S2_CLKOUT2[31:16]; //See log file for 16 bit reporting of the register
+
+    localparam [37:0] S2_CLKOUT3        =
+       mmcm_count_calc(S2_CLKOUT3_DIVIDE, S2_CLKOUT3_PHASE, S2_CLKOUT3_DUTY);
+       localparam [15:0] S2_CLKOUT3_REG1        = S2_CLKOUT3[15:0];  //See log file for 16 bit reporting of the register
+       localparam [15:0] S2_CLKOUT3_REG2        = S2_CLKOUT3[31:16]; //See log file for 16 bit reporting of the register
+
+    localparam [37:0] S2_CLKOUT4        =
+       mmcm_count_calc(S2_CLKOUT4_DIVIDE, S2_CLKOUT4_PHASE, S2_CLKOUT4_DUTY);
+       localparam [15:0] S2_CLKOUT4_REG1        = S2_CLKOUT4[15:0];  //See log file for 16 bit reporting of the register
+       localparam [15:0] S2_CLKOUT4_REG2        = S2_CLKOUT4[31:16]; //See log file for 16 bit reporting of the register
+
+    localparam [37:0] S2_CLKOUT5        =
+       mmcm_count_calc(S2_CLKOUT5_DIVIDE, S2_CLKOUT5_PHASE, S2_CLKOUT5_DUTY);
+       localparam [15:0] S2_CLKOUT5_REG1        = S2_CLKOUT5[15:0];  //See log file for 16 bit reporting of the register
+       localparam [15:0] S2_CLKOUT5_REG2        = S2_CLKOUT5[31:16]; //See log file for 16 bit reporting of the register
+
+    localparam [37:0] S2_CLKOUT6        =
+       mmcm_count_calc(S2_CLKOUT6_DIVIDE, S2_CLKOUT6_PHASE, S2_CLKOUT6_DUTY);
+       localparam [15:0] S2_CLKOUT6_REG1        = S2_CLKOUT6[15:0];  //See log file for 16 bit reporting of the register
+       localparam [15:0] S2_CLKOUT6_REG2        = S2_CLKOUT6[31:16]; //See log file for 16 bit reporting of the register
+
+    initial begin
+       // rom entries contain (in order) the address, a bitmask, and a bitset
+       //***********************************************************************
+       // State 1 Initialization
+       //***********************************************************************
+
+       // Store the power bits
+       rom[0] = {7'h28, 16'h0000, 16'hFFFF};
+
+       // Store CLKOUT0 divide and phase
+       rom[1]  = (S1_CLKOUT0_FRAC_EN == 0) ?
+                         {7'h09, 16'h8000, S1_CLKOUT0[31:16]}:
+                         {7'h09, 16'h8000, S1_CLKOUT0_FRAC_CALC[31:16]};
+       rom[2]  = (S1_CLKOUT0_FRAC_EN == 0) ?
+                         {7'h08, 16'h1000, S1_CLKOUT0[15:0]}:
+                         {7'h08, 16'h1000, S1_CLKOUT0_FRAC_CALC[15:0]};
+
+       // Store CLKOUT1 divide and phase
+       rom[3]  = {7'h0A, 16'h1000, S1_CLKOUT1[15:0]};
+       rom[4]  = {7'h0B, 16'hFC00, S1_CLKOUT1[31:16]};
+
+       // Store CLKOUT2 divide and phase
+       rom[5]  = {7'h0C, 16'h1000, S1_CLKOUT2[15:0]};
+       rom[6]  = {7'h0D, 16'hFC00, S1_CLKOUT2[31:16]};
+
+       // Store CLKOUT3 divide and phase
+       rom[7]  = {7'h0E, 16'h1000, S1_CLKOUT3[15:0]};
+       rom[8]  = {7'h0F, 16'hFC00, S1_CLKOUT3[31:16]};
+
+       // Store CLKOUT4 divide and phase
+       rom[9]  = {7'h10, 16'h1000, S1_CLKOUT4[15:0]};
+       rom[10]  = {7'h11, 16'hFC00, S1_CLKOUT4[31:16]};
+
+       // Store CLKOUT5 divide and phase
+       rom[11] = {7'h06, 16'h1000, S1_CLKOUT5[15:0]};
+       rom[12] = (S1_CLKOUT0_FRAC_EN == 0) ?
+                 {7'h07, 16'hC000, S1_CLKOUT5[31:16]}:
+                 {7'h07, 16'hC000, S1_CLKOUT5[31:30], S1_CLKOUT0_FRAC_CALC[35:32],S1_CLKOUT5[25:16]};
+
+       // Store CLKOUT6 divide and phase
+       rom[13] = {7'h12, 16'h1000, S1_CLKOUT6[15:0]};
+       rom[14] = (S1_CLKFBOUT_FRAC_EN == 0) ?
+                 {7'h13, 16'hC000, S1_CLKOUT6[31:16]}:
+                 {7'h13, 16'hC000, S1_CLKOUT6[31:30], S1_CLKFBOUT_FRAC_CALC[35:32],S1_CLKOUT6[25:16]};
+
+       // Store the input divider
+       rom[15] = {7'h16, 16'hC000, {2'h0, S1_DIVCLK[23:22], S1_DIVCLK[11:0]} };
+
+       // Store the feedback divide and phase
+       rom[16] = (S1_CLKFBOUT_FRAC_EN == 0) ?
+                 {7'h14, 16'h1000, S1_CLKFBOUT[15:0]}:
+                 {7'h14, 16'h1000, S1_CLKFBOUT_FRAC_CALC[15:0]};
+       rom[17] = (S1_CLKFBOUT_FRAC_EN == 0) ?
+                 {7'h15, 16'h8000, S1_CLKFBOUT[31:16]}:
+                 {7'h15, 16'h8000, S1_CLKFBOUT_FRAC_CALC[31:16]};
+
+       // Store the lock settings
+       rom[18] = {7'h18, 16'hFC00, {6'h00, S1_LOCK[29:20]} };
+       rom[19] = {7'h19, 16'h8000, {1'b0 , S1_LOCK[34:30], S1_LOCK[9:0]} };
+       rom[20] = {7'h1A, 16'h8000, {1'b0 , S1_LOCK[39:35], S1_LOCK[19:10]} };
+
+       // Store the filter settings
+       rom[21] = {7'h4E, 16'h66FF,
+                 S1_DIGITAL_FILT[9], 2'h0, S1_DIGITAL_FILT[8:7], 2'h0,
+                 S1_DIGITAL_FILT[6], 8'h00 };
+       rom[22] = {7'h4F, 16'h666F,
+                 S1_DIGITAL_FILT[5], 2'h0, S1_DIGITAL_FILT[4:3], 2'h0,
+                 S1_DIGITAL_FILT[2:1], 2'h0, S1_DIGITAL_FILT[0], 4'h0 };
+
+       //***********************************************************************
+       // State 2 Initialization
+       //***********************************************************************
+
+       // Store the power bits
+       rom[23] = {7'h28, 16'h0000, 16'hFFFF};
+
+       // Store CLKOUT0 divide and phase
+       rom[24] = (S2_CLKOUT0_FRAC_EN == 0) ?
+                 {7'h09, 16'h8000, S2_CLKOUT0[31:16]}:
+                 {7'h09, 16'h8000, S2_CLKOUT0_FRAC_CALC[31:16]};
+       rom[25] = (S2_CLKOUT0_FRAC_EN == 0) ?
+                 {7'h08, 16'h1000, S2_CLKOUT0[15:0]}:
+                 {7'h08, 16'h1000, S2_CLKOUT0_FRAC_CALC[15:0]};
+
+       // Store CLKOUT1 divide and phase
+       rom[26] = {7'h0A, 16'h1000, S2_CLKOUT1[15:0]};
+       rom[27] = {7'h0B, 16'hFC00, S2_CLKOUT1[31:16]};
+
+       // Store CLKOUT2 divide and phase
+       rom[28] = {7'h0C, 16'h1000, S2_CLKOUT2[15:0]};
+       rom[29] = {7'h0D, 16'hFC00, S2_CLKOUT2[31:16]};
+
+       // Store CLKOUT3 divide and phase
+       rom[30] = {7'h0E, 16'h1000, S2_CLKOUT3[15:0]};
+       rom[31] = {7'h0F, 16'hFC00, S2_CLKOUT3[31:16]};
+
+       // Store CLKOUT4 divide and phase
+       rom[32] = {7'h10, 16'h1000, S2_CLKOUT4[15:0]};
+       rom[33] = {7'h11, 16'hFC00, S2_CLKOUT4[31:16]};
+
+       // Store CLKOUT5 divide and phase
+       rom[34] = {7'h06, 16'h1000, S2_CLKOUT5[15:0]};
+       rom[35] = (S2_CLKOUT0_FRAC_EN == 0) ?
+                 {7'h07, 16'hC000, S2_CLKOUT5[31:16]}:
+                 {7'h07, 16'hC000, S2_CLKOUT5[31:30], S2_CLKOUT0_FRAC_CALC[35:32],S2_CLKOUT5[25:16]};
+
+       // Store CLKOUT6 divide and phase
+       rom[36] = {7'h12, 16'h1000, S2_CLKOUT6[15:0]};
+       rom[37] = (S2_CLKFBOUT_FRAC_EN == 0) ?
+                 {7'h13, 16'hC000, S2_CLKOUT6[31:16]}:
+                 {7'h13, 16'hC000, S2_CLKOUT6[31:30], S2_CLKFBOUT_FRAC_CALC[35:32],S2_CLKOUT6[25:16]};
+
+       // Store the input divider
+       rom[38] = {7'h16, 16'hC000, {2'h0, S2_DIVCLK[23:22], S2_DIVCLK[11:0]} };
+
+       // Store the feedback divide and phase
+       rom[39] = (S2_CLKFBOUT_FRAC_EN == 0) ?
+                 {7'h14, 16'h1000, S2_CLKFBOUT[15:0]}:
+                 {7'h14, 16'h1000, S2_CLKFBOUT_FRAC_CALC[15:0]};
+       rom[40] = (S2_CLKFBOUT_FRAC_EN == 0) ?
+                 {7'h15, 16'h8000, S2_CLKFBOUT[31:16]}:
+                 {7'h15, 16'h8000, S2_CLKFBOUT_FRAC_CALC[31:16]};
+
+       // Store the lock settings
+       rom[41] = {7'h18, 16'hFC00, {6'h00, S2_LOCK[29:20]} };
+       rom[42] = {7'h19, 16'h8000, {1'b0 , S2_LOCK[34:30], S2_LOCK[9:0]} };
+       rom[43] = {7'h1A, 16'h8000, {1'b0 , S2_LOCK[39:35], S2_LOCK[19:10]} };
+
+       // Store the filter settings
+       rom[44] = {7'h4E, 16'h66FF,
+                 S2_DIGITAL_FILT[9], 2'h0, S2_DIGITAL_FILT[8:7], 2'h0,
+                 S2_DIGITAL_FILT[6], 8'h00 };
+       rom[45] = {7'h4F, 16'h666F,
+                 S2_DIGITAL_FILT[5], 2'h0, S2_DIGITAL_FILT[4:3], 2'h0,
+                 S2_DIGITAL_FILT[2:1], 2'h0, S2_DIGITAL_FILT[0], 4'h0 };
+
+       // Initialize the rest of the ROM
+       rom[46] = {7'h28,32'h0000_0000};
+       for(ii = 47; ii < 64; ii = ii +1) begin
+          rom[ii] = 0;
+       end
+    end
+
+    // Output the initialized rom value based on rom_addr each clock cycle
+    always @(posedge SCLK) begin
+       rom_do<= #TCQ rom[rom_addr];
+    end
+
+    //**************************************************************************
+    // Everything below is associated whith the state machine that is used to
+    // Read/Modify/Write to the MMCM.
+    //**************************************************************************
+
+    // State Definitions
+    localparam RESTART      = 4'h1;
+    localparam WAIT_LOCK    = 4'h2;
+    localparam WAIT_SEN     = 4'h3;
+    localparam ADDRESS      = 4'h4;
+    localparam WAIT_A_DRDY  = 4'h5;
+    localparam BITMASK      = 4'h6;
+    localparam BITSET       = 4'h7;
+    localparam WRITE        = 4'h8;
+    localparam WAIT_DRDY    = 4'h9;
+
+    // State sync
+    reg [3:0]  current_state   = RESTART;
+    reg [3:0]  next_state      = RESTART;
+
+    // These variables are used to keep track of the number of iterations that
+    //    each state takes to reconfigure.
+    // STATE_COUNT_CONST is used to reset the counters and should match the
+    //    number of registers necessary to reconfigure each state.
+    localparam STATE_COUNT_CONST  = 23;
+    reg [4:0] state_count         = STATE_COUNT_CONST;
+    reg [4:0] next_state_count    = STATE_COUNT_CONST;
+
+    // This block assigns the next register value from the state machine below
+    always @(posedge SCLK) begin
+       DADDR       <= #TCQ next_daddr;
+       DWE         <= #TCQ next_dwe;
+       DEN         <= #TCQ next_den;
+       RST_MMCM    <= #TCQ next_rst_mmcm;
+       DI          <= #TCQ next_di;
+
+       SRDY        <= #TCQ next_srdy;
+
+       rom_addr    <= #TCQ next_rom_addr;
+       state_count <= #TCQ next_state_count;
+    end
+
+    // This block assigns the next state, reset is syncronous.
+    always @(posedge SCLK) begin
+       if(RST) begin
+          current_state <= #TCQ RESTART;
+       end else begin
+          current_state <= #TCQ next_state;
+       end
+    end
+
+    always @* begin
+       // Setup the default values
+       next_srdy         = 1'b0;
+       next_daddr        = DADDR;
+       next_dwe          = 1'b0;
+       next_den          = 1'b0;
+       next_rst_mmcm     = RST_MMCM;
+       next_di           = DI;
+       next_rom_addr     = rom_addr;
+       next_state_count  = state_count;
+
+       case (current_state)
+          // If RST is asserted reset the machine
+          RESTART: begin
+             next_daddr     = 7'h00;
+             next_di        = 16'h0000;
+             next_rom_addr  = 6'h00;
+             next_rst_mmcm  = 1'b1;
+             next_state     = WAIT_LOCK;
+          end
+
+          // Waits for the MMCM to assert IntLocked - once it does asserts SRDY
+          WAIT_LOCK: begin
+             // Make sure reset is de-asserted
+             next_rst_mmcm   = 1'b0;
+             // Reset the number of registers left to write for the next
+             // reconfiguration event.
+             next_state_count = STATE_COUNT_CONST ;
+             next_rom_addr = SADDR ? STATE_COUNT_CONST : 8'h00;
+
+             if(IntLocked) begin
+                // MMCM is IntLocked, go on to wait for the SEN signal
+                next_state  = WAIT_SEN;
+                // Assert SRDY to indicate that the reconfiguration module is
+                // ready
+                next_srdy   = 1'b1;
+             end else begin
+                // Keep waiting, IntLocked has not asserted yet
+                next_state  = WAIT_LOCK;
+             end
+          end
+
+          // Wait for the next SEN pulse and set the ROM addr appropriately
+          //    based on SADDR
+          WAIT_SEN: begin
+             next_rom_addr = SADDR ? STATE_COUNT_CONST : 8'h00;
+             if (SEN) begin
+                next_rom_addr = SADDR ? STATE_COUNT_CONST : 8'h00;
+                // Go on to address the MMCM
+                next_state = ADDRESS;
+             end else begin
+                // Keep waiting for SEN to be asserted
+                next_state = WAIT_SEN;
+             end
+          end
+
+          // Set the address on the MMCM and assert DEN to read the value
+          ADDRESS: begin
+             // Reset the DCM through the reconfiguration
+             next_rst_mmcm  = 1'b1;
+             // Enable a read from the MMCM and set the MMCM address
+             next_den       = 1'b1;
+             next_daddr     = rom_do[38:32];
+
+             // Wait for the data to be ready
+             next_state     = WAIT_A_DRDY;
+          end
+
+          // Wait for DRDY to assert after addressing the MMCM
+          WAIT_A_DRDY: begin
+             if (DRDY) begin
+                // Data is ready, mask out the bits to save
+                next_state = BITMASK;
+             end else begin
+                // Keep waiting till data is ready
+                next_state = WAIT_A_DRDY;
+             end
+          end
+
+          // Zero out the bits that are not set in the mask stored in rom
+          BITMASK: begin
+             // Do the mask
+             next_di     = rom_do[31:16] & DO;
+             // Go on to set the bits
+             next_state  = BITSET;
+          end
+
+          // After the input is masked, OR the bits with calculated value in rom
+          BITSET: begin
+             // Set the bits that need to be assigned
+             next_di           = rom_do[15:0] | DI;
+             // Set the next address to read from ROM
+             next_rom_addr     = rom_addr + 1'b1;
+             // Go on to write the data to the MMCM
+             next_state        = WRITE;
+          end
+
+          // DI is setup so assert DWE, DEN, and RST_MMCM.  Subtract one from the
+          //    state count and go to wait for DRDY.
+          WRITE: begin
+             // Set WE and EN on MMCM
+             next_dwe          = 1'b1;
+             next_den          = 1'b1;
+
+             // Decrement the number of registers left to write
+             next_state_count  = state_count - 1'b1;
+             // Wait for the write to complete
+             next_state        = WAIT_DRDY;
+          end
+
+          // Wait for DRDY to assert from the MMCM.  If the state count is not 0
+          //    jump to ADDRESS (continue reconfiguration).  If state count is
+          //    0 wait for lock.
+          WAIT_DRDY: begin
+             if(DRDY) begin
+                // Write is complete
+                if(state_count > 0) begin
+                   // If there are more registers to write keep going
+                   next_state  = ADDRESS;
+                end else begin
+                   // There are no more registers to write so wait for the MMCM
+                   // to lock
+                   next_state  = WAIT_LOCK;
+                end
+             end else begin
+                // Keep waiting for write to complete
+                next_state     = WAIT_DRDY;
+             end
+          end
+
+          // If in an unknown state reset the machine
+          default: begin
+             next_state = RESTART;
+          end
+       endcase
+    end
+endmodule

+ 830 - 0
sources_1/new/MMCM/mmcme2_drp_func.h

@@ -0,0 +1,830 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+//    Company:          Xilinx
+//    Engineer:         Jim Tatsukawa, Karl Kurbjun and Carl Ribbing
+//                      Updated by Marc Defossez
+//    Date:             19 Sep 2018
+//    Design Name:      MMCME2 DRP
+//    Module Name:      mmcme2_drp_func.h
+//    Version:          1.31
+//    Target Devices:   7 Series
+//    Tool versions:    2014.3 or later
+//    Description:      This header provides the functions necessary to
+//                      calculate the DRP register values for the V6 MMCM.
+//
+//	Revision Notes:
+//      3/12       - Updating lookup_low/lookup_high (CR)
+//			4/13       - Fractional divide function in mmcm_frac_count_calc function. CRS610807
+//			10/24      - Adjusting settings for clarity
+//      19 Sep 18  - Update of CP_RES_LFHF tables -- CR1010263
+//
+//    Disclaimer:  XILINX IS PROVIDING THIS DESIGN, CODE, OR
+//                 INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING
+//                 PROGRAMS AND SOLUTIONS FOR XILINX DEVICES.  BY
+//                 PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+//                 ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+//                 APPLICATION OR STANDARD, XILINX IS MAKING NO
+//                 REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
+//                 FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE
+//                 RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY
+//                 REQUIRE FOR YOUR IMPLEMENTATION.  XILINX
+//                 EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH
+//                 RESPECT TO THE ADEQUACY OF THE IMPLEMENTATION,
+//                 INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+//                 REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
+//                 FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES
+//                 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+//                 PURPOSE.
+//
+//                 (c) Copyright 2009-2010 Xilinx, Inc.
+//                 All rights reserved.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+// These are user functions that should not be modified.  Changes to the defines
+// or code within the functions may alter the accuracy of the calculations.
+
+// Define debug to provide extra messages durring elaboration
+`define DEBUG 1
+
+// FRAC_PRECISION describes the width of the fractional portion of the fixed
+//    point numbers.  These should not be modified, they are for development
+//    only
+`define FRAC_PRECISION  10
+// FIXED_WIDTH describes the total size for fixed point calculations(int+frac).
+// Warning: L.50 and below will not calculate properly with FIXED_WIDTHs
+//    greater than 32
+`define FIXED_WIDTH     32
+
+// This function takes a fixed point number and rounds it to the nearest
+//    fractional precision bit.
+function [`FIXED_WIDTH:1] round_frac
+   (
+      // Input is (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point number
+      input [`FIXED_WIDTH:1] decimal,
+
+      // This describes the precision of the fraction, for example a value
+      //    of 1 would modify the fractional so that instead of being a .16
+      //    fractional, it would be a .1 (rounded to the nearest 0.5 in turn)
+      input [`FIXED_WIDTH:1] precision
+   );
+
+   begin
+
+   `ifdef DEBUG
+      $display("round_frac - decimal: %h, precision: %h", decimal, precision);
+   `endif
+      // If the fractional precision bit is high then round up
+      if( decimal[(`FRAC_PRECISION-precision)] == 1'b1) begin
+         round_frac = decimal + (1'b1 << (`FRAC_PRECISION-precision));
+      end else begin
+         round_frac = decimal;
+      end
+   `ifdef DEBUG
+      $display("round_frac: %h", round_frac);
+   `endif
+   end
+endfunction
+
+// This function calculates high_time, low_time, w_edge, and no_count
+//    of a non-fractional counter based on the divide and duty cycle
+//
+// NOTE: high_time and low_time are returned as integers between 0 and 63
+//    inclusive.  64 should equal 6'b000000 (in other words it is okay to
+//    ignore the overflow)
+function [13:0] mmcm_divider
+   (
+      input [7:0] divide,        // Max divide is 128
+      input [31:0] duty_cycle    // Duty cycle is multiplied by 100,000
+   );
+
+   reg [`FIXED_WIDTH:1]    duty_cycle_fix;
+      // min/max allowed duty cycle range calc for divide => 64
+   reg [`FIXED_WIDTH:1]    duty_cycle_min;
+   reg [`FIXED_WIDTH:1]    duty_cycle_max;
+
+
+   // High/Low time is initially calculated with a wider integer to prevent a
+   // calculation error when it overflows to 64.
+   reg [6:0]               high_time;
+   reg [6:0]               low_time;
+   reg                     w_edge;
+   reg                     no_count;
+
+   reg [`FIXED_WIDTH:1]    temp;
+
+   begin
+      // Duty Cycle must be between 0 and 1,000
+      if(duty_cycle <=0 || duty_cycle >= 100000) begin
+         $display("ERROR: duty_cycle: %d is invalid", duty_cycle);
+         $finish;
+      end
+      if (divide >= 64) begin     // DCD and frequency generation fix if O divide => 64
+           duty_cycle_min = ((divide - 64) * 100_000) / divide;
+           duty_cycle_max = (64.5 / divide) * 100_000;
+           if (duty_cycle > duty_cycle_max)  duty_cycle = duty_cycle_max;
+           if (duty_cycle < duty_cycle_min)  duty_cycle = duty_cycle_min;
+       end
+      // Convert to FIXED_WIDTH-FRAC_PRECISION.FRAC_PRECISION fixed point
+      duty_cycle_fix = (duty_cycle << `FRAC_PRECISION) / 100_000;
+
+   `ifdef DEBUG
+      $display("duty_cycle_fix: %h", duty_cycle_fix);
+   `endif
+
+      // If the divide is 1 nothing needs to be set except the no_count bit.
+      //    Other values are dummies
+      if(divide == 7'h01) begin
+         high_time   = 7'h01;
+         w_edge      = 1'b0;
+         low_time    = 7'h01;
+         no_count    = 1'b1;
+      end else begin
+         temp = round_frac(duty_cycle_fix*divide, 1);
+
+         // comes from above round_frac
+         high_time   = temp[`FRAC_PRECISION+7:`FRAC_PRECISION+1];
+         // If the duty cycle * divide rounded is .5 or greater then this bit
+         //    is set.
+         w_edge      = temp[`FRAC_PRECISION]; // comes from round_frac
+
+         // If the high time comes out to 0, it needs to be set to at least 1
+         // and w_edge set to 0
+         if(high_time == 7'h00) begin
+            high_time   = 7'h01;
+            w_edge      = 1'b0;
+         end
+
+         if(high_time == divide) begin
+            high_time   = divide - 1;
+            w_edge      = 1'b1;
+         end
+
+         // Calculate low_time based on the divide setting and set no_count to
+         //    0 as it is only used when divide is 1.
+         low_time    = divide - high_time;
+         no_count    = 1'b0;
+      end
+
+      // Set the return value.
+      mmcm_divider = {w_edge,no_count,high_time[5:0],low_time[5:0]};
+   end
+endfunction
+
+// This function calculates mx, delay_time, and phase_mux
+//  of a non-fractional counter based on the divide and phase
+//
+// NOTE: The only valid value for the MX bits is 2'b00 to ensure the coarse mux
+//    is used.
+function [10:0] mmcm_phase
+   (
+      // divide must be an integer (use fractional if not)
+      //  assumed that divide already checked to be valid
+      input [7:0] divide, // Max divide is 128
+
+      // Phase is given in degrees (-360,000 to 360,000)
+      input signed [31:0] phase
+   );
+
+   reg [`FIXED_WIDTH:1] phase_in_cycles;
+   reg [`FIXED_WIDTH:1] phase_fixed;
+   reg [1:0]            mx;
+   reg [5:0]            delay_time;
+   reg [2:0]            phase_mux;
+
+   reg [`FIXED_WIDTH:1] temp;
+
+   begin
+`ifdef DEBUG
+      $display("mmcm_phase-divide:%d,phase:%d",
+         divide, phase);
+`endif
+
+      if ((phase < -360000) || (phase > 360000)) begin
+         $display("ERROR: phase of $phase is not between -360000 and 360000");
+         $finish;
+      end
+
+      // If phase is less than 0, convert it to a positive phase shift
+      // Convert to (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point
+      if(phase < 0) begin
+         phase_fixed = ( (phase + 360000) << `FRAC_PRECISION ) / 1000;
+      end else begin
+         phase_fixed = ( phase << `FRAC_PRECISION ) / 1000;
+      end
+
+      // Put phase in terms of decimal number of vco clock cycles
+      phase_in_cycles = ( phase_fixed * divide ) / 360;
+
+`ifdef DEBUG
+      $display("phase_in_cycles: %h", phase_in_cycles);
+`endif
+
+
+	 temp  =  round_frac(phase_in_cycles, 3);
+
+	 // set mx to 2'b00 that the phase mux from the VCO is enabled
+	 mx    			=  2'b00;
+	 phase_mux      =  temp[`FRAC_PRECISION:`FRAC_PRECISION-2];
+	 delay_time     =  temp[`FRAC_PRECISION+6:`FRAC_PRECISION+1];
+
+   `ifdef DEBUG
+      $display("temp: %h", temp);
+   `endif
+
+      // Setup the return value
+      mmcm_phase={mx, phase_mux, delay_time};
+   end
+endfunction
+
+// This function takes the divide value and outputs the necessary lock values
+function [39:0] mmcm_lock_lookup
+   (
+      input [6:0] divide // Max divide is 64
+   );
+
+   reg [2559:0]   lookup;
+
+   begin
+      lookup = {
+         // This table is composed of:
+         // LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt
+         40'b00110_00110_1111101000_1111101001_0000000001,
+         40'b00110_00110_1111101000_1111101001_0000000001,
+         40'b01000_01000_1111101000_1111101001_0000000001,
+         40'b01011_01011_1111101000_1111101001_0000000001,
+         40'b01110_01110_1111101000_1111101001_0000000001,
+         40'b10001_10001_1111101000_1111101001_0000000001,
+         40'b10011_10011_1111101000_1111101001_0000000001,
+         40'b10110_10110_1111101000_1111101001_0000000001,
+         40'b11001_11001_1111101000_1111101001_0000000001,
+         40'b11100_11100_1111101000_1111101001_0000000001,
+         40'b11111_11111_1110000100_1111101001_0000000001,
+         40'b11111_11111_1100111001_1111101001_0000000001,
+         40'b11111_11111_1011101110_1111101001_0000000001,
+         40'b11111_11111_1010111100_1111101001_0000000001,
+         40'b11111_11111_1010001010_1111101001_0000000001,
+         40'b11111_11111_1001110001_1111101001_0000000001,
+         40'b11111_11111_1000111111_1111101001_0000000001,
+         40'b11111_11111_1000100110_1111101001_0000000001,
+         40'b11111_11111_1000001101_1111101001_0000000001,
+         40'b11111_11111_0111110100_1111101001_0000000001,
+         40'b11111_11111_0111011011_1111101001_0000000001,
+         40'b11111_11111_0111000010_1111101001_0000000001,
+         40'b11111_11111_0110101001_1111101001_0000000001,
+         40'b11111_11111_0110010000_1111101001_0000000001,
+         40'b11111_11111_0110010000_1111101001_0000000001,
+         40'b11111_11111_0101110111_1111101001_0000000001,
+         40'b11111_11111_0101011110_1111101001_0000000001,
+         40'b11111_11111_0101011110_1111101001_0000000001,
+         40'b11111_11111_0101000101_1111101001_0000000001,
+         40'b11111_11111_0101000101_1111101001_0000000001,
+         40'b11111_11111_0100101100_1111101001_0000000001,
+         40'b11111_11111_0100101100_1111101001_0000000001,
+         40'b11111_11111_0100101100_1111101001_0000000001,
+         40'b11111_11111_0100010011_1111101001_0000000001,
+         40'b11111_11111_0100010011_1111101001_0000000001,
+         40'b11111_11111_0100010011_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001,
+         40'b11111_11111_0011111010_1111101001_0000000001
+      };
+
+      // Set lookup_entry with the explicit bits from lookup with a part select
+      mmcm_lock_lookup = lookup[ ((64-divide)*40) +: 40];
+   `ifdef DEBUG
+      $display("lock_lookup: %b", mmcm_lock_lookup);
+   `endif
+   end
+endfunction
+
+// This function takes the divide value and the bandwidth setting of the MMCM
+//  and outputs the digital filter settings necessary.
+function [9:0] mmcm_filter_lookup
+  (
+     input [6:0] divide, // Max divide is 64
+     input [8*9:0] BANDWIDTH
+  );
+
+  reg [639:0] lookup_low;
+  reg [639:0] lookup_low_ss;
+  reg [639:0] lookup_high;
+  reg [639:0] lookup_optimized;
+
+  reg [9:0] lookup_entry;
+
+  begin
+    lookup_low = {
+      // CP_RES_LFHF
+      10'b0010_1111_00, // 1
+      10'b0010_1111_00, // 2
+      10'b0010_1111_00, // 3
+      10'b0010_1111_00, // 4
+      10'b0010_0111_00, // ....
+      10'b0010_1011_00,
+      10'b0010_1101_00,
+      10'b0010_0011_00,
+      10'b0010_0101_00,
+      10'b0010_0101_00,
+      10'b0010_1001_00,
+      10'b0010_1110_00,
+      10'b0010_1110_00,
+      10'b0010_1110_00,
+      10'b0010_1110_00,
+      10'b0010_0001_00,
+      10'b0010_0001_00,
+      10'b0010_0001_00,
+      10'b0010_0110_00,
+      10'b0010_0110_00,
+      10'b0010_0110_00,
+      10'b0010_0110_00,
+      10'b0010_0110_00,
+      10'b0010_0110_00,
+      10'b0010_0110_00,
+      10'b0010_1010_00,
+      10'b0010_1010_00,
+      10'b0010_1010_00,
+      10'b0010_1010_00,
+      10'b0010_1010_00,
+      10'b0010_1100_00,
+      10'b0010_1100_00,
+      10'b0010_1100_00,
+      10'b0010_1100_00,
+      10'b0010_1100_00,
+      10'b0010_1100_00,
+      10'b0010_1100_00,
+      10'b0010_1100_00,
+      10'b0010_1100_00,
+      10'b0010_1100_00,
+      10'b0010_1100_00,
+      10'b0010_1100_00,
+      10'b0010_1100_00,
+      10'b0010_1100_00,
+      10'b0010_1100_00,
+      10'b0010_1100_00,
+      10'b0010_1100_00,
+      10'b0010_0010_00,
+      10'b0010_0010_00,
+      10'b0010_0010_00,
+      10'b0010_0010_00,
+      10'b0010_0010_00,
+      10'b0010_0010_00,
+      10'b0010_0010_00,
+      10'b0010_0010_00,
+      10'b0010_0010_00,
+      10'b0010_0010_00,
+      10'b0010_0010_00,
+      10'b0010_0010_00,
+      10'b0010_0010_00, // ....
+      10'b0010_0010_00, // 61
+      10'b0010_0010_00, // 62
+      10'b0010_0010_00, // 63
+      10'b0010_0010_00  // 64
+    };
+
+    lookup_low_ss = {
+      // CP_RES_LFHF
+      10'b0010_1111_11, // 1
+      10'b0010_1111_11, // 2
+      10'b0010_1111_11, // 3
+      10'b0010_1111_11, // 4
+      10'b0010_0111_11, // ....
+      10'b0010_1011_11,
+      10'b0010_1101_11,
+      10'b0010_0011_11,
+      10'b0010_0101_11,
+      10'b0010_0101_11,
+      10'b0010_1001_11,
+      10'b0010_1110_11,
+      10'b0010_1110_11,
+      10'b0010_1110_11,
+      10'b0010_1110_11,
+      10'b0010_0001_11,
+      10'b0010_0001_11,
+      10'b0010_0001_11,
+      10'b0010_0110_11,
+      10'b0010_0110_11,
+      10'b0010_0110_11,
+      10'b0010_0110_11,
+      10'b0010_0110_11,
+      10'b0010_0110_11,
+      10'b0010_0110_11,
+      10'b0010_1010_11,
+      10'b0010_1010_11,
+      10'b0010_1010_11,
+      10'b0010_1010_11,
+      10'b0010_1010_11,
+      10'b0010_1100_11,
+      10'b0010_1100_11,
+      10'b0010_1100_11,
+      10'b0010_1100_11,
+      10'b0010_1100_11,
+      10'b0010_1100_11,
+      10'b0010_1100_11,
+      10'b0010_1100_11,
+      10'b0010_1100_11,
+      10'b0010_1100_11,
+      10'b0010_1100_11,
+      10'b0010_1100_11,
+      10'b0010_1100_11,
+      10'b0010_1100_11,
+      10'b0010_1100_11,
+      10'b0010_1100_11,
+      10'b0010_1100_11,
+      10'b0010_0010_11,
+      10'b0010_0010_11,
+      10'b0010_0010_11,
+      10'b0010_0010_11,
+      10'b0010_0010_11,
+      10'b0010_0010_11,
+      10'b0010_0010_11,
+      10'b0010_0010_11,
+      10'b0010_0010_11,
+      10'b0010_0010_11,
+      10'b0010_0010_11,
+      10'b0010_0010_11,
+      10'b0010_0010_11, // ....
+      10'b0010_0010_11, // 61
+      10'b0010_0010_11, // 62
+      10'b0010_0010_11, // 63
+      10'b0010_0010_11  // 64
+    };
+
+    lookup_high = {
+      // CP_RES_LFHF
+      10'b0010_1111_00, // 1
+      10'b0100_1111_00, // 2
+      10'b0101_1011_00, // 3
+      10'b0111_0111_00, // 4
+      10'b1101_0111_00, // ....
+      10'b1110_1011_00,
+      10'b1110_1101_00,
+      10'b1111_0011_00,
+      10'b1110_0101_00,
+      10'b1111_0101_00,
+      10'b1111_1001_00,
+      10'b1101_0001_00,
+      10'b1111_1001_00,
+      10'b1111_1001_00,
+      10'b1111_1001_00,
+      10'b1111_1001_00,
+      10'b1111_0101_00,
+      10'b1111_0101_00,
+      10'b1100_0001_00,
+      10'b1100_0001_00,
+      10'b1100_0001_00,
+      10'b0101_1100_00,
+      10'b0101_1100_00,
+      10'b0101_1100_00,
+      10'b0101_1100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0010_1000_00,
+      10'b0010_1000_00,
+      10'b0010_1000_00,
+      10'b0010_1000_00,
+      10'b0010_1000_00,
+      10'b0111_0001_00,
+      10'b0111_0001_00,
+      10'b0100_1100_00,
+      10'b0100_1100_00,
+      10'b0100_1100_00,
+      10'b0100_1100_00,
+      10'b0110_0001_00,
+      10'b0110_0001_00,
+      10'b0101_0110_00,
+      10'b0101_0110_00,
+      10'b0101_0110_00,
+      10'b0010_0100_00,
+      10'b0010_0100_00,
+      10'b0010_0100_00, // ....
+      10'b0010_0100_00, // 61
+      10'b0100_1010_00, // 62
+      10'b0011_1100_00, // 63
+      10'b0011_1100_00  // 64
+    };
+
+    lookup_optimized = {
+      // CP_RES_LFHF
+      10'b0010_1111_00, // 1
+      10'b0100_1111_00, // 2
+      10'b0101_1011_00, // 3
+      10'b0111_0111_00, // 4
+      10'b1101_0111_00, // ....
+      10'b1110_1011_00,
+      10'b1110_1101_00,
+      10'b1111_0011_00,
+      10'b1110_0101_00,
+      10'b1111_0101_00,
+      10'b1111_1001_00,
+      10'b1101_0001_00,
+      10'b1111_1001_00,
+      10'b1111_1001_00,
+      10'b1111_1001_00,
+      10'b1111_1001_00,
+      10'b1111_0101_00,
+      10'b1111_0101_00,
+      10'b1100_0001_00,
+      10'b1100_0001_00,
+      10'b1100_0001_00,
+      10'b0101_1100_00,
+      10'b0101_1100_00,
+      10'b0101_1100_00,
+      10'b0101_1100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0011_0100_00,
+      10'b0010_1000_00,
+      10'b0010_1000_00,
+      10'b0010_1000_00,
+      10'b0010_1000_00,
+      10'b0010_1000_00,
+      10'b0111_0001_00,
+      10'b0111_0001_00,
+      10'b0100_1100_00,
+      10'b0100_1100_00,
+      10'b0100_1100_00,
+      10'b0100_1100_00,
+      10'b0110_0001_00,
+      10'b0110_0001_00,
+      10'b0101_0110_00,
+      10'b0101_0110_00,
+      10'b0101_0110_00,
+      10'b0010_0100_00,
+      10'b0010_0100_00,
+      10'b0010_0100_00, // ....
+      10'b0010_0100_00, // 61
+      10'b0100_1010_00, // 62
+      10'b0011_1100_00, // 63
+      10'b0011_1100_00  // 64
+    };
+
+    // Set lookup_entry with the explicit bits from lookup with a part select
+    if(BANDWIDTH == "LOW") begin
+      // Low Bandwidth
+      mmcm_filter_lookup = lookup_low[((64-divide)*10) +: 10];
+    end
+    else if (BANDWIDTH == "LOW_SS") begin
+      // low Spread spectrum bandwidth
+      mmcm_filter_lookup = lookup_low_ss[((64-divide)*10) +: 10];
+    end
+    else if (BANDWIDTH == "HIGH") begin
+      // High bandwidth
+      mmcm_filter_lookup = lookup_high[((64-divide)*10) +: 10];
+    end
+    else if (BANDWIDTH == "OPTIMIZED") begin
+      // Optimized bandwidth
+      mmcm_filter_lookup = lookup_optimized[((64-divide)*10) +: 10];
+    end
+
+    `ifdef DEBUG
+        $display("filter_lookup: %b", mmcm_filter_lookup);
+    `endif
+  end
+endfunction
+
+// This function takes in the divide, phase, and duty cycle
+// setting to calculate the upper and lower counter registers.
+function [37:0] mmcm_count_calc
+   (
+      input [7:0] divide, // Max divide is 128
+      input signed [31:0] phase,
+      input [31:0] duty_cycle // Multiplied by 100,000
+   );
+
+   reg [13:0] div_calc;
+   reg [16:0] phase_calc;
+
+   begin
+   `ifdef DEBUG
+      $display("mmcm_count_calc- divide:%h, phase:%d, duty_cycle:%d",
+         divide, phase, duty_cycle);
+   `endif
+
+      // w_edge[13], no_count[12], high_time[11:6], low_time[5:0]
+      div_calc = mmcm_divider(divide, duty_cycle);
+      // mx[10:9], pm[8:6], dt[5:0]
+      phase_calc = mmcm_phase(divide, phase);
+
+      // Return value is the upper and lower address of counter
+      //    Upper address is:
+      //       RESERVED    [31:26]
+      //       MX          [25:24]
+      //       EDGE        [23]
+      //       NOCOUNT     [22]
+      //       DELAY_TIME  [21:16]
+      //    Lower Address is:
+      //       PHASE_MUX   [15:13]
+      //       RESERVED    [12]
+      //       HIGH_TIME   [11:6]
+      //       LOW_TIME    [5:0]
+
+   `ifdef DEBUG
+      $display("div:%d dc:%d phase:%d ht:%d lt:%d ed:%d nc:%d mx:%d dt:%d pm:%d",
+         divide, duty_cycle, phase, div_calc[11:6], div_calc[5:0],
+         div_calc[13], div_calc[12],
+         phase_calc[16:15], phase_calc[5:0], phase_calc[14:12]);
+   `endif
+
+      mmcm_count_calc =
+         {
+            // Upper Address
+            6'h00, phase_calc[10:9], div_calc[13:12], phase_calc[5:0],
+            // Lower Address
+            phase_calc[8:6], 1'b0, div_calc[11:0]
+         };
+   end
+endfunction
+
+
+// This function takes in the divide, phase, and duty cycle
+// setting to calculate the upper and lower counter registers.
+// for fractional multiply/divide functions.
+//
+//
+function [37:0] mmcm_frac_count_calc
+   (
+      input [7:0] divide, // Max divide is 128
+      input signed [31:0] phase,
+      input [31:0] duty_cycle, // Multiplied by 1,000
+      input [9:0] frac // Multiplied by 1000
+   );
+
+	//Required for fractional divide calculations
+			  reg  [7:0]     lt_frac;
+			  reg  [7:0]     ht_frac;
+
+			  reg            wf_fall_frac;
+			  reg            wf_rise_frac;
+
+			  reg [31:0]     a;
+			  reg  [7:0]     pm_rise_frac_filtered ;
+			  reg  [7:0]     pm_fall_frac_filtered ;
+			  reg  [7:0]     clkout0_divide_int;
+			  reg  [2:0]     clkout0_divide_frac;
+			  reg  [7:0]     even_part_high;
+			  reg  [7:0]     even_part_low;
+			  reg [15:0]     drp_reg1;
+			  reg [15:0]     drp_reg2;
+			  reg  [5:0]     drp_regshared;
+
+			  reg  [7:0]     odd;
+			  reg  [7:0]     odd_and_frac;
+
+			  reg  [7:0]     pm_fall;
+			  reg  [7:0]     pm_rise;
+			  reg  [7:0]     dt;
+			  reg  [7:0]     dt_int;
+			  reg [63:0]     dt_calc;
+
+			  reg  [7:0]     pm_rise_frac;
+			  reg  [7:0]     pm_fall_frac;
+
+			  reg [31:0]     a_per_in_octets;
+			  reg [31:0]     a_phase_in_cycles;
+
+			                 parameter precision = 0.125;
+			  reg [31:0]     phase_fixed; // changed to 31:0 from 32:1 jt 5/2/11
+			  reg [31:0]     phase_pos;
+			  reg [31:0]     phase_vco;
+			  reg [31:0]     temp;// changed to 31:0 from 32:1 jt 5/2/11
+			  reg [13:0]     div_calc;
+			  reg [16:0]     phase_calc;
+
+   begin
+	`ifdef DEBUG
+			$display("mmcm_frac_count_calc- divide:%h, phase:%d, duty_cycle:%d",
+				divide, phase, duty_cycle);
+	`endif
+
+   //convert phase to fixed
+   if ((phase < -360000) || (phase > 360000)) begin
+      $display("ERROR: phase of $phase is not between -360000 and 360000");
+      $finish;
+   end
+
+
+      // Return value is
+      //    Shared data
+      //       RESERVED     [37:36]
+      //       FRAC_TIME    [35:33]
+      //       FRAC_WF_FALL [32]
+      //    Register 2 - Upper address is:
+      //       RESERVED     [31:26]
+      //       MX           [25:24]
+      //       EDGE         [23]
+      //       NOCOUNT      [22]
+      //       DELAY_TIME   [21:16]
+      //    Register 1 - Lower Address is:
+      //       PHASE_MUX    [15:13]
+      //       RESERVED     [12]
+      //       HIGH_TIME    [11:6]
+      //       LOW_TIME     [5:0]
+
+
+
+	clkout0_divide_frac = frac / 125;
+	clkout0_divide_int = divide;
+
+	even_part_high = clkout0_divide_int >> 1;//$rtoi(clkout0_divide_int / 2);
+	even_part_low = even_part_high;
+
+	odd = clkout0_divide_int - even_part_high - even_part_low;
+	odd_and_frac = (8*odd) + clkout0_divide_frac;
+
+	lt_frac = even_part_high - (odd_and_frac <= 9);//IF(odd_and_frac>9,even_part_high, even_part_high - 1)
+	ht_frac = even_part_low  - (odd_and_frac <= 8);//IF(odd_and_frac>8,even_part_low, even_part_low- 1)
+
+	pm_fall =  {odd[6:0],2'b00} + {6'h00, clkout0_divide_frac[2:1]}; // using >> instead of clkout0_divide_frac / 2
+	pm_rise = 0; //0
+
+	wf_fall_frac = ((odd_and_frac >=2) && (odd_and_frac <=9)) || ((clkout0_divide_frac == 1) && (clkout0_divide_int == 2));//CRS610807
+	wf_rise_frac = (odd_and_frac >=1) && (odd_and_frac <=8);//IF(odd_and_frac>=1,IF(odd_and_frac <= 8,1,0),0)
+
+
+
+	//Calculate phase in fractional cycles
+	a_per_in_octets		= (8 * divide) + (frac / 125) ;
+	a_phase_in_cycles	= (phase+10) * a_per_in_octets / 360000 ;//Adding 1 due to rounding errors
+	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};
+
+	dt_calc 	= ((phase+10) * a_per_in_octets / 8 )/360000 ;//TRUNC(phase* divide / 360); //or_simply (a_per_in_octets / 8)
+	dt 	= dt_calc[7:0];
+
+	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;
+
+	dt_int			= dt + (& pm_rise_frac[7:4]); //IF(pm_rise_overwriting>7,dt+1,dt)
+	pm_fall_frac		= pm_fall + pm_rise_frac;
+	pm_fall_frac_filtered	= pm_fall + pm_rise_frac - {pm_fall_frac[7:3], 3'b000};
+
+	div_calc	= mmcm_divider(divide, duty_cycle); //Use to determine edge[7], no count[6]
+	phase_calc	= mmcm_phase(divide, phase);// returns{mx[1:0], phase_mux[2:0], delay_time[5:0]}
+
+
+
+      drp_regshared[5:0] = { 2'b11, pm_fall_frac_filtered[2:0], wf_fall_frac};
+      drp_reg2[15:0] = { 1'b0, clkout0_divide_frac[2:0], 1'b1, wf_rise_frac, 4'h0, dt[5:0] };
+      drp_reg1[15:0] = { 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] };
+      mmcm_frac_count_calc[37:0] =   {drp_regshared, drp_reg2, drp_reg1} ;
+
+   `ifdef DEBUG
+      $display("DADDR Reg1 %h", drp_reg1);
+      $display("DADDR Reg2 %h", drp_reg2);
+      $display("DADDR Reg Shared %h", drp_regshared);
+      $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);
+   `endif
+
+   end
+endfunction

+ 691 - 0
sources_1/new/MMCM/top_mmcme2.tcl

@@ -0,0 +1,691 @@
+##################################################################################################
+# This TCL script is used to do basic project setup and clarify the DRP settings
+#
+# XAPP888 TCL commands:
+#       xapp888_create_project <> - Basic project setup. Adjust as needed
+#       xapp888_help <>           - Descriptions of added TCL commands
+#
+# XAPP888 TCL DRP Settings:
+#       xapp888_drp_settings <CLKFBOUT_MULT>  <DIVCLK_DIVIDE> <PHASE> <HIGH|LOW|high|low>
+#            - Displays & Returns the ordered pairs of DRP addresses & Data
+#
+#       xapp888_drp_clkout <DIVIDE>  <Duty Cycle e.g. 0.5> <Phase e.g.11.25> <CLKOUT0 to CLKOUT6>
+#            - Displays & Returns the ordered pairs of DRP addresses & Data
+#
+#       xapp888_merge_drp_clkout <list>
+#            - Returns the ordered DRP addresses/data merging fractional address 07 & 13
+#
+# Revision History:
+#       10/22/14 - Added TCL DRP commands
+#        3/17/16 - Added min/max duty cycle checks
+#        7/10/18 - Fixed duty cycles for divide > 64
+#       19 Sep 2018 - Add new lookup tables for CP RES LFHF
+#       05 Oct 2018 - Cosmetic updates to text.
+#
+##################################################################################################
+
+
+
+proc xapp888_create_project {} {
+create_project xapp888_mmcme2  -force xapp888_mmcme2 -part xc7k325tffg900-2
+add_files -norecurse {mmcme2_drp_func.h mmcme2_drp.v top_mmcme2.v  top_mmcme2.xdc}
+import_files -force -norecurse
+import_files -fileset sim_1 -norecurse {top_mmcme2_tb.v}
+update_compile_order -fileset sim_1
+}
+proc xapp888_merge_drp {list} {
+    set count_07 0
+    set merge_07 ""
+    set count_13 0
+    set merge_13 ""
+    set drp_merged ""
+    for {set i 0} { $i <= [expr [llength $list]/2] } {incr i} {
+        if {[string match [lindex $list [expr $i*2]] 07]} {
+            incr count_07; set merge_07 "$merge_07 [lindex $list [expr 2*$i + 1] ]"
+        } elseif {[string match [lindex $list [expr $i*2]] 13]} {
+            incr count_13; set merge_13 "$merge_13 [lindex $list [expr 2*$i + 1] ]"
+        } else {
+            set drp_merged "$drp_merged [lindex $list [expr $i * 2]] [lindex $list [expr $i * 2 + 1]]"
+        }
+    }
+
+    if {[llength $merge_07] > 1 } {set drp_07_merged [format %x [expr 0x[lindex $merge_07 0] | 0x[lindex $merge_07 1]]]} else {set drp_07_merged [lindex $merge_07 0]}
+    if {[llength $merge_13] > 1} {set drp_13_merged  [format %x [expr 0x[lindex $merge_13 0] | 0x[lindex $merge_13 1]]]} else {set drp_13_merged [lindex $merge_13 0]}
+    if {$count_07 >2} {
+            puts "ERROR: Too many shared addresses for 07. Only the first 2 terms are being marged. $merge_07"
+    } elseif {$count_07 > 0} {
+        set drp_merged "$drp_merged  07 $drp_07_merged"
+    }
+    if {$count_13 >2} {
+        puts "ERROR: Too many shared addresses for 13. Only the first 2 terms are being merged. $merge_13"
+    } elseif {$count_13 > 0} {
+        set drp_merged "$drp_merged 13 $drp_13_merged"
+    }
+    puts "$list has been changed to $drp_merged"
+    return $drp_merged
+}
+proc xapp888_drp_clkout_frac {divide phase} {
+    set divide_frac [expr fmod($divide, 1)]
+    set divide_frac_8ths [scan [expr $divide_frac * 8] %d]
+    set divide_int [scan [expr floor($divide)] %d]
+
+    set even_part_high [scan [expr floor($divide_int / 2)] %d]
+    set even_part_low $even_part_high
+
+    set odd [expr $divide_int - $even_part_high - $even_part_low]
+    set odd_and_frac [scan [expr 8 * $odd + $divide_frac_8ths] %d]
+
+    if {$odd_and_frac <=9} {set lt_frac [expr $even_part_high - 1]} else {set lt_frac $even_part_high}
+    if {$odd_and_frac <=8} {set ht_frac [expr $even_part_low - 1]} else {set ht_frac $even_part_low}
+
+    set pmfall [scan [expr $odd * 4 + floor($divide_frac_8ths / 2)] %d]
+    set pmrise 0
+    set dt [scan [expr floor($phase * $divide / 360)] %d]
+    set pmrise [scan [expr floor( 8 * (($phase * $divide /360 ) - $dt)+ 0.5 )] %d]
+    set pmfall [scan [expr $pmfall + $pmrise] %d]
+
+    if {$odd_and_frac <=9 && $odd_and_frac >=2 || $divide == 2.125} {set wf_fall 1} else {set wf_fall 0}
+    if {$odd_and_frac <=8 && $odd_and_frac >=1} {set wf_rise 1} else {set wf_rise 0}
+
+    set dt [scan [expr $dt + floor($pmrise / 8)] %d]
+    set pmrise [scan [expr fmod($pmrise , 8)] %d]
+    set pmfall [scan [expr fmod($pmfall , 8)] %d]
+
+    set reg1       "[xapp888_dec2bin $pmrise 3]1[xapp888_dec2bin $ht_frac 6][xapp888_dec2bin $lt_frac 6]"
+    set reg2       "0[xapp888_dec2bin $divide_frac_8ths 3]1[expr $wf_rise]0000[xapp888_dec2bin $dt 6]"
+    set regshared  "00[xapp888_dec2bin $pmfall 3][expr $wf_fall]"
+
+    return "$reg1 $reg2 $regshared "
+}
+
+proc xapp888_drp_clkout {divide dutycycle phase clkout} {
+    set clkout_lower [string tolower $clkout]
+        switch -glob -- $clkout_lower {
+            clkout0  {  set daddr_reg1 08
+                        set daddr_reg2 09
+                        }
+            clkout1  {  set daddr_reg1 0A
+                        set daddr_reg2 0B
+                        }
+            clkout2  {  set daddr_reg1 0C
+                        set daddr_reg2 0D
+                        }
+            clkout3  {  set daddr_reg1 0E
+                        set daddr_reg2 0F
+                        }
+            clkout4  {  set daddr_reg1 10
+                        set daddr_reg2 11
+                        }
+            clkout5  {  set daddr_reg1 06
+                        set daddr_reg2 07
+                        }
+            clkout6  {  set daddr_reg1 12
+                        set daddr_reg2 13
+                        }
+    }
+
+        if {$phase < 0} {set phase [expr 360 + $phase]}
+
+# Calculate phase for PM and O counter.
+# Round counter phase setting up if => 0.5 to closes possible phase
+        set phase_in_cycles [expr $phase / 360.0 * $divide]
+        set phasecycles_dec [expr (8 * $phase_in_cycles)]
+        set phasecycles_int [expr int($phasecycles_dec)]
+        set phasecycles_rem [expr ($phasecycles_dec - $phasecycles_int )]
+        if {$phasecycles_rem >= 0.5} {set phasecycles_int [expr ($phasecycles_int + 1)]}
+        set phasecycles [expr int($phasecycles_int / 8)]
+        set pmphasecycles [expr ($phasecycles_int - $phasecycles * 8)]
+# Duty cycle stuff
+         if {$divide < 64} {
+            set min_dc [expr 1.0 / $divide]
+            set max_dc [expr ($divide - 0.5) / $divide]
+       } else {
+            set min_dc [expr ($divide - 64.0) / $divide]
+            set max_dc [expr (64 + 0.5) / $divide]
+       }
+        if {$dutycycle < $min_dc} {puts "\n\tWARNING: Min duty cycle violation $dutycycle < $min_dc\n\t         Changing dutycycle to $min_dc\n"; set dutycycle $min_dc}
+        if {$dutycycle > $max_dc} {puts "\n\tWARNING: Max duty cycle is $dutycycle > $max_dc\n\t         Changing dutycycle to $max_dc\n"; set dutycycle $max_dc}
+
+    puts "Requested phase is: $phase; Given divide=$divide then phase increments in [format %f [expr 45.000/$divide ]  ];  "
+    #puts "DT will be $phasecycles, PM will be $pmphasecycles"
+    #puts "Phase will be shifted by VCO period * $phasecycles.[expr 1000*$pmphasecycles / 8]"
+    #puts "Phase will be shifted by [format %f [expr $phasecycles * 360.000 / $divide]] + [format %f  [expr $pmphasecycles * 45.000 / $divide]] = [format %f [expr ( $phasecycles * 360.000 / $divide) + ($pmphasecycles * 45.000 / $divide) ] ]"
+    puts "Requested Phase is: $phase; Actual: [format %f [expr ( $phasecycles * 360.000 / $divide) + ($pmphasecycles * 45.000 / $divide) ] ];  "
+
+#puts "[expr $pmphasecycles * 45 / $divide]"
+
+
+        set ht [scan [expr int($dutycycle * [expr ($divide ) ])] %d]
+        set lt [scan [expr $divide - $ht] %d]
+        set even_high [scan [expr $divide / 2] %d]
+        set odd [expr $divide - $even_high * 2]
+
+        if {$divide == 1} {
+             set drp_reg1 "[xapp888_bin2hex [binary scan [binary format I $pmphasecycles] B32 var;string range $var end-2 end]1000001000001]"
+             set drp_reg2 "[xapp888_bin2hex 00000000[expr $odd]1[xapp888_dec2bin $phasecycles 6] ]"
+             puts "DADDR_$daddr_reg1: $drp_reg1\t-[string toupper $clkout] Register 1"
+             puts "DADDR_$daddr_reg2: $drp_reg2\t-[string toupper $clkout] Register 2"
+             return "$daddr_reg1 $drp_reg1 $daddr_reg2 $drp_reg2"
+        } elseif {[expr fmod($divide,1)] == 0  }  {
+             set drp_reg1 "[xapp888_bin2hex [binary scan [binary format I $pmphasecycles] B32 var;string range $var end-2 end]1[xapp888_dec2bin4ltht $ht][xapp888_dec2bin4ltht $lt]]"
+             set drp_reg2 "[xapp888_bin2hex 00000000[expr $odd]0[xapp888_dec2bin $phasecycles 6] ]"
+             puts "DADDR_$daddr_reg1: $drp_reg1\t-[string toupper $clkout] Register 1"
+             puts "DADDR_$daddr_reg2: $drp_reg2\t-[string toupper $clkout] Register 2"
+             return "$daddr_reg1 $drp_reg1 $daddr_reg2 $drp_reg2"
+        } elseif {[string tolower $clkout] == "clkout0" } {
+            set drp_frac_registers [xapp888_drp_clkout_frac $divide $phase ]
+            set drp_reg1 [xapp888_bin2hex [lindex $drp_frac_registers 0]]
+            set drp_reg2 [xapp888_bin2hex [lindex $drp_frac_registers 1]]
+            set drp_regshared [xapp888_bin2hex [lindex $drp_frac_registers 2]0000000000]
+            puts "DADDR_$daddr_reg2: $drp_reg2\t-[string toupper $clkout] Register 1"
+            puts "DADDR_$daddr_reg1: $drp_reg1\t-[string toupper $clkout] Register 2"
+            puts "DADDR_07: $drp_regshared\t-[string toupper $clkout] Register Shared with CLKOUT5"
+            return "08 $drp_reg1 09 $drp_reg2 07 $drp_regshared"
+        }  else {puts "\nERROR: Fractional divide setting only supported for CLKOUT0. Output clock set to [string toupper $clkout] \n"
+    }
+}
+
+proc xapp888_drp_calc_m {divide phase} {
+    set phasecycles [expr int(($divide*$phase)/360)]
+    set pmphase [expr ($phase - ($phasecycles *360)/$divide)]
+    set pmphasecycles [scan [expr int(($pmphase *$divide)/ 45)] %d]
+
+    set ht [scan [expr ($divide ) / 2] %d]
+    set lt [scan [expr $divide - $ht] %d]
+    set odd [expr $lt - $ht]
+    set daddr_reg1 14
+    set daddr_reg2 15
+    set daddr_regshared 13
+    if {$divide == 1} {
+            set drp_reg1 "[xapp888_bin2hex [binary scan [binary format I $pmphasecycles] B32 var;string range $var end-2 end]1000001000001]"
+            set drp_reg2 "[xapp888_bin2hex 00000000[expr $odd]1[xapp888_dec2bin $phasecycles 6] ]"
+            puts "DADDR_$daddr_reg1: $drp_reg1\t-CLKFBOUT Register 1- "
+            puts "DADDR_$daddr_reg2: $drp_reg2\t-CLKFBOUT Register 2- "
+            return "$daddr_reg1 $drp_reg1 $daddr_reg2 $drp_reg2"
+    } elseif {$divide >=64  } {
+        puts "DADDR_14: ERROR: M must be 2 to 64\t-CLKFBOUT Register 2-"
+        puts "DADDR_15: ERROR: M must be 2 to 64\t-CLKFBOUT Register 2-\tNOTE: The calculations are only for the non-fractional settings. CLKFBOUT must use an integer divide value for these DRP settings to work"
+        return "14 ERROR 15 ERROR "
+    } elseif {[expr fmod($divide,1)] > 0} {
+        set drp_frac_registers [xapp888_drp_clkout_frac $divide $phase ]
+        set drp_reg1 [xapp888_bin2hex [lindex $drp_frac_registers 0]]
+        set drp_reg2 [xapp888_bin2hex [lindex $drp_frac_registers 1]]
+        set drp_regshared [xapp888_bin2hex [lindex $drp_frac_registers 2]0000000000]
+        puts "DADDR_$daddr_reg1: $drp_reg1\t-CLKFBOUT Register 1- "
+        puts "DADDR_$daddr_reg2: $drp_reg2\t-CLKFBOUT Register 2- "
+        puts "DADDR_$daddr_regshared: $drp_regshared\t-CLKFBOUT Register Shared with CLKOUT6- "
+        return "$daddr_reg1  $drp_reg1 $daddr_reg2  $drp_reg2 13 $drp_regshared"
+    } else {
+        puts "DADDR_$daddr_reg1: [xapp888_bin2hex [binary scan [binary format I $pmphasecycles] B32 var;string range $var end-2 end]1[xapp888_dec2bin4ltht $ht][xapp888_dec2bin4ltht $lt]]\t-CLKFBOUT Register 1- "
+        puts "DADDR_$daddr_reg2: [xapp888_bin2hex 00000000[expr $odd]0[binary scan [binary format I $phasecycles] B32 var;string range $var end-5 end] ]\t-CLKFBOUT Register 2- "
+        return "$daddr_reg1  [xapp888_bin2hex [binary scan [binary format I $pmphasecycles] B32 var;string range $var end-2 end]1[xapp888_dec2bin4ltht $ht][xapp888_dec2bin4ltht $lt]] $daddr_reg2  [xapp888_bin2hex 00000000[expr $odd]0[binary scan [binary format I $phasecycles] B32 var;string range $var end-5 end] ]"
+    }
+}
+
+proc xapp888_drp_calc_d {divide} {
+    set ht [scan [expr ($divide ) / 2] %d]
+    set lt [scan [expr $divide - $ht] %d]
+    if {$divide == 1} {
+        puts "DADDR_16: [xapp888_bin2hex 0001000001000001]\t-DIVCLK Register $divide-"
+        return "16 [xapp888_bin2hex 0001000001000001]"
+    } elseif { $divide > 19} {
+        puts "DADDR_16: ERROR D must be 1 to 19"
+        return "16 ERROR"
+    } else {
+        puts "DADDR_16: [xapp888_bin2hex 0000[xapp888_dec2bin4ltht $ht][xapp888_dec2bin4ltht $lt] ]\t-DIVCLK Register $divide-" }
+        return "16 [xapp888_bin2hex 0000[xapp888_dec2bin4ltht $ht][xapp888_dec2bin4ltht $lt] ] "
+}
+
+proc xapp888_dec2bin4ltht {dec} {
+     binary scan [binary format c $dec] B* bin
+     string range $bin end-5 end
+}
+
+proc xapp888_cpres {div bw} {
+    #CP_RES_LFHF
+    set div [scan $div %d]
+    set bw_lower [string tolower $bw]
+    if {$bw_lower == "low" } then {
+        switch -glob -- $div {
+            1   {set CP 0010 ; set RES 1111 ; set LFHF 00 }
+            2   {set CP 0010 ; set RES 1111 ; set LFHF 00 }
+            3   {set CP 0010 ; set RES 1111 ; set LFHF 00 }
+            4   {set CP 0010 ; set RES 1111 ; set LFHF 00 }
+            5   {set CP 0010 ; set RES 0111 ; set LFHF 00 }
+            6   {set CP 0010 ; set RES 1011 ; set LFHF 00 }
+            7   {set CP 0010 ; set RES 1101 ; set LFHF 00 }
+            8   {set CP 0010 ; set RES 0011 ; set LFHF 00 }
+            9   {set CP 0010 ; set RES 0101 ; set LFHF 00 }
+            10  {set CP 0010 ; set RES 0101 ; set LFHF 00 }
+            11  {set CP 0010 ; set RES 1001 ; set LFHF 00 }
+            12  {set CP 0010 ; set RES 1110 ; set LFHF 00 }
+            13  {set CP 0010 ; set RES 1110 ; set LFHF 00 }
+            14  {set CP 0010 ; set RES 1110 ; set LFHF 00 }
+            15  {set CP 0010 ; set RES 1110 ; set LFHF 00 }
+            16  {set CP 0010 ; set RES 0001 ; set LFHF 00 }
+            17  {set CP 0010 ; set RES 0001 ; set LFHF 00 }
+            18  {set CP 0010 ; set RES 0001 ; set LFHF 00 }
+            19  {set CP 0010 ; set RES 0110 ; set LFHF 00 }
+            20  {set CP 0010 ; set RES 0110 ; set LFHF 00 }
+            21  {set CP 0010 ; set RES 0110 ; set LFHF 00 }
+            22  {set CP 0010 ; set RES 0110 ; set LFHF 00 }
+            23  {set CP 0010 ; set RES 0110 ; set LFHF 00 }
+            24  {set CP 0010 ; set RES 0110 ; set LFHF 00 }
+            25  {set CP 0010 ; set RES 0110 ; set LFHF 00 }
+            26  {set CP 0010 ; set RES 1010 ; set LFHF 00 }
+            27  {set CP 0010 ; set RES 1010 ; set LFHF 00 }
+            28  {set CP 0010 ; set RES 1010 ; set LFHF 00 }
+            29  {set CP 0010 ; set RES 1010 ; set LFHF 00 }
+            30  {set CP 0010 ; set RES 1010 ; set LFHF 00 }
+            31  {set CP 0010 ; set RES 1100 ; set LFHF 00 }
+            32  {set CP 0010 ; set RES 1100 ; set LFHF 00 }
+            33  {set CP 0010 ; set RES 1100 ; set LFHF 00 }
+            34  {set CP 0010 ; set RES 1100 ; set LFHF 00 }
+            35  {set CP 0010 ; set RES 1100 ; set LFHF 00 }
+            36  {set CP 0010 ; set RES 1100 ; set LFHF 00 }
+            37  {set CP 0010 ; set RES 1100 ; set LFHF 00 }
+            38  {set CP 0010 ; set RES 1100 ; set LFHF 00 }
+            39  {set CP 0010 ; set RES 1100 ; set LFHF 00 }
+            40  {set CP 0010 ; set RES 1100 ; set LFHF 00 }
+            41  {set CP 0010 ; set RES 1100 ; set LFHF 00 }
+            42  {set CP 0010 ; set RES 1100 ; set LFHF 00 }
+            43  {set CP 0010 ; set RES 1100 ; set LFHF 00 }
+            44  {set CP 0010 ; set RES 1100 ; set LFHF 00 }
+            45  {set CP 0010 ; set RES 1100 ; set LFHF 00 }
+            46  {set CP 0010 ; set RES 1100 ; set LFHF 00 }
+            47  {set CP 0010 ; set RES 1100 ; set LFHF 00 }
+            48  {set CP 0010 ; set RES 0010 ; set LFHF 00 }
+            49  {set CP 0010 ; set RES 0010 ; set LFHF 00 }
+            50  {set CP 0010 ; set RES 0010 ; set LFHF 00 }
+            51  {set CP 0010 ; set RES 0010 ; set LFHF 00 }
+            52  {set CP 0010 ; set RES 0010 ; set LFHF 00 }
+            53  {set CP 0010 ; set RES 0010 ; set LFHF 00 }
+            54  {set CP 0010 ; set RES 0010 ; set LFHF 00 }
+            55  {set CP 0010 ; set RES 0010 ; set LFHF 00 }
+            56  {set CP 0010 ; set RES 0010 ; set LFHF 00 }
+            57  {set CP 0010 ; set RES 0010 ; set LFHF 00 }
+            58  {set CP 0010 ; set RES 0010 ; set LFHF 00 }
+            59  {set CP 0010 ; set RES 0010 ; set LFHF 00 }
+            60  {set CP 0010 ; set RES 0010 ; set LFHF 00 }
+            61  {set CP 0010 ; set RES 0010 ; set LFHF 00 }
+            62  {set CP 0010 ; set RES 0010 ; set LFHF 00 }
+            63  {set CP 0010 ; set RES 0010 ; set LFHF 00 }
+            64  {set CP 0010 ; set RES 0010 ; set LFHF 00 }
+        }
+    } elseif {$bw_lower == "low_ss"} then {
+        switch -glob -- $div {
+            1   {set CP 0010 ; set RES 1111 ; set LFHF 11 }
+            2   {set CP 0010 ; set RES 1111 ; set LFHF 11 }
+            3   {set CP 0010 ; set RES 1111 ; set LFHF 11 }
+            4   {set CP 0010 ; set RES 1111 ; set LFHF 11 }
+            5   {set CP 0010 ; set RES 0111 ; set LFHF 11 }
+            6   {set CP 0010 ; set RES 1011 ; set LFHF 11 }
+            7   {set CP 0010 ; set RES 1101 ; set LFHF 11 }
+            8   {set CP 0010 ; set RES 0011 ; set LFHF 11 }
+            9   {set CP 0010 ; set RES 0101 ; set LFHF 11 }
+            10  {set CP 0010 ; set RES 0101 ; set LFHF 11 }
+            11  {set CP 0010 ; set RES 1001 ; set LFHF 11 }
+            12  {set CP 0010 ; set RES 1110 ; set LFHF 11 }
+            13  {set CP 0010 ; set RES 1110 ; set LFHF 11 }
+            14  {set CP 0010 ; set RES 1110 ; set LFHF 11 }
+            15  {set CP 0010 ; set RES 1110 ; set LFHF 11 }
+            16  {set CP 0010 ; set RES 0001 ; set LFHF 11 }
+            17  {set CP 0010 ; set RES 0001 ; set LFHF 11 }
+            18  {set CP 0010 ; set RES 0001 ; set LFHF 11 }
+            19  {set CP 0010 ; set RES 0110 ; set LFHF 11 }
+            20  {set CP 0010 ; set RES 0110 ; set LFHF 11 }
+            21  {set CP 0010 ; set RES 0110 ; set LFHF 11 }
+            22  {set CP 0010 ; set RES 0110 ; set LFHF 11 }
+            23  {set CP 0010 ; set RES 0110 ; set LFHF 11 }
+            24  {set CP 0010 ; set RES 0110 ; set LFHF 11 }
+            25  {set CP 0010 ; set RES 0110 ; set LFHF 11 }
+            26  {set CP 0010 ; set RES 1010 ; set LFHF 11 }
+            27  {set CP 0010 ; set RES 1010 ; set LFHF 11 }
+            28  {set CP 0010 ; set RES 1010 ; set LFHF 11 }
+            29  {set CP 0010 ; set RES 1010 ; set LFHF 11 }
+            30  {set CP 0010 ; set RES 1010 ; set LFHF 11 }
+            31  {set CP 0010 ; set RES 1100 ; set LFHF 11 }
+            32  {set CP 0010 ; set RES 1100 ; set LFHF 11 }
+            33  {set CP 0010 ; set RES 1100 ; set LFHF 11 }
+            34  {set CP 0010 ; set RES 1100 ; set LFHF 11 }
+            35  {set CP 0010 ; set RES 1100 ; set LFHF 11 }
+            36  {set CP 0010 ; set RES 1100 ; set LFHF 11 }
+            37  {set CP 0010 ; set RES 1100 ; set LFHF 11 }
+            38  {set CP 0010 ; set RES 1100 ; set LFHF 11 }
+            39  {set CP 0010 ; set RES 1100 ; set LFHF 11 }
+            40  {set CP 0010 ; set RES 1100 ; set LFHF 11 }
+            41  {set CP 0010 ; set RES 1100 ; set LFHF 11 }
+            42  {set CP 0010 ; set RES 1100 ; set LFHF 11 }
+            43  {set CP 0010 ; set RES 1100 ; set LFHF 11 }
+            44  {set CP 0010 ; set RES 1100 ; set LFHF 11 }
+            45  {set CP 0010 ; set RES 1100 ; set LFHF 11 }
+            46  {set CP 0010 ; set RES 1100 ; set LFHF 11 }
+            47  {set CP 0010 ; set RES 1100 ; set LFHF 11 }
+            48  {set CP 0010 ; set RES 0010 ; set LFHF 11 }
+            49  {set CP 0010 ; set RES 0010 ; set LFHF 11 }
+            50  {set CP 0010 ; set RES 0010 ; set LFHF 11 }
+            51  {set CP 0010 ; set RES 0010 ; set LFHF 11 }
+            52  {set CP 0010 ; set RES 0010 ; set LFHF 11 }
+            53  {set CP 0010 ; set RES 0010 ; set LFHF 11 }
+            54  {set CP 0010 ; set RES 0010 ; set LFHF 11 }
+            55  {set CP 0010 ; set RES 0010 ; set LFHF 11 }
+            56  {set CP 0010 ; set RES 0010 ; set LFHF 11 }
+            57  {set CP 0010 ; set RES 0010 ; set LFHF 11 }
+            58  {set CP 0010 ; set RES 0010 ; set LFHF 11 }
+            59  {set CP 0010 ; set RES 0010 ; set LFHF 11 }
+            60  {set CP 0010 ; set RES 0010 ; set LFHF 11 }
+            61  {set CP 0010 ; set RES 0010 ; set LFHF 11 }
+            62  {set CP 0010 ; set RES 0010 ; set LFHF 11 }
+            63  {set CP 0010 ; set RES 0010 ; set LFHF 11 }
+            64  {set CP 0010 ; set RES 0010 ; set LFHF 11 }
+        }
+    } elseif {$bw_lower == "high"} then {
+        switch -glob -- $div {
+            1   {set CP 0010 ; set RES 1111 ; set LFHF 00 }
+            2   {set CP 0100 ; set RES 1111 ; set LFHF 00 }
+            3   {set CP 0101 ; set RES 1011 ; set LFHF 00 }
+            4   {set CP 0111 ; set RES 0111 ; set LFHF 00 }
+            5   {set CP 1101 ; set RES 0111 ; set LFHF 00 }
+            6   {set CP 1110 ; set RES 1011 ; set LFHF 00 }
+            7   {set CP 1110 ; set RES 1101 ; set LFHF 00 }
+            8   {set CP 1111 ; set RES 0011 ; set LFHF 00 }
+            9   {set CP 1110 ; set RES 0101 ; set LFHF 00 }
+            10  {set CP 1111 ; set RES 0101 ; set LFHF 00 }
+            11  {set CP 1111 ; set RES 1001 ; set LFHF 00 }
+            12  {set CP 1101 ; set RES 0001 ; set LFHF 00 }
+            13  {set CP 1111 ; set RES 1001 ; set LFHF 00 }
+            14  {set CP 1111 ; set RES 1001 ; set LFHF 00 }
+            15  {set CP 1111 ; set RES 1001 ; set LFHF 00 }
+            16  {set CP 1111 ; set RES 1001 ; set LFHF 00 }
+            17  {set CP 1111 ; set RES 0101 ; set LFHF 00 }
+            18  {set CP 1111 ; set RES 0101 ; set LFHF 00 }
+            19  {set CP 1100 ; set RES 0001 ; set LFHF 00 }
+            20  {set CP 1100 ; set RES 0001 ; set LFHF 00 }
+            21  {set CP 1100 ; set RES 0001 ; set LFHF 00 }
+            22  {set CP 0101 ; set RES 1100 ; set LFHF 00 }
+            23  {set CP 0101 ; set RES 1100 ; set LFHF 00 }
+            24  {set CP 0101 ; set RES 1100 ; set LFHF 00 }
+            25  {set CP 0101 ; set RES 1100 ; set LFHF 00 }
+            26  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            27  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            28  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            29  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            30  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            31  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            32  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            33  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            34  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            35  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            36  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            37  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            38  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            39  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            40  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            41  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            42  {set CP 0010 ; set RES 1000 ; set LFHF 00 }
+            43  {set CP 0010 ; set RES 1000 ; set LFHF 00 }
+            44  {set CP 0010 ; set RES 1000 ; set LFHF 00 }
+            45  {set CP 0010 ; set RES 1000 ; set LFHF 00 }
+            46  {set CP 0010 ; set RES 1000 ; set LFHF 00 }
+            47  {set CP 0111 ; set RES 0001 ; set LFHF 00 }
+            48  {set CP 0111 ; set RES 0001 ; set LFHF 00 }
+            49  {set CP 0100 ; set RES 1100 ; set LFHF 00 }
+            50  {set CP 0100 ; set RES 1100 ; set LFHF 00 }
+            51  {set CP 0100 ; set RES 1100 ; set LFHF 00 }
+            52  {set CP 0100 ; set RES 1100 ; set LFHF 00 }
+            53  {set CP 0110 ; set RES 0001 ; set LFHF 00 }
+            54  {set CP 0110 ; set RES 0001 ; set LFHF 00 }
+            55  {set CP 0101 ; set RES 0110 ; set LFHF 00 }
+            56  {set CP 0101 ; set RES 0110 ; set LFHF 00 }
+            57  {set CP 0101 ; set RES 0110 ; set LFHF 00 }
+            58  {set CP 0010 ; set RES 0100 ; set LFHF 00 }
+            59  {set CP 0010 ; set RES 0100 ; set LFHF 00 }
+            60  {set CP 0010 ; set RES 0100 ; set LFHF 00 }
+            61  {set CP 0010 ; set RES 0100 ; set LFHF 00 }
+            62  {set CP 0100 ; set RES 1010 ; set LFHF 00 }
+            63  {set CP 0011 ; set RES 1100 ; set LFHF 00 }
+            64  {set CP 0011 ; set RES 1100 ; set LFHF 00 }
+        }
+    } else {
+      # OPTIMIZED
+        switch -glob -- $div {
+            1   {set CP 0010 ; set RES 1111 ; set LFHF 00 }
+            2   {set CP 0100 ; set RES 1111 ; set LFHF 00 }
+            3   {set CP 0101 ; set RES 1011 ; set LFHF 00 }
+            4   {set CP 0111 ; set RES 0111 ; set LFHF 00 }
+            5   {set CP 1101 ; set RES 0111 ; set LFHF 00 }
+            6   {set CP 1110 ; set RES 1011 ; set LFHF 00 }
+            7   {set CP 1110 ; set RES 1101 ; set LFHF 00 }
+            8   {set CP 1111 ; set RES 0011 ; set LFHF 00 }
+            9   {set CP 1110 ; set RES 0101 ; set LFHF 00 }
+            10  {set CP 1111 ; set RES 0101 ; set LFHF 00 }
+            11  {set CP 1111 ; set RES 1001 ; set LFHF 00 }
+            12  {set CP 1101 ; set RES 0001 ; set LFHF 00 }
+            13  {set CP 1111 ; set RES 1001 ; set LFHF 00 }
+            14  {set CP 1111 ; set RES 1001 ; set LFHF 00 }
+            15  {set CP 1111 ; set RES 1001 ; set LFHF 00 }
+            16  {set CP 1111 ; set RES 1001 ; set LFHF 00 }
+            17  {set CP 1111 ; set RES 0101 ; set LFHF 00 }
+            18  {set CP 1111 ; set RES 0101 ; set LFHF 00 }
+            19  {set CP 1100 ; set RES 0001 ; set LFHF 00 }
+            20  {set CP 1100 ; set RES 0001 ; set LFHF 00 }
+            21  {set CP 1100 ; set RES 0001 ; set LFHF 00 }
+            22  {set CP 0101 ; set RES 1100 ; set LFHF 00 }
+            23  {set CP 0101 ; set RES 1100 ; set LFHF 00 }
+            24  {set CP 0101 ; set RES 1100 ; set LFHF 00 }
+            25  {set CP 0101 ; set RES 1100 ; set LFHF 00 }
+            26  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            27  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            28  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            29  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            30  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            31  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            32  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            33  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            34  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            35  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            36  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            37  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            38  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            39  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            40  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            41  {set CP 0011 ; set RES 0100 ; set LFHF 00 }
+            42  {set CP 0010 ; set RES 1000 ; set LFHF 00 }
+            43  {set CP 0010 ; set RES 1000 ; set LFHF 00 }
+            44  {set CP 0010 ; set RES 1000 ; set LFHF 00 }
+            45  {set CP 0010 ; set RES 1000 ; set LFHF 00 }
+            46  {set CP 0010 ; set RES 1000 ; set LFHF 00 }
+            47  {set CP 0111 ; set RES 0001 ; set LFHF 00 }
+            48  {set CP 0111 ; set RES 0001 ; set LFHF 00 }
+            49  {set CP 0100 ; set RES 1100 ; set LFHF 00 }
+            50  {set CP 0100 ; set RES 1100 ; set LFHF 00 }
+            51  {set CP 0100 ; set RES 1100 ; set LFHF 00 }
+            52  {set CP 0100 ; set RES 1100 ; set LFHF 00 }
+            53  {set CP 0110 ; set RES 0001 ; set LFHF 00 }
+            54  {set CP 0110 ; set RES 0001 ; set LFHF 00 }
+            55  {set CP 0101 ; set RES 0110 ; set LFHF 00 }
+            56  {set CP 0101 ; set RES 0110 ; set LFHF 00 }
+            57  {set CP 0101 ; set RES 0110 ; set LFHF 00 }
+            58  {set CP 0010 ; set RES 0100 ; set LFHF 00 }
+            59  {set CP 0010 ; set RES 0100 ; set LFHF 00 }
+            60  {set CP 0010 ; set RES 0100 ; set LFHF 00 }
+            61  {set CP 0010 ; set RES 0100 ; set LFHF 00 }
+            62  {set CP 0100 ; set RES 1010 ; set LFHF 00 }
+            63  {set CP 0011 ; set RES 1100 ; set LFHF 00 }
+            64  {set CP 0011 ; set RES 1100 ; set LFHF 00 }
+          }
+    }
+        puts "DADDR_4E: [xapp888_bin2hex "[string index $CP 0]00[string range $CP 1 2]00[string index $CP 3]00000000"]\t-Filter Register 1: M set to $div with $bw bandwidth-"
+        puts "DADDR_4F: [xapp888_bin2hex "[string index $RES 0]00[string range $RES 1 2]00[string index $RES 3][string index $LFHF 0]00[string index $LFHF 1]0000"]\t-Filter Register 2: M set to $div with $bw bandwidth-"
+        return "4F [xapp888_bin2hex "[string index $RES 0]00[string range $RES 1 2]00[string index $RES 3][string index $LFHF 0]00[string index $LFHF 1]0000"] 4E [xapp888_bin2hex "[string index $CP 0]00[string range $CP 1 2]00[string index $CP 3]00000000"]"
+}
+
+proc xapp888_locking {div} {
+        # LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt
+        set div [scan $div %d]
+        switch -glob -- $div {
+            1 {set LockRefDly 00110 ; set LockFBDly 00110 ; set LockCnt 0111101000 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            2 {set LockRefDly 00110 ; set LockFBDly 00110 ; set LockCnt 0111101000 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            3 {set LockRefDly 01000 ; set LockFBDly 01000 ; set LockCnt 0111101000 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            4 {set LockRefDly 01011 ; set LockFBDly 01011 ; set LockCnt 0111101000 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            5 {set LockRefDly 01110 ; set LockFBDly 01110 ; set LockCnt 0111101000 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            6 {set LockRefDly 10001 ; set LockFBDly 10001 ; set LockCnt 0111101000 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            7 {set LockRefDly 10011 ; set LockFBDly 10011 ; set LockCnt 0111101000 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            8 {set LockRefDly 10110 ; set LockFBDly 10110 ; set LockCnt 0111101000 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            9 {set LockRefDly 11001 ; set LockFBDly 11001 ; set LockCnt 0111101000 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            10 {set LockRefDly 11100 ; set LockFBDly 11100 ; set LockCnt 0111101000 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            11 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0110000100 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            12 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0100111001 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            13 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0111101110 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            14 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0110111100 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            15 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0110001010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            16 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0101110001 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            17 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0100111111 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            18 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0100100110 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            19 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0100001101 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            20 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011110100 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            21 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011011011 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            22 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011000010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            23 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0010101001 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            24 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0010010000 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            25 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0010010000 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            26 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0001110111 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            27 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0001011110 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            28 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0001011110 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            29 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0001000101 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            30 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0001000101 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            31 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0000101100 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            32 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0000101100 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            33 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0000101100 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            34 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0000010011 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            35 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0000010011 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            36 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0000010011 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            37 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            38 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            39 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            40 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            41 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            42 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            43 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            44 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            45 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            46 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            47 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            48 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            49 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            50 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            51 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            52 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            53 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            54 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            55 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            56 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            57 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            58 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            59 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            60 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            61 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            62 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            63 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+            64 {set LockRefDly 11111 ; set LockFBDly 11111 ; set LockCnt 0011111010 ;set LockSatHigh 0111101001 ;set UnlockCnt 0000000001}
+         }
+
+        puts "DADDR_28: FFFF\t-Power register leaving all interpolators on - "
+        puts "DADDR_18: [xapp888_bin2hex 000000$LockCnt]\t-Lock Register 1: for M set to $div -"
+        puts "DADDR_19: [xapp888_bin2hex 0$LockFBDly$UnlockCnt]\t-Lock Register 2: for M set to $div"
+        puts "DADDR_1A: [xapp888_bin2hex 0$LockRefDly$LockSatHigh]\t-Lock Register 3: for M set to $div"
+        return "28 FFFF 18 [xapp888_bin2hex 000000$LockCnt] 19 [xapp888_bin2hex 0$LockFBDly$UnlockCnt] 1A [xapp888_bin2hex 0$LockRefDly$LockSatHigh]"
+}
+
+proc xapp888_bin2hex {bits} {
+    set abits ""
+    for {set i 0} {$i <= [expr 15 - [string length $bits]] } {incr i} {
+        append abits 0}
+    append abits "$bits"
+    set binValue [binary format B16 $abits]
+    binary scan $binValue H4 hex
+    return $hex
+    }
+
+proc xapp888_hex2bin {hex} {
+    for {set i 0} { $i <= [string length $hex]} { incr i 1} {
+        append convert2bin [xapp888_hex2bin_ [string range $hex $i $i] ]
+        }
+    return $convert2bin
+
+}
+proc xapp888_hex2bin_ {hex} {
+        return [string map -nocase {
+            0 0000 1 0001 2 0010 3 0011 4 0100 5 0101 6 0110 7 0111
+            8 1000 9 1001 a 1010 b 1011 c 1100 d 1101 e 1110 f 1111
+            } $hex ]
+
+}
+
+proc xapp888_dec2hex {value} {
+   # Creates a 16 bit hex number from a signed decimal number
+   # Replace all non-decimal characters
+   regsub -all {[^0-9\.\-]} $value {} newtemp
+   set value [string trim $newtemp]
+   if {$value < 65535 && $value >= 0} {
+      set tempvalue [format "%#010X" [expr $value]]
+      return [string range $tempvalue 6 9]
+   } elseif {$value < 0} {
+      puts "Unsigned value"
+      return "0000"
+   } else {
+      puts "Violates 16 bit range"
+      return "FFFF"
+   }
+}
+proc xapp888_drp_settings {m d phase bw} {
+    if {$phase < 0} {set phase [expr 360 + $phase]}
+    set data_m [xapp888_drp_calc_m $m $phase]
+    set data_d [xapp888_drp_calc_d $d]
+    set data_cpres [xapp888_cpres $m $bw]
+    set data_locking [xapp888_locking $m]
+    return "$data_m $data_d $data_cpres $data_locking"
+}
+
+proc xapp888_dec2bin {dec bits} {return [binary scan [binary format I $dec] B32 var;string range $var end-[expr $bits-1] end]}
+
+proc xapp888_dec2bindt {dec} {
+        return [string map { 0 000 1 001 2 010 3 011 4 100 5 101 6 110 7 111} $dec]
+}
+
+proc xapp888_help {} {
+    puts "\n\n-----------------------------------------------------------------------------------------------\
+    \nXAPP888 TCL commands:\
+    \n      xapp888_create_project <> - Basic project setup. Adjust as needed\
+    \n      xapp888_help <>           - Descriptions of added TCL commands\
+    \n\nXAPP888 TCL DRP Settings:\n   The following TCL commands are being added to give example calculations\
+    \n   for drp programming values for MMCME2 (7 series). For other architectures care\
+    \n   should be taken due to VCO and programming addresses. This script can be altered\
+    \n   to adjust for those differences but exact settings should be reviewed.\
+    \n\n   Also please note that this is a subset of the full programming options.\
+    \n   Fine phase shifting and dynamic phase shifting is not directly supported by\
+    \n   these scripts.\
+    \n\n      xapp888_drp_settings <CLKFBOUT_MULT>  <DIVCLK_DIVIDE> <PHASE> <BANDWIDTH>\
+    \n           - BANDWIDTH can be: LOW, LOW_SS, HIGH, OPTIMIZED (case insensitive). \
+    \n           - Displays & Returns the ordered pairs of DRP addresses & Data
+    \n      xapp888_drp_clkout <DIVIDE>  <Duty Cycle e.g. 0.5> <Phase e.g.11.25> <CLKOUT0 to CLKOUT6> \
+    \n           - Displays & Returns the ordered pairs of DRP addresses & Data
+    \n      xapp888_merge_drp_clkout <list>\
+    \n           - Returns the ordered DRP addresses/data merging fractional address 07 & 13
+    \n\n   For Example:\
+    \n\t   xapp888_drp_settings <m> <d> <phase> <bw>;\
+    \n\t   xapp888_drp_clkout <div> <dc> <phase> clkout0;\
+    \n\t   xapp888_drp_clkout <div> <dc> <phase> clkout1;\
+    \n\t   xapp888_drp_clkout <div> <dc> <phase> clkout2;\
+    \n\t   xapp888_drp_clkout <div> <dc> <phase> clkout3;\
+    \n\t   xapp888_drp_clkout <div> <dc> <phase> clkout4;\
+    \n\t   xapp888_drp_clkout <div> <dc> <phase> clkout5;\
+    \n\t   xapp888_drp_clkout <div> <dc> <phase> clkout6;\
+    \n\n   To show how to use the xapp888_merg_drp command the following is an arbitrary example"
+    puts {          set drp "[xapp888_drp_settings 2.125 2 0 high]"}
+    puts {          set drp "$drp [xapp888_drp_clkout 3.75 0.5 90 clkout0]"}
+    puts {          for {set i 1} {$i <= 6} {incr i} {set drp "$drp [xapp888_drp_clkout 7 0.5 90 clkout$i]"} }
+    puts {          xapp888_merge_drp $drp}
+    puts "-----------------------------------------------------------------------------------------------"
+}
+xapp888_help

+ 385 - 0
sources_1/new/MMCM/top_mmcme2.v

@@ -0,0 +1,385 @@
+//------------------------------------------------------------------------------------------
+//   ____  ____
+//  /   /\/   /
+// /___/  \  /
+// \   \   \/    � Copyright 2019 Xilinx, Inc. All rights reserved.
+//  \   \        This file contains confidential and proprietary information of Xilinx, Inc.
+//  /   /        and is protected under U.S. and international copyright and other
+// /___/   /\    intellectual property laws.
+// \   \  /  \
+//  \___\/\___\
+//
+//-------------------------------------------------------------------------------------------
+// Device:              7-Series
+// Author:              Tatsukawa, Kruger, Defossez
+// Entity Name:         top_mmcme2
+// Purpose:             This is a basic demonstration of the MMCM_DRP
+//                      connectivity to the MMCM_ADV.
+// Tools:               Vivado_2019.1 or newer
+// Limitations:
+//
+// Vendor:              Xilinx Inc.
+// Version:             1.40
+// Filename:            top_mmcme2.v
+// Date Created:        30-Jul-2014
+// Date Last Modified:  25-Jun-2019
+//-------------------------------------------------------------------------------------------
+// Disclaimer:
+//		This disclaimer is not a license and does not grant any rights to the materials
+//		distributed herewith. Except as otherwise provided in a valid license issued to you
+//		by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE MATERIALS
+//		ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL
+//		WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED
+//		TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR
+//		PURPOSE; and (2) Xilinx shall not be liable (whether in contract or tort, including
+//		negligence, or under any other theory of liability) for any loss or damage of any
+//		kind or nature related to, arising under or in connection with these materials,
+//		including for any direct, or any indirect, special, incidental, or consequential
+//		loss or damage (including loss of data, profits, goodwill, or any type of loss or
+//		damage suffered as a result of any action brought by a third party) even if such
+//		damage or loss was reasonably foreseeable or Xilinx had been advised of the
+//		possibility of the same.
+//
+// CRITICAL APPLICATIONS
+//		Xilinx products are not designed or intended to be fail-safe, or for use in any
+//		application requiring fail-safe performance, such as life-support or safety devices
+//		or systems, Class III medical devices, nuclear facilities, applications related to
+//		the deployment of airbags, or any other applications that could lead to death,
+//		personal injury, or severe property or environmental damage (individually and
+//		collectively, "Critical Applications"). Customer assumes the sole risk and
+//		liability of any use of Xilinx products in Critical Applications, subject only to
+//		applicable laws and regulations governing limitations on product liability.
+//
+// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
+//
+// Contact:    e-mail  hotline@xilinx.com        phone   + 1 800 255 7778
+//-------------------------------------------------------------------------------------------
+// Revision History:
+//  Rev: 30-Apr-2014 - Tatsukawa
+//      Initial code release
+//  Rev: 25-Jun-2019 - Defossez
+//      Add possibility to register the LOCKED signal.
+//-------------------------------------------------------------------------------------------
+//
+`timescale 1ps/1ps
+//
+//-------------------------------------------------------------------------------------------
+// Entity pin description
+//-------------------------------------------------------------------------------------------
+// Inputs
+//      SSTEP:      Start a reconfiguration. It should only be pulsed for one clock cycle.
+//      STATE:      Determines which state the MMCM_ADV will be reconfigured to. A value
+//                  of 0 correlates to state 1, and a value of 1 correlates to state 2.
+//      RST:        RST will reset the entire reference design including the MMCM_ADV.
+//      CLKIN:      Clock for the MMCM_ADV CLKIN as well as the clock for the MMCM_DRP module
+//      SRDY:       Pulses for one clock cycle after the MMCM_ADV is locked and the
+//                  MMCM_DRP module is ready to start another re-configuration.
+// Outputs
+//      LOCKED_OUT: MMCM is locked after configuration or reconfiguration.
+//      CLK0OUT:    These are the clock outputs from the MMCM_ADV.
+//      CLK1OUT:    These are the clock outputs from the MMCM_ADV.
+//      CLK2OUT:    These are the clock outputs from the MMCM_ADV.
+//      CLK3OUT:    These are the clock outputs from the MMCM_ADV.
+//      CLK4OUT:    These are the clock outputs from the MMCM_ADV.
+//      CLK5OUT:    These are the clock outputs from the MMCM_ADV.
+//      CLK6OUT:    These are the clock outputs from the MMCM_ADV.
+//-------------------------------------------------------------------------------------------
+module top_mmcme2
+    (
+        input    SSTEP,
+        input    STATE,
+        input    RST,
+        input    CLKIN,
+        output   SRDY,
+ 		output 	 LOCKED_OUT,
+        output   CLK0OUT,
+        output   CLK1OUT,
+        output   CLK2OUT,
+        output   CLK3OUT,
+        output   CLK4OUT,
+        output   CLK5OUT,
+        output   CLK6OUT
+    );
+//-------------------------------------------------------------------------------------------
+// These signals are used as direct connections between the MMCM_ADV and the
+// MMCM_DRP.
+(* mark_debug = "true" *) wire [15:0]    di;
+(* mark_debug = "true" *) wire [6:0]     daddr;
+(* mark_debug = "true" *) wire [15:0]    dout;
+(* mark_debug = "true" *) wire           den;
+(* mark_debug = "true" *) wire           dwe;
+wire            dclk;
+wire            rst_mmcm;
+wire            drdy;
+reg				current_state;
+reg [7:0]		sstep_int ;
+reg				init_drp_state = 1;
+// These signals are used for the BUFG's necessary for the design.
+wire            CLKIN_ibuf;
+wire            clkin_bufgout;
+wire            clkfb_bufgout;
+wire            clkfb_bufgin;
+wire            clk0_bufgin;
+wire            clk0_bufgout;
+wire            clk1_bufgin;
+wire            clk1_bufgout;
+wire            clk2_bufgin;
+wire            clk2_bufgout;
+wire            clk3_bufgin;
+wire            clk3_bufgout;
+wire            clk4_bufgin;
+wire            clk4_bufgout;
+wire            clk5_bufgin;
+wire            clk5_bufgout;
+wire            clk6_bufgin;
+wire            clk6_bufgout;
+wire            LOCKED;
+//-------------------------------------------------------------------------------------------
+assign CLKIN_ibuf = CLKIN;
+//
+BUFG BUFG_IN    (.O (clkin_bufgout),    .I (CLKIN_ibuf));
+BUFG BUFG_FB    (.O (clkfb_bufgout),    .I (clkfb_bufgin));
+BUFG BUFG_CLK0  (.O (clk0_bufgout),     .I (clk0_bufgin));
+BUFG BUFG_CLK1  (.O (clk1_bufgout),     .I (clk1_bufgin));
+BUFG BUFG_CLK2  (.O (clk2_bufgout),     .I (clk2_bufgin));
+BUFG BUFG_CLK3  (.O (clk3_bufgout),     .I (clk3_bufgin));
+BUFG BUFG_CLK4  (.O (clk4_bufgout),     .I (clk4_bufgin));
+BUFG BUFG_CLK5  (.O (clk5_bufgout),     .I (clk5_bufgin));
+BUFG BUFG_CLK6  (.O (clk6_bufgout),     .I (clk6_bufgin));
+//
+// ODDR registers used to output clocks
+ODDR ODDR_CLK0 (.Q(CLK0OUT), .C(clk0_bufgout), .CE(1'b1), .D1(1'b1), .D2(1'b0), .R(RST), .S(1'b0));
+ODDR ODDR_CLK1 (.Q(CLK1OUT), .C(clk1_bufgout), .CE(1'b1), .D1(1'b1), .D2(1'b0), .R(RST), .S(1'b0));
+ODDR ODDR_CLK2 (.Q(CLK2OUT), .C(clk2_bufgout), .CE(1'b1), .D1(1'b1), .D2(1'b0), .R(RST), .S(1'b0));
+ODDR ODDR_CLK3 (.Q(CLK3OUT), .C(clk3_bufgout), .CE(1'b1), .D1(1'b1), .D2(1'b0), .R(RST), .S(1'b0));
+ODDR ODDR_CLK4 (.Q(CLK4OUT), .C(clk4_bufgout), .CE(1'b1), .D1(1'b1), .D2(1'b0), .R(RST), .S(1'b0));
+ODDR ODDR_CLK5 (.Q(CLK5OUT), .C(clk5_bufgout), .CE(1'b1), .D1(1'b1), .D2(1'b0), .R(RST), .S(1'b0));
+ODDR ODDR_CLK6 (.Q(CLK6OUT), .C(clk6_bufgout), .CE(1'b1), .D1(1'b1), .D2(1'b0), .R(RST), .S(1'b0));
+//
+// MMCM_ADV that reconfiguration will take place on
+//
+//  BANDWIDTH:              : "HIGH", "LOW" or "OPTIMIZED"
+//  DIVCLK_DIVIDE           : Value from 1 to 106
+//  CLKFBOUT_MULT_F         : Value from 2 to 64
+//  CLKFBOUT_PHASE          :
+//  CLKFBOUT_USE_FINE_PS    : "TRUE" or "FALSE",
+//  CLKIN1_PERIOD           : Value from 0.968 to 100.000. Set the period (ns) of input clocks
+//  REF_JITTER1             :
+//  CLKIN2_PERIOD           :
+//  REF_JITTER2             :
+//  CLKOUT parameters:
+//  DIVIDE                  : Value from 1 to 128
+//  DUTY_CYCLE              : 0.01 to 0.99 - This is dependent on the divide value.
+//  PHASE                   : 0.0 to 360.0 - This is dependent on the divide value.
+//  USE_FINE_PS             : TRUE or FALSE
+//  Misc parameters
+//  COMPENSATION
+//  STARTUP_WAIT
+//
+MMCME2_ADV #(
+   .BANDWIDTH           ("OPTIMIZED"),
+   .DIVCLK_DIVIDE       (1),
+   .CLKFBOUT_MULT_F     (6),
+   .CLKFBOUT_PHASE      (0.0),
+   .CLKFBOUT_USE_FINE_PS("FALSE"),
+   .CLKIN1_PERIOD       (10.000),
+   .REF_JITTER1         (0.010),
+   .CLKIN2_PERIOD       (10.000),
+   .REF_JITTER2         (0.010),
+   .CLKOUT0_DIVIDE_F    (6),
+   .CLKOUT0_DUTY_CYCLE  (0.5),
+   .CLKOUT0_PHASE       (0.0),
+   .CLKOUT0_USE_FINE_PS ("FALSE"),
+   .CLKOUT1_DIVIDE      (6),
+   .CLKOUT1_DUTY_CYCLE  (0.5),
+   .CLKOUT1_PHASE       (0.0),
+   .CLKOUT1_USE_FINE_PS ("FALSE"),
+   .CLKOUT2_DIVIDE      (6),
+   .CLKOUT2_DUTY_CYCLE  (0.5),
+   .CLKOUT2_PHASE       (0.0),
+   .CLKOUT2_USE_FINE_PS ("FALSE"),
+   .CLKOUT3_DIVIDE      (6),
+   .CLKOUT3_DUTY_CYCLE  (0.5),
+   .CLKOUT3_PHASE       (0.0),
+   .CLKOUT3_USE_FINE_PS ("FALSE"),
+   .CLKOUT4_DIVIDE      (6),
+   .CLKOUT4_DUTY_CYCLE  (0.5),
+   .CLKOUT4_PHASE       (0.0),
+   .CLKOUT4_USE_FINE_PS ("FALSE"),
+   .CLKOUT4_CASCADE     ("FALSE"),
+   .CLKOUT5_DIVIDE      (6),
+   .CLKOUT5_DUTY_CYCLE  (0.5),
+   .CLKOUT5_PHASE       (0.0),
+   .CLKOUT5_USE_FINE_PS ("FALSE"),
+   .CLKOUT6_DIVIDE      (6),
+   .CLKOUT6_DUTY_CYCLE  (0.5),
+   .CLKOUT6_PHASE       (0.0),
+   .CLKOUT6_USE_FINE_PS ("FALSE"),
+   .COMPENSATION        ("ZHOLD"),
+   .STARTUP_WAIT        ("FALSE")
+) mmcme2_test_inst (
+   .CLKFBOUT            (clkfb_bufgin),
+   .CLKFBOUTB           (),
+   .CLKFBSTOPPED        (),
+   .CLKINSTOPPED        (),
+   .CLKOUT0             (clk0_bufgin),
+   .CLKOUT0B            (),
+   .CLKOUT1             (clk1_bufgin),
+   .CLKOUT1B            (),
+   .CLKOUT2             (clk2_bufgin),
+   .CLKOUT2B            (),
+   .CLKOUT3             (clk3_bufgin),
+   .CLKOUT3B            (),
+   .CLKOUT4             (clk4_bufgin),
+   .CLKOUT5             (clk5_bufgin),
+   .CLKOUT6             (clk6_bufgin),
+   .DO                  (dout),
+   .DRDY                (drdy),
+   .DADDR               (daddr),
+   .DCLK                (dclk),
+   .DEN                 (den),
+   .DI                  (di),
+   .DWE                 (dwe),
+   .LOCKED              (LOCKED),
+   .CLKFBIN             (clkfb_bufgout),
+   .CLKIN1              (clkin_bufgout),
+   .CLKIN2              (),
+   .CLKINSEL            (1'b1),
+   .PSDONE              (),
+   .PSCLK               (1'b0),
+   .PSEN                (1'b0),
+   .PSINCDEC            (1'b0),
+   .PWRDWN              (1'b0),
+   .RST                 (rst_mmcm)
+);
+// MMCM_DRP instance that will perform the reconfiguration operations
+mmcme2_drp #(
+    // Register the LOCKED signal with teh MMCME3_ADV input clock.
+    // The LOCKED_IN (LOCKED from the MMCME3_ADV) is fed into a register and then
+    // passed the LOCKED_OUT when REGISTER_LOCKED is set to "Reg" or when set to
+    // "NoReg" LOCKED_IN is just passed on to LOCKED_OUT without being registered.
+    .REGISTER_LOCKED       ("Reg"),
+    // Use the registered LOCKED signal from the MMCME3 also for the DRP state machine.
+    .USE_REG_LOCKED        ("No"),
+    // Possible combination of above two parameters:
+    // | REGISTER_LOCKED | USE_REG_LOCKED |                                            |
+    // |-----------------|----------------|--------------------------------------------|
+    // |      "NoReg"    |     "No"       | LOCKED is just passed through mmcme3_drp   |
+    // |                 |                | and is used as is with the state machine   |
+    // |      "NoReg"    |     "Yes"      | NOT ALLOWED                                |
+    // |       "Reg"     |     "No"       | LOCKED is registered but the unregistered  |
+    // |                 |                | version is used for the state machine.     |
+    // |       "Reg"     |     "Yes"      | LOCKED is registered and the registered    |
+    // |                 |                | version is also used by the state machine. |
+    //
+    //***********************************************************************
+    // State 1 Parameters - These are for the first reconfiguration state.
+    //***********************************************************************
+    // Set the multiply to 6.0 with 0 deg phase offset, optimized bandwidth, input divide of 1
+    .S1_CLKFBOUT_MULT(6),
+    .S1_CLKFBOUT_PHASE(000_000),
+    .S1_CLKFBOUT_FRAC(000),
+    .S1_CLKFBOUT_FRAC_EN(0),
+    .S1_BANDWIDTH("OPTIMIZED"),
+    .S1_DIVCLK_DIVIDE(1),
+    // Set clockout0 to a divide of 6.0 (unity gain), 0 deg phase offset, 50/50 duty cycle
+    .S1_CLKOUT0_DIVIDE(6),
+    .S1_CLKOUT0_PHASE(000_000),
+    .S1_CLKOUT0_DUTY(50000),
+    .S1_CLKOUT0_FRAC(000),
+    .S1_CLKOUT0_FRAC_EN(0),
+    // Set clockout 1 to a divide of 1, 0 deg phase offset, 50/50 duty cycle
+    .S1_CLKOUT1_DIVIDE(1),
+    .S1_CLKOUT1_PHASE(000_000),
+    .S1_CLKOUT1_DUTY(50000),
+    // Set clockout 2 to a divide of 2, 0 deg phase offset, 50/50 duty cycle
+    .S1_CLKOUT2_DIVIDE(2),
+    .S1_CLKOUT2_PHASE(000_000),
+    .S1_CLKOUT2_DUTY(50000),
+    // Set clockout 3 to a divide of 3, 0 deg phase offset, 50/50 duty cycle
+    .S1_CLKOUT3_DIVIDE(3),
+    .S1_CLKOUT3_PHASE(000_000),
+    .S1_CLKOUT3_DUTY(50000),
+    // Set clockout 4 to a divide of 4, 0 deg phase offset, 50/50 duty cycle
+    .S1_CLKOUT4_DIVIDE(4),
+    .S1_CLKOUT4_PHASE(000_000),
+    .S1_CLKOUT4_DUTY(50000),
+    // Set clockout 5 to a divide of 5, 0 deg phase offset, 50/50 duty cycle
+    .S1_CLKOUT5_DIVIDE(5),
+    .S1_CLKOUT5_PHASE(000_000),
+    .S1_CLKOUT5_DUTY(50000),
+    // Set clockout 6 to a divide of 10, 0 deg phase offset, 50/50 duty cycle
+    .S1_CLKOUT6_DIVIDE(10),
+    .S1_CLKOUT6_PHASE(000_000),
+    .S1_CLKOUT6_DUTY(50000),
+    //***********************************************************************
+    // State 2 Parameters - These are for the second reconfiguration state.
+    //***********************************************************************
+    .S2_CLKFBOUT_MULT(7),
+    .S2_CLKFBOUT_PHASE(000_000),
+    .S2_CLKFBOUT_FRAC(000),
+    .S2_CLKFBOUT_FRAC_EN(0),
+    .S2_BANDWIDTH("OPTIMIZED"),
+    .S2_DIVCLK_DIVIDE(1),
+    // Set clockout 0 to a divide of 4.750, 0 deg phase offset, 50/50 duty cycle
+    .S2_CLKOUT0_DIVIDE(7),
+    .S2_CLKOUT0_PHASE(000_000),
+    .S2_CLKOUT0_DUTY(50000),
+    .S2_CLKOUT0_FRAC(000),
+    .S2_CLKOUT0_FRAC_EN(0),
+    // Set clockout 1 to a divide of 1, 45.0 deg phase offset, 50/50 duty cycle
+    .S2_CLKOUT1_DIVIDE(1),
+    .S2_CLKOUT1_PHASE(045_000),
+    .S2_CLKOUT1_DUTY(50000),
+    // Set clock out 0 to a divide of 1, 90.0 deg phase offset, 50/50 duty cycle
+    .S2_CLKOUT2_DIVIDE(1),
+    .S2_CLKOUT2_PHASE(090_000),
+    .S2_CLKOUT2_DUTY(90000),
+    // Set clockout3 to a divide of 1, 135.0 deg phase offset, 50/50 duty cycle
+    .S2_CLKOUT3_DIVIDE(1),
+    .S2_CLKOUT3_PHASE(135_000),
+    .S2_CLKOUT3_DUTY(50000),
+    // Set clockout4 to a divide of 1, 180.0 deg phase offset, 50/50 duty cycle
+    .S2_CLKOUT4_DIVIDE(1),
+    .S2_CLKOUT4_PHASE(180_000),
+    .S2_CLKOUT4_DUTY(50000),
+    // Set clockout5 to a divide of 1, 225.0 deg phase offset, 50/50 duty cycle
+    .S2_CLKOUT5_DIVIDE(1),
+    .S2_CLKOUT5_PHASE(225_000),
+    .S2_CLKOUT5_DUTY(50000),
+    // Set clockout6 to a divide of 1, 270.0 deg phase offset, 50/50 duty cycle
+    .S2_CLKOUT6_DIVIDE(1),
+    .S2_CLKOUT6_PHASE(270_000),
+    .S2_CLKOUT6_DUTY(50000)
+) mmcme2_drp_inst (
+    .SADDR              (STATE),
+    .SEN                (sstep_int[0]),
+    .RST                (RST),
+    .SRDY               (SRDY),
+    .SCLK               (clkin_bufgout),
+    .DO                 (dout),
+    .DRDY               (drdy),
+    .LOCK_REG_CLK_IN    (clkin_bufgout),
+    .LOCKED_IN          (LOCKED),
+    .DWE                (dwe),
+    .DEN                (den),
+    .DADDR              (daddr),
+    .DI                 (di),
+    .DCLK               (dclk),
+    .RST_MMCM           (rst_mmcm),
+    .LOCKED_OUT         (LOCKED_OUT)
+);
+   //***********************************************************************
+   // Additional STATE and SSTEP logic for push buttons and switches
+   //***********************************************************************
+// The following logic is not required but is being used to allow the DRP
+// circuitry work more effectively with boards that use toggle switches or
+// buttons that may not adhere to the single clock requirement.
+//
+// Only start DRP after initial lock and when STATE has changed
+always @ (posedge clkin_bufgout or posedge SSTEP)
+    if (SSTEP) sstep_int <=  8'h80;
+    else sstep_int <= {1'b0, sstep_int[7:1]};
+//
+//-------------------------------------------------------------------------------------------
+endmodule

+ 2 - 0
sources_1/new/MMCM/top_mmcme2.xdc

@@ -0,0 +1,2 @@
+create_clock -period 10.000 -name CLKIN -waveform {0.000 5.000} [get_ports CLKIN]
+

+ 140 - 0
sources_1/new/MMCM/top_mmcme2_tb.v

@@ -0,0 +1,140 @@
+//------------------------------------------------------------------------------------------
+//   ____  ____
+//  /   /\/   /
+// /___/  \  /
+// \   \   \/    � Copyright 2019 Xilinx, Inc. All rights reserved.
+//  \   \        This file contains confidential and proprietary information of Xilinx, Inc.
+//  /   /        and is protected under U.S. and international copyright and other
+// /___/   /\    intellectual property laws.
+// \   \  /  \
+//  \___\/\___\
+//
+//-------------------------------------------------------------------------------------------
+// Device:              7-Series
+// Author:              Tatsukawa, Defossez
+// Entity Name:         top_mmcme2_tb
+// Purpose:            This is a basic demonstration that drives the MMCM_DRP
+//                      ports to trigger two reconfiguration events, one for
+//                      each state.
+// Tools:               QuestaSim_10.7d or newer
+// Limitations:
+//
+// Vendor:              Xilinx Inc.
+// Version:             0.01
+// Filename:            top_mmcme2_tb.v
+// Date Created:        30-Jul-2014
+// Date Last Modified:  26-Jun-2019
+//-------------------------------------------------------------------------------------------
+// Disclaimer:
+//        This disclaimer is not a license and does not grant any rights to the materials
+//        distributed herewith. Except as otherwise provided in a valid license issued to you
+//        by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE MATERIALS
+//        ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL
+//        WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED
+//        TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR
+//        PURPOSE; and (2) Xilinx shall not be liable (whether in contract or tort, including
+//        negligence, or under any other theory of liability) for any loss or damage of any
+//        kind or nature related to, arising under or in connection with these materials,
+//        including for any direct, or any indirect, special, incidental, or consequential
+//        loss or damage (including loss of data, profits, goodwill, or any type of loss or
+//        damage suffered as a result of any action brought by a third party) even if such
+//        damage or loss was reasonably foreseeable or Xilinx had been advised of the
+//        possibility of the same.
+//
+// CRITICAL APPLICATIONS
+//        Xilinx products are not designed or intended to be fail-safe, or for use in any
+//        application requiring fail-safe performance, such as life-support or safety devices
+//        or systems, Class III medical devices, nuclear facilities, applications related to
+//        the deployment of airbags, or any other applications that could lead to death,
+//        personal injury, or severe property or environmental damage (individually and
+//        collectively, "Critical Applications"). Customer assumes the sole risk and
+//        liability of any use of Xilinx products in Critical Applications, subject only to
+//        applicable laws and regulations governing limitations on product liability.
+//
+// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
+//
+// Contact:    e-mail  hotline@xilinx.com        phone   + 1 800 255 7778
+//-------------------------------------------------------------------------------------------
+// Revision History:
+//  Rev: 30-Jul-20149 - Tatsukawa
+//      Initial version of this design - source code.
+//  Rev: 26-Jun-2019 - Defossez
+//      Make sure the simulation works after modifications to the design.
+//-------------------------------------------------------------------------------------------
+//
+`timescale 1ps / 1ps
+//-------------------------------------------------------------------------------------------
+module top_tb  ();
+    reg SSTEP, RST, CLKin, STATE;
+    wire SRDY, clk0out, clk1out, clk2out, clk3out, clk4out, clk5out, clk6out;
+//-------------------------------------------------------------------------------------------
+    top_mmcme2 U1
+    (
+        .SSTEP      (SSTEP),
+        .STATE      (STATE),
+        .RST        (RST),
+        .CLKIN      (CLKin),
+        .SRDY       (SRDY),
+        .LOCKED_OUT (locked),
+        .CLK0OUT    (clk0out),
+        .CLK1OUT    (clk1out),
+        .CLK2OUT    (clk2out),
+        .CLK3OUT    (clk3out),
+        .CLK4OUT    (clk4out),
+        .CLK5OUT    (clk5out),
+        .CLK6OUT    (clk6out)
+    );
+//-------------------------------------------------------------------------------------------
+    localparam one_ns = 1000;
+    localparam clock_period = 10;
+    parameter [1:0]    STARTUP = 0, STATE0 = 1, STATE1 = 2, UNDEFINED = 3;
+    reg [1:0] SM = STARTUP ;
+
+always @ (posedge CLKin)
+    begin
+        if (RST)
+               SM = STARTUP;
+        else
+            case (SM)
+                STARTUP:
+                    begin
+                        SM = STATE0;
+                        SSTEP=1'b0;
+                        STATE=1'b0;
+                    end
+                STATE0:
+                    begin
+                        if (locked == 1 )
+                            begin
+                                #(1 * clock_period * one_ns) SSTEP= 1'b1;
+                                #(1 * clock_period * one_ns) SSTEP=1'b0;
+                                #(100 * clock_period * one_ns) SM = STATE1 ;
+                                STATE=1'b1;
+                            end
+                    end
+                STATE1:
+                    begin
+                        if (locked == 1 )
+                            begin
+                                #(1 * clock_period * one_ns) SSTEP= 1'b1;
+                                #(1 * clock_period * one_ns) SSTEP=1'b0;
+                                #(100 * clock_period * one_ns) SM = STATE0;
+                                STATE=1'b0;
+                            end
+                    end
+                UNDEFINED:   SM= STARTUP;
+            endcase
+        end
+//
+    initial
+        begin
+                CLKin = 0;
+                RST = 1;
+                #50000 RST = 0;
+        end
+    always
+        # (clock_period * one_ns / 2) CLKin = ~CLKin;
+//
+//-------------------------------------------------------------------------------------------
+endmodule
+//

+ 30 - 0
sources_1/new/RstSync/RstSync.v

@@ -0,0 +1,30 @@
+
+module RstSync 
+(
+    input	Clk_i,
+    input	Rst_i,
+
+	output	Rst_o
+);
+//================================================================================
+//	REG/WIRE
+//================================================================================
+	reg	rstReg0;
+	reg	rstReg1;
+//================================================================================
+//	ASSIGNMENTS
+//================================================================================
+	assign	Rst_o	=	rstReg1;
+//================================================================================
+//	LOCALPARAMS
+//================================================================================
+
+//================================================================================
+//	CODING
+//================================================================================
+
+always	@(posedge	Clk_i)	begin
+	rstReg0	<=	Rst_i;
+	rstReg1	<=	rstReg0;
+end
+endmodule

+ 63 - 100
sources_1/new/S5443_3Top.v

@@ -28,13 +28,16 @@ module S5443_3Top #(
 
 )(
     input Clk123_i,
-    input [AddrRegWidth-2:0] Addr_i,
-    inout [CmdRegWidth/2-1:0] Data_i,
+    input [AddrRegWidth-2:0] SmcAddr_i,
+    inout [CmdRegWidth/2-1:0] SmcData_i,
     
-    input writeEn_i,
-    input readEn_i,
-    input [1:0] BE_i,
-    input outputEn_i,
+    input SmcAwe_i,
+    input SmcAmsN_i,
+	
+    input SmcAre_i,
+    // input DspRst_i,
+    input [1:0] SmcBe_i,
+    input SmcAoe_i,
     output [SpiNum-1:0] LD_i,
 
     output  Led_o,
@@ -44,7 +47,6 @@ module S5443_3Top #(
     output  [SpiNum-1:0] Mosi2_o,
     output  [SpiNum-1:0] Mosi3_o,
     output  [SpiNum-1:0] Ss_o,
-    output  [SpiNum-1:0] SsFlash_o,
     output  [SpiNum-1:0] Sck_o,
     output  [SpiNum-1:0] SpiRst_o,
     output  LD_o
@@ -161,37 +163,23 @@ wire [SpiNum-1:0] FifoTxRst;
 wire [0:7]  WordCntTx [SpiNum-1:0];
 wire [0:7]  WordCntRx [SpiNum-1:0];
 
-wire [SpiNum-1:0] CS0;
-wire [SpiNum-1:0] CS1;
-
-wire [SpiNum-1:0] Assel;
-
-
+wire	[SpiNum-1:0]	spiClkBus;
+wire	[SpiNum-1:0]	spiSyncRst;
 
+wire	[AddrRegWidth-1:0]	smcAddr;
+wire	[CmdRegWidth-1:0]	smcData;
+wire	smcVal;
+	
 //================================================================================
 //  ASSIGNMENTS
 //================================================================================
-assign addr = {Addr_i, 1'b0};
-assign Data_i = (!outputEn_i) ? data : 16'bz;
+assign Data_i = (!SmcAoe_i) ? data : 16'bz;
 assign ten = SpiTxRxEn[6:0];
 assign Mosi0_o = Mosi0;
 assign Mosi1_o = Mosi1;
 assign Mosi2_o = Mosi2;
 assign Mosi3_o = Mosi3;
-assign Ss_o[0] = (Assel[0])? ((CS0[0])? Ss[0]:~Ss[0]):CS0[0];
-assign Ss_o[1] = (Assel[1])? ((CS0[1])? Ss[1]:~Ss[1]):CS0[1];
-assign Ss_o[2] = (Assel[2])? ((CS0[2])? Ss[2]:~Ss[2]):CS0[2];
-assign Ss_o[3] = (Assel[3])? ((CS0[3])? Ss[3]:~Ss[3]):CS0[3];
-assign Ss_o[4] = (Assel[4])? ((CS0[4])? Ss[4]:~Ss[4]):CS0[4];
-assign Ss_o[5] = (Assel[5])? ((CS0[5])? Ss[5]:~Ss[5]):CS0[5];
-assign Ss_o[6] = (Assel[6])? ((CS0[6])? Ss[6]:~Ss[6]):CS0[6];
-assign SsFlash_o[0] = (Assel[0])?(CS1[0]? Ss[0]:~Ss[0]):CS1[0];
-assign SsFlash_o[1] = (Assel[1])?(CS1[1]? Ss[1]:~Ss[1]):CS1[1];
-assign SsFlash_o[2] = (Assel[2])?(CS1[2]? Ss[2]:~Ss[2]):CS1[2];
-assign SsFlash_o[3] = (Assel[3])?(CS1[3]? Ss[3]:~Ss[3]):CS1[3];
-assign SsFlash_o[4] = (Assel[4])?(CS1[4]? Ss[4]:~Ss[4]):CS1[4];
-assign SsFlash_o[5] = (Assel[5])?(CS1[5]? Ss[5]:~Ss[5]):CS1[5];
-assign SsFlash_o[6] = (Assel[6])?(CS1[6]? Ss[6]:~Ss[6]):CS1[6];
+assign Ss_o = Ss;
 assign Sck_o = Sck;
 
 assign widthSel[0] = Spi0Ctrl[6:5];
@@ -234,15 +222,6 @@ assign selSt[4] = Spi4Ctrl[4];
 assign selSt[5] = Spi5Ctrl[4];
 assign selSt[6] = Spi6Ctrl[4];
 
-assign Assel[0] = Spi0Ctrl[3];
-assign Assel[1] = Spi1Ctrl[3];
-assign Assel[2] = Spi2Ctrl[3];
-assign Assel[3] = Spi3Ctrl[3];
-assign Assel[4] = Spi4Ctrl[3];
-assign Assel[5] = Spi5Ctrl[3];
-assign Assel[6] = Spi6Ctrl[3];
-
-
 assign stopDelay[0] = Spi0CsDelay[7:2];
 assign stopDelay[1] = Spi1CsDelay[7:2];
 assign stopDelay[2] = Spi2CsDelay[7:2];
@@ -325,25 +304,6 @@ assign WordCntTx[4] = Spi4TxFifoCtrl[15:8];
 assign WordCntTx[5] = Spi5TxFifoCtrl[15:8];
 assign WordCntTx[6] = Spi6TxFifoCtrl[15:8];
 
-assign CS0[0] = Spi0CsCtrl[0];
-assign CS0[1] = Spi1CsCtrl[0];
-assign CS0[2] = Spi2CsCtrl[0];
-assign CS0[3] = Spi3CsCtrl[0];
-assign CS0[4] = Spi4CsCtrl[0];
-assign CS0[5] = Spi5CsCtrl[0];
-assign CS0[6] = Spi6CsCtrl[0];
-
-assign CS1[0] = Spi0CsCtrl[1];
-assign CS1[1] = Spi1CsCtrl[1];
-assign CS1[2] = Spi2CsCtrl[1];
-assign CS1[3] = Spi3CsCtrl[1];
-assign CS1[4] = Spi4CsCtrl[1];
-assign CS1[5] = Spi5CsCtrl[1];
-assign CS1[6] = Spi6CsCtrl[1];
-
-
-
-
 
 //================================================================================
 //  CODING
@@ -354,44 +314,33 @@ BUFG BUFG_inst (
    .I(Clk123_i)  // 1-bit input: Clock input
 );
 
-
- clk_wiz_0 ClkGen
-   (
-   .s_axi_aclk      (),        // input s_axi_aclk                        
-   .s_axi_aresetn   (),     // input s_axi_aresetn,                                                          
-   .s_axi_awaddr    (),      // input [10 : 0] s_axi_awaddr,                              
-   .s_axi_awvalid   (),     // input s_axi_awvalid,                                                          
-   .s_axi_awready   (),     // output s_axi_awready,                                                         
-   .s_axi_wdata     (),       // input [31 : 0] s_axi_wdata,                             
-   .s_axi_wstrb     (),       // input [3 : 0] s_axi_wstrb,                         
-   .s_axi_wvalid    (),      // input s_axi_wvalid,                                                         
-   .s_axi_wready    (),      // output s_axi_wready,                                                        
-   .s_axi_bresp     (),       // output [1 : 0] s_axi_bresp,                                               
-   .s_axi_bvalid    (),      // output s_axi_bvalid,                                                        
-   .s_axi_bready    (),      // input s_axi_bready,                                                         
-   .s_axi_araddr    (),      // input [10 : 0] s_axi_araddr,                              
-   .s_axi_arvalid   (),     // input s_axi_arvalid,                                                          
-   .s_axi_arready   (),     // output s_axi_arready,                                                         
-   .s_axi_rdata     (),       // output [31 : 0] s_axi_rdata,                            
-   .s_axi_rresp     (),       // output [1 : 0] s_axi_rresp,                                               
-   .s_axi_rvalid    (),      // output s_axi_rvalid,                                                        
-   .s_axi_rready    (),      // input s_axi_rready,                                                         
-    // Clock out ports
-    .clk_out1(Clk100_i),     // output clk_out1
-    // .clk_out2(clk61),     // output clk_out2
-    // Status and control signals
-    .locked(),       // output locked
-   // Clock in ports
-    .clk_in1(gclk));      // input clk_in1
+SmcRx	SmcRx
+(
+	.Clk_i		(gclk),
+	.RstN_i		(!initRst),
+	.ForceRstN_i(1'b0),
+
+	.SmcD_i		(SmcD_i),
+	.SmcA_i		(SmcA_i),
+	.SmcAwe_i	(SmcAwe_i),
+	.SmcAmsN_i	(SmcAmsN_i),
+	.SmcAoe_i	(SmcAoe_i),
+	.SmcAre_i	(SmcAre_i),
+	.SmcBe_i	(SmcBe_i),
+	
+	.Data_o		(smcData),
+	.Addr_o		(smcAddr),
+	.Val_o		(smcVal)
+);
 
 SmcDataMux SmcDataMuxer
 (
     .Clk_i	(gclk),
     .Rst_i	(initRst),
 
-	.SmcVal_i	(1'b1),
-	.SmcData_i	({Data_i,Data_i}),
-    .SmcAddr_i	({Addr_i,1'b0}),
+	.SmcVal_i	(smcVal),
+	.SmcData_i	(smcData),
+    .SmcAddr_i	({smcAddr,1'b0}),
 
 	.ToRegMapVal_o	(toRegMapVal),
 	.ToRegMapData_o	(toRegMapData),
@@ -402,7 +351,6 @@ SmcDataMux SmcDataMuxer
 	
 );
 
-
 RegMap #(
     .CmdRegWidth(32),
     .AddrRegWidth(12)
@@ -412,9 +360,9 @@ RegMap_inst (
     .Rst_i(initRst),
     .Data_i(toRegMapData),
     .Addr_i(toRegMapAddr),
-    .wrEn_i(writeEn_i|toRegMapVal),
-    .rdEn_i(readEn_i),
-    .BE_i(BE_i),
+    .wrEn_i(SmcAwe_i|toRegMapVal),
+    .rdEn_i(SmcAre_i),
+    .SmcBe_i(SmcBe_i),
     .Led_o(Led_o),
     .AnsDataReg_o(data),
     //Spi0
@@ -486,20 +434,35 @@ RegMap_inst (
 
 );
 
+MmcmWrapper MainMmcm
+(
+	.Clk_i		(gclk),
+	.Rst_i		(initRst),
 
+	.SpiCLk_o	(spiClkBus)
+);
 
 
 genvar i;
 
 generate
     for  (i = 0; i < SpiNum; i = i + 1) begin: SpiGen
-	
-		DataFifoWrapper DataFifoWrapepr
+		
+		RstSync SpiRstSync
+		(
+			.Clk_i	(spiClkBus[i]),
+			.Rst_i	(initRst),
+
+			.Rst_o	(spiSyncRst[i])
+		);
+		
+		DataFifoWrapper DataFifoWrapper
 		(
 			.WrClk_i	(gclk),
-			.RdClk_i	(Clk100_i),
-			.Rst_i		(initRst | FifoRxRst[i]),
-            .readEn_i   (readEn_i),
+			.RdClk_i	(spiClkBus[i]),
+			// .Rst_i		(initRst | FifoRxRst[i]),
+			.Rst_i		(spiSyncRst[i] | FifoRxRst[i]),
+            .SmcAre_i   (SmcAre_i),
 	
 			.ToFifoVal_i	(toFifoVal[i]),
 			.ToFifoData_i	(toFifoData[32*i+:32]),
@@ -507,9 +470,9 @@ generate
 			.ToSpiVal_o		(toSpiVal[i]),
 			.ToSpiData_o	(toSpiData[i])
 		);
-	
+		
         QuadSPIm QuadSPIm_inst (
-            .Clk_i(Clk100_i),
+            .Clk_i(spiClkBus[i]),
             .Start_i(ten[i]),
             .Rst_i(initRst),
 			.SpiDataVal_i	(toSpiVal),