1 /* ****************************************************************************
\r
2 -- (C) Copyright 2016 Kevin M. Hubbard - All rights reserved.
\r
3 -- Source file: sump2.v
\r
6 -- Description: SUMP2 is a fast and simple logic analyzer.
\r
7 -- It captures N/2 samples before and after a specified trigger
\r
8 -- event where N is length of BRAM specified when instantiated.
\r
9 -- It is designed to scale easily from small and simple to wide
\r
10 -- and deep block RAM primiting.
\r
11 -- Language: Verilog-2001
\r
12 -- Simulation: Mentor-Modelsim
\r
13 -- Synthesis: Xilinst-XST, Lattice-Synplify
\r
14 -- License: This project is licensed with the CERN Open Hardware Licence
\r
15 -- v1.2. You may redistribute and modify this project under the
\r
16 -- terms of the CERN OHL v.1.2. (http://ohwr.org/cernohl).
\r
17 -- This project is distributed WITHOUT ANY EXPRESS OR IMPLIED
\r
18 -- WARRANTY, INCLUDING OF MERCHANTABILITY, SATISFACTORY QUALITY
\r
19 -- AND FITNESS FOR A PARTICULAR PURPOSE. Please see the CERN OHL
\r
20 -- v.1.2 for applicable Conditions.
\r
22 -- Design Instance Parameters with examples:
\r
23 -- depth_len = 1024 : Depth of RAM in number of cell, example 1024,4096
\r
24 -- depth_bits = 10 : Number of RAM address lines, example 10,12
\r
25 -- event_bytes = 4 : Number of event bytes 1,2,3 or 4
\r
26 -- data_dwords = 16 : Number of DWORDs for Data 0,4,8,12 or 16
\r
28 -- nonrle_en = 1 : If 0, removes Event RAM (for small RLE only designs)
\r
29 -- rle_en = 1 : Adds logic for Event RLE captures.
\r
30 -- pattern_en = 1 : Adds logic for 32bit event pattern triggers
\r
31 -- trigger_nth_en = 1 : Adds logic for triggering on Nth trigger event
\r
32 -- trigger_dly_en = 1 : Adds logic for triggering after a delay from trigger
\r
34 -- freq_mhz = 16'd80 : Freq integer 0 MHz up to 65 GHz ( 16bit )
\r
35 -- freq_fracts = 16'h0000 : Freq fraction bits, example C000 = 0.75 MHz
\r
36 -- sump_id = 16'hABBA : Don't Change
\r
37 -- sump_rev = 8'h01 : Don't Change
\r
39 -- LocalBus 2 DWORD Register Interface
\r
40 -- lb_cs_ctrl : PCI addr sel for Control
\r
41 -- lb_cs_data : PCI addr sel for Data transfers. +0x4 offset from lb_cs_ctrl
\r
43 -- Software Interface
\r
44 -- 5bit Control Commands:
\r
45 -- 0x00 : Idle + Read Status
\r
46 -- 0x01 : ARM + Read Status
\r
49 -- 0x04 : Load Trigger Type ( AND,OR,Ext )
\r
50 -- 0x05 : Load Trigger Field ( AND/OR bits )
\r
51 -- 0x06 : Load Trigger Delay & nth
\r
52 -- 0x07 : Load Trigger Position ( Num Post Trigger Samples to capture ).
\r
54 -- 0x08 : Load RLE Event Enable
\r
55 -- 0x09 : Load Read Pointer
\r
56 -- 0x0a : Load Read Page
\r
58 -- 0x0b : Read HW ID + Revision
\r
59 -- 0x0c : Read HW Config RAM Width+Length
\r
60 -- 0x0d : Read HW Config Sample Clock Frequency
\r
61 -- 0x0e : Read Trigger Location
\r
62 -- 0x0f : Read RAM Data ( address auto incrementing )
\r
64 -- 0x10 : Load User Controls
\r
65 -- 0x11 : Load User Pattern0
\r
66 -- 0x12 : Load User Pattern1
\r
67 -- 0x13 : Load Data Enable Field
\r
70 -- AND Rising = 0x00;
\r
71 -- AND Falling = 0x01;
\r
72 -- OR Rising = 0x02;
\r
73 -- OR Falling = 0x03;
\r
74 -- Pattern Rising = 0x04;
\r
75 -- Pattern Falling = 0x05;
\r
76 -- Input Trigger Rising = 0x06;
\r
77 -- Input Trigger Falling = 0x07;
\r
79 -- Revision History:
\r
80 -- Ver# When Who What
\r
81 -- ---- -------- -------- --------------------------------------------------
\r
82 -- 0.1 07.01.16 khubbard Creation
\r
83 -- ***************************************************************************/
\r
84 `default_nettype none // Strictly enforce all nets to be declared
\r
89 parameter depth_len = 1024,
\r
90 parameter depth_bits = 10,
\r
91 parameter event_bytes = 4,
\r
92 parameter data_dwords = 16,
\r
94 parameter nonrle_en = 1,
\r
95 parameter rle_en = 1,
\r
96 parameter pattern_en = 1,
\r
97 parameter trigger_nth_en = 1,
\r
98 parameter trigger_dly_en = 1,
\r
99 parameter trigger_wd_en = 1,
\r
101 parameter freq_mhz = 16'd80,
\r
102 parameter freq_fracts = 16'h0000,
\r
103 parameter sump_id = 16'hABBA,
\r
104 parameter sump_rev = 8'h01
\r
108 input wire clk_cap,
\r
110 input wire lb_cs_ctrl,
\r
111 input wire lb_cs_data,
\r
114 input wire [31:0] lb_wr_d,
\r
115 output reg [31:0] lb_rd_d,
\r
116 output reg lb_rd_rdy,
\r
119 output wire [31:0] user_ctrl,
\r
120 output wire [31:0] user_pat0,
\r
121 output wire [31:0] user_pat1,
\r
123 input wire trigger_in,
\r
124 output reg trigger_out,
\r
126 input wire [31:0] events_din,
\r
128 input wire [127:0] dwords_3_0,
\r
129 input wire [127:0] dwords_7_4,
\r
130 input wire [127:0] dwords_11_8,
\r
131 input wire [127:0] dwords_15_12,
\r
132 output reg [3:0] led_bus
\r
139 wire [7:0] cap_status;
\r
140 wire [4:0] ctrl_cmd;
\r
141 reg [4:0] ctrl_cmd_loc;
\r
143 wire [4:0] ctrl_rd_page;
\r
144 wire [15:0] ctrl_rd_ptr;
\r
145 wire ctrl_trigger_edge;
\r
146 wire [4:0] ctrl_trigger;
\r
147 reg [4:0] ctrl_trigger_p1;
\r
148 reg [4:0] ctrl_reg;
\r
149 reg [31:0] events_loc;
\r
154 reg trigger_and_p1;
\r
156 reg trigger_pat_p1;
\r
164 reg [31:0] ctrl_04_reg;
\r
165 reg [31:0] ctrl_05_reg;
\r
166 reg [31:0] ctrl_06_reg;
\r
167 reg [31:0] ctrl_07_reg;
\r
168 reg [31:0] ctrl_08_reg;
\r
169 reg [31:0] ctrl_09_reg;
\r
170 reg [31:0] ctrl_0a_reg;
\r
171 reg [31:0] ctrl_0b_reg;
\r
172 reg [31:0] ctrl_10_reg;
\r
173 reg [31:0] ctrl_11_reg;
\r
174 reg [31:0] ctrl_12_reg;
\r
175 reg [31:0] ctrl_13_reg;
\r
177 reg [31:0] ctrl_14_reg;
\r
178 wire [31:0] watchdog_reg;
\r
179 reg [31:0] watchdog_cnt;
\r
183 wire [31:0] trigger_bits;
\r
184 wire [3:0] trigger_type;
\r
185 wire [31:0] trigger_pos;
\r
186 wire [15:0] trigger_nth;
\r
187 wire [15:0] trigger_delay;
\r
188 reg [15:0] trigger_dly_cnt;
\r
189 wire [31:0] rle_event_en;
\r
190 reg [15:0] trigger_cnt;
\r
191 reg [31:0] ram_rd_d;
\r
192 reg [depth_bits-1:0] post_trig_cnt;
\r
193 reg [depth_bits-1:0] trigger_ptr;
\r
194 reg trigger_in_meta;
\r
200 // Variable Size Capture BRAM
\r
201 reg [31:0] event_ram_array[depth_len-1:0];
\r
202 reg [127:0] dwords_3_0_ram_array[depth_len-1:0];
\r
203 reg [127:0] dwords_7_4_ram_array[depth_len-1:0];
\r
204 reg [127:0] dwords_11_8_ram_array[depth_len-1:0];
\r
205 reg [127:0] dwords_15_12_ram_array[depth_len-1:0];
\r
207 reg [127:0] dwords_3_0_p1;
\r
208 reg [127:0] dwords_7_4_p1;
\r
209 reg [127:0] dwords_11_8_p1;
\r
210 reg [127:0] dwords_15_12_p1;
\r
212 reg [127:0] dwords_3_0_p2;
\r
213 reg [127:0] dwords_7_4_p2;
\r
214 reg [127:0] dwords_11_8_p2;
\r
215 reg [127:0] dwords_15_12_p2;
\r
217 reg [127:0] dwords_3_0_do;
\r
218 reg [127:0] dwords_7_4_do;
\r
219 reg [127:0] dwords_11_8_do;
\r
220 reg [127:0] dwords_15_12_do;
\r
222 reg [depth_bits-1:0] c_addr;
\r
223 reg [depth_bits-1:0] c_addr_p1;
\r
227 reg [31:0] c_di_p1;
\r
228 reg [depth_bits-1:0] d_addr;
\r
231 reg [63:0] rle_ram_array[depth_len-1:0];
\r
232 reg [depth_bits-1:0] a_addr;
\r
233 reg [depth_bits-1:0] a_addr_p1;
\r
237 reg [63:0] a_di_p1;
\r
238 reg [depth_bits-1:0] b_addr;
\r
241 wire [31:0] data_en_bits;
\r
243 reg data_en_loc_p1;
\r
244 reg [31:0] events_pre;
\r
245 reg [31:0] events_p1;
\r
246 reg [31:0] events_p2;
\r
247 reg [31:0] rle_time;
\r
248 reg [31:0] rle_time_p1;
\r
252 wire [7:0] data_4x_dwords;
\r
255 assign zeros = 16'd0;
\r
256 assign ones = 16'hFFFF;
\r
257 assign reset_loc = reset;
\r
260 assign cap_status = { rle_en, 1'b0, rle_done_jk, ~rle_pre_jk,
\r
261 complete_jk, acquired_jk, triggered_jk, armed_jk };
\r
264 //-----------------------------------------------------------------------------
\r
265 // Flop the input events and support reduction for much smaller designs.
\r
266 //-----------------------------------------------------------------------------
\r
267 always @ ( posedge clk_cap ) begin : proc_din
\r
268 if ( event_bytes == 1 ) begin
\r
269 events_loc <= { 24'd0, events_din[7:0] };
\r
270 end else if ( event_bytes == 2 ) begin
\r
271 events_loc <= { 16'd0, events_din[15:0] };
\r
272 end else if ( event_bytes == 3 ) begin
\r
273 events_loc <= { 8'd0, events_din[23:0] };
\r
275 events_loc <= { events_din[31:0] };
\r
278 if ( rle_en == 1 ) begin
\r
279 events_pre <= events_loc[31:0] & rle_event_en[31:0];
\r
280 events_p1 <= events_pre[31:0];
\r
281 events_p2 <= events_p1[31:0];
\r
286 //-----------------------------------------------------------------------------
\r
287 // Capture Logic. When armed, capture in a continuous loop until trigger is
\r
288 // detected and then capture N/2 samples more.
\r
289 // Note: Software Must go from Idle to Arm to clear the JKs.
\r
290 //-----------------------------------------------------------------------------
\r
291 always @ ( * ) begin : proc_data_en
\r
292 if ( data_en_bits == 32'h00000000 ||
\r
293 ( data_en_bits[31:0] & events_din[31:0] ) != 32'h00000000 ) begin
\r
294 data_en_loc <= 1;// Capture sample in time
\r
296 data_en_loc <= 0;// Prevent sample capture
\r
298 end // proc_data_en
\r
301 //-----------------------------------------------------------------------------
\r
302 // Capture Logic. When armed, capture in a continuous loop until trigger is
\r
303 // detected and then capture N/2 samples more.
\r
304 // Note: Software Must go from Idle to Arm to clear the JKs.
\r
305 //-----------------------------------------------------------------------------
\r
307 always @ ( posedge clk_cap ) begin : proc_trig
\r
308 trigger_in_meta <= trigger_in;
\r
309 trigger_in_p1 <= trigger_in_meta;
\r
310 trigger_in_p2 <= trigger_in_p1;
\r
314 trigger_or_p1 <= trigger_or;
\r
315 trigger_and_p1 <= trigger_and;
\r
316 trigger_pat_p1 <= trigger_pat;
\r
317 data_en_loc_p1 <= data_en_loc;
\r
319 for ( i = 0; i <= 31; i=i+1 ) begin
\r
320 if ( trigger_bits[i] == 1 && events_loc[i] == 1 ) begin
\r
321 trigger_or <= 1;// This is a 32bit OR
\r
325 if ( ( events_loc[31:0] & trigger_bits[31:0] ) == trigger_bits[31:0] ) begin
\r
330 (( events_loc[31:0] & pat0[31:0] ) ^
\r
331 ( pat1[31:0] & pat0[31:0] ) ) == 32'h00000000 ) begin
\r
333 if ( pattern_en == 1 ) begin
\r
334 trigger_pat <= 1;// Exact 32bit Pattern Match
\r
341 //-----------------------------------------------------------------------------
\r
342 // Capture Logic. When armed, capture in a continuous loop until trigger is
\r
343 // detected and then capture N/2 samples more.
\r
344 // Note: Software Must go from Idle to Arm to clear the JKs.
\r
345 //-----------------------------------------------------------------------------
\r
346 always @ ( posedge clk_cap ) begin : proc_cap
\r
354 if ( ctrl_cmd_loc == 5'h01 ) begin
\r
357 // Watchdog gets armed on 1st kick. Every kick after clears count.
\r
358 // If count expires, assert trigger_wd.
\r
359 if ( trigger_wd_en == 1 && ( trigger_or != trigger_or_p1 ) ) begin
\r
362 if ( wd_armed_jk == 0 || ( trigger_or != trigger_or_p1 ) ) begin
\r
363 watchdog_cnt <= 32'd0;
\r
366 watchdog_cnt <= watchdog_cnt[31:0] + 1;
\r
367 if ( watchdog_cnt == watchdog_reg[31:0] ) begin
\r
373 if ( triggered_jk == 0 && acquired_jk == 0 ) begin
\r
374 // PreTrigger Acquire
\r
376 if ( data_en_loc == 1 || data_en_loc_p1 == 1 ) begin
\r
378 c_addr <= c_addr + 1;
\r
381 if ( trigger_dly_cnt != 16'hFFFF ) begin
\r
382 trigger_dly_cnt <= trigger_dly_cnt + 1;
\r
385 if ( ( trigger_type==4'h0 && trigger_and==1 && trigger_and_p1==0 ) ||
\r
386 ( trigger_type==4'h1 && trigger_and==0 && trigger_and_p1==1 ) ||
\r
387 ( trigger_type==4'h2 && trigger_or ==1 && trigger_or_p1 ==0 ) ||
\r
388 ( trigger_type==4'h3 && trigger_or ==0 && trigger_or_p1 ==1 ) ||
\r
389 ( trigger_type==4'h4 && trigger_pat==1 && trigger_pat_p1==0 ) ||
\r
390 ( trigger_type==4'h5 && trigger_pat==0 && trigger_pat_p1==1 ) ||
\r
391 ( trigger_type==4'h6 && trigger_in_p1 ==1 && trigger_in_p2 ==0 ) ||
\r
392 ( trigger_type==4'h7 && trigger_in_p1 ==0 && trigger_in_p2 ==1 ) ||
\r
393 ( trigger_type==4'h8 && trigger_wd == 1 )
\r
395 if ( trigger_dly_cnt == 16'hFFFF || trigger_dly_en==0 ) begin
\r
396 trigger_dly_cnt <= 16'd0;
\r
397 trigger_loc <= 1;// Only used if trigger delay is removed
\r
398 c_we <= 1;// Store Trigger even if data_en_loc == 0
\r
399 c_addr <= c_addr + 1;
\r
403 // Don't allow trigger until pre-trig buffer is full
\r
404 if ( complete_jk == 1 ) begin
\r
405 if ( ( trigger_dly_cnt == trigger_delay[15:0] ) ||
\r
406 ( trigger_dly_en==0 && trigger_loc == 1 ) ) begin
\r
407 trigger_dly_cnt <= 16'hFFFF;
\r
408 if ( trigger_cnt == trigger_nth[15:0] || trigger_nth_en==0 ) begin
\r
410 trigger_ptr <= c_addr[depth_bits-1:0];
\r
414 trigger_cnt <= trigger_cnt + 1;
\r
418 end else if ( triggered_jk == 1 && acquired_jk == 0 ) begin
\r
419 // PostTrigger Acquire
\r
421 if ( data_en_loc == 1 || data_en_loc_p1 == 1 ) begin
\r
423 c_addr <= c_addr + 1;
\r
424 post_trig_cnt <= post_trig_cnt + 1;
\r
426 if ( post_trig_cnt == trigger_pos[depth_bits-1:0] ) begin
\r
432 // If RAM has rolled, then pre-trigger buffer is full. Assert status bit.
\r
433 // If RAM hasn't rolled, then pre-trigger samples start at 0x0.
\r
434 if ( c_addr[depth_bits-1] == 0 && c_addr_p1[depth_bits-1] == 1 ) begin
\r
439 end else if ( ctrl_cmd_loc == 5'h02 ) begin
\r
440 c_addr <= zeros[depth_bits-1:0];
\r
441 post_trig_cnt <= zeros[depth_bits-1:0];
\r
442 post_trig_cnt[1:0] <= 2'b11;// Subtracts 3 from trigger_pos for alignment
\r
443 trigger_cnt <= 16'd1;
\r
444 trigger_dly_cnt <= 16'hFFFF;
\r
452 // Cleanly xfer clock domains
\r
454 if ( ctrl_cmd_xfer == 1 ) begin
\r
455 ctrl_cmd_loc <= ctrl_cmd[4:0];
\r
460 assign c_di = events_loc[31:0];
\r
463 //-----------------------------------------------------------------------------
\r
464 // led_bus : Spins while waiting for trigger event. 2 Solids when done.
\r
465 //-----------------------------------------------------------------------------
\r
466 always @ ( posedge clk_cap ) begin : proc_led_bus
\r
467 if ( rle_done_jk == 0 ) begin
\r
470 if ( ctrl_cmd_loc == 5'h01 ) begin
\r
471 if ( rle_time[25:24] == 2'd0 ) begin
\r
473 end else if ( rle_time[25:24] == 2'd1 ) begin
\r
475 end else if ( rle_time[25:24] == 2'd2 ) begin
\r
480 // After Trigger, but before completion, only flash Left and Right
\r
481 if ( triggered_jk == 1 ) begin
\r
482 led_bus[2] <= 1'b0;
\r
483 led_bus[0] <= 1'b0;
\r
486 if ( rle_done_jk == 1 ) begin
\r
492 //-----------------------------------------------------------------------------
\r
493 // RLE Capture Logic. This captures and stores event changes along with
\r
494 // time stamps to a x64 BRAM. 1st half of RAM is any pre-trigger activity.
\r
495 // 2nd half of RAM is post-trigger activity. Pre-trig is circular and must
\r
496 // be unrolled by software in correct order. Enabling RLE block is optional.
\r
497 //-----------------------------------------------------------------------------
\r
498 always @ ( posedge clk_cap ) begin : proc_rle
\r
500 rle_time_p1 <= rle_time[31:0];
\r
501 // Prevent RLE from hanging in cases where no activity happens after the
\r
502 // trigger event by storing a non-changing sample periodically every
\r
503 // 2^24 clock cycles about 100ms at 100 MHz
\r
504 // 2^20 clock cycles about 10ms at 100 MHz x 1024 RAM = 10Sec
\r
505 // rle_wd_sample <= rle_time[23] & ~ rle_time_p1[23];
\r
506 rle_wd_sample <= rle_time[19] & ~ rle_time_p1[19];// About 5sec
\r
509 if ( ctrl_cmd_loc == 5'h01 ) begin
\r
510 rle_time <= rle_time[31:0] + 1;
\r
511 if ( triggered_jk == 0 ) begin
\r
512 a_addr[depth_bits-1] <= 0;// Pre-Trigger Half
\r
513 // If the prebuffer is invalid, store everything, change or no change
\r
514 // as to immediately fill up RAM with valid samples
\r
515 // Once prebuffer is valid, only store event deltas ( RLE )
\r
516 if ( rle_pre_jk == 1 || rle_wd_sample == 1 ||
\r
517 ( events_p1 != events_p2[31:0] ) ) begin
\r
519 a_addr[depth_bits-2:0] <= a_addr[depth_bits-2:0] + 1;
\r
520 if ( a_addr[depth_bits-2:0] == ones[depth_bits-2:0] ) begin
\r
521 rle_pre_jk <= 0;// PreBuffer is completely valid - and rolling
\r
524 end else if ( triggered_jk == 1 && rle_done_jk == 0 ) begin
\r
525 if ( ( events_p1 != events_p2[31:0] ) || ( rle_wd_sample == 1) ) begin
\r
527 a_addr[depth_bits-2:0] <= a_addr[depth_bits-2:0] + 1;
\r
528 // If previous write was to last address in RAM, then call it quits
\r
529 if ( a_addr[depth_bits-2:0] == ones[depth_bits-2:0] ) begin
\r
530 rle_done_jk <= 1;// Post-Trig RAM is full
\r
532 a_addr[depth_bits-2:0] <= a_addr[depth_bits-2:0];
\r
534 // If previous cycle was pre-trig, set address to start of post trig
\r
535 if ( a_addr[depth_bits-1] == 0 ) begin
\r
536 a_addr[depth_bits-1] <= 1;// Post-Trigger Half
\r
537 a_addr[depth_bits-2:0] <= zeros[depth_bits-2:0];
\r
543 end else if ( ctrl_cmd_loc == 5'h02 ) begin
\r
544 rle_time <= 32'd0;// 43 seconds at 100 MHz
\r
545 a_addr <= zeros[depth_bits-1:0];
\r
549 a_di[31:0] <= events_p1[31:0];
\r
550 a_di[63:32] <= rle_time[31:0];
\r
552 //assign a_di[31:0] = events_p1[31:0];
\r
553 //assign a_di[63:32] = rle_time[31:0];
\r
556 //-----------------------------------------------------------------------------
\r
557 // LocalBus Write Ctrl register
\r
558 //-----------------------------------------------------------------------------
\r
559 always @ ( posedge clk_lb ) begin : proc_lb_wr
\r
560 if ( lb_wr == 1 && lb_cs_ctrl == 1 ) begin
\r
561 ctrl_reg[4:0] <= lb_wr_d[4:0];
\r
562 ctrl_cmd_xfer <= 1;
\r
565 if ( lb_wr == 1 && lb_cs_data == 1 ) begin
\r
566 case( ctrl_cmd[4:0] )
\r
567 5'h04 : ctrl_04_reg <= lb_wr_d[31:0];
\r
568 5'h05 : ctrl_05_reg <= lb_wr_d[31:0];
\r
569 5'h06 : ctrl_06_reg <= lb_wr_d[31:0];
\r
570 5'h07 : ctrl_07_reg <= lb_wr_d[31:0];
\r
572 5'h08 : ctrl_08_reg <= lb_wr_d[31:0];
\r
573 5'h09 : ctrl_09_reg <= lb_wr_d[31:0];
\r
574 5'h0A : ctrl_0a_reg <= lb_wr_d[31:0];
\r
575 5'h0B : ctrl_0b_reg <= lb_wr_d[31:0];
\r
577 5'h10 : ctrl_10_reg <= lb_wr_d[31:0];
\r
578 5'h11 : ctrl_11_reg <= lb_wr_d[31:0];
\r
579 5'h12 : ctrl_12_reg <= lb_wr_d[31:0];
\r
580 5'h13 : ctrl_13_reg <= lb_wr_d[31:0];
\r
581 5'h14 : ctrl_14_reg <= lb_wr_d[31:0];
\r
585 if ( xfer_clr == 1 ) begin
\r
586 ctrl_cmd_xfer <= 0;
\r
589 if ( ctrl_cmd == 5'h01 ) begin
\r
590 d_addr <= c_addr[depth_bits-1:0];// When Acq stops, d_addr will be last
\r
592 if ( lb_wr == 1 && lb_cs_data == 1 && ctrl_cmd == 5'h09 ) begin
\r
593 d_addr <= lb_wr_d[depth_bits-1:0];// Load user specified address
\r
595 if ( rd_inc == 1 ) begin
\r
596 d_addr <= d_addr[depth_bits-1:0] + 1;// Auto Increment on each read
\r
599 if ( reset_loc == 1 ) begin
\r
600 ctrl_reg[4:0] <= 5'd0;
\r
601 ctrl_cmd_xfer <= 1;// Flag to xfer ctrl_reg into other clock domain
\r
605 assign ctrl_cmd[4:0] = ctrl_reg[4:0];
\r
607 assign trigger_type = ctrl_04_reg[3:0];
\r
608 assign trigger_bits = ctrl_05_reg[31:0];
\r
609 assign trigger_nth = ctrl_06_reg[15:0];
\r
610 assign trigger_delay = ctrl_06_reg[31:16];
\r
611 assign trigger_pos = ctrl_07_reg[31:0];
\r
612 assign rle_event_en = ctrl_08_reg[31:0];
\r
614 assign user_ctrl[31:0] = ctrl_10_reg[31:0];
\r
615 assign user_pat0[31:0] = ctrl_11_reg[31:0];
\r
616 assign user_pat1[31:0] = ctrl_12_reg[31:0];
\r
617 assign pat0[31:0] = ctrl_11_reg[31:0];
\r
618 assign pat1[31:0] = ctrl_12_reg[31:0];
\r
619 assign data_en_bits[31:0] = ctrl_13_reg[31:0];
\r
620 assign watchdog_reg[31:0] = ctrl_14_reg[31:0];
\r
622 assign ctrl_rd_ptr[15:0] = ctrl_09_reg[15:0];
\r
623 assign ctrl_rd_page[4:0] = ctrl_0a_reg[4:0];
\r
625 assign data_4x_dwords = data_dwords;
\r
628 //-----------------------------------------------------------------------------
\r
629 // LocalBus readback of ctrl_reg and data_reg
\r
630 //-----------------------------------------------------------------------------
\r
631 always @ ( posedge clk_lb ) begin : proc_lb_rd
\r
636 if ( lb_rd == 1 && lb_cs_ctrl == 1 ) begin
\r
637 lb_rd_d[4:0] <= ctrl_reg[4:0];
\r
641 if ( lb_rd == 1 && lb_cs_data == 1 ) begin
\r
643 if ( ctrl_cmd == 5'h00 ||
\r
646 lb_rd_d[7:0] <= cap_status[7:0];
\r
648 if ( ctrl_cmd == 5'h0b ) begin
\r
649 lb_rd_d[31:16] <= sump_id;// Identification
\r
650 lb_rd_d[15:8] <= sump_rev;// Revision
\r
651 lb_rd_d[7:5] <= 3'd0;
\r
652 lb_rd_d[4] <= ~ nonrle_en;// Invert to disable backwards SW comptbl
\r
653 lb_rd_d[3] <= rle_en;
\r
654 lb_rd_d[2] <= pattern_en;
\r
655 lb_rd_d[1] <= trigger_nth_en;
\r
656 lb_rd_d[0] <= trigger_dly_en;
\r
658 if ( ctrl_cmd == 5'h0c ) begin
\r
659 lb_rd_d[31:28] <= rle_en ;// 1 if RLE RAM exists
\r
660 lb_rd_d[27:24] <= event_bytes;// How Many Event Bytes 1-4
\r
661 lb_rd_d[23:16] <= data_4x_dwords[5:2];// How Many 32bit BRAMs data 4x
\r
662 lb_rd_d[15:0] <= depth_len; // How deep RAMs are
\r
664 if ( ctrl_cmd == 5'h0d ) begin
\r
665 lb_rd_d[15:0] <= freq_fracts;// Fractional MHz bits 1/2,1/4,etc.
\r
666 lb_rd_d[31:16] <= freq_mhz ;// Integer MHz
\r
668 if ( ctrl_cmd == 5'h0e ) begin
\r
669 lb_rd_d[depth_bits-1:0] <= trigger_ptr[depth_bits-1:0];// Where Trig Is
\r
671 if ( ctrl_cmd == 5'h0f ) begin
\r
672 lb_rd_d <= ram_rd_d[31:0];
\r
673 rd_inc <= 1;// Auto Increment RAM Address
\r
677 if ( data_dwords != 0 ) begin
\r
678 // Mux between the BRAMs
\r
679 case( ctrl_rd_page[4:0] )
\r
680 5'H02 : ram_rd_d <= b_do[31:0]; // RLE Data
\r
681 5'H03 : ram_rd_d <= b_do[63:32]; // RLE Time
\r
683 5'H10 : ram_rd_d <= dwords_3_0_do[31:0];
\r
684 5'H11 : ram_rd_d <= dwords_3_0_do[63:32];
\r
685 5'H12 : ram_rd_d <= dwords_3_0_do[95:64];
\r
686 5'H13 : ram_rd_d <= dwords_3_0_do[127:96];
\r
688 5'H14 : ram_rd_d <= dwords_7_4_do[31:0];
\r
689 5'H15 : ram_rd_d <= dwords_7_4_do[63:32];
\r
690 5'H16 : ram_rd_d <= dwords_7_4_do[95:64];
\r
691 5'H17 : ram_rd_d <= dwords_7_4_do[127:96];
\r
693 5'H18 : ram_rd_d <= dwords_11_8_do[31:0];
\r
694 5'H19 : ram_rd_d <= dwords_11_8_do[63:32];
\r
695 5'H1a : ram_rd_d <= dwords_11_8_do[95:64];
\r
696 5'H1b : ram_rd_d <= dwords_11_8_do[127:96];
\r
698 5'H1c : ram_rd_d <= dwords_15_12_do[31:0];
\r
699 5'H1d : ram_rd_d <= dwords_15_12_do[63:32];
\r
700 5'H1e : ram_rd_d <= dwords_15_12_do[95:64];
\r
701 5'H1f : ram_rd_d <= dwords_15_12_do[127:96];
\r
703 default : ram_rd_d <= d_do[31:0]; // Events
\r
706 // Mux between the BRAMs
\r
707 case( ctrl_rd_page[4:0] )
\r
708 5'H02 : ram_rd_d <= b_do[31:0]; // RLE Data
\r
709 5'H03 : ram_rd_d <= b_do[63:32];// RLE Time
\r
710 default : ram_rd_d <= d_do[31:0]; // Events
\r
717 //-----------------------------------------------------------------------------
\r
718 // Data Dual Port RAM - Infer RAM here to make easy to change depth on the fly
\r
719 //-----------------------------------------------------------------------------
\r
720 always @( posedge clk_cap )
\r
723 c_addr_p1 <= c_addr;
\r
725 if ( c_we_p1 ) begin
\r
726 if ( nonrle_en == 1 ) begin
\r
727 event_ram_array[c_addr_p1] <= c_di_p1;
\r
731 dwords_3_0_p1 <= dwords_3_0[127:0];
\r
732 dwords_7_4_p1 <= dwords_7_4[127:0];
\r
733 dwords_11_8_p1 <= dwords_11_8[127:0];
\r
734 dwords_15_12_p1 <= dwords_15_12[127:0];
\r
736 dwords_3_0_p2 <= dwords_3_0_p1[127:0];
\r
737 dwords_7_4_p2 <= dwords_7_4_p1[127:0];
\r
738 dwords_11_8_p2 <= dwords_11_8_p1[127:0];
\r
739 dwords_15_12_p2 <= dwords_15_12_p1[127:0];
\r
741 if ( c_we_p1 ) begin
\r
742 if ( data_dwords >= 4 ) begin
\r
743 dwords_3_0_ram_array[ c_addr_p1 ] <= dwords_3_0_p2[127:0];
\r
745 if ( data_dwords >= 8 ) begin
\r
746 dwords_7_4_ram_array[ c_addr_p1 ] <= dwords_7_4_p2[127:0];
\r
748 if ( data_dwords >= 12 ) begin
\r
749 dwords_11_8_ram_array[ c_addr_p1 ] <= dwords_11_8_p2[127:0];
\r
751 if ( data_dwords >= 16 ) begin
\r
752 dwords_15_12_ram_array[ c_addr_p1 ] <= dwords_15_12_p2[127:0];
\r
758 //-----------------------------------------------------------------------------
\r
759 // 2nd Port of RAM is clocked from local bus
\r
760 //-----------------------------------------------------------------------------
\r
761 always @( posedge clk_lb )
\r
763 if ( nonrle_en == 1 ) begin
\r
764 d_do <= event_ram_array[d_addr] ;
\r
767 if ( data_dwords >= 4 ) begin
\r
768 dwords_3_0_do <= dwords_3_0_ram_array[ d_addr ];
\r
770 if ( data_dwords >= 8 ) begin
\r
771 dwords_7_4_do <= dwords_7_4_ram_array[ d_addr ];
\r
773 if ( data_dwords >= 12 ) begin
\r
774 dwords_11_8_do <= dwords_11_8_ram_array[ d_addr ];
\r
776 if ( data_dwords >= 16 ) begin
\r
777 dwords_15_12_do <= dwords_15_12_ram_array[ d_addr ];
\r
782 //-----------------------------------------------------------------------------
\r
783 // RLE Dual Port RAM - Infer RAM here to make easy to change depth on the fly
\r
784 //-----------------------------------------------------------------------------
\r
785 always @( posedge clk_cap )
\r
787 if ( rle_en == 1 ) begin
\r
789 a_addr_p1 <= a_addr;
\r
791 a_addr_p1 <= a_addr;
\r
793 // if ( a_we_p1 ) begin
\r
794 // rle_ram_array[a_addr_p1] <= a_di_p1;
\r
795 // end // if ( a_we )
\r
797 rle_ram_array[a_addr ] <= a_di;
\r
803 //-----------------------------------------------------------------------------
\r
804 // 2nd Port of RAM is clocked from local bus
\r
805 //-----------------------------------------------------------------------------
\r
806 always @( posedge clk_lb )
\r
808 if ( rle_en == 1 ) begin
\r
809 b_do <= rle_ram_array[d_addr];
\r