forked from open-ephys/rhythm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
memc3_infrastructure.v
executable file
·222 lines (195 loc) · 7.44 KB
/
memc3_infrastructure.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
`timescale 1ns/1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: Intan Technologies, LLC
//
// Design Name: RHD2000 Rhythm Interface
// Module Name: memc3_infrastructure
// Project Name: Opal Kelly FPGA/USB RHD2000 Interface
// Target Devices:
// Tool versions:
// Description: SDRAM memory controller module
// Adapted from Opal Kelly's RAMTester example
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module memc3_infrastructure #
(
parameter C_MEMCLK_PERIOD = 2500,
parameter C_RST_ACT_LOW = 1,
parameter C_INPUT_CLK_TYPE = "DIFFERENTIAL"
)
(
input wire sys_clk_p,
//input wire sys_clk_n,
input wire sys_clk,
input wire sys_rst_n,
output wire clk0,
output wire rst0,
output wire async_rst,
output wire sysclk_2x,
output wire sysclk_2x_180,
output wire mcb_drp_clk,
output wire pll_ce_0,
output wire pll_ce_90,
output wire pll_lock,
output wire sys_clk_ibufg_out // Added by Intan -- buffered clk1 output
);
// # of clock cycles to delay deassertion of reset. Needs to be a fairly
// high number not so much for metastability protection, but to give time
// for reset (i.e. stable clock cycles) to propagate through all state
// machines and to all control signals (i.e. not all control signals have
// resets, instead they rely on base state logic being reset, and the effect
// of that reset propagating through the logic). Need this because we may not
// be getting stable clock cycles while reset asserted (i.e. since reset
// depends on PLL/DCM lock status)
localparam RST_SYNC_NUM = 25;
localparam CLK_PERIOD_NS = 10; //C_MEMCLK_PERIOD / 1000.0;
localparam CLK_PERIOD_INT = 10; //C_MEMCLK_PERIOD/1000;
wire clk_2x_0;
wire clk_2x_180;
wire clk0_bufg;
wire clk0_bufg_in;
wire mcb_drp_clk_bufg_in;
wire clkfbout_clkfbin;
wire locked;
reg [RST_SYNC_NUM-1:0] rst0_sync_r /* synthesis syn_maxfan = 10 */;
wire rst_tmp;
reg powerup_pll_locked;
wire sys_rst;
wire bufpll_mcb_locked;
(* KEEP = "TRUE" *) wire sys_clk_ibufg;
assign sys_clk_ibufg_out = sys_clk_ibufg;
assign sys_rst = C_RST_ACT_LOW ? ~sys_rst_n: sys_rst_n;
assign clk0 = clk0_bufg;
assign pll_lock = locked;
/*IBUFGDS # (.DIFF_TERM("TRUE"))
u_ibufg_sys_clk(
.I (sys_clk_p),
.IB (sys_clk_n),
.O (sys_clk_ibufg)
);
*/
IBUFG u_ibufg_sys_clk(
.I (sys_clk_p),
.O (sys_clk_ibufg)
);
//***************************************************************************
// Global clock generation and distribution
//***************************************************************************
PLL_ADV #
(
.BANDWIDTH ("OPTIMIZED"),
.CLKIN1_PERIOD (CLK_PERIOD_NS),
.CLKIN2_PERIOD (CLK_PERIOD_NS),
.CLKOUT0_DIVIDE (1), // 625 MHz system clock
.CLKOUT1_DIVIDE (1), // 625 MHz system clock (180 deg)
.CLKOUT2_DIVIDE (4), // 156.256 MHz test bench clock
.CLKOUT3_DIVIDE (8), // 78.125 MHz calibration clock
.CLKOUT4_DIVIDE (1),
.CLKOUT5_DIVIDE (1),
.CLKOUT0_PHASE (0.000),
.CLKOUT1_PHASE (180.000),
.CLKOUT2_PHASE (0.000),
.CLKOUT3_PHASE (0.000),
.CLKOUT4_PHASE (0.000),
.CLKOUT5_PHASE (0.000),
.CLKOUT0_DUTY_CYCLE (0.500),
.CLKOUT1_DUTY_CYCLE (0.500),
.CLKOUT2_DUTY_CYCLE (0.500),
.CLKOUT3_DUTY_CYCLE (0.500),
.CLKOUT4_DUTY_CYCLE (0.500),
.CLKOUT5_DUTY_CYCLE (0.500),
.COMPENSATION ("INTERNAL"),
.DIVCLK_DIVIDE (4),
.CLKFBOUT_MULT (25), // 25MHz x 25 = 625 MHz system clock
.CLKFBOUT_PHASE (0.0),
.REF_JITTER (0.005000)
)
u_pll_adv
(
.CLKFBIN (clkfbout_clkfbin),
.CLKINSEL (1'b1),
.CLKIN1 (sys_clk_ibufg),
.CLKIN2 (1'b0),
.DADDR (5'b0),
.DCLK (1'b0),
.DEN (1'b0),
.DI (16'b0),
.DWE (1'b0),
.REL (1'b0),
.RST (sys_rst),
.CLKFBDCM (),
.CLKFBOUT (clkfbout_clkfbin),
.CLKOUTDCM0 (),
.CLKOUTDCM1 (),
.CLKOUTDCM2 (),
.CLKOUTDCM3 (),
.CLKOUTDCM4 (),
.CLKOUTDCM5 (),
.CLKOUT0 (clk_2x_0),
.CLKOUT1 (clk_2x_180),
.CLKOUT2 (clk0_bufg_in),
.CLKOUT3 (mcb_drp_clk_bufg_in),
.CLKOUT4 (),
.CLKOUT5 (),
.DO (),
.DRDY (),
.LOCKED (locked)
);
BUFG U_BUFG_CLK0
(
.O (clk0_bufg),
.I (clk0_bufg_in)
);
BUFG U_BUFG_CLK1
(
.O (mcb_drp_clk),
.I (mcb_drp_clk_bufg_in)
);
always @(posedge clk0_bufg , posedge sys_rst)
if(sys_rst)
powerup_pll_locked <= 1'b0;
else if (bufpll_mcb_locked)
powerup_pll_locked <= 1'b1;
//***************************************************************************
// Reset synchronization
// NOTES:
// 1. shut down the whole operation if the PLL hasn't yet locked (and
// by inference, this means that external SYS_RST_IN has been asserted -
// PLL deasserts LOCKED as soon as SYS_RST_IN asserted)
// 2. asynchronously assert reset. This was we can assert reset even if
// there is no clock (needed for things like 3-stating output buffers).
// reset deassertion is synchronous.
// 3. asynchronous reset only look at pll_lock from PLL during power up. After
// power up and pll_lock is asserted, the powerup_pll_locked will be asserted
// forever until sys_rst is asserted again. PLL will lose lock when FPGA
// enters suspend mode. We don't want reset to MCB get
// asserted in the application that needs suspend feature.
//***************************************************************************
assign rst_tmp = sys_rst | ~powerup_pll_locked;
assign async_rst = rst_tmp;
// synthesis attribute max_fanout of rst0_sync_r is 10
always @(posedge clk0_bufg or posedge rst_tmp)
if (rst_tmp)
rst0_sync_r <= {RST_SYNC_NUM{1'b1}};
else
// logical left shift by one (pads with 0)
rst0_sync_r <= rst0_sync_r << 1;
assign rst0 = rst0_sync_r[RST_SYNC_NUM-1];
BUFPLL_MCB BUFPLL_MCB1
( .IOCLK0 (sysclk_2x),
.IOCLK1 (sysclk_2x_180),
.LOCKED (locked),
.GCLK (mcb_drp_clk),
.SERDESSTROBE0 (pll_ce_0),
.SERDESSTROBE1 (pll_ce_90),
.PLLIN0 (clk_2x_0),
.PLLIN1 (clk_2x_180),
.LOCK (bufpll_mcb_locked)
);
endmodule