Date:2010-08-31 16:39:37 (4 years 2 months ago)
Author:Carlos Camargo
Commit:acf516e22d5f21c0ea8fcb7cf76c95b88a330bde
Message:Fixing some examples, adding scripts for compiling xilinx libs with ghdl

Files: Examples/sram/logic/Makefile (1 diff)
Examples/sram/logic/simulation/glbl.v (1 diff)
Examples/sram/logic/simulation/sram_bus_TB.do (1 diff)
Examples/sram/logic/simulation/sram_bus_TIMING_TB.do (1 diff)
Examples/sram/logic/simulation/transcript (1 diff)
Examples/sram/logic/simulation/vsim.wlf (0 diffs)
Examples/sram/logic/simulation/wave.do (1 diff)
Examples/sram/logic/simulation/work/_info (1 diff)
Examples/sram/logic/simulation/work/glbl/_primary.dat (0 diffs)
Examples/sram/logic/simulation/work/glbl/_primary.vhd (1 diff)
Examples/sram/logic/simulation/work/glbl/verilog.asm (0 diffs)
Examples/sram/logic/simulation/work/sram_bus/_primary.dat (0 diffs)
Examples/sram/logic/simulation/work/sram_bus/_primary.vhd (1 diff)
Examples/sram/logic/simulation/work/sram_bus/verilog.asm (0 diffs)
Examples/sram/logic/simulation/work/sram_bus_@t@b_v/_primary.dat (0 diffs)
Examples/sram/logic/simulation/work/sram_bus_@t@b_v/_primary.vhd (1 diff)
Examples/sram/logic/simulation/work/sram_bus_@t@b_v/verilog.asm (0 diffs)
Examples/sram/logic/sram_bus.ucf (1 diff)
Examples/sram/logic/sram_bus.v (1 diff)
Examples/sram/logic/sram_bus_TB.v (1 diff)
Examples/sram/src/Makefile (1 diff)
Examples/sram/src/enable_rx.c (1 diff)
Examples/sram/src/jz47xx_gpio.c (1 diff)
Examples/sram/src/jz47xx_gpio.h (1 diff)
Examples/sram/src/jz47xx_mmap.c (1 diff)
Examples/sram/src/jz47xx_mmap.h (1 diff)
Examples/sram/src/jz_init_sram.c (1 diff)
Examples/sram/src/jz_test_gpio.c (1 diff)
Examples/sram_gpio/logic/Makefile (1 diff)
Examples/sram_gpio/logic/sim/ddr/ddr.v (1 diff)
Examples/sram_gpio/logic/sim/ddr/ddr_parameters.vh (1 diff)
Examples/sram_gpio/logic/sim/ddr/parameters.v (1 diff)
Examples/sram_gpio/logic/sim/ddr/readme.txt (1 diff)
Examples/sram_gpio/logic/sim/sram/sram16.v (1 diff)
Examples/sram_gpio/logic/sim/unisims/BUFG.v (1 diff)
Examples/sram_gpio/logic/sim/unisims/DCM.v (1 diff)
Examples/sram_gpio/logic/sim/unisims/DCM_SP.v (1 diff)
Examples/sram_gpio/logic/sim/unisims/FDDRRSE.v (1 diff)
Examples/sram_gpio/logic/sim/unisims/RAMB16_S2.v (1 diff)
Examples/sram_gpio/logic/sim/unisims/RAMB16_S2_S18.v (1 diff)
Examples/sram_gpio/logic/sim/unisims/RAMB16_S2_S2.v (1 diff)
Examples/sram_gpio/logic/sim/unisims/RAMB16_S2_S36.v (1 diff)
Examples/sram_gpio/logic/sim/unisims/RAMB16_S2_S4.v (1 diff)
Examples/sram_gpio/logic/sim/unisims/RAMB16_S2_S9.v (1 diff)
Examples/sram_gpio/logic/simulation/glbl.v (1 diff)
Examples/sram_gpio/logic/simulation/sram_bus_TB.do (1 diff)
Examples/sram_gpio/logic/simulation/sram_bus_TIMING_TB.do (1 diff)
Examples/sram_gpio/logic/simulation/transcript (1 diff)
Examples/sram_gpio/logic/simulation/vsim.wlf (0 diffs)
Examples/sram_gpio/logic/simulation/wave.do (1 diff)
Examples/sram_gpio/logic/sram_bus.ucf (1 diff)
Examples/sram_gpio/logic/sram_bus.v (1 diff)
Examples/sram_gpio/logic/sram_bus_TB.v (1 diff)
Examples/sram_gpio/src/Makefile (1 diff)
Examples/sram_gpio/src/enable_irq.c (1 diff)
Examples/sram_gpio/src/enable_rx.c (1 diff)
Examples/sram_gpio/src/jz47xx_gpio.c (1 diff)
Examples/sram_gpio/src/jz47xx_gpio.h (1 diff)
Examples/sram_gpio/src/jz47xx_mmap.c (1 diff)
Examples/sram_gpio/src/jz47xx_mmap.h (1 diff)
Examples/sram_gpio/src/jz_init_sram.c (1 diff)
Examples/sram_gpio/src/jz_test_gpio.c (1 diff)
binaries/sie_rootfs_files/etc/init.d/start (1 diff)
lm32/logic/sakc/firmware/boot0-serial/image.bin (1 diff)
plasma/gpio/gpio.c (3 diffs)
plasma/logic/Makefile (1 diff)
plasma/logic/ram_image.vhd (4 diffs)
plasma/logic/simulation/plasma_TB.do (1 diff)
xilinx_lib/xilinx_ghdl_simprim (1 diff)
xilinx_lib/xilinx_ghdl_unisim (1 diff)
xilinx_lib/xilinx_vhdl_chop (1 diff)

Change Details

