📄 atmrxsync.c
字号:
/***************************************************************************** * Copyright (c) 1999, 2000, 2001, 2002 C-Port Corporation, a Motorola Company * * All Rights Reserved * * * * The information contained in this file is C-Port Corporation confidential * * and proprietary. * * Any reproduction, use or disclosure, in whole or in part, of this * * program, including any attempt to obtain a human-readable version of this * * program, without the express, prior written consent of C-Port * * Corporation or Motorola Incorporated is strictly prohibited. * *****************************************************************************/#define RXSYNC#include "sdpUcode.h"#include "dcpRegistersCp.h"#include "rcSdpAtmApiIf.h"#include <stdio.h>#define RXSYNCCTL ((int) &((SdpRxCregs*)NULL)->rxCtl.sync)#define CellByteCnt Ireg0#define DeltaHdrCnt Ireg1#define AlphaHdrCnt Ireg2#define PayLdSkip Ireg3#define HdrBytes Ireg5/* ireg 6-9 are available */#define HEC_MAGIC_NO 0xAC#define crc10readHi Literal(1)#define crc10readLo Literal(0)/*********************************************************************** * RxSync Functionality: * * GENERAL: * This rxSync ucode runs the cell delineation state machine and its 3 * states. These include HUNT, PRESYNC and SYNC. When in HUNT, rxSync * is searching for a match of the magic number on every fifth byte received. * Once it receives a good HEC, it transitions to the PRESYNC state where * deltaCnt cells with good HEC must be received before transitioning to SYNC. * While in SYNC, rxSync will pass cells to the rxbyte processor. In * all other states, no cells are forwarded. The HEC field is overwritten with * the PayldSkip indicator indicating whether the cell is an idle or * an unassigned cell (00 00 00 00 or 00 00 00 01), whether the HEC is * bad or whether this is a good cell. The payload of the cell is not * forwarded for idle cells, unassigned cells or cells with a bad HEC. * Merge9 is passed to indicate the end of the cell or cell header without * payload being passed. Merge9 is sent with an additional byte after the * 5 byte header or 53 byte cell. So, in fact there are 6 bytes or 54 bytes * sent to rxbyte. If alphaCnt cells are received with bad HEC, * rxSync will transition to the HUNT state and stop forwarding cells. * * CRC-10 Checking for OAM: * While in SYNC, OAM CRC-10 is checked on all cells received other than idle * or HEC errored cells. The merge9 byte is transmitted at the after the * cell indicating whether the CRC-10 was valid or not. Note that CRC10 is * only valid for OAM cells even though CRC10 is checked on all cells received. * * FEATURES TO ADD: * 1. In B00, the rxSync processor can only receive bytes from the rxSONET * block once every 3 clocks (BUG 914). I believe this is only at OC12 * rates that this is a problem. * * 2. CRC10 will not work on receive in B00 or C00 (BUG 1027). This code * will not be tested on the hardware until D00 is available. ************************************************************************/voidSDPmain(){ Description = ("ATM Ucode for the SDP RX Sync Processor."); /************************************************************** * STATE: HUNT * * In the Hunt state we hunt for a valid HEC (Header CRC's). * This means that we read bytes in checking the HEC * CRC calculated over the 5 header bytes. If the hardware HEC * calculator returns the magic number (0xAC) we have a valid HEC. * At this point we think we have just seen our first valid cell * and transition to PRESYNC header. **************************************************************/LabelDef(HUNT_INIT); CregsAddrWrite(RXSYNCCTL + (int) &((RxSyncCtrlSpc*)NULL)->state); Branch(ALWAYS, Upc+1); Abus(Literal(0x00)); ALU(PassA); Pbus(ALUout); Actions(CregsWrite); Branch(ALWAYS, Upc+1); DCPSIM_MESSAGE(HUNT); CregsAddrWrite(RXSYNCCTL + (int) &((RxSyncCtrlSpc*)NULL)->deltaCnt); Branch (ALWAYS, Upc+1); /* Descrambling off, out of cell delineation */ Abus(IregsA(STATUSreg)); Bbus(Literal(DELINLOSS)); ALU(PassB); Actions(IregsAwrite + CregAddrIncr); Branch(ALWAYS, Upc+1); Abus(Creg); IregsA(DeltaHdrCnt); ALU(PassA); Actions(IregsAwrite); Branch(ALWAYS, Upc+1); Abus(Creg); IregsA(AlphaHdrCnt); ALU(PassA); Actions(IregsAwrite); Branch(ALWAYS, Upc+1);LabelDef(HUNT); IregInit(CellByteCnt, -ATM_CELL_HDR_SZ, UseAbus); Actions(HECinit); Branch(ALWAYS, Upc+1); Abus(Payload); ALU(PassA); Actions(UnloadFIFO + IregIncr(CellByteCnt) + RepeatUntil); Branch(AllOnes(CellByteCnt), Upc+1); Bbus(HEC); Abus(Literal(HEC_MAGIC_NO)); ALU(XOR); Branch(ALWAYS, Upc+1); Actions(InvertCondition); Branch(ALUzero, Label(HUNT)); /************************************************************** * STATE: PRESYNC * * In this state we ensure that we see n valid Cells * in a row. If not we transition back to the HUNT State. **************************************************************/LabelDef(PRESYNC_INIT); DCPSIM_MESSAGE(PRESYNC); IregInit(CellByteCnt, -ATM_CELL_PAYLD_SZ, UseAbus); Branch(ALWAYS, Upc+1);LabelDef(PRESYNC_PAYLOAD); Actions(UnloadFIFO + IregIncr(CellByteCnt) + RepeatUntil); Branch(AllOnes(CellByteCnt), Upc+1);LabelDef(PRESYNC_HDR); IregInit(CellByteCnt, -ATM_CELL_HDR_SZ, UseAbus); Actions(HECinit); Branch(ALWAYS, Upc+1); Actions(UnloadFIFO + IregIncr(CellByteCnt) + RepeatUntil); Branch(AllOnes(CellByteCnt), Upc+1); Bbus(HEC); Abus(Literal(HEC_MAGIC_NO)); ALU(XOR); Branch(ALWAYS, Upc+1); Actions(IregIncr(DeltaHdrCnt) + InvertCondition); Branch(ALUzero, Label(HUNT_INIT)); Actions(InvertCondition); Branch(AllOnes(DeltaHdrCnt), Label(PRESYNC_INIT)); IregInit(CellByteCnt, -ATM_CELL_PAYLD_SZ, UseAbus); Branch(ALWAYS, Upc+1); Actions(UnloadFIFO + IregIncr(CellByteCnt) + RepeatUntil); Branch(AllOnes(CellByteCnt), Upc+1); CregsAddrWrite(RXSYNCCTL + (int) &((RxSyncCtrlSpc*)NULL)->state); Branch(ALWAYS, Upc+1); DCPSIM_MESSAGE(CELL SYNCHRONIZATION OBTAINED); Abus(Literal(0xFF)); ALU(PassA); Pbus(ALUout); Actions(CregsWrite); Branch(ALWAYS, Upc+1); /************************************************************** * STATE: SYNC * * Once in the SYNC State we begin passing headers (and payload for * user cells) with appended status to the RxByte Processor. * We also turn off Loss of Cell Delineation (LCD). We allow alphaCnt * bad cells before returning to HUNT State. * **************************************************************/LabelDef(SYNC); DCPSIM_MESSAGE(SYNC); /* turn off both scrambling and lcd indicator */ Abus(IregsA(STATUSreg)); Bbus(Literal(0)); ALU(PassB); Actions(IregsAwrite); Branch(ALWAYS, Upc+1); IregInit(PayLdSkip, ~GOOD_HEC_CELL, UseAbus); Branch(ALWAYS, Upc+1); Abus(IregsA(HdrBytes)); Bbus(IregsB(HdrBytes)); ALU(XOR); Actions(IregsAwrite + HECinit); Branch(ALWAYS, Label(SYNC_READ_XFER));LabelDef(SYNC_ONLY); /* just stay in sync */ /* count = 5-1; HEC */ IregInit(CellByteCnt, -(ATM_CELL_HDR_SZ-1), UseAbus); Branch(ALWAYS, Upc+1); Actions(UnloadFIFO); Actions(IregIncr(CellByteCnt) + RepeatUntil); Branch(AllOnes(CellByteCnt), Label(SYNC_CRC_CHK)); /* Chew 4 bytes of Hdr, !HEC */LabelDef(SYNC_READ_XFER); IregInit(CellByteCnt, -(ATM_CELL_HDR_SZ-2), UseBbus); Branch(ALWAYS, Upc+1); Abus(IregsA(HdrBytes)); Bbus(Payload); ALU(OR); Pbus(Payload); Actions(IregsAwrite + UnloadFIFO + IregIncr(CellByteCnt) + RepeatUntil + DataOutValid); Branch(AllOnes(CellByteCnt), Upc+1); Abus(IregsA(HdrBytes)); Bbus(Payload); ALU(OR); Pbus(Payload); Actions(UnloadFIFO + IregsAwrite + InvertCondition + DataOutValid); Branch(ALUzero, Label(SYNC_CRC_CHK)); Branch(ALUzero, Label(IDLE_UNASSIGNED)); /* Unassigned Cell? */ Abus(IregsA(HdrBytes)); /* Idle Cell? */ Bbus(Literal(1)); ALU(XOR); Branch(ALWAYS, Upc+1); Actions(InvertCondition); Branch(ALUzero, Label(SYNC_CRC_CHK));LabelDef(IDLE_UNASSIGNED); DCPSIM_MESSAGE(IDLE_CELL); IregInit(PayLdSkip, ~IDLE_UA_CELL, UseAbus); Branch(ALWAYS, Upc+1);LabelDef(SYNC_CRC_CHK); CregsAddrWrite(RXSYNCCTL + (int) &((RxSyncCtrlSpc*)NULL)->alphaCnt); Actions(UnloadFIFO); Branch(ALWAYS, Upc+1); Bbus(HEC); Abus(Literal(HEC_MAGIC_NO)); ALU(XOR); Branch(ALWAYS, Upc+1); Branch(ALUzero, Label(REPLACE_HEC_W_STATUS_INIT)); /***************************************************************** * SYNC_BAD will increment our number of BAD CRCs after were in sync * and Jump to HUNT if we detect Alpha Loss Of Cell Delineation (LCD). * This will also set payload skip to indicate cell to be dropped *****************************************************************/LabelDef(SYNC_BAD); DCPSIM_MESSAGE(BAD_HEC); IregInit(PayLdSkip, ~BAD_HEC_CELL, UseAbus); Branch(ALWAYS, Upc+1); Abus(IregsA(AlphaHdrCnt)); ALU(PassA); Actions(IregIncr(AlphaHdrCnt)+InvertCondition); Branch(AllOnes(AlphaHdrCnt), Label(REPLACE_HEC_W_STATUS)); Abus(IregsA(PayLdSkip)); ALU(NotA); Pbus(ALUout); Actions(DataOutValid); Branch(ALWAYS, Upc+1); Abus(Literal(0xFF)); ALU(PassA); Pbus(ALUout); Actions(DataOutValid + Merge9); Branch(ALWAYS, Upc+1); Branch(ALWAYS, Label(HUNT_INIT)); /************************************************************** * STATE: REPLACE_HEC_W_STATUS * Signal Header to RxByte and append Status byte after HEC. **************************************************************/LabelDef(REPLACE_HEC_W_STATUS_INIT); Abus(Creg); /* Reset Alpha Counter. We can only get */ IregsA(AlphaHdrCnt); /* here if we had a good CRC */ ALU(PassA); Actions(IregsAwrite); Branch(ALWAYS, Upc+1);LabelDef(REPLACE_HEC_W_STATUS); Abus(IregsA(PayLdSkip)); ALU(NotA); Pbus(ALUout); Actions(DataOutValid); Branch(ALWAYS, Upc+1); /************************************************************** * STATE: PAYLOAD_PROCESS * * Drop through from above, or come from SYNC_BAD (where we want to * skip through the payload **************************************************************/LabelDef(PAYLOAD_PROCESS); Branch(AllOnes(PayLdSkip),Label(PAYLOAD_PROCESS_XFER)); Abus(Literal(0xCC)); ALU(PassA); Pbus(ALUout); Actions(DataOutValid + Merge9); Branch(ALWAYS, Upc+1);LabelDef(PAYLOAD_PROCESS_DROP); Abus(IregsA(STATUSreg)); /* turn on DESCRAM for payload */ Bbus(Literal(DESCRAM)); ALU(OR); Actions(IregsAwrite); Branch(ALWAYS, Upc+1); IregInit(CellByteCnt, -ATM_CELL_PAYLD_SZ, UseAbus); Branch(ALWAYS, Upc+1); Actions(UnloadFIFO + IregIncr(CellByteCnt) + RepeatUntil); Branch(AllOnes(CellByteCnt), Upc+1); /* chew through whole cell */ Branch(ALWAYS, Label(SYNC));LabelDef(PAYLOAD_PROCESS_XFER); Abus(IregsA(STATUSreg)); /* turn on DESCRAM for payload */ Bbus(Literal(DESCRAM)); ALU(OR); Actions(IregsAwrite); Branch(ALWAYS, Upc+1);LabelDef(PAYLOAD_LOOP); IregInit(CellByteCnt, -ATM_CELL_PAYLD_SZ, UseAbus); Actions(CRC10init); Branch(ALWAYS, Upc+1); Actions(UnloadFIFO + CRC10accum + IregIncr(CellByteCnt) + RepeatUntil); PayloadOut(FIFOout); Branch(AllOnes(CellByteCnt), Upc+1); /* chew through whole cell */ Branch(ALWAYS, Upc+1); /* Test the 10 bit CRC. Pass a single byte to the RxByte sequencer * which indicates the success/failure (0/-1) of the 10 bit CRC. * This is referenced by the RC on OAM cells, otherwise ignored. */ /* crc10readHigh has a 1-cycle latency to take affect */ crc10readHi; Branch(ALWAYS,Upc+1); /* Pass ms 2 bits of CRC through ALU - should be zero if CRC OK */ crc10readLo; Bbus(CRC10); ALU(PassB); Branch(ALWAYS,Upc+1); /* Pass ls 8 bits of CRC through ALU - should be zero if CRC OK */ /* Branch on ms 2 bits check */ Bbus(CRC10); ALU(PassB); BranchNot(ALUzero,Label(INDICATE_CRC10_BAD)); /* Branch on ms 2 bits check */ Branch(ALUzero,Label(INDICATE_CRC10_GOOD));LabelDef(INDICATE_CRC10_BAD); DCPSIM_MESSAGE(BAD_CRC10); Abus(Literal(BAD_CRC10)); ALU(PassA); Pbus(ALUout); Actions(DataOutValid + Merge9); Branch(ALWAYS, Upc+1); Branch(ALWAYS, Label(SYNC));LabelDef(INDICATE_CRC10_GOOD); DCPSIM_MESSAGE(GOOD_CRC10); Abus(Literal(GOOD_CRC10)); ALU(PassA); Pbus(ALUout); Actions(DataOutValid + Merge9); Branch(ALWAYS, Upc+1); Branch(ALWAYS, Label(SYNC));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -