Cell Relay Archive[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index][Thread Index][Author Index][Subject Index] Re: 8bit PRBS generation & BER Detection?
--a0000000000000000000000000000000
Content-Type: TEXT/PLAIN; charset=US-ASCII
Content-Transfer-Encoding: 7Bit
On Mon Nov 23 1998 novice@korea.com wrote:
>
> Hi,
>
> I'm implementing BER Tester.
> How can I generate PRBS code in BYTE size of O.151 & O.153, etc?
>
> And How can I detect Bit Error with BYTE boundary?
>
> Any Info will be very appreciated.
The attached test program might help ... it is a modification of one
that we have used to count the number of errors in data we received
from a DeskNet OC3port tester set up to send the 2^15-1 PRBS sequence.
In a real BER tester you will, of course, need to have resynchronization
logic which re-seeds the PRBS accumulator whenever the measured error
rate is too high (more than 10%, according to O.151). The attached test
program does not do this; it assumes the initial 32 bits of the received
sequence is correct and counts the number of errors in the remainder.
Cordially,
Mike
--
C. M. Heard/VVNET, Inc.
heard@vvnet.com
--a0000000000000000000000000000000
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
/* PRBS polynomials */
#define PRBS_2_23_1_POLYNOMIAL 0x00420000UL /* x^23 + x^18 + 1 */
#define PRBS_2_15_1_POLYNOMIAL 0x00006000UL /* x^15 + x^14 + 1 */
#define PRBS_2_11_1_POLYNOMIAL 0x00000500UL /* x^11 + x^9 + 1 */
#define PRBS_2_9_1_POLYNOMIAL 0x00000110UL /* x^9 + x^5 + 1 */
#define PRBS_2_6_1_POLYNOMIAL 0x00000030UL /* x^6 + x^5 + 1 */
/* table of matrix products used to update a 32-bit PRBS generator */
static unsigned long prbs_table [4] [256];
/* PRBS generator polarity mask */
static unsigned char polarity_mask;
/* table of weights for 8-bit bytes */
unsigned char weight[256];
/*
* Generate a parity check for a 32-bit word.
*/
static unsigned long
parity_check (unsigned long prbs_accum) {
unsigned long mask=1UL, parity=0UL;
int i;
for (i = 0; i < 32; ++i) {
parity ^= ((prbs_accum & mask) != 0UL);
mask <<= 1;
}
return parity;
}
/*
* Generate a table of matrix products to update a 32-bit PRBS generator.
*/
static void
gen_prbs_table (unsigned long polynomial) {
int i;
for (i = 0; i < 4; ++i) {
int j;
for (j = 0; j < 256; ++j) {
unsigned long prbs_accum = ((unsigned long)j << (i * 8));
int k;
for (k = 0; k < 8; ++k) {
prbs_accum = (prbs_accum << 1)
^ parity_check(prbs_accum & polynomial);
}
prbs_table[i][j] = (prbs_accum & 0xff);
}
}
}
/*
* Update a 32-bit PRBS generator eight bits at a time.
*/
static unsigned long
update_prbs (unsigned long prbs_accum) {
unsigned char acc_lsb = 0;
int i;
for (i = 0; i < 4; ++i ) {
acc_lsb ^= prbs_table [i] [ (prbs_accum >> (i * 8) ) & 0xff ];
}
return (prbs_accum << 8) ^ ((unsigned long)acc_lsb);
}
/*
* Generate the weight table.
*/
static void
gen_weight_table (void) {
int i;
for (i = 0; i < 256; ++i) {
unsigned char mask=1U, ones_count = 0U;
int j;
for (j = 0; j < 8; ++j) {
ones_count += ((i & mask) != 0U);
mask = mask << 1;
}
weight[i] = ones_count;
}
}
/*
* Count the number of errors in a block of received data.
*/
static unsigned long
error_count (unsigned char *rx_data, int rx_data_length)
{
unsigned long error_count = 0U;
unsigned long prbs_accum = 0U;
int i;
/* seed the PRBS accumulator */
for (i = 0; i < 4; ++i) {
prbs_accum = (prbs_accum << 8) ^ (rx_data[i] ^ polarity_mask);
}
/* check the received data */
for (i = 0; i < rx_data_length; ++i) {
unsigned char error_pattern =
(prbs_accum >> 24) ^ (rx_data[i] ^ polarity_mask);
if (error_pattern != 0U) {
error_count += weight[error_pattern];
}
prbs_accum = update_prbs(prbs_accum);
}
return error_count;
}
/* data received from Desknet OC3port set up to send 2^15-1 PRBS pattern */
static unsigned char received_data [] = {
0xeb, 0xff, 0x00, 0x01, 0xff, 0xfb, 0xff, 0xe7,
0xff, 0xaf, 0xfe, 0x1f, 0xfb, 0xbf, 0xe6, 0x7f,
0xaa, 0xfe, 0x01, 0xfb, 0xfb, 0xe7, 0xe7, 0xaf,
0xae, 0x1e, 0x1b, 0xbb, 0xa6, 0x66, 0x2a, 0xab,
0x00, 0x05, 0xff, 0xe3, 0xff, 0xb7, 0xfe, 0x4f,
0xfa, 0x5f, 0xe2, 0x3f, 0xb3, 0x7e, 0x54, 0xfa,
0x05, 0xe3, 0xe3, 0xb7, 0xb6, 0x4e, 0x4a, 0x5a,
0x42, 0x22, 0x73, 0x32, 0xd5, 0x51, 0x00, 0x19,
0xff, 0xab, 0xfe, 0x07, 0xfb, 0xef, 0xe7, 0x9f,
0xae, 0xbe, 0x18, 0x7b, 0xae, 0xe6, 0x19, 0xab,
0xaa, 0x06, 0x03, 0xeb, 0xf7, 0x87, 0xce, 0xef,
0x59, 0x9c, 0x2a, 0xb7, 0x00, 0x4d, 0xfe, 0x53,
0xfa, 0x17, 0xe3, 0x8f, 0xb6, 0xde, 0x49, 0x3a,
0x49, 0x62, 0x48, 0xb2, 0x4c, 0x52, 0x56, 0x12,
0x0b, 0x93, 0xc6, 0x97, 0x68, 0x8c, 0x8c, 0xd4,
0xd5, 0x05, 0x01, 0xe1, 0xfb, 0xbb, 0xe6, 0x67,
0xaa, 0xae, 0x00, 0x1b, 0xff, 0xa7, 0xfe, 0x2f,
0xfb, 0x1f, 0xe5, 0xbf, 0xa2, 0x7e, 0x32, 0xfb,
0x51, 0xe4, 0x1b, 0xa7, 0xa6, 0x2e, 0x2b, 0x1b,
0x05, 0xa5, 0xe2, 0x23, 0xb3, 0x36, 0x55, 0x4a,
0x00, 0x43, 0xfe, 0x77, 0xfa, 0xcf, 0xe1, 0x5f,
0xb8, 0x3e, 0x6f, 0x7a, 0x9c, 0xe0, 0xb5, 0xbc,
0x42, 0x76, 0x72, 0xca, 0xd1, 0x41, 0x18, 0x79,
0xae, 0xea, 0x19, 0x83, 0xaa, 0xf6, 0x01, 0xcb,
};
#include <stdio.h>
int
main (void) {
gen_prbs_table(PRBS_2_15_1_POLYNOMIAL);
polarity_mask = 0xff;
gen_weight_table();
printf(
"error count = %lu\n",
error_count(
received_data,
(sizeof received_data)/sizeof(unsigned char)
)
);
return 0;
}
--a0000000000000000000000000000000--
|
|