Prepare for new DDR PHY
[litex.git] / verilog / m1crg / m1crg.v
1 /*
2 * Milkymist-NG SoC
3 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 Sebastien Bourdeauducq
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 module m1crg #(
19 parameter in_period = 0.0,
20 parameter f_mult = 0,
21 parameter f_div = 0,
22 parameter clk2x_period = (in_period*f_div)/(2.0*f_mult)
23 ) (
24 input clkin,
25 input trigger_reset,
26
27 output sys_clk,
28 output reg sys_rst,
29
30 /* Reset off-chip devices */
31 output ac97_rst_n,
32 output videoin_rst_n,
33 output flash_rst_n,
34
35 /* DDR PHY clocks */
36 output clk2x_90,
37 output clk4x_wr,
38 output clk4x_wr_strb,
39 output clk4x_rd,
40 output clk4x_rd_strb
41 );
42
43 /*
44 * Reset
45 */
46
47 reg [19:0] rst_debounce;
48 always @(posedge sys_clk) begin
49 if(trigger_reset)
50 rst_debounce <= 20'hFFFFF;
51 else if(rst_debounce != 20'd0)
52 rst_debounce <= rst_debounce - 20'd1;
53 sys_rst <= rst_debounce != 20'd0;
54 end
55
56 assign ac97_rst_n = ~sys_rst;
57 assign videoin_rst_n = ~sys_rst;
58
59 /*
60 * We must release the Flash reset before the system reset
61 * because the Flash needs some time to come out of reset
62 * and the CPU begins fetching instructions from it
63 * as soon as the system reset is released.
64 * From datasheet, minimum reset pulse width is 100ns
65 * and reset-to-read time is 150ns.
66 */
67
68 reg [7:0] flash_rstcounter;
69
70 always @(posedge sys_clk) begin
71 if(trigger_reset)
72 flash_rstcounter <= 8'd0;
73 else if(~flash_rstcounter[7])
74 flash_rstcounter <= flash_rstcounter + 8'd1;
75 end
76
77 assign flash_rst_n = flash_rstcounter[7];
78
79 /*
80 * Clock management. Inspired by the NWL reference design.
81 */
82
83 wire sdr_clkin;
84 wire clkdiv;
85
86 IBUF #(
87 .IOSTANDARD("DEFAULT")
88 ) clk2_iob (
89 .I(clkin),
90 .O(sdr_clkin)
91 );
92
93 BUFIO2 #(
94 .DIVIDE(1),
95 .DIVIDE_BYPASS("FALSE"),
96 .I_INVERT("FALSE")
97 ) bufio2_inst2 (
98 .I(sdr_clkin),
99 .IOCLK(),
100 .DIVCLK(clkdiv),
101 .SERDESSTROBE()
102 );
103
104 wire pll_lckd;
105 wire buf_pll_fb_out;
106 wire pllout0;
107 wire pllout1;
108 wire pllout2;
109 wire pllout3;
110
111 PLL_ADV #(
112 .BANDWIDTH("OPTIMIZED"),
113 .CLKFBOUT_MULT(4*f_mult),
114 .CLKFBOUT_PHASE(0.0),
115 .CLKIN1_PERIOD(in_period),
116 .CLKIN2_PERIOD(in_period),
117 .CLKOUT0_DIVIDE(f_div),
118 .CLKOUT0_DUTY_CYCLE(0.5),
119 .CLKOUT0_PHASE(0),
120 .CLKOUT1_DIVIDE(f_div),
121 .CLKOUT1_DUTY_CYCLE(0.5),
122 .CLKOUT1_PHASE(0),
123 .CLKOUT2_DIVIDE(2*f_div),
124 .CLKOUT2_DUTY_CYCLE(0.5),
125 .CLKOUT2_PHASE(90.0),
126 .CLKOUT3_DIVIDE(4*f_div),
127 .CLKOUT3_DUTY_CYCLE(0.5),
128 .CLKOUT3_PHASE(0.0),
129 .CLKOUT4_DIVIDE(7),
130 .CLKOUT4_DUTY_CYCLE(0.5),
131 .CLKOUT4_PHASE(0),
132 .CLKOUT5_DIVIDE(7),
133 .CLKOUT5_DUTY_CYCLE(0.5),
134 .CLKOUT5_PHASE(0.0),
135 .COMPENSATION("INTERNAL"),
136 .DIVCLK_DIVIDE(1),
137 .REF_JITTER(0.100),
138 .CLK_FEEDBACK("CLKFBOUT"),
139 .SIM_DEVICE("SPARTAN6")
140 ) pll (
141 .CLKFBDCM(),
142 .CLKFBOUT(buf_pll_fb_out),
143 .CLKOUT0(pllout0), /* < x4 clock for writes */
144 .CLKOUT1(pllout1), /* < x4 clock for reads */
145 .CLKOUT2(pllout2), /* < x2 90 clock to generate memory clock, clock DQS and memory address and control signals. */
146 .CLKOUT3(pllout3), /* < x1 clock for system and memory controller */
147 .CLKOUT4(),
148 .CLKOUT5(),
149 .CLKOUTDCM0(),
150 .CLKOUTDCM1(),
151 .CLKOUTDCM2(),
152 .CLKOUTDCM3(),
153 .CLKOUTDCM4(),
154 .CLKOUTDCM5(),
155 .DO(),
156 .DRDY(),
157 .LOCKED(pll_lckd),
158 .CLKFBIN(buf_pll_fb_out),
159 .CLKIN1(clkdiv),
160 .CLKIN2(1'b0),
161 .CLKINSEL(1'b1),
162 .DADDR(5'b00000),
163 .DCLK(1'b0),
164 .DEN(1'b0),
165 .DI(16'h0000),
166 .DWE(1'b0),
167 .RST(1'b0),
168 .REL(1'b0)
169 );
170
171 BUFPLL #(
172 .DIVIDE(4)
173 ) wr_bufpll (
174 .PLLIN(pllout0),
175 .GCLK(sys_clk),
176 .LOCKED(pll_lckd),
177 .IOCLK(clk4x_wr),
178 .LOCK(),
179 .SERDESSTROBE(clk4x_wr_strb)
180 );
181
182 BUFPLL #(
183 .DIVIDE(4)
184 ) rd_bufpll (
185 .PLLIN(pllout1),
186 .GCLK(sys_clk),
187 .LOCKED(pll_lckd),
188 .IOCLK(clk4x_rd),
189 .LOCK(),
190 .SERDESSTROBE(clk4x_rd_strb)
191 );
192
193 BUFG bufg_x2_2(
194 .I(pllout2),
195 .O(clk2x_90)
196 );
197
198 BUFG bufg_x1(
199 .I(pllout3),
200 .O(sys_clk)
201 );
202
203 endmodule