forked from aws/aws-fpga
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaws_clk_regs.sv
299 lines (269 loc) · 11.4 KB
/
aws_clk_regs.sv
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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
///////////////////////////////////////////////////////////////////////////////////
// Amazon FPGA Hardware Development Kit
//
// Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Amazon Software License (the "License"). You may not use
// this file except in compliance with the License. A copy of the License is
// located at
//
// http://aws.amazon.com/asl/
//
// or in the "license" file accompanying this file. This file is distributed on
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or
// implied. See the License for the specific language governing permissions and
// limitations under the License.
///////////////////////////////////////////////////////////////////////////////////
// Module
// -------
// AWS_CLK_REGS
//
// Description
// -----------
// * Houses all the Control/Status Regs for AWS_CLK_GEN design
//
///////////////////////////////////////////////////////////////////////////////////
module aws_clk_regs
#(
parameter CLK_GRP_A_EN = 1,
parameter CLK_GRP_B_EN = 1,
parameter CLK_GRP_C_EN = 1,
parameter CLK_HBM_EN = 1,
parameter MAX_NUM_CLKS = 10 //Max number of clocks supported
)
(
input logic i_clk,
input logic i_rst_n,
input logic [31:0] s_axil_awaddr,
input logic s_axil_awvalid,
output logic s_axil_awready,
input logic [31:0] s_axil_wdata,
input logic [3:0] s_axil_wstrb,
input logic s_axil_wvalid,
output logic s_axil_wready,
output logic [1:0] s_axil_bresp,
output logic s_axil_bvalid,
input logic s_axil_bready,
input logic [31:0] s_axil_araddr,
input logic s_axil_arvalid,
output logic s_axil_arready,
output logic [31:0] s_axil_rdata,
output logic [1:0] s_axil_rresp,
output logic s_axil_rvalid,
input logic s_axil_rready,
input logic i_mmcm_a_lock,
input logic i_mmcm_b_lock,
input logic i_mmcm_c_lock,
input logic i_mmcm_hbm_lock,
output logic o_glbl_rst = '0,
output logic o_cl_rst_hbm_axi_n = '0,
output logic o_cl_rst_hbm_ref_n = '0,
output logic o_cl_rst_c1_n = '0,
output logic o_cl_rst_c0_n = '0,
output logic o_cl_rst_b1_n = '0,
output logic o_cl_rst_b0_n = '0,
output logic o_cl_rst_a3_n = '0,
output logic o_cl_rst_a2_n = '0,
output logic o_cl_rst_a1_n = '0,
output logic o_cl_rst_main_n = '0
);
//===================================================================
// AXI-L to CFG convert
//===================================================================
axil_bus_t s_axil_bus();
cfg_bus_t cfg_bus();
always_comb begin //{
s_axil_bus.awaddr = s_axil_awaddr;
s_axil_bus.awvalid = s_axil_awvalid;
s_axil_awready = s_axil_bus.awready;
s_axil_bus.wdata = s_axil_wdata;
s_axil_bus.wstrb = s_axil_wstrb;
s_axil_bus.wvalid = s_axil_wvalid;
s_axil_wready = s_axil_bus.wready;
s_axil_bresp = s_axil_bus.bresp;
s_axil_bvalid = s_axil_bus.bvalid;
s_axil_bus.bready = s_axil_bready;
s_axil_bus.araddr = s_axil_araddr;
s_axil_bus.arvalid = s_axil_arvalid;
s_axil_arready = s_axil_bus.arready;
s_axil_rdata = s_axil_bus.rdata;
s_axil_rresp = s_axil_bus.rresp;
s_axil_rvalid = s_axil_bus.rvalid;
s_axil_bus.rready = s_axil_rready;
end //}
// AXIL to CFG convertor
axil_to_cfg_cnv
#(
.ADDR_WIDTH (32),
.DATA_WIDTH (32)
)
AXIL_TO_CFG_CNV_I
(
.clk (i_clk ),
.rst_n (i_rst_n ),
.s_axil_bus (s_axil_bus ),
.m_cfg_bus (cfg_bus ),
.o_fsm_busy ( )
);
//===================================================================
// CFG WR/RD reqs
//===================================================================
logic [7:0] cfg_addr_q = '0;
logic cfg_wr_q = '0;
logic cfg_rd_q = '0;
logic cfg_wr_pulse_q = '0;
logic cfg_rd_pulse_q = '0;
logic [31:0] cfg_rdata_q = '0;
logic [31:0] cfg_wdata_q = '0;
always_ff @(posedge i_clk)
if (!i_rst_n) begin //{
cfg_wr_q <= '0;
cfg_rd_q <= '0;
end //}
else begin //{
cfg_wr_q <= cfg_bus.wr;
cfg_rd_q <= cfg_bus.rd;
cfg_addr_q <= cfg_bus.addr[0+:$bits(cfg_addr_q)];
cfg_wdata_q <= cfg_bus.wdata;
cfg_wr_pulse_q <= ~cfg_wr_q & cfg_bus.wr;
cfg_rd_pulse_q <= ~cfg_rd_q & cfg_bus.rd;
end //}
always_ff @(posedge i_clk)
if (!i_rst_n)
cfg_bus.ack <= '0;
else
cfg_bus.ack <= cfg_wr_pulse_q | cfg_rd_pulse_q;
assign cfg_bus.rdata = cfg_rdata_q;
//===================================================================
// CSRs
//===================================================================
localparam ID_REG = 8'h00;
localparam VER_REG = 8'h04;
localparam BUILD_REG = 8'h08;
localparam CLKS_AVAIL_REG = 8'h0C;
localparam G_RST_REG = 8'h10;
localparam SYS_RST_REG = 8'h14;
localparam DIS_RST_MAIN_REG = 8'h18;
localparam MMCM_LOCK_REG = 8'h20;
localparam MMCM_LOCK_ERR_REG = 8'h24;
logic [31:0] id_reg = '0;
logic [31:0] ver_reg = '0;
logic [31:0] build_reg = '0;
logic [31:0] clks_avail_reg = '0;
logic [31:0] g_rst_reg = '0;
logic [31:0] sys_rst_reg = 32'hFFFF_FFFE;
logic dis_rst_main_reg = '0;
logic [31:0] mmcm_lock_reg = '0;
logic [31:0] mmcm_lock_err_reg = '0;
//===================================================================
// Read Datapath
//===================================================================
always_ff @(posedge i_clk)
unique case (cfg_addr_q) //{
ID_REG : cfg_rdata_q <= id_reg;
VER_REG : cfg_rdata_q <= ver_reg;
BUILD_REG : cfg_rdata_q <= build_reg;
CLKS_AVAIL_REG : cfg_rdata_q <= clks_avail_reg;
G_RST_REG : cfg_rdata_q <= g_rst_reg;
SYS_RST_REG : cfg_rdata_q <= sys_rst_reg;
DIS_RST_MAIN_REG : cfg_rdata_q <= 32'(dis_rst_main_reg);
MMCM_LOCK_REG : cfg_rdata_q <= mmcm_lock_reg;
MMCM_LOCK_ERR_REG : cfg_rdata_q <= mmcm_lock_err_reg;
default : cfg_rdata_q <= 32'hBAAD_DEC0;
endcase // unique case (cfg_addr_q) }
always_comb begin //{
id_reg = 32'h9048_1D0F; // AWS unique ID
ver_reg = 32'h02_01_00_00; // Arch, Major, Minor, Maintenance version
build_reg = 32'h09_23_22_23;
clks_avail_reg = { 23'd0, // Reserved
1'(CLK_HBM_EN), // 1 = clk_hbm_axi available | 0 = clock unavilable
1'(CLK_GRP_C_EN), // 1 = clk_extra_c1 available | 0 = clock unavilable
1'(CLK_GRP_C_EN), // 1 = clk_extra_c0 available | 0 = clock unavilable
1'(CLK_GRP_B_EN), // 1 = clk_extra_b1 available | 0 = clock unavilable
1'(CLK_GRP_B_EN), // 1 = clk_extra_b0 available | 0 = clock unavilable
1'(CLK_GRP_A_EN), // 1 = clk_extra_a3 available | 0 = clock unavilable
1'(CLK_GRP_A_EN), // 1 = clk_extra_a2 available | 0 = clock unavilable
1'(CLK_GRP_A_EN), // 1 = clk_extra_a1 available | 0 = clock unavilable
1'b1 }; // 1 = clk_main_a0 available | 0 = clock unavilable
end //}
//===================================================================
// Writes
//===================================================================
always_ff @(posedge i_clk) begin //{
if ((cfg_addr_q == G_RST_REG) && cfg_wr_pulse_q)
g_rst_reg <= cfg_wdata_q;
if ((cfg_addr_q == SYS_RST_REG) && cfg_wr_pulse_q)
sys_rst_reg <= cfg_wdata_q;
if ((cfg_addr_q == DIS_RST_MAIN_REG) && cfg_wr_pulse_q)
dis_rst_main_reg <= cfg_wdata_q[0];
if ((cfg_addr_q == MMCM_LOCK_ERR_REG) && cfg_wr_pulse_q)
mmcm_lock_err_reg <= mmcm_lock_err_reg & ~cfg_wdata_q; // Write 1 to Clear
end //}
//===================================================================
// Reset Outputs
//===================================================================
always_ff @(posedge i_clk)
o_glbl_rst <= (g_rst_reg == '1);
logic [31:0] rst_out_n = '0;
//===================================================================
// Reset truth table
// -----------------
// o_glbl_rst | sys_rst_reg | dis_rst_main_reg | i_rst_n | Output
// ---------------------------------------------------------------
// 1 | X | X | X | 0
// 0 | 1 | X | X | 0
// 0 | 0 | 0 | 0 | 0
// 0 | 0 | 0 | 1 | 1
// 0 | 0 | 1 | X | 1
// 0 | 0 | 1 | X | 1
//===================================================================
always_ff @(posedge i_clk)
for (int gg = 0; gg < MAX_NUM_CLKS; gg++)
rst_out_n[gg] <= ~o_glbl_rst & ~sys_rst_reg[gg] & (dis_rst_main_reg | i_rst_n);
always_comb begin : RST_OUT_I //{
o_cl_rst_hbm_axi_n = rst_out_n[9];
o_cl_rst_hbm_ref_n = rst_out_n[8];
o_cl_rst_c1_n = rst_out_n[7];
o_cl_rst_c0_n = rst_out_n[6];
o_cl_rst_b1_n = rst_out_n[5];
o_cl_rst_b0_n = rst_out_n[4];
o_cl_rst_a3_n = rst_out_n[3];
o_cl_rst_a2_n = rst_out_n[2];
o_cl_rst_a1_n = rst_out_n[1];
o_cl_rst_main_n = rst_out_n[0];
end : RST_OUT_I //}
//==========================================================================
// MMCM Lock
//==========================================================================
logic [3:0] mmcm_lock_in;
logic [3:0] mmcm_lock_syncd;
assign mmcm_lock_in = {i_mmcm_hbm_lock, i_mmcm_c_lock, i_mmcm_b_lock, i_mmcm_a_lock};
generate //{
for (genvar jj = 0; jj < $bits(mmcm_lock_in); jj++) begin : MMCM_LOCK_SYNC_I //{
xpm_cdc_single
#(
.DEST_SYNC_FF (2),
.INIT_SYNC_FF (0),
.SIM_ASSERT_CHK (0),
.SRC_INPUT_REG (0)
)
CDC_XPM_SINGLE
(
.src_clk (i_clk ),
.src_in (mmcm_lock_in[jj] ),
.dest_clk (i_clk ),
.dest_out (mmcm_lock_syncd[jj] )
);
end : MMCM_LOCK_SYNC_I//}
endgenerate //}
//
// MMCM_LOCK_REG
//
always_comb begin //{
mmcm_lock_reg = '0;
mmcm_lock_reg[0] = mmcm_lock_syncd[0]; // MMCM-A locked
mmcm_lock_reg[4] = mmcm_lock_syncd[1]; // MMCM-B locked
mmcm_lock_reg[6] = mmcm_lock_syncd[2]; // MMCM-C locked
mmcm_lock_reg[8] = mmcm_lock_syncd[3]; // MMCM-HBM locked
end //}
endmodule // aws_clk_regs