--- /dev/null
+// --------------------------------------------------------------------
+// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
+// --------------------------------------------------------------------
+// Copyright (c) 2007 by Lattice Semiconductor Corporation
+// --------------------------------------------------------------------
+//
+//
+// Lattice Semiconductor Corporation
+// 5555 NE Moore Court
+// Hillsboro, OR 97214
+// U.S.A.
+//
+// TEL: 1-800-Lattice (USA and Canada)
+// 1-408-826-6000 (other locations)
+//
+// web: http://www.latticesemi.com/
+// email: techsupport@latticesemi.com
+//
+// --------------------------------------------------------------------
+//
+// Simulation Library File for DDRDLLA in ECP5U/M, LIFMD
+//
+// $Header:
+//
+
+`celldefine
+`timescale 1 ns / 1 ps
+module DDRDLLA (CLK, RST, UDDCNTLN, FREEZE, DDRDEL, LOCK, DCNTL7, DCNTL6, DCNTL5, DCNTL4,
+ DCNTL3, DCNTL2, DCNTL1, DCNTL0);
+
+parameter FORCE_MAX_DELAY = "NO";
+parameter GSR = "ENABLED";
+
+parameter LOCK_CYC = 200;
+
+localparam PHASE_SHIFT = 90;
+input CLK, RST, UDDCNTLN, FREEZE;
+output LOCK, DDRDEL, DCNTL7, DCNTL6, DCNTL5, DCNTL4, DCNTL3, DCNTL2, DCNTL1, DCNTL0;
+
+wire RST_int, UDDCNTL_int, UDDCNTL_buf;
+reg LOCK_int, DDRDEL_int;
+wire clkin_in, FREEZEB, clkin_out;
+reg last_clkin_in, freeze_clk_sync, freeze_clk_sync2n;
+reg SRN, clock_valid;
+integer cntl_ratio;
+wire [7:0] cntl_reg;
+reg [7:0] cntl_reg_final;
+reg [7:0] cntl_reg_update;
+realtime next_clock_edge, last_clock_edge;
+realtime t_in_clk, t_in_clk1, t_in_clk2;
+realtime t_90, t_45, t_57, t_68, t_79;
+realtime t_101, t_112, t_123, t_135;
+realtime delta;
+
+initial
+begin
+ cntl_reg_update = 8'b000000;
+ cntl_ratio = 0;
+ delta = 0.025;
+ clock_valid = 1'b0;
+end
+
+// tri1 GSR_sig = GSR_INST.GSRNET;
+// tri1 PUR_sig = PUR_INST.PURNET;
+tri1 GSR_sig, PUR_sig;
+`ifndef mixed_hdl
+ assign GSR_sig = GSR_INST.GSRNET;
+ assign PUR_sig = PUR_INST.PURNET;
+`else
+ gsr_pur_assign gsr_pur_assign_inst (GSR_sig, PUR_sig);
+`endif
+
+buf buf_clkin (clkin_in, CLK);
+buf buf_rst (RSTB1, RST);
+buf buf_uddcntl (UDDCNTL_buf, UDDCNTLN);
+buf buf_freeze (FREEZEB, FREEZE);
+
+buf buf_lock (LOCK, LOCK_int);
+buf buf_ddrdel (DDRDEL, DDRDEL_int);
+buf U4 (DCNTL0, cntl_reg_final[0]);
+buf U5 (DCNTL1, cntl_reg_final[1]);
+buf U6 (DCNTL2, cntl_reg_final[2]);
+buf U7 (DCNTL3, cntl_reg_final[3]);
+buf U8 (DCNTL4, cntl_reg_final[4]);
+buf U9 (DCNTL5, cntl_reg_final[5]);
+buf U10 (DCNTL6, cntl_reg_final[6]);
+buf U11 (DCNTL7, cntl_reg_final[7]);
+
+integer clk_rising_edge_count;
+
+assign UDDCNTL_int = ~UDDCNTL_buf;
+
+initial
+begin
+ clk_rising_edge_count = 0;
+ freeze_clk_sync = 1'b0;
+ freeze_clk_sync2n = 1'b1;
+ last_clkin_in = 1'b0;
+end
+
+ always @ (GSR_sig or PUR_sig ) begin
+ if (GSR == "ENABLED")
+ SRN = GSR_sig & PUR_sig ;
+ else if (GSR == "DISABLED")
+ SRN = PUR_sig;
+ end
+
+ not (SR, SRN);
+ or INST1 (RST_int, RSTB1, SR);
+
+always @ (clkin_in)
+begin
+ last_clkin_in <= clkin_in;
+end
+
+always @ (clkin_in or RST_int) // neg edge
+begin
+ if (RST_int == 1'b1)
+ begin
+ freeze_clk_sync <= 1'b0;
+ freeze_clk_sync2n <= 1'b1;
+ end
+ else if (clkin_in === 1'b0 && last_clkin_in === 1'b1)
+ begin
+ freeze_clk_sync <= FREEZEB;
+ freeze_clk_sync2n <= ~freeze_clk_sync;
+ end
+end
+
+and INST2 (clkin_out, clkin_in, freeze_clk_sync2n);
+
+always @(posedge clkin_out or posedge RST_int)
+begin
+ if (RST_int)
+ clk_rising_edge_count = 0;
+ else
+ clk_rising_edge_count = clk_rising_edge_count + 1;
+end
+
+always @(clk_rising_edge_count or RST_int)
+begin
+ if (RST_int)
+ LOCK_int = 1'b0;
+ else if (clk_rising_edge_count > LOCK_CYC)
+ LOCK_int = 1'b1;
+end
+
+always @(LOCK_int or UDDCNTL_int or RST_int)
+begin
+ if (RST_int)
+ DDRDEL_int = 1'b0;
+ else if (UDDCNTL_int == 1'b1)
+ DDRDEL_int = LOCK_int;
+ else
+ DDRDEL_int = DDRDEL_int;
+end
+
+ always @(posedge clkin_in)
+ begin
+ last_clock_edge=next_clock_edge;
+ next_clock_edge=$realtime;
+
+ if (last_clock_edge > 0)
+ begin
+ t_in_clk <= next_clock_edge - last_clock_edge;
+ t_in_clk1 <= t_in_clk;
+ end
+
+ if (t_in_clk > 0)
+ begin
+ if ( ((t_in_clk - t_in_clk1) < 0.0001) && ((t_in_clk - t_in_clk1) > -0.0001))
+// if (t_in_clk == t_in_clk1)
+ clock_valid = 1;
+ else
+ clock_valid = 0;
+ end
+
+ if (t_in_clk > 0)
+ begin
+ t_45 = (t_in_clk / 8 );
+ t_57 = ((t_in_clk * 5) / 32 );
+ t_68 = ((t_in_clk * 3) / 16 );
+ t_79 = ((t_in_clk * 7) / 32 );
+ t_90 = (t_in_clk / 4 );
+ t_101 = ((t_in_clk * 9) / 32 );
+ t_112 = ((t_in_clk * 5) / 16 );
+ t_123 = ((t_in_clk * 11) / 32 );
+ t_135 = ((t_in_clk * 3) / 8 );
+ end
+
+ if (PHASE_SHIFT == 90)
+ begin
+ if (t_90 > 0)
+ begin
+ cntl_ratio = (t_90 / delta);
+ end
+ end
+ end
+
+ assign cntl_reg = cntl_ratio;
+
+ always @(cntl_reg or UDDCNTL_int or clock_valid)
+ begin
+ if (clock_valid == 1'b1)
+ begin
+ if (UDDCNTL_int == 1'b1)
+ begin
+ cntl_reg_update <= cntl_reg;
+ end
+ end
+ end
+
+ always @(RST_int or cntl_reg_update)
+ begin
+ if (RST_int == 1'b1)
+ cntl_reg_final <= 8'b00000000;
+ else
+ cntl_reg_final <= cntl_reg_update;
+ end
+
+/* specify
+
+(CLK => LOCK) = 0:0:0, 0:0:0;
+(CLK => DDRDEL) = 0:0:0, 0:0:0;
+(RST => LOCK) = 0:0:0, 0:0:0;
+(RST => DDRDEL) = 0:0:0, 0:0:0;
+(UDDCNTLN => LOCK) = 0:0:0, 0:0:0;
+(UDDCNTLN => DDRDEL) = 0:0:0, 0:0:0;
+
+endspecify */
+
+endmodule
+
+`endcelldefine