-
Notifications
You must be signed in to change notification settings - Fork 380
/
pattern_detect.sv
84 lines (68 loc) · 2.15 KB
/
pattern_detect.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
//------------------------------------------------------------------------------
// pattern_detect.sv
// published as part of https://github.com/pConst/basic_verilog
// Konstantin Pavlov, pavlovconst@gmail.com
//------------------------------------------------------------------------------
// INFO ------------------------------------------------------------------------
// Detects data pattern specified by the provided PAT parameter
//
// Features capturing WIDTH bits simultaneously in case your data
// comes in parallel, like in QSPI interface, for example
//
// Detects pattern in any possible bit position, supposing that input data
// is an unaligned bit stream
//
/* --- INSTANTIATION TEMPLATE BEGIN ---
pattern_detect #(
.DEPTH( 2 ),
.WIDTH( 16 ),
// pattern parameters
.PAT_WIDTH( 5 ), // must be less than DEPTH*WIDTH
.PAT( 5'b10011 )
) PD1 (
.clk( clk ),
.nrst( nrst ),
.ena( 1'b1 ),
.data( data[4:0] ),
.detected_pos( )
.detected( )
);
--- INSTANTIATION TEMPLATE END ---*/
module pattern_detect #( parameter
DEPTH = 2,
WIDTH = 16,
PAT_WIDTH = 5, // must be less than DEPTH*WIDTH
bit [PAT_WIDTH-1:0] PAT = '1
)(
input clk,
input nrst,
input ena,
input [WIDTH-1:0] data,
output logic detected,
output logic [DEPTH*WIDTH-1:0] detected_mask
);
logic [DEPTH*WIDTH-1:0] sample_buf = '0;
logic [DEPTH*WIDTH-1:0] ena_buf = '0;
always @ (posedge clk) begin
if( ~nrst ) begin
sample_buf[DEPTH*WIDTH-1:0] <= {DEPTH*WIDTH{1'b0}};
ena_buf[DEPTH*WIDTH-1:0] <= {DEPTH*WIDTH{1'b0}};
end else begin
sample_buf[DEPTH*WIDTH-1:0] <= {sample_buf[DEPTH*WIDTH-WIDTH-1:0],
data[WIDTH-1:0]};
ena_buf[DEPTH*WIDTH-1:0] <= {ena_buf[DEPTH*WIDTH-WIDTH-1:0],
{WIDTH{ena}} };
end
end
always_comb begin
integer i;
detected_mask[DEPTH*WIDTH-1:0] = '0;
for( i=0; i<(DEPTH*WIDTH-PAT_WIDTH); i++ ) begin
if( sample_buf[i+:PAT_WIDTH] == PAT[PAT_WIDTH-1:0] &&
ena_buf[i+:PAT_WIDTH]) begin
detected_mask[i] = 1'b1;
end
end
detected = |detected_mask[DEPTH*WIDTH-1:0];
end
endmodule