Examples/sram/logic/Makefile
1DESIGN = sram_bus
2PINS = sram_bus.ucf
3DEVICE = xc3s500e-VQ100-4
4BGFLAGS = -g TdoPin:PULLNONE -g DonePin:PULLUP \
5                  -g CRC:enable -g StartUpClk:CCLK
6
7SIM_CMD = /opt/cad/modeltech/bin/vsim
8SIM_COMP_SCRIPT = simulation/$(DESIGN)_TB.do
9SIMGEN_OPTIONS = -p $(FPGA_ARCH) -lang $(LANGUAGE)
10SAKC_IP = 192.168.254.101
11IVERILOG = iverilog
12XILINXCADROOT = /opt/cad/Xilinx/verilog/src
13#XILINXCADROOT = /opt/cad/modeltech/xilinx/verilog/
14
15
16SRC = sram_bus.v
17
18SIM_SRC = $(DESIGN)_TB.v \
19# sim/unisims/BUFG.v \
20# sim/unisims/DCM.v \
21# sim/unisims/FDDRRSE.v \
22# glbl.v
23# sim/unisims/RAMB16_S2_S9.v
24
25
26all: bits
27
28remake: clean-build all
29
30clean:
31    rm -f *~ */*~ a.out *.log *.key *.edf *.ps trace.dat
32    rm -rf *.bit
33
34clean-build: clean
35    rm -rf build
36
37cleanall: clean
38    rm -rf build $(DESIGN).bit
39
40bits: $(DESIGN).bit
41
42#
43# Synthesis
44#
45build/project.src:
46    @[ -d build ] || mkdir build
47    @rm -f $@
48    for i in $(SRC); do echo verilog work ../$$i >> $@; done
49    for i in $(SRC_HDL); do echo VHDL work ../$$i >> $@; done
50
51build/project.xst: build/project.src
52    echo "run" > $@
53    echo "-top $(DESIGN) " >> $@
54    echo "-p $(DEVICE)" >> $@
55    echo "-opt_mode Area" >> $@
56    echo "-opt_level 1" >> $@
57    echo "-ifn project.src" >> $@
58    echo "-ifmt mixed" >> $@
59    echo "-ofn project.ngc" >> $@
60    echo "-ofmt NGC" >> $@
61    echo "-rtlview yes" >> $@
62
63build/project.ngc: build/project.xst $(SRC)
64    cd build && xst -ifn project.xst -ofn project.log
65
66build/project.ngd: build/project.ngc $(PINS)
67    cd build && ngdbuild -p $(DEVICE) project.ngc -uc ../$(PINS)
68
69build/project.ncd: build/project.ngd
70    cd build && map -pr b -p $(DEVICE) project
71
72build/project_r.ncd: build/project.ncd
73    cd build && par -w project project_r.ncd
74
75build/project_r.twr: build/project_r.ncd
76    cd build && trce -v 25 project_r.ncd project.pcf
77
78$(DESIGN).bit: build/project_r.ncd build/project_r.twr
79    cd build && bitgen project_r.ncd -l -w $(BGFLAGS)
80    @mv -f build/project_r.bit $@
81
82build/project_r.v: build/project_r.ncd
83    cd build && ngd2ver project.ngd -w project.v
84
85modelsim:
86    cd simulation; $(SIM_CMD) -do $(DESIGN)_TB.do
87
88timesim: build/project_r.v
89    cd simulation; $(SIM_CMD) -do $(DESIGN)_TIMING_TB.do
90
91iversim:
92    $(IVERILOG) -Wall -o simulation/$(DESIGN)_TB.vvp $(VINCDIR) $(SRC) $(SIM_SRC) -s $(DESIGN)_TB
93    vvp simulation/$(DESIGN)_TB.vvp; mv $(DESIGN)_TB.vcd simulation/
94    gtkwave simulation/$(DESIGN)_TB.vcd&
95
96upload: $(DESIGN).bit
97    scp $(DESIGN).bit root@$(SAKC_IP):
Examples/sram/logic/simulation/glbl.v
1// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/glbl.v,v 1.11.156.1 2007/03/09 18:12:55 patrickp Exp $
2
3`timescale 1 ps / 1 ps
4
5module glbl ();
6
7    parameter ROC_WIDTH = 100000;
8    parameter TOC_WIDTH = 0;
9
10    wire GSR;
11    wire GTS;
12    wire PRLD;
13
14    reg GSR_int;
15    reg GTS_int;
16    reg PRLD_int;
17
18//-------- JTAG Globals --------------
19    wire JTAG_TDO_GLBL;
20    wire JTAG_TCK_GLBL;
21    wire JTAG_TDI_GLBL;
22    wire JTAG_TMS_GLBL;
23    wire JTAG_TRST_GLBL;
24
25    reg JTAG_CAPTURE_GLBL;
26    reg JTAG_RESET_GLBL;
27    reg JTAG_SHIFT_GLBL;
28    reg JTAG_UPDATE_GLBL;
29
30    reg JTAG_SEL1_GLBL = 0;
31    reg JTAG_SEL2_GLBL = 0 ;
32    reg JTAG_SEL3_GLBL = 0;
33    reg JTAG_SEL4_GLBL = 0;
34
35    reg JTAG_USER_TDO1_GLBL = 1'bz;
36    reg JTAG_USER_TDO2_GLBL = 1'bz;
37    reg JTAG_USER_TDO3_GLBL = 1'bz;
38    reg JTAG_USER_TDO4_GLBL = 1'bz;
39
40    assign (weak1, weak0) GSR = GSR_int;
41    assign (weak1, weak0) GTS = GTS_int;
42    assign (weak1, weak0) PRLD = PRLD_int;
43
44    initial begin
45    GSR_int = 1'b1;
46    PRLD_int = 1'b1;
47    #(ROC_WIDTH)
48    GSR_int = 1'b0;
49    PRLD_int = 1'b0;
50    end
51
52    initial begin
53    GTS_int = 1'b1;
54    #(TOC_WIDTH)
55    GTS_int = 1'b0;
56    end
57
58endmodule
Examples/sram/logic/simulation/sram_bus_TB.do
1vlib work
2vlog -incr +libext+.v \
3            "../sram_bus.v" \
4            "../sram_bus_TB.v" \
5            "glbl.v"
6vsim -t 1ps -L simprims_ver -L unisims_ver -L xilinxcorelib_ver sram_bus_TB glbl
7view wave
8#do wave.do
9add wave *
10view structure
11view signals
12run 5us
Examples/sram/logic/simulation/sram_bus_TIMING_TB.do
1vlib work
2vlog -incr "../build/project.v" "../sram_bus_TB.v" "glbl.v"
3vsim -t 1ps -L simprims_ver -L unisims_ver -L xilinxcorelib_ver sram_bus_TB glbl
4view wave
5#do wave.do
6add wave *
7view structure
8view signals
9run 5us
Examples/sram/logic/simulation/transcript
1# // ModelSim SE 6.0d Apr 25 2005 Linux 2.6.32-22-generic
2# //
3# // Copyright Mentor Graphics Corporation 2005
4# // All Rights Reserved.
5# //
6# // THIS WORK CONTAINS TRADE SECRET AND
7# // PROPRIETARY INFORMATION WHICH IS THE PROPERTY
8# // OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS
9# // AND IS SUBJECT TO LICENSE TERMS.
10# //
11# do sram_bus_TB.do
12# ** Warning: (vlib-34) Library already exists at "work".
13# Model Technology ModelSim SE vlog 6.0d Compiler 2005.04 Apr 25 2005
14# -- Compiling module sram_bus
15# -- Compiling module sram_bus_TB
16# -- Compiling module glbl
17#
18# Top level modules:
19# sram_bus_TB
20# glbl
21# vsim -L simprims_ver -L unisims_ver -L xilinxcorelib_ver -t 1ps sram_bus_TB glbl
22# Loading work.sram_bus_TB
23# Loading work.sram_bus
24# Loading /opt/cad/modeltech/xilinx/verilog/unisims_ver.RAMB16_S2
25# Loading work.glbl
26# ** Warning: (vsim-3017) ../sram_bus_TB.v(21): [TFMPC] - Too few port connections. Expected 8, found 7.
27# Region: /sram_bus_TB/uut
28# ** Warning: (vsim-3015) ../sram_bus_TB.v(21): [PCDPC] - Port size (8 or 8) does not match connection size (1) for port 'sram_data'.
29# Region: /sram_bus_TB/uut
30# ** Warning: (vsim-3722) ../sram_bus_TB.v(21): [TFMPC] - Missing connection for port 'led'.
31# .main_pane.mdi.interior.cs.vm.paneset.cli_0.wf.clip.cs
32# .main_pane.workspace
33# .main_pane.signals.interior.cs
34quit
Examples/sram/logic/simulation/vsim.wlf
Examples/sram/logic/simulation/wave.do
1onerror {resume}
2quietly WaveActivateNextPane {} 0
3add wave -noupdate -format Logic -radix hexadecimal /sram_bus_TB_v/clk
4add wave -noupdate -format Literal -radix hexadecimal /sram_bus_TB_v/addr
5add wave -noupdate -format Logic -radix hexadecimal /sram_bus_TB_v/nwe
6add wave -noupdate -format Logic -radix hexadecimal /sram_bus_TB_v/ncs
7add wave -noupdate -format Logic -radix hexadecimal /sram_bus_TB_v/noe
8add wave -noupdate -format Logic -radix hexadecimal /sram_bus_TB_v/reset
9add wave -noupdate -format Logic -radix hexadecimal /sram_bus_TB_v/led
10add wave -noupdate -format Literal -radix hexadecimal {/sram_bus_TB_v/sram_data$inout$reg}
11add wave -noupdate -format Logic -radix hexadecimal /sram_bus_TB_v/sram_data
12add wave -noupdate -format Literal -radix hexadecimal /sram_bus_TB_v/data_tx
13add wave -noupdate -format Logic -radix hexadecimal /glbl/GSR
14TreeUpdate [SetDefaultTree]
15WaveRestoreCursors {{Cursor 1} {154070 ps} 0}
16configure wave -namecolwidth 323
17configure wave -valuecolwidth 100
18configure wave -justifyvalue left
19configure wave -signalnamewidth 0
20configure wave -snapdistance 10
21configure wave -datasetprefix 0
22configure wave -rowmargin 4
23configure wave -childrowmargin 2
24configure wave -gridoffset 0
25configure wave -gridperiod 1
26configure wave -griddelta 40
27configure wave -timeline 0
28update
29WaveRestoreZoom {0 ps} {656250 ps}
Examples/sram/logic/simulation/work/_info
1m255
213
3cModel Technology
4d/home/cain/Embedded/ingenic/sakc/nn-usb-fpga/Examples/sram/logic/simulation
5vglbl
6IT?5S;>bN`@zG_25]R_4A33
7VnN]4Gon>inod6>M^M2[SV1
8w1273510321
9Fglbl.v
10L0 5
11OE;L;6.0d;29
12r1
1331
14o+libext+.v
15vsram_bus
16I4L5C3LJ<U_bBN0U__mYo>0
17V7R>S0^PdJz?6eY;E[l1^E2
18w1273543761
19F../sram_bus.v
20L0 2
21OE;L;6.0d;29
22r1
2331
24o+libext+.v
25vsram_bus_TB
26IeNSImUgW[X4l`QoUVUKI`3
27V<VFiY^801Z<UUJ?^z?JM20
28w1273676679
29F../sram_bus_TB.v
30L0 3
31OE;L;6.0d;29
32r1
3331
34o+libext+.v
35nsram_bus_@t@b
36vsram_bus_TB_v
37IA=m;kT@<eh:`ekMlOPXX@0
38VQ[@Nfjd=de;Dc[[gj0bf41
39w1273541944
40F../sram_bus_TB.v
41L0 3
42OE;L;6.0d;29
43r1
4431
45o+libext+.v
46nsram_bus_@t@b_v
Examples/sram/logic/simulation/work/glbl/_primary.dat
Examples/sram/logic/simulation/work/glbl/_primary.vhd
1library verilog;
2use verilog.vl_types.all;
3entity glbl is
4    generic(
5        ROC_WIDTH : integer := 100000;
6        TOC_WIDTH : integer := 0
7    );
8end glbl;
Examples/sram/logic/simulation/work/glbl/verilog.asm
Examples/sram/logic/simulation/work/sram_bus/_primary.dat
Examples/sram/logic/simulation/work/sram_bus/_primary.vhd
1library verilog;
2use verilog.vl_types.all;
3entity sram_bus is
4    generic(
5        B : integer := 7
6    );
7    port(
8        clk : in vl_logic;
9        sram_data : inout vl_logic_vector;
10        addr : in vl_logic_vector(12 downto 0);
11        nwe : in vl_logic;
12        ncs : in vl_logic;
13        noe : in vl_logic;
14        reset : in vl_logic;
15        led : out vl_logic
16    );
17end sram_bus;
Examples/sram/logic/simulation/work/sram_bus/verilog.asm
Examples/sram/logic/simulation/work/sram_bus_@t@b_v/_primary.dat
Examples/sram/logic/simulation/work/sram_bus_@t@b_v/_primary.vhd
1library verilog;
2use verilog.vl_types.all;
3entity sram_bus_TB_v is
4    generic(
5        PERIOD : integer := 20;
6        DUTY_CYCLE : real := 0.500000;
7        OFFSET : integer := 0;
8        TSET : integer := 3;
9        THLD : integer := 3;
10        NWS : integer := 3;
11        CAM_OFF : integer := 4000
12    );
13end sram_bus_TB_v;
Examples/sram/logic/simulation/work/sram_bus_@t@b_v/verilog.asm
Examples/sram/logic/sram_bus.ucf
1NET clk LOC = "P38";
2NET reset LOC = "P30";
3NET led LOC = "P44";
4NET irq_pin LOC = "P71";
5
6#ADDRESS BUS
7NET "addr<12>" LOC = "P90";
8NET "addr<11>" LOC = "P91";
9NET "addr<10>" LOC = "P85";
10NET "addr<9>" LOC = "P92";
11NET "addr<8>" LOC = "P94";
12NET "addr<7>" LOC = "P95";
13NET "addr<6>" LOC = "P98";
14NET "addr<5>" LOC = "P3";
15NET "addr<4>" LOC = "P2";
16NET "addr<3>" LOC = "P78";
17NET "addr<2>" LOC = "P79";
18NET "addr<1>" LOC = "P83";
19NET "addr<0>" LOC = "P84";
20
21#DATA BUS
22NET "sram_data<7>" LOC = "P4";
23NET "sram_data<6>" LOC = "P5";
24NET "sram_data<5>" LOC = "P9";
25NET "sram_data<4>" LOC = "P10";
26NET "sram_data<3>" LOC = "P11";
27NET "sram_data<2>" LOC = "P12";
28NET "sram_data<1>" LOC = "P15";
29NET "sram_data<0>" LOC = "P16";
30
31#CONTROL BUS
32NET "nwe" LOC = "P88";
33NET "noe" LOC = "P86";
34NET "ncs" LOC = "P69";
35
36#ADC
37#NET "ADC_EOC" LOC = "P17";
38#NET "ADC_SCLK" LOC = "P18";
39#NET "ADC_SDIN" LOC = "P22";
40#NET "ADC_SDOUT" LOC = "P23";
41#NET "ADC_CS" LOC = "P24";
42#NET "ADC_CSTART" LOC = "P26";
43
44
Examples/sram/logic/sram_bus.v
1`timescale 1ns / 1ps
2module sram_bus(clk, sram_data, addr, nwe, ncs, noe, reset, led, irq_pin);
3  parameter B = (7);
4
5  input clk, nwe, ncs, noe, reset;
6  input [12:0] addr;
7  inout [B:0] sram_data;
8  output led;
9  input irq_pin;
10
11  // synchronize signals
12  reg sncs, snwe;
13  reg [12:0] buffer_addr;
14  reg [B:0] buffer_data;
15
16  // interfaz fpga signals
17// wire [12:0] addr;
18
19  // bram interfaz signals
20  reg we;
21  reg w_st;
22
23  reg [B:0] wdBus;
24  wire [B:0] rdBus;
25
26  // interefaz signals assignments
27  wire T = ~noe | ncs;
28  assign sram_data = T?8'bZ:rdBus;
29
30  //--------------------------------------------------------------------------
31
32  // synchronize assignment
33  always @(negedge clk)
34  begin
35    sncs <= ncs;
36    snwe <= nwe;
37    buffer_data <= sram_data;
38    buffer_addr <= addr;
39  end
40
41  // write access cpu to bram
42  always @(posedge clk)
43    if(~reset) {w_st, we, wdBus} <= 0;
44      else begin
45        wdBus <= buffer_data;
46        case (w_st)
47          0: begin
48              we <= 0;
49              if(sncs | snwe) w_st <= 1;
50          end
51          1: begin
52            if(~(sncs | snwe)) begin
53              we <= 1;
54              w_st <= 0;
55            end
56            else we <= 0;
57          end
58        endcase
59      end
60
61RAMB16_S2 ba0( .CLK(~clk), .EN(1'b1), .SSR(1'b0), .ADDR(buffer_addr),
62               .WE(we), .DI(wdBus[1:0]), .DO(rdBus[1:0]) );
63
64RAMB16_S2 ba1( .CLK(~clk), .EN(1'b1), .SSR(1'b0), .ADDR(buffer_addr),
65               .WE(we), .DI(wdBus[3:2]), .DO(rdBus[3:2]) );
66
67RAMB16_S2 ba2( .CLK(~clk), .EN(1'b1), .SSR(1'b0), .ADDR(buffer_addr),
68               .WE(we), .DI(wdBus[5:4]), .DO(rdBus[5:4]) );
69
70RAMB16_S2 ba3( .CLK(~clk), .EN(1'b1), .SSR(1'b0), .ADDR(buffer_addr),
71               .WE(we), .DI(wdBus[7:6]), .DO(rdBus[7:6]) );
72
73  reg [24:0] counter;
74  always @(posedge clk) begin
75    if (~reset)
76      counter <= {25{1'b0}};
77    else
78      counter <= counter + 1;
79  end
80  assign led = counter[24];
81
82endmodule
83
Examples/sram/logic/sram_bus_TB.v
1`timescale 1ns / 1ps
2
3module sram_bus_TB;
4
5   // inputs
6   reg clk;
7   reg [12:0] addr;
8   reg nwe;
9   reg ncs;
10   reg noe;
11   reg reset;
12   // leds
13   reg led;
14   // Bidirs
15   reg [7:0] sram_data$inout$reg ;
16
17   // Instantiate the Unit Under Test (UUT)
18   sram_bus uut ( .clk(clk), .reset(reset),
19       .sram_data(sram_data), .addr(addr), .nwe(nwe),
20       .ncs(ncs), .noe(noe)
21   );
22   parameter PERIOD = 20;
23   parameter real DUTY_CYCLE = 0.5;
24   parameter OFFSET = 0;
25   parameter TSET = 3;
26   parameter THLD = 3;
27   parameter NWS = 3;
28   parameter CAM_OFF = 4000;
29
30     reg [15:0] i;
31     reg [15:0] j;
32     reg [15:0] k;
33     reg [15:0] data_tx;
34
35
36    event reset_trigger;
37    event reset_done_trigger;
38
39    initial begin // Reset the system, Start the image capture process
40      forever begin
41        @ (reset_trigger);
42        @ (negedge clk);
43        reset = 1;
44        @ (negedge clk);
45        reset = 0;
46        -> reset_done_trigger;
47      end
48    end
49
50    initial begin // Initialize Inputs
51      clk = 0; addr = 0; nwe = 1; ncs = 1; noe = 1;
52    end
53
54   initial begin // Process for clk
55     #OFFSET;
56     forever
57     begin
58       clk = 1'b0;
59       #(PERIOD-(PERIOD*DUTY_CYCLE)) clk = 1'b1;
60       #(PERIOD*DUTY_CYCLE);
61     end
62   end
63
64 initial begin: TEST_CASE
65     #10 -> reset_trigger;
66     @ (reset_done_trigger);
67     // Write data to SRAM
68   for(i=0; i<10; i=i+1) begin
69     @ (posedge clk);
70     ncs <= 0;
71     addr <= i[9:0];
72     repeat (TSET) begin
73       @ (posedge clk);
74     end
75     nwe <= 0;
76     sram_data$inout$reg <= i*2;
77     repeat (NWS) begin
78       @ (posedge clk);
79     end
80     nwe <= 1;
81     repeat (THLD) begin
82       @ (posedge clk);
83     end
84     ncs <= 1;
85     sram_data$inout$reg = {16{1'bz}};
86   end
87   nwe = 1;
88
89   //Read Data
90   for(i=0; i<10; i=i+1) begin
91     @ (posedge clk);
92     ncs <= 0;
93     addr <= i[9:0];
94     repeat (TSET) begin
95       @ (posedge clk);
96     end
97     noe <= 0;
98     sram_data$inout$reg <= i;
99     repeat (NWS) begin
100       @ (posedge clk);
101     end
102     noe <= 1;
103     repeat (THLD) begin
104      @ (posedge clk);
105     end
106     ncs <= 1;
107     sram_data$inout$reg = {16{1'bz}};
108   end
109 end
110
111
112endmodule
113
Examples/sram/src/Makefile
1CC = mipsel-openwrt-linux-gcc
2
3all: jz_init_sram jz_test_gpio enable_rx enable_irq
4
5DEBUG = -O3 -g0
6
7COMMON_SOURCES = jz47xx_gpio.c jz47xx_mmap.c
8
9H_SOURCES = jz47xx_gpio.h jz47xx_mmap.h
10
11INCLUDE = -I.
12
13WARNINGS= -Wcast-align -Wpacked -Wpadded -Wall
14
15CCFLAGS = ${INCLUDE} ${DEBUG} ${WARNINGS}
16
17LDFLAGS =
18
19COMMON_OBJECTS = $(COMMON_SOURCES:.c=.o)
20
21NANO_IP = 192.168.254.101
22
23jz_init_sram: $(COMMON_OBJECTS)
24    $(CC) $(LDFLAGS) $(COMMON_OBJECTS) jz_init_sram.c -o jz_init_sram
25
26jz_test_gpio: $(COMMON_OBJECTS)
27    $(CC) $(LDFLAGS) $(COMMON_OBJECTS) jz_test_gpio.c -o jz_test_gpio
28
29enable_rx: $(COMMON_OBJECTS)
30    $(CC) $(LDFLAGS) $(COMMON_OBJECTS) enable_rx.c -o enable_rx
31
32enable_irq: $(COMMON_OBJECTS)
33    $(CC) $(LDFLAGS) $(COMMON_OBJECTS) enable_irq.c -o enable_irq
34
35.c.o:
36    $(CC) -c $(CCFLAGS) $< -o $@
37
38upload: jz_init_sram jz_test_gpio
39    scp jz_test_gpio jz_init_sram root@$(NANO_IP):
40
41clean:
42    rm -f *.o jz_init_sram jz_test_gpio enable_rx ${EXEC} *~ enable_irq
43
44indent:
45    indent -bad -bap -nbc -bl -nce -i2 --no-tabs --line-length120 $(COMMON_SOURCES) $(H_SOURCES)
Examples/sram/src/enable_rx.c
1/*
2  JZ47xx test gpio
3
4  Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com
5                          Carlos Camargo cicamargoba@unal.edu.co
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
20
21#include <stdio.h>
22#include <unistd.h>
23
24#include "jz47xx_gpio.h"
25
26#define RXD_PORT JZ_GPIO_PORT_D
27#define RXD_PIN 26
28
29int
30main ()
31{
32  JZ_PIO *pio = jz_gpio_map (RXD_PORT);
33
34  if (!pio)
35    return -1;
36
37  jz_gpio_as_func (pio, RXD_PIN, 1);
38
39  return 0;
40}
Examples/sram/src/jz47xx_gpio.c
1/*
2  JZ47xx GPIO at userspace
3
4  Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <unistd.h>
23
24#include <jz47xx_gpio.h>
25#include <jz47xx_mmap.h>
26
27
28#define JZ_GPIO_BASE 0x10010000
29
30void
31jz_gpio_as_output (JZ_PIO * pio, unsigned int o)
32{
33  pio->PXFUNC = (1 << (o));
34  pio->PXSELC = (1 << (o));
35  pio->PXDIRS = (1 << (o));
36}
37
38void
39jz_gpio_as_input (JZ_PIO * pio, unsigned int o)
40{
41  pio->PXFUNC = (1 << (o));
42  pio->PXSELC = (1 << (o));
43  pio->PXDIRC = (1 << (o));
44}
45
46void
47jz_gpio_as_irq (JZ_PIO * pio, unsigned int o)
48{
49  pio->PXFUNC = (1 << (o));
50  pio->PXSELS = (1 << (o));
51  pio->PXDIRC = (1 << (o));
52}
53
54void
55jz_gpio_set_pin (JZ_PIO * pio, unsigned int o)
56{
57  pio->PXDATS = (1 << (o));
58}
59
60void
61jz_gpio_clear_pin (JZ_PIO * pio, unsigned int o)
62{
63  pio->PXDATC = (1 << (o));
64}
65
66void
67jz_gpio_out (JZ_PIO * pio, unsigned int o, unsigned int val)
68{
69  if (val == 0)
70    pio->PXDATC = (1 << (o));
71  else
72    pio->PXDATS = (1 << (o));
73}
74
75unsigned int
76jz_gpio_get_pin (JZ_PIO * pio, unsigned int o)
77{
78  return (pio->PXPIN & (1 << o)) ? 1 : 0;
79}
80
81int
82jz_gpio_as_func (JZ_PIO * pio, unsigned int o, int func)
83{
84  switch (func)
85    {
86    case 0:
87      pio->PXFUNS = (1 << o);
88      pio->PXTRGC = (1 << o);
89      pio->PXSELC = (1 << o);
90      pio->PXPES = (1 << o);
91      return 1;
92
93    case 1:
94      pio->PXFUNS = (1 << o);
95      pio->PXTRGC = (1 << o);
96      pio->PXSELS = (1 << o);
97      pio->PXPES = (1 << o);
98      return 1;
99
100    case 2:
101      pio->PXFUNS = (1 << o);
102      pio->PXTRGS = (1 << o);
103      pio->PXSELC = (1 << o);
104      pio->PXPES = (1 << o);
105      return 1;
106    }
107  return 0;
108}
109
110JZ_PIO *
111jz_gpio_map (int port)
112{
113  JZ_PIO *pio;
114
115  pio = (JZ_PIO *) jz_mmap (JZ_GPIO_BASE);
116  pio = (JZ_PIO *) ((unsigned int) pio + port * 0x100);
117
118  return pio;
119}
Examples/sram/src/jz47xx_gpio.h
1/*
2  JZ47xx GPIO at userspace
3
4  Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
19
20#ifndef __jz47xx_gpio_h__
21#define __jz47xx_gpio_h__
22
23#define JZ_GPIO_PORT_A 0
24#define JZ_GPIO_PORT_B 1
25#define JZ_GPIO_PORT_C 2
26#define JZ_GPIO_PORT_D 3
27
28typedef volatile unsigned int JZ_REG; /* Hardware register definition */
29
30typedef struct _JZ_PIO
31{
32  JZ_REG PXPIN; /* PIN Level Register */
33  JZ_REG Reserved0;
34  JZ_REG Reserved1;
35  JZ_REG Reserved2;
36  JZ_REG PXDAT; /* Port Data Register */
37  JZ_REG PXDATS; /* Port Data Set Register */
38  JZ_REG PXDATC; /* Port Data Clear Register */
39  JZ_REG Reserved3;
40  JZ_REG PXIM; /* Interrupt Mask Register */
41  JZ_REG PXIMS; /* Interrupt Mask Set Reg */
42  JZ_REG PXIMC; /* Interrupt Mask Clear Reg */
43  JZ_REG Reserved4;
44  JZ_REG PXPE; /* Pull Enable Register */
45  JZ_REG PXPES; /* Pull Enable Set Reg. */
46  JZ_REG PXPEC; /* Pull Enable Clear Reg. */
47  JZ_REG Reserved5;
48  JZ_REG PXFUN; /* Function Register */
49  JZ_REG PXFUNS; /* Function Set Register */
50  JZ_REG PXFUNC; /* Function Clear Register */
51  JZ_REG Reserved6;
52  JZ_REG PXSEL; /* Select Register */
53  JZ_REG PXSELS; /* Select Set Register */
54  JZ_REG PXSELC; /* Select Clear Register */
55  JZ_REG Reserved7;
56  JZ_REG PXDIR; /* Direction Register */
57  JZ_REG PXDIRS; /* Direction Set Register */
58  JZ_REG PXDIRC; /* Direction Clear Register */
59  JZ_REG Reserved8;
60  JZ_REG PXTRG; /* Trigger Register */
61  JZ_REG PXTRGS; /* Trigger Set Register */
62  JZ_REG PXTRGC; /* Trigger Set Register */
63  JZ_REG Reserved9;
64  JZ_REG PXFLG; /* Port Flag Register */
65  JZ_REG PXFLGC; /* Port Flag clear Register */
66} JZ_PIO, *PJZ_PIO;
67
68void jz_gpio_as_output (JZ_PIO * pio, unsigned int o);
69
70void jz_gpio_as_input (JZ_PIO * pio, unsigned int o);
71
72void jz_gpio_set_pin (JZ_PIO * pio, unsigned int o);
73
74void jz_gpio_clear_pin (JZ_PIO * pio, unsigned int o);
75
76void jz_gpio_out (JZ_PIO * pio, unsigned int o, unsigned int val);
77
78unsigned int jz_gpio_get_pin (JZ_PIO * pio, unsigned int o);
79
80int jz_gpio_as_func (JZ_PIO * pio, unsigned int o, int func);
81
82JZ_PIO *jz_gpio_map (int port);
83
84#endif
Examples/sram/src/jz47xx_mmap.c
1/*
2 * JZ47xx GPIO lines
3 *
4 * Written 2010 by Andres Calderon andres.calderon@emqbit.com
5 */
6
7#include <stdio.h>
8#include <sys/mman.h>
9#include <fcntl.h>
10#include <stdlib.h>
11#include <termios.h>
12#include <unistd.h>
13
14#include <jz47xx_mmap.h>
15
16
17void *
18jz_mmap (off_t address)
19{
20  int fd;
21
22  void *pio;
23
24  if ((fd = open ("/dev/mem", O_RDWR | O_SYNC)) == -1)
25    {
26      fprintf (stderr, "Cannot open /dev/mem.\n");
27      return 0;
28    }
29
30  pio = (void *) mmap (0, getpagesize (), PROT_READ | PROT_WRITE, MAP_SHARED, fd, address);
31
32  if (pio == (void *) -1)
33    {
34      fprintf (stderr, "Cannot mmap.\n");
35      return 0;
36    }
37
38  return pio;
39}
40
41void *
42jz_fpga_map (off_t address)
43{
44  int fd;
45
46  void *fpga;
47
48  if ((fd = open ("/dev/mem", O_RDWR | O_SYNC)) == -1)
49    {
50      fprintf (stderr, "Cannot open /dev/mem.\n");
51      return 0;
52    }
53
54  fpga = (void *) mmap (0, FPGA_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, address);
55
56  if (fpga == (void *) -1)
57    {
58      fprintf (stderr, "Cannot mmap.\n");
59      return 0;
60    }
61
62  return fpga;
63}
64
Examples/sram/src/jz47xx_mmap.h
1/*
2 * JZ47xx GPIO lines
3 *
4 * Written 2010 by Andres Calderon andres.calderon@emqbit.com
5 */
6
7#ifndef __jz47xx_mmap_h__
8#define __jz47xx_mmap_h__
9
10#include <sys/mman.h>
11
12#define FPGA_SIZE (1 << 15)
13
14void *jz_mmap (off_t address);
15void *jz_fpga_map (off_t address);
16
17#endif
Examples/sram/src/jz_init_sram.c
1/* SAKC FPGA/SRAM interface test
2
3Copyright (C) 2010 Carlos Camargo cicamargoba@unal.edu.co
4                               Andres Calderon andres.calderon@emqbit.com
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
19
20#include <stdio.h>
21#include <unistd.h>
22#include <stdlib.h>
23
24#include "jz47xx_gpio.h"
25#include "jz47xx_mmap.h"
26
27#define CS2_PORT JZ_GPIO_PORT_B
28#define CS2_PIN 26
29
30int
31main ()
32{
33  int i;
34  JZ_PIO *pio;
35  int *virt_addr;
36
37  pio = jz_gpio_map (CS2_PORT);
38  jz_gpio_as_func (pio, CS2_PIN, 0);
39
40  virt_addr = (int *) jz_mmap (0x13010000) + 0x18;
41
42  if (*virt_addr != 0xFFF7700)
43    { // 0 WS, 8 bits
44      *virt_addr = 0xFFF7700;
45      printf ("Configuring CS2 8 bits \n");
46    }
47  else
48    printf ("CS3, already configured\n");
49
50  virt_addr = (int *) jz_fpga_map (0x15000000);
51
52  printf ("Writing Memory..\n");
53
54  srand48(0x3c);
55
56  for (i = 0; i < FPGA_SIZE/4; i++)
57      virt_addr[i] = (lrand48() & 0x00ff);
58
59  printf ("Reading Memory..\n");
60
61
62  srand48(0x3c);
63
64  for (i = 0; i < FPGA_SIZE/4; i++){
65    printf("%X\n", virt_addr[i]);
66    if (virt_addr[i] != (lrand48() & 0x00ff)){
67      printf ("FPGA - Xburst connection test failed on Address:0x%x\n", i);
68      return 1; /* Error */
69    }
70  }
71  printf ("%d\n", i);
72      printf ("FPGA - Xburst connection test passed\n");
73
74  return 0;
75}
Examples/sram/src/jz_test_gpio.c
1/*
2  JZ47xx test gpio
3
4  Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com
5                          Carlos Camargo cicamargoba@unal.edu.co
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
20
21#include <stdio.h>
22#include <unistd.h>
23
24#include "jz47xx_gpio.h"
25
26#define TEST_PORT JZ_GPIO_PORT_C
27#define TEST_PIN 17
28
29int
30main ()
31{
32  JZ_PIO *pio = jz_gpio_map (TEST_PORT);
33
34  if (!pio)
35    return -1;
36
37  jz_gpio_as_output (pio, TEST_PIN);
38
39  int tg = 1;
40
41  while (1)
42    {
43      jz_gpio_out (pio, TEST_PIN, tg);
44      printf ("[%d]", jz_gpio_get_pin (pio, TEST_PIN));
45      fflush (stdout);
46      usleep (500 * 1000);
47      tg = !tg;
48    }
49  return 0;
50}
Examples/sram_gpio/logic/Makefile
1DESIGN = sram_bus
2PINS = sram_bus.ucf
3DEVICE = xc3s500e-VQ100-4
4BGFLAGS = -g TdoPin:PULLNONE -g DonePin:PULLUP \
5                  -g CRC:enable -g StartUpClk:CCLK
6
7SIM_CMD = /opt/cad/modeltech/bin/vsim
8SIM_COMP_SCRIPT = simulation/$(DESIGN)_TB.do
9SIMGEN_OPTIONS = -p $(FPGA_ARCH) -lang $(LANGUAGE)
10SAKC_IP = 192.168.254.101
11IVERILOG = iverilog
12XILINXCADROOT = /opt/cad/Xilinx/verilog/src
13#XILINXCADROOT = /opt/cad/modeltech/xilinx/verilog/
14
15
16SRC = sram_bus.v
17
18SIM_SRC = $(DESIGN)_TB.v \
19# sim/unisims/BUFG.v \
20# sim/unisims/DCM.v \
21# sim/unisims/FDDRRSE.v \
22# glbl.v
23# sim/unisims/RAMB16_S2_S9.v
24
25
26all: bits
27
28remake: clean-build all
29
30clean:
31    rm -f *~ */*~ a.out *.log *.key *.edf *.ps trace.dat
32    rm -rf *.bit
33
34clean-build: clean
35    rm -rf build
36
37cleanall: clean
38    rm -rf build $(DESIGN).bit
39
40bits: $(DESIGN).bit
41
42#
43# Synthesis
44#
45build/project.src:
46    @[ -d build ] || mkdir build
47    @rm -f $@
48    for i in $(SRC); do echo verilog work ../$$i >> $@; done
49    for i in $(SRC_HDL); do echo VHDL work ../$$i >> $@; done
50
51build/project.xst: build/project.src
52    echo "run" > $@
53    echo "-top $(DESIGN) " >> $@
54    echo "-p $(DEVICE)" >> $@
55    echo "-opt_mode Area" >> $@
56    echo "-opt_level 1" >> $@
57    echo "-ifn project.src" >> $@
58    echo "-ifmt mixed" >> $@
59    echo "-ofn project.ngc" >> $@
60    echo "-ofmt NGC" >> $@
61    echo "-rtlview yes" >> $@
62
63build/project.ngc: build/project.xst $(SRC)
64    cd build && xst -ifn project.xst -ofn project.log
65
66build/project.ngd: build/project.ngc $(PINS)
67    cd build && ngdbuild -p $(DEVICE) project.ngc -uc ../$(PINS)
68
69build/project.ncd: build/project.ngd
70    cd build && map -pr b -p $(DEVICE) project
71
72build/project_r.ncd: build/project.ncd
73    cd build && par -w project project_r.ncd
74
75build/project_r.twr: build/project_r.ncd
76    cd build && trce -v 25 project_r.ncd project.pcf
77
78$(DESIGN).bit: build/project_r.ncd build/project_r.twr
79    cd build && bitgen project_r.ncd -l -w $(BGFLAGS)
80    @mv -f build/project_r.bit $@
81
82build/project_r.v: build/project_r.ncd
83    cd build && ngd2ver project.ngd -w project.v
84
85modelsim:
86    cd simulation; $(SIM_CMD) -do $(DESIGN)_TB.do
87
88timesim: build/project_r.v
89    cd simulation; $(SIM_CMD) -do $(DESIGN)_TIMING_TB.do
90
91iversim:
92    $(IVERILOG) -Wall -o simulation/$(DESIGN)_TB.vvp $(VINCDIR) $(SRC) $(SIM_SRC) -s $(DESIGN)_TB
93    vvp simulation/$(DESIGN)_TB.vvp; mv $(DESIGN)_TB.vcd simulation/
94    gtkwave simulation/$(DESIGN)_TB.vcd&
95
96upload: $(DESIGN).bit
97    scp $(DESIGN).bit root@$(SAKC_IP):
Examples/sram_gpio/logic/sim/ddr/ddr.v
1/****************************************************************************************
2*
3* File Name: ddr.v
4* Version: 5.7
5* Model: BUS Functional
6*
7* Dependencies: ddr_parameters.v
8*
9* Description: Micron SDRAM DDR (Double Data Rate)
10*
11* Limitation: - Doesn't check for 8K-cycle refresh.
12* - Doesn't check power-down entry/exit
13* - Doesn't check self-refresh entry/exit.
14*
15* Note: - Set simulator resolution to "ps" accuracy
16* - Set Debug = 0 to disable $display messages
17* - Model assume Clk and Clk# crossing at both edge
18*
19* Disclaimer This software code and all associated documentation, comments or other
20* of Warranty: information (collectively "Software") is provided "AS IS" without
21* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
22* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
23* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
24* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
25* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
26* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
27* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
28* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
29* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
30* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
31* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
32* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
33* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
34* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
35* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
36* DAMAGES. Because some jurisdictions prohibit the exclusion or
37* limitation of liability for consequential or incidental damages, the
38* above limitation may not apply to you.
39*
40* Copyright 2003 Micron Technology, Inc. All rights reserved.
41*
42* Rev Author Date Changes
43* --- ------ ---------- ---------------------------------------
44* 2.1 SPH 03/19/2002 - Second Release
45* - Fix tWR and several incompatability
46* between different simulators
47* 3.0 TFK 02/18/2003 - Added tDSS and tDSH timing checks.
48* - Added tDQSH and tDQSL timing checks.
49* 3.1 CAH 05/28/2003 - update all models to release version 3.1
50* (no changes to this model)
51* 3.2 JMK 06/16/2003 - updated all DDR400 models to support CAS Latency 3
52* 3.3 JMK 09/11/2003 - Added initialization sequence checks.
53* 4.0 JMK 12/01/2003 - Grouped parameters into "ddr_parameters.v"
54* - Fixed tWTR check
55* 4.1 JMK 01/14/2004 - Grouped specify parameters by speed grade
56* - Fixed mem_sizes parameter
57* 4.2 JMK 03/19/2004 - Fixed pulse width checking on Dqs
58* 4.3 JMK 04/27/2004 - Changed BL wire size in tb module
59* - Changed Dq_buf size to [15:0]
60* 5.0 JMK 06/16/2004 - Added read to write checking.
61* - Added read with precharge truncation to write checking.
62* - Added associative memory array to reduce memory consumption.
63* - Added checking for required DQS edges during write.
64* 5.1 JMK 08/16/2004 - Fixed checking for required DQS edges during write.
65* - Fixed wdqs_valid window.
66* 5.2 JMK 09/24/2004 - Read or Write without activate will be ignored.
67* 5.3 JMK 10/27/2004 - Added tMRD checking during Auto Refresh and Activate.
68* - Added tRFC checking during Load Mode and Precharge.
69* 5.4 JMK 12/13/2004 - The model will not respond to illegal command sequences.
70* 5.5 SPH 01/13/2005 - The model will issue a halt on illegal command sequences.
71* JMK 02/11/2005 - Changed the display format for numbers to hex.
72* 5.6 JMK 04/22/2005 - Fixed Write with auto precharge calculation.
73* 5.7 JMK 08/05/2005 - Changed conditions for read with precharge truncation error.
74* - Renamed parameters file with .vh extension.
75****************************************************************************************/
76
77// DO NOT CHANGE THE TIMESCALE
78// MAKE SURE YOUR SIMULATOR USE "PS" RESOLUTION
79`timescale 1ns / 1ps
80
81module ddr (Dq, Dqs, Addr, Ba, Clk, Clk_n, Cke, Cs_n, Ras_n, Cas_n, We_n, Dm);
82
83    `include "ddr_parameters.vh"
84
85    // Port Declarations
86    inout [DQ_BITS - 1 : 0] Dq;
87    inout [DQS_BITS - 1 : 0] Dqs;
88    input [ADDR_BITS - 1 : 0] Addr;
89    input [1 : 0] Ba;
90    input Clk;
91    input Clk_n;
92    input Cke;
93    input Cs_n;
94    input Ras_n;
95    input Cas_n;
96    input We_n;
97    input [DM_BITS - 1 : 0] Dm;
98
99    // Internal Wires (fixed width)
100    wire [15 : 0] Dq_in;
101    wire [1 : 0] Dqs_in;
102    wire [1 : 0] Dm_in;
103
104    assign Dq_in [DQ_BITS - 1 : 0] = Dq;
105    assign Dqs_in [DQS_BITS - 1 : 0] = Dqs;
106    assign Dm_in [DM_BITS - 1 : 0] = Dm;
107
108    // Data pair
109    reg [15 : 0] dq_rise;
110    reg [1 : 0] dm_rise;
111    reg [15 : 0] dq_fall;
112    reg [1 : 0] dm_fall;
113    reg [3 : 0] dm_pair;
114    reg [15 : 0] Dq_buf;
115
116    // Mode Register
117    reg [ADDR_BITS - 1 : 0] Mode_reg;
118
119    // Internal System Clock
120    reg CkeZ, Sys_clk;
121
122    // Internal Dqs initialize
123    reg Dqs_int;
124
125    // Dqs buffer
126    reg [DQS_BITS - 1 : 0] Dqs_out;
127
128    // Dq buffer
129    reg [DQ_BITS - 1 : 0] Dq_out;
130
131    // Read pipeline variables
132    reg Read_cmnd [0 : 6];
133    reg [1 : 0] Read_bank [0 : 6];
134    reg [COL_BITS - 1 : 0] Read_cols [0 : 6];
135
136    // Write pipeline variables
137    reg Write_cmnd [0 : 3];
138    reg [1 : 0] Write_bank [0 : 3];
139    reg [COL_BITS - 1 : 0] Write_cols [0 : 3];
140
141    // Auto precharge variables
142    reg Read_precharge [0 : 3];
143    reg Write_precharge [0 : 3];
144    integer Count_precharge [0 : 3];
145
146    // Manual precharge variables
147    reg A10_precharge [0 : 6];
148    reg [1 : 0] Bank_precharge [0 : 6];
149    reg Cmnd_precharge [0 : 6];
150
151    // Burst terminate variables
152    reg Cmnd_bst [0 : 6];
153
154    // Memory Banks
155`ifdef FULL_MEM
156    reg [DQ_BITS - 1 : 0] mem_array [0 : (1<<full_mem_bits)-1];
157`else
158    reg [DQ_BITS - 1 : 0] mem_array [0 : (1<<part_mem_bits)-1];
159    reg [full_mem_bits - 1 : 0] addr_array [0 : (1<<part_mem_bits)-1];
160    reg [part_mem_bits : 0] mem_used;
161    initial mem_used = 0;
162`endif
163
164    // Dqs edge checking
165    integer i;
166    reg [1:0] expect_pos_dqs;
167    reg [1:0] expect_neg_dqs;
168
169    // Burst counter
170    reg [COL_BITS - 1 : 0] Burst_counter;
171
172    // Precharge variables
173    reg Pc_b0, Pc_b1, Pc_b2, Pc_b3;
174
175    // Activate variables
176    reg Act_b0, Act_b1, Act_b2, Act_b3;
177
178    // Data IO variables
179    reg Data_in_enable;
180    reg Data_out_enable;
181
182    // Internal address mux variables
183    reg [1 : 0] Prev_bank;
184    reg [1 : 0] Bank_addr;
185    reg [COL_BITS - 1 : 0] Cols_addr, Cols_brst, Cols_temp;
186    reg [ADDR_BITS - 1 : 0] Rows_addr;
187    reg [ADDR_BITS - 1 : 0] B0_row_addr;
188    reg [ADDR_BITS - 1 : 0] B1_row_addr;
189    reg [ADDR_BITS - 1 : 0] B2_row_addr;
190    reg [ADDR_BITS - 1 : 0] B3_row_addr;
191
192    // DLL Reset variable
193    reg DLL_enable;
194    reg DLL_reset;
195    reg DLL_done;
196    integer DLL_count;
197    integer aref_count;
198    integer Prech_count;
199    reg power_up_done;
200
201    // Write DQS for tDSS, tDSH, tDQSH, tDQSL checks
202    wire wdqs_valid = Write_cmnd[2] || Write_cmnd[1] || Data_in_enable;
203
204    // Commands Decode
205    wire Active_enable = ~Cs_n & ~Ras_n & Cas_n & We_n;
206    wire Aref_enable = ~Cs_n & ~Ras_n & ~Cas_n & We_n;
207    wire Burst_term = ~Cs_n & Ras_n & Cas_n & ~We_n;
208    wire Ext_mode_enable = ~Cs_n & ~Ras_n & ~Cas_n & ~We_n & Ba[0] & ~Ba[1];
209    wire Mode_reg_enable = ~Cs_n & ~Ras_n & ~Cas_n & ~We_n & ~Ba[0] & ~Ba[1];
210    wire Prech_enable = ~Cs_n & ~Ras_n & Cas_n & ~We_n;
211    wire Read_enable = ~Cs_n & Ras_n & ~Cas_n & We_n;
212    wire Write_enable = ~Cs_n & Ras_n & ~Cas_n & ~We_n;
213
214    // Burst Length Decode
215    wire [3:0] burst_length = 1 << (Mode_reg[2:0]);
216    reg [3:0] read_precharge_truncation;
217
218    // CAS Latency Decode
219// wire [2:0] cas_latency_x2 = (Mode_reg[6:4] === 3'o6) ? 5 : 2*Mode_reg[6:4];
220    wire [2:0] cas_latency_x2 = 5;
221
222    // DQS Buffer
223    assign Dqs = Dqs_out;
224
225    // DQ Buffer
226    assign Dq = Dq_out;
227
228    // Timing Check
229    time MRD_chk;
230    time RFC_chk;
231    time RRD_chk;
232    time RAS_chk0, RAS_chk1, RAS_chk2, RAS_chk3;
233    time RAP_chk0, RAP_chk1, RAP_chk2, RAP_chk3;
234    time RC_chk0, RC_chk1, RC_chk2, RC_chk3;
235    time RCD_chk0, RCD_chk1, RCD_chk2, RCD_chk3;
236    time RP_chk0, RP_chk1, RP_chk2, RP_chk3;
237    time WR_chk0, WR_chk1, WR_chk2, WR_chk3;
238
239    initial begin
240        CkeZ = 1'b0;
241        Sys_clk = 1'b0;
242        {Pc_b0, Pc_b1, Pc_b2, Pc_b3} = 4'b0000;
243        {Act_b0, Act_b1, Act_b2, Act_b3} = 4'b1111;
244        Dqs_int = 1'b0;
245        Dqs_out = {DQS_BITS{1'bz}};
246        Dq_out = {DQ_BITS{1'bz}};
247        Data_in_enable = 1'b0;
248        Data_out_enable = 1'b0;
249        DLL_enable = 1'b0;
250        DLL_reset = 1'b0;
251        DLL_done = 1'b0;
252        DLL_count = 0;
253        aref_count = 0;
254        Prech_count = 0;
255        power_up_done = 0;
256        MRD_chk = 0;
257        RFC_chk = 0;
258        RRD_chk = 0;
259        {RAS_chk0, RAS_chk1, RAS_chk2, RAS_chk3} = 0;
260        {RAP_chk0, RAP_chk1, RAP_chk2, RAP_chk3} = 0;
261        {RC_chk0, RC_chk1, RC_chk2, RC_chk3} = 0;
262        {RCD_chk0, RCD_chk1, RCD_chk2, RCD_chk3} = 0;
263        {RP_chk0, RP_chk1, RP_chk2, RP_chk3} = 0;
264        {WR_chk0, WR_chk1, WR_chk2, WR_chk3} = 0;
265        $timeformat (-9, 3, " ns", 12);
266    end
267
268    // System Clock
269    always begin
270        @ (posedge Clk) begin
271            Sys_clk = CkeZ;
272            CkeZ = Cke;
273        end
274        @ (negedge Clk) begin
275            Sys_clk = 1'b0;
276        end
277    end
278
279    // Check to make sure that we have a Deselect or NOP command on the bus when CKE is brought high
280    always @(Cke) begin
281        if (Cke === 1'b1) begin
282            if (!((Cs_n) || (~Cs_n & Ras_n & Cas_n & We_n))) begin
283                $display ("%m: at time %t MEMORY ERROR: You must have a Deselect or NOP command applied", $time);
284                $display ("%m: when the Clock Enable is brought High.");
285            end
286        end
287    end
288
289    // Check the initialization sequence
290    initial begin
291        @ (posedge Cke) begin
292            @ (posedge DLL_enable) begin
293                aref_count = 0;
294                @ (posedge DLL_reset) begin
295                    @ (Prech_count) begin
296                        if (aref_count >= 2) begin
297                            if (Debug) $display ("%m: at time %t MEMORY: Power Up and Initialization Sequence is complete", $time);
298                            power_up_done = 1;
299                        end else begin
300                            aref_count = 0;
301                            @ (aref_count >= 2) begin
302                                if (Debug) $display ("%m: at time %t MEMORY: Power Up and Initialization Sequence is complete", $time);
303                                power_up_done = 1;
304                            end
305                        end
306                    end
307                end
308            end
309        end
310    end
311
312    // Write Memory
313    task write_mem;
314        input [full_mem_bits - 1 : 0] addr;
315        input [DQ_BITS - 1 : 0] data;
316        reg [part_mem_bits : 0] i;
317        begin
318`ifdef FULL_MEM
319            mem_array[addr] = data;
320`else
321            begin : loop
322                for (i = 0; i < mem_used; i = i + 1) begin
323                    if (addr_array[i] === addr) begin
324                        disable loop;
325                    end
326                end
327            end
328            if (i === mem_used) begin
329                if (i === (1<<part_mem_bits)) begin
330                    $display ("At time %t ERROR: Memory overflow.\n Write to Address %h with Data %h will be lost.\n You must increase the part_mem_bits parameter or define FULL_MEM.", $time, addr, data);
331                end else begin
332                    mem_used = mem_used + 1;
333                    addr_array[i] = addr;
334                end
335            end
336            mem_array[i] = data;
337`endif
338        end
339    endtask
340
341    // Read Memory
342    task read_mem;
343        input [full_mem_bits - 1 : 0] addr;
344        output [DQ_BITS - 1 : 0] data;
345        reg [part_mem_bits : 0] i;
346        begin
347`ifdef FULL_MEM
348            data = mem_array[addr];
349`else
350            begin : loop
351                for (i = 0; i < mem_used; i = i + 1) begin
352                    if (addr_array[i] === addr) begin
353                        disable loop;
354                    end
355                end
356            end
357            if (i <= mem_used) begin
358                data = mem_array[i];
359            end
360`endif
361        end
362    endtask
363
364    // Burst Decode
365    task Burst_Decode;
366    begin
367
368        // Advance Burst Counter
369        if (Burst_counter < burst_length) begin
370            Burst_counter = Burst_counter + 1;
371        end
372
373        // Burst Type
374        if (Mode_reg[3] === 1'b0) begin // Sequential Burst
375            Cols_temp = Cols_addr + 1;
376        end else if (Mode_reg[3] === 1'b1) begin // Interleaved Burst
377            Cols_temp[2] = Burst_counter[2] ^ Cols_brst[2];
378            Cols_temp[1] = Burst_counter[1] ^ Cols_brst[1];
379            Cols_temp[0] = Burst_counter[0] ^ Cols_brst[0];
380        end
381
382        // Burst Length
383        if (burst_length === 2) begin
384            Cols_addr [0] = Cols_temp [0];
385        end else if (burst_length === 4) begin
386            Cols_addr [1 : 0] = Cols_temp [1 : 0];
387        end else if (burst_length === 8) begin
388            Cols_addr [2 : 0] = Cols_temp [2 : 0];
389        end else begin
390            Cols_addr = Cols_temp;
391        end
392
393        // Data Counter
394        if (Burst_counter >= burst_length) begin
395            Data_in_enable = 1'b0;
396            Data_out_enable = 1'b0;
397            read_precharge_truncation = 4'h0;
398        end
399
400    end
401    endtask
402
403    // Manual Precharge Pipeline
404    task Manual_Precharge_Pipeline;
405    begin
406        // A10 Precharge Pipeline
407        A10_precharge[0] = A10_precharge[1];
408        A10_precharge[1] = A10_precharge[2];
409        A10_precharge[2] = A10_precharge[3];
410        A10_precharge[3] = A10_precharge[4];
411        A10_precharge[4] = A10_precharge[5];
412        A10_precharge[5] = A10_precharge[6];
413        A10_precharge[6] = 1'b0;
414
415        // Bank Precharge Pipeline
416        Bank_precharge[0] = Bank_precharge[1];
417        Bank_precharge[1] = Bank_precharge[2];
418        Bank_precharge[2] = Bank_precharge[3];
419        Bank_precharge[3] = Bank_precharge[4];
420        Bank_precharge[4] = Bank_precharge[5];
421        Bank_precharge[5] = Bank_precharge[6];
422        Bank_precharge[6] = 2'b0;
423
424        // Command Precharge Pipeline
425        Cmnd_precharge[0] = Cmnd_precharge[1];
426        Cmnd_precharge[1] = Cmnd_precharge[2];
427        Cmnd_precharge[2] = Cmnd_precharge[3];
428        Cmnd_precharge[3] = Cmnd_precharge[4];
429        Cmnd_precharge[4] = Cmnd_precharge[5];
430        Cmnd_precharge[5] = Cmnd_precharge[6];
431        Cmnd_precharge[6] = 1'b0;
432
433        // Terminate a Read if same bank or all banks
434        if (Cmnd_precharge[0] === 1'b1) begin
435            if (Bank_precharge[0] === Bank_addr || A10_precharge[0] === 1'b1) begin
436                if (Data_out_enable === 1'b1) begin
437                    Data_out_enable = 1'b0;
438                    read_precharge_truncation = 4'hF;
439                end
440            end
441        end
442    end
443    endtask
444
445    // Burst Terminate Pipeline
446    task Burst_Terminate_Pipeline;
447    begin
448        // Command Precharge Pipeline
449        Cmnd_bst[0] = Cmnd_bst[1];
450        Cmnd_bst[1] = Cmnd_bst[2];
451        Cmnd_bst[2] = Cmnd_bst[3];
452        Cmnd_bst[3] = Cmnd_bst[4];
453        Cmnd_bst[4] = Cmnd_bst[5];
454        Cmnd_bst[5] = Cmnd_bst[6];
455        Cmnd_bst[6] = 1'b0;
456
457        // Terminate a Read regardless of banks
458        if (Cmnd_bst[0] === 1'b1 && Data_out_enable === 1'b1) begin
459            Data_out_enable = 1'b0;
460        end
461    end
462    endtask
463
464    // Dq and Dqs Drivers
465    task Dq_Dqs_Drivers;
466    begin
467        // read command pipeline
468        Read_cmnd [0] = Read_cmnd [1];
469        Read_cmnd [1] = Read_cmnd [2];
470        Read_cmnd [2] = Read_cmnd [3];
471        Read_cmnd [3] = Read_cmnd [4];
472        Read_cmnd [4] = Read_cmnd [5];
473        Read_cmnd [5] = Read_cmnd [6];
474        Read_cmnd [6] = 1'b0;
475
476        // read bank pipeline
477        Read_bank [0] = Read_bank [1];
478        Read_bank [1] = Read_bank [2];
479        Read_bank [2] = Read_bank [3];
480        Read_bank [3] = Read_bank [4];
481        Read_bank [4] = Read_bank [5];
482        Read_bank [5] = Read_bank [6];
483        Read_bank [6] = 2'b0;
484
485        // read column pipeline
486        Read_cols [0] = Read_cols [1];
487        Read_cols [1] = Read_cols [2];
488        Read_cols [2] = Read_cols [3];
489        Read_cols [3] = Read_cols [4];
490        Read_cols [4] = Read_cols [5];
491        Read_cols [5] = Read_cols [6];
492        Read_cols [6] = 0;
493
494        // Initialize Read command
495        if (Read_cmnd [0] === 1'b1) begin
496            Data_out_enable = 1'b1;
497            Bank_addr = Read_bank [0];
498            Cols_addr = Read_cols [0];
499            Cols_brst = Cols_addr [2 : 0];
500            Burst_counter = 0;
501
502            // Row Address Mux
503            case (Bank_addr)
504                2'd0 : Rows_addr = B0_row_addr;
505                2'd1 : Rows_addr = B1_row_addr;
506                2'd2 : Rows_addr = B2_row_addr;
507                2'd3 : Rows_addr = B3_row_addr;
508                default : $display ("At time %t ERROR: Invalid Bank Address", $time);
509            endcase
510        end
511
512        // Toggle Dqs during Read command
513        if (Data_out_enable === 1'b1) begin
514            Dqs_int = 1'b0;
515            if (Dqs_out === {DQS_BITS{1'b0}}) begin
516                Dqs_out = {DQS_BITS{1'b1}};
517            end else if (Dqs_out === {DQS_BITS{1'b1}}) begin
518                Dqs_out = {DQS_BITS{1'b0}};
519            end else begin
520                Dqs_out = {DQS_BITS{1'b0}};
521            end
522        end else if (Data_out_enable === 1'b0 && Dqs_int === 1'b0) begin
523            Dqs_out = {DQS_BITS{1'bz}};
524        end
525
526        // Initialize dqs for Read command
527        if (Read_cmnd [2] === 1'b1) begin
528            if (Data_out_enable === 1'b0) begin
529                Dqs_int = 1'b1;
530                Dqs_out = {DQS_BITS{1'b0}};
531            end
532        end
533
534        // Read latch
535        if (Data_out_enable === 1'b1) begin
536            // output data
537            read_mem({Bank_addr, Rows_addr, Cols_addr}, Dq_out);
538            if (Debug) begin
539                $display ("At time %t READ : Bank = %h, Row = %h, Col = %h, Data = %h", $time, Bank_addr, Rows_addr, Cols_addr, Dq_out);
540            end
541        end else begin
542            Dq_out = {DQ_BITS{1'bz}};
543        end
544    end
545    endtask
546
547    // Write FIFO and DM Mask Logic
548    task Write_FIFO_DM_Mask_Logic;
549    begin
550        // Write command pipeline
551        Write_cmnd [0] = Write_cmnd [1];
552        Write_cmnd [1] = Write_cmnd [2];
553        Write_cmnd [2] = Write_cmnd [3];
554        Write_cmnd [3] = 1'b0;
555
556        // Write command pipeline
557        Write_bank [0] = Write_bank [1];
558        Write_bank [1] = Write_bank [2];
559        Write_bank [2] = Write_bank [3];
560        Write_bank [3] = 2'b0;
561
562        // Write column pipeline
563        Write_cols [0] = Write_cols [1];
564        Write_cols [1] = Write_cols [2];
565        Write_cols [2] = Write_cols [3];
566        Write_cols [3] = {COL_BITS{1'b0}};
567
568        // Initialize Write command
569        if (Write_cmnd [0] === 1'b1) begin
570            Data_in_enable = 1'b1;
571            Bank_addr = Write_bank [0];
572            Cols_addr = Write_cols [0];
573            Cols_brst = Cols_addr [2 : 0];
574            Burst_counter = 0;
575
576            // Row address mux
577            case (Bank_addr)
578                2'd0 : Rows_addr = B0_row_addr;
579                2'd1 : Rows_addr = B1_row_addr;
580                2'd2 : Rows_addr = B2_row_addr;
581                2'd3 : Rows_addr = B3_row_addr;
582                default : $display ("At time %t ERROR: Invalid Row Address", $time);
583            endcase
584        end
585
586        // Write data
587        if (Data_in_enable === 1'b1) begin
588
589            // Data Buffer
590            read_mem({Bank_addr, Rows_addr, Cols_addr}, Dq_buf);
591
592            // write negedge Dqs on posedge Sys_clk
593            if (Sys_clk) begin
594                if (!dm_fall[0]) begin
595                    Dq_buf [ 7 : 0] = dq_fall [ 7 : 0];
596                end
597                if (!dm_fall[1]) begin
598                    Dq_buf [15 : 8] = dq_fall [15 : 8];
599                end
600                if (~&dm_fall) begin
601                    if (Debug) begin
602                        $display ("At time %t WRITE: Bank = %h, Row = %h, Col = %h, Data = %h", $time, Bank_addr, Rows_addr, Cols_addr, Dq_buf[DQ_BITS-1:0]);
603                    end
604                end
605            // write posedge Dqs on negedge Sys_clk
606            end else begin
607                if (!dm_rise[0]) begin
608                    Dq_buf [ 7 : 0] = dq_rise [ 7 : 0];
609                end
610                if (!dm_rise[1]) begin
611                    Dq_buf [15 : 8] = dq_rise [15 : 8];
612                end
613                if (~&dm_rise) begin
614                    if (Debug) begin
615                        $display ("At time %t WRITE: Bank = %h, Row = %h, Col = %h, Data = %h", $time, Bank_addr, Rows_addr, Cols_addr, Dq_buf[DQ_BITS-1:0]);
616                    end
617                end
618            end
619
620            // Write Data
621            write_mem({Bank_addr, Rows_addr, Cols_addr}, Dq_buf);
622
623            // tWR start and tWTR check
624            if (Sys_clk && &dm_pair === 1'b0) begin
625                case (Bank_addr)
626                    2'd0 : WR_chk0 = $time;
627                    2'd1 : WR_chk1 = $time;
628                    2'd2 : WR_chk2 = $time;
629                    2'd3 : WR_chk3 = $time;
630                    default : $display ("At time %t ERROR: Invalid Bank Address (tWR)", $time);
631                endcase
632
633                // tWTR check
634                if (Read_enable === 1'b1) begin
635                    $display ("At time %t ERROR: tWTR violation during Read", $time);
636                end
637            end
638        end
639    end
640    endtask
641
642    // Auto Precharge Calculation
643    task Auto_Precharge_Calculation;
644    begin
645        // Precharge counter
646        if (Read_precharge [0] === 1'b1 || Write_precharge [0] === 1'b1) begin
647            Count_precharge [0] = Count_precharge [0] + 1;
648        end
649        if (Read_precharge [1] === 1'b1 || Write_precharge [1] === 1'b1) begin
650            Count_precharge [1] = Count_precharge [1] + 1;
651        end
652        if (Read_precharge [2] === 1'b1 || Write_precharge [2] === 1'b1) begin
653            Count_precharge [2] = Count_precharge [2] + 1;
654        end
655        if (Read_precharge [3] === 1'b1 || Write_precharge [3] === 1'b1) begin
656            Count_precharge [3] = Count_precharge [3] + 1;
657        end
658
659        // Read with AutoPrecharge Calculation
660        // The device start internal precharge when:
661        // 1. Meet tRAS requirement
662        // 2. BL/2 cycles after command
663        if ((Read_precharge[0] === 1'b1) && ($time - RAS_chk0 >= tRAS)) begin
664            if (Count_precharge[0] >= burst_length/2) begin
665                Pc_b0 = 1'b1;
666                Act_b0 = 1'b0;
667                RP_chk0 = $time;
668                Read_precharge[0] = 1'b0;
669            end
670        end
671        if ((Read_precharge[1] === 1'b1) && ($time - RAS_chk1 >= tRAS)) begin
672            if (Count_precharge[1] >= burst_length/2) begin
673                Pc_b1 = 1'b1;
674                Act_b1 = 1'b0;
675                RP_chk1 = $time;
676                Read_precharge[1] = 1'b0;
677            end
678        end
679        if ((Read_precharge[2] === 1'b1) && ($time - RAS_chk2 >= tRAS)) begin
680            if (Count_precharge[2] >= burst_length/2) begin
681                Pc_b2 = 1'b1;
682                Act_b2 = 1'b0;
683                RP_chk2 = $time;
684                Read_precharge[2] = 1'b0;
685            end
686        end
687        if ((Read_precharge[3] === 1'b1) && ($time - RAS_chk3 >= tRAS)) begin
688            if (Count_precharge[3] >= burst_length/2) begin
689                Pc_b3 = 1'b1;
690                Act_b3 = 1'b0;
691                RP_chk3 = $time;
692                Read_precharge[3] = 1'b0;
693            end
694        end
695
696        // Write with AutoPrecharge Calculation
697        // The device start internal precharge when:
698        // 1. Meet tRAS requirement
699        // 2. Write Latency PLUS BL/2 cycles PLUS tWR after Write command
700
701        if ((Write_precharge[0] === 1'b1) && ($time - RAS_chk0 >= tRAS)) begin
702            if ((Count_precharge[0] >= burst_length/2+1) && ($time - WR_chk0 >= tWR)) begin
703                Pc_b0 = 1'b1;
704                Act_b0 = 1'b0;
705                RP_chk0 = $time;
706                Write_precharge[0] = 1'b0;
707            end
708        end
709        if ((Write_precharge[1] === 1'b1) && ($time - RAS_chk1 >= tRAS)) begin
710            if ((Count_precharge[1] >= burst_length/2+1) && ($time - WR_chk1 >= tWR)) begin
711                Pc_b1 = 1'b1;
712                Act_b1 = 1'b0;
713                RP_chk1 = $time;
714                Write_precharge[1] = 1'b0;
715            end
716        end
717        if ((Write_precharge[2] === 1'b1) && ($time - RAS_chk2 >= tRAS)) begin
718            if ((Count_precharge[2] >= burst_length/2+1) && ($time - WR_chk2 >= tWR)) begin
719                Pc_b2 = 1'b1;
720                Act_b2 = 1'b0;
721                RP_chk2 = $time;
722                Write_precharge[2] = 1'b0;
723            end
724        end
725        if ((Write_precharge[3] === 1'b1) && ($time - RAS_chk3 >= tRAS)) begin
726            if ((Count_precharge[3] >= burst_length/2+1) && ($time - WR_chk3 >= tWR)) begin
727                Pc_b3 = 1'b1;
728                Act_b3 = 1'b0;
729                RP_chk3 = $time;
730                Write_precharge[3] = 1'b0;
731            end
732        end
733    end
734    endtask
735
736    // DLL Counter
737    task DLL_Counter;
738    begin
739        if (DLL_reset === 1'b1 && DLL_done === 1'b0) begin
740            DLL_count = DLL_count + 1;
741            if (DLL_count >= 200) begin
742                DLL_done = 1'b1;
743            end
744        end
745    end
746    endtask
747
748    // Control Logic
749    task Control_Logic;
750    begin
751        // Auto Refresh
752        if (Aref_enable === 1'b1) begin
753            // Display Debug Message
754            if (Debug) begin
755                $display ("At time %t AREF : Auto Refresh", $time);
756            end
757
758            // Precharge to Auto Refresh
759            if (($time - RP_chk0 < tRP) || ($time - RP_chk1 < tRP) ||
760                ($time - RP_chk2 < tRP) || ($time - RP_chk3 < tRP)) begin
761                $display ("At time %t ERROR: tRP violation during Auto Refresh", $time);
762            end
763
764            // LMR/EMR to Auto Refresh
765            if ($time - MRD_chk < tMRD) begin
766                $display ("At time %t ERROR: tMRD violation during Auto Refresh", $time);
767            end
768
769            // Auto Refresh to Auto Refresh
770            if ($time - RFC_chk < tRFC) begin
771                $display ("At time %t ERROR: tRFC violation during Auto Refresh", $time);
772            end
773
774            // Precharge to Auto Refresh
775            if (Pc_b0 === 1'b0 || Pc_b1 === 1'b0 || Pc_b2 === 1'b0 || Pc_b3 === 1'b0) begin
776                $display ("At time %t ERROR: All banks must be Precharged before Auto Refresh", $time);
777                if (!no_halt) $stop (0);
778            end else begin
779                aref_count = aref_count + 1;
780                RFC_chk = $time;
781            end
782        end
783
784        // Extended Mode Register
785        if (Ext_mode_enable === 1'b1) begin
786            if (Debug) begin
787                $display ("At time %t EMR : Extended Mode Register", $time);
788            end
789
790            // Precharge to LMR/EMR
791            if (($time - RP_chk0 < tRP) || ($time - RP_chk1 < tRP) ||
792                ($time - RP_chk2 < tRP) || ($time - RP_chk3 < tRP)) begin
793                $display ("At time %t ERROR: tRP violation during Extended Mode Register", $time);
794            end
795
796            // LMR/EMR to LMR/EMR
797            if ($time - MRD_chk < tMRD) begin
798                $display ("At time %t ERROR: tMRD violation during Extended Mode Register", $time);
799            end
800
801            // Auto Refresh to LMR/EMR
802            if ($time - RFC_chk < tRFC) begin
803                $display ("At time %t ERROR: tRFC violation during Extended Mode Register", $time);
804            end
805
806            // Precharge to LMR/EMR
807            if (Pc_b0 === 1'b0 || Pc_b1 === 1'b0 || Pc_b2 === 1'b0 || Pc_b3 === 1'b0) begin
808                $display ("At time %t ERROR: all banks must be Precharged before Extended Mode Register", $time);
809                if (!no_halt) $stop (0);
810            end else begin
811                if (Addr[0] === 1'b0) begin
812                    DLL_enable = 1'b1;
813                    if (Debug) begin
814                        $display ("At time %t EMR : Enable DLL", $time);
815                    end
816                end else begin
817                    DLL_enable = 1'b0;
818                    if (Debug) begin
819                        $display ("At time %t EMR : Disable DLL", $time);
820                    end
821                end
822                MRD_chk = $time;
823            end
824        end
825
826        // Load Mode Register
827        if (Mode_reg_enable === 1'b1) begin
828            if (Debug) begin
829                $display ("At time %t LMR : Load Mode Register", $time);
830            end
831
832            // Precharge to LMR/EMR
833            if (($time - RP_chk0 < tRP) || ($time - RP_chk1 < tRP) ||
834                ($time - RP_chk2 < tRP) || ($time - RP_chk3 < tRP)) begin
835                $display ("At time %t ERROR: tRP violation during Load Mode Register", $time);
836            end
837
838            // LMR/EMR to LMR/EMR
839            if ($time - MRD_chk < tMRD) begin
840                $display ("At time %t ERROR: tMRD violation during Load Mode Register", $time);
841            end
842
843            // Auto Refresh to LMR/EMR
844            if ($time - RFC_chk < tRFC) begin
845                $display ("At time %t ERROR: tRFC violation during Load Mode Register", $time);
846            end
847
848            // Precharge to LMR/EMR
849            if (Pc_b0 === 1'b0 || Pc_b1 === 1'b0 || Pc_b2 === 1'b0 || Pc_b3 === 1'b0) begin
850                $display ("At time %t ERROR: all banks must be Precharged before Load Mode Register", $time);
851            end else begin
852                // Register Mode
853                Mode_reg = Addr;
854
855                // DLL Reset
856                if (DLL_enable === 1'b1 && Addr [8] === 1'b1) begin
857                    DLL_reset = 1'b1;
858                    DLL_done = 1'b0;
859                    DLL_count = 0;
860                end else if (DLL_enable === 1'b1 && DLL_reset === 1'b0 && Addr [8] === 1'b0) begin
861                    $display ("At time %t ERROR: DLL is ENABLE: DLL RESET is required.", $time);
862                end else if (DLL_enable === 1'b0 && Addr [8] === 1'b1) begin
863                    $display ("At time %t ERROR: DLL is DISABLE: DLL RESET will be ignored.", $time);
864                end
865
866                // Burst Length
867                case (Addr [2 : 0])
868                    3'b001 : $display ("At time %t LMR : Burst Length = 2", $time);
869                    3'b010 : $display ("At time %t LMR : Burst Length = 4", $time);
870                    3'b011 : $display ("At time %t LMR : Burst Length = 8", $time);
871                    default : $display ("At time %t ERROR: Burst Length not supported", $time);
872                endcase
873
874                // CAS Latency
875                case (Addr [6 : 4])
876                    3'b010 : $display ("At time %t LMR : CAS Latency = 2", $time);
877                    3'b110 : $display ("At time %t LMR : CAS Latency = 2.5", $time);
878                    3'b011 : $display ("At time %t LMR : CAS Latency = 3", $time);
879                    default : $display ("At time %t ERROR: CAS Latency not supported", $time);
880                endcase
881
882                // Record current tMRD time
883                MRD_chk = $time;
884            end
885        end
886
887        // Activate Block
888        if (Active_enable === 1'b1) begin
889            if (!(power_up_done)) begin
890                $display ("%m: at time %t ERROR: Power Up and Initialization Sequence not completed before executing Activate command", $time);
891            end
892            // Display Debug Message
893            if (Debug) begin
894                $display ("At time %t ACT : Bank = %h, Row = %h", $time, Ba, Addr);
895            end
896
897            // Activate to Activate (different bank)
898            if ((Prev_bank != Ba) && ($time - RRD_chk < tRRD)) begin
899                $display ("At time %t ERROR: tRRD violation during Activate bank %h", $time, Ba);
900            end
901
902            // LMR/EMR to Activate
903            if ($time - MRD_chk < tMRD) begin
904                $display ("At time %t ERROR: tMRD violation during Activate bank %h", $time, Ba);
905            end
906
907            // AutoRefresh to Activate
908            if ($time - RFC_chk < tRFC) begin
909                $display ("At time %t ERROR: tRFC violation during Activate bank %h", $time, Ba);
910            end
911
912            // Precharge to Activate
913            if ((Ba === 2'b00 && Pc_b0 === 1'b0) || (Ba === 2'b01 && Pc_b1 === 1'b0) ||
914                (Ba === 2'b10 && Pc_b2 === 1'b0) || (Ba === 2'b11 && Pc_b3 === 1'b0)) begin
915                $display ("At time %t ERROR: Bank = %h is already activated - Command Ignored", $time, Ba);
916                if (!no_halt) $stop (0);
917            end else begin
918                // Activate Bank 0
919                if (Ba === 2'b00 && Pc_b0 === 1'b1) begin
920                    // Activate to Activate (same bank)
921                    if ($time - RC_chk0 < tRC) begin
922                        $display ("At time %t ERROR: tRC violation during Activate bank %h", $time, Ba);
923                    end
924
925                    // Precharge to Activate
926                    if ($time - RP_chk0 < tRP) begin
927                        $display ("At time %t ERROR: tRP violation during Activate bank %h", $time, Ba);
928                    end
929
930                    // Record variables for checking violation
931                    Act_b0 = 1'b1;
932                    Pc_b0 = 1'b0;
933                    B0_row_addr = Addr;
934                    RC_chk0 = $time;
935                    RCD_chk0 = $time;
936                    RAS_chk0 = $time;
937                    RAP_chk0 = $time;
938                end
939
940                // Activate Bank 1
941                if (Ba === 2'b01 && Pc_b1 === 1'b1) begin
942                    // Activate to Activate (same bank)
943                    if ($time - RC_chk1 < tRC) begin
944                        $display ("At time %t ERROR: tRC violation during Activate bank %h", $time, Ba);
945                    end
946
947                    // Precharge to Activate
948                    if ($time - RP_chk1 < tRP) begin
949                        $display ("At time %t ERROR: tRP violation during Activate bank %h", $time, Ba);
950                    end
951
952                    // Record variables for checking violation
953                    Act_b1 = 1'b1;
954                    Pc_b1 = 1'b0;
955                    B1_row_addr = Addr;
956                    RC_chk1 = $time;
957                    RCD_chk1 = $time;
958                    RAS_chk1 = $time;
959                    RAP_chk1 = $time;
960                end
961
962                // Activate Bank 2
963                if (Ba === 2'b10 && Pc_b2 === 1'b1) begin
964                    // Activate to Activate (same bank)
965                    if ($time - RC_chk2 < tRC) begin
966                        $display ("At time %t ERROR: tRC violation during Activate bank %h", $time, Ba);
967                    end
968
969                    // Precharge to Activate
970                    if ($time - RP_chk2 < tRP) begin
971                        $display ("At time %t ERROR: tRP violation during Activate bank %h", $time, Ba);
972                    end
973
974                    // Record variables for checking violation
975                    Act_b2 = 1'b1;
976                    Pc_b2 = 1'b0;
977                    B2_row_addr = Addr;
978                    RC_chk2 = $time;
979                    RCD_chk2 = $time;
980                    RAS_chk2 = $time;
981                    RAP_chk2 = $time;
982                end
983
984                // Activate Bank 3
985                if (Ba === 2'b11 && Pc_b3 === 1'b1) begin
986                    // Activate to Activate (same bank)
987                    if ($time - RC_chk3 < tRC) begin
988                        $display ("At time %t ERROR: tRC violation during Activate bank %h", $time, Ba);
989                    end
990
991                    // Precharge to Activate
992                    if ($time - RP_chk3 < tRP) begin
993                        $display ("At time %t ERROR: tRP violation during Activate bank %h", $time, Ba);
994                    end
995
996                    // Record variables for checking violation
997                    Act_b3 = 1'b1;
998                    Pc_b3 = 1'b0;
999                    B3_row_addr = Addr;
1000                    RC_chk3 = $time;
1001                    RCD_chk3 = $time;
1002                    RAS_chk3 = $time;
1003                    RAP_chk3 = $time;
1004                end
1005                // Record variable for checking violation
1006                RRD_chk = $time;
1007                Prev_bank = Ba;
1008                read_precharge_truncation[Ba] = 1'b0;
1009            end
1010        end
1011
1012        // Precharge Block - consider NOP if bank already precharged or in process of precharging
1013        if (Prech_enable === 1'b1) begin
1014            // Display Debug Message
1015            if (Debug) begin
1016                $display ("At time %t PRE : Addr[10] = %b, Bank = %b", $time, Addr[10], Ba);
1017            end
1018
1019            // LMR/EMR to Precharge
1020            if ($time - MRD_chk < tMRD) begin
1021                $display ("At time %t ERROR: tMRD violation during Precharge", $time);
1022            end
1023
1024            // AutoRefresh to Precharge
1025            if ($time - RFC_chk < tRFC) begin
1026                $display ("At time %t ERROR: tRFC violation during Precharge", $time);
1027            end
1028
1029            // Precharge bank 0
1030            if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b00)) && Act_b0 === 1'b1) begin
1031                Act_b0 = 1'b0;
1032                Pc_b0 = 1'b1;
1033                RP_chk0 = $time;
1034
1035                // Activate to Precharge Bank
1036                if ($time - RAS_chk0 < tRAS) begin
1037                    $display ("At time %t ERROR: tRAS violation during Precharge", $time);
1038                end
1039
1040                // tWR violation check for Write
1041                if ($time - WR_chk0 < tWR) begin
1042                    $display ("At time %t ERROR: tWR violation during Precharge", $time);
1043                end
1044            end
1045
1046            // Precharge bank 1
1047            if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b01)) && Act_b1 === 1'b1) begin
1048                Act_b1 = 1'b0;
1049                Pc_b1 = 1'b1;
1050                RP_chk1 = $time;
1051
1052                // Activate to Precharge Bank 1
1053                if ($time - RAS_chk1 < tRAS) begin
1054                    $display ("At time %t ERROR: tRAS violation during Precharge", $time);
1055                end
1056
1057                // tWR violation check for Write
1058                if ($time - WR_chk1 < tWR) begin
1059                    $display ("At time %t ERROR: tWR violation during Precharge", $time);
1060                end
1061            end
1062
1063            // Precharge bank 2
1064            if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b10)) && Act_b2 === 1'b1) begin
1065                Act_b2 = 1'b0;
1066                Pc_b2 = 1'b1;
1067                RP_chk2 = $time;
1068
1069                // Activate to Precharge Bank 2
1070                if ($time - RAS_chk2 < tRAS) begin
1071                    $display ("At time %t ERROR: tRAS violation during Precharge", $time);
1072                end
1073
1074                // tWR violation check for Write
1075                if ($time - WR_chk2 < tWR) begin
1076                    $display ("At time %t ERROR: tWR violation during Precharge", $time);
1077                end
1078            end
1079
1080            // Precharge bank 3
1081            if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b11)) && Act_b3 === 1'b1) begin
1082                Act_b3 = 1'b0;
1083                Pc_b3 = 1'b1;
1084                RP_chk3 = $time;
1085
1086                // Activate to Precharge Bank 3
1087                if ($time - RAS_chk3 < tRAS) begin
1088                    $display ("At time %t ERROR: tRAS violation during Precharge", $time);
1089                end
1090
1091                // tWR violation check for Write
1092                if ($time - WR_chk3 < tWR) begin
1093                    $display ("At time %t ERROR: tWR violation during Precharge", $time);
1094                end
1095            end
1096
1097            // Prech_count is to make sure we have met part of the initialization sequence
1098            Prech_count = Prech_count + 1;
1099
1100            // Pipeline for READ
1101            A10_precharge [cas_latency_x2] = Addr[10];
1102            Bank_precharge[cas_latency_x2] = Ba;
1103            Cmnd_precharge[cas_latency_x2] = 1'b1;
1104        end
1105
1106        // Burst terminate
1107        if (Burst_term === 1'b1) begin
1108            // Display Debug Message
1109            if (Debug) begin
1110                $display ("At time %t BST : Burst Terminate",$time);
1111            end
1112
1113            if (Data_in_enable === 1'b1) begin
1114                // Illegal to burst terminate a Write
1115                $display ("At time %t ERROR: It's illegal to burst terminate a Write", $time);
1116                if (!no_halt) $stop (0);
1117            end else if (Read_precharge[0] === 1'b1 || Read_precharge[1] === 1'b1 ||
1118                // Illegal to burst terminate a Read with Auto Precharge
1119                Read_precharge[2] === 1'b1 || Read_precharge[3] === 1'b1) begin
1120                $display ("At time %t ERROR: It's illegal to burst terminate a Read with Auto Precharge", $time);
1121                if (!no_halt) $stop (0);
1122            end else begin
1123                // Burst Terminate Command Pipeline for Read
1124                Cmnd_bst[cas_latency_x2] = 1'b1;
1125            end
1126
1127        end
1128
1129        // Read Command
1130        if (Read_enable === 1'b1) begin
1131            if (!(power_up_done)) begin
1132                $display ("%m: at time %t ERROR: Power Up and Initialization Sequence not completed before executing Read Command", $time);
1133            end
1134            // Check for DLL reset before Read
1135            if (DLL_reset === 1 && DLL_done === 0) begin
1136                $display ("%m: at time %t ERROR: You need to wait 200 tCK after DLL Reset Enable to Read, Not %0d clocks.", $time, DLL_count);
1137            end
1138            // Display Debug Message
1139            if (Debug) begin
1140                $display ("At time %t READ : Bank = %h, Col = %h", $time, Ba, {Addr [11], Addr [9 : 0]});
1141            end
1142
1143            // Terminate a Write
1144            if (Data_in_enable === 1'b1) begin
1145                Data_in_enable = 1'b0;
1146            end
1147
1148            // Activate to Read without Auto Precharge
1149            if ((Addr [10] === 1'b0 && Ba === 2'b00 && $time - RCD_chk0 < tRCD) ||
1150                (Addr [10] === 1'b0 && Ba === 2'b01 && $time - RCD_chk1 < tRCD) ||
1151                (Addr [10] === 1'b0 && Ba === 2'b10 && $time - RCD_chk2 < tRCD) ||
1152                (Addr [10] === 1'b0 && Ba === 2'b11 && $time - RCD_chk3 < tRCD)) begin
1153                $display("At time %t ERROR: tRCD violation during Read", $time);
1154            end
1155
1156            // Activate to Read with Auto Precharge
1157            if ((Addr [10] === 1'b1 && Ba === 2'b00 && $time - RAP_chk0 < tRAP) ||
1158                (Addr [10] === 1'b1 && Ba === 2'b01 && $time - RAP_chk1 < tRAP) ||
1159                (Addr [10] === 1'b1 && Ba === 2'b10 && $time - RAP_chk2 < tRAP) ||
1160                (Addr [10] === 1'b1 && Ba === 2'b11 && $time - RAP_chk3 < tRAP)) begin
1161                $display ("At time %t ERROR: tRAP violation during Read", $time);
1162            end
1163
1164            // Interrupt a Read with Auto Precharge (same bank only)
1165            if (Read_precharge [Ba] === 1'b1) begin
1166                $display ("At time %t ERROR: It's illegal to interrupt a Read with Auto Precharge", $time);
1167                if (!no_halt) $stop (0);
1168                // Cancel Auto Precharge
1169                if (Addr[10] === 1'b0) begin
1170                    Read_precharge [Ba]= 1'b0;
1171                end
1172            end
1173            // Activate to Read
1174            if ((Ba === 2'b00 && Pc_b0 === 1'b1) || (Ba === 2'b01 && Pc_b1 === 1'b1) ||
1175                (Ba === 2'b10 && Pc_b2 === 1'b1) || (Ba === 2'b11 && Pc_b3 === 1'b1)) begin
1176                $display("At time %t ERROR: Bank is not Activated for Read", $time);
1177                if (!no_halt) $stop (0);
1178            end else begin
1179                // CAS Latency pipeline
1180                Read_cmnd[cas_latency_x2] = 1'b1;
1181                Read_bank[cas_latency_x2] = Ba;
1182                Read_cols[cas_latency_x2] = {Addr [ADDR_BITS - 1 : 11], Addr [9 : 0]};
1183                // Auto Precharge
1184                if (Addr[10] === 1'b1) begin
1185                    Read_precharge [Ba]= 1'b1;
1186                    Count_precharge [Ba]= 0;
1187                end
1188            end
1189        end
1190
1191        // Write Command
1192        if (Write_enable === 1'b1) begin
1193            if (!(power_up_done)) begin
1194                $display ("%m: at time %t ERROR: Power Up and Initialization Sequence not completed before executing Write Command", $time);
1195                if (!no_halt) $stop (0);
1196            end
1197            // display debug message
1198            if (Debug) begin
1199                $display ("At time %t WRITE: Bank = %h, Col = %h", $time, Ba, {Addr [ADDR_BITS - 1 : 11], Addr [9 : 0]});
1200            end
1201
1202            // Activate to Write
1203            if ((Ba === 2'b00 && $time - RCD_chk0 < tRCD) ||
1204                (Ba === 2'b01 && $time - RCD_chk1 < tRCD) ||
1205                (Ba === 2'b10 && $time - RCD_chk2 < tRCD) ||
1206                (Ba === 2'b11 && $time - RCD_chk3 < tRCD)) begin
1207                $display("At time %t ERROR: tRCD violation during Write to Bank %h", $time, Ba);
1208            end
1209
1210            // Read to Write
1211            if (Read_cmnd[0] || Read_cmnd[1] || Read_cmnd[2] || Read_cmnd[3] ||
1212                Read_cmnd[4] || Read_cmnd[5] || Read_cmnd[6] || (Burst_counter < burst_length)) begin
1213                if (Data_out_enable || read_precharge_truncation[Ba]) begin
1214                    $display("At time %t ERROR: Read to Write violation", $time);
1215                end
1216            end
1217
1218            // Interrupt a Write with Auto Precharge (same bank only)
1219            if (Write_precharge [Ba] === 1'b1) begin
1220                $display ("At time %t ERROR: it's illegal to interrupt a Write with Auto Precharge", $time);
1221                if (!no_halt) $stop (0);
1222                // Cancel Auto Precharge
1223                if (Addr[10] === 1'b0) begin
1224                    Write_precharge [Ba]= 1'b0;
1225                end
1226            end
1227            // Activate to Write
1228            if ((Ba === 2'b00 && Pc_b0 === 1'b1) || (Ba === 2'b01 && Pc_b1 === 1'b1) ||
1229                (Ba === 2'b10 && Pc_b2 === 1'b1) || (Ba === 2'b11 && Pc_b3 === 1'b1)) begin
1230                $display("At time %t ERROR: Bank is not Activated for Write", $time);
1231                if (!no_halt) $stop (0);
1232            end else begin
1233                // Pipeline for Write
1234                Write_cmnd [3] = 1'b1;
1235                Write_bank [3] = Ba;
1236                Write_cols [3] = {Addr [ADDR_BITS - 1 : 11], Addr [9 : 0]};
1237                // Auto Precharge
1238                if (Addr[10] === 1'b1) begin
1239                    Write_precharge [Ba]= 1'b1;
1240                    Count_precharge [Ba]= 0;
1241                end
1242            end
1243        end
1244    end
1245    endtask
1246
1247    task check_neg_dqs;
1248    begin
1249        if (Write_cmnd[2] || Write_cmnd[1] || Data_in_enable) begin
1250            for (i=0; i<DQS_BITS; i=i+1) begin
1251                if (expect_neg_dqs[i]) begin
1252                    $display ("At time %t ERROR: Negative DQS[%1d] transition required.", $time, i);
1253                end
1254                expect_neg_dqs[i] = 1'b1;
1255            end
1256        end else begin
1257            expect_pos_dqs = 0;
1258            expect_neg_dqs = 0;
1259        end
1260    end
1261    endtask
1262
1263    task check_pos_dqs;
1264    begin
1265        if (Write_cmnd[2] || Write_cmnd[1] || Data_in_enable) begin
1266            for (i=0; i<DQS_BITS; i=i+1) begin
1267                if (expect_pos_dqs[i]) begin
1268                    $display ("At time %t ERROR: Positive DQS[%1d] transition required.", $time, i);
1269                end
1270                expect_pos_dqs[i] = 1'b1;
1271            end
1272        end else begin
1273            expect_pos_dqs = 0;
1274            expect_neg_dqs = 0;
1275        end
1276    end
1277    endtask
1278
1279    // Main Logic
1280    always @ (posedge Sys_clk) begin
1281        Manual_Precharge_Pipeline;
1282        Burst_Terminate_Pipeline;
1283        Dq_Dqs_Drivers;
1284        Write_FIFO_DM_Mask_Logic;
1285        Burst_Decode;
1286        check_neg_dqs;
1287        Auto_Precharge_Calculation;
1288        DLL_Counter;
1289        Control_Logic;
1290    end
1291
1292    always @ (negedge Sys_clk) begin
1293        Manual_Precharge_Pipeline;
1294        Burst_Terminate_Pipeline;
1295        Dq_Dqs_Drivers;
1296        Write_FIFO_DM_Mask_Logic;
1297        Burst_Decode;
1298        check_pos_dqs;
1299    end
1300
1301    // Dqs Receiver
1302    always @ (posedge Dqs_in[0]) begin
1303        // Latch data at posedge Dqs
1304        dq_rise[7 : 0] = Dq_in[7 : 0];
1305        dm_rise[0] = Dm_in[0];
1306        expect_pos_dqs[0] = 0;
1307    end
1308
1309    always @ (posedge Dqs_in[1]) begin
1310        // Latch data at posedge Dqs
1311        dq_rise[15 : 8] = Dq_in[15 : 8];
1312        dm_rise[1] = Dm_in [1];
1313        expect_pos_dqs[1] = 0;
1314    end
1315
1316    always @ (negedge Dqs_in[0]) begin
1317        // Latch data at negedge Dqs
1318        dq_fall[7 : 0] = Dq_in[7 : 0];
1319        dm_fall[0] = Dm_in[0];
1320        dm_pair[1:0] = {dm_rise[0], dm_fall[0]};
1321        expect_neg_dqs[0] = 0;
1322    end
1323
1324    always @ (negedge Dqs_in[1]) begin
1325        // Latch data at negedge Dqs
1326        dq_fall[15: 8] = Dq_in[15 : 8];
1327        dm_fall[1] = Dm_in[1];
1328        dm_pair[3:2] = {dm_rise[1], dm_fall[1]};
1329        expect_neg_dqs[1] = 0;
1330    end
1331
1332    specify
1333                                              // SYMBOL UNITS DESCRIPTION
1334                                              // ------ ----- -----------
1335//`ifdef sg5B // specparams for -5B (CL = 3)
1336// specparam tDSS = 1.0; // tDSS ns DQS falling edge to CLK rising (setup time) = 0.2*tCK
1337// specparam tDSH = 1.0; // tDSH ns DQS falling edge from CLK rising (hold time) = 0.2*tCK
1338// specparam tIH = 0.600; // tIH ns Input Hold Time
1339// specparam tIS = 0.600; // tIS ns Input Setup Time
1340// specparam tDQSH = 1.75; // tDQSH ns DQS input High Pulse Width = 0.35*tCK
1341// specparam tDQSL = 1.75; // tDQSL ns DQS input Low Pulse Width = 0.35*tCK
1342//`else `ifdef sg6 // specparams for -6 (CL = 2.5)
1343        specparam tDSS = 1.2; // tDSS ns DQS falling edge to CLK rising (setup time) = 0.2*tCK
1344        specparam tDSH = 1.2; // tDSH ns DQS falling edge from CLK rising (hold time) = 0.2*tCK
1345        specparam tIH = 0.750; // tIH ns Input Hold Time
1346        specparam tIS = 0.750; // tIS ns Input Setup Time
1347        specparam tDQSH = 2.1; // tDQSH ns DQS input High Pulse Width = 0.35*tCK
1348        specparam tDQSL = 2.1; // tDQSL ns DQS input Low Pulse Width = 0.35*tCK
1349//`else `ifdef sg75E // specparams for -75E (CL = 2)
1350// specparam tDSS = 1.5; // tDSS ns DQS falling edge to CLK rising (setup time) = 0.2*tCK
1351// specparam tDSH = 1.5; // tDSH ns DQS falling edge from CLK rising (hold time) = 0.2*tCK
1352// specparam tIH = 0.900; // tIH ns Input Hold Time
1353// specparam tIS = 0.900; // tIS ns Input Setup Time
1354// specparam tDQSH = 2.625; // tDQSH ns DQS input High Pulse Width = 0.35*tCK
1355// specparam tDQSL = 2.625; // tDQSL ns DQS input Low Pulse Width = 0.35*tCK
1356//`else
1357//`define sg75Z // specparams for -75Z (CL = 2)
1358// specparam tDSS = 1.5; // tDSS ns DQS falling edge to CLK rising (setup time) = 0.2*tCK
1359// specparam tDSH = 1.5; // tDSH ns DQS falling edge from CLK rising (hold time) = 0.2*tCK
1360// specparam tIH = 0.900; // tIH ns Input Hold Time
1361// specparam tIS = 0.900; // tIS ns Input Setup Time
1362// specparam tDQSH = 2.625; // tDQSH ns DQS input High Pulse Width = 0.35*tCK
1363// specparam tDQSL = 2.625; // tDQSL ns DQS input Low Pulse Width = 0.35*tCK
1364//`endif `endif `endif
1365        $width (posedge Dqs_in[0] &&& wdqs_valid, tDQSH);
1366        $width (posedge Dqs_in[1] &&& wdqs_valid, tDQSH);
1367        $width (negedge Dqs_in[0] &&& wdqs_valid, tDQSL);
1368        $width (negedge Dqs_in[1] &&& wdqs_valid, tDQSL);
1369        $setuphold(posedge Clk, Cke, tIS, tIH);
1370        $setuphold(posedge Clk, Cs_n, tIS, tIH);
1371        $setuphold(posedge Clk, Cas_n, tIS, tIH);
1372        $setuphold(posedge Clk, Ras_n, tIS, tIH);
1373        $setuphold(posedge Clk, We_n, tIS, tIH);
1374        $setuphold(posedge Clk, Addr, tIS, tIH);
1375        $setuphold(posedge Clk, Ba, tIS, tIH);
1376        $setuphold(posedge Clk, negedge Dqs &&& wdqs_valid, tDSS, tDSH);
1377    endspecify
1378
1379endmodule
Examples/sram_gpio/logic/sim/ddr/ddr_parameters.vh
1/****************************************************************************************
2*
3* Disclaimer This software code and all associated documentation, comments or other
4* of Warranty: information (collectively "Software") is provided "AS IS" without
5* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
6* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
7* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
8* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
9* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
10* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
11* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
12* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
13* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
14* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
15* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
16* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
17* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
18* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
19* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
20* DAMAGES. Because some jurisdictions prohibit the exclusion or
21* limitation of liability for consequential or incidental damages, the
22* above limitation may not apply to you.
23*
24* Copyright 2003 Micron Technology, Inc. All rights reserved.
25*
26****************************************************************************************/
27
28    // Timing parameters based on Speed Grade
29
30                                          // SYMBOL UNITS DESCRIPTION
31                                          // ------ ----- -----------
32
33// `ifdef sg6T // Timing Parameters for -6T (CL = 2.5)
34    parameter tCK = 6.0; // tCK ns Nominal Clock Cycle Time
35    parameter tDQSQ = 0.45; // tDQSS ns DQS-DQ skew, DQS to last DQ valid, per group, per access
36    parameter tMRD = 12.0; // tMRD ns Load Mode Register command cycle time
37    parameter tRAP = 15.0; // tRAP ns ACTIVE to READ with Auto precharge command
38    parameter tRAS = 42.0; // tRAS ns Active to Precharge command time
39    parameter tRC = 60.0; // tRC ns Active to Active/Auto Refresh command time
40    parameter tRFC = 120.0; // tRFC ns Refresh to Refresh Command interval time
41    parameter tRCD = 15.0; // tRCD ns Active to Read/Write command time
42    parameter tRP = 15.0; // tRP ns Precharge command period
43    parameter tRRD = 12.0; // tRRD ns Active bank a to Active bank b command time
44    parameter tWR = 15.0; // tWR ns Write recovery time
45
46
47
48    // Size Parameters based on Part Width
49
50
51//`else `define x16
52    parameter ADDR_BITS = 13; // Set this parameter to control how many Address bits are used
53    parameter DQ_BITS = 16; // Set this parameter to control how many Data bits are used
54    parameter DQS_BITS = 2; // Set this parameter to control how many DQS bits are used
55    parameter DM_BITS = 2; // Set this parameter to control how many DM bits are used
56    parameter COL_BITS = 10; // Set this parameter to control how many Column bits are used
57
58    parameter full_mem_bits = 2+ADDR_BITS+COL_BITS; // Set this parameter to control how many unique addresses are used
59    parameter part_mem_bits = 14; // Set this parameter to control how many unique addresses are used
60
61    parameter no_halt = 0; // If set to 1, the model won't halt on command sequence/major errors
62    parameter Debug = 1; // Turn on debug message
63
Examples/sram_gpio/logic/sim/ddr/parameters.v
1///////////////////////////////////////////////////////////////////////////////
2// Copyright (c) 2005 Xilinx, Inc.
3// This design is confidential and proprietary of Xilinx, All Rights Reserved.
4///////////////////////////////////////////////////////////////////////////////
5// ____ ____
6// / /\/ /
7// /___/ \ / Vendor : Xilinx
8// \ \ \/ Version : $Name: mig_v1_73_b0 $
9// \ \ Application : MIG
10// / / Filename : mem_interface_top_parameters_0.v
11// /___/ /\ Date Last Modified : $Date: 2007/06/06 05:44:42 $
12// \ \ / \ Date Created : Mon May 2 2005
13// \___\/\___\
14// Device : Spartan-3/3E/3A
15// Design Name : DDR1 SDRAM
16// Purpose : This module has the parameters used in the design.
17///////////////////////////////////////////////////////////////////////////////
18
19`define data_width 16
20`define data_strobe_width 2
21`define data_mask_width 2
22`define clk_width 1
23`define fifo_16 1
24`define ReadEnable 1
25`define memory_width 8
26`define DatabitsPerReadClock 8
27`define DatabitsPerMask 8
28`define no_of_cs 1
29`define data_mask 1
30`define mask_disable 0
31`define RESET 0
32`define cke_width 1
33`define registered 0
34`define col_ap_width 11
35`define write_pipe_itr 1
36`define write_pipeline 4
37`define top_bottom 0
38`define left_right 1
39`define row_address 13
40`define column_address 10
41`define bank_address 2
42`define spartan3e 1
43`define burst_length 3'b001
44`define burst_type 1'b0
45`define cas_latency_value 3'b110
46`define Operating_mode 5'b00000
47`define load_mode_register 13'b0000001100001
48`define drive_strengh 1'b0
49`define dll_enable 1'b0
50`define ext_load_mode_register 13'b0000000000000
51`define chip_address 1
52`define reset_active_low 1'b1
53`define rcd_count_value 3'b001
54`define ras_count_value 4'b0101
55`define mrd_count_value 1'b0
56`define rp_count_value 3'b001
57`define rfc_count_value 6'b001001
58`define twr_count_value 3'b110
59`define twtr_count_value 3'b100
60`define max_ref_width 11
61`define max_ref_cnt 11'b10000000001
62
63`timescale 1ns/100ps
64
Examples/sram_gpio/logic/sim/ddr/readme.txt
1********************************************************************************************
2The sim folder has sample test_bench files to simulate the designs in Modelsim environment.
3This folder has the memory model, test bench, glbl file and required parameter files.
4Read the steps in this file before simulations are done.
5
6To run simulations for this sample configuration, user has to generate the RTL from the tool for the following GUI
7options.
8
9Data_width : 64
10HDL : Verilog or VHDL
11Memory configuration : x16
12DIMM/Component : Component
13Memory Part No : MT46V16M16XX-5
14Add test bench : Yes
15Use DCM : Yes
16Number of controllers : 1
17Number of Write pipelines : 4
18
19-----------------------------------------------For Verilog or VHDL----------------------------------------------------------
20
211. After the rtl is generated, create the Model sim project file. Add all the rtl files from the rtl folder
22   to the project Also add the memory model, test bench and glbl files from the sim folder.
23
242. Compile the design.
25
263. After successful compilation of design load the design using the following comamnd.
27
28   vsim -t ps +notimingchecks -L ../Modeltech_6.1a/unisims_ver work.ddr1_test_tb glbl
29   Note : User should set proper path for unisim verilog libraries
30
314. After the design is successfully loaded, run the simulations and view the waveforms.
32
33
34Notes :
35
361. To run simulations for different data widths and configurations, users should modify the test bench files
37    with right memory models and design files.
38
392. User must manually change the frequency of the test bench for proper simulations.
40
413. Users should modify the test bench files for without test bench case.
42
43
44
Examples/sram_gpio/logic/sim/sram/sram16.v
1//---------------------------------------------------------------------------
2// Behavioral model of a static ram chip
3//
4// Organization:
5//
6// 16 bit x 2**(adr_width-1)
7//---------------------------------------------------------------------------
8module sram16 #(
9    parameter adr_width = 18
10) (
11    input [adr_width-1:0] adr,
12    inout [15:0] dat,
13    input ub_n,
14    input lb_n,
15    input cs_n,
16    input we_n,
17    input oe_n
18);
19
20parameter dat_width = 16;
21
22//---------------------------------------------------------------------------
23// Actual RAM cells
24//---------------------------------------------------------------------------
25reg [7:0] mem_ub [0:1<<adr_width];
26reg [7:0] mem_lb [0:1<<adr_width];
27
28//---------------------------------------------------------------------------
29//
30//---------------------------------------------------------------------------
31wire [15:0] mem = { mem_ub[adr], mem_lb[adr] };
32wire [15:0] zzz = 16'bz;
33
34// Drive output
35assign dat = (!cs_n && !oe_n) ? mem : zzz;
36
37// Write to UB
38always @(*)
39    if (!cs_n && !we_n && !ub_n)
40        mem_ub[adr] = dat[15:8];
41
42// Write to LB
43always @(*)
44    if (!cs_n && !we_n && !lb_n)
45        mem_lb[adr] = dat[7:0];
46
47always @(*)
48    if (!we_n && !oe_n)
49        $display("Operational error in RamChip: OE and WE both active");
50
51endmodule
52
Examples/sram_gpio/logic/sim/unisims/BUFG.v
1// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/BUFG.v,v 1.5.158.1 2007/03/09 18:13:02 patrickp Exp $
2///////////////////////////////////////////////////////////////////////////////
3// Copyright (c) 1995/2004 Xilinx, Inc.
4// All Right Reserved.
5///////////////////////////////////////////////////////////////////////////////
6// ____ ____
7// / /\/ /
8// /___/ \ / Vendor : Xilinx
9// \ \ \/ Version : 8.1i (I.13)
10// \ \ Description : Xilinx Functional Simulation Library Component
11// / / Global Clock Buffer
12// /___/ /\ Filename : BUFG.v
13// \ \ / \ Timestamp : Thu Mar 25 16:42:14 PST 2004
14// \___\/\___\
15//
16// Revision:
17// 03/23/04 - Initial version.
18// End Revision
19
20`timescale 100 ps / 10 ps
21
22
23module BUFG (O, I);
24
25    output O;
26
27    input I;
28
29    buf B1 (O, I);
30
31
32endmodule
33
Examples/sram_gpio/logic/sim/unisims/DCM.v
1// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/DCM.v,v 1.28.4.3 2007/04/11 20:32:09 yanx Exp $
2///////////////////////////////////////////////////////////////////////////////
3// Copyright (c) 1995/2004 Xilinx, Inc.
4// All Right Reserved.
5///////////////////////////////////////////////////////////////////////////////
6// ____ ____
7// / /\/ /
8// /___/ \ / Vendor : Xilinx
9// \ \ \/ Version : 9.2i (J.36)
10// \ \ Description : Xilinx Functional Simulation Library Component
11// / / Digital Clock Manager
12// /___/ /\ Filename : DCM.v
13// \ \ / \ Timestamp : Thu Mar 25 16:42:15 PST 2004
14// \___\/\___\
15//
16// Revision:
17// 03/23/04 - Initial version.
18// 04/11/05 - Initial all output signals.
19// 05/06/05 - Use assign/deassign to reset all output clocks. CR 207692.
20// 05/11/05 - Add clkin alignment check control to remove the glitch when
21// clkin stopped. (CR207409).
22// 05/25/05 - Seperate clock_second_pos and neg to another process due to
23// wait caused unreset. Set fb_delay_found after fb_delay computed.
24// Enable clkfb_div after lock_fb high (CR 208771)
25// 07/05/05 - Use counter to generate clkdv_out to align with clk0_out. (CR211465).
26// Add lock_fb_dly to alignment check. (CR210755).
27// 07/25/05 - Set CLKIN_PERIOD default to 10.0ns to (CR 213190).
28// 12/22/05 - LOCKED = x when RST less than 3 clock cycles (CR 222795)
29// 01/12/06 - Add rst_in to period_div and period_ps block to handle clkin frequency
30// change case. (CR 221989).
31// 02/28/06 - Add integer and real to parameter declaration.
32// 09/22/06 - Add lock_period and lock_fb to clkfb_div block (CR418722).
33// 12/19/06 - Add clkfb_div_en for clkfb2x divider (CR431210).
34// 04/06/07 - Enable the clock out in clock low time after reset in model
35// clock_divide_by_2 (CR 437471).
36// End Revision
37
38
39`ifndef NEW_DCM
40
41`timescale 1 ps / 1 ps
42
43module DCM (
44    CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90,
45    CLKDV, CLKFX, CLKFX180, LOCKED, PSDONE, STATUS,
46    CLKFB, CLKIN, DSSEN, PSCLK, PSEN, PSINCDEC, RST);
47
48parameter CLKDV_DIVIDE = 2.0;
49parameter integer CLKFX_DIVIDE = 1;
50parameter integer CLKFX_MULTIPLY = 4;
51parameter CLKIN_DIVIDE_BY_2 = "FALSE";
52parameter CLKIN_PERIOD = 10.0; // non-simulatable
53parameter CLKOUT_PHASE_SHIFT = "NONE";
54parameter CLK_FEEDBACK = "1X";
55parameter DESKEW_ADJUST = "SYSTEM_SYNCHRONOUS"; // non-simulatable
56parameter DFS_FREQUENCY_MODE = "LOW";
57parameter DLL_FREQUENCY_MODE = "LOW";
58parameter DSS_MODE = "NONE"; // non-simulatable
59parameter DUTY_CYCLE_CORRECTION = "TRUE";
60parameter FACTORY_JF = 16'hC080; // non-simulatable
61parameter integer MAXPERCLKIN = 1000000; // non-modifiable simulation parameter
62parameter integer MAXPERPSCLK = 100000000; // non-modifiable simulation parameter
63parameter integer PHASE_SHIFT = 0;
64parameter integer SIM_CLKIN_CYCLE_JITTER = 300; // non-modifiable simulation parameter
65parameter integer SIM_CLKIN_PERIOD_JITTER = 1000; // non-modifiable simulation parameter
66parameter STARTUP_WAIT = "FALSE"; // non-simulatable
67
68input CLKFB, CLKIN, DSSEN;
69input PSCLK, PSEN, PSINCDEC, RST;
70
71output CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90;
72output CLKDV, CLKFX, CLKFX180, LOCKED, PSDONE;
73output [7:0] STATUS;
74
75reg CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90;
76reg CLKDV, CLKFX, CLKFX180;
77
78wire locked_out_out;
79wire clkfb_in, clkin_in, dssen_in;
80wire psclk_in, psen_in, psincdec_in, rst_in;
81reg clk0_out;
82reg clk2x_out, clkdv_out;
83reg clkfx_out, clkfx180_en;
84reg rst_flag;
85reg locked_out, psdone_out, ps_overflow_out, ps_lock;
86reg clkfb_div, clkfb_chk, clkfb_div_en;
87integer clkdv_cnt;
88
89reg [1:0] clkfb_type;
90reg [8:0] divide_type;
91reg clkin_type;
92reg [1:0] ps_type;
93reg [3:0] deskew_adjust_mode;
94reg dfs_mode_type;
95reg dll_mode_type;
96reg clk1x_type;
97integer ps_in, ps_in_ps;
98
99reg lock_period, lock_delay, lock_clkin, lock_clkfb;
100reg first_time_locked;
101reg en_status;
102reg ps_overflow_out_ext;
103reg clkin_lost_out_ext;
104reg clkfx_lost_out_ext;
105reg [1:0] lock_out;
106reg lock_out1_neg;
107reg lock_fb, lock_ps, lock_ps_dly, lock_fb_dly, lock_fb_dly_tmp;
108reg fb_delay_found;
109reg clock_stopped;
110reg clkin_chkin, clkfb_chkin;
111
112wire chk_enable, chk_rst;
113wire clkin_div;
114wire lock_period_pulse;
115wire lock_period_dly;
116
117reg clkin_ps;
118reg clkin_fb;
119
120time FINE_SHIFT_RANGE;
121time ps_delay;
122time clkin_edge;
123time clkin_div_edge;
124time clkin_ps_edge;
125time delay_edge;
126time clkin_period [2:0];
127time period;
128time period_div;
129time period_orig;
130time period_ps;
131time clkout_delay;
132time fb_delay;
133time period_fx, remain_fx;
134time period_dv_high, period_dv_low;
135time cycle_jitter, period_jitter;
136
137reg clkin_window, clkfb_window;
138reg [2:0] rst_reg;
139reg [12:0] numerator, denominator, gcd;
140reg [23:0] i, n, d, p;
141
142reg notifier;
143
144initial begin
145    #1;
146    if ($realtime == 0) begin
147    $display ("Simulator Resolution Error : Simulator resolution is set to a value greater than 1 ps.");
148    $display ("In order to simulate the DCM, the simulator resolution must be set to 1ps or smaller.");
149    $finish;
150    end
151end
152
153initial begin
154    case (CLKDV_DIVIDE)
155    1.5 : divide_type = 'd3;
156    2.0 : divide_type = 'd4;
157    2.5 : divide_type = 'd5;
158    3.0 : divide_type = 'd6;
159    3.5 : divide_type = 'd7;
160    4.0 : divide_type = 'd8;
161    4.5 : divide_type = 'd9;
162    5.0 : divide_type = 'd10;
163    5.5 : divide_type = 'd11;
164    6.0 : divide_type = 'd12;
165    6.5 : divide_type = 'd13;
166    7.0 : divide_type = 'd14;
167    7.5 : divide_type = 'd15;
168    8.0 : divide_type = 'd16;
169    9.0 : divide_type = 'd18;
170    10.0 : divide_type = 'd20;
171    11.0 : divide_type = 'd22;
172    12.0 : divide_type = 'd24;
173    13.0 : divide_type = 'd26;
174    14.0 : divide_type = 'd28;
175    15.0 : divide_type = 'd30;
176    16.0 : divide_type = 'd32;
177    default : begin
178        $display("Attribute Syntax Error : The attribute CLKDV_DIVIDE on DCM instance %m is set to %0.1f. Legal values for this attribute are 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, or 16.0.", CLKDV_DIVIDE);
179        $finish;
180    end
181    endcase
182
183    if ((CLKFX_DIVIDE <= 0) || (32 < CLKFX_DIVIDE)) begin
184    $display("Attribute Syntax Error : The attribute CLKFX_DIVIDE on DCM instance %m is set to %d. Legal values for this attribute are 1 ... 32.", CLKFX_DIVIDE);
185    $finish;
186    end
187
188    if ((CLKFX_MULTIPLY <= 1) || (32 < CLKFX_MULTIPLY)) begin
189    $display("Attribute Syntax Error : The attribute CLKFX_MULTIPLY on DCM instance %m is set to %d. Legal values for this attribute are 2 ... 32.", CLKFX_MULTIPLY);
190    $finish;
191    end
192
193    case (CLKIN_DIVIDE_BY_2)
194    "false" : clkin_type = 0;
195    "FALSE" : clkin_type = 0;
196    "true" : clkin_type = 1;
197    "TRUE" : clkin_type = 1;
198    default : begin
199        $display("Attribute Syntax Error : The attribute CLKIN_DIVIDE_BY_2 on DCM instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", CLKIN_DIVIDE_BY_2);
200        $finish;
201    end
202    endcase
203
204    case (CLKOUT_PHASE_SHIFT)
205    "NONE" : begin
206             ps_in = 256;
207             ps_type = 0;
208             end
209    "none" : begin
210             ps_in = 256;
211             ps_type = 0;
212             end
213    "FIXED" : begin
214             ps_in = PHASE_SHIFT + 256;
215             ps_type = 1;
216             end
217    "fixed" : begin
218             ps_in = PHASE_SHIFT + 256;
219             ps_type = 1;
220             end
221    "VARIABLE" : begin
222             ps_in = PHASE_SHIFT + 256;
223             ps_type = 2;
224             end
225    "variable" : begin
226             ps_in = PHASE_SHIFT + 256;
227             ps_type = 2;
228             end
229    default : begin
230        $display("Attribute Syntax Error : The attribute CLKOUT_PHASE_SHIFT on DCM instance %m is set to %s. Legal values for this attribute are NONE, FIXED or VARIABLE.", CLKOUT_PHASE_SHIFT);
231        $finish;
232    end
233    endcase
234
235    ps_in_ps = ps_in;
236
237    case (CLK_FEEDBACK)
238    "none" : clkfb_type = 2'b00;
239    "NONE" : clkfb_type = 2'b00;
240    "1x" : clkfb_type = 2'b01;
241    "1X" : clkfb_type = 2'b01;
242    "2x" : clkfb_type = 2'b10;
243    "2X" : clkfb_type = 2'b10;
244    default : begin
245        $display("Attribute Syntax Error : The attribute CLK_FEEDBACK on DCM instance %m is set to %s. Legal values for this attribute are NONE, 1X or 2X.", CLK_FEEDBACK);
246        $finish;
247    end
248    endcase
249
250    case (DESKEW_ADJUST)
251    "source_synchronous" : deskew_adjust_mode = 8;
252    "SOURCE_SYNCHRONOUS" : deskew_adjust_mode = 8;
253    "system_synchronous" : deskew_adjust_mode = 11;
254    "SYSTEM_SYNCHRONOUS" : deskew_adjust_mode = 11;
255    "0" : deskew_adjust_mode = 0;
256    "1" : deskew_adjust_mode = 1;
257    "2" : deskew_adjust_mode = 2;
258    "3" : deskew_adjust_mode = 3;
259    "4" : deskew_adjust_mode = 4;
260    "5" : deskew_adjust_mode = 5;
261    "6" : deskew_adjust_mode = 6;
262    "7" : deskew_adjust_mode = 7;
263    "8" : deskew_adjust_mode = 8;
264    "9" : deskew_adjust_mode = 9;
265    "10" : deskew_adjust_mode = 10;
266    "11" : deskew_adjust_mode = 11;
267    "12" : deskew_adjust_mode = 12;
268    "13" : deskew_adjust_mode = 13;
269    "14" : deskew_adjust_mode = 14;
270    "15" : deskew_adjust_mode = 15;
271    default : begin
272        $display("Attribute Syntax Error : The attribute DESKEW_ADJUST on DCM instance %m is set to %s. Legal values for this attribute are SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or 0 ... 15.", DESKEW_ADJUST);
273        $finish;
274    end
275    endcase
276
277    case (DFS_FREQUENCY_MODE)
278    "high" : dfs_mode_type = 1;
279    "HIGH" : dfs_mode_type = 1;
280    "low" : dfs_mode_type = 0;
281    "LOW" : dfs_mode_type = 0;
282    default : begin
283        $display("Attribute Syntax Error : The attribute DFS_FREQUENCY_MODE on DCM instance %m is set to %s. Legal values for this attribute are HIGH or LOW.", DFS_FREQUENCY_MODE);
284        $finish;
285    end
286    endcase
287
288    period_jitter = SIM_CLKIN_PERIOD_JITTER;
289    cycle_jitter = SIM_CLKIN_CYCLE_JITTER;
290
291    case (DLL_FREQUENCY_MODE)
292    "high" : dll_mode_type = 1;
293    "HIGH" : dll_mode_type = 1;
294    "low" : dll_mode_type = 0;
295    "LOW" : dll_mode_type = 0;
296    default : begin
297        $display("Attribute Syntax Error : The attribute DLL_FREQUENCY_MODE on DCM instance %m is set to %s. Legal values for this attribute are HIGH or LOW.", DLL_FREQUENCY_MODE);
298        $finish;
299    end
300    endcase
301
302    if ((dll_mode_type ==1) && (clkfb_type == 2'b10)) begin
303        $display("Attribute Syntax Error : The attributes DLL_FREQUENCY_MODE on DCM instance %m is set to %s and CLK_FEEDBACK is set to %s. CLK_FEEDBACK 2X is not supported when DLL_FREQUENCY_MODE is HIGH.", DLL_FREQUENCY_MODE, CLK_FEEDBACK);
304           $finish;
305    end
306
307    case (DSS_MODE)
308    "none" : ;
309    "NONE" : ;
310    default : begin
311        $display("Attribute Syntax Error : The attribute DSS_MODE on DCM instance %m is set to %s. Legal values for this attribute is NONE.", DSS_MODE);
312        $finish;
313    end
314    endcase
315
316    case (DUTY_CYCLE_CORRECTION)
317    "false" : clk1x_type = 0;
318    "FALSE" : clk1x_type = 0;
319    "true" : clk1x_type = 1;
320    "TRUE" : clk1x_type = 1;
321    default : begin
322        $display("Attribute Syntax Error : The attribute DUTY_CYCLE_CORRECTION on DCM instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", DUTY_CYCLE_CORRECTION);
323        $finish;
324    end
325    endcase
326
327    if ((PHASE_SHIFT < -255) || (PHASE_SHIFT > 255)) begin
328    $display("Attribute Syntax Error : The attribute PHASE_SHIFT on DCM instance %m is set to %d. Legal values for this attribute are -255 ... 255.", PHASE_SHIFT);
329    $display("Error : PHASE_SHIFT = %d is not -255 ... 255.", PHASE_SHIFT);
330    $finish;
331    end
332
333    case (STARTUP_WAIT)
334    "false" : ;
335    "FALSE" : ;
336    "true" : ;
337    "TRUE" : ;
338    default : begin
339        $display("Attribute Syntax Error : The attribute STARTUP_WAIT on DCM instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", STARTUP_WAIT);
340        $finish;
341    end
342    endcase
343end
344
345//
346// fx parameters
347//
348
349initial begin
350    gcd = 1;
351    for (i = 2; i <= CLKFX_MULTIPLY; i = i + 1) begin
352    if (((CLKFX_MULTIPLY % i) == 0) && ((CLKFX_DIVIDE % i) == 0))
353        gcd = i;
354    end
355    numerator = CLKFX_MULTIPLY / gcd;
356    denominator = CLKFX_DIVIDE / gcd;
357end
358
359//
360// input wire delays
361//
362
363buf b_clkin (clkin_in, CLKIN);
364buf b_clkfb (clkfb_in, CLKFB);
365buf b_dssen (dssen_in, DSSEN);
366buf b_psclk (psclk_in, PSCLK);
367buf b_psen (psen_in, PSEN);
368buf b_psincdec (psincdec_in, PSINCDEC);
369buf b_rst (rst_in, RST);
370buf #100 b_locked (LOCKED, locked_out_out);
371buf #100 b_psdone (PSDONE, psdone_out);
372buf b_ps_overflow (STATUS[0], ps_overflow_out_ext);
373buf b_clkin_lost (STATUS[1], clkin_lost_out_ext);
374buf b_clkfx_lost (STATUS[2], clkfx_lost_out_ext);
375
376assign STATUS[7:3] = 5'b0;
377
378dcm_clock_divide_by_2 i_clock_divide_by_2 (clkin_in, clkin_type, clkin_div, rst_in);
379
380dcm_maximum_period_check #("CLKIN", MAXPERCLKIN) i_max_clkin (clkin_in);
381dcm_maximum_period_check #("PSCLK", MAXPERPSCLK) i_max_psclk (psclk_in);
382
383dcm_clock_lost i_clkin_lost (clkin_in, first_time_locked, clkin_lost_out, rst_in);
384dcm_clock_lost i_clkfx_lost (CLKFX, first_time_locked, clkfx_lost_out, rst_in);
385
386always @(rst_in or en_status or clkfx_lost_out or clkin_lost_out or ps_overflow_out)
387   if (rst_in == 1 || en_status == 0) begin
388       ps_overflow_out_ext = 0;
389       clkin_lost_out_ext = 0;
390       clkfx_lost_out_ext = 0;
391    end
392   else
393   begin
394      ps_overflow_out_ext = ps_overflow_out;
395      clkin_lost_out_ext = clkin_lost_out;
396      clkfx_lost_out_ext = clkfx_lost_out;
397   end
398
399always @(posedge rst_in or posedge LOCKED)
400  if (rst_in == 1)
401      en_status <= 0;
402   else
403      en_status <= 1;
404
405
406always @(clkin_div)
407    clkin_ps <= #(ps_delay) clkin_div;
408
409always @(clkin_ps or lock_fb)
410    clkin_fb = clkin_ps & lock_fb;
411
412
413always @(negedge clkfb_in or posedge rst_in)
414    if (rst_in)
415        clkfb_div_en <= 0;
416    else
417       if (lock_fb_dly && lock_period && lock_fb && ~clkin_ps)
418          clkfb_div_en <= 1;
419
420always @(posedge clkfb_in or posedge rst_in)
421    if (rst_in)
422        clkfb_div <= 0;
423    else
424      if (clkfb_div_en )
425        clkfb_div <= ~clkfb_div;
426
427always @(clkfb_in or clkfb_div)
428    if (clkfb_type == 2'b10 )
429         clkfb_chk = clkfb_div;
430    else
431         clkfb_chk = clkfb_in & lock_fb_dly;
432
433always @(posedge clkin_fb or posedge chk_rst)
434    if (chk_rst)
435       clkin_chkin <= 0;
436    else
437       clkin_chkin <= 1;
438
439always @(posedge clkfb_chk or posedge chk_rst)
440    if (chk_rst)
441       clkfb_chkin <= 0;
442    else
443       clkfb_chkin <= 1;
444
445    assign chk_rst = (rst_in==1 || clock_stopped==1 ) ? 1 : 0;
446    assign chk_enable = (clkin_chkin == 1 && clkfb_chkin == 1 &&
447                         lock_ps ==1 && lock_fb ==1 && lock_fb_dly == 1) ? 1 : 0;
448
449always @(posedge clkin_div or posedge rst_in)
450  if (rst_in) begin
451     period_div <= 0;
452     clkin_div_edge <= 0;
453   end
454  else
455   if ( clkin_div ==1 ) begin
456      clkin_div_edge <= $time;
457      if (($time - clkin_div_edge) <= (1.5 * period_div))
458      period_div <= $time - clkin_div_edge;
459      else if ((period_div == 0) && (clkin_div_edge != 0))
460      period_div <= $time - clkin_div_edge;
461   end
462
463always @(posedge clkin_ps or posedge rst_in)
464  if (rst_in) begin
465        period_ps <= 0;
466        clkin_ps_edge <= 0;
467  end
468  else
469  if (clkin_ps == 1 ) begin
470    clkin_ps_edge <= $time;
471    if (($time - clkin_ps_edge) <= (1.5 * period_ps))
472    period_ps <= $time - clkin_ps_edge;
473    else if ((period_ps == 0) && (clkin_ps_edge != 0))
474    period_ps <= $time - clkin_ps_edge;
475 end
476
477always @(posedge clkin_ps) begin
478    lock_ps <= lock_period;
479    lock_ps_dly <= lock_ps;
480    lock_fb <= lock_ps_dly;
481    lock_fb_dly_tmp <= lock_fb;
482end
483
484always @(negedge clkin_ps or posedge rst_in)
485  if (rst_in)
486    lock_fb_dly <= 1'b0;
487  else
488// lock_fb_dly <= #(period/4) lock_fb_dly_tmp;
489    lock_fb_dly <= #(period * 0.75) lock_fb_dly_tmp;
490
491
492always @(period or fb_delay )
493  if (fb_delay == 0)
494    clkout_delay = 0;
495  else
496    clkout_delay = period - fb_delay;
497
498//
499// generate master reset signal
500//
501
502always @(posedge clkin_in) begin
503    rst_reg[0] <= rst_in;
504    rst_reg[1] <= rst_reg[0] & rst_in;
505    rst_reg[2] <= rst_reg[1] & rst_reg[0] & rst_in;
506end
507
508reg rst_tmp1, rst_tmp2;
509initial
510begin
511rst_tmp1 = 0;
512rst_tmp2 = 0;
513rst_flag = 0;
514end
515
516always @(rst_in)
517begin
518   if (rst_in)
519       rst_flag = 0;
520
521   rst_tmp1 = rst_in;
522   if (rst_tmp1 == 0 && rst_tmp2 == 1) begin
523      if ((rst_reg[2] & rst_reg[1] & rst_reg[0]) == 0) begin
524         rst_flag = 1;
525    $display("Input Error : RST on instance %m must be asserted for 3 CLKIN clock cycles.");
526      end
527   end
528   rst_tmp2 = rst_tmp1;
529end
530
531initial begin
532    CLK0 = 0;
533    CLK180 = 0;
534    CLK270 = 0;
535    CLK2X = 0;
536    CLK2X180 = 0;
537    CLK90 = 0;
538    CLKDV = 0;
539    CLKFX = 0;
540    CLKFX180 = 0;
541    clk0_out = 0;
542    clk2x_out = 0;
543    clkdv_out = 0;
544    clkdv_cnt = 0;
545    clkfb_window = 0;
546    clkfx_out = 0;
547    clkfx180_en = 0;
548    clkin_div_edge = 0;
549    clkin_period[0] = 0;
550    clkin_period[1] = 0;
551    clkin_period[2] = 0;
552    clkin_edge = 0;
553    clkin_ps_edge = 0;
554    clkin_window = 0;
555    clkout_delay = 0;
556    clock_stopped = 1;
557    fb_delay = 0;
558    fb_delay_found = 0;
559    lock_clkfb = 0;
560    lock_clkin = 0;
561    lock_delay = 0;
562    lock_fb = 0;
563    lock_fb_dly = 0;
564    lock_out = 2'b00;
565    lock_out1_neg = 0;
566    lock_period = 0;
567    lock_ps = 0;
568    lock_ps_dly = 0;
569    locked_out = 0;
570    period = 0;
571    period_div = 0;
572    period_fx = 0;
573    period_orig = 0;
574    period_ps = 0;
575    psdone_out = 0;
576    ps_delay = 0;
577    ps_lock = 0;
578    ps_overflow_out = 0;
579    ps_overflow_out_ext = 0;
580    clkin_lost_out_ext = 0;
581    clkfx_lost_out_ext = 0;
582    rst_reg = 3'b000;
583    first_time_locked = 0;
584    en_status = 0;
585    clkfb_div = 0;
586    clkin_chkin = 0;
587    clkfb_chkin = 0;
588end
589
590// RST less than 3 cycles, lock = x
591
592  assign locked_out_out = (rst_flag) ? 1'bx : locked_out;
593
594//
595// detect_first_time_locked
596//
597always @(posedge locked_out)
598  if (first_time_locked == 0)
599          first_time_locked <= 1;
600
601//
602// phase shift parameters
603//
604
605always @(posedge lock_period) begin
606    if (ps_type == 2'b01)
607    FINE_SHIFT_RANGE = 10000;
608    else if (ps_type == 2'b10)
609    FINE_SHIFT_RANGE = 5000;
610    if (PHASE_SHIFT > 0) begin
611    if ((ps_in * period_orig / 256) > period_orig + FINE_SHIFT_RANGE) begin
612        $display("Function Error : Instance %m Requested Phase Shift = PHASE_SHIFT * PERIOD / 256 = %d * %1.3f / 256 = %1.3f. This exceeds the FINE_SHIFT_RANGE of %1.3f ns.", PHASE_SHIFT, period_orig / 1000.0, PHASE_SHIFT * period_orig / 256 / 1000.0, FINE_SHIFT_RANGE / 1000.0);
613          $finish;
614    end
615    end
616    else if (PHASE_SHIFT < 0) begin
617    if ((period_orig > FINE_SHIFT_RANGE) &&
618        ((ps_in * period_orig / 256) < period_orig - FINE_SHIFT_RANGE)) begin
619        $display("Function Error : Instance %m Requested Phase Shift = PHASE_SHIFT * PERIOD / 256 = %d * %1.3f / 256 = %1.3f. This exceeds the FINE_SHIFT_RANGE of %1.3f ns.", PHASE_SHIFT, period_orig / 1000.0, -(PHASE_SHIFT) * period_orig / 256 / 1000.0, FINE_SHIFT_RANGE / 1000.0);
620          $finish;
621    end
622    end
623end
624
625always @(posedge lock_period_pulse or posedge rst_in or ps_in_ps)
626  if (rst_in) begin
627     ps_delay <= 0;
628  end
629  else if (lock_period_pulse) begin
630          ps_delay <= (ps_in * period_div / 256);
631  end
632  else begin
633    if (ps_type == 2'b10 && ps_lock ==1)
634     begin
635          ps_delay = (ps_in_ps * period_div / 256);
636     end
637  end
638
639
640always @(posedge psclk_in or rst_in)
641  if (rst_in) begin
642     ps_in_ps <= ps_in;
643     ps_overflow_out <= 0;
644  end
645  else begin
646    if (ps_type == 2'b10)
647    if (psen_in)
648        if (ps_lock == 1)
649          $display(" Warning : Please wait for PSDONE signal before adjusting the Phase Shift.");
650        else
651        if (psincdec_in == 1) begin
652        if (ps_in_ps == 511)
653            ps_overflow_out <= 1;
654        else if (((ps_in_ps + 1) * period_orig / 256) > period_orig + FINE_SHIFT_RANGE)
655            ps_overflow_out <= 1;
656        else begin
657            ps_in_ps <= ps_in_ps + 1;
658            ps_overflow_out <= 0;
659        end
660        ps_lock <= 1;
661        end
662        else if (psincdec_in == 0) begin
663        if (ps_in_ps == 1)
664            ps_overflow_out <= 1;
665        else if ((period_orig > FINE_SHIFT_RANGE) &&
666             (((ps_in_ps - 1) * period_orig / 256) < period_orig - FINE_SHIFT_RANGE))
667              ps_overflow_out <= 1;
668        else begin
669            ps_in_ps <= ps_in_ps - 1;
670            ps_overflow_out <= 0;
671        end
672        ps_lock <= 1;
673        end
674end
675
676always @(posedge ps_lock) begin
677    @(posedge clkin_ps)
678    @(posedge psclk_in)
679    @(posedge psclk_in)
680    @(posedge psclk_in)
681    psdone_out <= 1;
682    @(posedge psclk_in)
683    psdone_out <= 0;
684    ps_lock <= 0;
685end
686
687//
688// determine clock period
689//
690
691always @(posedge clkin_div or negedge clkin_div or posedge rst_in)
692  if (rst_in == 1) begin
693    clkin_period[0] <= 0;
694    clkin_period[1] <= 0;
695    clkin_period[2] <= 0;
696    clkin_edge <= 0;
697  end
698  else
699  if (clkin_div == 1) begin
700    clkin_edge <= $time;
701    clkin_period[2] <= clkin_period[1];
702    clkin_period[1] <= clkin_period[0];
703    if (clkin_edge != 0)
704    clkin_period[0] <= $time - clkin_edge;
705  end
706  else if (clkin_div == 0)
707      if (lock_period == 1)
708        if (100000000 < clkin_period[0]/1000)
709        begin
710        end
711        else if ((period_orig * 2 < clkin_period[0]) && (clock_stopped == 0)) begin
712          clkin_period[0] <= clkin_period[1];
713        end
714
715always @(negedge clkin_div or posedge rst_in)
716  if (rst_in == 1) begin
717      lock_period <= 0;
718      clock_stopped <= 1;
719  end
720  else begin
721    if (lock_period == 1'b0) begin
722    if ((clkin_period[0] != 0) &&
723        (clkin_period[0] - cycle_jitter <= clkin_period[1]) &&
724        (clkin_period[1] <= clkin_period[0] + cycle_jitter) &&
725        (clkin_period[1] - cycle_jitter <= clkin_period[2]) &&
726        (clkin_period[2] <= clkin_period[1] + cycle_jitter)) begin
727        lock_period <= 1;
728        period_orig <= (clkin_period[0] +
729                clkin_period[1] +
730                clkin_period[2]) / 3;
731        period <= clkin_period[0];
732    end
733    end
734    else if (lock_period == 1'b1) begin
735    if (100000000 < (clkin_period[0] / 1000)) begin
736        $display(" Warning : CLKIN stopped toggling on instance %m exceeds %d ms. Current CLKIN Period = %1.3f ns.", 100, clkin_period[0] / 1000.0);
737        lock_period <= 0;
738        @(negedge rst_reg[2]);
739    end
740    else if ((period_orig * 2 < clkin_period[0]) && clock_stopped == 1'b0) begin
741        clock_stopped <= 1'b1;
742    end
743    else if ((clkin_period[0] < period_orig - period_jitter) ||
744        (period_orig + period_jitter < clkin_period[0])) begin
745        $display(" Warning : Input Clock Period Jitter on instance %m exceeds %1.3f ns. Locked CLKIN Period = %1.3f. Current CLKIN Period = %1.3f.", period_jitter / 1000.0, period_orig / 1000.0, clkin_period[0] / 1000.0);
746        lock_period <= 0;
747        @(negedge rst_reg[2]);
748    end
749    else if ((clkin_period[0] < clkin_period[1] - cycle_jitter) ||
750        (clkin_period[1] + cycle_jitter < clkin_period[0])) begin
751        $display(" Warning : Input Clock Cycle-Cycle Jitter on instance %m exceeds %1.3f ns. Previous CLKIN Period = %1.3f. Current CLKIN Period = %1.3f.", cycle_jitter / 1000.0, clkin_period[1] / 1000.0, clkin_period[0] / 1000.0);
752        lock_period <= 0;
753        @(negedge rst_reg[2]);
754    end
755    else begin
756        period <= clkin_period[0];
757        clock_stopped <= 1'b0;
758    end
759    end
760end
761
762  assign #(period/2) lock_period_dly = lock_period;
763  assign lock_period_pulse = (lock_period==1 && lock_period_dly==0) ? 1 : 0;
764
765//
766// determine clock delay
767//
768
769//always @(posedge lock_period or posedge rst_in)
770always @(posedge lock_ps_dly or posedge rst_in)
771  if (rst_in) begin
772    fb_delay <= 0;
773    fb_delay_found <= 0;
774  end
775  else begin
776    if (lock_period && clkfb_type != 2'b00) begin
777    if (clkfb_type == 2'b01) begin
778        @(posedge CLK0 or rst_in)
779        delay_edge = $time;
780    end
781    else if (clkfb_type == 2'b10) begin
782        @(posedge CLK2X or rst_in)
783        delay_edge = $time;
784    end
785    @(posedge clkfb_in or rst_in) begin
786     fb_delay <= ($time - delay_edge) % period_orig;
787         fb_delay_found <= 1;
788       end
789    end
790  end
791
792//
793// determine feedback lock
794//
795
796//always @(posedge clkfb_in or posedge rst_in)
797always @(posedge clkfb_chk or posedge rst_in)
798  if (rst_in)
799      clkfb_window <= 0;
800  else begin
801      clkfb_window <= 1;
802    #cycle_jitter clkfb_window <= 0;
803  end
804
805always @(posedge clkin_fb or posedge rst_in)
806  if (rst_in)
807      clkin_window <= 0;
808  else begin
809      clkin_window <= 1;
810    #cycle_jitter clkin_window <= 0;
811  end
812
813always @(posedge clkin_fb or posedge rst_in)
814  if (rst_in)
815     lock_clkin <= 0;
816  else begin
817    #1
818    if ((clkfb_window && fb_delay_found) || (clkin_lost_out == 1'b1 && lock_out[0]==1'b1))
819    lock_clkin <= 1;
820    else
821       if (chk_enable==1)
822     lock_clkin <= 0;
823  end
824
825always @(posedge clkfb_chk or posedge rst_in)
826  if (rst_in)
827    lock_clkfb <= 0;
828  else begin
829    #1
830    if ((clkin_window && fb_delay_found) || (clkin_lost_out == 1'b1 && lock_out[0]==1'b1))
831    lock_clkfb <= 1;
832    else
833       if (chk_enable ==1)
834    lock_clkfb <= 0;
835  end
836
837always @(negedge clkin_fb or posedge rst_in)
838  if (rst_in)
839    lock_delay <= 0;
840  else
841    lock_delay <= lock_clkin || lock_clkfb;
842
843//
844// generate lock signal
845//
846
847always @(posedge clkin_ps or posedge rst_in)
848  if (rst_in) begin
849      lock_out <= 2'b0;
850      locked_out <=0;
851  end
852  else begin
853    if (clkfb_type == 2'b00)
854    lock_out[0] <= lock_period;
855    else
856    lock_out[0] <= lock_period & lock_delay & lock_fb;
857    lock_out[1] <= lock_out[0];
858    locked_out <= lock_out[1];
859  end
860
861always @(negedge clkin_ps or posedge rst_in)
862  if (rst_in)
863    lock_out1_neg <= 0;
864  else
865    lock_out1_neg <= lock_out[1];
866
867
868//
869// generate the clk1x_out
870//
871
872always @(posedge clkin_ps or negedge clkin_ps or posedge rst_in)
873  if (rst_in)
874      clk0_out <= 0;
875  else
876    if (clkin_ps ==1)
877       if (clk1x_type==1 && lock_out[0]) begin
878          clk0_out <= 1;
879          #(period / 2)
880             clk0_out <= 0;
881       end
882       else
883          clk0_out <= 1;
884    else
885      if (clkin_ps == 0 && ((clk1x_type && lock_out[0]) == 0 || (lock_out[0]== 1 && lock_out[1]== 0)))
886          clk0_out <= 0;
887
888//
889// generate the clk2x_out
890//
891
892always @(posedge clkin_ps or posedge rst_in)
893  if (rst_in)
894     clk2x_out <= 0;
895  else begin
896    clk2x_out <= 1;
897    #(period / 4)
898    clk2x_out <= 0;
899    #(period / 4)
900    clk2x_out <= 1;
901    #(period / 4)
902    clk2x_out <= 0;
903 end
904
905//
906// generate the clkdv_out
907//
908
909always @(posedge clkin_ps or negedge clkin_ps or posedge rst_in)
910  if (rst_in) begin
911       clkdv_out <= 1'b0;
912       clkdv_cnt <= 0;
913  end
914  else
915    if (lock_out1_neg) begin
916      if (clkdv_cnt >= divide_type -1)
917           clkdv_cnt <= 0;
918      else
919           clkdv_cnt <= clkdv_cnt + 1;
920
921      if (clkdv_cnt < divide_type /2)
922          clkdv_out <= 1'b1;
923      else
924         if ( (divide_type[0] == 1'b1) && dll_mode_type == 1'b0)
925             clkdv_out <= #(period/4) 1'b0;
926         else
927            clkdv_out <= 1'b0;
928    end
929
930
931//
932// generate fx output signal
933//
934
935always @(lock_period or period or denominator or numerator) begin
936    if (lock_period == 1'b1) begin
937    period_fx = (period * denominator) / (numerator * 2);
938    remain_fx = (period * denominator) % (numerator * 2);
939    end
940end
941
942always @(posedge clkin_ps or posedge clkin_lost_out or posedge rst_in )
943    if (rst_in == 1)
944       clkfx_out = 1'b0;
945    else if (clkin_lost_out == 1'b1 ) begin
946           if (locked_out == 1)
947            @(negedge rst_reg[2]);
948        end
949    else
950      if (lock_out[1] == 1) begin
951    clkfx_out = 1'b1;
952    for (p = 0; p < (numerator * 2 - 1); p = p + 1) begin
953        #(period_fx);
954            if (p < remain_fx)
955                #1;
956        clkfx_out = !clkfx_out;
957    end
958    if (period_fx > (period / 2)) begin
959        #(period_fx - (period / 2));
960    end
961      end
962
963//
964// generate all output signal
965//
966
967always @(rst_in)
968if (rst_in) begin
969   assign CLK0 = 0;
970   assign CLK90 = 0;
971   assign CLK180 = 0;
972   assign CLK270 = 0;
973   assign CLK2X = 0;
974   assign CLK2X180 =0;
975   assign CLKDV = 0;
976   assign CLKFX = 0;
977   assign CLKFX180 = 0;
978end
979else begin
980   deassign CLK0;
981   deassign CLK90;
982   deassign CLK180;
983   deassign CLK270;
984   deassign CLK2X;
985   deassign CLK2X180;
986   deassign CLKDV;
987   deassign CLKFX;
988   deassign CLKFX180;
989end
990
991always @(clk0_out) begin
992    CLK0 <= #(clkout_delay) clk0_out && (clkfb_type != 2'b00);
993    CLK90 <= #(clkout_delay + period / 4) clk0_out && !dll_mode_type && (clkfb_type != 2'b00);
994    CLK180 <= #(clkout_delay) ~clk0_out && (clkfb_type != 2'b00);
995    CLK270 <= #(clkout_delay + period / 4) ~clk0_out && !dll_mode_type && (clkfb_type != 2'b00);
996  end
997
998always @(clk2x_out) begin
999    CLK2X <= #(clkout_delay) clk2x_out && !dll_mode_type && (clkfb_type != 2'b00);
1000     CLK2X180 <= #(clkout_delay) ~clk2x_out && !dll_mode_type && (clkfb_type != 2'b00);
1001end
1002
1003always @(clkdv_out)
1004    CLKDV <= #(clkout_delay) clkdv_out && (clkfb_type != 2'b00);
1005
1006always @(clkfx_out )
1007    CLKFX <= #(clkout_delay) clkfx_out;
1008
1009always @( clkfx_out or first_time_locked or locked_out)
1010  if ( ~first_time_locked)
1011     CLKFX180 = 0;
1012  else
1013     CLKFX180 <= #(clkout_delay) ~clkfx_out;
1014
1015
1016endmodule
1017
1018//////////////////////////////////////////////////////
1019
1020module dcm_clock_divide_by_2 (clock, clock_type, clock_out, rst);
1021input clock;
1022input clock_type;
1023input rst;
1024output clock_out;
1025
1026reg clock_out;
1027reg clock_div2;
1028reg [2:0] rst_reg;
1029
1030wire clk_src;
1031
1032initial begin
1033    clock_out = 1'b0;
1034    clock_div2 = 1'b0;
1035end
1036
1037always @(posedge clock)
1038    clock_div2 <= ~clock_div2;
1039
1040always @(posedge clock) begin
1041    rst_reg[0] <= rst;
1042    rst_reg[1] <= rst_reg[0] & rst;
1043    rst_reg[2] <= rst_reg[1] & rst_reg[0] & rst;
1044end
1045
1046assign clk_src = (clock_type) ? clock_div2 : clock;
1047
1048always @(clk_src or rst or rst_reg)
1049    if (rst == 1'b0)
1050        clock_out = clk_src;
1051    else if (rst == 1'b1) begin
1052        clock_out = 1'b0;
1053        @(negedge rst_reg[2]);
1054        if (clk_src == 1'b1)
1055          @(negedge clk_src);
1056    end
1057
1058
1059endmodule
1060
1061module dcm_maximum_period_check (clock);
1062parameter clock_name = "";
1063parameter maximum_period = 0;
1064input clock;
1065
1066time clock_edge;
1067time clock_period;
1068
1069initial begin
1070    clock_edge = 0;
1071    clock_period = 0;
1072end
1073
1074always @(posedge clock) begin
1075    clock_edge <= $time;
1076    clock_period <= $time - clock_edge;
1077    if (clock_period > maximum_period ) begin
1078    $display(" Warning : Input clock period of, %1.3f ns, on the %s port of instance %m exceeds allotted value of %1.3f ns at simulation time %1.3f ns.", clock_period/1000.0, clock_name, maximum_period/1000.0, $time/1000.0);
1079    end
1080end
1081endmodule
1082
1083module dcm_clock_lost (clock, enable, lost, rst);
1084input clock;
1085input enable;
1086input rst;
1087output lost;
1088
1089time clock_edge;
1090reg [63:0] period;
1091reg clock_low, clock_high;
1092reg clock_posedge, clock_negedge;
1093reg lost_r, lost_f, lost;
1094reg clock_second_pos, clock_second_neg;
1095
1096initial begin
1097    clock_edge = 0;
1098    clock_high = 0;
1099    clock_low = 0;
1100    lost_r = 0;
1101    lost_f = 0;
1102    period = 0;
1103    clock_posedge = 0;
1104    clock_negedge = 0;
1105    clock_second_pos = 0;
1106    clock_second_neg = 0;
1107end
1108
1109always @(posedge clock or posedge rst)
1110  if (rst==1)
1111    period <= 0;
1112  else begin
1113    clock_edge <= $time;
1114    if (period != 0 && (($time - clock_edge) <= (1.5 * period)))
1115        period <= $time - clock_edge;
1116    else if (period != 0 && (($time - clock_edge) > (1.5 * period)))
1117        period <= 0;
1118    else if ((period == 0) && (clock_edge != 0) && clock_second_pos == 1)
1119        period <= $time - clock_edge;
1120  end
1121
1122
1123always @(posedge clock or posedge rst)
1124  if (rst)
1125    lost_r <= 0;
1126  else
1127  if (enable == 1 && clock_second_pos == 1) begin
1128      #1;
1129      if ( period != 0)
1130         lost_r <= 0;
1131      #((period * 9.1) / 10)
1132      if ((clock_low != 1'b1) && (clock_posedge != 1'b1) && rst == 0)
1133        lost_r <= 1;
1134    end
1135
1136always @(posedge clock or negedge clock or posedge rst)
1137  if (rst) begin
1138     clock_second_pos <= 0;
1139     clock_second_neg <= 0;
1140  end
1141  else if (clock)
1142     clock_second_pos <= 1;
1143  else if (~clock)
1144     clock_second_neg <= 1;
1145
1146always @(negedge clock or posedge rst)
1147  if (rst==1) begin
1148     lost_f <= 0;
1149   end
1150   else begin
1151     if (enable == 1 && clock_second_neg == 1) begin
1152      if ( period != 0)
1153        lost_f <= 0;
1154      #((period * 9.1) / 10)
1155      if ((clock_high != 1'b1) && (clock_negedge != 1'b1) && rst == 0)
1156        lost_f <= 1;
1157    end
1158  end
1159
1160always @( lost_r or lost_f or enable)
1161begin
1162  if (enable == 1)
1163         lost = lost_r | lost_f;
1164  else
1165        lost = 0;
1166end
1167
1168
1169always @(posedge clock or negedge clock or posedge rst)
1170  if (rst==1) begin
1171           clock_low <= 1'b0;
1172           clock_high <= 1'b0;
1173           clock_posedge <= 1'b0;
1174           clock_negedge <= 1'b0;
1175  end
1176  else begin
1177    if (clock ==1) begin
1178           clock_low <= 1'b0;
1179           clock_high <= 1'b1;
1180           clock_posedge <= 1'b0;
1181           clock_negedge <= 1'b1;
1182    end
1183    else if (clock == 0) begin
1184           clock_low <= 1'b1;
1185           clock_high <= 1'b0;
1186           clock_posedge <= 1'b1;
1187           clock_negedge <= 1'b0;
1188    end
1189end
1190
1191
1192endmodule
1193
1194`else
1195
1196
1197`timescale 1 ps / 1 ps
1198
1199module DCM (
1200    CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90,
1201    CLKDV, CLKFX, CLKFX180, LOCKED, PSDONE, STATUS,
1202    CLKFB, CLKIN, DSSEN, PSCLK, PSEN, PSINCDEC, RST);
1203
1204   parameter real CLKDV_DIVIDE = 2.0;
1205   parameter integer CLKFX_DIVIDE = 1;
1206   parameter integer CLKFX_MULTIPLY = 4;
1207   parameter CLKIN_DIVIDE_BY_2 = "FALSE";
1208   parameter real CLKIN_PERIOD = 10.0;
1209   parameter CLKOUT_PHASE_SHIFT = "NONE";
1210   parameter CLK_FEEDBACK = "1X";
1211   parameter DESKEW_ADJUST = "SYSTEM_SYNCHRONOUS";
1212   parameter DFS_FREQUENCY_MODE = "LOW";
1213   parameter DLL_FREQUENCY_MODE = "LOW";
1214   parameter DSS_MODE = "NONE";
1215   parameter DUTY_CYCLE_CORRECTION = "TRUE";
1216   parameter [15:0] FACTORY_JF = 16'hC080;
1217   parameter integer PHASE_SHIFT = 0;
1218   parameter STARTUP_WAIT = "FALSE";
1219
1220   input CLKFB, CLKIN, DSSEN;
1221   input PSCLK, PSEN, PSINCDEC, RST;
1222
1223   output CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90;
1224   output CLKDV, CLKFX, CLKFX180, LOCKED, PSDONE;
1225   output [7:0] STATUS;
1226
1227
1228   reg CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90;
1229   reg CLKDV, CLKFX, CLKFX180;
1230   reg LOCKED_out, PSDONE = 0;
1231   reg [7:0] STATUS = 8'b0;
1232   wire LOCKED;
1233
1234   reg [1:0] clkfb_type, ps_type;
1235   reg clkin_type, align, clkin_divide, fbsync = 0;
1236   reg [2:0] pos_shift, neg_shift;
1237   reg [2:0] pos_shift_st, neg_shift_st;
1238   reg [3:0] deskew_adjust_mode;
1239// reg [8:0] shift = 9'b0;
1240   reg [1:0] clkin_cnt, old_clkin_cnt;
1241   reg clkin_error;
1242   reg period_updated;
1243   reg clkin_cnt_en;
1244   reg rst_tmp, rst_done_fx, rst_done_dv;
1245
1246   integer shift;
1247
1248   realtime clk_period; // = (250*CLKIN_PERIOD);
1249   realtime clkfx_period; // = ((CLKIN_PERIOD*CLKFX_DIVIDE*1000)/(CLKFX_MULTIPLY*2));
1250   realtime shift_ammount; // = ((CLKIN_PERIOD*1000)/256);
1251   realtime clkdv_period; // = ((CLKIN_PERIOD*CLKDV_DIVIDE*1000)/2);
1252   realtime clkin_time1, clkin_time2, period_clkin;
1253
1254   time start_time, delay_time;
1255
1256
1257  initial begin
1258
1259   case (CLKIN_DIVIDE_BY_2)
1260        "false" : clkin_type <= 0;
1261        "FALSE" : clkin_type <= 0;
1262        "true" : clkin_type <= 1;
1263        "TRUE" : clkin_type <= 1;
1264        default : begin
1265            $display("Attribute Syntax Error : The attribute CLKIN_DIVIDE_BY_2 on DCM instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", CLKIN_DIVIDE_BY_2);
1266            $finish;
1267        end
1268    endcase
1269
1270    case (CLKDV_DIVIDE)
1271    1.5 : ;
1272    2.0 : ;
1273    2.5 : ;
1274    3.0 : ;
1275    3.5 : ;
1276    4.0 : ;
1277    4.5 : ;
1278    5.0 : ;
1279        5.5 : ;
1280    6.0 : ;
1281    6.5 : ;
1282    7.0 : ;
1283    7.5 : ;
1284    8.0 : ;
1285    9.0 : ;
1286    10.0 : ;
1287    11.0 : ;
1288    12.0 : ;
1289    13.0 : ;
1290    14.0 : ;
1291    15.0 : ;
1292    16.0 : ;
1293    default : begin
1294        $display("Attribute Syntax Error : The attribute CLKDV_DIVIDE on DCM instance %m is set to %0.1f. Legal values for this attribute are 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, or 16.0.", CLKDV_DIVIDE);
1295        $finish;
1296    end
1297    endcase
1298
1299    if ((CLKFX_DIVIDE <= 0) || (32 < CLKFX_DIVIDE)) begin
1300    $display("Attribute Syntax Error : The attribute CLKFX_DIVIDE on DCM instance %m is set to %d. Legal values for this attribute are 1 ... 32.", CLKFX_DIVIDE);
1301    $finish;
1302    end
1303
1304    if ((CLKFX_MULTIPLY <= 1) || (32 < CLKFX_MULTIPLY)) begin
1305    $display("Attribute Syntax Error : The attribute CLKFX_MULTIPLY on DCM instance %m is set to %d. Legal values for this attribute are 2 ... 32.", CLKFX_MULTIPLY);
1306    $finish;
1307    end
1308
1309    case (CLKIN_DIVIDE_BY_2)
1310    "false" : clkin_divide <= 0;
1311    "FALSE" : clkin_divide <= 0;
1312    "true" : clkin_divide <= 1;
1313    "TRUE" : clkin_divide <= 1;
1314    default : begin
1315        $display("Attribute Syntax Error : The attribute CLKIN_DIVIDE_BY_2 on DCM instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", CLKIN_DIVIDE_BY_2);
1316        $finish;
1317    end
1318    endcase
1319
1320    case (CLKOUT_PHASE_SHIFT)
1321    "NONE" : ps_type <= 0;
1322    "none" : ps_type <= 0;
1323    "FIXED" : ps_type <= 1;
1324        "fixed" : ps_type <= 1;
1325        "VARIABLE" : ps_type <= 2;
1326        "variable" : ps_type <= 2;
1327    default : begin
1328        $display("Attribute Syntax Error : The attribute CLKOUT_PHASE_SHIFT on DCM instance %m is set to %s. Legal values for this attribute are NONE, FIXED or VARIABLE.", CLKOUT_PHASE_SHIFT);
1329        $finish;
1330    end
1331    endcase
1332
1333    case (CLK_FEEDBACK)
1334    "none" : clkfb_type <= 0;
1335    "NONE" : clkfb_type <= 0;
1336    "1x" : clkfb_type <= 1;
1337    "1X" : clkfb_type <= 1;
1338    "2x" : clkfb_type <= 2;
1339    "2X" : clkfb_type <= 2;
1340    default : begin
1341        $display("Attribute Syntax Error : The attribute CLK_FEEDBACK on DCM instance %m is set to %s. Legal values for this attribute are NONE, 1X or 2X.", CLK_FEEDBACK);
1342        $finish;
1343    end
1344    endcase
1345
1346    case (DESKEW_ADJUST)
1347    "source_synchronous" : deskew_adjust_mode <= 8;
1348    "SOURCE_SYNCHRONOUS" : deskew_adjust_mode <= 8;
1349    "system_synchronous" : deskew_adjust_mode <= 11;
1350    "SYSTEM_SYNCHRONOUS" : deskew_adjust_mode <= 11;
1351    "0" : deskew_adjust_mode <= 0;
1352    "1" : deskew_adjust_mode <= 1;
1353    "2" : deskew_adjust_mode <= 2;
1354    "3" : deskew_adjust_mode <= 3;
1355    "4" : deskew_adjust_mode <= 4;
1356    "5" : deskew_adjust_mode <= 5;
1357    "6" : deskew_adjust_mode <= 6;
1358    "7" : deskew_adjust_mode <= 7;
1359    "8" : deskew_adjust_mode <= 8;
1360    "9" : deskew_adjust_mode <= 9;
1361    "10" : deskew_adjust_mode <= 10;
1362    "11" : deskew_adjust_mode <= 11;
1363    "12" : deskew_adjust_mode <= 12;
1364    "13" : deskew_adjust_mode <= 13;
1365    "14" : deskew_adjust_mode <= 14;
1366    "15" : deskew_adjust_mode <= 15;
1367    default : begin
1368        $display("Attribute Syntax Error : The attribute DESKEW_ADJUST on DCM instance %m is set to %s. Legal values for this attribute are SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or 0 ... 15.", DESKEW_ADJUST);
1369        $finish;
1370    end
1371    endcase
1372
1373    case (DFS_FREQUENCY_MODE)
1374    "high" : ;
1375    "HIGH" : ;
1376    "low" : ;
1377    "LOW" : ;
1378    default : begin
1379        $display("Attribute Syntax Error : The attribute DFS_FREQUENCY_MODE on DCM instance %m is set to %s. Legal values for this attribute are HIGH or LOW.", DFS_FREQUENCY_MODE);
1380        $finish;
1381    end
1382    endcase
1383
1384    case (DLL_FREQUENCY_MODE)
1385    "high" : ;
1386    "HIGH" : ;
1387    "low" : ;
1388    "LOW" : ;
1389    default : begin
1390        $display("Attribute Syntax Error : The attribute DLL_FREQUENCY_MODE on DCM instance %m is set to %s. Legal values for this attribute are HIGH or LOW.", DLL_FREQUENCY_MODE);
1391        $finish;
1392    end
1393    endcase
1394
1395    case (DSS_MODE)
1396    "none" : ;
1397    "NONE" : ;
1398    default : begin
1399        $display("Attribute Syntax Error : The attribute DSS_MODE on DCM instance %m is set to %s. The legal value for this attribute is NONE.", DSS_MODE);
1400        $finish;
1401    end
1402    endcase
1403
1404    case (DUTY_CYCLE_CORRECTION)
1405    "false" : begin
1406        $display("Unsupported Attribute Error : The attribute DUTY_CYCLE_CORRECTION on DCM instance %m is set to %s which is not supported in this simulation model. The legal value of DUTY_CYCLE_CORRECTION for this model is TRUE.", DUTY_CYCLE_CORRECTION);
1407            $finish;
1408    end
1409    "FALSE" : begin
1410        $display("Unsupported Attribute Error : The attribute DUTY_CYCLE_CORRECTION on DCM instance %m is set to %s which is not supported in this simulation model. The legal value of DUTY_CYCLE_CORRECTION for this model is TRUE.", DUTY_CYCLE_CORRECTION);
1411            $finish;
1412    end
1413    "true" : ;
1414    "TRUE" : ;
1415    default : begin
1416        $display("Attribute Syntax Error : The attribute DUTY_CYCLE_CORRECTION on DCM instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", DUTY_CYCLE_CORRECTION);
1417        $finish;
1418    end
1419    endcase
1420
1421    if ((PHASE_SHIFT < -255) || (PHASE_SHIFT > 255)) begin
1422    $display("Attribute Syntax Error : The attribute PHASE_SHIFT on DCM instance %m is set to %d. Legal values for this attribute are -255 ... 255.", PHASE_SHIFT);
1423    $display("Error : PHASE_SHIFT = %d is not -255 ... 255.", PHASE_SHIFT);
1424    $finish;
1425    end
1426
1427    case (STARTUP_WAIT)
1428    "false" : ;
1429    "FALSE" : ;
1430    "true" : ;
1431    "TRUE" : ;
1432    default : begin
1433        $display("Attribute Syntax Error : The attribute STARTUP_WAIT on DCM instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", STARTUP_WAIT);
1434        $finish;
1435    end
1436    endcase
1437
1438
1439// if (CLKIN_PERIOD == 0.0) begin
1440// $display("Attribute Syntax Error : The attribute CLKIN_PERIOD on DCM instance %m must be defined to the value of the input clock period in nano-seconds");
1441// $finish;
1442// end
1443end
1444
1445// always @(posedge RST) begin
1446// disable main_dcm;
1447// disable clkdv_dcm;
1448// disable clkfx_dcm;
1449// end
1450
1451   integer t;
1452
1453
1454   assign #100 LOCKED = LOCKED_out;
1455
1456   always begin: feedback_dcm
1457      fbsync = 0;
1458      wait (RST==0);
1459      wait (period_updated==1)
1460      @(posedge CLKFB);
1461      delay_time = $time - start_time;
1462      @(posedge CLKIN);
1463      #(((12*clk_period)-(delay_time)));
1464      fbsync = 1;
1465      wait (RST==1);
1466   end
1467
1468   always begin: main_dcm
1469      pos_shift[0] = 1'b0;
1470      neg_shift[0] = 1'b0;
1471      align = 0;
1472      LOCKED_out = 1'b0;
1473      period_updated = 0;
1474      clkin_cnt_en = 0;
1475      CLK0 = 1'b0;
1476      CLK90 = 1'b0;
1477      CLK180 = 1'b0;
1478      CLK270 = 1'b0;
1479      CLK2X = 1'b0;
1480      CLK2X180 = 1'b0;
1481      rst_tmp <= 1'b1;
1482      wait (RST==0);
1483      wait (rst_done_fx==1 );
1484      wait (rst_done_dv==1);
1485       rst_tmp <= 1'b0;
1486      @(posedge CLKIN);
1487      clkin_time1 = $time;
1488      @(posedge CLKIN);
1489      clkin_time2 = $time;
1490      period_clkin = clkin_time2 - clkin_time1;
1491
1492      clk_period = (0.25*period_clkin);
1493      clkfx_period = ((period_clkin*CLKFX_DIVIDE)/(CLKFX_MULTIPLY*2));
1494      shift_ammount = ((period_clkin)/256);
1495      clkdv_period = ((period_clkin*CLKDV_DIVIDE)/2);
1496
1497      @(posedge CLKIN);
1498      period_updated = 1;
1499      start_time = $time;
1500      repeat (6) begin
1501         CLK0 = ~CLK0;
1502         CLK2X = ~CLK2X;
1503     #(clk_period);
1504     CLK2X = ~CLK2X;
1505     #(clk_period);
1506      end
1507      repeat (6) begin
1508         CLK0 = ~CLK0;
1509         CLK2X = ~CLK2X;
1510         #(clk_period);
1511         CLK2X = ~CLK2X;
1512         #(clk_period);
1513      end
1514      if (clkfb_type != 0)
1515     wait(fbsync==1);
1516      if (ps_type != 0)
1517    if (PHASE_SHIFT > 0)
1518      #((period_clkin*PHASE_SHIFT)/256);
1519    else if (PHASE_SHIFT < 0)
1520      #((period_clkin)-((period_clkin*PHASE_SHIFT)/256));
1521      align = 1;
1522      CLK0 = ~CLK0;
1523      CLK2X = ~CLK2X;
1524      #(clk_period);
1525      CLK90 = ~CLK90;
1526      CLK2X = ~CLK2X;
1527      CLK2X180 = ~CLK2X180;
1528      #(clk_period);
1529      repeat (7) begin
1530     CLK0 = ~CLK0;
1531     CLK180 = ~CLK180;
1532     CLK2X = ~CLK2X;
1533     CLK2X180 = ~CLK2X180;
1534     #(clk_period);
1535     CLK90 = ~CLK90;
1536     CLK2X = ~CLK2X;
1537     CLK2X180 = ~CLK2X180;
1538     CLK270 = ~CLK270;
1539     #(clk_period);
1540      end
1541      LOCKED_out = 1'b1;
1542      clkin_cnt_en = 1'b1;
1543// forever begin
1544      while (RST==0) begin
1545     CLK0 = ~CLK0;
1546     CLK180 = ~CLK180;
1547     CLK2X = ~CLK2X;
1548     CLK2X180 = ~CLK2X180;
1549     #(clk_period);
1550     CLK90 = ~CLK90;
1551     CLK270 = ~CLK270;
1552     CLK2X = ~CLK2X;
1553     CLK2X180 = ~CLK2X180;
1554         #(clk_period);
1555         CLK0 = ~CLK0;
1556         CLK180 = ~CLK180;
1557         CLK2X = ~CLK2X;
1558         CLK2X180 = ~CLK2X180;
1559         #(clk_period);
1560         CLK90 = ~CLK90;
1561         CLK270 = ~CLK270;
1562         CLK2X = ~CLK2X;
1563         CLK2X180 = ~CLK2X180;
1564     if (pos_shift_st[0]==1'b1 && pos_shift[0]==1'b0) begin
1565           #((clk_period)+shift_ammount);
1566// pos_shift[0] <= 1;
1567        pos_shift[0] = 1;
1568     end
1569     else if (neg_shift_st[0]==1'b1 && neg_shift[0]==1'b0) begin
1570       #((clk_period)-shift_ammount);
1571// neg_shift[0] <= 1;
1572        neg_shift[0] = 1;
1573     end
1574     else begin
1575           if (pos_shift_st[0] == 1'b0)
1576// pos_shift[0] <= 0;
1577               pos_shift[0] = 0;
1578           if (neg_shift_st[0] == 1'b0)
1579// neg_shift[0] <= 0;
1580               neg_shift[0] = 0;
1581       #(clk_period);
1582         end
1583     if (clkin_error)
1584       wait (0);
1585      end
1586   end
1587
1588   always begin: clkfx_dcm
1589      pos_shift[1]=1'b0;
1590      neg_shift[1]=1'b0;
1591      CLKFX = 1'b0;
1592      CLKFX180 = 1'b0;
1593      rst_done_fx <= 1'b1;
1594// wait (RST==0);
1595      wait (rst_tmp==0 && RST==0);
1596      wait (LOCKED_out==1);
1597      rst_done_fx <= 1'b0;
1598      CLKFX = 1;
1599      CLKFX180 = 0;
1600// forever begin
1601      while (RST== 0 && rst_tmp==0) begin
1602         #(clkfx_period);
1603         CLKFX = ~CLKFX;
1604     CLKFX180 = ~CLKFX180;
1605     if (pos_shift_st[1]==1'b1 && pos_shift[1]==1'b0) begin
1606           #((clkfx_period)+shift_ammount);
1607        pos_shift[1] <= 1;
1608     end
1609     else if (neg_shift_st[1]==1'b1 && neg_shift[1]==1'b0) begin
1610       #((clkfx_period)-shift_ammount);
1611        neg_shift[1] <= 1;
1612     end
1613     else begin
1614           if (pos_shift_st[1] == 1'b0)
1615               pos_shift[1] <= 0;
1616           if (neg_shift_st[1] == 1'b0)
1617               neg_shift[1] <= 0;
1618       #(clkfx_period);
1619         end
1620         CLKFX = ~CLKFX;
1621     CLKFX180 = ~CLKFX180;
1622     if (clkin_error)
1623       wait(0);
1624      end
1625   end
1626
1627   always begin: clkdv_dcm
1628      pos_shift[2] = 0;
1629      neg_shift[2] = 0;
1630      CLKDV = 1'b0;
1631      rst_done_dv <= 1'b1;
1632// wait (RST==0);
1633      wait (rst_tmp==0 && RST==0);
1634      wait (LOCKED_out==1);
1635      rst_done_dv <= 1'b0;
1636      CLKDV = ~CLKDV;
1637// forever begin
1638      while (RST==0 && rst_tmp==0) begin
1639     if (pos_shift_st[2]==1'b1 && pos_shift[2]==1'b0) begin
1640           #(clkdv_period+shift_ammount);
1641        pos_shift[2] = 1;
1642     end
1643     else if (neg_shift_st[2]==1'b1 && neg_shift[2]==1'b0) begin
1644       #(clkdv_period-shift_ammount);
1645        neg_shift[2] = 1;
1646     end
1647     else begin
1648            if (pos_shift_st[2] == 1'b0)
1649               pos_shift[2] <= 0;
1650            if (neg_shift_st[2] == 1'b0)
1651               neg_shift[2] <= 0;
1652        #(clkdv_period);
1653         end
1654     CLKDV = ~CLKDV;
1655     if (clkin_error)
1656       wait(0);
1657      end
1658   end
1659
1660   initial shift = 0;
1661
1662   always @(posedge PSCLK) begin: dps_dcm
1663      PSDONE <= 1'b0;
1664      if (ps_type==2) begin
1665    if (PSEN) begin
1666         if (pos_shift != 3'b000 || neg_shift != 3'b000)
1667             $display("Warning : Please wait for PSDONE signal before adjusting the Phase Shift. %m at time %t. ", $time);
1668         else begin
1669      if (PSINCDEC==1'b1 && pos_shift==3'b000) begin
1670        pos_shift_st <= 3'b111;
1671        shift = shift + 1;
1672            if (shift > 256)
1673               STATUS[0] <= 1;
1674            else
1675               STATUS[0] <= 0;
1676      end
1677          else if (PSINCDEC==1'b0 && neg_shift==3'b000) begin
1678        neg_shift_st <= 3'b111;
1679        shift = shift - 1;
1680            if (shift < -256)
1681               STATUS[0] <= 1;
1682            else
1683               STATUS[0] <= 0;
1684      end
1685         end
1686       end
1687       if (pos_shift==3'b111) begin
1688           pos_shift_st <= 3'b000;
1689           PSDONE <= 1'b1;
1690       end
1691       if (neg_shift==3'b111) begin
1692           neg_shift_st <= 3'b000;
1693           PSDONE <= 1'b1;
1694       end
1695     end
1696   end // block: dps_dcm
1697
1698
1699   always @(posedge CLKIN)
1700     if (RST) begin
1701    clkin_cnt <= 2'b00;
1702     end
1703     else begin
1704       if (clkin_cnt_en ==1)
1705            clkin_cnt <= clkin_cnt + 1;
1706     end
1707
1708   always @(posedge CLK0 or posedge RST) begin : status_dcm
1709   if (RST) begin
1710      old_clkin_cnt <= 0;
1711       clkin_error <= 1'b0;
1712   end
1713   else
1714      if (clkin_cnt_en== 1'b1) begin
1715      #1 clkin_error <= 1'b0;
1716      @(posedge CLK0);
1717      if (clkin_cnt == old_clkin_cnt) begin
1718// $display("Error: This DCM simulation for %m does not support the stopping of CLKIN or the use of frequecies to other than that specified for the CLKIN_PERIOD, %f.\nPlease use the standard DCM model to properly view this behavior.\nAll DCM outputs will be suspended until the DCM is reset.",CLKIN_PERIOD);
1719     $display("Error: This DCM simulation for %m does not support the stopping of CLKIN.\nPlease use the standard DCM model to properly view this behavior.\nAll DCM outputs will be suspended until the DCM is reset.");
1720     clkin_error <= 1;
1721     wait (RST==1);
1722      end
1723      else
1724    old_clkin_cnt <= clkin_cnt;
1725   end
1726  end
1727
1728
1729endmodule
1730
1731`endif
Examples/sram_gpio/logic/sim/unisims/DCM_SP.v
1// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/DCM_SP.v,v 1.9.4.3 2007/04/11 20:30:19 yanx Exp $
2///////////////////////////////////////////////////////////////////////////////
3// Copyright (c) 1995/2004 Xilinx, Inc.
4// All Right Reserved.
5///////////////////////////////////////////////////////////////////////////////
6// ____ ____
7// / /\/ /
8// /___/ \ / Vendor : Xilinx
9// \ \ \/ Version : 9.2i (J.36)
10// \ \ Description : Xilinx Function Simulation Library Component
11// / / Digital Clock Manager
12// /___/ /\ Filename : DCM_SP.v
13// \ \ / \ Timestamp :
14// \___\/\___\
15//
16// Revision:
17// 02/28/06 - Initial version.
18// 05/09/06 - Add clkin_ps_mkup and clkin_ps_mkup_win for phase shifting (CR 229789).
19// 06/14/06 - Add clkin_ps_mkup_flag for multiple cycle delays (CR233283).
20// 07/21/06 - Change range of variable phase shifting to +/- integer of 20*(Period-3ns).
21// Give warning not support initial phase shifting for variable phase shifting.
22// (CR 235216).
23// 09/22/06 - Add lock_period and lock_fb to clkfb_div block (CR 418722).
24// 12/19/06 - Add clkfb_div_en for clkfb2x divider (CR431210).
25// 04/06/07 - Enable the clock out in clock low time after reset in model
26// clock_divide_by_2 (CR 437471).
27// End Revision
28
29
30`timescale 1 ps / 1 ps
31
32module DCM_SP (
33    CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90,
34    CLKDV, CLKFX, CLKFX180, LOCKED, PSDONE, STATUS,
35    CLKFB, CLKIN, DSSEN, PSCLK, PSEN, PSINCDEC, RST);
36
37parameter CLKDV_DIVIDE = 2.0;
38parameter integer CLKFX_DIVIDE = 1;
39parameter integer CLKFX_MULTIPLY = 4;
40parameter CLKIN_DIVIDE_BY_2 = "FALSE";
41parameter CLKIN_PERIOD = 10.0; // non-simulatable
42parameter CLKOUT_PHASE_SHIFT = "NONE";
43parameter CLK_FEEDBACK = "1X";
44parameter DESKEW_ADJUST = "SYSTEM_SYNCHRONOUS"; // non-simulatable
45parameter DFS_FREQUENCY_MODE = "LOW";
46parameter DLL_FREQUENCY_MODE = "LOW";
47parameter DSS_MODE = "NONE"; // non-simulatable
48parameter DUTY_CYCLE_CORRECTION = "TRUE";
49parameter FACTORY_JF = 16'hC080; // non-simulatable
50parameter integer MAXPERCLKIN = 1000000; // non-modifiable simulation parameter
51parameter integer MAXPERPSCLK = 100000000; // non-modifiable simulation parameter
52parameter integer PHASE_SHIFT = 0;
53parameter integer SIM_CLKIN_CYCLE_JITTER = 300; // non-modifiable simulation parameter
54parameter integer SIM_CLKIN_PERIOD_JITTER = 1000; // non-modifiable simulation parameter
55parameter STARTUP_WAIT = "FALSE"; // non-simulatable
56
57
58localparam PS_STEP = 25;
59
60input CLKFB, CLKIN, DSSEN;
61input PSCLK, PSEN, PSINCDEC, RST;
62
63output CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90;
64output CLKDV, CLKFX, CLKFX180, LOCKED, PSDONE;
65output [7:0] STATUS;
66
67reg CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90;
68reg CLKDV, CLKFX, CLKFX180;
69
70wire locked_out_out;
71wire clkfb_in, clkin_in, dssen_in;
72wire psclk_in, psen_in, psincdec_in, rst_in;
73reg clk0_out;
74reg clk2x_out, clkdv_out;
75reg clkfx_out, clkfx180_en;
76reg rst_flag;
77reg locked_out, psdone_out, ps_overflow_out, ps_lock;
78reg clkfb_div, clkfb_chk, clkfb_div_en;
79integer clkdv_cnt;
80
81reg [1:0] clkfb_type;
82reg [8:0] divide_type;
83reg clkin_type;
84reg [1:0] ps_type;
85reg [3:0] deskew_adjust_mode;
86reg dfs_mode_type;
87reg dll_mode_type;
88reg clk1x_type;
89integer ps_in;
90
91reg lock_period, lock_delay, lock_clkin, lock_clkfb;
92reg first_time_locked;
93reg en_status;
94reg ps_overflow_out_ext;
95reg clkin_lost_out_ext;
96reg clkfx_lost_out_ext;
97reg [1:0] lock_out;
98reg lock_out1_neg;
99reg lock_fb, lock_ps, lock_ps_dly, lock_fb_dly, lock_fb_dly_tmp;
100reg fb_delay_found;
101reg clock_stopped;
102reg clkin_chkin, clkfb_chkin;
103
104wire chk_enable, chk_rst;
105wire clkin_div;
106wire lock_period_pulse;
107wire lock_period_dly, lock_period_dly1;
108
109reg clkin_ps, clkin_ps_tmp, clkin_ps_mkup, clkin_ps_mkup_win, clkin_ps_mkup_flag;
110reg clkin_fb;
111
112time FINE_SHIFT_RANGE;
113//time ps_delay, ps_delay_init, ps_delay_md, ps_delay_all, ps_max_range;
114integer ps_delay, ps_delay_init, ps_delay_md, ps_delay_all, ps_max_range;
115integer ps_delay_last;
116integer ps_acc;
117time clkin_edge;
118time clkin_div_edge;
119time clkin_ps_edge;
120time delay_edge;
121time clkin_period [2:0];
122time period;
123integer period_int, period_int2, period_int3, period_ps_tmp;
124time period_div;
125integer period_orig_int;
126time period_orig;
127time period_ps;
128time clkout_delay;
129time fb_delay;
130time period_fx, remain_fx;
131time period_dv_high, period_dv_low;
132time cycle_jitter, period_jitter;
133
134reg clkin_window, clkfb_window;
135reg [2:0] rst_reg;
136reg [12:0] numerator, denominator, gcd;
137reg [23:0] i, n, d, p;
138
139reg notifier;
140
141initial begin
142    #1;
143    if ($realtime == 0) begin
144    $display ("Simulator Resolution Error : Simulator resolution is set to a value greater than 1 ps.");
145    $display ("In order to simulate the DCM_SP, the simulator resolution must be set to 1ps or smaller.");
146    $finish;
147    end
148end
149
150initial begin
151    case (2.0)
152    1.5 : divide_type = 'd3;
153    2.0 : divide_type = 'd4;
154    2.5 : divide_type = 'd5;
155    3.0 : divide_type = 'd6;
156    3.5 : divide_type = 'd7;
157    4.0 : divide_type = 'd8;
158    4.5 : divide_type = 'd9;
159    5.0 : divide_type = 'd10;
160    5.5 : divide_type = 'd11;
161    6.0 : divide_type = 'd12;
162    6.5 : divide_type = 'd13;
163    7.0 : divide_type = 'd14;
164    7.5 : divide_type = 'd15;
165    8.0 : divide_type = 'd16;
166    9.0 : divide_type = 'd18;
167    10.0 : divide_type = 'd20;
168    11.0 : divide_type = 'd22;
169    12.0 : divide_type = 'd24;
170    13.0 : divide_type = 'd26;
171    14.0 : divide_type = 'd28;
172    15.0 : divide_type = 'd30;
173    16.0 : divide_type = 'd32;
174    default : begin
175        $display("Attribute Syntax Error : The attribute CLKDV_DIVIDE on DCM_SP instance %m is set to %0.1f. Legal values for this attribute are 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, or 16.0.", CLKDV_DIVIDE);
176        $finish;
177    end
178    endcase
179
180    if ((CLKFX_DIVIDE <= 0) || (32 < CLKFX_DIVIDE)) begin
181    $display("Attribute Syntax Error : The attribute CLKFX_DIVIDE on DCM_SP instance %m is set to %d. Legal values for this attribute are 1 ... 32.", CLKFX_DIVIDE);
182    $finish;
183    end
184
185    if ((CLKFX_MULTIPLY <= 1) || (32 < CLKFX_MULTIPLY)) begin
186    $display("Attribute Syntax Error : The attribute CLKFX_MULTIPLY on DCM_SP instance %m is set to %d. Legal values for this attribute are 2 ... 32.", CLKFX_MULTIPLY);
187    $finish;
188    end
189
190    case (CLKIN_DIVIDE_BY_2)
191    "false" : clkin_type = 0;
192    "FALSE" : clkin_type = 0;
193    "true" : clkin_type = 1;
194    "TRUE" : clkin_type = 1;
195    default : begin
196        $display("Attribute Syntax Error : The attribute CLKIN_DIVIDE_BY_2 on DCM_SP instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", CLKIN_DIVIDE_BY_2);
197        $finish;
198    end
199    endcase
200
201    case (CLKOUT_PHASE_SHIFT)
202    "NONE" : begin
203             ps_in = 256;
204             ps_type = 0;
205             end
206    "none" : begin
207             ps_in = 256;
208             ps_type = 0;
209             end
210    "FIXED" : begin
211             ps_in = PHASE_SHIFT + 256;
212             ps_type = 1;
213             end
214    "fixed" : begin
215             ps_in = PHASE_SHIFT + 256;
216             ps_type = 1;
217             end
218    "VARIABLE" : begin
219             ps_in = PHASE_SHIFT + 256;
220             ps_type = 2;
221             end
222    "variable" : begin
223             ps_in = PHASE_SHIFT + 256;
224             ps_type = 2;
225                         if (PHASE_SHIFT != 0)
226                         $display("Attribute Syntax Warning : The attribute PHASE_SHIFT on DCM_SP instance %m is set to %d. The maximum variable phase shift range is only valid when initial phase shift PHASE_SHIFT is zero.", PHASE_SHIFT);
227             end
228    default : begin
229        $display("Attribute Syntax Error : The attribute CLKOUT_PHASE_SHIFT on DCM_SP instance %m is set to %s. Legal values for this attribute are NONE, FIXED or VARIABLE.", CLKOUT_PHASE_SHIFT);
230        $finish;
231    end
232    endcase
233
234
235    case (CLK_FEEDBACK)
236    "none" : clkfb_type = 2'b00;
237    "NONE" : clkfb_type = 2'b00;
238    "1x" : clkfb_type = 2'b01;
239    "1X" : clkfb_type = 2'b01;
240    "2x" : clkfb_type = 2'b10;
241    "2X" : clkfb_type = 2'b10;
242    default : begin
243        $display("Attribute Syntax Error : The attribute CLK_FEEDBACK on DCM_SP instance %m is set to %s. Legal values for this attribute are NONE, 1X or 2X.", CLK_FEEDBACK);
244        $finish;
245    end
246    endcase
247
248    case (DESKEW_ADJUST)
249    "source_synchronous" : deskew_adjust_mode = 8;
250    "SOURCE_SYNCHRONOUS" : deskew_adjust_mode = 8;
251    "system_synchronous" : deskew_adjust_mode = 11;
252    "SYSTEM_SYNCHRONOUS" : deskew_adjust_mode = 11;
253    "0" : deskew_adjust_mode = 0;
254    "1" : deskew_adjust_mode = 1;
255    "2" : deskew_adjust_mode = 2;
256    "3" : deskew_adjust_mode = 3;
257    "4" : deskew_adjust_mode = 4;
258    "5" : deskew_adjust_mode = 5;
259    "6" : deskew_adjust_mode = 6;
260    "7" : deskew_adjust_mode = 7;
261    "8" : deskew_adjust_mode = 8;
262    "9" : deskew_adjust_mode = 9;
263    "10" : deskew_adjust_mode = 10;
264    "11" : deskew_adjust_mode = 11;
265    "12" : deskew_adjust_mode = 12;
266    "13" : deskew_adjust_mode = 13;
267    "14" : deskew_adjust_mode = 14;
268    "15" : deskew_adjust_mode = 15;
269    default : begin
270        $display("Attribute Syntax Error : The attribute DESKEW_ADJUST on DCM_SP instance %m is set to %s. Legal values for this attribute are SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or 0 ... 15.", DESKEW_ADJUST);
271        $finish;
272    end
273    endcase
274
275    case (DFS_FREQUENCY_MODE)
276    "high" : dfs_mode_type = 1;
277    "HIGH" : dfs_mode_type = 1;
278    "low" : dfs_mode_type = 0;
279    "LOW" : dfs_mode_type = 0;
280    default : begin
281        $display("Attribute Syntax Error : The attribute DFS_FREQUENCY_MODE on DCM_SP instance %m is set to %s. Legal values for this attribute are HIGH or LOW.", DFS_FREQUENCY_MODE);
282        $finish;
283    end
284    endcase
285
286    period_jitter = SIM_CLKIN_PERIOD_JITTER;
287    cycle_jitter = SIM_CLKIN_CYCLE_JITTER;
288
289    case (DLL_FREQUENCY_MODE)
290    "high" : dll_mode_type = 1;
291    "HIGH" : dll_mode_type = 1;
292    "low" : dll_mode_type = 0;
293    "LOW" : dll_mode_type = 0;
294    default : begin
295        $display("Attribute Syntax Error : The attribute DLL_FREQUENCY_MODE on DCM_SP instance %m is set to %s. Legal values for this attribute are HIGH or LOW.", DLL_FREQUENCY_MODE);
296        $finish;
297    end
298    endcase
299
300    if ((dll_mode_type ==1) && (clkfb_type == 2'b10)) begin
301        $display("Attribute Syntax Error : The attributes DLL_FREQUENCY_MODE on DCM_SP instance %m is set to %s and CLK_FEEDBACK is set to %s. CLK_FEEDBACK 2X is not supported when DLL_FREQUENCY_MODE is HIGH.", DLL_FREQUENCY_MODE, CLK_FEEDBACK);
302           $finish;
303    end
304
305    case (DSS_MODE)
306    "none" : ;
307    "NONE" : ;
308    default : begin
309        $display("Attribute Syntax Error : The attribute DSS_MODE on DCM_SP instance %m is set to %s. Legal values for this attribute is NONE.", DSS_MODE);
310        $finish;
311    end
312    endcase
313
314    case (DUTY_CYCLE_CORRECTION)
315    "false" : clk1x_type = 0;
316    "FALSE" : clk1x_type = 0;
317    "true" : clk1x_type = 1;
318    "TRUE" : clk1x_type = 1;
319    default : begin
320        $display("Attribute Syntax Error : The attribute DUTY_CYCLE_CORRECTION on DCM_SP instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", DUTY_CYCLE_CORRECTION);
321        $finish;
322    end
323    endcase
324
325    if ((PHASE_SHIFT < -255) || (PHASE_SHIFT > 255)) begin
326    $display("Attribute Syntax Error : The attribute PHASE_SHIFT on DCM_SP instance %m is set to %d. Legal values for this attribute are -255 ... 255.", PHASE_SHIFT);
327    $display("Error : PHASE_SHIFT = %d is not -255 ... 255.", PHASE_SHIFT);
328    $finish;
329    end
330
331    case (STARTUP_WAIT)
332    "false" : ;
333    "FALSE" : ;
334    "true" : ;
335    "TRUE" : ;
336    default : begin
337        $display("Attribute Syntax Error : The attribute STARTUP_WAIT on DCM_SP instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", STARTUP_WAIT);
338        $finish;
339    end
340    endcase
341end
342
343//
344// fx parameters
345//
346
347initial begin
348    gcd = 1;
349    for (i = 2; i <= CLKFX_MULTIPLY; i = i + 1) begin
350    if (((CLKFX_MULTIPLY % i) == 0) && ((CLKFX_DIVIDE % i) == 0))
351        gcd = i;
352    end
353    numerator = CLKFX_MULTIPLY / gcd;
354    denominator = CLKFX_DIVIDE / gcd;
355end
356
357//
358// input wire delays
359//
360
361buf b_clkin (clkin_in, CLKIN);
362buf b_clkfb (clkfb_in, CLKFB);
363buf b_dssen (dssen_in, DSSEN);
364buf b_psclk (psclk_in, PSCLK);
365buf b_psen (psen_in, PSEN);
366buf b_psincdec (psincdec_in, PSINCDEC);
367buf b_rst (rst_in, RST);
368buf #100 b_LOCKED (LOCKED, locked_out_out);
369buf #100 b_PSDONE (PSDONE, psdone_out);
370buf b_ps_overflow (STATUS[0], ps_overflow_out_ext);
371buf b_clkin_lost (STATUS[1], clkin_lost_out_ext);
372buf b_clkfx_lost (STATUS[2], clkfx_lost_out_ext);
373
374assign STATUS[7:3] = 5'b0;
375
376dcm_sp_clock_divide_by_2 i_clock_divide_by_2 (clkin_in, clkin_type, clkin_div, rst_in);
377
378dcm_sp_maximum_period_check #("CLKIN", MAXPERCLKIN) i_max_clkin (clkin_in, rst_in);
379dcm_sp_maximum_period_check #("PSCLK", MAXPERPSCLK) i_max_psclk (psclk_in, rst_in);
380
381dcm_sp_clock_lost i_clkin_lost (clkin_in, first_time_locked, clkin_lost_out, rst_in);
382dcm_sp_clock_lost i_clkfx_lost (CLKFX, first_time_locked, clkfx_lost_out, rst_in);
383
384always @(rst_in or en_status or clkfx_lost_out or clkin_lost_out or ps_overflow_out)
385   if (rst_in == 1 || en_status == 0) begin
386       ps_overflow_out_ext = 0;
387       clkin_lost_out_ext = 0;
388       clkfx_lost_out_ext = 0;
389    end
390   else
391   begin
392      ps_overflow_out_ext = ps_overflow_out;
393      clkin_lost_out_ext = clkin_lost_out;
394      clkfx_lost_out_ext = clkfx_lost_out;
395   end
396
397always @(posedge rst_in or posedge LOCKED)
398  if (rst_in == 1)
399      en_status <= 0;
400   else
401      en_status <= 1;
402
403
404always @(clkin_div)
405    clkin_ps_tmp <= #(ps_delay_md) clkin_div;
406
407always @(clkin_ps_tmp or clkin_ps_mkup or clkin_ps_mkup_win)
408  if (clkin_ps_mkup_win)
409       clkin_ps = clkin_ps_mkup;
410  else
411       clkin_ps = clkin_ps_tmp;
412
413always @(ps_delay_last or period_int or ps_delay) begin
414    period_int2 = 2 * period_int;
415    period_int3 = 3 * period_int;
416  if ((ps_delay_last >= period_int && ps_delay < period_int) ||
417       (ps_delay_last >= period_int2 && ps_delay < period_int2) ||
418       (ps_delay_last >= period_int3 && ps_delay < period_int3))
419           clkin_ps_mkup_flag = 1;
420   else
421           clkin_ps_mkup_flag = 0;
422end
423
424always @(posedge clkin_div or negedge clkin_div) begin
425 if (ps_type == 2'b10) begin
426  if ((ps_delay_last > 0 && ps_delay <= 0 ) || clkin_ps_mkup_flag == 1) begin
427     if (clkin_div) begin
428        clkin_ps_mkup_win <= 1;
429        clkin_ps_mkup <= 1;
430        #1;
431        @(negedge clkin_div) begin
432           clkin_ps_mkup_win <= 1;
433           clkin_ps_mkup <= 0;
434        end
435     end
436     else begin
437        clkin_ps_mkup_win <= 0;
438        clkin_ps_mkup <= 0;
439        #1;
440        @(posedge clkin_div) begin
441           clkin_ps_mkup_win <= 1;
442           clkin_ps_mkup <= 1;
443        end
444        @(negedge clkin_div) begin
445           clkin_ps_mkup_win <= 1;
446           clkin_ps_mkup <= 0;
447        end
448     end
449   end
450   else begin
451        clkin_ps_mkup_win <= 0;
452        clkin_ps_mkup <= 0;
453   end
454   ps_delay_last <= ps_delay;
455 end
456end
457
458always @(clkin_ps or lock_fb)
459    clkin_fb = clkin_ps & lock_fb;
460
461always @(negedge clkfb_in or posedge rst_in)
462    if (rst_in)
463        clkfb_div_en <= 0;
464    else
465       if (lock_fb_dly && lock_period && lock_fb && ~clkin_ps)
466          clkfb_div_en <= 1;
467
468always @(posedge clkfb_in or posedge rst_in)
469    if (rst_in)
470        clkfb_div <= 0;
471    else
472      if (clkfb_div_en )
473        clkfb_div <= ~clkfb_div;
474
475always @(clkfb_in or clkfb_div )
476    if (clkfb_type == 2'b10 )
477         clkfb_chk = clkfb_div;
478    else
479         clkfb_chk = clkfb_in & lock_fb_dly;
480
481always @(posedge clkin_fb or posedge chk_rst)
482    if (chk_rst)
483       clkin_chkin <= 0;
484    else
485       clkin_chkin <= 1;
486
487always @(posedge clkfb_chk or posedge chk_rst)
488    if (chk_rst)
489       clkfb_chkin <= 0;
490    else
491       clkfb_chkin <= 1;
492
493    assign chk_rst = (rst_in==1 || clock_stopped==1 ) ? 1 : 0;
494    assign chk_enable = (clkin_chkin == 1 && clkfb_chkin == 1 &&
495                         lock_ps ==1 && lock_fb ==1 && lock_fb_dly == 1) ? 1 : 0;
496
497always @(posedge clkin_div or posedge rst_in)
498  if (rst_in) begin
499     period_div <= 0;
500     clkin_div_edge <= 0;
501   end
502  else
503   if ( clkin_div ==1 ) begin
504      clkin_div_edge <= $time;
505      if (($time - clkin_div_edge) <= (1.5 * period_div))
506      period_div <= $time - clkin_div_edge;
507      else if ((period_div == 0) && (clkin_div_edge != 0))
508      period_div <= $time - clkin_div_edge;
509   end
510
511always @(posedge clkin_ps or posedge rst_in)
512  if (rst_in) begin
513        period_ps <= 0;
514        clkin_ps_edge <= 0;
515  end
516  else
517  if (clkin_ps == 1 ) begin
518    clkin_ps_edge <= $time;
519    if (($time - clkin_ps_edge) <= (1.5 * period_ps))
520    period_ps <= $time - clkin_ps_edge;
521    else if ((period_ps == 0) && (clkin_ps_edge != 0))
522    period_ps <= $time - clkin_ps_edge;
523 end
524
525always @(posedge clkin_ps) begin
526    lock_ps <= lock_period;
527    lock_ps_dly <= lock_ps;
528    lock_fb <= lock_ps_dly;
529    lock_fb_dly_tmp <= lock_fb;
530end
531
532always @(negedge clkin_ps or posedge rst_in)
533  if (rst_in)
534    lock_fb_dly <= 1'b0;
535  else
536    lock_fb_dly <= #(period/4) lock_fb_dly_tmp;
537
538
539always @(period or fb_delay )
540  if (fb_delay == 0)
541    clkout_delay = 0;
542  else
543    clkout_delay = period - fb_delay;
544
545//
546// generate master reset signal
547//
548
549always @(posedge clkin_in) begin
550    rst_reg[0] <= rst_in;
551    rst_reg[1] <= rst_reg[0] & rst_in;
552    rst_reg[2] <= rst_reg[1] & rst_reg[0] & rst_in;
553end
554
555reg rst_tmp1, rst_tmp2;
556initial
557begin
558rst_tmp1 = 0;
559rst_tmp2 = 0;
560rst_flag = 0;
561end
562
563always @(rst_in)
564begin
565   if (rst_in)
566       rst_flag = 0;
567
568   rst_tmp1 = rst_in;
569   if (rst_tmp1 == 0 && rst_tmp2 == 1) begin
570      if ((rst_reg[2] & rst_reg[1] & rst_reg[0]) == 0) begin
571         rst_flag = 1;
572    $display("Input Error : RST on instance %m must be asserted for 3 CLKIN clock cycles.");
573      end
574   end
575   rst_tmp2 = rst_tmp1;
576end
577
578initial begin
579    CLK0 = 0;
580    CLK180 = 0;
581    CLK270 = 0;
582    CLK2X = 0;
583    CLK2X180 = 0;
584    CLK90 = 0;
585    CLKDV = 0;
586    CLKFX = 0;
587    CLKFX180 = 0;
588    clk0_out = 0;
589    clk2x_out = 0;
590    clkdv_out = 0;
591    clkdv_cnt = 0;
592    clkfb_window = 0;
593    clkfx_out = 0;
594    clkfx180_en = 0;
595    clkin_div_edge = 0;
596    clkin_period[0] = 0;
597    clkin_period[1] = 0;
598    clkin_period[2] = 0;
599    clkin_edge = 0;
600    clkin_ps_edge = 0;
601    clkin_window = 0;
602    clkout_delay = 0;
603    clock_stopped = 1;
604    fb_delay = 0;
605    fb_delay_found = 0;
606    lock_clkfb = 0;
607    lock_clkin = 0;
608    lock_delay = 0;
609    lock_fb = 0;
610    lock_fb_dly = 0;
611    lock_out = 2'b00;
612    lock_out1_neg = 0;
613    lock_period = 0;
614    lock_ps = 0;
615    lock_ps_dly = 0;
616    locked_out = 0;
617    period = 0;
618    period_int = 0;
619    period_int2 = 0;
620    period_int3 = 0;
621    period_div = 0;
622    period_fx = 0;
623    period_orig = 0;
624    period_orig_int = 0;
625    period_ps = 0;
626    psdone_out = 0;
627    ps_delay = 0;
628    ps_delay_md = 0;
629    ps_delay_init = 0;
630    ps_acc = 0;
631    ps_delay_all = 0;
632    ps_lock = 0;
633    ps_overflow_out = 0;
634    ps_overflow_out_ext = 0;
635    clkin_lost_out_ext = 0;
636    clkfx_lost_out_ext = 0;
637    rst_reg = 3'b000;
638    first_time_locked = 0;
639    en_status = 0;
640    clkfb_div = 0;
641    clkin_chkin = 0;
642    clkfb_chkin = 0;
643    clkin_ps_mkup = 0;
644    clkin_ps_mkup_win = 0;
645    clkin_ps_mkup_flag = 0;
646    ps_delay_last = 0;
647    clkin_ps_tmp = 0;
648end
649
650// RST less than 3 cycles, lock = x
651
652  assign locked_out_out = (rst_flag) ? 1'bx : locked_out;
653
654//
655// detect_first_time_locked
656//
657always @(posedge locked_out)
658  if (first_time_locked == 0)
659          first_time_locked <= 1;
660
661//
662// phase shift parameters
663//
664
665always @(posedge lock_period)
666    ps_delay_init <= ps_in * period_orig /256;
667
668
669always @(period) begin
670    period_int = period;
671    if (clkin_type==1)
672       period_ps_tmp = 2 * period;
673    else
674       period_ps_tmp = period;
675
676   if (period_ps_tmp > 3000)
677        ps_max_range = 20 * (period_ps_tmp - 3000)/1000;
678   else
679     ps_max_range = 0;
680end
681
682always @(ps_delay or rst_in or period_int or lock_period)
683  if ( rst_in)
684       ps_delay_md = 0;
685  else if (lock_period) begin
686       ps_delay_md = period_int + ps_delay % period_int;
687  end
688
689always @(posedge psclk_in or posedge rst_in or posedge lock_period_pulse)
690  if (rst_in) begin
691     ps_delay <= 0;
692     ps_overflow_out <= 0;
693     ps_acc <= 0;
694  end
695  else if (lock_period_pulse)
696     ps_delay <= ps_delay_init;
697  else
698    if (ps_type == 2'b10)
699    if (psen_in) begin
700        if (ps_lock == 1)
701          $display(" Warning : Please wait for PSDONE signal before adjusting the Phase Shift.");
702        else if (lock_ps) begin
703          if (psincdec_in == 1) begin
704        if (ps_acc > ps_max_range)
705            ps_overflow_out <= 1;
706        else begin
707            ps_delay <= ps_delay + PS_STEP;
708                    ps_acc <= ps_acc + 1;
709            ps_overflow_out <= 0;
710        end
711        ps_lock <= 1;
712          end
713          else if (psincdec_in == 0) begin
714        if (ps_acc < -ps_max_range)
715              ps_overflow_out <= 1;
716        else begin
717            ps_delay <= ps_delay - PS_STEP;
718                    ps_acc <= ps_acc - 1;
719            ps_overflow_out <= 0;
720        end
721        ps_lock <= 1;
722          end
723           end
724     end
725
726always @(posedge ps_lock) begin
727    @(posedge clkin_ps)
728    @(posedge psclk_in)
729    @(posedge psclk_in)
730    @(posedge psclk_in)
731    psdone_out <= 1;
732    @(posedge psclk_in)
733    psdone_out <= 0;
734    ps_lock <= 0;
735end
736
737//
738// determine clock period
739//
740
741always @(posedge clkin_div or negedge clkin_div or posedge rst_in)
742  if (rst_in == 1) begin
743    clkin_period[0] <= 0;
744    clkin_period[1] <= 0;
745    clkin_period[2] <= 0;
746    clkin_edge <= 0;
747  end
748  else
749  if (clkin_div == 1) begin
750    clkin_edge <= $time;
751    clkin_period[2] <= clkin_period[1];
752    clkin_period[1] <= clkin_period[0];
753    if (clkin_edge != 0)
754    clkin_period[0] <= $time - clkin_edge;
755  end
756  else if (clkin_div == 0)
757      if (lock_period == 1)
758        if (100000000 < clkin_period[0]/1000)
759        begin
760        end
761        else if ((period_orig * 2 < clkin_period[0]) && (clock_stopped == 0)) begin
762          clkin_period[0] <= clkin_period[1];
763        end
764
765always @(negedge clkin_div or posedge rst_in)
766  if (rst_in == 1) begin
767      lock_period <= 0;
768      clock_stopped <= 1;
769  end
770  else begin
771    if (lock_period == 1'b0) begin
772    if ((clkin_period[0] != 0) &&
773        (clkin_period[0] - cycle_jitter <= clkin_period[1]) &&
774        (clkin_period[1] <= clkin_period[0] + cycle_jitter) &&
775        (clkin_period[1] - cycle_jitter <= clkin_period[2]) &&
776        (clkin_period[2] <= clkin_period[1] + cycle_jitter)) begin
777        lock_period <= 1;
778        period_orig <= (clkin_period[0] +
779                clkin_period[1] +
780                clkin_period[2]) / 3;
781        period <= clkin_period[0];
782    end
783    end
784    else if (lock_period == 1'b1) begin
785    if (100000000 < (clkin_period[0] / 1000)) begin
786        $display(" Warning : CLKIN stopped toggling on instance %m exceeds %d ms. Current CLKIN Period = %1.3f ns.", 100, clkin_period[0] / 1000.0);
787        lock_period <= 0;
788        @(negedge rst_reg[2]);
789    end
790    else if ((period_orig * 2 < clkin_period[0]) && clock_stopped == 1'b0) begin
791        clock_stopped <= 1'b1;
792    end
793    else if ((clkin_period[0] < period_orig - period_jitter) ||
794        (period_orig + period_jitter < clkin_period[0])) begin
795        $display(" Warning : Input Clock Period Jitter on instance %m exceeds %1.3f ns. Locked CLKIN Period = %1.3f. Current CLKIN Period = %1.3f.", period_jitter / 1000.0, period_orig / 1000.0, clkin_period[0] / 1000.0);
796        lock_period <= 0;
797        @(negedge rst_reg[2]);
798    end
799    else if ((clkin_period[0] < clkin_period[1] - cycle_jitter) ||
800        (clkin_period[1] + cycle_jitter < clkin_period[0])) begin
801        $display(" Warning : Input Clock Cycle-Cycle Jitter on instance %m exceeds %1.3f ns. Previous CLKIN Period = %1.3f. Current CLKIN Period = %1.3f.", cycle_jitter / 1000.0, clkin_period[1] / 1000.0, clkin_period[0] / 1000.0);
802        lock_period <= 0;
803        @(negedge rst_reg[2]);
804    end
805    else begin
806        period <= clkin_period[0];
807        clock_stopped <= 1'b0;
808    end
809    end
810end
811
812  assign #1 lock_period_dly1 = lock_period;
813  assign #(period/2) lock_period_dly = lock_period_dly1;
814  assign lock_period_pulse = (lock_period_dly1==1 && lock_period_dly==0) ? 1 : 0;
815
816//
817// determine clock delay
818//
819
820//always @(posedge lock_period or posedge rst_in)
821always @(posedge lock_ps_dly or posedge rst_in)
822  if (rst_in) begin
823    fb_delay <= 0;
824    fb_delay_found <= 0;
825  end
826  else begin
827    if (lock_period && clkfb_type != 2'b00) begin
828    if (clkfb_type == 2'b01) begin
829        @(posedge CLK0 or rst_in)
830        delay_edge = $time;
831    end
832    else if (clkfb_type == 2'b10) begin
833        @(posedge CLK2X or rst_in)
834        delay_edge = $time;
835    end
836    @(posedge clkfb_in or rst_in) begin
837     fb_delay <= ($time - delay_edge) % period_orig;
838         fb_delay_found <= 1;
839       end
840    end
841  end
842
843//
844// determine feedback lock
845//
846
847always @(posedge clkfb_chk or posedge rst_in)
848  if (rst_in)
849      clkfb_window <= 0;
850  else begin
851      clkfb_window <= 1;
852    #cycle_jitter clkfb_window <= 0;
853  end
854
855always @(posedge clkin_fb or posedge rst_in)
856  if (rst_in)
857      clkin_window <= 0;
858  else begin
859      clkin_window <= 1;
860    #cycle_jitter clkin_window <= 0;
861  end
862
863always @(posedge clkin_fb or posedge rst_in)
864  if (rst_in)
865     lock_clkin <= 0;
866  else begin
867    #1
868    if ((clkfb_window && fb_delay_found) || (clkin_lost_out == 1'b1 && lock_out[0]==1'b1))
869    lock_clkin <= 1;
870    else
871       if (chk_enable==1)
872     lock_clkin <= 0;
873  end
874
875always @(posedge clkfb_chk or posedge rst_in)
876  if (rst_in)
877    lock_clkfb <= 0;
878  else begin
879    #1
880    if ((clkin_window && fb_delay_found) || (clkin_lost_out == 1'b1 && lock_out[0]==1'b1))
881    lock_clkfb <= 1;
882    else
883       if (chk_enable ==1)
884    lock_clkfb <= 0;
885  end
886
887always @(negedge clkin_fb or posedge rst_in)
888  if (rst_in)
889    lock_delay <= 0;
890  else
891    lock_delay <= lock_clkin || lock_clkfb;
892
893//
894// generate lock signal
895//
896
897always @(posedge clkin_ps or posedge rst_in)
898  if (rst_in) begin
899      lock_out <= 2'b0;
900      locked_out <=0;
901  end
902  else begin
903    if (clkfb_type == 2'b00)
904    lock_out[0] <= lock_period;
905    else
906    lock_out[0] <= lock_period & lock_delay & lock_fb;
907    lock_out[1] <= lock_out[0];
908    locked_out <= lock_out[1];
909  end
910
911always @(negedge clkin_ps or posedge rst_in)
912  if (rst_in)
913    lock_out1_neg <= 0;
914  else
915    lock_out1_neg <= lock_out[1];
916
917
918//
919// generate the clk1x_out
920//
921
922always @(posedge clkin_ps or negedge clkin_ps or posedge rst_in)
923  if (rst_in)
924      clk0_out <= 0;
925  else
926    if (clkin_ps ==1)
927       if (clk1x_type==1 && lock_out[0]) begin
928          clk0_out <= 1;
929          #(period / 2)
930             clk0_out <= 0;
931       end
932       else
933          clk0_out <= 1;
934    else
935      if (clkin_ps == 0 && ((clk1x_type && lock_out[0]) == 0 || (lock_out[0]== 1 && lock_out[1]== 0)))
936          clk0_out <= 0;
937
938//
939// generate the clk2x_out
940//
941
942always @(posedge clkin_ps or posedge rst_in)
943  if (rst_in)
944     clk2x_out <= 0;
945  else begin
946    clk2x_out <= 1;
947    #(period / 4)
948    clk2x_out <= 0;
949    #(period / 4)
950    clk2x_out <= 1;
951    #(period / 4)
952    clk2x_out <= 0;
953 end
954
955//
956// generate the clkdv_out
957//
958
959always @(posedge clkin_ps or negedge clkin_ps or posedge rst_in)
960  if (rst_in) begin
961       clkdv_out <= 1'b0;
962       clkdv_cnt <= 0;
963  end
964  else
965    if (lock_out1_neg) begin
966      if (clkdv_cnt >= divide_type -1)
967           clkdv_cnt <= 0;
968      else
969           clkdv_cnt <= clkdv_cnt + 1;
970
971      if (clkdv_cnt < divide_type /2)
972          clkdv_out <= 1'b1;
973      else
974         if ( (divide_type[0] == 1'b1) && dll_mode_type == 1'b0)
975             clkdv_out <= #(period/4) 1'b0;
976         else
977            clkdv_out <= 1'b0;
978    end
979
980
981//
982// generate fx output signal
983//
984
985always @(lock_period or period or denominator or numerator) begin
986    if (lock_period == 1'b1) begin
987    period_fx = (period * denominator) / (numerator * 2);
988    remain_fx = (period * denominator) % (numerator * 2);
989    end
990end
991
992always @(posedge clkin_ps or posedge clkin_lost_out or posedge rst_in )
993    if (rst_in == 1)
994       clkfx_out = 1'b0;
995    else if (clkin_lost_out == 1'b1 ) begin
996           if (locked_out == 1)
997            @(negedge rst_reg[2]);
998        end
999    else
1000      if (lock_out[1] == 1) begin
1001    clkfx_out = 1'b1;
1002    for (p = 0; p < (numerator * 2 - 1); p = p + 1) begin
1003        #(period_fx);
1004        if (p < remain_fx)
1005        #1;
1006        clkfx_out = !clkfx_out;
1007    end
1008    if (period_fx > (period / 2)) begin
1009        #(period_fx - (period / 2));
1010    end
1011      end
1012
1013//
1014// generate all output signal
1015//
1016
1017always @(rst_in)
1018if (rst_in) begin
1019   assign CLK0 = 0;
1020   assign CLK90 = 0;
1021   assign CLK180 = 0;
1022   assign CLK270 = 0;
1023   assign CLK2X = 0;
1024   assign CLK2X180 =0;
1025   assign CLKDV = 0;
1026   assign CLKFX = 0;
1027   assign CLKFX180 = 0;
1028end
1029else begin
1030   deassign CLK0;
1031   deassign CLK90;
1032   deassign CLK180;
1033   deassign CLK270;
1034   deassign CLK2X;
1035   deassign CLK2X180;
1036   deassign CLKDV;
1037   deassign CLKFX;
1038   deassign CLKFX180;
1039end
1040
1041always @(clk0_out) begin
1042    CLK0 <= #(clkout_delay) clk0_out && (clkfb_type != 2'b00);
1043    CLK90 <= #(clkout_delay + period / 4) clk0_out && !dll_mode_type && (clkfb_type != 2'b00);
1044    CLK180 <= #(clkout_delay) ~clk0_out && (clkfb_type != 2'b00);
1045    CLK270 <= #(clkout_delay + period / 4) ~clk0_out && !dll_mode_type && (clkfb_type != 2'b00);
1046  end
1047
1048always @(clk2x_out) begin
1049    CLK2X <= #(clkout_delay) clk2x_out && !dll_mode_type && (clkfb_type != 2'b00);
1050     CLK2X180 <= #(clkout_delay) ~clk2x_out && !dll_mode_type && (clkfb_type != 2'b00);
1051end
1052
1053always @(clkdv_out)
1054    CLKDV <= #(clkout_delay) clkdv_out && (clkfb_type != 2'b00);
1055
1056always @(clkfx_out )
1057    CLKFX <= #(clkout_delay) clkfx_out;
1058
1059always @( clkfx_out or first_time_locked or locked_out)
1060  if ( ~first_time_locked)
1061     CLKFX180 = 0;
1062  else
1063     CLKFX180 <= #(clkout_delay) ~clkfx_out;
1064
1065
1066endmodule
1067
1068//////////////////////////////////////////////////////
1069
1070module dcm_sp_clock_divide_by_2 (clock, clock_type, clock_out, rst);
1071input clock;
1072input clock_type;
1073input rst;
1074output clock_out;
1075
1076reg clock_out;
1077reg clock_div2;
1078reg [2:0] rst_reg;
1079wire clk_src;
1080
1081initial begin
1082    clock_out = 1'b0;
1083    clock_div2 = 1'b0;
1084end
1085
1086always @(posedge clock)
1087    clock_div2 <= ~clock_div2;
1088
1089always @(posedge clock) begin
1090    rst_reg[0] <= rst;
1091    rst_reg[1] <= rst_reg[0] & rst;
1092    rst_reg[2] <= rst_reg[1] & rst_reg[0] & rst;
1093end
1094
1095assign clk_src = (clock_type) ? clock_div2 : clock;
1096
1097always @(clk_src or rst or rst_reg)
1098    if (rst == 1'b0)
1099        clock_out = clk_src;
1100    else if (rst == 1'b1) begin
1101        clock_out = 1'b0;
1102        @(negedge rst_reg[2]);
1103        if (clk_src == 1'b1)
1104          @(negedge clk_src);
1105    end
1106
1107
1108endmodule
1109
1110module dcm_sp_maximum_period_check (clock, rst);
1111parameter clock_name = "";
1112parameter maximum_period = 0;
1113input clock;
1114input rst;
1115
1116time clock_edge;
1117time clock_period;
1118
1119initial begin
1120    clock_edge = 0;
1121    clock_period = 0;
1122end
1123
1124always @(posedge clock) begin
1125    clock_edge <= $time;
1126// clock_period <= $time - clock_edge;
1127    clock_period = $time - clock_edge;
1128    if (clock_period > maximum_period ) begin
1129        if (rst == 0)
1130    $display(" Warning : Input clock period of %1.3f ns, on the %s port of instance %m exceeds allowed value of %1.3f ns at time %1.3f ns.", clock_period/1000.0, clock_name, maximum_period/1000.0, $time/1000.0);
1131    end
1132end
1133endmodule
1134
1135module dcm_sp_clock_lost (clock, enable, lost, rst);
1136input clock;
1137input enable;
1138input rst;
1139output lost;
1140
1141time clock_edge;
1142reg [63:0] period;
1143reg clock_low, clock_high;
1144reg clock_posedge, clock_negedge;
1145reg lost_r, lost_f, lost;
1146reg clock_second_pos, clock_second_neg;
1147
1148initial begin
1149    clock_edge = 0;
1150    clock_high = 0;
1151    clock_low = 0;
1152    lost_r = 0;
1153    lost_f = 0;
1154    period = 0;
1155    clock_posedge = 0;
1156    clock_negedge = 0;
1157    clock_second_pos = 0;
1158    clock_second_neg = 0;
1159end
1160
1161always @(posedge clock or posedge rst)
1162  if (rst==1)
1163    period <= 0;
1164  else begin
1165    clock_edge <= $time;
1166    if (period != 0 && (($time - clock_edge) <= (1.5 * period)))
1167        period <= $time - clock_edge;
1168    else if (period != 0 && (($time - clock_edge) > (1.5 * period)))
1169        period <= 0;
1170    else if ((period == 0) && (clock_edge != 0) && clock_second_pos == 1)
1171        period <= $time - clock_edge;
1172  end
1173
1174
1175always @(posedge clock or posedge rst)
1176  if (rst)
1177    lost_r <= 0;
1178  else
1179  if (enable == 1 && clock_second_pos == 1) begin
1180      #1;
1181      if ( period != 0)
1182         lost_r <= 0;
1183      #((period * 9.1) / 10)
1184      if ((clock_low != 1'b1) && (clock_posedge != 1'b1) && rst == 0)
1185        lost_r <= 1;
1186    end
1187
1188always @(posedge clock or negedge clock or posedge rst)
1189  if (rst) begin
1190     clock_second_pos <= 0;
1191     clock_second_neg <= 0;
1192  end
1193  else if (clock)
1194     clock_second_pos <= 1;
1195  else if (~clock)
1196     clock_second_neg <= 1;
1197
1198always @(negedge clock or posedge rst)
1199  if (rst==1) begin
1200     lost_f <= 0;
1201   end
1202   else begin
1203     if (enable == 1 && clock_second_neg == 1) begin
1204      if ( period != 0)
1205        lost_f <= 0;
1206      #((period * 9.1) / 10)
1207      if ((clock_high != 1'b1) && (clock_negedge != 1'b1) && rst == 0)
1208        lost_f <= 1;
1209    end
1210  end
1211
1212always @( lost_r or lost_f or enable)
1213begin
1214  if (enable == 1)
1215         lost = lost_r | lost_f;
1216  else
1217        lost = 0;
1218end
1219
1220
1221always @(posedge clock or negedge clock or posedge rst)
1222  if (rst==1) begin
1223           clock_low <= 1'b0;
1224           clock_high <= 1'b0;
1225           clock_posedge <= 1'b0;
1226           clock_negedge <= 1'b0;
1227  end
1228  else begin
1229    if (clock ==1) begin
1230           clock_low <= 1'b0;
1231           clock_high <= 1'b1;
1232           clock_posedge <= 1'b0;
1233           clock_negedge <= 1'b1;
1234    end
1235    else if (clock == 0) begin
1236           clock_low <= 1'b1;
1237           clock_high <= 1'b0;
1238           clock_posedge <= 1'b1;
1239           clock_negedge <= 1'b0;
1240    end
1241end
1242
1243
1244endmodule
Examples/sram_gpio/logic/sim/unisims/FDDRRSE.v
1// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/FDDRRSE.v,v 1.15.48.1 2007/03/09 18:13:02 patrickp Exp $
2///////////////////////////////////////////////////////////////////////////////
3// Copyright (c) 1995/2004 Xilinx, Inc.
4// All Right Reserved.
5///////////////////////////////////////////////////////////////////////////////
6// ____ ____
7// / /\/ /
8// /___/ \ / Vendor : Xilinx
9// \ \ \/ Version : 8.1i (I.27)
10// \ \ Description : Xilinx Functional Simulation Library Component
11// / / Dual Data Rate D Flip-Flop with Synchronous Reset and Set and Clock Enable
12// /___/ /\ Filename : FDDRRSE.v
13// \ \ / \ Timestamp : Thu Mar 25 16:42:16 PST 2004
14// \___\/\___\
15//
16// Revision:
17// 03/23/04 - Initial version.
18// 02/04/05 - Rev 0.0.1 Remove input/output bufs; Seperate GSR from clock block.
19// 05/06/05 - Remove internal input data strobe and add to the output. (CR207678)
20// 10/20/05 - Add set & reset check to main block. (CR219794)
21// 10/28/05 - combine strobe block and data block. (CR220298).
22// 2/07/06 - Remove set & reset from main block and add specify block (CR225119)
23// 2/10/06 - Change Q from reg to wire (CR 225613)
24// End Revision
25
26`timescale 1 ps / 1 ps
27
28
29module FDDRRSE (Q, C0, C1, CE, D0, D1, R, S);
30
31    parameter INIT = 1'h0;
32
33    output Q;
34
35    input C0, C1, CE, D0, D1, R, S;
36
37    wire Q;
38    reg q_out;
39
40    reg q0_out, q1_out;
41    reg C0_tmp, C1_tmp;
42
43    initial begin
44       q_out = INIT;
45       q0_out = INIT;
46       q1_out = INIT;
47       C0_tmp = 0;
48       C1_tmp = 0;
49    end
50
51    assign Q = q_out;
52
53    always @(posedge C0)
54      if (CE == 1 || R == 1 || S == 1) begin
55      C0_tmp <= 1;
56      C0_tmp <= #100 0;
57    end
58
59    always @(posedge C1)
60     if (CE == 1 || R == 1 || S == 1) begin
61      C1_tmp <= 1;
62      C1_tmp <= #100 0;
63    end
64
65        always @(posedge C0)
66            if (R)
67                q0_out <= 0;
68            else if (S)
69                q0_out <= 1;
70            else if (CE)
71                q0_out <= D0;
72
73        always @(posedge C1)
74            if (R)
75                q1_out <= 0;
76            else if (S)
77                q1_out <= 1;
78            else if (CE)
79                q1_out <= D1;
80
81       always @(posedge C0_tmp or posedge C1_tmp )
82            if (C1_tmp)
83               q_out = q1_out;
84            else
85               q_out = q0_out;
86
87    specify
88        if (R)
89            (posedge C0 => (Q +: 1'b0)) = (100, 100);
90        if (!R && S)
91            (posedge C0 => (Q +: 1'b1)) = (100, 100);
92        if (!R && !S && CE)
93            (posedge C0 => (Q +: D0)) = (100, 100);
94        if (R)
95            (posedge C1 => (Q +: 1'b0)) = (100, 100);
96        if (!R && S)
97            (posedge C1 => (Q +: 1'b1)) = (100, 100);
98        if (!R && !S && CE)
99            (posedge C1 => (Q +: D1)) = (100, 100);
100    endspecify
101
102endmodule
Examples/sram_gpio/logic/sim/unisims/RAMB16_S2.v
1// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/RAMB16_S2.v,v 1.7.158.1 2007/03/09 18:13:18 patrickp Exp $
2///////////////////////////////////////////////////////////////////////////////
3// Copyright (c) 1995/2005 Xilinx, Inc.
4// All Right Reserved.
5///////////////////////////////////////////////////////////////////////////////
6// ____ ____
7// / /\/ /
8// /___/ \ / Vendor : Xilinx
9// \ \ \/ Version : 8.1i (I.13)
10// \ \ Description : Xilinx Functional Simulation Library Component
11// / / 16K-Bit Data and 2K-Bit Parity Single Port Block RAM
12// /___/ /\ Filename : RAMB16_S2.v
13// \ \ / \ Timestamp : Thu Mar 10 16:43:35 PST 2005
14// \___\/\___\
15//
16// Revision:
17// 03/23/04 - Initial version.
18// End Revision
19
20`ifdef legacy_model
21
22`timescale 1 ps / 1 ps
23
24module RAMB16_S2 (DO, ADDR, CLK, DI, EN, SSR, WE);
25
26    parameter INIT = 2'h0;
27    parameter SRVAL = 2'h0;
28    parameter WRITE_MODE = "WRITE_FIRST";
29
30    parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
31    parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
32    parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
33    parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
34    parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
35    parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
36    parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
37    parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
38    parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
39    parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
40    parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
41    parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
42    parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
43    parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
44    parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
45    parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
46    parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
47    parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
48    parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
49    parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
50    parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
51    parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
52    parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
53    parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
54    parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
55    parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
56    parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
57    parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
58    parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
59    parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
60    parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
61    parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
62    parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
63    parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
64    parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
65    parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
66    parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
67    parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
68    parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
69    parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
70    parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
71    parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
72    parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
73    parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
74    parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
75    parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
76    parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
77    parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
78    parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
79    parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
80    parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
81    parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
82    parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
83    parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
84    parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
85    parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
86    parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
87    parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
88    parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
89    parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
90    parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
91    parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
92    parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
93    parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
94
95    output [1:0] DO;
96    reg do0_out, do1_out;
97
98    input [12:0] ADDR;
99    input [1:0] DI;
100    input EN, CLK, WE, SSR;
101
102    reg [18431:0] mem;
103    reg [8:0] count;
104    reg [1:0] wr_mode;
105
106    wire [12:0] addr_int;
107    wire [1:0] di_int;
108    wire en_int, clk_int, we_int, ssr_int;
109
110    tri0 GSR = glbl.GSR;
111
112    always @(GSR)
113    if (GSR) begin
114        assign do0_out = INIT[0];
115        assign do1_out = INIT[1];
116    end
117    else begin
118        deassign do0_out;
119        deassign do1_out;
120    end
121
122    buf b_do_out0 (DO[0], do0_out);
123    buf b_do_out1 (DO[1], do1_out);
124    buf b_addr_0 (addr_int[0], ADDR[0]);
125    buf b_addr_1 (addr_int[1], ADDR[1]);
126    buf b_addr_2 (addr_int[2], ADDR[2]);
127    buf b_addr_3 (addr_int[3], ADDR[3]);
128    buf b_addr_4 (addr_int[4], ADDR[4]);
129    buf b_addr_5 (addr_int[5], ADDR[5]);
130    buf b_addr_6 (addr_int[6], ADDR[6]);
131    buf b_addr_7 (addr_int[7], ADDR[7]);
132    buf b_addr_8 (addr_int[8], ADDR[8]);
133    buf b_addr_9 (addr_int[9], ADDR[9]);
134    buf b_addr_10 (addr_int[10], ADDR[10]);
135    buf b_addr_11 (addr_int[11], ADDR[11]);
136    buf b_addr_12 (addr_int[12], ADDR[12]);
137    buf b_di_0 (di_int[0], DI[0]);
138    buf b_di_1 (di_int[1], DI[1]);
139    buf b_en (en_int, EN);
140    buf b_clk (clk_int, CLK);
141    buf b_we (we_int, WE);
142    buf b_ssr (ssr_int, SSR);
143
144    initial begin
145    for (count = 0; count < 256; count = count + 1) begin
146        mem[count] <= INIT_00[count];
147        mem[256 * 1 + count] <= INIT_01[count];
148        mem[256 * 2 + count] <= INIT_02[count];
149        mem[256 * 3 + count] <= INIT_03[count];
150        mem[256 * 4 + count] <= INIT_04[count];
151        mem[256 * 5 + count] <= INIT_05[count];
152        mem[256 * 6 + count] <= INIT_06[count];
153        mem[256 * 7 + count] <= INIT_07[count];
154        mem[256 * 8 + count] <= INIT_08[count];
155        mem[256 * 9 + count] <= INIT_09[count];
156        mem[256 * 10 + count] <= INIT_0A[count];
157        mem[256 * 11 + count] <= INIT_0B[count];
158        mem[256 * 12 + count] <= INIT_0C[count];
159        mem[256 * 13 + count] <= INIT_0D[count];
160        mem[256 * 14 + count] <= INIT_0E[count];
161        mem[256 * 15 + count] <= INIT_0F[count];
162        mem[256 * 16 + count] <= INIT_10[count];
163        mem[256 * 17 + count] <= INIT_11[count];
164        mem[256 * 18 + count] <= INIT_12[count];
165        mem[256 * 19 + count] <= INIT_13[count];
166        mem[256 * 20 + count] <= INIT_14[count];
167        mem[256 * 21 + count] <= INIT_15[count];
168        mem[256 * 22 + count] <= INIT_16[count];
169        mem[256 * 23 + count] <= INIT_17[count];
170        mem[256 * 24 + count] <= INIT_18[count];
171        mem[256 * 25 + count] <= INIT_19[count];
172        mem[256 * 26 + count] <= INIT_1A[count];
173        mem[256 * 27 + count] <= INIT_1B[count];
174        mem[256 * 28 + count] <= INIT_1C[count];
175        mem[256 * 29 + count] <= INIT_1D[count];
176        mem[256 * 30 + count] <= INIT_1E[count];
177        mem[256 * 31 + count] <= INIT_1F[count];
178        mem[256 * 32 + count] <= INIT_20[count];
179        mem[256 * 33 + count] <= INIT_21[count];
180        mem[256 * 34 + count] <= INIT_22[count];
181        mem[256 * 35 + count] <= INIT_23[count];
182        mem[256 * 36 + count] <= INIT_24[count];
183        mem[256 * 37 + count] <= INIT_25[count];
184        mem[256 * 38 + count] <= INIT_26[count];
185        mem[256 * 39 + count] <= INIT_27[count];
186        mem[256 * 40 + count] <= INIT_28[count];
187        mem[256 * 41 + count] <= INIT_29[count];
188        mem[256 * 42 + count] <= INIT_2A[count];
189        mem[256 * 43 + count] <= INIT_2B[count];
190        mem[256 * 44 + count] <= INIT_2C[count];
191        mem[256 * 45 + count] <= INIT_2D[count];
192        mem[256 * 46 + count] <= INIT_2E[count];
193        mem[256 * 47 + count] <= INIT_2F[count];
194        mem[256 * 48 + count] <= INIT_30[count];
195        mem[256 * 49 + count] <= INIT_31[count];
196        mem[256 * 50 + count] <= INIT_32[count];
197        mem[256 * 51 + count] <= INIT_33[count];
198        mem[256 * 52 + count] <= INIT_34[count];
199        mem[256 * 53 + count] <= INIT_35[count];
200        mem[256 * 54 + count] <= INIT_36[count];
201        mem[256 * 55 + count] <= INIT_37[count];
202        mem[256 * 56 + count] <= INIT_38[count];
203        mem[256 * 57 + count] <= INIT_39[count];
204        mem[256 * 58 + count] <= INIT_3A[count];
205        mem[256 * 59 + count] <= INIT_3B[count];
206        mem[256 * 60 + count] <= INIT_3C[count];
207        mem[256 * 61 + count] <= INIT_3D[count];
208        mem[256 * 62 + count] <= INIT_3E[count];
209        mem[256 * 63 + count] <= INIT_3F[count];
210    end
211    end
212
213    initial begin
214    case (WRITE_MODE)
215        "WRITE_FIRST" : wr_mode <= 2'b00;
216        "READ_FIRST" : wr_mode <= 2'b01;
217        "NO_CHANGE" : wr_mode <= 2'b10;
218        default : begin
219                $display("Attribute Syntax Error : The attribute WRITE_MODE on RAMB16_S2 instance %m is set to %s. Legal values for this attribute are WRITE_FIRST, READ_FIRST or NO_CHANGE.", WRITE_MODE);
220                $finish;
221                end
222    endcase
223    end
224
225    always @(posedge clk_int) begin
226    if (en_int == 1'b1) begin
227        if (ssr_int == 1'b1) begin
228        do0_out <= SRVAL[0];
229        do1_out <= SRVAL[1];
230        end
231        else begin
232        if (we_int == 1'b1) begin
233            if (wr_mode == 2'b00) begin
234            do0_out <= di_int[0];
235            do1_out <= di_int[1];
236            end
237            else if (wr_mode == 2'b01) begin
238            do0_out <= mem[addr_int * 2 + 0];
239            do1_out <= mem[addr_int * 2 + 1];
240            end
241            else begin
242            do0_out <= do0_out;
243            do1_out <= do1_out;
244            end
245        end
246        else begin
247            do0_out <= mem[addr_int * 2 + 0];
248            do1_out <= mem[addr_int * 2 + 1];
249        end
250        end
251    end
252    end
253
254    always @(posedge clk_int) begin
255    if (en_int == 1'b1 && we_int == 1'b1) begin
256        mem[addr_int * 2 + 0] <= di_int[0];
257        mem[addr_int * 2 + 1] <= di_int[1];
258    end
259    end
260
261    specify
262    (CLK *> DO) = (100, 100);
263    endspecify
264
265endmodule
266
267`else
268
269// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/RAMB16_S2.v,v 1.7.158.1 2007/03/09 18:13:18 patrickp Exp $
270///////////////////////////////////////////////////////////////////////////////
271// Copyright (c) 1995/2005 Xilinx, Inc.
272// All Right Reserved.
273///////////////////////////////////////////////////////////////////////////////
274// ____ ____
275// / /\/ /
276// /___/ \ / Vendor : Xilinx
277// \ \ \/ Version : 8.1i (I.13)
278// \ \ Description : Xilinx Timing Simulation Library Component
279// / / 16K-Bit Data and 2K-Bit Parity Single Port Block RAM
280// /___/ /\ Filename : RAMB16_S2.v
281// \ \ / \ Timestamp : Thu Mar 10 16:44:01 PST 2005
282// \___\/\___\
283//
284// Revision:
285// 03/23/04 - Initial version.
286// 03/10/05 - Initialized outputs.
287// End Revision
288
289`timescale 1 ps/1 ps
290
291module RAMB16_S2 (DO, ADDR, CLK, DI, EN, SSR, WE);
292
293    parameter INIT = 2'h0;
294    parameter SRVAL = 2'h0;
295    parameter WRITE_MODE = "WRITE_FIRST";
296
297    parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
298    parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
299    parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
300    parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
301    parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
302    parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
303    parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
304    parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
305    parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
306    parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
307    parameter INIT_0A = 256'h000000000000000000000000000000000