Skip to content

Commit c189b88

Browse files
committed
Added PRBS test sequence generator and chekker
1 parent 8fa8244 commit c189b88

File tree

2 files changed

+217
-0
lines changed

2 files changed

+217
-0
lines changed

prbs_gen_chk.sv

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
//------------------------------------------------------------------------------
2+
// prbs_gen_chk.sv
3+
// Konstantin Pavlov, [email protected]
4+
//------------------------------------------------------------------------------
5+
6+
// INFO ------------------------------------------------------------------------
7+
// This module generates or checks a PRBS pattern
8+
// See "xapp884" appnote for more info
9+
10+
// Set paramaters for compliance to ITU-T Recommendation O.150 Section 5
11+
//--------------------------------- ------------------------------------------
12+
// POLY_LEN POLY_TAP INV_PATTERN | nbr of bit seq. max 0 feedback
13+
// | stages length sequence stages
14+
//--------------------------------- ------------------------------------------
15+
// 7(non standard) 6 false | 7 127 6 6, 7
16+
// 9 5 false | 9 511 8 5, 9
17+
// 11 9 false | 11 2047 10 9,11
18+
// 15 14 true | 15 32767 15 14,15
19+
// 20 3 false | 20 1048575 19 3,20
20+
// 23 18 true | 23 8388607 23 18,23
21+
// 29 27 true | 29 536870911 29 27,29
22+
// 31 28 true | 31 2147483647 31 28,31
23+
24+
25+
/* --- INSTANTIATION TEMPLATE BEGIN ---
26+
27+
prbs_gen_chk #(
28+
.WIDTH( 32 ),
29+
.CHK_MODE( 0 ),
30+
.INV_PATTERN( 1 ),
31+
.POLY_LEN( 31 ),
32+
.POLY_TAP( 28 )
33+
) prbs1 (
34+
.clk( clk ),
35+
.nrst( nrst ),
36+
.en( 1'b1 )
37+
.data_in( 0 ),
38+
.data_out( d[31:0] )
39+
)
40+
41+
--- INSTANTIATION TEMPLATE END ---*/
42+
43+
44+
module prbs_gen_chk #( parameter
45+
WIDTH = 32, // data_in, data_out port width
46+
CHK_MODE = 0, // 0 - module is a gen
47+
// 1 - module is a chk
48+
INV_PATTERN = 1, // invert PRBS bit-wise
49+
POLY_LEN = 31, // generator polynomial length
50+
POLY_TAP = 28 // generator polynomial tap
51+
)(
52+
input clk,
53+
input nrst,
54+
input en,
55+
input [(WIDTH-1):0] data_in, // CHK_MODE: data to be checked
56+
// ~CHK_MODE: inject error
57+
output logic [(WIDTH-1):0] data_out = {WIDTH{1'b1}}
58+
// CHK_MODE: error found (checker), LSB is the oldest received bit
59+
// ~CHK_MODE: generated prbs pattern, LSB is the oldest-generated bit
60+
);
61+
62+
// considering inversion
63+
logic [(WIDTH-1):0] data_in_i;
64+
assign data_in_i[(WIDTH-1):0] = (INV_PATTERN)?
65+
(~data_in[(WIDTH-1):0]):
66+
(data_in[(WIDTH-1):0]);
67+
68+
logic [(POLY_LEN-1):0] prbs_register = {POLY_LEN{1'b1}}; // LFSR itself
69+
logic [WIDTH:0][(POLY_LEN-1):0] shift_table;
70+
logic [(WIDTH-1):0] xor_results;
71+
72+
// generating [POLY_LEN cols]x[WIDTH+1 rows] table by shifting prbs register
73+
genvar i;
74+
generate
75+
assign shift_table[0] = prbs_register[(POLY_LEN-1):0];
76+
for (i=0; i<WIDTH; i=i+1) begin : gen1
77+
assign xor_results[i] = shift_table[i][POLY_LEN-POLY_TAP] ^ shift_table[i][0];
78+
assign shift_table[i+1] = { (CHK_MODE)?(data_in_i[i]):(xor_results[i]),
79+
shift_table[i][(POLY_LEN-1):1] };
80+
end
81+
endgenerate
82+
83+
always_ff @(posedge clk) begin
84+
if(~nrst) begin
85+
data_out[(WIDTH-1):0] <= {WIDTH{1'b1}};
86+
prbs_register[(POLY_LEN-1):0] <= {POLY_LEN{1'b1}};
87+
end else if (en) begin
88+
// taking new bits generated by xor operation
89+
data_out[(WIDTH-1):0] <= xor_results[(WIDTH-1):0] ^ data_in_i[(WIDTH-1):0];
90+
// storing prbs register
91+
prbs_register[(POLY_LEN-1):0] <= shift_table[WIDTH][(POLY_LEN-1):0];
92+
end
93+
end
94+
95+
endmodule
96+

prbs_gen_chk_tb.sv

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
//------------------------------------------------------------------------------
2+
// prbs_gen_chk_tb.sv
3+
// Konstantin Pavlov, [email protected]
4+
//------------------------------------------------------------------------------
5+
6+
// INFO ------------------------------------------------------------------------
7+
//
8+
9+
`timescale 1ns / 1ps
10+
11+
module prbs_gen_chk_tb();
12+
13+
logic clk200;
14+
initial begin
15+
#0 clk200 = 1'b0;
16+
forever
17+
#2.5 clk200 = ~clk200;
18+
end
19+
20+
// external device "asynchronous" clock
21+
logic clk33;
22+
initial begin
23+
#0 clk33 = 1'b0;
24+
forever
25+
#15.151 clk33 = ~clk33;
26+
end
27+
28+
logic rst;
29+
initial begin
30+
#0 rst = 1'b0;
31+
#10.2 rst = 1'b1;
32+
#5 rst = 1'b0;
33+
//#10000;
34+
forever begin
35+
#9985 rst = ~rst;
36+
#5 rst = ~rst;
37+
end
38+
end
39+
40+
logic nrst;
41+
assign nrst = ~rst;
42+
43+
logic rst_once;
44+
initial begin
45+
#0 rst_once = 1'b0;
46+
#10.2 rst_once = 1'b1;
47+
#5 rst_once = 1'b0;
48+
end
49+
50+
logic nrst_once;
51+
assign nrst_once = ~rst_once;
52+
53+
logic [31:0] DerivedClocks;
54+
clk_divider #(
55+
.WIDTH( 32 )
56+
) cd1 (
57+
.clk( clk200 ),
58+
.nrst( nrst_once ),
59+
.ena( 1'b1 ),
60+
.out( DerivedClocks[31:0] )
61+
);
62+
63+
logic [31:0] E_DerivedClocks;
64+
edge_detect ed1[31:0] (
65+
.clk( {32{clk200}} ),
66+
.nrst( {32{nrst_once}} ),
67+
.in( DerivedClocks[31:0] ),
68+
.rising( E_DerivedClocks[31:0] ),
69+
.falling( ),
70+
.both( )
71+
);
72+
73+
logic [15:0] RandomNumber1;
74+
c_rand rng1 (
75+
.clk( clk200 ),
76+
.rst( rst_once ),
77+
.reseed( 1'b0 ),
78+
.seed_val( DerivedClocks[31:0] ),
79+
.out( RandomNumber1[15:0] )
80+
);
81+
82+
logic start;
83+
initial begin
84+
#0 start = 1'b0;
85+
#100 start = 1'b1;
86+
#20 start = 1'b0;
87+
end
88+
89+
// Module under test ==========================================================
90+
91+
logic [31:0] d1;
92+
prbs_gen_chk #(
93+
.WIDTH( 32 ),
94+
.CHK_MODE( 0 ),
95+
.INV_PATTERN( 1 ),
96+
.POLY_LEN( 31 ),
97+
.POLY_TAP( 28 )
98+
) gen (
99+
.clk( clk200 ),
100+
.nrst( nrst_once ),
101+
.en( 1'b1 ),
102+
.data_in( {2{RandomNumber1[15:0]}} ),
103+
.data_out( d1[31:0] )
104+
);
105+
106+
prbs_gen_chk #(
107+
.WIDTH( 32 ),
108+
.CHK_MODE( 1 ),
109+
.INV_PATTERN( 1 ),
110+
.POLY_LEN( 31 ),
111+
.POLY_TAP( 28 )
112+
) checker (
113+
.clk( clk200 ),
114+
.nrst( nrst_once ),
115+
.en( 1'b1 ),
116+
.data_in( d1[31:0] ),
117+
.data_out( )
118+
);
119+
120+
121+
endmodule

0 commit comments

Comments
 (0)