-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcsreg.v
410 lines (379 loc) · 12.3 KB
/
csreg.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
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
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: ITEP
// Engineer: SvirLex
//
// Create Date: 19:59:41 09/26/2014
// Design Name: fpga_main
// Module Name: csreg
// Project Name: wfd125
// Target Devices: s6
// Revision 0.01 - File Created
// Additional Comments:
// This is a CSR regiter, with main purpose to make commutations between
// CSR[2:0] defines connection of trigger:
// 0 - I->I internal trigger to channels
// 1 - I->FI internal trigger to channels and front panel
// 2 - I->BI internal trigger to channels and back panel
// 3 - I->FBI internal trigger to channels, front and back panels
// 4 - F->I front panel trigger to channels
// 5 - F->BI front panel trigger to channels and back panel
// 6 - B->I back panel trigger to channels
// 7 - B->FI back panel trigger to channels and front panel
// CSR[3] if 1, channels do not accept trigger
// CSR[6:4] defines connection of INH similarly to trigger connections
// CSR[7] if 1, channels are insensitive to INH
// CSR[10:8] defines connection of clocks similarly to trigger connections
// in addition, programming of CDCUN required:
// for modes 0-3 IN1 of CDCUN must be selected
// for modes 4-7 IN2 of CDCUN must be selected
// CSR[11] test pulse generation enable (makes ~100 Hz ~1 us pulses on ICX[7])
// CSR[12] enable trigger+inhibit mixture on FP[5:4]
// CSR[15:13] general purpose CSR outputs. CSR[13] - enable token sychro blocks (type=5).
// CSR[30:16] user word to be put to trigger block written to memory
// CSR[31] peripheral WB reset
// CSR+4 [31:0] are general inputs from the upper hierarchy, unused so far
//
//////////////////////////////////////////////////////////////////////////////////
module csreg(
// WB signals
input [31:0] wb_dat_i,
output [31:0] wb_dat_o,
input wb_we,
input wb_clk,
input wb_cyc,
output reg wb_ack,
input wb_stb,
input wb_adr,
// reg outputs/inputs for general purposes
output [2:0] gen_o,
input [31:0] gen_i,
// assigned outputs
output pwb_rst, // peripheral wishbone reset
output [14:0] usr_word, // user word to be put to trigger memory block
// inputs from triggen
input trig,
input inh,
output auxtrig, // translated from FP trig1 trigger
// front panel signals
inout [1:0] trig_FP,
inout [1:0] inh_FP,
inout [1:0] trig1_FP,
// back panel signals
inout [1:0] trig_BP,
inout [1:0] inh_BP,
// signals to peripheral X's
output [1:0] trig_ICX,
output inh_ICX,
// outputs to drive CLK muxes
output reg ECLKSEL,
output reg OCLKSEL,
output reg CLKENFP,
output reg CLKENBP,
output reg CLKENBFP,
output reg testpulse
);
reg [31:0] csr;
reg [31:0] reg_i;
// trigger propagation signals
wire trig_from_FP;
wire trig_to_FP;
reg trig_en_FP = 0;
reg trig_FP_sel = 0;
wire trig_from_BP;
wire trig_to_BP;
reg trig_en_BP = 0;
reg trig_BP_sel = 0;
wire trig_to_ICX;
reg [1:0] trig_ICX_sel;
reg trig1_to_FP;
wire trig1_from_FP;
// inhibit propagation signals
wire inh_from_FP;
wire inh_to_FP;
reg inh_en_FP = 0;
reg inh_FP_sel = 0;
wire inh_from_BP;
wire inh_to_BP;
reg inh_en_BP = 0;
reg inh_BP_sel = 0;
wire inh_to_ICX;
reg [1:0] inh_ICX_sel;
reg [1:0] aux_trig_d = 0;
// test pulse
reg [6:0] test_prediv = 0;
reg test_prepulse = 0;
reg [12:0] test_div = 0;
// trigger + inhibit mixture
reg [6:0] trig_blk_cnt = 0;
assign gen_o = csr[15:13];
assign pwb_rst = csr[31];
assign usr_word = csr[30:16];
// WB protocol
assign wb_dat_o = (wb_adr) ? reg_i : csr;
always @ (posedge wb_clk) begin
wb_ack <= wb_cyc & wb_stb;
if (wb_cyc & wb_stb & wb_we & (~wb_adr)) csr <= wb_dat_i;
reg_i <= {2'b00, inh_ICX_sel, inh_FP_sel, inh_BP_sel, inh_en_FP, inh_en_BP,
2'b00, trig_ICX_sel, trig_FP_sel, trig_BP_sel, trig_en_FP, trig_en_BP, gen_i[15:0]};
end
// Clock control
always @ (posedge wb_clk) begin
// default values are all zeroes, meaning no outputs are enabled
ECLKSEL <= 0;
OCLKSEL <= 0;
CLKENFP <= 0;
CLKENBP <= 0;
CLKENBFP <= 0;
case (csr[10:8])
3'b000 : begin // internal clock to ADC's, needs CDCUN select input 0
end
3'b001 : begin // internal clock to ADC's and front panel, needs CDCUN select input 0
CLKENFP <= 1;
end
3'b010 : begin // internal clock to ADC's and back panel, needs CDCUN select input 0
CLKENBP <= 1;
end
3'b011 : begin // internal clock to ADC's, front and back panel, needs CDCUN select input 0
CLKENFP <= 1;
CLKENBP <= 1;
end
3'b100 : begin // front panel clock to ADC's, needs CDCUN select input 1
end
3'b101 : begin // front panel clock to ADC's and back panel, needs CDCUN select input 1
OCLKSEL <= 1;
CLKENBP <= 1;
end
3'b110 : begin // back panel clock to ADC's, needs CDCUN select input 1
ECLKSEL <= 1;
end
3'b111 : begin // back panel clock to ADC's and front panel, needs CDCUN select input 1
ECLKSEL <= 1;
CLKENBFP <= 1;
end
endcase
end
// Trigger propagation
// Front panel input is always terminated
IOBUFDS #(
.DIFF_TERM("TRUE"), // Differential Termination
.IOSTANDARD("LVDS_25") // Specify the I/O standard
) trig_fp (
.O(trig_from_FP), // Buffer output
.IO(trig_FP[0]), // Diff_p inout (connect directly to top-level port)
.IOB(trig_FP[1]), // Diff_n inout (connect directly to top-level port)
.I(trig_to_FP), // Buffer input
.T(~trig_en_FP) // 3-state enable input, high=input, low=output
);
// Back panel input should be terminated only in the module last in crate
IOBUFDS #(
`ifdef TERM_TRIG_BP
.DIFF_TERM("TRUE"), // Differential Termination
`else
.DIFF_TERM("FALSE"), // Differential Termination
`endif
.IOSTANDARD("BLVDS_25") // Specify the I/O standard
) trig_bp (
.O(trig_from_BP), // Buffer output
.IO(trig_BP[0]), // Diff_p inout (connect directly to top-level port)
.IOB(trig_BP[1]), // Diff_n inout (connect directly to top-level port)
.I(trig_to_BP), // Buffer input
.T(~trig_en_BP) // 3-state enable input, high=input, low=output
);
// no differential outputs on bank 3
assign trig_ICX[0] = trig_to_ICX;
assign trig_ICX[1] = ~trig_to_ICX;
cmux21 trig_fp_sel(
.I0 (trig),
.I1 (trig_from_BP),
.S (trig_FP_sel),
.O (trig_to_FP)
);
cmux21 trig_bp_sel(
.I0 (trig),
.I1 (trig_from_FP),
.S (trig_BP_sel),
.O (trig_to_BP)
);
cmux41 trig_icx_sel(
.I0 (trig),
.I1 (trig_from_FP),
.I2 (trig_from_BP),
.I3 (1'b0),
.S (trig_ICX_sel),
.O (trig_to_ICX)
);
always @ (posedge wb_clk) begin
// front and back panel transmitters are disabled by default
trig_en_FP <= 0;
trig_en_BP <= 0;
trig_FP_sel <= 0;
trig_BP_sel <= 0;
case (csr[2:0])
3'b000 : begin // internal trig to X's
trig_ICX_sel <= 0;
end
3'b001 : begin // internal trig to X's and front panel
trig_ICX_sel <= 0;
trig_en_FP <= 1;
end
3'b010 : begin // internal trig to X's and back panel
trig_ICX_sel <= 0;
trig_en_BP <= 1;
end
3'b011 : begin // internal trig to X's, back and front panel
trig_ICX_sel <= 0;
trig_en_FP <= 1;
trig_en_BP <= 1;
end
3'b100 : begin // front panel trig to X's
trig_ICX_sel <= 1;
end
3'b101 : begin // front panel trig to X's and back panel
trig_ICX_sel <= 1;
trig_BP_sel <= 1;
trig_en_BP <= 1;
end
3'b110 : begin // back panel trig to X's
trig_ICX_sel <= 2;
end
3'b111 : begin // back panel trig to X's and front panel
trig_ICX_sel <= 2;
trig_FP_sel <= 1;
trig_en_FP <= 1;
end
endcase
if (csr[3]) trig_ICX_sel <= 3; // X's are insensitive to INH
end
// INH propagation
// Front panel input is always terminated
IOBUFDS #(
.DIFF_TERM("TRUE"), // Differential Termination
.IOSTANDARD("LVDS_25") // Specify the I/O standard
) inh_fp (
.O(inh_from_FP), // Buffer output
.IO(inh_FP[0]), // Diff_p inout (connect directly to top-level port)
.IOB(inh_FP[1]), // Diff_n inout (connect directly to top-level port)
.I(inh_to_FP), // Buffer input
.T(~inh_en_FP) // 3-state enable input, high=input, low=output
);
// Back panel input should be terminated only in the module last in crate
IOBUFDS #(
`ifdef TERM_INH_BP
.DIFF_TERM("TRUE"), // Differential Termination
`else
.DIFF_TERM("FALSE"), // Differential Termination
`endif
.IOSTANDARD("BLVDS_25") // Specify the I/O standard
) inh_bp (
.O(inh_from_BP), // Buffer output
.IO(inh_BP[0]), // Diff_p inout (connect directly to top-level port)
.IOB(inh_BP[1]), // Diff_n inout (connect directly to top-level port)
.I(inh_to_BP), // Buffer input
.T(~inh_en_BP) // 3-state enable input, high=input, low=output
);
// onboard INH is single ended
assign inh_ICX = inh_to_ICX;
cmux21 inh_fp_sel(
.I0 (inh),
.I1 (inh_from_BP),
.S (inh_FP_sel),
.O (inh_to_FP)
);
cmux21 inh_bp_sel(
.I0 (inh),
.I1 (inh_from_FP),
.S (inh_BP_sel),
.O (inh_to_BP)
);
cmux41 inh_icx_sel(
.I0 (inh),
.I1 (inh_from_FP),
.I2 (inh_from_BP),
.I3 (1'b0),
.S (inh_ICX_sel),
.O (inh_to_ICX)
);
always @ (posedge wb_clk) begin
// front and back panel transmitters are disabled by default
inh_en_FP <= 0;
inh_en_BP <= 0;
inh_FP_sel <= 0;
inh_BP_sel <= 0;
case (csr[6:4])
3'b000 : begin // internal inh to X's
inh_ICX_sel <= 0;
end
3'b001 : begin // internal inh to X's and front panel
inh_ICX_sel <= 0;
inh_en_FP <= 1;
end
3'b010 : begin // internal inh to X's and back panel
inh_ICX_sel <= 0;
inh_en_BP <= 1;
end
3'b011 : begin // internal inh to X's, back and front panel
inh_ICX_sel <= 0;
inh_en_FP <= 1;
inh_en_BP <= 1;
end
3'b100 : begin // front panel inh to X's
inh_ICX_sel <= 1;
end
3'b101 : begin // front panel inh to X's and back panel
inh_ICX_sel <= 1;
inh_BP_sel <= 1;
inh_en_BP <= 1;
end
3'b110 : begin // back panel inh to X's
inh_ICX_sel <= 2;
end
3'b111 : begin // back panel inh to X's and front panel
inh_ICX_sel <= 2;
inh_FP_sel <= 1;
inh_en_FP <= 1;
end
endcase
if (csr[7]) inh_ICX_sel <= 3; // X's are insensitive to INH
end
// test pulse
always @ (posedge wb_clk) begin
if (csr[11]) begin
testpulse <= (test_div == 0);
test_prepulse <= (test_prediv == 0);
test_prediv <= test_prediv + 1;
if (test_prepulse) test_div <= test_div + 1;
end else begin
testpulse <= 0;
end
end
// Trigger + inhibit mixture for proportional chambers
IBUFDS #(
.DIFF_TERM("TRUE"), // Differential Termination
.IOSTANDARD("LVDS_25") // Specify the I/O standard
) auxtrig_fp (
.O(trig1_from_FP), // Buffer output
.I(trig1_FP[0]), // Diff_p inout (connect directly to top-level port)
.IB(trig1_FP[1]) // Diff_n inout (connect directly to top-level port)
// .I(trig1_to_FP), // Buffer input
// .T(~csr[12]) // 3-state enable input, high=input, low=output
);
always @ (posedge wb_clk) begin
trig1_to_FP <= 0;
if (inh) begin
trig1_to_FP <= 1;
trig_blk_cnt <= 0;
end else if (trig_blk_cnt > 0) begin
trig_blk_cnt <= trig_blk_cnt - 1;
trig1_to_FP <= (trig_blk_cnt > 56) ? 1 : 0;
end else if (trig) begin
trig_blk_cnt <= 63;
trig1_to_FP <= 1;
end
// auxtrig <= 0;
// if (aux_trig_d == 2'b01) auxtrig <= 1;
// aux_trig_d <= {aux_trig_d[0], trig1_from_FP};
end
// just translate input auxtrig to the trigger module
assign auxtrig = trig1_from_FP;
endmodule