Update repo

This commit is contained in:
2026-08-30 23:04:35 -07:00
parent 749dab5721
commit ce65a0f59a
14950 changed files with 4408250 additions and 1 deletions
@@ -0,0 +1,136 @@
//#############################################################################
//! \file source/common/C/crc/crc_16.c
//!
//! \brief 16-bit CRC
//#############################################################################
//!
//! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
//! All rights reserved not granted herein.
//! Limited License.
//!
//! Texas Instruments Incorporated grants a world-wide, royalty-free,
//! non-exclusive license under copyrights and patents it now or hereafter
//! owns or controls to make, have made, use, import, offer to sell and sell
//! ("Utilize") this software subject to the terms herein. With respect to the
//! foregoing patent license, such license is granted solely to the extent that
//! any such patent is necessary to Utilize the software alone. The patent
//! license shall not apply to any combinations which include this software,
//! other than combinations with devices manufactured by or for TI
//! ("TI Devices").
//! No hardware patent is licensed hereunder.
//!
//! Redistributions must preserve existing copyright notices and reproduce this
//! license (including the above copyright notice and the disclaimer and
//! (if applicable) source code license limitations below) in the documentation
//! and/or other materials provided with the distribution.
//!
//! Redistribution and use in binary form, without modification, are permitted
//! provided that the following conditions are met:
//!
//! * No reverse engineering, decompilation, or disassembly of this software is
//! permitted with respect to any software provided in binary form.
//! * Any redistribution and use are licensed by TI for use only
//! with TI Devices.
//! * Nothing shall obligate TI to provide you with source code for the
//! software licensed and provided to you in object code.
//!
//! If software source code is provided to you, modification and redistribution
//! of the source code are permitted provided that the following conditions
//! are met:
//!
//! * any redistribution and use of the source code, including any resulting
//! derivative works, are licensed by TI for use only with TI Devices.
//! * any redistribution and use of any object code compiled from the source
//! code and any resulting derivative works, are licensed by TI for use
//! only with TI Devices.
//!
//! Neither the name of Texas Instruments Incorporated nor the names of its
//! suppliers may be used to endorse or promote products derived from this
//! software without specific prior written permission.
//#############################################################################
//*****************************************************************************
// includes
//*****************************************************************************
#include "VCU2_CRC.h"
//*****************************************************************************
// defines
//*****************************************************************************
//*****************************************************************************
// globals
//*****************************************************************************
//*****************************************************************************
// function definitions
//*****************************************************************************
void CRC_run16BitTableLookupC(CRC_Handle hndCRC)
{
uint16_t i;
uint16_t tableIndex;
uint16_t parity = (uint16_t)hndCRC->parity;
uint16_t accumulator = hndCRC->seedValue;
uint16_t *pInputVector = (uint16_t *)hndCRC->pMsgBuffer;
uint16_t *pCrcTable = (uint16_t *)hndCRC->pCrcTable;
// The assumption is the message bytes are packed into 16-bit words
// and the calculation starts from either the high or low byte
// The memory arrangement is as follows:
// Address|_LB__|_HB__|
// 0x0000 |_D0L_|_D0H_|
// 0x0001 |_D1L_|_D1H_|
// 0x0002 |_D2L_|_D2H_|
// 0x0003 |_D3L_|_D3H_|
// 0x0004 |_D4L_|_D4H_|
// ...
for(i = 0; i < hndCRC->nMsgBytes; i++, parity++){
// __byte selects either the low(0) or high(1) byte in a word
// the initial selection provided by the enumeration parity
// the table index is calculated from the high byte of the accumulator
// XOR'd with the low and high bytes of each word in the input vector
tableIndex = (accumulator >> 8) ^ __byte((int *)pInputVector, parity);
accumulator = (accumulator << 8) ^ pCrcTable[tableIndex];
}
// Save the CRC result
hndCRC->crcResult = (uint32_t)accumulator;
}
void CRC_run16BitReflectedTableLookupC(CRC_Handle hndCRC)
{
uint16_t i;
uint16_t tableIndex;
uint16_t parity = (uint16_t)hndCRC->parity;
uint16_t accumulator = hndCRC->seedValue;
uint16_t *pInputVector = (uint16_t *)hndCRC->pMsgBuffer;
uint16_t *pCrcTable = (uint16_t *)hndCRC->pCrcTable;
// The assumption is the message bytes are packed into 16-bit words
// and the calculation starts from either the high or low byte
// The memory arrangement is as follows:
// Address|_LB__|_HB__|
// 0x0000 |_D0L_|_D0H_|
// 0x0001 |_D1L_|_D1H_|
// 0x0002 |_D2L_|_D2H_|
// 0x0003 |_D3L_|_D3H_|
// 0x0004 |_D4L_|_D4H_|
// ...
for(i = 0; i < hndCRC->nMsgBytes; i++, parity++){
// __byte selects either the low(0) or high(1) byte in a word
// the initial selection provided by the enumeration parity
// the table index is calculated from the low byte of the accumulator
// XOR'd with the low and high bytes of each word in the input vector
tableIndex = (accumulator & 0x00FF) ^ __byte((int *)pInputVector, parity);
accumulator = (accumulator >> 8) ^ pCrcTable[tableIndex];
}
// Save the CRC result
hndCRC->crcResult = (uint32_t)accumulator;
}
// End of file
@@ -0,0 +1,196 @@
//#############################################################################
//! \file source/common/C/crc/crc_16_alt.c
//!
//! \brief 16-bit CRC
//#############################################################################
//!
//! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
//! All rights reserved not granted herein.
//! Limited License.
//!
//! Texas Instruments Incorporated grants a world-wide, royalty-free,
//! non-exclusive license under copyrights and patents it now or hereafter
//! owns or controls to make, have made, use, import, offer to sell and sell
//! ("Utilize") this software subject to the terms herein. With respect to the
//! foregoing patent license, such license is granted solely to the extent that
//! any such patent is necessary to Utilize the software alone. The patent
//! license shall not apply to any combinations which include this software,
//! other than combinations with devices manufactured by or for TI
//! ("TI Devices").
//! No hardware patent is licensed hereunder.
//!
//! Redistributions must preserve existing copyright notices and reproduce this
//! license (including the above copyright notice and the disclaimer and
//! (if applicable) source code license limitations below) in the documentation
//! and/or other materials provided with the distribution.
//!
//! Redistribution and use in binary form, without modification, are permitted
//! provided that the following conditions are met:
//!
//! * No reverse engineering, decompilation, or disassembly of this software is
//! permitted with respect to any software provided in binary form.
//! * Any redistribution and use are licensed by TI for use only
//! with TI Devices.
//! * Nothing shall obligate TI to provide you with source code for the
//! software licensed and provided to you in object code.
//!
//! If software source code is provided to you, modification and redistribution
//! of the source code are permitted provided that the following conditions
//! are met:
//!
//! * any redistribution and use of the source code, including any resulting
//! derivative works, are licensed by TI for use only with TI Devices.
//! * any redistribution and use of any object code compiled from the source
//! code and any resulting derivative works, are licensed by TI for use
//! only with TI Devices.
//!
//! Neither the name of Texas Instruments Incorporated nor the names of its
//! suppliers may be used to endorse or promote products derived from this
//! software without specific prior written permission.
//#############################################################################
//*****************************************************************************
// includes
//*****************************************************************************
#include "VCU0_CRC.h"
// Generate the CRC lookup table using the polynomial 0x8005
//
// \param none
//
// This function is to generate the CRC16 table for every possible byte
// i.e. 2^8 = 256 table values, using the CRC16_802_15_4 polynomial 0x8005. It
// expects a global array, crc16p1_table, to be defined in the application
// code
//
// \return none
//
void genCRC16P1Table(void)
{
int i, j;
unsigned long poly, c;
/* terms of polynomial defining this crc (except x^16): */
//static const byte p[] = {0,2,15};
static const int p[] = {0,2,15};
/* make exclusive-or pattern from polynomial (0x1021) */
poly = 0L;
for ( i = 0; i < sizeof( p ) / sizeof( int ); i++ )
{
poly |= 1L << p[i];
}
for ( i = 0; i < 256; i++ )
{
c = i << 8;
for ( j = 0; j < 8; j++ )
{
c = ( c & 0x8000 ) ? poly ^ ( c << 1 ) : ( c << 1 );
}
crc16p1_table[i] = (unsigned int) c;
}
}
// Generate the CRC lookup table using the polynomial 0x1021
//
// \param none
//
// This function is to generate the CRC16 table for every possible byte
// i.e. 2^8 = 256 table values, using the CRC16_ALT polynomial 0x1021. It
// expects a global array, crc16p2_table, to be defined in the application
// code
//
// \return none
//
void genCRC16P2Table(void)
{
int i, j;
unsigned long poly, c;
/* terms of polynomial defining this crc (except x^16): */
//static const byte p[] = {0,5,12};
static const int p[] = {0,5,12};
/* make exclusive-or pattern from polynomial (0x1021) */
poly = 0L;
for ( i = 0; i < sizeof( p ) / sizeof( int ); i++ )
{
poly |= 1L << p[i];
}
for ( i = 0; i < 256; i++ )
{
c = i << 8;
for ( j = 0; j < 8; j++ )
{
c = ( c & 0x8000 ) ? poly ^ ( c << 1 ) : ( c << 1 );
}
crc16p2_table[i] = (unsigned int) c;
}
}
// C- function to get the 16-bit CRC
//
// \param The initial value of crc, in case the message has been
// chopped into several parts, you can use the crc16 of the previous
// segment as the init value for the current segment crc16 calculation
// until the final crc is derived.
// \param Address of the message buffer
// \param Parity of the first message byte, i.e. whether its on an even
// or odd address
// \param Length of the message in bytes
//
// Calculate the 16-bit CRC of a message buffer by using the lookup table,
// crc16p1_table based on the polynomial 0x8005
//
// \return CRC result
//
uint16 getCRC16P1_cpu (uint16 input_crc16_accum, uint16 * msg, CRC_parity_e parity,
uint16 rxLen)
{
uint16 crc16_accum = input_crc16_accum;
SINT16 *pdata = (SINT16 *)msg;
uint16 i, j = 0;
for (j=0; j<rxLen; j++, parity++)
{
i = (crc16_accum >> 8) ^ __byte(pdata, parity);
crc16_accum = (crc16_accum << 8) ^ crc16p1_table[i];
}
return (uint16)crc16_accum;
}
// C- function to get the 16-bit CRC
//
// \param The initial value of crc, in case the message has been
// chopped into several parts, you can use the crc16 of the previous
// segment as the init value for the current segment crc16 calculation
// until the final crc is derived.
// \param Address of the message buffer
// \param Parity of the first message byte, i.e. whether its on an even
// or odd address
// \param Length of the message in bytes
//
// Calculate the 16-bit CRC of a message buffer by using the lookup table,
// crc16p2_table based on the polynomial 0x1021
//
// \return CRC result
//
uint16 getCRC16P2_cpu (uint16 input_crc16_accum, uint16 * msg, CRC_parity_e parity,
uint16 rxLen)
{
uint16 crc16_accum = input_crc16_accum;
SINT16 *pdata = (SINT16 *)msg;
uint16 i, j = 0;
for (j=0; j<rxLen; j++, parity++)
{
i = (crc16_accum >> 8) ^ __byte(pdata, parity);
crc16_accum = (crc16_accum << 8) ^ crc16p2_table[i];
}
return (uint16)crc16_accum;
}
// End of file
@@ -0,0 +1,134 @@
//#############################################################################
//! \file source/common/C/crc/crc_24.c
//!
//! \brief 24-bit CRC
//#############################################################################
//!
//! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
//! All rights reserved not granted herein.
//! Limited License.
//!
//! Texas Instruments Incorporated grants a world-wide, royalty-free,
//! non-exclusive license under copyrights and patents it now or hereafter
//! owns or controls to make, have made, use, import, offer to sell and sell
//! ("Utilize") this software subject to the terms herein. With respect to the
//! foregoing patent license, such license is granted solely to the extent that
//! any such patent is necessary to Utilize the software alone. The patent
//! license shall not apply to any combinations which include this software,
//! other than combinations with devices manufactured by or for TI
//! ("TI Devices").
//! No hardware patent is licensed hereunder.
//!
//! Redistributions must preserve existing copyright notices and reproduce this
//! license (including the above copyright notice and the disclaimer and
//! (if applicable) source code license limitations below) in the documentation
//! and/or other materials provided with the distribution.
//!
//! Redistribution and use in binary form, without modification, are permitted
//! provided that the following conditions are met:
//!
//! * No reverse engineering, decompilation, or disassembly of this software is
//! permitted with respect to any software provided in binary form.
//! * Any redistribution and use are licensed by TI for use only
//! with TI Devices.
//! * Nothing shall obligate TI to provide you with source code for the
//! software licensed and provided to you in object code.
//!
//! If software source code is provided to you, modification and redistribution
//! of the source code are permitted provided that the following conditions
//! are met:
//!
//! * any redistribution and use of the source code, including any resulting
//! derivative works, are licensed by TI for use only with TI Devices.
//! * any redistribution and use of any object code compiled from the source
//! code and any resulting derivative works, are licensed by TI for use
//! only with TI Devices.
//!
//! Neither the name of Texas Instruments Incorporated nor the names of its
//! suppliers may be used to endorse or promote products derived from this
//! software without specific prior written permission.
//#############################################################################
//*****************************************************************************
// includes
//*****************************************************************************
#include "VCU2_CRC.h"
//*****************************************************************************
// defines
//*****************************************************************************
//*****************************************************************************
// globals
//*****************************************************************************
//*****************************************************************************
// function definitions
//*****************************************************************************
void CRC_run24BitTableLookupC(CRC_Handle hndCRC)
{
uint16_t i;
uint32_t tableIndex;
uint16_t parity = hndCRC->parity;
uint32_t accumulator = hndCRC->seedValue;
uint32_t *pInputVector = (uint32_t *)hndCRC->pMsgBuffer;
uint32_t *pCrcTable = (uint32_t *)hndCRC->pCrcTable;
// The assumption is the message bytes are packed into 32-bit words
// and the calculation starts from either the high or low byte
// The memory arrangement is as follows:
// Address|_LB__|_HB__|
// 0x0000 |_D01_|_D02_|
// 0x0001 |_D03_|_D04_|
// 0x0002 |_D11_|_D12_|
// 0x0003 |_D13_|_D14_|
// 0x0004 |_D21_|_D22_|
// ...
for(i = 0; i < hndCRC->nMsgBytes; i++, parity++){
// __byte selects either the low(0) or high(1) byte in a word
// the initial selection provided by the enumeration parity
// the table index is calculated from the high byte of the accumulator
// XOR'd with the low and high bytes of each word in the input vector
// High byte of [23:0] of the Accumulator after bitwise ANDing with 0x00FFFFFF
tableIndex = ((accumulator & 0x00FFFFFF)>> 16) ^ __byte((int *)pInputVector, parity);
accumulator = (accumulator << 8) ^ pCrcTable[tableIndex];
}
// Save the CRC result
hndCRC->crcResult = (uint32_t)accumulator & 0x00FFFFFF;
}
void CRC_run24BitReflectedTableLookupC(CRC_Handle hndCRC)
{
uint16_t i;
uint32_t tableIndex;
uint16_t parity = hndCRC->parity;
uint32_t accumulator = hndCRC->seedValue;
uint32_t *pInputVector = (uint32_t *)hndCRC->pMsgBuffer;
uint32_t *pCrcTable = (uint32_t *)hndCRC->pCrcTable;
// The assumption is the message bytes are packed into 32-bit words
// and the calculation starts from either the high or low byte
// The memory arrangement is as follows:
// Address|_LB__|_HB__|
// 0x0000 |_D01_|_D02_|
// 0x0001 |_D03_|_D04_|
// 0x0002 |_D11_|_D12_|
// 0x0003 |_D13_|_D14_|
// 0x0004 |_D21_|_D22_|
// ...
for(i = 0; i < hndCRC->nMsgBytes; i++, parity++){
// __byte selects either the low(0) or high(1) byte in a word
// the initial selection provided by the enumeration parity
// the table index is calculated from the low byte of the accumulator
// XOR'd with the low and high bytes of each word in the input vector
tableIndex = (accumulator & 0x000000FF) ^ __byte((int *)pInputVector, parity);
accumulator = ((accumulator >> 8) ^ pCrcTable[tableIndex]);
}
// Save the CRC result
hndCRC->crcResult = (uint32_t)accumulator;
}
// End of file
@@ -0,0 +1,133 @@
//#############################################################################
//! \file source/common/C/crc/crc_32.c
//!
//! \brief 32-bit CRC
//#############################################################################
//!
//! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
//! All rights reserved not granted herein.
//! Limited License.
//!
//! Texas Instruments Incorporated grants a world-wide, royalty-free,
//! non-exclusive license under copyrights and patents it now or hereafter
//! owns or controls to make, have made, use, import, offer to sell and sell
//! ("Utilize") this software subject to the terms herein. With respect to the
//! foregoing patent license, such license is granted solely to the extent that
//! any such patent is necessary to Utilize the software alone. The patent
//! license shall not apply to any combinations which include this software,
//! other than combinations with devices manufactured by or for TI
//! ("TI Devices").
//! No hardware patent is licensed hereunder.
//!
//! Redistributions must preserve existing copyright notices and reproduce this
//! license (including the above copyright notice and the disclaimer and
//! (if applicable) source code license limitations below) in the documentation
//! and/or other materials provided with the distribution.
//!
//! Redistribution and use in binary form, without modification, are permitted
//! provided that the following conditions are met:
//!
//! * No reverse engineering, decompilation, or disassembly of this software is
//! permitted with respect to any software provided in binary form.
//! * Any redistribution and use are licensed by TI for use only
//! with TI Devices.
//! * Nothing shall obligate TI to provide you with source code for the
//! software licensed and provided to you in object code.
//!
//! If software source code is provided to you, modification and redistribution
//! of the source code are permitted provided that the following conditions
//! are met:
//!
//! * any redistribution and use of the source code, including any resulting
//! derivative works, are licensed by TI for use only with TI Devices.
//! * any redistribution and use of any object code compiled from the source
//! code and any resulting derivative works, are licensed by TI for use
//! only with TI Devices.
//!
//! Neither the name of Texas Instruments Incorporated nor the names of its
//! suppliers may be used to endorse or promote products derived from this
//! software without specific prior written permission.
//#############################################################################
//*****************************************************************************
// includes
//*****************************************************************************
#include "VCU2_CRC.h"
//*****************************************************************************
// defines
//*****************************************************************************
//*****************************************************************************
// globals
//*****************************************************************************
//*****************************************************************************
// function definitions
//*****************************************************************************
void CRC_run32BitTableLookupC(CRC_Handle hndCRC)
{
uint16_t i;
uint32_t tableIndex;
uint16_t parity = hndCRC->parity;
uint32_t accumulator = hndCRC->seedValue;
uint32_t *pInputVector = (uint32_t *)hndCRC->pMsgBuffer;
uint32_t *pCrcTable = (uint32_t *)hndCRC->pCrcTable;
// The assumption is the message bytes are packed into 32-bit words
// and the calculation starts from either the high or low byte
// The memory arrangement is as follows:
// Address|_LB__|_HB__|
// 0x0000 |_D01_|_D02_|
// 0x0001 |_D03_|_D04_|
// 0x0002 |_D11_|_D12_|
// 0x0003 |_D13_|_D14_|
// 0x0004 |_D21_|_D22_|
// ...
for(i = 0; i < hndCRC->nMsgBytes; i++, parity++){
// __byte selects either the low(0) or high(1) byte in a word
// the initial selection provided by the enumeration parity
// the table index is calculated from the high byte of the accumulator
// XOR'd with the low and high bytes of each word in the input vector
tableIndex = (accumulator >> 24) ^ __byte((int *)pInputVector, parity);
accumulator = (accumulator << 8) ^ pCrcTable[tableIndex];
}
// Save the CRC result
hndCRC->crcResult = (uint32_t)accumulator;
}
void CRC_run32BitReflectedTableLookupC(CRC_Handle hndCRC)
{
uint16_t i;
uint32_t tableIndex;
uint16_t parity = hndCRC->parity;
uint32_t accumulator = hndCRC->seedValue;
uint32_t *pInputVector = (uint32_t *)hndCRC->pMsgBuffer;
uint32_t *pCrcTable = (uint32_t *)hndCRC->pCrcTable;
// The assumption is the message bytes are packed into 32-bit words
// and the calculation starts from either the high or low byte
// The memory arrangement is as follows:
// Address|_LB__|_HB__|
// 0x0000 |_D01_|_D02_|
// 0x0001 |_D03_|_D04_|
// 0x0002 |_D11_|_D12_|
// 0x0003 |_D13_|_D14_|
// 0x0004 |_D21_|_D22_|
// ...
for(i = 0; i < hndCRC->nMsgBytes; i++, parity++){
// __byte selects either the low(0) or high(1) byte in a word
// the initial selection provided by the enumeration parity
// the table index is calculated from the high byte of the accumulator
// XOR'd with the low and high bytes of each word in the input vector
tableIndex = (accumulator & 0x000000FF) ^ __byte((int *)pInputVector, parity);
accumulator = (accumulator >> 8) ^ pCrcTable[tableIndex];
}
// Save the CRC result
hndCRC->crcResult = (uint32_t)accumulator;
}
// End of file
@@ -0,0 +1,131 @@
//#############################################################################
//! \file source/common/C/crc/crc_32_alt.c
//!
//! \brief 32-bit CRC
//
// o CRC implementation is based on tables. If the tables
// are calculated on the fly, the macro GEN_CRC_TABLES shall be defined
// and genCRC32Tables() shall be called during
// initialization. If the macro is not defined, pre-calculated tables will
// will be used. Using the latter option can put the tables to flash.
//
//#############################################################################
//!
//! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
//! All rights reserved not granted herein.
//! Limited License.
//!
//! Texas Instruments Incorporated grants a world-wide, royalty-free,
//! non-exclusive license under copyrights and patents it now or hereafter
//! owns or controls to make, have made, use, import, offer to sell and sell
//! ("Utilize") this software subject to the terms herein. With respect to the
//! foregoing patent license, such license is granted solely to the extent that
//! any such patent is necessary to Utilize the software alone. The patent
//! license shall not apply to any combinations which include this software,
//! other than combinations with devices manufactured by or for TI
//! ("TI Devices").
//! No hardware patent is licensed hereunder.
//!
//! Redistributions must preserve existing copyright notices and reproduce this
//! license (including the above copyright notice and the disclaimer and
//! (if applicable) source code license limitations below) in the documentation
//! and/or other materials provided with the distribution.
//!
//! Redistribution and use in binary form, without modification, are permitted
//! provided that the following conditions are met:
//!
//! * No reverse engineering, decompilation, or disassembly of this software is
//! permitted with respect to any software provided in binary form.
//! * Any redistribution and use are licensed by TI for use only
//! with TI Devices.
//! * Nothing shall obligate TI to provide you with source code for the
//! software licensed and provided to you in object code.
//!
//! If software source code is provided to you, modification and redistribution
//! of the source code are permitted provided that the following conditions
//! are met:
//!
//! * any redistribution and use of the source code, including any resulting
//! derivative works, are licensed by TI for use only with TI Devices.
//! * any redistribution and use of any object code compiled from the source
//! code and any resulting derivative works, are licensed by TI for use
//! only with TI Devices.
//!
//! Neither the name of Texas Instruments Incorporated nor the names of its
//! suppliers may be used to endorse or promote products derived from this
//! software without specific prior written permission.
//#############################################################################
//*****************************************************************************
// includes
//*****************************************************************************
#include "VCU0_CRC.h"
// Generate the CRC lookup table using the polynomial 0x04c11db7
//
// \param none
//
// This function is to generate the CRC32 table for every possible byte
// i.e. 2^8 = 256 table values, using the CRC32_PRIME polynomial 0x04c11db7.
// It expects a global array, crc32_table, to be defined in the application
// code
//
// \return none
//
void genCRC32Table()
/* generate the table of CRC remainders for all possible bytes */
{
register uint16 i, j;
register uint32 crc32_accum;
for ( i = 0; i < 256; i++ )
{
// myindex = i;
crc32_accum = ( (uint32) i << 24 );
for ( j = 0; j < 8; j++ )
{
if ( crc32_accum & 0x80000000L )
crc32_accum = ( crc32_accum << 1 ) ^ POLYNOMIAL32;
else
crc32_accum = ( crc32_accum << 1 );
}
crc32_table[i] = crc32_accum;
}
}
// C- function to get the 32-bit CRC
//
// \param The initial value of crc, in case the message has been
// chopped into several parts, you can use the crc32 of the previous
// segment as the init value for the current segment crc32 calculation
// until the final crc is derived.
// \param Address of the message buffer
// \param Parity of the first message byte, i.e. whether its on an even
// or odd address
// \param Length of the message in bytes
//
// Calculate the 32-bit CRC of a message buffer by using the lookup table,
// crc32_table based on the polynomial 0x04c11db7
//
// \return CRC result
//
uint32 getCRC32_cpu (uint32 input_crc32_accum, uint16 * msg, CRC_parity_e parity,
uint16 rxLen)
{
register uint16 i;
register uint16 j;
uint32 crc32_accum;
SINT16 *pdata;
crc32_accum = input_crc32_accum;
pdata = (SINT16 *) msg;
for (j = 0; j < rxLen; j++, parity++)
{
i = ( crc32_accum >> 24 ) ^ (__byte(pdata, parity));
crc32_accum = ( crc32_accum << 8 ) ^ crc32_table[i];
}
return crc32_accum;
}
// End of file
@@ -0,0 +1,101 @@
//#############################################################################
//! \file source/common/C/crc/crc_8.c
//!
//! \brief 8-bit CRC
//#############################################################################
//!
//! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
//! All rights reserved not granted herein.
//! Limited License.
//!
//! Texas Instruments Incorporated grants a world-wide, royalty-free,
//! non-exclusive license under copyrights and patents it now or hereafter
//! owns or controls to make, have made, use, import, offer to sell and sell
//! ("Utilize") this software subject to the terms herein. With respect to the
//! foregoing patent license, such license is granted solely to the extent that
//! any such patent is necessary to Utilize the software alone. The patent
//! license shall not apply to any combinations which include this software,
//! other than combinations with devices manufactured by or for TI
//! ("TI Devices").
//! No hardware patent is licensed hereunder.
//!
//! Redistributions must preserve existing copyright notices and reproduce this
//! license (including the above copyright notice and the disclaimer and
//! (if applicable) source code license limitations below) in the documentation
//! and/or other materials provided with the distribution.
//!
//! Redistribution and use in binary form, without modification, are permitted
//! provided that the following conditions are met:
//!
//! * No reverse engineering, decompilation, or disassembly of this software is
//! permitted with respect to any software provided in binary form.
//! * Any redistribution and use are licensed by TI for use only
//! with TI Devices.
//! * Nothing shall obligate TI to provide you with source code for the
//! software licensed and provided to you in object code.
//!
//! If software source code is provided to you, modification and redistribution
//! of the source code are permitted provided that the following conditions
//! are met:
//!
//! * any redistribution and use of the source code, including any resulting
//! derivative works, are licensed by TI for use only with TI Devices.
//! * any redistribution and use of any object code compiled from the source
//! code and any resulting derivative works, are licensed by TI for use
//! only with TI Devices.
//!
//! Neither the name of Texas Instruments Incorporated nor the names of its
//! suppliers may be used to endorse or promote products derived from this
//! software without specific prior written permission.
//#############################################################################
//*****************************************************************************
// includes
//*****************************************************************************
#include "VCU2_CRC.h"
//*****************************************************************************
// defines
//*****************************************************************************
//*****************************************************************************
// globals
//*****************************************************************************
//*****************************************************************************
// function definitions
//*****************************************************************************
void CRC_run8BitTableLookupC(CRC_Handle hndCRC)
{
uint32_t i;
uint16_t tableIndex;
uint16_t accumulator = hndCRC->seedValue;
uint16_t parity = (uint16_t)hndCRC->parity;
uint16_t *pInputVector = (uint16_t *)hndCRC->pMsgBuffer;
uint16_t *pCrcTable = (uint16_t *)hndCRC->pCrcTable;
// The assumption is the message bytes are packed into 16-bit words
// and the calculation starts from from either the high or low byte
// The memory arrangement is as follows
// Address|__LB__|__HB__|
// 0x0000 |__D0__|__D1__|
// 0x0001 |__D2__|__D3__|
// 0x0002 |__D4__|__D5__|
// 0x0003 |__D6__|__D7__|
// 0x0004 |__D8__|__D9__|
// ...
for(i = 0; i < hndCRC->nMsgBytes; i++, parity++){
// __byte selects either the low(0) or high(1) byte in a word
// the initial selection provided by the enumeration parity
tableIndex = accumulator ^ __byte((int *)pInputVector, parity);
accumulator = pCrcTable[tableIndex];
}
// Save the CRC result
hndCRC->crcResult = (uint32_t)(accumulator & 0x00FF);
}
// End of file
@@ -0,0 +1,131 @@
//#############################################################################
//! \file source/common/C/crc/crc_8_alt.c
//!
//! \brief 8-bit CRC
//
// o CRC implementation is based on tables. If the tables
// are calculated on the fly, the macro GEN_CRC_TABLES shall be defined
// and genCRC8Tables() shall be called during
// initialization. If the macro is not defined, pre-calculated tables will
// will be used. Using the latter option can put the tables to flash.
//#############################################################################
//!
//! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
//! All rights reserved not granted herein.
//! Limited License.
//!
//! Texas Instruments Incorporated grants a world-wide, royalty-free,
//! non-exclusive license under copyrights and patents it now or hereafter
//! owns or controls to make, have made, use, import, offer to sell and sell
//! ("Utilize") this software subject to the terms herein. With respect to the
//! foregoing patent license, such license is granted solely to the extent that
//! any such patent is necessary to Utilize the software alone. The patent
//! license shall not apply to any combinations which include this software,
//! other than combinations with devices manufactured by or for TI
//! ("TI Devices").
//! No hardware patent is licensed hereunder.
//!
//! Redistributions must preserve existing copyright notices and reproduce this
//! license (including the above copyright notice and the disclaimer and
//! (if applicable) source code license limitations below) in the documentation
//! and/or other materials provided with the distribution.
//!
//! Redistribution and use in binary form, without modification, are permitted
//! provided that the following conditions are met:
//!
//! * No reverse engineering, decompilation, or disassembly of this software is
//! permitted with respect to any software provided in binary form.
//! * Any redistribution and use are licensed by TI for use only
//! with TI Devices.
//! * Nothing shall obligate TI to provide you with source code for the
//! software licensed and provided to you in object code.
//!
//! If software source code is provided to you, modification and redistribution
//! of the source code are permitted provided that the following conditions
//! are met:
//!
//! * any redistribution and use of the source code, including any resulting
//! derivative works, are licensed by TI for use only with TI Devices.
//! * any redistribution and use of any object code compiled from the source
//! code and any resulting derivative works, are licensed by TI for use
//! only with TI Devices.
//!
//! Neither the name of Texas Instruments Incorporated nor the names of its
//! suppliers may be used to endorse or promote products derived from this
//! software without specific prior written permission.
//#############################################################################
//*****************************************************************************
// includes
//*****************************************************************************
#include "VCU0_CRC.h"
// Generate the CRC lookup table using the polynomial 0x7
//
// \param none
//
// This function is to generate the CRC8 table for every possible byte
// i.e. 2^8 = 256 table values, using the CRC8_PRIME polynomial 0x07. It
// expects a global array, crc8_table, to be defined in the application
// code
//
// \return none
//
void genCRC8Table()
{
register uint16 i;
register uint16 j;
register uint16 crc8_accum;
for ( i = 0; i < 256; i++ )
{
crc8_accum = i;
for ( j = 0; j < 8; j++ )
{
if ( crc8_accum & 0x80L )
crc8_accum = ( (crc8_accum << 1) & 0xff ) ^ POLYNOMIAL8;
else
crc8_accum = ( crc8_accum << 1 ) & 0xff;
}
crc8_table[i] = crc8_accum;
}
}
// C- function to get the 8-bit CRC
//
// \param The initial value of crc, in case the message has been
// chopped into several parts, you can use the crc8 of the previous
// segment as the init value for the current segment crc8 calculation
// until the final crc is derived.
// \param Address of the message buffer
// \param Parity of the first message byte, i.e. whether its on an even
// or odd address
// \param Length of the message in bytes
//
// Calculate the 8-bit CRC of a message buffer by using the lookup table,
// crc8_table to get the CRC of each byte.
//
// \return CRC result
//
uint16 getCRC8_cpu (uint16 input_crc8_accum, uint16 * msg, CRC_parity_e parity,
uint16 rxLen)
{
register uint16 i;
register uint16 j;
uint16 crc8_accum;
SINT16 *pdata;
crc8_accum = input_crc8_accum;
pdata = (SINT16 *)msg;
for (j = 0; j < rxLen; j++, parity++)
{
i = crc8_accum ^ (__byte(pdata, parity));
crc8_accum = crc8_table[i];
}
return (uint16)crc8_accum;
}
// End of file
@@ -0,0 +1,77 @@
//#############################################################################
//! \file source/common/C/crc/crc_flip.c
//!
//! \brief Flip 16b input buffer
//#############################################################################
//!
//! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
//! All rights reserved not granted herein.
//! Limited License.
//!
//! Texas Instruments Incorporated grants a world-wide, royalty-free,
//! non-exclusive license under copyrights and patents it now or hereafter
//! owns or controls to make, have made, use, import, offer to sell and sell
//! ("Utilize") this software subject to the terms herein. With respect to the
//! foregoing patent license, such license is granted solely to the extent that
//! any such patent is necessary to Utilize the software alone. The patent
//! license shall not apply to any combinations which include this software,
//! other than combinations with devices manufactured by or for TI
//! ("TI Devices").
//! No hardware patent is licensed hereunder.
//!
//! Redistributions must preserve existing copyright notices and reproduce this
//! license (including the above copyright notice and the disclaimer and
//! (if applicable) source code license limitations below) in the documentation
//! and/or other materials provided with the distribution.
//!
//! Redistribution and use in binary form, without modification, are permitted
//! provided that the following conditions are met:
//!
//! * No reverse engineering, decompilation, or disassembly of this software is
//! permitted with respect to any software provided in binary form.
//! * Any redistribution and use are licensed by TI for use only
//! with TI Devices.
//! * Nothing shall obligate TI to provide you with source code for the
//! software licensed and provided to you in object code.
//!
//! If software source code is provided to you, modification and redistribution
//! of the source code are permitted provided that the following conditions
//! are met:
//!
//! * any redistribution and use of the source code, including any resulting
//! derivative works, are licensed by TI for use only with TI Devices.
//! * any redistribution and use of any object code compiled from the source
//! code and any resulting derivative works, are licensed by TI for use
//! only with TI Devices.
//!
//! Neither the name of Texas Instruments Incorporated nor the names of its
//! suppliers may be used to endorse or promote products derived from this
//! software without specific prior written permission.
//#############################################################################
//*****************************************************************************
// includes
//*****************************************************************************
#include "VCU0_CRC.h"
//*****************************************************************************
// defines
//*****************************************************************************
//*****************************************************************************
// globals
//*****************************************************************************
//*****************************************************************************
// function definitions
//*****************************************************************************
#pragma FUNC_ALWAYS_INLINE(flipInputBuf_cpu)
void flipInputBuf_cpu (uint16 *dst, uint16 *src, uint16 rxLen){
uint16 i;
for ( i = 0; i < rxLen; i++ )
{
*dst++ = __flip16(*src++);
}
}
// End of file
@@ -0,0 +1,113 @@
//#############################################################################
//! \file source/common/C/crc/crc_util.c
//!
//! \brief Utility routines for CRC calculations
//#############################################################################
//!
//! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
//! All rights reserved not granted herein.
//! Limited License.
//!
//! Texas Instruments Incorporated grants a world-wide, royalty-free,
//! non-exclusive license under copyrights and patents it now or hereafter
//! owns or controls to make, have made, use, import, offer to sell and sell
//! ("Utilize") this software subject to the terms herein. With respect to the
//! foregoing patent license, such license is granted solely to the extent that
//! any such patent is necessary to Utilize the software alone. The patent
//! license shall not apply to any combinations which include this software,
//! other than combinations with devices manufactured by or for TI
//! ("TI Devices").
//! No hardware patent is licensed hereunder.
//!
//! Redistributions must preserve existing copyright notices and reproduce this
//! license (including the above copyright notice and the disclaimer and
//! (if applicable) source code license limitations below) in the documentation
//! and/or other materials provided with the distribution.
//!
//! Redistribution and use in binary form, without modification, are permitted
//! provided that the following conditions are met:
//!
//! * No reverse engineering, decompilation, or disassembly of this software is
//! permitted with respect to any software provided in binary form.
//! * Any redistribution and use are licensed by TI for use only
//! with TI Devices.
//! * Nothing shall obligate TI to provide you with source code for the
//! software licensed and provided to you in object code.
//!
//! If software source code is provided to you, modification and redistribution
//! of the source code are permitted provided that the following conditions
//! are met:
//!
//! * any redistribution and use of the source code, including any resulting
//! derivative works, are licensed by TI for use only with TI Devices.
//! * any redistribution and use of any object code compiled from the source
//! code and any resulting derivative works, are licensed by TI for use
//! only with TI Devices.
//!
//! Neither the name of Texas Instruments Incorporated nor the names of its
//! suppliers may be used to endorse or promote products derived from this
//! software without specific prior written permission.
//#############################################################################
//*****************************************************************************
// includes
//*****************************************************************************
#include "VCU2_CRC.h"
//*****************************************************************************
// defines
//*****************************************************************************
//*****************************************************************************
// globals
//*****************************************************************************
//*****************************************************************************
// function definitions
//*****************************************************************************
uint32_t CRC_bitReflect(uint32_t valToReverse,int16_t bitWidth)
{
int16_t i,j,p,t;
uint32_t pattern, skip;
//unsigned int a, b;
uint32_t value = valToReverse;
//Determine what power of 2 bitWidth is
t = bitWidth; p = 0;
while(t > 1){
t = t >> 1;
p++;
}
//Start the reversing process
for(i = 0; i < p; i++){
//Increment skip
skip = CRC_pow2(i);
//Initialize pattern
pattern = 0xFFFFFFFF;
//First generate the pattern for the switch
for(j = 0; j < (bitWidth/skip)-1; j++){
pattern ^= (pattern << skip);
}
//Make the switch
//a = ((value & pattern) << skip);
//b = ((value >> skip) & pattern);
//value = a | b;
value = (((value & pattern) << skip) | ((value >> skip) & pattern));
}
return value;
}
uint16_t CRC_pow2(uint16_t power)
{
if (power == 0){
return 1;
}else{
return(2 * CRC_pow2(--power));
}
}
// End of file
@@ -0,0 +1,162 @@
//#############################################################################
//! /file source/reference/C/interleaver/interleaver.c
//!
//! \brief Interleaver
// \author Smart Grid Group
//#############################################################################
//!
//! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
//! All rights reserved not granted herein.
//! Limited License.
//!
//! Texas Instruments Incorporated grants a world-wide, royalty-free,
//! non-exclusive license under copyrights and patents it now or hereafter
//! owns or controls to make, have made, use, import, offer to sell and sell
//! ("Utilize") this software subject to the terms herein. With respect to the
//! foregoing patent license, such license is granted solely to the extent that
//! any such patent is necessary to Utilize the software alone. The patent
//! license shall not apply to any combinations which include this software,
//! other than combinations with devices manufactured by or for TI
//! ("TI Devices").
//! No hardware patent is licensed hereunder.
//!
//! Redistributions must preserve existing copyright notices and reproduce this
//! license (including the above copyright notice and the disclaimer and
//! (if applicable) source code license limitations below) in the documentation
//! and/or other materials provided with the distribution.
//!
//! Redistribution and use in binary form, without modification, are permitted
//! provided that the following conditions are met:
//!
//! * No reverse engineering, decompilation, or disassembly of this software is
//! permitted with respect to any software provided in binary form.
//! * Any redistribution and use are licensed by TI for use only
//! with TI Devices.
//! * Nothing shall obligate TI to provide you with source code for the
//! software licensed and provided to you in object code.
//!
//! If software source code is provided to you, modification and redistribution
//! of the source code are permitted provided that the following conditions
//! are met:
//!
//! * any redistribution and use of the source code, including any resulting
//! derivative works, are licensed by TI for use only with TI Devices.
//! * any redistribution and use of any object code compiled from the source
//! code and any resulting derivative works, are licensed by TI for use
//! only with TI Devices.
//!
//! Neither the name of Texas Instruments Incorporated nor the names of its
//! suppliers may be used to endorse or promote products derived from this
//! software without specific prior written permission.
//#############################################################################
//*****************************************************************************
// includes
//*****************************************************************************
#include "interleaver.h"
//*****************************************************************************
// defines
//*****************************************************************************
#define MAX_NUM_TONES_IN_SYMBOL 72
#define MAX_NUM_ILV_SYMBS 511 // G3 PLC -> FCC band
#define BITS_PER_SYMBOL 3
//*****************************************************************************
// globals
//*****************************************************************************
const uint16_t INTERLEAVER_subCarrierParams[MAX_NUM_TONES_IN_SYMBOL][4] = {
#include "interleaverSubCarrierParams.h"
};
const uint16_t INTERLEAVER_symbolParams[MAX_NUM_ILV_SYMBS * BITS_PER_SYMBOL][2] = {
#include "interleaverSymbolParams.h"
};
//*****************************************************************************
// function definitions
//*****************************************************************************
// \brief Finds the interleaver parameters
//
// \param hndInterleaver pointer to the interleaver object
// \param[in] n number of symbols
// \param[in] m number of sub-carriers
//
void INTERLEAVER_findParams(INTERLEAVER_Handle hndInterleaver,
uint16_t n,
uint16_t m)
{
// Locals
int16_t tbl_offset;
hndInterleaver->m_i = INTERLEAVER_subCarrierParams[m - 1][0];
hndInterleaver->m_j = INTERLEAVER_subCarrierParams[m - 1][1];
hndInterleaver->a = INTERLEAVER_subCarrierParams[m - 1][2];
hndInterleaver->u = INTERLEAVER_subCarrierParams[m - 1][3];
hndInterleaver->m = m;
hndInterleaver->n = n;
// LUT starts from symbol 4
tbl_offset = hndInterleaver->n - 4;
if (tbl_offset < 0){
tbl_offset = 0;
}
hndInterleaver->n_i = INTERLEAVER_symbolParams[tbl_offset][0] >> 8;
hndInterleaver->n_j = INTERLEAVER_symbolParams[tbl_offset][0] & 0xFF;
hndInterleaver->b = INTERLEAVER_symbolParams[tbl_offset][1];
hndInterleaver->v = hndInterleaver->b * hndInterleaver->n_i;
hndInterleaver->offset = 0;
}
// \brief Runs the Interleaver
//
// Generates interleaved bits for data
//
// \param hndInterleaver pointer to the interleaver object
// \param[in] in_p pointer to the input buffer
// \param[in] out_p pointer to the output buffer
// \param[in] symb number of sub-carriers
//
void INTERLEAVER_run(INTERLEAVER_Handle hndInterleaver,
uint16_t *in_p, uint16_t *out_p,
uint16_t symb)
{
uint16_t ii, wordLoc, bitLoc, wordVal;
uint16_t n, m, i, j, vii, b, v, a, u, muJ, inLoc, offset;
uint16_t bJmodn;
uint16_t yy;
n = hndInterleaver->n;
b = hndInterleaver->b;
v = hndInterleaver->v;
m = hndInterleaver->m;
a = (hndInterleaver->a) << 4;
u = hndInterleaver->u;
offset = hndInterleaver->offset;
muJ = (m - ((long)__rpt_subcu((long)u * symb, m, 15) >> 16))<<4;
bJmodn = n + ((long)__rpt_subcu((long)b * symb, n, 15) >> 16);
yy = muJ;
for (ii = 0; ii < m; ii++){//ii is I
// I=ii, J=symb
// i = (a*I-u*J)%m = (a*I+m-uJ)%m
// j = (b*J-v*ii)%n
//
// a*ii+m-uJ < 4096 or 12 bits
i = ((long)__rpt_subcu((long)yy, m, 11) >> 16);
yy += a;
vii = ((long)__rpt_subcu(((long)v * i), n, 15) >> 16);
// bJmodn+n-vii < 1024 or 10 bits
j = ((long)__rpt_subcu((bJmodn - vii)<<6, n, 9) >> 16);
inLoc = i + j * m + offset; // QPSK and 8PSK could roll over
// compute the bit location
wordLoc = inLoc >> 4;
bitLoc = inLoc - (wordLoc << 4);
wordVal = *(in_p+wordLoc);
// save the bit to the interleaver output buffer
*out_p++ = (wordVal >> bitLoc) & 0x1;
}
}
// End of file
@@ -0,0 +1,126 @@
//#############################################################################
//! \file /interleaver/interleaverSubCarrierParams.h
//!
//! \brief Interleaver Parameters for Tones, m_i, m_j, a, u
//
//#############################################################################
//!
//! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
//! All rights reserved not granted herein.
//! Limited License.
//!
//! Texas Instruments Incorporated grants a world-wide, royalty-free,
//! non-exclusive license under copyrights and patents it now or hereafter
//! owns or controls to make, have made, use, import, offer to sell and sell
//! ("Utilize") this software subject to the terms herein. With respect to the
//! foregoing patent license, such license is granted solely to the extent that
//! any such patent is necessary to Utilize the software alone. The patent
//! license shall not apply to any combinations which include this software,
//! other than combinations with devices manufactured by or for TI
//! ("TI Devices").
//! No hardware patent is licensed hereunder.
//!
//! Redistributions must preserve existing copyright notices and reproduce this
//! license (including the above copyright notice and the disclaimer and
//! (if applicable) source code license limitations below) in the documentation
//! and/or other materials provided with the distribution.
//!
//! Redistribution and use in binary form, without modification, are permitted
//! provided that the following conditions are met:
//!
//! * No reverse engineering, decompilation, or disassembly of this software is
//! permitted with respect to any software provided in binary form.
//! * Any redistribution and use are licensed by TI for use only
//! with TI Devices.
//! * Nothing shall obligate TI to provide you with source code for the
//! software licensed and provided to you in object code.
//!
//! If software source code is provided to you, modification and redistribution
//! of the source code are permitted provided that the following conditions
//! are met:
//!
//! * any redistribution and use of the source code, including any resulting
//! derivative works, are licensed by TI for use only with TI Devices.
//! * any redistribution and use of any object code compiled from the source
//! code and any resulting derivative works, are licensed by TI for use
//! only with TI Devices.
//!
//! Neither the name of Texas Instruments Incorporated nor the names of its
//! suppliers may be used to endorse or promote products derived from this
//! software without specific prior written permission.
//#############################################################################
{ 1, 1, 1, 1}, // 1
{ 3, 5, 3, 15}, // 2
{ 4, 5, 4, 20}, // 3
{ 3, 1, 3, 3}, // 4
{ 3, 4, 2, 8}, // 5
{ 5, 1, 5, 5}, // 6
{ 3, 4, 5, 20}, // 7
{ 3, 5, 3, 15}, // 8
{ 4, 5, 7, 35}, // 9
{ 3, 7, 7, 49}, //10
{ 3, 4, 4, 16}, //11
{ 5, 7, 5, 35}, //12
{ 3, 4, 9, 36}, //13
{ 3, 5, 5, 25}, //14
{ 4, 7, 4, 28}, //15
{ 3, 5, 11, 55}, //16
{ 3, 4, 6, 24}, //17
{ 5, 7, 11, 77}, //18
{ 3, 4, 13, 52}, //19
{ 3, 7, 7, 49}, //20
{ 4, 5, 16, 80}, //21
{ 3, 5, 15, 75}, //22
{ 3, 4, 8, 32}, //23
{ 5, 7, 5, 35}, //24
{ 3, 4, 17, 68}, //25
{ 3, 5, 9, 45}, //26
{ 4, 5, 7, 35}, //27
{ 3, 5, 19, 95}, //28
{ 3, 4, 10, 40}, //29
{ 7,11, 13, 143}, //30
{ 3, 4, 21, 84}, //31
{ 3, 5, 11, 55}, //32
{ 4, 5, 25, 125}, //33
{ 3, 5, 23, 115}, //34
{ 3, 4, 12, 48}, //35
{ 5, 7, 29, 203}, //36
{ 3, 4, 25, 100}, //37
{ 3, 5, 13, 65}, //38
{ 4, 5, 10, 50}, //39
{ 3, 7, 27, 189}, //40
{ 3, 4, 14, 56}, //41
{ 5,11, 17, 187}, //42
{ 3, 4, 29, 116}, //43
{ 3, 5, 15, 75}, //44
{ 4, 7, 34, 238}, //45
{ 3, 5, 31, 155}, //46
{ 3, 4, 16, 64}, //47
{ 5, 7, 29, 203}, //48
{ 3, 4, 33, 132}, //49
{ 3, 7, 17, 119}, //50
{ 4, 5, 13, 65}, //51
{ 3, 5, 35, 175}, //52
{ 3, 4, 18, 72}, //53
{ 5, 7, 11, 77}, //54
{ 3, 4, 37, 148}, //55
{ 3, 5, 19, 95}, //56
{ 4, 5, 43, 215}, //57
{ 3, 5, 39, 195}, //58
{ 3, 4, 20, 80}, //59
{ 7,11, 43, 473}, //60
{ 3, 4, 41, 164}, //61
{ 3, 5, 21, 105}, //62
{ 4, 5, 16, 80}, //63
{ 3, 5, 43, 215}, //64
{ 3, 4, 22, 88}, //65
{ 5, 7, 53, 371}, //66
{ 3, 4, 45, 180}, //67
{ 3, 5, 23, 115}, //68
{ 4, 5, 52, 260}, //69
{ 3, 9, 47, 423}, //70
{ 3, 4, 24, 96}, //71
{ 5, 7, 29, 203}, //72
// End of file
@@ -0,0 +1,209 @@
//#############################################################################
//! /file source/reference/C/reed_solomon/reed_solomon_enc.c
//!
//! \brief Reed-Solomon Encoder
//#############################################################################
//!
//! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
//! All rights reserved not granted herein.
//! Limited License.
//!
//! Texas Instruments Incorporated grants a world-wide, royalty-free,
//! non-exclusive license under copyrights and patents it now or hereafter
//! owns or controls to make, have made, use, import, offer to sell and sell
//! ("Utilize") this software subject to the terms herein. With respect to the
//! foregoing patent license, such license is granted solely to the extent that
//! any such patent is necessary to Utilize the software alone. The patent
//! license shall not apply to any combinations which include this software,
//! other than combinations with devices manufactured by or for TI
//! ("TI Devices").
//! No hardware patent is licensed hereunder.
//!
//! Redistributions must preserve existing copyright notices and reproduce this
//! license (including the above copyright notice and the disclaimer and
//! (if applicable) source code license limitations below) in the documentation
//! and/or other materials provided with the distribution.
//!
//! Redistribution and use in binary form, without modification, are permitted
//! provided that the following conditions are met:
//!
//! * No reverse engineering, decompilation, or disassembly of this software is
//! permitted with respect to any software provided in binary form.
//! * Any redistribution and use are licensed by TI for use only
//! with TI Devices.
//! * Nothing shall obligate TI to provide you with source code for the
//! software licensed and provided to you in object code.
//!
//! If software source code is provided to you, modification and redistribution
//! of the source code are permitted provided that the following conditions
//! are met:
//!
//! * any redistribution and use of the source code, including any resulting
//! derivative works, are licensed by TI for use only with TI Devices.
//! * any redistribution and use of any object code compiled from the source
//! code and any resulting derivative works, are licensed by TI for use
//! only with TI Devices.
//!
//! Neither the name of Texas Instruments Incorporated nor the names of its
//! suppliers may be used to endorse or promote products derived from this
//! software without specific prior written permission.
//#############################################################################
//*****************************************************************************
// includes
//*****************************************************************************
#include "reedsolomon_encoder.h"
//*****************************************************************************
// defines
//*****************************************************************************
//*****************************************************************************
// globals
//*****************************************************************************
//*****************************************************************************
// Local function prototypes
//*****************************************************************************
static inline int16_t GF_add(int16_t op1, int16_t op2);
static inline int16_t GF_mult(int16_t op1, int16_t op2,
int16_t *pRS_expTable, int16_t *pRS_logTable,
uint16_t n );
//*****************************************************************************
// function definitions
//*****************************************************************************
// \brief Initializes the Reed Solomon Encoder object
//
// \param[in] hndRSEncoder handle to the Reed Solomon Encoder object
// \param[in] pGenPolyIdx pointer to the code generator polynomial (Index Form)
// \param[in] pRS_expTable pointer to the lookup table that converts index to decimal form
// \param[in] pRS_logTable pointer to the lookup table that converts decimal to index form
// \param[in] pRoots Pointer to the roots, \f$a^{b_{0}+i},/ i = [1, n-k-1]\f$
//
void REEDSOLOMON_ENCODER_init(REEDSOLOMON_ENCODER_Handle hndRSEncoder,
int16_t *pGenPolyIdx,
int16_t *pRS_expTable,
int16_t *pRS_logTable)
{
hndRSEncoder -> n = RS_BLOCK_N;
hndRSEncoder -> k = RS_BLOCK_K;
hndRSEncoder -> t = RS_BLOCK_T;
hndRSEncoder -> pGenPolyIdx = pGenPolyIdx;
hndRSEncoder -> pRS_expTable = pRS_expTable;
hndRSEncoder -> pRS_logTable = pRS_logTable;
}
// \brief Runs the Reed Solomon Encoder
//
// A pipelined version of polynomial division
//
// \param[in] hndRSEncoder handle to the Reed Solomon Encoder object
// \param pData pointer to the original message or data
// \param[in] nBytes number of bytes in the input message
//
void REEDSOLOMON_ENCODER_run(REEDSOLOMON_ENCODER_Handle hndRSEncoder,
int16_t *pData, int16_t nBytes)
{
int16_t i, j, temp, T, dataByte, multiplier;
int16_t *pGenPolyEnd, *pGenPolyIter;
int16_t R[2*RS_BLOCK_T]; // Remainder from polynomial division
int16_t *pR;
T = 2*(hndRSEncoder->t);
pGenPolyEnd = &(hndRSEncoder->pGenPolyIdx[T-1]);
// Reset all the remainder symbols
for(i = 0; i < T; i++){
R[i] = 0;
}
// Iterate through all bytes of the message
for( i = 0; i < nBytes; i++){
#if WORD_2BYTES
dataByte = __byte((int *)pData, i);
#else
dataByte = pData[i];
#endif //WORD_2BYTES
multiplier = GF_add(dataByte, R[T-1]);
if(multiplier == 0){
for(j = T-1; j > 0; j--){
R[j] = R[j-1];
}
R[0] = 0;
}else{
//Convert multiplier to index form
multiplier = hndRSEncoder->pRS_logTable[multiplier];
pGenPolyIter = pGenPolyEnd;
for( j = T-1; j > 0; j--){
// Multiply the generator polynomial by the multiplier
// in index form
// \f[ \alpha^{a} \alpha^{b} = \alpha^{a+b % n} \f]
temp = GF_mult(multiplier, *pGenPolyIter--,
hndRSEncoder->pRS_expTable,
hndRSEncoder->pRS_logTable,
hndRSEncoder->n);
R[j] = GF_add(R[j-1], temp);
}
temp = GF_mult(multiplier, *pGenPolyIter--,
hndRSEncoder->pRS_expTable,
hndRSEncoder->pRS_logTable,
hndRSEncoder->n);
R[0] = temp;
}
}
//Attach n-k remainder symobols to the message
pR = &R[T-1];
for( i = 0; i < T; i++){
#if WORD_2BYTES
__byte((int *)pData, nBytes + i) = *pR--;
#else
pData[i + nBytes] = *pR--;
#endif
}
}
// \brief Galois Field Addition
//
// Addition or subtraction in GF(2) binary and GF(2^m) extenstion fields
// are equivalent and can be carried out through a simple XOR operation
// \param[in] op1 First operand in decimal form
// \param[in] op2 Second operand in decimal form
// \return Sum (or difference) of the two operands using GF arithmetic in
// decimal form
//
static inline int16_t GF_add(int16_t op1, int16_t op2)
{
return ( op1 ^ op2);
}
// \brief Galois Field Multiplication
//
// \f[ \alpha^{a}.\alpha^{b} = \alpha^{(a+b)% 2^{m}-1}\f]
// We will use the index form of the operands to do the multiplication.
//
// \param[in] op1 First operand in index form
// \param[in] op2 Second operand in index form (usually the polynomial coefficients)
// \param[in] pRS_expTable pointer to the lookup table that translates index to
// decimal form
// \param[in] pRS_logTable pointer to the lookup table that translates decimal to
// index form
// \param[in] Block size \f$ n = 2^{m}-1 \f$
// \return product of the two operands using GF arithmetic in decimal form
//
static inline int16_t GF_mult(int16_t op1, int16_t op2,
int16_t *pRS_expTable, int16_t *pRS_logTable,
uint16_t n )
{
uint32_t tmp, tmp1;
tmp = op1 + op2;
// The __rpt_subcu intrinsic translates to RPT || SUBCU ACC, loc16 instruction
// The SUBCU will shift the ACC left by 1 and then subtract loc16 << 16 from it
// This is equivalent to an unsigned mod operation, it leaves the remainder in
// AH and the quotient in AL
tmp1 = __rpt_subcu((tmp) << 14, n, 1);
return(pRS_expTable[tmp1 >> 16]);
}
// End of file
@@ -0,0 +1,239 @@
//#############################################################################
//! \file source/common/C/viterbi/viterbi_cnv_enc.c
//!
//! \brief Viterbi Convolutional Encoders
//#############################################################################
//!
//! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
//! All rights reserved not granted herein.
//! Limited License.
//!
//! Texas Instruments Incorporated grants a world-wide, royalty-free,
//! non-exclusive license under copyrights and patents it now or hereafter
//! owns or controls to make, have made, use, import, offer to sell and sell
//! ("Utilize") this software subject to the terms herein. With respect to the
//! foregoing patent license, such license is granted solely to the extent that
//! any such patent is necessary to Utilize the software alone. The patent
//! license shall not apply to any combinations which include this software,
//! other than combinations with devices manufactured by or for TI
//! ("TI Devices").
//! No hardware patent is licensed hereunder.
//!
//! Redistributions must preserve existing copyright notices and reproduce this
//! license (including the above copyright notice and the disclaimer and
//! (if applicable) source code license limitations below) in the documentation
//! and/or other materials provided with the distribution.
//!
//! Redistribution and use in binary form, without modification, are permitted
//! provided that the following conditions are met:
//!
//! * No reverse engineering, decompilation, or disassembly of this software is
//! permitted with respect to any software provided in binary form.
//! * Any redistribution and use are licensed by TI for use only
//! with TI Devices.
//! * Nothing shall obligate TI to provide you with source code for the
//! software licensed and provided to you in object code.
//!
//! If software source code is provided to you, modification and redistribution
//! of the source code are permitted provided that the following conditions
//! are met:
//!
//! * any redistribution and use of the source code, including any resulting
//! derivative works, are licensed by TI for use only with TI Devices.
//! * any redistribution and use of any object code compiled from the source
//! code and any resulting derivative works, are licensed by TI for use
//! only with TI Devices.
//!
//! Neither the name of Texas Instruments Incorporated nor the names of its
//! suppliers may be used to endorse or promote products derived from this
//! software without specific prior written permission.
//#############################################################################
//*****************************************************************************
// includes
//*****************************************************************************
#include "viterbi_encoder.h"
//*****************************************************************************
// defines
//*****************************************************************************
//*****************************************************************************
// globals
//*****************************************************************************
//*****************************************************************************
// function definitions
//*****************************************************************************
//
// \brief Initialize the encoder structure by zeroing out the delay line
// \param hndVITEncoder Handle to the Viterbi Encoder Structure
//
void VITERBI_ENCODER_init(VITERBI_ENCODER_Handle hndVITEncoder)
{
int16_t i;
for(i = 0; i < MAX_CNV_ENC_DELAY_LEN; i++){
hndVITEncoder->delay[0] = 0;
}
}
//
// \brief This function performs convolution encoding in prime. It uses
// constraint length of K=7, and code rate 1/2.
//
// The polynomials are:
// G0 = 1 + D2 + D3
// G1 = 1 + D + D2 + D3
//
// It calculates:
// c(2k )=u(k)+u(k-2)+u(k-3)
// c(2k+1)=u(k)+u(k-1)+u(k-2)+u(k-3)
//
// \param hndVITEncoder handle to the Viterbi encoder object whose elements are
// nBits - number of input bits for decode
// u_p - pointer to input uncoded bits
// c_p - pointer to output coded bits
// (It produces 2xnBit bits)
//
void VITERBI_ENCODER_runK4CR12(VITERBI_ENCODER_Handle hndVITEncoder)
{
uint16_t *c_p, *u_p, *d_p, *uu_p, tmp;
int16_t i;
u_p = hndVITEncoder->u_p;
c_p = hndVITEncoder->c_p;
d_p = &hndVITEncoder->delay[0];
c_p[0] = (u_p[0] ^ d_p[1] ^ d_p[0]);
c_p[1] = (u_p[0] ^ d_p[2] ^ d_p[1] ^ d_p[0]);
c_p[2] = (u_p[1] ^ d_p[1] ^ d_p[0]);
c_p[3] = (u_p[1] ^ u_p[0] ^ d_p[1] ^ d_p[0]);
c_p[4] = (u_p[2] ^ u_p[0] ^ d_p[0]);
c_p[5] = (u_p[2] ^ u_p[1] ^ u_p[0] ^ d_p[0]);
c_p = &c_p[6];
uu_p = u_p;
for(i=3; i < hndVITEncoder->nBits; i++)
{
tmp = uu_p[3] ^ uu_p[1] ^ uu_p[0];
*c_p++ = tmp;
*c_p++ = tmp ^ uu_p[2];
uu_p++;
}
/* Update delays */
u_p += (hndVITEncoder->nBits - K7_CNV_ENC_DELAY_LEN);
for (i=0; i<K7_CNV_ENC_DELAY_LEN; i++)
*d_p++ = *u_p++;
}
//
// \brief This function performs convolution encoding in prime. It uses
// constraint length of K=7, and code rate 1/2.
//
// The polynomials are:
// G0 = 1 + D + D2 +D3 + D6
// G1 = 1 + D2 + D3 + D5 + D6
//
// It calculates:
// c(2k )=u(k)+u(k-1)+u(k-2)+u(k-3)+u(k-6)
// c(2k+1)=u(k)+u(k-2)+u(k-3)+u(k-5)+u(k-6)
//
// \param hndVITEncoder handle to the Viterbi encoder object whose elements are
// nBits - number of input bits for decode
// u_p - pointer to input uncoded bits
// c_p - pointer to output coded bits
// (It produces 2xnBit bits)
//
void VITERBI_ENCODER_runK7CR12(VITERBI_ENCODER_Handle hndVITEncoder)
{
uint16_t *c_p, *u_p, *d_p, *uu_p, tmp;
int16_t i;
u_p = hndVITEncoder->u_p;
c_p = hndVITEncoder->c_p;
d_p = &hndVITEncoder->delay[0];
c_p[0] = (u_p[0] ^ d_p[5] ^ d_p[4] ^ d_p[3] ^ d_p[0]);
c_p[1] = (u_p[0] ^ d_p[4] ^ d_p[3] ^ d_p[1] ^ d_p[0]);
c_p[2] = (u_p[1] ^ u_p[0] ^ d_p[5] ^ d_p[4] ^ d_p[1]);
c_p[3] = (u_p[1] ^ d_p[5] ^ d_p[4] ^ d_p[2] ^ d_p[1]);
c_p[4] = (u_p[2] ^ u_p[1] ^ u_p[0] ^ d_p[5] ^ d_p[2]);
c_p[5] = (u_p[2] ^ u_p[0] ^ d_p[5] ^ d_p[3] ^ d_p[2]);
c_p[6] = (u_p[3] ^ u_p[2] ^ u_p[1] ^ u_p[0] ^ d_p[3]);
c_p[7] = (u_p[3] ^ u_p[1] ^ u_p[0] ^ d_p[4] ^ d_p[3]);
c_p[8] = (u_p[4] ^ u_p[3] ^ u_p[2] ^ u_p[1] ^ d_p[4]);
c_p[9] = (u_p[4] ^ u_p[2] ^ u_p[1] ^ d_p[5] ^ d_p[4]);
c_p[10] = (u_p[5] ^ u_p[4] ^ u_p[3] ^ u_p[2] ^ d_p[5]);
c_p[11] = (u_p[5] ^ u_p[3] ^ u_p[2] ^ u_p[0] ^ d_p[5]);
c_p = &c_p[12];
uu_p = u_p;
for(i=6; i < hndVITEncoder->nBits; i++)
{
tmp = uu_p[6] ^ uu_p[4] ^ uu_p[3] ^ uu_p[0];
*c_p++ = tmp ^ uu_p[5];
*c_p++ = tmp ^ uu_p[1];
uu_p++;
}
/* Update delays */
u_p += (hndVITEncoder->nBits - K4_CNV_ENC_DELAY_LEN);
for (i=0; i<K4_CNV_ENC_DELAY_LEN; i++)
*d_p++ = *u_p++;
}
//
// \brief Quantization of Encoder Bits
// \param hndVITEncoder handle to the Viterbi encoder object whose elements are
// nBits - number of input bits to be quantized
// c_p - pointer to output coded bits
// \param format power of 2, the bits will be quantized to +-(2^format)
//
void VITERBI_ENCODER_quantizeBits(VITERBI_ENCODER_Handle hndVITEncoder, int16_t format)
{
int16_t i;
int16_t value;
value = 1 << format;
/* quantize */
for (i=0; i<(hndVITEncoder->nBits * hndVITEncoder->cr); i++)
{
if (hndVITEncoder->c_p[i] == 0)
hndVITEncoder->c_p[i] = value;
else
hndVITEncoder->c_p[i] = -value;
}
}
//
// \breif Word Unpacking to Bits
// \param[in] nSize number of 16-bits words
// \param[in] in_p pointer to input data in 16-bit words
// \param[out] out_p pointer to output data in bits
//
void VITERBI_ENCODER_blockUnpack2Bits(uint16_t nSize, uint16_t *in_p, uint16_t *out_p)
{
int16_t i;
uint16_t data;
for (i=0; i<(nSize << 1); i++)
{
data = __byte((int *)in_p, i);
*out_p++ = (data >> 7) & 0x1;
*out_p++ = (data >> 6) & 0x1;
*out_p++ = (data >> 5) & 0x1;
*out_p++ = (data >> 4) & 0x1;
*out_p++ = (data >> 3) & 0x1;
*out_p++ = (data >> 2) & 0x1;
*out_p++ = (data >> 1) & 0x1;
*out_p++ = (data ) & 0x1;
}
}
// End of file
@@ -0,0 +1,414 @@
;;###############################################################################
;;! \file /crc/vcrc_configpoly_asm.asm
;;!
;;! \brief Generic polynomial CRC calculation for byte wise and bitwise data
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;*****************************************************************************
;; global defines
;;*****************************************************************************
;; CRC Routine defines
;; Argument structure defines
SEEDVAL_OFFSET .set 0
NBYTES_OFFSET .set 2
PARITY_OFFSET .set 3
CRCRESULT_OFFSET .set 4
MSGBUFFER_OFFSET .set 6
NBITS_OFFSET .set 10
POLYNOMIAL_OFFSET .set 12
PSIZE_OFFSET .set 14
DSIZE_OFFSET .set 15
REFLECTED_OFFSET .set 16
LOCAL_FRAME_SIZE .set 4
VRX_BASE .set 0
VCRC_OFFSET .set 2
ARG_OFFSET .set 4
;;*****************************************************************************
;; macros
;;*****************************************************************************
;;
;; MACRO : 'CRC_CONTEXT_SAVE'
;; SIZE : Number of WORDS/Number of Cycles 6
;; USAGE : Called on entry into CRC routine
;;
CRC_CONTEXT_SAVE .macro
PUSH XAR0
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #LOCAL_FRAME_SIZE ; allocate stack space for local frame
VMOV32 *-SP[VRX_BASE+VCRC_OFFSET], VCRC ; save VCRC to stack
.endm
;;
;; MACRO : 'CRC_CONTEXT_RESTORE'
;; SIZE : Number of WORDS/Number of Cycles 6
;; USAGE : Called on exit from CRC routine
;;
CRC_CONTEXT_RESTORE .macro
VMOV32 VCRC, *-SP[VRX_BASE+VCRC_OFFSET]
SUBB SP, #LOCAL_FRAME_SIZE ; deallocate stack space for local frame
POP XAR3
POP XAR2
POP XAR1
POP XAR0
.endm
.if __TI_EABI__
.asg CRC_init16Bit, _CRC_init16Bit
.asg CRC_init32Bit, _CRC_init32Bit
.asg CRC_runConfigPolyBits, _CRC_runConfigPolyBits
.asg CRC_runConfigPolyBytes, _CRC_runConfigPolyBytes
.asg CRC_runConfigPolyBitsReflected, _CRC_runConfigPolyBitsReflected
.asg CRC_runConfigPolyBytesReflected, _CRC_runConfigPolyBytesReflected
.endif
;;*****************************************************************************
;; globals
;;*****************************************************************************
.global _CRC_init16Bit
.global _CRC_init32Bit
.global _CRC_runConfigPolyBits
.global _CRC_runConfigPolyBytes
.global _CRC_runConfigPolyBitsReflected
.global _CRC_runConfigPolyBytesReflected
;;*****************************************************************************
;; function definitions
;;*****************************************************************************
.text
;;*****************************************************************************
;;
;; \brief Calculate the n-bit CRC using Generic CRC polynomial using functions
;; _CRC_runConfigPolyBytes and _CRC_runConfigPolyBits
;; \param Handle to the structure, CRC_Obj(passed in XAR4)
;; - *+XAR4[0]: uint32_t seedValue -> Initial value of the CRC calculation
;; - *+XAR4[2]: uint32_t nMsgBytes -> the number of bytes in the message buffer
;; - *+XAR4[3]: Parity_e parity -> the location, in a word, of the first byte of the CRC calculation
;; - *+XAR4[4]: uint32_t crcResult -> the calculated CRC
;; - *+XAR4[6]: void *pMsgBuffer -> Pointer to the message buffer
;; - *+XAR4[8]: void *pCrcTable -> Pointer to the CRC lookup table
;; - *+XAR4[10]: uint32_t nMsgBits -> provde the data size in bits if the CRC is to be computed bitwise
;; - *+XAR4[12]: uint32_t polynomial -> added to ensure customized polynomial can be added by the user
;; - *+XAR4[14]; uint32_t polySize -> provide the polynomial size for the customized polynomial
;; PolySize - Polynomial size - size of of 1 bit - indicated by programming a value of 0x0
;; Polynomial size - size of of 32bits - indicated by programming a value of 0x1F
;; - *+XAR4[15]; uint32_t dataSize -> data size for CRC computation
;; dataSize - Data size - size of 1 bit - indicated by prograaming a value of 0x0
;; Data size - size of 8 bits is indicated by programming a value of 0x7
;; These are to be set in the VCRCSIZE register - PSIZE and DSIZE fields
;; - *+XAR4[16]; uint32_t reflected -> choose CRC computation in either reflected or non-reflected mode
;; \brief : Assembly function for generic CRC calculation in bytewise mode
_CRC_runConfigPolyBytes:
CRC_CONTEXT_SAVE
MOVL XAR2, XAR4
;; Register Usage:
;; XAR0: Number of bytes to process
;; XAR1: Loading polynomial, polynomial size, data size and repeat block counter
;; XAR2: Pointer to iterate through the CRC object
;; XAR4: Points to the CRC object
;; XAR5: Points to the message buffer
;;
MOV AR1, #POLYNOMIAL_OFFSET ; Load Polynomial
VMOV32 VCRCPOLY, *+XAR4[AR1]
MOV AR1, #PSIZE_OFFSET ; Initialize polynomial size
VMOV16 VCRCPSIZE, *+XAR4[AR1]
MOV AR1, #DSIZE_OFFSET ; Initialize data size
VMOV16 VCRCDSIZE, *+XAR4[AR1]
; Need 2+ cyc before using VCRC
VCRCCLR ; Clear out the CRC result register
MOVL XAR0, *+XAR4[NBYTES_OFFSET] ; Load number of message bytes into AR0
VMOV32 VCRC, *+XAR4[SEEDVAL_OFFSET] ; Load seed value into the CRC result register
MOV AR1, #MSGBUFFER_OFFSET
MOVL XAR5, *+XAR4[AR1] ; XAR5 points to the message buffer
MOV AL, *+XAR4[PARITY_OFFSET] ; Check the parity
SBF _CRC_runConfigPolyBytes_Loop, EQ ; If Parity = LOW_BYTE, skip to loop
VCRCH *XAR5++ ; Parity = HIGH_BYTE, calculate high byte of the first word,
; ignore the low byte and proceed to next word
DEC AR0
SBF _CRC_runConfigPolyBytes_End, EQ ; Jump to end if no more bytes
_CRC_runConfigPolyBytes_Loop:
MOV AL, AR0
MOV AH, AR0
AND AL, #0xFFF8 ; Check to see if length greater than 8 bytes
; if true, handle the <8 bytes in a loop
; AL is now a multiple of 8
SBF _CRC_runConfigPolyBytes_LT8BytesLeft, EQ
LSR AL, #3 ; loop in 8 bytes at a time
MOV AR1, AL ; move count into AR1
SUB AR1, #1 ; subtract 1, accounts for the RPTB instruction i.e. it loops
; N + 1 times
.align 2 ; align at 32-bit boundary to remove penalty
; loop through the message 8 bytes at a time
RPTB _CRC_runConfigPolyBytes_RepeatBlock, AR1
VCRCL *XAR5
NOP
NOP
VCRCH *XAR5++
NOP
NOP
VCRCL *XAR5
NOP
NOP
VCRCH *XAR5++
NOP
NOP
VCRCL *XAR5
NOP
NOP
VCRCH *XAR5++
NOP
NOP
VCRCL *XAR5
NOP
NOP
VCRCH *XAR5++
NOP
NOP
_CRC_runConfigPolyBytes_RepeatBlock:
LSL AL, #3 ; multiply by 8 to get the pre RPTB count
SUB AH, AL ; AH holds the number of remaining bytes(<8)
SBF _CRC_runConfigPolyBytes_End, EQ ; if multiple of 8, AH is 0, done processing
MOV AR0, AH
_CRC_runConfigPolyBytes_LT8BytesLeft:
VCRCL *XAR5
DEC AR0
SBF _CRC_runConfigPolyBytes_End, EQ
VCRCH *XAR5++
DEC AR0
SBF _CRC_runConfigPolyBytes_LT8BytesLeft, NEQ
_CRC_runConfigPolyBytes_End:
MOV AR1, #REFLECTED_OFFSET
CMP *+XAR4[AR1], #0x0
SBF _CRC_runConfigPolyBytes_End_NotReflected, EQ
;MOV AR1, #CRCRESULT_OFFSET
VMOV32 *+XAR4[CRCRESULT_OFFSET], VCRC ; Save the result to the structure
CRC_CONTEXT_RESTORE
LRETR
_CRC_runConfigPolyBytes_End_NotReflected:
MOV AR1, #PSIZE_OFFSET ; Initialize polynomial size
CMP *+XAR4[AR1], #0x1F
SBF _CRC_runConfigPolyBytes_End_NotReflected_32Bits, EQ
;MOV AR1, #CRCRESULT_OFFSET
VMOV32 *+XAR4[CRCRESULT_OFFSET], VCRC ; Save the result to the structure
MOVL ACC, *+XAR4[CRCRESULT_OFFSET]
FLIP AL
MOVL *+XAR4[CRCRESULT_OFFSET], ACC
CRC_CONTEXT_RESTORE
LRETR
_CRC_runConfigPolyBytes_End_NotReflected_32Bits:
;MOV AR1, #CRCRESULT_OFFSET
VMOV32 *+XAR4[CRCRESULT_OFFSET], VCRC
; Swap words during save
MOV AH, *+XAR4[CRCRESULT_OFFSET]
;MOV AR1, #CRCRESULT_OFFSET+1
MOV AL, *+XAR4[CRCRESULT_OFFSET+1]
; Reverse both halves
FLIP AH ; Flip the result in case of not reflected mode for 32 bits
FLIP AL
MOVL *+XAR4[CRCRESULT_OFFSET], ACC
CRC_CONTEXT_RESTORE
LRETR
;;*****************************************************************************
;; \brief: Assembly for CRC calculation in bitwise mode
_CRC_runConfigPolyBits:
CRC_CONTEXT_SAVE
;; Register Usage:
;; XAR0: Number of bytes to process
;; XAR1: Loading polynomial, polynomial size, data size and pointer index to DataSize
;; XAR4: Points to the CRC object
;; XAR5: Points to the message buffer
;;
VCRCCLR
MOV AR1, #POLYNOMIAL_OFFSET ; Load Polynomial
VMOV32 VCRCPOLY, *+XAR4[AR1]
MOV AR1, #PSIZE_OFFSET ; Initialize polynomial size
VMOV16 VCRCPSIZE, *+XAR4[AR1]
VMOV32 VCRC, *+XAR4[SEEDVAL_OFFSET] ; Load seed value into the CRC result register
MOV AR1, #MSGBUFFER_OFFSET
MOVL XAR5, *+XAR4[AR1] ; XAR5 points to the message buffer
MOV AR1, #DSIZE_OFFSET ; Initialize data size size
VMOV16 VCRCDSIZE, *+XAR4[AR1]
;;; Load # of bits, store modulus 8 (remaining bits after all full bytes processed)
;;; minus one back to CRC.dataSize
MOV AR1, #NBITS_OFFSET ; Initialize the data size
AND AL, *+XAR4[AR1], #7 ; AND with #7 to get the remaining number of bits after absolute byte conversion
SUBB ACC, #1 ; subtract 1 and load to the accumulator
MOV AR1, #DSIZE_OFFSET ; keep the remaining bits in DSIZE_OFFSET. e.g if NBITS_OFFSET = 13 then at this point DSIZE_OFFSET will hold value 5 which is the remaining bits after absolute byte count
MOV *+XAR4[AR1], AL ; load the remaining bits to CRC.dataSize
;;; Load # of bits, right shift to bytes, and store in # of bytes XAR0 (if needed)
MOV AR1, #NBITS_OFFSET ; Initialize data size
MOV AL, *+XAR4[AR1] ; Load # of bits
LSR AL, #3 ; Divide by 8
MOV AR1, #DSIZE_OFFSET ; ensure that AR1 still points to the remaining number of bits for CRC computation after absolute byte count
BF _LESS_THAN_A_BYTE_LOW, EQ ; If no full bytes, skip ahead
SUBB ACC, #1
MOV AR0, AL ; XAR0 = # of whole bytes - 1
MOV AL, *+XAR4[PARITY_OFFSET] ; branch to lower byte or higher byte depending on parity inputs
BF _PROCESS_HIGH_BYTE, NEQ
_PROCESS_LOW_BYTE:
VCRCL *XAR5 ; Takes 3 cycles
BANZ _PROCESS_HIGH_BYTE, AR0--
_LESS_THAN_A_BYTE_HIGH:
CMP *+XAR4[AR1], #0xFFFF
BF _CRC_runConfigPolyBits_End, EQ
VMOV16 VCRCDSIZE, *+XAR4[AR1] ; Load data size for last (< byte) CRC
VCRCH *XAR5++
BF _CRC_runConfigPolyBits_End, UNC
_PROCESS_HIGH_BYTE:
VCRCH *XAR5++ ; process the CRC for highger byte of a 16 bit word
BANZ _PROCESS_LOW_BYTE, AR0--
_LESS_THAN_A_BYTE_LOW:
CMP *+XAR4[AR1], #0xFFFF
BF _CRC_runConfigPolyBits_End, EQ
VMOV16 VCRCDSIZE, *+XAR4[AR1] ; Load data size for last (< byte) CRC
VCRCL *XAR5
BF _CRC_runConfigPolyBits_End, UNC
_CRC_runConfigPolyBits_End:
MOV AR1, #REFLECTED_OFFSET
CMP *+XAR4[AR1], #0x0
SBF _CRC_runConfigPolyBits_End_NotReflected, EQ
;MOV AR1, #CRCRESULT_OFFSET
VMOV32 *+XAR4[CRCRESULT_OFFSET], VCRC ; Save the result to the structure
CRC_CONTEXT_RESTORE
LRETR
_CRC_runConfigPolyBits_End_NotReflected:
MOV AR1, #PSIZE_OFFSET ; Initialize polynomial size
CMP *+XAR4[AR1], #0x1F
SBF _CRC_runConfigPolyBits_End_NotReflected_32Bits, EQ
;MOV AR1, #CRCRESULT_OFFSET
VMOV32 *+XAR4[CRCRESULT_OFFSET], VCRC ; Save the result to the structure
MOVL ACC, *+XAR4[CRCRESULT_OFFSET]
FLIP AL
MOVL *+XAR4[CRCRESULT_OFFSET], ACC
CRC_CONTEXT_RESTORE
LRETR
_CRC_runConfigPolyBits_End_NotReflected_32Bits:
;MOV AR1, #CRCRESULT_OFFSET
VMOV32 *+XAR4[CRCRESULT_OFFSET], VCRC
; Swap words during save
MOV AH, *+XAR4[CRCRESULT_OFFSET]
;MOV AR1, #CRCRESULT_OFFSET+1
MOV AL, *+XAR4[CRCRESULT_OFFSET+1]
; Reverse both halves
FLIP AH ; Flip the result in case of not reflected mode for 32 bits
FLIP AL
MOVL *+XAR4[CRCRESULT_OFFSET], ACC
CRC_CONTEXT_RESTORE
LRETR
;;*****************************************************************************
_CRC_runConfigPolyBytesReflected:
VSETCRCMSGFLIP
LCR _CRC_runConfigPolyBytes
VCLRCRCMSGFLIP
LRETR
;;*****************************************************************************
_CRC_runConfigPolyBitsReflected:
VSETCRCMSGFLIP
LCR _CRC_runConfigPolyBits
VCLRCRCMSGFLIP
LRETR
;;*****************************************************************************
;; End of file
@@ -0,0 +1,219 @@
;;*****************************************************************************
;;! \file source/vcu0/vcu0_crc_16.asm
;;!
;;! \brief 16-bit CRC that uses the polynomials 0x1021 and 0x8005
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;*****************************************************************************
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;;*****************************************************************************
;; global defines
;;*****************************************************************************
;; CRC Routine defines
;/*! ASM- function to get the 16-bit CRC
; *
; * \param ACC = The initial value of crc, in case the message has been
; * chopped into several parts, you can use the crc16 of the previous
; * segment as the init value for the current segment crc16 calculation
; * until the final crc is derived.
; * \param *+XAR4 = Address of the message buffer
; * \param AR5 = Parity of the first message byte, i.e. whether its on an even
; * or odd address
; * \param *-SP[1]/AR0 = Length of the message in bytes
; *
; * Calculate the 16-bit CRC of a message buffer by using the VCU instructions
; * VCRC16P1H_1 and VCRC16P1L_1
; *
; * \return CRC result in AL
; */
.if __TI_EABI__
.asg getCRC16P1_vcu,_getCRC16P1_vcu
.endif
.def _getCRC16P1_vcu
_getCRC16P1_vcu:
PUSH XAR0
PUSH XAR1
MOVZ AR0, *-SP[7] ; load rxLen
ADDB SP, #4 ; allocate 4 words for local
VMOV32 *-SP[2], VCRC ; Store current CRC
VCRCCLR
MOVL *-SP[4], ACC
VMOV32 VCRC,*-SP[4] ; VCRC = Inital value
MOV AL, AR5 ; check the parity
SBF _CRC16p1_loop_prep, EQ
VCRC16P1H_1 *XAR4++ ; if parity=1, calculate high byte first
DEC AR0
SBF _CRC16p1done, EQ
_CRC16p1_loop_prep:
MOV AL, AR0
MOV AH, AR0
AND AL, #0xFFF8 ; check to see if the length is greater than 8 bytes
BF _CRC16p1_LSB,EQ
LSR AL, #3 ; loop in 8 bytes
MOV AR1, AL
SUB AR1, #1
.align (2) ; align at 32-bit boundary to remove penalty
RPTB _CRC16p1_post, AR1 ; loop for the middle part of the packet
VCRC16P1L_1 *XAR4
VCRC16P1H_1 *XAR4++
VCRC16P1L_1 *XAR4
VCRC16P1H_1 *XAR4++
VCRC16P1L_1 *XAR4
VCRC16P1H_1 *XAR4++
VCRC16P1L_1 *XAR4
VCRC16P1H_1 *XAR4++
_CRC16p1_post
LSL AL, #3 ; calculating remaining number of bytes
SUB AH, AL
SBF _CRC16p1done, EQ ;branch to end on 0 remainder
MOV AR0, AH
_CRC16p1_LSB
VCRC16P1L_1 *XAR4 ; if parity=0, calculate the low byte
DEC AR0
SBF _CRC16p1done, EQ
VCRC16P1H_1 *XAR4++
DEC AR0
SBF _CRC16p1_LSB, NEQ
_CRC16p1done
VMOV32 *-SP[4], VCRC ; Store CRC
MOV AL, *-SP[4] ; return AL
VMOV32 VCRC, *-SP[2] ; Restore VCRC
SUBB SP, #4 ; restore stack pointer
POP XAR1
POP XAR0
LRETR
;/*! ASM- function to get the 16-bit CRC
; *
; * \param ACC = The initial value of crc, in case the message has been
; * chopped into several parts, you can use the crc16 of the previous
; * segment as the init value for the current segment crc16 calculation
; * until the final crc is derived.
; * \param *+XAR4 = Address of the message buffer
; * \param AR5 = Parity of the first message byte, i.e. whether its on an even
; * or odd address
; * \param *-SP[1]/AR0 = Length of the message in bytes
; *
; * Calculate the 16-bit CRC of a message buffer by using the VCU instructions
; * VCRC16P2H_1 and VCRC16P2L_1
; *
; * \return CRC result in AL
; */
.if __TI_EABI__
.asg getCRC16P2_vcu,_getCRC16P2_vcu
.endif
.def _getCRC16P2_vcu
_getCRC16P2_vcu:
PUSH XAR0
PUSH XAR1
MOVZ AR0, *-SP[7] ; load rxLen
ADDB SP, #4 ; allocate 4 words for local
VMOV32 *-SP[2], VCRC ; Store current CRC
VCRCCLR
MOVL *-SP[4], ACC
VMOV32 VCRC,*-SP[4] ; VCRC = Inital value
MOV AL,AR5 ; check the parity
SBF _CRC16p2_loop_prep, EQ
VCRC16P2H_1 *XAR4++ ; if parity=1, calculate high byte first
DEC AR0
SBF _CRC16p2done, EQ
_CRC16p2_loop_prep:
MOV AL, AR0
MOV AH, AR0
AND AL, #0xFFF8 ; check to see if the length is greater than 8 bytes
BF _CRC16p2_LSB,EQ
LSR AL, #3 ; loop in 8 bytes
MOV AR1, AL
SUB AR1, #1
.align (2) ; align at 32-bit boundary to remove penalty
RPTB _CRC16p2_post, AR1 ; loop for the middle part of the packet
VCRC16P2L_1 *XAR4
VCRC16P2H_1 *XAR4++
VCRC16P2L_1 *XAR4
VCRC16P2H_1 *XAR4++
VCRC16P2L_1 *XAR4
VCRC16P2H_1 *XAR4++
VCRC16P2L_1 *XAR4
VCRC16P2H_1 *XAR4++
_CRC16p2_post
LSL AL, #3 ; calculating remaining number of bytes
SUB AH, AL
SBF _CRC16p2done, EQ ;branch to end on 0 remainder
MOV AR0, AH
_CRC16p2_LSB
VCRC16P2L_1 *XAR4 ; if parity=0, calculate the low byte
DEC AR0
SBF _CRC16p2done, EQ
VCRC16P2H_1 *XAR4++
DEC AR0
SBF _CRC16p2_LSB, NEQ
_CRC16p2done
VMOV32 *-SP[4], VCRC ; Store CRC
MOV AL, *-SP[4] ; return AL
VMOV32 VCRC, *-SP[2] ; Restore VCRC
SUBB SP, #4 ; restore stack pointer
POP XAR1
POP XAR0
LRETR
;; End of file
@@ -0,0 +1,142 @@
;;*****************************************************************************
;;! \file source/vcu0/vcu0_crc_32.asm
;;!
;;! \brief 32-bit CRC that uses the polynomial 0x04c11db7
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;*****************************************************************************
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;;*****************************************************************************
;; global defines
;;*****************************************************************************
;; CRC Routine defines
;/*! ASM- function to get the 32-bit CRC
; *
; * \param ACC = The initial value of crc, in case the message has been
; * chopped into several parts, you can use the crc32 of the previous
; * segment as the init value for the current segment crc32 calculation
; * until the final crc is derived.
; * \param *+XAR4 = Address of the message buffer
; * \param AR5 = Parity of the first message byte, i.e. whether its on an even
; * or odd address
; * \param *-SP[1]/AR0 = Length of the message in bytes
; *
; * Calculate the 32-bit CRC of a message buffer by using the VCU instructions
; * VCRC32H_1 and VCRC32L_1
; *
; * \return CRC result in ACC
; */
.if __TI_EABI__
.asg getCRC32_vcu,_getCRC32_vcu
.endif
.def _getCRC32_vcu
_getCRC32_vcu:
PUSH XAR0
PUSH XAR1
MOVZ AR0, *-SP[7] ; load rxLen
ADDB SP, #4 ; allocate 4 words for local
VMOV32 *-SP[2], VCRC ; Store current CRC
VCRCCLR
MOVL *-SP[4], ACC
VMOV32 VCRC,*-SP[4] ; VCRC = Inital value
MOV AL, AR5 ; check the parity
SBF _CRC32_loop_prep, EQ
VCRC32H_1 *XAR4++ ; if parity=1, calculate high byte first
DEC AR0
SBF _CRC32done, EQ
_CRC32_loop_prep:
MOV AL, AR0
MOV AH, AR0
AND AL, #0xFFF8 ; check to see if the length is greater than 8 bytes
BF _CRC32_LSB,EQ
LSR AL, #3 ; loop in 8 bytes
MOV AR1, AL
SUB AR1, #1
.align (2) ; align at 32-bit boundary to remove penalty
RPTB _CRC32_post, AR1 ; loop for the middle part of the packet
VCRC32L_1 *XAR4
VCRC32H_1 *XAR4++
VCRC32L_1 *XAR4
VCRC32H_1 *XAR4++
VCRC32L_1 *XAR4
VCRC32H_1 *XAR4++
VCRC32L_1 *XAR4
VCRC32H_1 *XAR4++
_CRC32_post:
LSL AL, #3 ; calculating remaining number of bytes
SUB AH, AL
SBF _CRC32done, EQ ; if multiple of 8, done
MOV AR0, AH
_CRC32_LSB
VCRC32L_1 *XAR4 ; if parity=0, calculate the low byte
DEC AR0
SBF _CRC32done, EQ
VCRC32H_1 *XAR4++
DEC AR0
SBF _CRC32_LSB, NEQ
_CRC32done
VMOV32 *-SP[4], VCRC ; Store CRC
MOVL ACC, *-SP[4] ; return ACC
VMOV32 VCRC, *-SP[2] ; Restore VCRC
SUBB SP, #4 ; restore stack pointer
POP XAR1
POP XAR0
LRETR
;; End of file
@@ -0,0 +1,142 @@
;;*****************************************************************************
;;! \file source/vcu0/vcu0_crc_32_hilo_order_swap.asm
;;!
;;! \brief 32-bit CRC that uses the polynomial 0x04c11db7
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;*****************************************************************************
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;;*****************************************************************************
;; global defines
;;*****************************************************************************
;; CRC Routine defines
;/*! ASM- function to get the 32-bit CRC
; *
; * \param ACC = The initial value of crc, in case the message has been
; * chopped into several parts, you can use the crc32 of the previous
; * segment as the init value for the current segment crc32 calculation
; * until the final crc is derived.
; * \param *+XAR4 = Address of the message buffer
; * \param AR5 = Parity of the first message byte, i.e. whether its on an even
; * or odd address
; * \param *-SP[1]/AR0 = Length of the message in bytes
; *
; * Calculate the 32-bit CRC of a message buffer by using the VCU instructions
; * VCRC32H_1 and VCRC32L_1
; *
; * \return CRC result in ACC
; */
.if __TI_EABI__
.asg getCRC32_vcu_hilo_order_swap,_getCRC32_vcu_hilo_order_swap
.endif
.def _getCRC32_vcu_hilo_order_swap
_getCRC32_vcu_hilo_order_swap:
PUSH XAR0
PUSH XAR1
MOVZ AR0, *-SP[7] ; load rxLen
ADDB SP, #4 ; allocate 4 words for local
VMOV32 *-SP[2], VCRC ; Store current CRC
VCRCCLR
MOVL *-SP[4], ACC
VMOV32 VCRC,*-SP[4] ; VCRC = Inital value
MOV AL, AR5 ; check the parity
SBF _CRC32_loop_prep_hilo_order_swap, EQ
VCRC32H_1 *XAR4++ ; if parity=1, calculate high byte first
DEC AR0
SBF _CRC32done_hilo_order_swap, EQ
_CRC32_loop_prep_hilo_order_swap:
MOV AL, AR0
MOV AH, AR0
AND AL, #0xFFF8 ; check to see if the length is greater than 8 bytes
BF _CRC32_LSB_hilo_order_swap,EQ
LSR AL, #3 ; loop in 8 bytes
MOV AR1, AL
SUB AR1, #1
.align (2) ; align at 32-bit boundary to remove penalty
RPTB _CRC32_post_hilo_order_swap, AR1 ; loop for the middle part of the packet
VCRC32H_1 *XAR4
VCRC32L_1 *XAR4++
VCRC32H_1 *XAR4
VCRC32L_1 *XAR4++
VCRC32H_1 *XAR4
VCRC32L_1 *XAR4++
VCRC32H_1 *XAR4
VCRC32L_1 *XAR4++
_CRC32_post_hilo_order_swap:
LSL AL, #3 ; calculating remaining number of bytes
SUB AH, AL
SBF _CRC32done_hilo_order_swap, EQ ; if multiple of 8, done
MOV AR0, AH
_CRC32_LSB_hilo_order_swap
VCRC32H_1 *XAR4 ; if parity=0, calculate the low byte
DEC AR0
SBF _CRC32done_hilo_order_swap, EQ
VCRC32L_1 *XAR4++
DEC AR0
SBF _CRC32_LSB_hilo_order_swap, NEQ
_CRC32done_hilo_order_swap
VMOV32 *-SP[4], VCRC ; Store CRC
MOVL ACC, *-SP[4] ; return ACC
VMOV32 VCRC, *-SP[2] ; Restore VCRC
SUBB SP, #4 ; restore stack pointer
POP XAR1
POP XAR0
LRETR
;; End of file
@@ -0,0 +1,144 @@
;;*****************************************************************************
;;! \file source/vcu0/vcu0_crc_8.asm
;;!
;;! \brief 8-bit CRC that uses the polynomial 0x07
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;*****************************************************************************
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;;*****************************************************************************
;; global defines
;;*****************************************************************************
;; CRC Routine defines
;
;/*! ASM- function to get the 8-bit CRC
; *
; * \param ACC = The initial value of crc, in case the message has been
; * chopped into several parts, you can use the crc8 of the previous
; * segment as the init value for the current segment crc8 calculation
; * until the final crc is derived.
; * \param *+XAR4 = Address of the message buffer
; * \param AR5 = Parity of the first message byte, i.e. whether its on an even
; * or odd address
; * \param *-SP[1]/AR0 = Length of the message in bytes
; *
; * Calculate the 8-bit CRC of a message buffer by using the VCU instructions,
; * VCRC8L_1 and VCRC8H_1
; *
; * \return CRC result in AL
; */
.if __TI_EABI__
.asg getCRC8_vcu,_getCRC8_vcu
.endif
.def _getCRC8_vcu
_getCRC8_vcu:
PUSH XAR0
PUSH XAR1
MOVZ AR0, *-SP[7] ; load rxLen
ADDB SP, #4 ; allocate 4 words for local
VMOV32 *-SP[2], VCRC ; Store current CRC
VCRCCLR
MOV *-SP[4], ACC
VMOV32 VCRC,*-SP[4] ; VCRC = Inital value
MOV AL, AR5 ; check the parity
SBF _CRC8_loop_prep, EQ
VCRC8H_1 *XAR4++ ; if parity=1, calculate high byte first
DEC AR0
SBF _CRC8done, EQ
_CRC8_loop_prep:
MOV AL, AR0
MOV AH, AR0
AND AL, #0xFFF8 ; check to see if the length is greater than 8 bytes
BF _CRC8_LSB,EQ
LSR AL, #3 ; loop in 8 bytes
MOV AR1, AL
SUB AR1, #1
.align (2) ; align at 32-bit boundary to remove penalty
RPTB _CRC8_post, AR1 ; loop for the middle part of the packet
VCRC8L_1 *XAR4
VCRC8H_1 *XAR4++
VCRC8L_1 *XAR4
VCRC8H_1 *XAR4++
VCRC8L_1 *XAR4
VCRC8H_1 *XAR4++
VCRC8L_1 *XAR4
VCRC8H_1 *XAR4++
_CRC8_post
LSL AL, #3 ; calculating remaining number of bytes
SUB AH, AL
SBF _CRC8done, EQ ; if multiple of 8, done
MOV AR0, AH
_CRC8_LSB
VCRC8L_1 *XAR4 ; if parity=0, calculate the low byte
DEC AR0
SBF _CRC8done, EQ
VCRC8H_1 *XAR4++
DEC AR0
SBF _CRC8_LSB, NEQ
_CRC8done
VMOV32 *-SP[4], VCRC ; Store CRC
MOV AL, *-SP[4] ; return AL
VMOV32 VCRC, *-SP[2] ; Restore VCRC
SUBB SP, #4 ; restore stack pointer
POP XAR1
POP XAR0
LRETR
;; End of file
@@ -0,0 +1,93 @@
;;*****************************************************************************
;;! \file source/vcu0/vcu0_crc_utils.asm
;;!
;;! \brief CRC Utility routines
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;*****************************************************************************
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;;*****************************************************************************
;; global defines
;;*****************************************************************************
;; CRC Routine defines
;
;/*! Workaround to the silicon issue of first VCU calculation on power up being
; * erroneous
; *
; * Details Due to the internal power-up state of the VCU module, it is possible
; * that the first CRC result will be incorrect. This condition applies to the
; * first result from each of the eight CRC instructions.
; * This rare condition can only occur after a power-on reset, but will not
; * necessarily occur on every power on. A warm reset will not cause this condition
; * to reappear.
; * Workaround(s): The application can reset the internal VCU CRC logic by
; * performing a CRC calculation of a single byte in the initialization routine.
; * This routine only needs to perform one CRC calculation and can use any of the
; * CRC instructions
; *
; */
.if __TI_EABI__
.asg CRC_reset,_CRC_reset
.endif
.def _CRC_reset
_CRC_reset:
MOVB XAR7, #0
VCRC8L_1 *XAR7
VCRCCLR
LRETR
;; End of file
@@ -0,0 +1,537 @@
;;*****************************************************************************
;; \file source/vcu0/vcu0_cfft_128.asm
;;
;; \brief 128-pt complex FFT
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;*****************************************************************************
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;.cdecls C,LIST,"fft.h"
;############################################################################
;
;/*! \page CFFT_128 (Complex FFT -- 128 point)
; - This routine implements the 128-pt complex FFT algorithm
; The 7 FFT stages are fully unrolled to take advantage of
; the repeat block and parallel VCCP instructions.
; - In the first 3 stages, the butterflies are rearranged to
; group those whose offset is constant. For examples, the second
; stage is grouped by even butterflies and odd butterflies.
; - Last 4 stages, butterflies are grouped in sub-FFTs
; For example , the 6th stage has 2 groups, upper and lower
;*/
;############################################################################
;/*! \defgroup CFFT_128_FN (128pt CFFT Routines)
; @{ .....starts the defintion block
;*/
.global _cfft16_128p_calc
;//###########################################################################
.text
;/*! Calculate the 128 pt Complex FFT
; *
; * \param Handle to the structure, cfft16_t
; *
; * XAR4 - FFT handle
; * *+XAR4[0]: int *ipcbptr -> input pointer
; * *+XAR4[2]: int *workptr -> work buffer pointer
; * *+XAR4[4]: int *tfptr -> twiddle factor table pointer
; * *+XAR4[6]: int size -> Number of data points
; * *+XAR4[7]: int nrstage -> Number of FFT stages
; * *+XAR4[8]: int step -> Twiddle factor table search step
; * *+XAR4[9]: 0
; * *+XAR4[10]: int *brevptr -> Bit reversal table pointer
; *
; * Registers
; * XAR0: offset address
; * XAR1: offset address
; * XAR2: FFT input base pointer
; * XAR3: FFT output base pointer
; * XAR4: FFT handler pointer
; * XAR5:
; * XAR6: Twiddle Factor table base pointer
; * XAR7:
; *
; * [SP-2]: Stores twiddle factor pointer
; *
; * \return none
; */
_cfft16_128p_calc:
PUSH XAR0
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #18 ; allocate stack space for temperary variables
VMOV32 *-SP[2], VR0 ; save VRx to stack
VMOV32 *-SP[4], VR1
VMOV32 *-SP[6], VR2
VMOV32 *-SP[8], VR3
VMOV32 *-SP[10], VR4
VMOV32 *-SP[12], VR5
VMOV32 *-SP[14], VR6
SETC SXM ; sign extension mode
VSATON ; VSTATUS.SAT = 1
VRNDON ; rounding on
VSETSHR #16 ; VSTATUS.SHIFTR = RIGHT_SHIFT
VSETSHL #15 ; VSTATUS.SHIFTL = LEFT_SHIFT, each stage output is scaled by2
;========================================================================
; FFT stage 1: N/2 groups of 2-pt FFT
;========================================================================
MOVL XAR2, *+XAR4[2] ; load FFT work buffer base pointer
MOVL XAR3, *+XAR4[0] ; load FFT input buffer pointer
MOVL XAR6, *+XAR4[4] ; load twiddle factor base pointer
; pre-load the pipeline
VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(0)
VMOV32 VR1,*XAR2++ ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
VNOP
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(1)
VMOV32 VR1,*XAR2++ ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP1, #61 ; 64 butterflies for each stage
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *XAR3++,VR6 ; Ib':Rb'(0) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(2)
VMOV32 VR1,*XAR2++ ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP1:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *XAR3++,VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
VMOV32 *XAR3++,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *XAR3++,VR6 ; Ib':Rb'(2) = VR6
;========================================================================
; FFT stage 2: N/4 groups 4-pt FFT
;========================================================================
ZAPA
MOV AR0, #1 ; loop twice , even and odd butterflies
_STAGE2_LOOP:
MOVL XAR2, *+XAR4[0] ; load input buffer base pointer, as the input buffer
MOVL XAR3, *+XAR4[2] ; load FFT work buffer base pointer, as the work buffer
MOVL ACC, XAR2 ; P stores offset between even and odd butterflies
ADDL ACC, P
MOVL XAR2, ACC
MOVL ACC, XAR3
ADDL ACC, P
MOVL XAR3, ACC
MOV AR1, #4 ; butterfy size 2 samples (I/Q)
; pre-load the pipeline
VMOV32 VR4,*XAR2 ; VR4 = Ia:Ra(0)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
ADDB XAR2, #8 ; move to the next butterfly
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2 ; VR4 = Ia:Ra(1)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP2, #29 ;32 butterflies for even butterflies
ADDB XAR2, #8 ; move to the next butterfly
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(0) = VR6
ADDB XAR3, #8
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2 ; VR4 = Ia:Ra(2)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP2:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
ADDB XAR3, #8
VMOV32 *XAR3,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(2) = VR6
ADD PL, #2
BANZ _STAGE2_LOOP, AR0--
;========================================================================
; FFT stage 3: N/8 groups 8-pt FFT
;========================================================================
ZAPA
MOV AR0, #3 ; loop four times
MOV AR1, #8 ; butterfy size 4 samples (I/Q)
_STAGE3_LOOP:
MOVL XAR2, *+XAR4[2] ; load FFT work buffer base pointer
MOVL XAR3, *+XAR4[0] ; load FFT input buffer pointer
MOVL ACC, XAR2 ; P stores offset between even and odd butterflies
ADDL ACC, P
MOVL XAR2, ACC
MOVL ACC, XAR3
ADDL ACC, P
MOVL XAR3, ACC
; pre-load the pipeline
VMOV32 VR4,*XAR2 ; VR4 = Ia:Ra(0)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
ADDB XAR2, #16 ; move to the next butterfly
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2 ; VR4 = Ia:Ra(1)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP3, #13 ; 16 butterflies for even butterflies
ADDB XAR2, #16 ; move to the next butterfly
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(0) = VR6
ADDB XAR3, #16
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2 ; VR4 = Ia:Ra(2)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP3:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
ADDB XAR3, #16
VMOV32 *XAR3,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(2) = VR6
ADD PL, #2 ; move to the next butterfly group
BANZ _STAGE3_LOOP, AR0--
;========================================================================
; FFT stage 4: N/16 groups 16-pt FFT
;========================================================================
ZAPA
MOV AR0, #7 ; loop 8 times (sub groups)
MOV AR1, #14 ; butterfy size 8 samples (I/Q), excluding one ++ operation
MOVL *-SP[16], XAR6 ; save the current twiddle factor pointer
_STAGE4_LOOP:
MOVL XAR6, *-SP[16] ; reload the twiddle factor base pointer
MOVL XAR2, *+XAR4[0] ; load input buffer base pointer, as the work buffer
MOVL XAR3, *+XAR4[2] ; load FFT work buffer base pointer, as the input buffer
MOVL ACC, XAR2 ; P stores offset between even and odd butterflies
ADDL ACC, P
MOVL XAR2, ACC
MOVL ACC, XAR3
ADDL ACC, P
MOVL XAR3, ACC
; pre-load the pipeline
VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(0)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VNOP
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(1)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP4, #5 ; 8 butterflies in one subgroup
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(0) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(2)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP4:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
VMOV32 *XAR3++,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(2) = VR6
ADD PL, #32 ; move to the next butterfly group
BANZ _STAGE4_LOOP, AR0--
;========================================================================
; FFT stage 5: N/32 groups 32-pt FFT
;========================================================================
ZAPA
MOV AR0, #3 ; loop four times (sub groups)
MOV AR1, #30 ; butterfy size 16 samples (I/Q), excluding one ++ operation
MOVL *-SP[16], XAR6 ; save the current twiddle factor pointer
_STAGE5_LOOP:
MOVL XAR6, *-SP[16] ; reload the twiddle factor base pointer
MOVL XAR2, *+XAR4[2] ; load FFT work buffer base pointer
MOVL XAR3, *+XAR4[0] ; load FFT input buffer pointer
MOVL ACC, XAR2 ; P stores offset between even and odd butterflies
ADDL ACC, P
MOVL XAR2, ACC
MOVL ACC, XAR3
ADDL ACC, P
MOVL XAR3, ACC
; pre-load the pipeline
VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(0)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VNOP
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(1)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP5, #13 ; 16 butterflies in one subgroup
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(0) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(2)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP5:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
VMOV32 *XAR3++,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(2) = VR6
ADD PL, #64 ; move to the next butterfly group
BANZ _STAGE5_LOOP, AR0--
;========================================================================
; FFT stage 6: N/64 groups 64-pt FFT
;========================================================================
ZAPA
MOV AR0, #1 ; loop two times (sub groups)
MOV AR1, #62 ; butterfy size 32 samples (I/Q), excluding one ++ operation
MOVL *-SP[16], XAR6 ; save the current twiddle factor pointer
_STAGE6_LOOP:
MOVL XAR6, *-SP[16] ; reload the twiddle factor base pointer
MOVL XAR2, *+XAR4[0] ; load input buffer base pointer, as the work buffer
MOVL XAR3, *+XAR4[2] ; load FFT work buffer base pointer, as the input buffer
MOVL ACC, XAR2 ; P stores offset between even and odd butterflies
ADDL ACC, P
MOVL XAR2, ACC
MOVL ACC, XAR3
ADDL ACC, P
MOVL XAR3, ACC
; pre-load the pipeline
VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(0)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VNOP
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(1)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP6, #29 ; 32 butterflies in one subgroup
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(0) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(2)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP6:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
VMOV32 *XAR3++,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(2) = VR6
ADD PL, #128 ; move to the next butterfly group
BANZ _STAGE6_LOOP, AR0--
;========================================================================
; FFT stage 7: N/128 groups 128-pt FFT
;========================================================================
ZAPA
MOV AR1, #126 ; butterfy size 64 samples (I/Q), excluding one ++ operation
MOVL XAR2, *+XAR4[2] ; load FFT work buffer base pointer
MOVL XAR3, *+XAR4[0] ; load FFT input buffer pointer
; pre-load the pipeline
VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(0)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VNOP
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(1)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP7, #61 ; 64 butterflies in one subgroup
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(0) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(2)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP7:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
VMOV32 *XAR3++,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(2) = VR6
VMOV32 VR0, *-SP[2] ; restore VR registers
VMOV32 VR1, *-SP[4]
VMOV32 VR2, *-SP[6]
VMOV32 VR3, *-SP[8]
VMOV32 VR4, *-SP[10]
VMOV32 VR5, *-SP[12]
VMOV32 VR6, *-SP[14]
SUBB SP, #18 ; restore SP
POP XAR3
POP XAR2
POP XAR1
POP XAR0
LRETR
;############################################################################
; Close the Doxygen group.
;//! @}
;############################################################################
;; End of file
@@ -0,0 +1,612 @@
;;*****************************************************************************
;; \file source/vcu0/vcu0_cfft_256.asm
;;
;; \brief 256-pt complex FFT
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;*****************************************************************************
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;.cdecls C,LIST,"fft.h"
;############################################################################
;
;/*! \page CFFT_256 (Complex FFT -- 256 point)
;- This routine implements the 256-pt complex FFT algorithm
; The 8 FFT stages are fully unrolled to take advantage of
; the repeat block and parallel VCCP instructions.
;- In the first 3 stages, the butterflies are rearranged to
; group those whose offset is constant. For examples, the second
; stage is grouped by even butterflies and odd butterflies.
;- Last 5 stages, butterflies are grouped in sub-FFTs
; For example , the 7th stage has 2 groups, upper and lower
;*/
;############################################################################
;/*! \defgroup CFFT_256_FN (256pt CFFT Routines)
; @{ .....starts the defintion block
;*/
.global _cfft16_256p_calc
;//###########################################################################
.text
;/*! Calculate the 256 pt Complex FFT
; *
; * \param Handle to the structure, cfft16_t
; *
; * XAR4 - FFT handle
; * *+XAR4[0]: int *ipcbptr -> input pointer
; * *+XAR4[2]: int *workptr -> work buffer pointer
; * *+XAR4[4]: int *tfptr -> twiddle factor table pointer
; * *+XAR4[6]: int size -> Number of data points
; * *+XAR4[7]: int nrstage -> Number of FFT stages
; * *+XAR4[8]: int step -> Twiddle factor table search step
; * *+XAR4[9]: 0
; * *+XAR4[10]: int *brevptr -> Bit reversal table pointer
; *
; * Registers
; * XAR0: offset address
; * XAR1: offset address
; * XAR2: FFT input base pointer
; * XAR3: FFT output base pointer
; * XAR4: FFT handler pointer
; * XAR5:
; * XAR6: Twiddle Factor table base pointer
; * XAR7:
; *
; * [SP-2]: Stores twiddle factor pointer
; *
; * \return none
; */
_cfft16_256p_calc:
PUSH XAR0
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #18 ; allocate stack space for temperary variables
VMOV32 *-SP[2], VR0 ; save VRx to stack
VMOV32 *-SP[4], VR1
VMOV32 *-SP[6], VR2
VMOV32 *-SP[8], VR3
VMOV32 *-SP[10], VR4
VMOV32 *-SP[12], VR5
VMOV32 *-SP[14], VR6
SETC SXM ; sign extension mode
VSATON ; VSTATUS.SAT = 1
VRNDON ; rounding on
VSETSHR #16 ; VSTATUS.SHIFTR = RIGHT_SHIFT
VSETSHL #15 ; VSTATUS.SHIFTL = LEFT_SHIFT, each stage output is scaled by2
;========================================================================
; FFT stage 1: N/2 groups of 2-pt FFT
;========================================================================
MOVL XAR2, *+XAR4[0] ; load FFT input buffer base pointer
MOVL XAR3, *+XAR4[2] ; load FFT work buffer pointer
MOVL XAR6, *+XAR4[4] ; load twiddle factor base pointer
; pre-load the pipeline
VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(0)
VMOV32 VR1,*XAR2++ ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
VNOP
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(1)
VMOV32 VR1,*XAR2++ ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP1, #125 ; 128 butterflies for each stage
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *XAR3++,VR6 ; Ib':Rb'(0) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(2)
VMOV32 VR1,*XAR2++ ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP1:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *XAR3++,VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
VMOV32 *XAR3++,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *XAR3++,VR6 ; Ib':Rb'(2) = VR6
;========================================================================
; FFT stage 2: N/4 groups 4-pt FFT
;========================================================================
ZAPA
MOV AR0, #1 ; loop twice , even and odd butterflies
_STAGE2_LOOP:
MOVL XAR2, *+XAR4[2] ; load work buffer base pointer, as the input buffer
MOVL XAR3, *+XAR4[0] ; load FFT input buffer base pointer, as the work buffer
MOVL ACC, XAR2 ; P stores offset between even and odd butterflies
ADDL ACC, P
MOVL XAR2, ACC
MOVL ACC, XAR3
ADDL ACC, P
MOVL XAR3, ACC
MOV AR1, #4 ; butterfy size 2 samples (I/Q)
; pre-load the pipeline
VMOV32 VR4,*XAR2 ; VR4 = Ia:Ra(0)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
ADDB XAR2, #8 ; move to the next butterfly
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2 ; VR4 = Ia:Ra(1)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP2, #61 ;64 butterflies for even butterflies
ADDB XAR2, #8 ; move to the next butterfly
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(0) = VR6
ADDB XAR3, #8
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2 ; VR4 = Ia:Ra(2)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP2:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
ADDB XAR3, #8
VMOV32 *XAR3,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(2) = VR6
MOV PL, #2
BANZ _STAGE2_LOOP, AR0--
;========================================================================
; FFT stage 3: N/8 groups 8-pt FFT
;========================================================================
ZAPA
MOV AR0, #3 ; loop four times
MOV AR1, #8 ; butterfy size 4 samples (I/Q)
_STAGE3_LOOP:
MOVL XAR2, *+XAR4[0] ; load FFT input buffer base pointer
MOVL XAR3, *+XAR4[2] ; load FFT work buffer pointer
MOVL ACC, XAR2 ; P stores offset between even and odd butterflies
ADDL ACC, P
MOVL XAR2, ACC
MOVL ACC, XAR3
ADDL ACC, P
MOVL XAR3, ACC
; pre-load the pipeline
VMOV32 VR4,*XAR2 ; VR4 = Ia:Ra(0)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
ADDB XAR2, #16 ; move to the next butterfly
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2 ; VR4 = Ia:Ra(1)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP3, #29 ; 32 butterflies for even butterflies
ADDB XAR2, #16 ; move to the next butterfly
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(0) = VR6
ADDB XAR3, #16
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2 ; VR4 = Ia:Ra(2)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP3:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
ADDB XAR3, #16
VMOV32 *XAR3,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(2) = VR6
ADD PL, #2 ; move to the next butterfly group
BANZ _STAGE3_LOOP, AR0--
;========================================================================
; FFT stage 4: N/16 groups 16-pt FFT
;========================================================================
ZAPA
MOV AR0, #15 ; loop 16 times (sub groups)
MOV AR1, #14 ; butterfy size 8 samples (I/Q), excluding one ++ operation
MOVL *-SP[16], XAR6 ; save the current twiddle factor pointer
_STAGE4_LOOP:
MOVL XAR6, *-SP[16] ; reload the twiddle factor base pointer
MOVL XAR2, *+XAR4[2] ; load work buffer base pointer, as the input buffer
MOVL XAR3, *+XAR4[0] ; load FFT input buffer base pointer, as the work buffer
MOVL ACC, XAR2 ; P stores offset between even and odd butterflies
ADDL ACC, P
MOVL XAR2, ACC
MOVL ACC, XAR3
ADDL ACC, P
MOVL XAR3, ACC
; pre-load the pipeline
VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(0)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VNOP
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(1)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP4, #5 ; 8 butterflies in one subgroup
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(0) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(2)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP4:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
VMOV32 *XAR3++,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(2) = VR6
ADD PL, #32 ; move to the next butterfly group
BANZ _STAGE4_LOOP, AR0--
;========================================================================
; FFT stage 5: N/32 groups 32-pt FFT
;========================================================================
ZAPA
MOV AR0, #7 ; loop 8 times (sub groups)
MOV AR1, #30 ; butterfy size 16 samples (I/Q), excluding one ++ operation
MOVL *-SP[16], XAR6 ; save the current twiddle factor pointer
_STAGE5_LOOP:
MOVL XAR6, *-SP[16] ; reload the twiddle factor base pointer
MOVL XAR2, *+XAR4[0] ; load FFT input buffer base pointer
MOVL XAR3, *+XAR4[2] ; load FFT work buffer pointer
MOVL ACC, XAR2 ; P stores offset between even and odd butterflies
ADDL ACC, P
MOVL XAR2, ACC
MOVL ACC, XAR3
ADDL ACC, P
MOVL XAR3, ACC
; pre-load the pipeline
VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(0)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VNOP
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(1)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP5, #13 ; 16 butterflies in one subgroup
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(0) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(2)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP5:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
VMOV32 *XAR3++,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(2) = VR6
ADD PL, #64 ; move to the next butterfly group
BANZ _STAGE5_LOOP, AR0--
;========================================================================
; FFT stage 6: N/64 groups 64-pt FFT
;========================================================================
ZAPA
MOV AR0, #3 ; loop 4 times (sub groups)
MOV AR1, #62 ; butterfy size 32 samples (I/Q), excluding one ++ operation
MOVL *-SP[16], XAR6 ; save the current twiddle factor pointer
_STAGE6_LOOP:
MOVL XAR6, *-SP[16] ; reload the twiddle factor base pointer
MOVL XAR2, *+XAR4[2] ; load work buffer base pointer, as the input buffer
MOVL XAR3, *+XAR4[0] ; load FFT input buffer base pointer, as the work buffer
MOVL ACC, XAR2 ; P stores offset between even and odd butterflies
ADDL ACC, P
MOVL XAR2, ACC
MOVL ACC, XAR3
ADDL ACC, P
MOVL XAR3, ACC
; pre-load the pipeline
VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(0)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VNOP
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(1)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP6, #29 ; 32 butterflies in one subgroup
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(0) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(2)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP6:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
VMOV32 *XAR3++,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(2) = VR6
ADD PL, #128 ; move to the next butterfly group
BANZ _STAGE6_LOOP, AR0--
;========================================================================
; FFT stage 7: N/128 groups 128-pt FFT
;========================================================================
ZAPA
MOV AR0, #1 ; loop 2 times (sub groups)
MOV AR1, #126 ; butterfy size 64 samples (I/Q), excluding one ++ operation
MOVL *-SP[16], XAR6 ; save the current twiddle factor pointer
_STAGE7_LOOP:
MOVL XAR6, *-SP[16] ; reload the twiddle factor base pointer
MOVL XAR2, *+XAR4[0] ; load FFT input buffer base pointer
MOVL XAR3, *+XAR4[2] ; load FFT work buffer pointer
MOVL ACC, XAR2 ; P stores offset between even and odd butterflies
ADDL ACC, P
MOVL XAR2, ACC
MOVL ACC, XAR3
ADDL ACC, P
MOVL XAR3, ACC
; pre-load the pipeline
VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(0)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VNOP
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(1)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP7, #61 ; 64 butterflies in one subgroup
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(0) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(2)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP7:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
VMOV32 *XAR3++,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(2) = VR6
ADD PL, #256 ; move to the next butterfly group
BANZ _STAGE7_LOOP, AR0--
;========================================================================
; FFT stage 8: N/256 groups 256-pt FFT
;========================================================================
ZAPA
MOV AR1, #254 ; butterfy size 128 samples (I/Q), excluding one ++ operation
MOVL XAR2, *+XAR4[2] ; load work buffer base pointer, as the input buffer
MOVL XAR3, *+XAR4[0] ; load FFT input buffer base pointer, as the work buffer
; pre-load the pipeline
VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(0)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VNOP
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(1)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP7A, #63 ; 128 butterflies in one subgroup, broken into 2 RPTB blocks
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(0) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(2)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP7A:
.align 2
RPTB _BUTTERFLY_LOOP7B, #61;
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(0) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(2)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP7B:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
VMOV32 *XAR3++,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(2) = VR6
VMOV32 VR0, *-SP[2] ; restore VR registers
VMOV32 VR1, *-SP[4]
VMOV32 VR2, *-SP[6]
VMOV32 VR3, *-SP[8]
VMOV32 VR4, *-SP[10]
VMOV32 VR5, *-SP[12]
VMOV32 VR6, *-SP[14]
SUBB SP, #18 ; restore SP
POP XAR3
POP XAR2
POP XAR1
POP XAR0
LRETR
;############################################################################
; Close the Doxygen group.
;//! @}
;############################################################################
;; End of file
@@ -0,0 +1,475 @@
;;*****************************************************************************
;; \file source/vcu0/vcu0_cfft_64.asm
;;
;; \brief 64-pt complex FFT
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;*****************************************************************************
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;.cdecls C,LIST,"fft.h"
;############################################################################
;
;/*! \page CFFT_64 (Complex FFT -- 64 point)
;- This routine implements the 64-pt complex FFT algorithm
; The 6 FFT stages are fully unrolled to take advantage of
; the repeat block and parallel VCCP instructions.
;- In the first 3 stages, the butterflies are rearranged to
; group those whose offset is constant. For examples, the second
; stage is grouped by even butterflies and odd butterflies.
;- Last 3 stages, butterflies are grouped in sub-FFTs
; For example , the 5th stage has 2 groups, upper and lower
;*/
;############################################################################
;/*! \defgroup CFFT_64_FN (64pt CFFT Routines)
; @{ .....starts the defintion block
;*/
.global _cfft16_64p_calc
;//###########################################################################
.text
;/*! Calculate the 64 pt Complex FFT
; *
; * \param Handle to the structure, cfft16_t
; *
; * XAR4 - FFT handle
; * *+XAR4[0]: int *ipcbptr -> input pointer
; * *+XAR4[2]: int *workptr -> work buffer pointer
; * *+XAR4[4]: int *tfptr -> twiddle factor table pointer
; * *+XAR4[6]: int size -> Number of data points
; * *+XAR4[7]: int nrstage -> Number of FFT stages
; * *+XAR4[8]: int step -> Twiddle factor table search step
; * *+XAR4[9]: 0
; * *+XAR4[10]: int *brevptr -> Bit reversal table pointer
; *
; * Registers
; * XAR0: offset address
; * XAR1: offset address
; * XAR2: FFT input base pointer
; * XAR3: FFT output base pointer
; * XAR4: FFT handler pointer
; * XAR5:
; * XAR6: Twiddle Factor table base pointer
; * XAR7:
; *
; * [SP-2]: Stores twiddle factor pointer
; *
; * \return none
; */
_cfft16_64p_calc:
PUSH XAR0
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #18 ; allocate stack space for temperary variables
VMOV32 *-SP[2], VR0 ; save VRx to stack
VMOV32 *-SP[4], VR1
VMOV32 *-SP[6], VR2
VMOV32 *-SP[8], VR3
VMOV32 *-SP[10], VR4
VMOV32 *-SP[12], VR5
VMOV32 *-SP[14], VR6
SETC SXM ; sign extension mode
VSATON ; VSTATUS.SAT = 1
VRNDON ; rounding on
VSETSHR #16 ; VSTATUS.SHIFTR = RIGHT_SHIFT
VSETSHL #15 ; VSTATUS.SHIFTL = LEFT_SHIFT, each stage output is scaled by2
;========================================================================
; FFT stage 1: N/2 groups of 2-pt FFT
;========================================================================
MOVL XAR2, *+XAR4[0] ; load FFT input buffer base pointer
MOVL XAR3, *+XAR4[2] ; load FFT work buffer pointer
MOVL XAR6, *+XAR4[4] ; load twiddle factor base pointer
; pre-load the pipeline
VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(0)
VMOV32 VR1,*XAR2++ ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
VNOP
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(1)
VMOV32 VR1,*XAR2++ ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP1, 29 ; N/2-2 butterflies for each stage
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *XAR3++,VR6 ; Ib':Rb'(0) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(2)
VMOV32 VR1,*XAR2++ ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP1:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *XAR3++,VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
VMOV32 *XAR3++,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *XAR3++,VR6 ; Ib':Rb'(2) = VR6
;========================================================================
; FFT stage 2: N/4 groups 4-pt FFT
;========================================================================
ZAPA
MOV AR0, #1 ; loop twice , even and odd butterflies
_STAGE2_LOOP:
MOVL XAR2, *+XAR4[2] ; load work buffer base pointer, as the input buffer
MOVL XAR3, *+XAR4[0] ; load FFT input buffer base pointer, as the work buffer
MOVL ACC, XAR2 ; P stores offset between even and odd butterflies
ADDL ACC, P
MOVL XAR2, ACC
MOVL ACC, XAR3
ADDL ACC, P
MOVL XAR3, ACC
MOV AR1, #4 ; butterfy size 2 samples (I/Q)
; pre-load the pipeline
VMOV32 VR4,*XAR2 ; VR4 = Ia:Ra(0)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
ADDB XAR2, #8 ; move to the next butterfly
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2 ; VR4 = Ia:Ra(1)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP2, #13 ; 16 butterflies for even butterflies
ADDB XAR2, #8 ; move to the next butterfly
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(0) = VR6
ADDB XAR3, #8
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2 ; VR4 = Ia:Ra(2)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP2:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
ADDB XAR3, #8
VMOV32 *XAR3,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(2) = VR6
ADD PL, #2
BANZ _STAGE2_LOOP, AR0--
;========================================================================
; FFT stage 3: N/8 groups 8-pt FFT
;========================================================================
ZAPA
MOV AR0, #3 ; loop four times
MOV AR1, #8 ; butterfy size 4 samples (I/Q)
_STAGE3_LOOP:
MOVL XAR2, *+XAR4[0] ; load FFT input buffer base pointer
MOVL XAR3, *+XAR4[2] ; load FFT work buffer pointer
MOVL ACC, XAR2 ; P stores offset between even and odd butterflies
ADDL ACC, P
MOVL XAR2, ACC
MOVL ACC, XAR3
ADDL ACC, P
MOVL XAR3, ACC
; pre-load the pipeline
VMOV32 VR4,*XAR2 ; VR4 = Ia:Ra(0)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
ADDB XAR2, #16 ; move to the next butterfly
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2 ; VR4 = Ia:Ra(1)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP3, #5 ; 8 butterflies for even butterflies
ADDB XAR2, #16 ; move to the next butterfly
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(0) = VR6
ADDB XAR3, #16
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2 ; VR4 = Ia:Ra(2)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP3:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
ADDB XAR3, #16
VMOV32 *XAR3,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(2) = VR6
ADD PL, #2 ;; move to the next butterfly group
BANZ _STAGE3_LOOP, AR0--
;========================================================================
; FFT stage 4: N/16 groups 16-pt FFT
;========================================================================
ZAPA
MOV AR0, #3 ; loop four times (sub groups)
MOV AR1, #14 ; butterfy size 8 samples (I/Q), excluding one ++ operation
MOVL *-SP[16], XAR6 ; save the current twiddle factor pointer
_STAGE4_LOOP:
MOVL XAR6, *-SP[16] ; reload the twiddle factor base pointer
MOVL XAR2, *+XAR4[2] ; load work buffer base pointer, as the input buffer
MOVL XAR3, *+XAR4[0] ; load FFT input buffer base pointer, as the work buffer
MOVL ACC, XAR2 ; P stores offset between even and odd butterflies
ADDL ACC, P
MOVL XAR2, ACC
MOVL ACC, XAR3
ADDL ACC, P
MOVL XAR3, ACC
; pre-load the pipeline
VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(0)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VNOP
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(1)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP4, #5 ; 8 butterflies in one subgroup
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(0) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(2)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP4:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
VMOV32 *XAR3++,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(2) = VR6
ADD PL, #32 ;; move to the next butterfly group
BANZ _STAGE4_LOOP, AR0--
;========================================================================
; FFT stage 5: N/32 groups 32-pt FFT
;========================================================================
ZAPA
MOV AR0, #1 ; loop two times (sub groups)
MOV AR1, #30 ; butterfy size 16 samples (I/Q), excluding one ++ operation
MOVL *-SP[16], XAR6 ; save the current twiddle factor pointer
_STAGE5_LOOP:
MOVL XAR6, *-SP[16] ; reload the twiddle factor base pointer
MOVL XAR2, *+XAR4[0] ; load FFT input buffer base pointer
MOVL XAR3, *+XAR4[2] ; load FFT work buffer pointer
MOVL ACC, XAR2 ; P stores offset between even and odd butterflies
ADDL ACC, P
MOVL XAR2, ACC
MOVL ACC, XAR3
ADDL ACC, P
MOVL XAR3, ACC
; pre-load the pipeline
VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(0)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VNOP
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(1)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP5, #13 ; 16 butterflies in one subgroup
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(0) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(2)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP5:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
VMOV32 *XAR3++,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(2) = VR6
ADD PL, #64 ;; move to the next butterfly group
BANZ _STAGE5_LOOP, AR0--
;========================================================================
; FFT stage 6: N/64 groups 64-pt FFT
;========================================================================
ZAPA
MOV AR1, #62 ; butterfy size 32 samples (I/Q), excluding one ++ operation
MOVL XAR2, *+XAR4[2] ; load work buffer base pointer, as the input buffer
MOVL XAR3, *+XAR4[0] ; load FFT input buffer base pointer, as the work buffer
; pre-load the pipeline
VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(0)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(0)
VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(0)
VCMPY VR3, VR2, VR1, VR0 ;
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VNOP
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(1)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(1)
.align 2
RPTB _BUTTERFLY_LOOP6, #29 ; 32 butterflies in one subgroup
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(0) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(0) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
|| VMOV32 VR0,*XAR6++ ; VR0 = COSn:SINn(1)
VCDADD16 VR5, VR4, VR3, VR2
|| VMOV32 VR4,*XAR2++ ; VR4 = Ia:Ra(2)
VMOV32 VR1,*+XAR2[AR1] ; VR1 = Ib:Rb(2)
_BUTTERFLY_LOOP6:
VCMPY VR3, VR2, VR1, VR0
|| VMOV32 *XAR3++,VR5 ; Ia':Ra'(1) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(1) = VR6
VCDSUB16 VR6, VR4, VR3, VR2
VCDADD16 VR5, VR4, VR3, VR2
VMOV32 *XAR3++,VR5 ; Ia':Ra'(2) = VR5
VMOV32 *+XAR3[AR1],VR6 ; Ib':Rb'(2) = VR6
VMOV32 VR0, *-SP[2] ; restore VR registers
VMOV32 VR1, *-SP[4]
VMOV32 VR2, *-SP[6]
VMOV32 VR3, *-SP[8]
VMOV32 VR4, *-SP[10]
VMOV32 VR5, *-SP[12]
VMOV32 VR6, *-SP[14]
SUBB SP, #18 ; restore SP
POP XAR3
POP XAR2
POP XAR1
POP XAR0
LRETR
;############################################################################
; Close the Doxygen group.
;//! @}
;############################################################################
;; End of file
@@ -0,0 +1,210 @@
;;*****************************************************************************
;; \file source/vcu0/vcu0_cfft_twiddleFactors.asm
;;
;; \brief Twiddle factors for VCU-0 Code
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;*****************************************************************************
;;
;;
;;*****************************************************************************
;;
;############################################################################
;
;/*! \page CFFT16_TF (Set of Twiddle Factors)
;This file contains 512 pairs of twiddle factors arragned in the following
; format:
;
; Each twiddle factor is a complex number and takes up 2 words. They are
; ordered as Imaginary : Real pairs in the Q15 format. They are arranged as
; follows:
; W(2,0)
; W(4,0) W(4,2)
; W(8,0) W(8,1) W(8,2) W(8,3)
; W(16,0) W(16,1) W(16,2) W(16,3) W(16,4) W(16,5) W(16,6) W(16,7)
; W(32,0) ... W(32,15)
; W(64,0) ... W(64,31)
; W(128,0)... W(128,63)
; W(256,0)... W(256,127)
; W(512,0)... W(512,255)
;*/
;############################################################################
.global _CFFT16_TF
.sect .econst
_CFFT16_TF:
.word 0, 32767, 0, 32767, -32767, 0, 0, 32767
.word -23170, 23170, -32767, 0, -23170, -23170, 0, 32767
.word -12539, 30273, -23170, 23170, -30273, 12539, -32767, 0
.word -30273, -12539, -23170, -23170, -12539, -30273, 0, 32767
.word -6393, 32137, -12539, 30273, -18204, 27245, -23170, 23170
.word -27245, 18204, -30273, 12539, -32137, 6393, -32767, 0
.word -32137, -6393, -30273, -12539, -27245, -18204, -23170, -23170
.word -18204, -27245, -12539, -30273, -6393, -32137, 0, 32767
.word -3212, 32609, -6393, 32137, -9512, 31356, -12539, 30273
.word -15446, 28898, -18204, 27245, -20787, 25329, -23170, 23170
.word -25329, 20787, -27245, 18204, -28898, 15446, -30273, 12539
.word -31356, 9512, -32137, 6393, -32609, 3212, -32767, 0
.word -32609, -3212, -32137, -6393, -31356, -9512, -30273, -12539
.word -28898, -15446, -27245, -18204, -25329, -20787, -23170, -23170
.word -20787, -25329, -18204, -27245, -15446, -28898, -12539, -30273
.word -9512, -31356, -6393, -32137, -3212, -32609, 0, 32767
.word -1608, 32728, -3212, 32609, -4808, 32412, -6393, 32137
.word -7962, 31785, -9512, 31356, -11039, 30852, -12539, 30273
.word -14010, 29621, -15446, 28898, -16846, 28105, -18204, 27245
.word -19519, 26319, -20787, 25329, -22005, 24279, -23170, 23170
.word -24279, 22005, -25329, 20787, -26319, 19519, -27245, 18204
.word -28105, 16846, -28898, 15446, -29621, 14010, -30273, 12539
.word -30852, 11039, -31356, 9512, -31785, 7962, -32137, 6393
.word -32412, 4808, -32609, 3212, -32728, 1608, -32767, 0
.word -32728, -1608, -32609, -3212, -32412, -4808, -32137, -6393
.word -31785, -7962, -31356, -9512, -30852, -11039, -30273, -12539
.word -29621, -14010, -28898, -15446, -28105, -16846, -27245, -18204
.word -26319, -19519, -25329, -20787, -24279, -22005, -23170, -23170
.word -22005, -24279, -20787, -25329, -19519, -26319, -18204, -27245
.word -16846, -28105, -15446, -28898, -14010, -29621, -12539, -30273
.word -11039, -30852, -9512, -31356, -7962, -31785, -6393, -32137
.word -4808, -32412, -3212, -32609, -1608, -32728, 0, 32767
.word -804, 32757, -1608, 32728, -2410, 32678, -3212, 32609
.word -4011, 32521, -4808, 32412, -5602, 32285, -6393, 32137
.word -7179, 31971, -7962, 31785, -8739, 31580, -9512, 31356
.word -10278, 31113, -11039, 30852, -11793, 30571, -12539, 30273
.word -13279, 29956, -14010, 29621, -14732, 29268, -15446, 28898
.word -16151, 28510, -16846, 28105, -17530, 27683, -18204, 27245
.word -18868, 26790, -19519, 26319, -20159, 25832, -20787, 25329
.word -21403, 24811, -22005, 24279, -22594, 23731, -23170, 23170
.word -23731, 22594, -24279, 22005, -24811, 21403, -25329, 20787
.word -25832, 20159, -26319, 19519, -26790, 18868, -27245, 18204
.word -27683, 17530, -28105, 16846, -28510, 16151, -28898, 15446
.word -29268, 14732, -29621, 14010, -29956, 13279, -30273, 12539
.word -30571, 11793, -30852, 11039, -31113, 10278, -31356, 9512
.word -31580, 8739, -31785, 7962, -31971, 7179, -32137, 6393
.word -32285, 5602, -32412, 4808, -32521, 4011, -32609, 3212
.word -32678, 2410, -32728, 1608, -32757, 804, -32767, 0
.word -32757, -804, -32728, -1608, -32678, -2410, -32609, -3212
.word -32521, -4011, -32412, -4808, -32285, -5602, -32137, -6393
.word -31971, -7179, -31785, -7962, -31580, -8739, -31356, -9512
.word -31113, -10278, -30852, -11039, -30571, -11793, -30273, -12539
.word -29956, -13279, -29621, -14010, -29268, -14732, -28898, -15446
.word -28510, -16151, -28105, -16846, -27683, -17530, -27245, -18204
.word -26790, -18868, -26319, -19519, -25832, -20159, -25329, -20787
.word -24811, -21403, -24279, -22005, -23731, -22594, -23170, -23170
.word -22594, -23731, -22005, -24279, -21403, -24811, -20787, -25329
.word -20159, -25832, -19519, -26319, -18868, -26790, -18204, -27245
.word -17530, -27683, -16846, -28105, -16151, -28510, -15446, -28898
.word -14732, -29268, -14010, -29621, -13279, -29956, -12539, -30273
.word -11793, -30571, -11039, -30852, -10278, -31113, -9512, -31356
.word -8739, -31580, -7962, -31785, -7179, -31971, -6393, -32137
.word -5602, -32285, -4808, -32412, -4011, -32521, -3212, -32609
.word -2410, -32678, -1608, -32728, -804, -32757, 0, 32767
.word -402, 32765, -804, 32757, -1206, 32745, -1608, 32728
.word -2009, 32705, -2410, 32678, -2811, 32646, -3212, 32609
.word -3612, 32567, -4011, 32521, -4410, 32469, -4808, 32412
.word -5205, 32351, -5602, 32285, -5998, 32213, -6393, 32137
.word -6786, 32057, -7179, 31971, -7571, 31880, -7962, 31785
.word -8351, 31685, -8739, 31580, -9126, 31470, -9512, 31356
.word -9896, 31237, -10278, 31113, -10659, 30985, -11039, 30852
.word -11417, 30714, -11793, 30571, -12167, 30424, -12539, 30273
.word -12910, 30117, -13279, 29956, -13645, 29791, -14010, 29621
.word -14372, 29447, -14732, 29268, -15090, 29085, -15446, 28898
.word -15800, 28706, -16151, 28510, -16499, 28310, -16846, 28105
.word -17189, 27896, -17530, 27683, -17869, 27466, -18204, 27245
.word -18537, 27019, -18868, 26790, -19195, 26556, -19519, 26319
.word -19841, 26077, -20159, 25832, -20475, 25582, -20787, 25329
.word -21096, 25072, -21403, 24811, -21705, 24547, -22005, 24279
.word -22301, 24007, -22594, 23731, -22884, 23452, -23170, 23170
.word -23452, 22884, -23731, 22594, -24007, 22301, -24279, 22005
.word -24547, 21705, -24811, 21403, -25072, 21096, -25329, 20787
.word -25582, 20475, -25832, 20159, -26077, 19841, -26319, 19519
.word -26556, 19195, -26790, 18868, -27019, 18537, -27245, 18204
.word -27466, 17869, -27683, 17530, -27896, 17189, -28105, 16846
.word -28310, 16499, -28510, 16151, -28706, 15800, -28898, 15446
.word -29085, 15090, -29268, 14732, -29447, 14372, -29621, 14010
.word -29791, 13645, -29956, 13279, -30117, 12910, -30273, 12539
.word -30424, 12167, -30571, 11793, -30714, 11417, -30852, 11039
.word -30985, 10659, -31113, 10278, -31237, 9896, -31356, 9512
.word -31470, 9126, -31580, 8739, -31685, 8351, -31785, 7962
.word -31880, 7571, -31971, 7179, -32057, 6786, -32137, 6393
.word -32213, 5998, -32285, 5602, -32351, 5205, -32412, 4808
.word -32469, 4410, -32521, 4011, -32567, 3612, -32609, 3212
.word -32646, 2811, -32678, 2410, -32705, 2009, -32728, 1608
.word -32745, 1206, -32757, 804, -32765, 402, -32767, 0
.word -32765, -402, -32757, -804, -32745, -1206, -32728, -1608
.word -32705, -2009, -32678, -2410, -32646, -2811, -32609, -3212
.word -32567, -3612, -32521, -4011, -32469, -4410, -32412, -4808
.word -32351, -5205, -32285, -5602, -32213, -5998, -32137, -6393
.word -32057, -6786, -31971, -7179, -31880, -7571, -31785, -7962
.word -31685, -8351, -31580, -8739, -31470, -9126, -31356, -9512
.word -31237, -9896, -31113, -10278, -30985, -10659, -30852, -11039
.word -30714, -11417, -30571, -11793, -30424, -12167, -30273, -12539
.word -30117, -12910, -29956, -13279, -29791, -13645, -29621, -14010
.word -29447, -14372, -29268, -14732, -29085, -15090, -28898, -15446
.word -28706, -15800, -28510, -16151, -28310, -16499, -28105, -16846
.word -27896, -17189, -27683, -17530, -27466, -17869, -27245, -18204
.word -27019, -18537, -26790, -18868, -26556, -19195, -26319, -19519
.word -26077, -19841, -25832, -20159, -25582, -20475, -25329, -20787
.word -25072, -21096, -24811, -21403, -24547, -21705, -24279, -22005
.word -24007, -22301, -23731, -22594, -23452, -22884, -23170, -23170
.word -22884, -23452, -22594, -23731, -22301, -24007, -22005, -24279
.word -21705, -24547, -21403, -24811, -21096, -25072, -20787, -25329
.word -20475, -25582, -20159, -25832, -19841, -26077, -19519, -26319
.word -19195, -26556, -18868, -26790, -18537, -27019, -18204, -27245
.word -17869, -27466, -17530, -27683, -17189, -27896, -16846, -28105
.word -16499, -28310, -16151, -28510, -15800, -28706, -15446, -28898
.word -15090, -29085, -14732, -29268, -14372, -29447, -14010, -29621
.word -13645, -29791, -13279, -29956, -12910, -30117, -12539, -30273
.word -12167, -30424, -11793, -30571, -11417, -30714, -11039, -30852
.word -10659, -30985, -10278, -31113, -9896, -31237, -9512, -31356
.word -9126, -31470, -8739, -31580, -8351, -31685, -7962, -31785
.word -7571, -31880, -7179, -31971, -6786, -32057, -6393, -32137
.word -5998, -32213, -5602, -32285, -5205, -32351, -4808, -32412
.word -4410, -32469, -4011, -32521, -3612, -32567, -3212, -32609
.word -2811, -32646, -2410, -32678, -2009, -32705, -1608, -32728
.word -1206, -32745, -804, -32757, -402, -32765, 0, 0
;; End of file
@@ -0,0 +1,662 @@
;;*****************************************************************************
;; \file source/vcu0/vcu0_cfft_utils.asm
;;
;; \brief Initialization and auxilliary functions used in the fft calculations
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;*****************************************************************************
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
.cdecls C,LIST,"VCU0_FFT.h" ;needed as the table CFFT16_TF is defined in fft.h
;;*****************************************************************************
;; global defines
.if __TI_EABI__
.asg CFFT16_TF,_CFFT16_TF
.endif
;############################################################################
;
;/*! \page CFFT16_UTILS (Initialization and Auxilliary Functions)
; The following initialization and utility functions are available:
; - void cfft16_init(void *fft_handle)
; - void cfft16_brev(void *fft_handle)
; - void cfft16_flip_re_img(void *fft_handle)
; - void cfft16_flip_re_img_conj(void *fft_handle)
; - void cfft16_unpack_asm(void *fft_handle)
; - void cifft16_pack_asm(void *fft_handle)
;*/
;############################################################################
;/*! \defgroup CFFT_128_FN (128pt CFFT Routines)
; @{ .....starts the defintion block
;*/
.global _cfft16_init,_cfft16_brev,_cfft16_tbl_brev
.global _cfft16_flip_re_img,_cfft16_flip_re_img_conj
.global _cfft16_unpack_asm,_cifft16_pack_asm
;//###########################################################################
.text
;/*! Twiddle Factor Table Initialization
; *
; * \param Handle to the structure, cfft16_t
; *
; * Initializes the tfptr to the start of the twiddle factor
; * table in memory
; *
; * XAR4 - FFT handle
; * *+XAR4[0]: int *ipcbptr -> input pointer
; * *+XAR4[2]: int *workptr -> work buffer pointer
; * *+XAR4[4]: int *tfptr -> twiddle factor table pointer
; * *+XAR4[6]: int size -> Number of data points
; * *+XAR4[7]: int nrstage -> Number of FFT stages
; * *+XAR4[8]: int step -> Twiddle factor table search step
; * *+XAR4[9]: 0
; * *+XAR4[10]: int *brevptr -> Bit reversal table pointer
; *
; * \return none
; */
_cfft16_init:
; Twiddle factor Initialisation
MOVL XAR5,#_CFFT16_TF ;
MOVL *+XAR4[4],XAR5 ; tfptr->CFFT16_TF
LRETR
;/*! Bit-Reversed Indexing
; *
; * \param Handle to the structure, cfft16_t
; *
; * Rearranges the input data in bit-reveresed index format. If the number
; * of FFT stages, the data is bit-reversed into the work buffer and then copied
; * back to the input buffer. In this respect the bit reversal is considered to be
; * in-place. For an odd number of stages the bit-reversed output is placed
; * in the work buffer (off-place). The FFT (not the bit reversal function)
; * will then transfer the data back to the input buffer pointed to by ipcbptr
; *
; * XAR4 - FFT handle
; * *+XAR4[0]: int *ipcbptr -> input pointer
; * *+XAR4[2]: int *workptr -> work buffer pointer
; * *+XAR4[4]: int *tfptr -> twiddle factor table pointer
; * *+XAR4[6]: int size -> Number of data points
; * *+XAR4[7]: int nrstage -> Number of FFT stages
; * *+XAR4[8]: int step -> Twiddle factor table search step
; * *+XAR4[9]: 0
; * *+XAR4[10]: int *brevptr -> Bit reversal table pointer
; *
; * \return none
; */
_cfft16_brev:
PUSH XAR0
PUSH XAR1 ; Context Save
PUSH XAR2
PUSH XAR3
MOVL XAR2,*XAR4 ; XAR2=ipcbptr, input array
MOVL XAR3, *+XAR4[2] ; XAR3=work buffer
MOVZ AR0,*+XAR4[6] ; load FFT size N
MOV ACC,*+XAR4[6] ; load FFT size N-1
ASR AL, #2 ; assuming the input is multiple of 2
MOV AR1, AL
SUBB XAR1, #1
.align (2)
RPTB _brev_loop, AR1
LPADDR ; Make sure AMODE = 1
.lp_amode ; Tell assembler that AMODE = 1
NOP *,ARP2 ; Set ARP pointer to point to XAR2
MOVL ACC,*++,ARP3 ; Load ACC with location pointed to by XAR2,
; post-increment XAR2 and Set ARP pointer to XAR3
MOVL *BR0++,ACC,ARP2 ; Store ACC into location pointed to by XAR3,
; Set ARP pointer to point to XAR2
MOVL ACC,*++,ARP3 ; Load ACC with location pointed to by XAR2,
; post-increment XAR2 and set ARP pointer to XAR3
MOVL *BR0++,ACC,ARP2 ; Store ACC into location pointed to by XAR3,
; Set ARP pointer to point to XAR2
MOVL ACC,*++,ARP3 ; Load ACC with location pointed to by XAR2,
; post-increment XAR2 and set ARP pointer to XAR3
MOVL *BR0++,ACC,ARP2 ; Store ACC into location pointed to by XAR3,
; Set ARP pointer to point to XAR2
MOVL ACC,*++,ARP3 ; Load ACC with location pointed to by XAR2,
; post-increment XAR2 and set ARP pointer to XAR3
MOVL *BR0++,ACC,ARP2 ; Store ACC into location pointed to by XAR3,
; Set ARP pointer to point to XAR2
_brev_loop:
C28ADDR ; Return to C28x address mode
.c28_amode
MOVB XAR1, #7
MOV ACC,*+XAR4[AR1] ; load nstage
ANDB AL, #0x1 ; Test odd or even
SBF _copy_loop, NEQ ; if odd, do not copy, FFT will transfer data back to the input buffer
; if even, copy to the input buffer
MOVL XAR2, *+XAR4[0] ; load FFT input buffer base pointer
MOVL XAR3, *+XAR4[2] ; XAR3=work buffer
MOV ACC,*+XAR4[6] ; load FFT size N-1
ASR AL, #3 ; assuming the input is multiple of 8
MOV AR1, AL
SUBB XAR1, #1
.align (2)
RPTB _copy_loop, AR1
MOVL ACC, *XAR3++
MOVL *XAR2++, ACC
MOVL ACC, *XAR3++
MOVL *XAR2++, ACC
MOVL ACC, *XAR3++
MOVL *XAR2++, ACC
MOVL ACC, *XAR3++
MOVL *XAR2++, ACC
MOVL ACC, *XAR3++
MOVL *XAR2++, ACC
MOVL ACC, *XAR3++
MOVL *XAR2++, ACC
MOVL ACC, *XAR3++
MOVL *XAR2++, ACC
MOVL ACC, *XAR3++
MOVL *XAR2++, ACC
_copy_loop:
POP XAR3
POP XAR2
POP XAR1
POP XAR0
LRETR
;/*! Table based Bit Reversal
; *
; * \param Handle to the structure, cfft16_t
; *
; * Uses the table, pointed to by brevptr, to rearrange the input data
; * in bit reversed index format
; *
; * XAR4 - FFT handle
; * *+XAR4[0]: int *ipcbptr -> input pointer
; * *+XAR4[2]: int *workptr -> work buffer pointer
; * *+XAR4[4]: int *tfptr -> twiddle factor table pointer
; * *+XAR4[6]: int size -> Number of data points
; * *+XAR4[7]: int nrstage -> Number of FFT stages
; * *+XAR4[8]: int step -> Twiddle factor table search step
; * *+XAR4[9]: 0
; * *+XAR4[10]: int *brevptr -> Bit reversal table pointer
; *
; * \return none
; */
_cfft16_tbl_brev:
PUSH XAR0
PUSH XAR1 ; Context Save
PUSH XAR2
PUSH XAR3
PUSH XAR4
MOVL XAR2, *+XAR4[0] ; load FFT input buffer base pointer
MOVL XAR3, *+XAR4[2] ; load FFT work buffer pointer
MOV AR0, #10
MOVL XAR7, *+XAR4[AR0] ; load bit reversal table pointer
.align (2)
RPTB _bit_reversal_loop, #15
MOVZ AR0, *XAR7++
MOVL ACC, *XAR2++
MOVL *+XAR3[AR0], ACC
MOVZ AR1, *XAR7++
MOVL ACC, *XAR2++
MOVL *+XAR3[AR1], ACC
MOVZ AR0, *XAR7++
MOVL ACC, *XAR2++
MOVL *+XAR3[AR0], ACC
MOVZ AR1, *XAR7++
MOVL ACC, *XAR2++
MOVL *+XAR3[AR1], ACC
_bit_reversal_loop:
MOVL XAR2, *+XAR4[0] ; load FFT input buffer base pointer
MOVL XAR3, *+XAR4[2] ; load FFT work buffer pointer
.align (2)
RPTB _copy_loop2, #7
MOVL ACC, *XAR3++
MOVL *XAR2++, ACC
MOVL ACC, *XAR3++
MOVL *XAR2++, ACC
MOVL ACC, *XAR3++
MOVL *XAR2++, ACC
MOVL ACC, *XAR3++
MOVL *XAR2++, ACC
MOVL ACC, *XAR3++
MOVL *XAR2++, ACC
MOVL ACC, *XAR3++
MOVL *XAR2++, ACC
MOVL ACC, *XAR3++
MOVL *XAR2++, ACC
MOVL ACC, *XAR3++
MOVL *XAR2++, ACC
_copy_loop2:
POP XAR4
POP XAR3
POP XAR2
POP XAR1
POP XAR0
LRETR
;/*! Flip real and imaginary parts of complex number
; *
; * \param Handle to the structure, cfft16_t
; *
; * This functions is needed in the computation of real FFTs to ensure that
; * the real part of the complex number always ends up at the high word of
; * a 32 bit address
; *
; * XAR4 - FFT handle
; * *+XAR4[0]: int *ipcbptr -> input pointer
; * *+XAR4[2]: int *workptr -> work buffer pointer
; * *+XAR4[4]: int *tfptr -> twiddle factor table pointer
; * *+XAR4[6]: int size -> Number of data points
; * *+XAR4[7]: int nrstage -> Number of FFT stages
; * *+XAR4[8]: int step -> Twiddle factor table search step
; * *+XAR4[9]: 0
; * *+XAR4[10]: int *brevptr -> Bit reversal table pointer
; *
; * \return none
; */
_cfft16_flip_re_img:
PUSH XAR1
PUSH XAR2
MOVL XAR2, *+XAR4[0] ; load FFT input buffer base pointer
MOVL ACC, *+XAR4[6] ;
ASR AL, #2 ; assuming the input is multiple of 4
MOV AR1, AL
SUB AR1, #1
.align (2)
RPTB FLIP_LOOP, AR1
MOV AH, *+XAR2[0];
MOV AL, *+XAR2[1];
MOVL *XAR2++, ACC
MOV AH, *+XAR2[0];
MOV AL, *+XAR2[1];
MOVL *XAR2++, ACC
MOV AH, *+XAR2[0];
MOV AL, *+XAR2[1];
MOVL *XAR2++, ACC
MOV AH, *+XAR2[0];
MOV AL, *+XAR2[1];
MOVL *XAR2++, ACC
FLIP_LOOP:
POP XAR2
POP XAR1
LRETR
;/*! Flip real and imaginary parts of complex number and conjugate
; *
; * \param Handle to the structure, cfft16_t
; *
; * This functions is needed in the computation of real IFFTs to ensure that
; * the real part of the complex number always ends up at the high word of
; * a 32 bit address
; *
; * XAR4 - FFT handle
; * *+XAR4[0]: int *ipcbptr -> input pointer
; * *+XAR4[2]: int *workptr -> work buffer pointer
; * *+XAR4[4]: int *tfptr -> twiddle factor table pointer
; * *+XAR4[6]: int size -> Number of data points
; * *+XAR4[7]: int nrstage -> Number of FFT stages
; * *+XAR4[8]: int step -> Twiddle factor table search step
; * *+XAR4[9]: 0
; * *+XAR4[10]: int *brevptr -> Bit reversal table pointer
; *
; * \return none
; */
_cfft16_flip_re_img_conj:
PUSH XAR1
PUSH XAR2
MOVL XAR2, *+XAR4[0] ; load FFT input buffer base pointer
MOVL XAR1, *+XAR4[6] ;
SUB AR1, #1
FLIP_LOOP_CONJ:
MOV AH, *+XAR2[0];
NEG AH ; conjugate the imaginary part
MOV AL, *+XAR2[1];
MOVL *XAR2++, ACC
BANZ FLIP_LOOP_CONJ,AR1--
POP XAR2
POP XAR1
LRETR
;/*! Real FFT Unpack
; *
; * \param Handle to the structure, cfft16_t
; *
; * When using an N/2 pt complex FFT to compute the N-pt real FFT. The
; * result of the complex FFT must be unpacked to get the real value. Refer
; * to http://www.engineeringproductivitytools.com/stuff/T0001/PT10.HTM
; * for more info
; *
; * XAR4 - FFT handle
; * *+XAR4[0]: int *ipcbptr -> input pointer
; * *+XAR4[2]: int *workptr -> work buffer pointer
; * *+XAR4[4]: int *tfptr -> twiddle factor table pointer
; * *+XAR4[6]: int size -> Number of data points
; * *+XAR4[7]: int nrstage -> Number of FFT stages
; * *+XAR4[8]: int step -> Twiddle factor table search step
; * *+XAR4[9]: 0
; * *+XAR4[10]: int *brevptr -> Bit reversal table pointer
; *
; * Registers used
; * AR1: FFT size
; * XAR2: FFT buffer upper pointer
; * XAR3: FFT buffer lower pointer
; * XAR4: FFT handle pointer
; * XAR5
; * XAR6: twiddle factor pointer
; *
; * \return none
; */
_cfft16_unpack_asm:
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #18 ; allocate stack space for temperary variables
VMOV32 *-SP[6], VR0 ; save VRx to stack
VMOV32 *-SP[8], VR1
VMOV32 *-SP[10], VR2
VMOV32 *-SP[12], VR3
VMOV32 *-SP[14], VR4
VMOV32 *-SP[16], VR5
VMOV32 *-SP[18], VR6
SETC SXM ; sign extension mode
ZAPA
VSATON ; VSTATUS.SAT = 1
VRNDON ; rounding on
VSETSHR #17 ; VSTATUS.SHIFTR = RIGHT_SHIFT, scale by 4
VSETSHL #15 ; VSTATUS.SHIFTL = LEFT_SHIFT
MOVL XAR2, *+XAR4[0] ; load FFT input buffer base pointer
MOVL XAR6, *+XAR4[4] ; load twiddle factor
MOVL ACC, *+XAR4[6] ; load number of points
MOV PL, AL ; save length
LSR AL, #1
SUB AL, #2 ; loop N/2-1 times
MOVZ AR1, AL
MOVL ACC, P
LSL ACC, #1 ; sin/cos pair
ADDL ACC, XAR6
MOVL XAR6, ACC ; twiddle factor offset by N
MOVL ACC, P ; load number of points
LSL ACC, #1 ; real/imag pair
ADDL ACC, XAR2 ; calculate lower half
SUB ACC, #2
MOVL XAR3, ACC
; process the first point X(0)
MOVL ACC, *XAR2
ADD AH, AL
ADD AH, #1
ASR AH, #1 ; (real+imag)/2 with rounding
MOV AL, #0
MOVL *XAR2++, ACC
.align (2)
RPTB _UNPACK_LOOP, AR1 ; loop for pairs
MOVL ACC, *XAR6++ ; load the twiddle factor
NEG AL ; conjugate
MOV *-SP[2], AH ; flip sin and cos
MOV *-SP[1], AL
VMOV32 VR0, *-SP[2]
VMOV32 VR2, *XAR2 ; load the upper point
VMOV32 VR1, *XAR3 ; load the lower point
VITDLADDSUB VR4, VR3, VR2, VR1 ; Fe(k) = {Z(k)+Z(N/2-k)*}/2
VMOV32 *-SP[2], VR4
VMOV32 *-SP[4], VR3
VITDHADDSUB VR4, VR3, VR2, VR1 ; Fo(k) = -j{Z(k)-Z(N/2-k)*}/2
VMOV16 VR4L, *-SP[2] ; reassemble Fe(k) and Fo(k)
VMOV16 VR3L, *-SP[4]
VMOV32 *-SP[2], VR3
VMOV32 VR1, *-SP[2]
VCMPY VR3, VR2, VR1, VR0 ; F(k) = Fe(k) - W(N,k)Fo(k)
VNOP
VCDADD16 VR5, VR4, VR3, VR2
VCDSUB16 VR6, VR4, VR3, VR2
VMOV32 *XAR3, VR5 ; lower half conjugate
MOV AL, *XAR3
NEG AL
MOV *XAR3, AL
SUBB XAR3, #2 ; move to the next lower point
VMOV32 *XAR2++, VR6
_UNPACK_LOOP:
MOVL ACC, *XAR3 ; the center point, X(N/2) = 0.5*conj(X(N/2))
NEG AL
ASR AL, #1
ASR AH, #1
MOVL *XAR3, ACC
VMOV32 VR0, *-SP[6] ; restore VR registers
VMOV32 VR1, *-SP[8]
VMOV32 VR2, *-SP[10]
VMOV32 VR3, *-SP[12]
VMOV32 VR4, *-SP[14]
VMOV32 VR5, *-SP[16]
VMOV32 VR6, *-SP[18]
SUBB SP, #18 ; restore SP
POP XAR3
POP XAR2
POP XAR1
LRETR
;/*! complex IFFT pack
; *
; * \param Handle to the structure, cfft16_t
; *
; * When calculating the IFFT of a Real FFT, the data must be packed before
; * using the complex IFFT to get the result. Refer to
; * http://www.engineeringproductivitytools.com/stuff/T0001/PT10.HTM
; * for more info
; *
; * XAR4 - FFT handle
; * *+XAR4[0]: int *ipcbptr -> input pointer
; * *+XAR4[2]: int *workptr -> work buffer pointer
; * *+XAR4[4]: int *tfptr -> twiddle factor table pointer
; * *+XAR4[6]: int size -> Number of data points
; * *+XAR4[7]: int nrstage -> Number of FFT stages
; * *+XAR4[8]: int step -> Twiddle factor table search step
; * *+XAR4[9]: 0
; * *+XAR4[10]: int *brevptr -> Bit reversal table pointer
; *
; * Registers used
; * AR1: FFT size
; * XAR2: FFT buffer upper pointer
; * XAR3: FFT buffer lower pointer
; * XAR4: FFT handle pointer
; * XAR5
; * XAR6: twiddle factor pointer
; *
; * \return none
; */
_cifft16_pack_asm:
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #18 ; allocate stack space for temperary variables
VMOV32 *-SP[6], VR0 ; save VRx to stack
VMOV32 *-SP[8], VR1
VMOV32 *-SP[10], VR2
VMOV32 *-SP[12], VR3
VMOV32 *-SP[14], VR4
VMOV32 *-SP[16], VR5
VMOV32 *-SP[18], VR6
SETC SXM ; sign extension mode
ZAPA
VSATON ; VSTATUS.SAT = 1
VRNDON ; rounding on
VSETSHR #17 ; VSTATUS.SHIFTR = RIGHT_SHIFT, scale by 4
VSETSHL #15 ; VSTATUS.SHIFTL = LEFT_SHIFT
MOVL XAR2, *+XAR4[0] ; load FFT input buffer base pointer
MOVL XAR6, *+XAR4[4] ; load twiddle factor
MOVL ACC, *+XAR4[6] ; load number of points
MOV PL, AL ; save length
LSR AL, #1
SUB AL, #2 ; loop N/2-1 times
MOVZ AR1, AL
MOVL ACC, P
LSL ACC, #1 ; sin/cos pair
ADDL ACC, XAR6
MOVL XAR6, ACC ; twiddle factor offset by N
MOVL ACC, P ; load number of points
LSL ACC, #1 ; real/imag pair
ADDL ACC, XAR2 ; calculate lower half
SUB ACC, #2
MOVL XAR3, ACC
; process the first point X(0)
MOVL ACC, *XAR2 ; conjugate
NEG AL
MOVL *XAR2++, ACC
.align (2)
; loop for pairs
RPTB _PACK_LOOP, AR1
MOVL ACC, *XAR6++ ; load the twiddle factor
MOV *-SP[2], AH ; flip sin and cos
MOV *-SP[1], AL
VMOV32 VR0, *-SP[2]
VMOV32 VR2, *XAR2 ; load the upper point
VMOV32 VR1, *XAR3 ; load the lower point
VITDLADDSUB VR4, VR3, VR2, VR1 ; Fe(k) = {Z(k)+Z(N/2-k)*}/2
VMOV32 *-SP[2], VR4 ; VR4L=VR2L-VR1L=SP[1]=imag(Fe(k))
VMOV32 *-SP[4], VR3 ; VR3L=VR2L+VR1L=SP[3]=imag(Fo(k))
VITDHADDSUB VR4, VR3, VR2, VR1 ; Fo(k) = -j{Z(k)-Z(N/2-k)*}/2
VMOV16 VR4L, *-SP[2] ; reassemble Fe(k) and Fo(k) VR4H =VR2H+VR1H= real(Fe(k))
VMOV16 VR3L, *-SP[4] ; VR3H = VR2H-VR1H=real(Fo(k))
VMOV32 *-SP[2], VR3
VMOV32 VR1, *-SP[2]
VCMPY VR3, VR2, VR1, VR0 ; F(k) = Fe(k) - W(N,k)Fo(k)
VNOP
VCDADD16 VR5, VR4, VR3, VR2
VCDSUB16 VR6, VR4, VR3, VR2
VMOV32 *XAR2, VR5 ; upper half conjugate
MOVL ACC, *XAR2
NEG AL
MOVL *XAR2++, ACC
VMOV32 *XAR3, VR6
SUBB XAR3, #2 ; move to the next lower point
_PACK_LOOP:
MOVL ACC, *XAR3 ; the center point, X(N/2) = 0.5(X(N/2))
ASR AL, #1
ASR AH, #1
MOVL *XAR3, ACC
VMOV32 VR0, *-SP[6] ; restore VR registers
VMOV32 VR1, *-SP[8]
VMOV32 VR2, *-SP[10]
VMOV32 VR3, *-SP[12]
VMOV32 VR4, *-SP[14]
VMOV32 VR5, *-SP[16]
VMOV32 VR6, *-SP[18]
SUBB SP, #18 ; restore SP
POP XAR3
POP XAR2
POP XAR1
LRETR
;############################################################################
; Close the Doxygen group.
;//! @}
;############################################################################
;; End of file
@@ -0,0 +1,726 @@
;;*****************************************************************************
;;! \file source/vcu0/vcu0_viterbi_k7_cr12_plc.asm
;;!
;;! \brief Viterbi Decoding K = 7, CR = 1/2
;;
;; \date Feb 12, 2013
;;!
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
.cdecls C,LIST,"vcu0_viterbi_decoder.h"
;############################################################################
;
;/*! \page VITERBI (Viterbi Decoder)
; The Viterbi decoder routines implement the
; PRIME standard (K=7, CR=1/2)
; - G0 = 1 + D + D2 +D3 + D6
; G1 = 1 + D2 + D3 + D5 + D6
; It performs;
; - Updated state metric for each state
; - Updates state transition histories
; - Metric scaling
; - Trace back and decode
;*/
;############################################################################
;/*! \defgroup VITERBI_FN (Viterbi Decoder Routines)
; @{ .....starts the defintion block
;*/
.if __TI_EABI__
.asg cnvDec_asm, _cnvDec_asm
.asg cnvDecInit_asm, _cnvDecInit_asm
.asg cnvDecMetricRescale_asm, _cnvDecMetricRescale_asm
.endif
.global _cnvDec_asm, _cnvDecInit_asm
.global _cnvDecMetricRescale_asm
;//###########################################################################
VIT_OUT_ODD: .set 0
;===============================================================================
; Viterbi working memory
;===============================================================================
.global _dold, _trn_tmp
_tran_hist .usect ".ebss", 560,2 ; 64 states (1bit/state), max 70 IBITS for G3 FCC
_dold .usect ".ebss", 64,2 ; old and new metric
_dnew .usect ".shadow", 64,2 ; old and new metric must be in different memory bank
_trn_tmp .usect ".ebss", 290,2 ; temp transition for pack, max 70 IBITS for G3 FCC
; temp trace output
_trn_s1_p .usect ".ebss", 2,2 ; ptr to where transition
_trn_s2_p .usect ".ebss", 2,2 ; update start
_trn_w1_p .usect ".ebss", 2,2 ; ptr to where trace ovlp2
_trn_w2_p .usect ".ebss", 2,2 ; should go (wrap)
.text
;======================================================================
; MACRO for flipping the 32-bit transition bits
; use *XAR7 as temporary memory location
;======================================================================
FLIP32: .macro
VMOV32 *XAR7, VR1 ; save transition bits into RAM
MOVL ACC, *XAR7
MOVB AL.LSB,*+XAR7[1] ; flip 32 bits
MOVB AH.LSB,*+XAR7[3]
MOVB AL.MSB,*+XAR7[0]
MOVB AH.MSB,*+XAR7[2]
FLIP AH
FLIP AL
.endm
;/*! Initialize Viterbi Decoder
; *
; * \param Number of Coded bits
; *
; * Initialize state metric table to a large negative value given by
; * CNV_DEC_METRIC_INIT and initialize the transition and wrap pointers
; *
; * AL : nTransBits
; *
; * \return none
; */
_cnvDecInit_asm:
SETC SXM ; sign extension mode
MOVW DP, #_trn_s1_p
MOVL XAR4, #_dold ; XAR4 = _dold
MOV *XAR4++, #0
RPT #(CNV_DEC_NUM_STATES-2)
||MOV *XAR4++, #CNV_DEC_METRIC_INIT
MOVL XAR4, #_tran_hist
MOVL @_trn_s1_p, XAR4 ; trn_s1_p = tran_hist[0][0]
LSL AL, #1
ADD AR4,AL
MOVL @_trn_s2_p, XAR4 ; trn_s2_p = tran_hist[nBits/2][0]
MOVL @_trn_w1_p, XAR4 ; trn_w1_p = tran_hist[nBits/2][0]
; (4 words/bits)
ADD AR4,AL
MOVL @_trn_w2_p, XAR4 ; trn_w2_p = tran_host[nBits][0]
LRETR
;/*! Viterbi Decoder
; *
; * \param Number of Coded bits
; * \param Address of input buffer
; * \param Address of output buffer
; * \param Mode of operation
; *
; * This routine performs the trellis decoding. It has four modes of
; * operation
; * - 0: Update metrics and transition, trace
; * and decodes all (for hdr)
; * - 1: Update metrics and transition only
; * 1st symbol in payload)
; * - 2: Update metrics and transition,
; * trace curr prv, decodes prv nBits/2 bits
; * - 3: Update metrics and transition,
; * trace curr prv, decodes curr+prv nBits/2 bits
; *
; * Register Usage
; * XAR0 - _dnew[32]
; * XAR1 - _dold
; * XAR2 - _dnew
; * XAR3 - trans_hist
; * XAR4 - data in
; * XAR5 - data_out / tran
; * AL - #input bits
; *
; * \note Decoder produces nBit/2 bits if flag=0/2 and
; * prv_blk+nBit/2 bits if flag=3
; *
; * \return none
; */
_cnvDec_asm:
;
; Save off everything for now. This can be reduced later
; if possible.
;
PUSH XAR0
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #4
LSR AL, #1 ; AL = nBits >> 1
MOV *-SP[1], AL ; Save nBits in stack (-SP[1])
MOV *-SP[2], AH ; Save flag in stack (-SP[2])
MOVL *-SP[4], XAR5 ; Save data_out
SETC SXM ; sign extension mode
SETC OVM ; no saturation
CMP AL, #0
BF _none_zero_acs, NEQ
; if # of output bits is zero, direct trace back
MOVW DP, #_trn_w1_p ; switch to previous tran_hist
MOVL XAR3, @_trn_w1_p
BF _cnv_dec_ovlp, UNC
_none_zero_acs:
SUBB AL, #1
MOVZ AR6, @AL ; AR6 = bit_in >> 1
; 2-bits per loop
MOVW DP, #_trn_s1_p
MOVL XAR2, #_dnew ; XAR2 = pts to _dnew[0]
MOVL XAR1, #_dold ; XAR1 = pts to _dold[0]
MOVL XAR0,#30 ; used for *+XAR2[AR0] addressing mode
MOVL XAR3, #_tran_hist ; XAR3 = pts to _tran_hist
CMP AH, #2 ; Check for flag
; If (flag = 2/3), start trace w/ trn_s1_p
BF _cnv_metric_update, LT
MOVL XAR3, @_trn_s1_p
_cnv_metric_update:
;Update branch matrices
VMOV32 VR0, *XAR4++
VITBM2 VR0
|| VMOV32 VR2, *XAR1++
;0(M=1,1)
VITDLADDSUB VR4,VR3,VR2,VR0
VITLSEL VR6,VR5,VR4,VR3
|| VMOV32 VR2, *XAR1++
;1(M=1,-1)
VITDHADDSUB VR4,VR3,VR2,VR0
VITHSEL VR6,VR5,VR4,VR3
|| VMOV32 VR2, *XAR1++
;2(M=1,1)
VITDLADDSUB VR4,VR3,VR2,VR0
|| VMOV32 *XAR2++, VR5
VITLSEL VR8,VR7,VR4,VR3
|| VMOV32 VR2, *XAR1++
;3(M=1,-1)
VITDHADDSUB VR4,VR3,VR2,VR0
|| VMOV32 *+XAR2[AR0], VR6
VITHSEL VR8,VR7,VR4,VR3
|| VMOV32 VR2, *XAR1++
;4(M=-1,-1)
VITDLSUBADD VR4,VR3,VR2,VR0
|| VMOV32 *XAR2++, VR7
VITLSEL VR6,VR5,VR4,VR3
|| VMOV32 VR2, *XAR1++
;5(M=-1,1)
VITDHSUBADD VR4,VR3,VR2,VR0
|| VMOV32 *+XAR2[AR0], VR8
VITHSEL VR6,VR5,VR4,VR3
|| VMOV32 VR2, *XAR1++
;6(M=-1,-1)
VITDLSUBADD VR4,VR3,VR2,VR0
|| VMOV32 *XAR2++, VR5
VITLSEL VR8,VR7,VR4,VR3
|| VMOV32 VR2, *XAR1++
;7(M=-1,1)
VITDHSUBADD VR4,VR3,VR2,VR0
|| VMOV32 *+XAR2[AR0], VR6
VITHSEL VR8,VR7,VR4,VR3
|| VMOV32 VR2, *XAR1++
;8(M=-1,-1)
VITDLSUBADD VR4,VR3,VR2,VR0
|| VMOV32 *XAR2++, VR7
VITLSEL VR6,VR5,VR4,VR3
|| VMOV32 VR2, *XAR1++
;9(M=-1,1)
VITDHSUBADD VR4,VR3,VR2,VR0
|| VMOV32 *+XAR2[AR0], VR8
VITHSEL VR6,VR5,VR4,VR3
|| VMOV32 VR2, *XAR1++
;10(M=-1,-1)
VITDLSUBADD VR4,VR3,VR2,VR0
|| VMOV32 *XAR2++, VR5
VITLSEL VR8,VR7,VR4,VR3
|| VMOV32 VR2, *XAR1++
;11(M=-1,1)
VITDHSUBADD VR4,VR3,VR2,VR0
|| VMOV32 *+XAR2[AR0], VR6
VITHSEL VR8,VR7,VR4,VR3
|| VMOV32 VR2, *XAR1++
;12(M=1,1)
VITDLADDSUB VR4,VR3,VR2,VR0
|| VMOV32 *XAR2++, VR7
VITLSEL VR6,VR5,VR4,VR3
|| VMOV32 VR2, *XAR1++
;13(M=1,-1)
VITDHADDSUB VR4,VR3,VR2,VR0
|| VMOV32 *+XAR2[AR0], VR8
VITHSEL VR6,VR5,VR4,VR3
|| VMOV32 VR2, *XAR1++
;14(M=1,1)
VITDLADDSUB VR4,VR3,VR2,VR0
|| VMOV32 *XAR2++, VR5
VITLSEL VR8,VR7,VR4,VR3
|| VMOV32 VR2, *XAR1++
;15(M=1,-1)
VITDHADDSUB VR4,VR3,VR2,VR0
|| VMOV32 *+XAR2[AR0], VR6
VITHSEL VR8,VR7,VR4,VR3
|| VMOV32 VR2, *XAR1++
;16(M=-1,1)
VITDHSUBADD VR4,VR3,VR2,VR0
|| VMOV32 *XAR2++, VR7
VITLSEL VR6,VR5,VR4,VR3
|| VMOV32 VR2, *XAR1++
;17(M=-1,-1)
VITDLSUBADD VR4,VR3,VR2,VR0
|| VMOV32 *+XAR2[AR0], VR8
VITHSEL VR6,VR5,VR4,VR3
|| VMOV32 VR2, *XAR1++
;18(M=-1,1)
VITDHSUBADD VR4,VR3,VR2,VR0
|| VMOV32 *XAR2++, VR5
VITLSEL VR8,VR7,VR4,VR3
|| VMOV32 VR2, *XAR1++
;19(M=-1,-1)
VITDLSUBADD VR4,VR3,VR2,VR0
|| VMOV32 *+XAR2[AR0], VR6
VITHSEL VR8,VR7,VR4,VR3
|| VMOV32 VR2, *XAR1++
;20(M=1,-1)
VITDHADDSUB VR4,VR3,VR2,VR0
|| VMOV32 *XAR2++, VR7
VITLSEL VR6,VR5,VR4,VR3
|| VMOV32 VR2, *XAR1++
;21(M=1,1)
VITDLADDSUB VR4,VR3,VR2,VR0
|| VMOV32 *+XAR2[AR0], VR8
VITHSEL VR6,VR5,VR4,VR3
|| VMOV32 VR2, *XAR1++
;22(M=1,-1)
VITDHADDSUB VR4,VR3,VR2,VR0
|| VMOV32 *XAR2++, VR5
VITLSEL VR8,VR7,VR4,VR3
|| VMOV32 VR2, *XAR1++
;23(M=1,1)
VITDLADDSUB VR4,VR3,VR2,VR0
|| VMOV32 *+XAR2[AR0], VR6
VITHSEL VR8,VR7,VR4,VR3
|| VMOV32 VR2, *XAR1++
;24(M=1,-1)
VITDHADDSUB VR4,VR3,VR2,VR0
|| VMOV32 *XAR2++, VR7
VITLSEL VR6,VR5,VR4,VR3
|| VMOV32 VR2, *XAR1++
;25(M=1,1)
VITDLADDSUB VR4,VR3,VR2,VR0
|| VMOV32 *+XAR2[AR0], VR8
VITHSEL VR6,VR5,VR4,VR3
|| VMOV32 VR2, *XAR1++
;26(M=1,-1)
VITDHADDSUB VR4,VR3,VR2,VR0
|| VMOV32 *XAR2++, VR5
VITLSEL VR8,VR7,VR4,VR3
|| VMOV32 VR2, *XAR1++
;27(M=1,1)
VITDLADDSUB VR4,VR3,VR2,VR0
|| VMOV32 *+XAR2[AR0], VR6
VITHSEL VR8,VR7,VR4,VR3
|| VMOV32 VR2, *XAR1++
;28(M=-1,1)
VITDHSUBADD VR4,VR3,VR2,VR0
|| VMOV32 *XAR2++, VR7
VITLSEL VR6,VR5,VR4,VR3
|| VMOV32 VR2, *XAR1++
;29(M=-1,-1)
VITDLSUBADD VR4,VR3,VR2,VR0
|| VMOV32 *+XAR2[AR0], VR8
VITHSEL VR6,VR5,VR4,VR3
|| VMOV32 VR2, *XAR1++
;30(M=-1,1)
VITDHSUBADD VR4,VR3,VR2,VR0
|| VMOV32 *XAR2++, VR5
VITLSEL VR8,VR7,VR4,VR3
|| VMOV32 VR2, *XAR1++
;31(M=-1,-1)
VITDLSUBADD VR4,VR3,VR2,VR0
|| VMOV32 *+XAR2[AR0], VR6
VITHSEL VR8,VR7,VR4,VR3
VMOV32 *XAR2++, VR7
VMOV32 *+XAR2[AR0], VR8
;Store the Transition bits in Trans[] Array
VMOV32 *XAR3++, VT1
VMOV32 *XAR3++, VT0
;Swap XAR1 and XAR2(old and new state pointers)
SUBB XAR1,#64
MOVL @XAR7,XAR1
SUBB XAR2,#32
MOVL @XAR1,XAR2
MOVL @XAR2,XAR7
;set the LOOP count
BANZ _cnv_metric_update,AR6--
;===============================================================================
; Check if (flag==1), then no trace back
;===============================================================================
CMP *-SP[2], #1 ; If (flag==1), no trace/decode
BF _cnv_dec_toggle_trn_s_p, EQ
;===============================================================================
; Check if (flag==0), then trace/decode all current blk
; o/p ptr = data_out[bits_out-6]
; loop cnt = bits_out-6
;
; Check if (flag==2), then trace all curr+prv blk
; o/p ptr = data_out[2*bits_out-6]
; loop cnt = 2*bits_out-6
;
; Check if (flag==3), then trace all curr+prv blk
; o/p ptr = data_out[bits_out+prv_blk_bits-6]
; loop cnt = bits_out+prv_blk_bits-6
;===============================================================================
ZAPA
CMP *-SP[2], #0 ; If (flag==0), go trace/decode
BF _cnv_dec_ovlp, NEQ
MOV AL, *-SP[1] ; AR6 = #output bits
MOVZ AR6, @AL
SUBB XAR6, #7 ; AR6 = (output_bits - 6) - 1 loop cnt
LSL AL, #1 ; 32-bit per output bit
MOVL XAR7, #_trn_tmp
ADDL XAR7, ACC ; XAR7 -> trn_tmp[out_bit]
RPT #11 ; Zero out the last 6 tail bits
||MOV *--XAR7, AH
; XAR7 = pts to data_out[bits_out-6]
; If (flag == 0)
;======================================================================
; Trace back all, 1 shot, to RAM (32-bit word per output bit)
;======================================================================
VCLEAR VR0
VCLEAR VR1
_tb_loop1: ;
;;For Viterbi stage = k
VMOV32 VT0, *--XAR3
VMOV32 VT1, *--XAR3
VTRACE *--XAR7,VR0,VT0,VT1
BANZ _tb_loop1, AR6--
BF _cnv_dec_op, UNC ; exit
;===============================================================================
; Trace back (overlap)
;===============================================================================
_cnv_dec_ovlp:
; If (flag=2/3)
MOV AL, *-SP[1] ; AR6 = #output bits
MOVZ AR6, @AL ; output_bits
SUBB XAR6, #1 ; AR6 = (output_bits - 6) - 1 loop cntr
MOVL XAR7, #_trn_tmp
VCLEAR VR0
VCLEAR VR1
CMP *-SP[2], #3 ; If (flag==2), go trace/decode, regular block
BF _tb_loop_ovlp1, NEQ
; If (flag==3), go trace/decode, irregular block
ADDB XAR6, #58 ; add the previous block, compensate for subb 1
MOV AL, @AR6
AND AL, #0x1F ; find modulo of 32 and use it as the first trace back
MOV @AR0, AL ; accumulate 32 bits for output
_tb_loop_ovlp0:
VMOV32 VT0, *--XAR3
VMOV32 VT1, *--XAR3
VTRACE VR1,VR0,VT0,VT1
BANZ _tb_loop_ovlp0_end, AR0--
; after 32 bits are accumulated output
VMOV32 *XAR7, VR1
FLIP32 ; flip 32bits in VR1 to ACC
MOVL *--XAR5, ACC ; output
MOVB XAR0, #31 ; accumulate 32 bits for output
_tb_loop_ovlp0_end:
MOV AL, AR6
CMPB AL, #58
BF _tb_loop_ovlp0_end1, NEQ
MOVW DP, #_trn_w1_p ; switch to previous tran_hist
MOVL XAR3, @_trn_w1_p
_tb_loop_ovlp0_end1:
BANZ _tb_loop_ovlp0, AR6--
BF _cnv_dec_toggle_trn_s_p, UNC
_tb_loop_ovlp1: ;
;;For Viterbi stage = k
VMOV32 VT0, *--XAR3
VMOV32 VT1, *--XAR3
VTRACE VR1,VR0,VT0,VT1
BANZ _tb_loop_ovlp1, AR6--
;======================================================================
; Second half of the block actually produces decode bits to o/p when ovlp
;======================================================================
MOVW DP, #_trn_w1_p
MOVL XAR3, @_trn_w1_p
;======================================================================
.align 2
RPTB _tb_loop_ovlp2, #12 ; the first word, the other 3 bits are already in VR1 from _tb_loop_ovlp1
VMOV32 VT0, *--XAR3
VMOV32 VT1, *--XAR3
VTRACE VR1,VR0,VT0,VT1
VMOV32 VT0, *--XAR3
VMOV32 VT1, *--XAR3
VTRACE VR1,VR0,VT0,VT1
_tb_loop_ovlp2:
FLIP32 ; flip 32bits in VR1 to ACC
.if (VIT_OUT_ODD == 0)
MOVL *+XAR5[2], ACC ; output
.else
ADDB XAR5, #1
MOVB *+XAR5[6], AH.MSB
SUBB XAR5, #1
MOVB *+XAR5[7], AH.LSB
MOVB *+XAR5[6], AL.MSB
MOVB *+XAR5[5], AL.LSB
.endif
;======================================================================
.align 2
RPTB _tb_loop_ovlp3, #15 ; the second word
VMOV32 VT0, *--XAR3
VMOV32 VT1, *--XAR3
VTRACE VR1,VR0,VT0,VT1
VMOV32 VT0, *--XAR3
VMOV32 VT1, *--XAR3
VTRACE VR1,VR0,VT0,VT1
_tb_loop_ovlp3:
FLIP32 ; flip 32bits in VR1 to ACC
.if (VIT_OUT_ODD == 0)
MOVL *XAR5, ACC ; output
.else
MOVB *+XAR5[4], AH.MSB
MOVB *+XAR5[3], AH.LSB
MOVB *+XAR5[2], AL.MSB
MOVB *+XAR5[1], AL.LSB
.endif
;======================================================================
; Toggle trn_w1_p/trn_w2_p
;======================================================================
_cnv_dec_op:
MOVL XAR3, @_trn_w1_p
MOVL XAR4, @_trn_w2_p
MOVL @_trn_w1_p, XAR4
MOVL @_trn_w2_p, XAR3
;======================================================================
; Toggle trn_s1_p/trn_s2_p
;======================================================================
_cnv_dec_toggle_trn_s_p:
MOVL XAR3, @_trn_s1_p
MOVL XAR4, @_trn_s2_p
MOVL @_trn_s1_p, XAR4
MOVL @_trn_s2_p, XAR3
SUBB SP, #4 ; restore stack pointer
POP XAR3
POP XAR2
POP XAR1
POP XAR0
LRETR
;/*! State Metrics Rescale
; *
; * \param none
; *
; * Rescale the state metrics by finding the lowest metric and dividing the
; * rest by it. This prevents overflow between successive decoder stages
; *
; * \return none
; */
_cnvDecMetricRescale_asm:
PUSH XAR2 ; save on stack
SETC SXM, OVM ; sign extention mode
MOV AL, #0x7FFF ; minimal metrics
MOVL XAR4, #_dold
RPT #63
||MIN AL, *XAR4++ ; find the minimal
MOVL XAR4, #_dold
MOV AR2, #3 ; offset for 64 samples
_cnvDecMetricRescale:
SUB *XAR4++, AL
SUB *XAR4++, AL
SUB *XAR4++, AL
SUB *XAR4++, AL
SUB *XAR4++, AL
SUB *XAR4++, AL
SUB *XAR4++, AL
SUB *XAR4++, AL
SUB *XAR4++, AL
SUB *XAR4++, AL
SUB *XAR4++, AL
SUB *XAR4++, AL
SUB *XAR4++, AL
SUB *XAR4++, AL
SUB *XAR4++, AL
SUB *XAR4++, AL
BANZ _cnvDecMetricRescale, AR2--
POP XAR2
LRETR
;############################################################################
; Close the Doxygen group.
;//! @}
;############################################################################
;; End of File
@@ -0,0 +1,101 @@
/******************************************************************************
*******************************************************************************
*
* FILE: crc16P1_table.c
*
* DESCRIPTION: This file contains lookup tables for each of the hardware supported
* crc polynomials
*
* Notes:
*
* o CRC implementation is based on tables. If the tables
* are calculated on the fly, genCRC32Tables() shall be called during
* initialization. If the macro is not defined, pre-calculated tables
* defined in this library will be used
* Using the latter option can put the tables to flash.
*******************************************************************************/
//#############################################################################
//!
//! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
//! All rights reserved not granted herein.
//! Limited License.
//!
//! Texas Instruments Incorporated grants a world-wide, royalty-free,
//! non-exclusive license under copyrights and patents it now or hereafter
//! owns or controls to make, have made, use, import, offer to sell and sell
//! ("Utilize") this software subject to the terms herein. With respect to the
//! foregoing patent license, such license is granted solely to the extent that
//! any such patent is necessary to Utilize the software alone. The patent
//! license shall not apply to any combinations which include this software,
//! other than combinations with devices manufactured by or for TI
//! ("TI Devices").
//! No hardware patent is licensed hereunder.
//!
//! Redistributions must preserve existing copyright notices and reproduce this
//! license (including the above copyright notice and the disclaimer and
//! (if applicable) source code license limitations below) in the documentation
//! and/or other materials provided with the distribution.
//!
//! Redistribution and use in binary form, without modification, are permitted
//! provided that the following conditions are met:
//!
//! * No reverse engineering, decompilation, or disassembly of this software is
//! permitted with respect to any software provided in binary form.
//! * Any redistribution and use are licensed by TI for use only
//! with TI Devices.
//! * Nothing shall obligate TI to provide you with source code for the
//! software licensed and provided to you in object code.
//!
//! If software source code is provided to you, modification and redistribution
//! of the source code are permitted provided that the following conditions
//! are met:
//!
//! * any redistribution and use of the source code, including any resulting
//! derivative works, are licensed by TI for use only with TI Devices.
//! * any redistribution and use of any object code compiled from the source
//! code and any resulting derivative works, are licensed by TI for use
//! only with TI Devices.
//!
//! Neither the name of Texas Instruments Incorporated nor the names of its
//! suppliers may be used to endorse or promote products derived from this
//! software without specific prior written permission.
//#############################################################################
#include "VCU0_CRC.h"
uint16 crc16p1_table[256] =
{
0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072,
0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041,
0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2,
0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1,
0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1,
0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082,
0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192,
0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1,
0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1,
0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2,
0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151,
0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162,
0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132,
0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101,
0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312,
0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321,
0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371,
0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342,
0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1,
0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2,
0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2,
0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381,
0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291,
0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2,
0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2,
0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1,
0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252,
0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261,
0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231,
0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202
} ;
// End of file
@@ -0,0 +1,101 @@
/******************************************************************************
*******************************************************************************
*
* FILE: crc16P2_table.c
*
* DESCRIPTION: This file contains lookup tables for each of the hardware supported
* crc polynomials
*
* Notes:
*
* o CRC implementation is based on tables. If the tables
* are calculated on the fly, genCRC32Tables() shall be called during
* initialization. If the macro is not defined, pre-calculated tables
* defined in this library will be used
* Using the latter option can put the tables to flash.
*******************************************************************************/
//#############################################################################
//!
//! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
//! All rights reserved not granted herein.
//! Limited License.
//!
//! Texas Instruments Incorporated grants a world-wide, royalty-free,
//! non-exclusive license under copyrights and patents it now or hereafter
//! owns or controls to make, have made, use, import, offer to sell and sell
//! ("Utilize") this software subject to the terms herein. With respect to the
//! foregoing patent license, such license is granted solely to the extent that
//! any such patent is necessary to Utilize the software alone. The patent
//! license shall not apply to any combinations which include this software,
//! other than combinations with devices manufactured by or for TI
//! ("TI Devices").
//! No hardware patent is licensed hereunder.
//!
//! Redistributions must preserve existing copyright notices and reproduce this
//! license (including the above copyright notice and the disclaimer and
//! (if applicable) source code license limitations below) in the documentation
//! and/or other materials provided with the distribution.
//!
//! Redistribution and use in binary form, without modification, are permitted
//! provided that the following conditions are met:
//!
//! * No reverse engineering, decompilation, or disassembly of this software is
//! permitted with respect to any software provided in binary form.
//! * Any redistribution and use are licensed by TI for use only
//! with TI Devices.
//! * Nothing shall obligate TI to provide you with source code for the
//! software licensed and provided to you in object code.
//!
//! If software source code is provided to you, modification and redistribution
//! of the source code are permitted provided that the following conditions
//! are met:
//!
//! * any redistribution and use of the source code, including any resulting
//! derivative works, are licensed by TI for use only with TI Devices.
//! * any redistribution and use of any object code compiled from the source
//! code and any resulting derivative works, are licensed by TI for use
//! only with TI Devices.
//!
//! Neither the name of Texas Instruments Incorporated nor the names of its
//! suppliers may be used to endorse or promote products derived from this
//! software without specific prior written permission.
//#############################################################################
#include "VCU0_CRC.h"
uint16 crc16p2_table[256] =
{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};
// End of file
@@ -0,0 +1,134 @@
/******************************************************************************
*******************************************************************************
*
* FILE: crc32_table.c
*
* DESCRIPTION: This file contains lookup tables for each of the hardware supported
* crc polynomials
*
* Notes:
*
* o CRC implementation is based on tables. If the tables
* are calculated on the fly, genCRC32Tables() shall be called during
* initialization. If the macro is not defined, pre-calculated tables
* defined in this library will be used
* Using the latter option can put the tables to flash.
*******************************************************************************/
//#############################################################################
//!
//! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
//! All rights reserved not granted herein.
//! Limited License.
//!
//! Texas Instruments Incorporated grants a world-wide, royalty-free,
//! non-exclusive license under copyrights and patents it now or hereafter
//! owns or controls to make, have made, use, import, offer to sell and sell
//! ("Utilize") this software subject to the terms herein. With respect to the
//! foregoing patent license, such license is granted solely to the extent that
//! any such patent is necessary to Utilize the software alone. The patent
//! license shall not apply to any combinations which include this software,
//! other than combinations with devices manufactured by or for TI
//! ("TI Devices").
//! No hardware patent is licensed hereunder.
//!
//! Redistributions must preserve existing copyright notices and reproduce this
//! license (including the above copyright notice and the disclaimer and
//! (if applicable) source code license limitations below) in the documentation
//! and/or other materials provided with the distribution.
//!
//! Redistribution and use in binary form, without modification, are permitted
//! provided that the following conditions are met:
//!
//! * No reverse engineering, decompilation, or disassembly of this software is
//! permitted with respect to any software provided in binary form.
//! * Any redistribution and use are licensed by TI for use only
//! with TI Devices.
//! * Nothing shall obligate TI to provide you with source code for the
//! software licensed and provided to you in object code.
//!
//! If software source code is provided to you, modification and redistribution
//! of the source code are permitted provided that the following conditions
//! are met:
//!
//! * any redistribution and use of the source code, including any resulting
//! derivative works, are licensed by TI for use only with TI Devices.
//! * any redistribution and use of any object code compiled from the source
//! code and any resulting derivative works, are licensed by TI for use
//! only with TI Devices.
//!
//! Neither the name of Texas Instruments Incorporated nor the names of its
//! suppliers may be used to endorse or promote products derived from this
//! software without specific prior written permission.
//#############################################################################
#include "VCU0_CRC.h"
uint32 crc32_table[256] =
{
0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9,
0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005,
0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61,
0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD,
0x4C11DB70, 0x48D0C6C7, 0x4593E01E, 0x4152FDA9,
0x5F15ADAC, 0x5BD4B01B, 0x569796C2, 0x52568B75,
0x6A1936C8, 0x6ED82B7F, 0x639B0DA6, 0x675A1011,
0x791D4014, 0x7DDC5DA3, 0x709F7B7A, 0x745E66CD,
0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039,
0x8B27C03C, 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5,
0xBE2B5B58, 0xBAEA46EF, 0xB7A96036, 0xB3687D81,
0xAD2F2D84, 0xA9EE3033, 0xA4AD16EA, 0xA06C0B5D,
0xD4326D90, 0xD0F37027, 0xDDB056FE, 0xD9714B49,
0xC7361B4C, 0xC3F706FB, 0xCEB42022, 0xCA753D95,
0xF23A8028, 0xF6FB9D9F, 0xFBB8BB46, 0xFF79A6F1,
0xE13EF6F4, 0xE5FFEB43, 0xE8BCCD9A, 0xEC7DD02D,
0x34867077, 0x30476DC0, 0x3D044B19, 0x39C556AE,
0x278206AB, 0x23431B1C, 0x2E003DC5, 0x2AC12072,
0x128E9DCF, 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16,
0x018AEB13, 0x054BF6A4, 0x0808D07D, 0x0CC9CDCA,
0x7897AB07, 0x7C56B6B0, 0x71159069, 0x75D48DDE,
0x6B93DDDB, 0x6F52C06C, 0x6211E6B5, 0x66D0FB02,
0x5E9F46BF, 0x5A5E5B08, 0x571D7DD1, 0x53DC6066,
0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA,
0xACA5C697, 0xA864DB20, 0xA527FDF9, 0xA1E6E04E,
0xBFA1B04B, 0xBB60ADFC, 0xB6238B25, 0xB2E29692,
0x8AAD2B2F, 0x8E6C3698, 0x832F1041, 0x87EE0DF6,
0x99A95DF3, 0x9D684044, 0x902B669D, 0x94EA7B2A,
0xE0B41DE7, 0xE4750050, 0xE9362689, 0xEDF73B3E,
0xF3B06B3B, 0xF771768C, 0xFA325055, 0xFEF34DE2,
0xC6BCF05F, 0xC27DEDE8, 0xCF3ECB31, 0xCBFFD686,
0xD5B88683, 0xD1799B34, 0xDC3ABDED, 0xD8FBA05A,
0x690CE0EE, 0x6DCDFD59, 0x608EDB80, 0x644FC637,
0x7A089632, 0x7EC98B85, 0x738AAD5C, 0x774BB0EB,
0x4F040D56, 0x4BC510E1, 0x46863638, 0x42472B8F,
0x5C007B8A, 0x58C1663D, 0x558240E4, 0x51435D53,
0x251D3B9E, 0x21DC2629, 0x2C9F00F0, 0x285E1D47,
0x36194D42, 0x32D850F5, 0x3F9B762C, 0x3B5A6B9B,
0x0315D626, 0x07D4CB91, 0x0A97ED48, 0x0E56F0FF,
0x1011A0FA, 0x14D0BD4D, 0x19939B94, 0x1D528623,
0xF12F560E, 0xF5EE4BB9, 0xF8AD6D60, 0xFC6C70D7,
0xE22B20D2, 0xE6EA3D65, 0xEBA91BBC, 0xEF68060B,
0xD727BBB6, 0xD3E6A601, 0xDEA580D8, 0xDA649D6F,
0xC423CD6A, 0xC0E2D0DD, 0xCDA1F604, 0xC960EBB3,
0xBD3E8D7E, 0xB9FF90C9, 0xB4BCB610, 0xB07DABA7,
0xAE3AFBA2, 0xAAFBE615, 0xA7B8C0CC, 0xA379DD7B,
0x9B3660C6, 0x9FF77D71, 0x92B45BA8, 0x9675461F,
0x8832161A, 0x8CF30BAD, 0x81B02D74, 0x857130C3,
0x5D8A9099, 0x594B8D2E, 0x5408ABF7, 0x50C9B640,
0x4E8EE645, 0x4A4FFBF2, 0x470CDD2B, 0x43CDC09C,
0x7B827D21, 0x7F436096, 0x7200464F, 0x76C15BF8,
0x68860BFD, 0x6C47164A, 0x61043093, 0x65C52D24,
0x119B4BE9, 0x155A565E, 0x18197087, 0x1CD86D30,
0x029F3D35, 0x065E2082, 0x0B1D065B, 0x0FDC1BEC,
0x3793A651, 0x3352BBE6, 0x3E119D3F, 0x3AD08088,
0x2497D08D, 0x2056CD3A, 0x2D15EBE3, 0x29D4F654,
0xC5A92679, 0xC1683BCE, 0xCC2B1D17, 0xC8EA00A0,
0xD6AD50A5, 0xD26C4D12, 0xDF2F6BCB, 0xDBEE767C,
0xE3A1CBC1, 0xE760D676, 0xEA23F0AF, 0xEEE2ED18,
0xF0A5BD1D, 0xF464A0AA, 0xF9278673, 0xFDE69BC4,
0x89B8FD09, 0x8D79E0BE, 0x803AC667, 0x84FBDBD0,
0x9ABC8BD5, 0x9E7D9662, 0x933EB0BB, 0x97FFAD0C,
0xAFB010B1, 0xAB710D06, 0xA6322BDF, 0xA2F33668,
0xBCB4666D, 0xB8757BDA, 0xB5365D03, 0xB1F740B4,
};
// End of file
@@ -0,0 +1,102 @@
/******************************************************************************
*******************************************************************************
*
* FILE: crc8_table.c
*
* DESCRIPTION: This file contains lookup tables for each of the hardware supported
* crc polynomials
*
* Notes:
*
* o CRC implementation is based on tables. If the tables
* are calculated on the fly, genCRC32Tables() shall be called during
* initialization. If the macro is not defined, pre-calculated tables
* defined in this library will be used
* Using the latter option can put the tables to flash.
*******************************************************************************/
//#############################################################################
//!
//! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
//! All rights reserved not granted herein.
//! Limited License.
//!
//! Texas Instruments Incorporated grants a world-wide, royalty-free,
//! non-exclusive license under copyrights and patents it now or hereafter
//! owns or controls to make, have made, use, import, offer to sell and sell
//! ("Utilize") this software subject to the terms herein. With respect to the
//! foregoing patent license, such license is granted solely to the extent that
//! any such patent is necessary to Utilize the software alone. The patent
//! license shall not apply to any combinations which include this software,
//! other than combinations with devices manufactured by or for TI
//! ("TI Devices").
//! No hardware patent is licensed hereunder.
//!
//! Redistributions must preserve existing copyright notices and reproduce this
//! license (including the above copyright notice and the disclaimer and
//! (if applicable) source code license limitations below) in the documentation
//! and/or other materials provided with the distribution.
//!
//! Redistribution and use in binary form, without modification, are permitted
//! provided that the following conditions are met:
//!
//! * No reverse engineering, decompilation, or disassembly of this software is
//! permitted with respect to any software provided in binary form.
//! * Any redistribution and use are licensed by TI for use only
//! with TI Devices.
//! * Nothing shall obligate TI to provide you with source code for the
//! software licensed and provided to you in object code.
//!
//! If software source code is provided to you, modification and redistribution
//! of the source code are permitted provided that the following conditions
//! are met:
//!
//! * any redistribution and use of the source code, including any resulting
//! derivative works, are licensed by TI for use only with TI Devices.
//! * any redistribution and use of any object code compiled from the source
//! code and any resulting derivative works, are licensed by TI for use
//! only with TI Devices.
//!
//! Neither the name of Texas Instruments Incorporated nor the names of its
//! suppliers may be used to endorse or promote products derived from this
//! software without specific prior written permission.
//#############################################################################
#include "VCU0_CRC.h"
uint16 crc8_table[256] =
{
0x0000, 0x0007, 0x000E, 0x0009, 0x001C, 0x001B, 0x0012, 0x0015,
0x0038, 0x003F, 0x0036, 0x0031, 0x0024, 0x0023, 0x002A, 0x002D,
0x0070, 0x0077, 0x007E, 0x0079, 0x006C, 0x006B, 0x0062, 0x0065,
0x0048, 0x004F, 0x0046, 0x0041, 0x0054, 0x0053, 0x005A, 0x005D,
0x00E0, 0x00E7, 0x00EE, 0x00E9, 0x00FC, 0x00FB, 0x00F2, 0x00F5,
0x00D8, 0x00DF, 0x00D6, 0x00D1, 0x00C4, 0x00C3, 0x00CA, 0x00CD,
0x0090, 0x0097, 0x009E, 0x0099, 0x008C, 0x008B, 0x0082, 0x0085,
0x00A8, 0x00AF, 0x00A6, 0x00A1, 0x00B4, 0x00B3, 0x00BA, 0x00BD,
0x00C7, 0x00C0, 0x00C9, 0x00CE, 0x00DB, 0x00DC, 0x00D5, 0x00D2,
0x00FF, 0x00F8, 0x00F1, 0x00F6, 0x00E3, 0x00E4, 0x00ED, 0x00EA,
0x00B7, 0x00B0, 0x00B9, 0x00BE, 0x00AB, 0x00AC, 0x00A5, 0x00A2,
0x008F, 0x0088, 0x0081, 0x0086, 0x0093, 0x0094, 0x009D, 0x009A,
0x0027, 0x0020, 0x0029, 0x002E, 0x003B, 0x003C, 0x0035, 0x0032,
0x001F, 0x0018, 0x0011, 0x0016, 0x0003, 0x0004, 0x000D, 0x000A,
0x0057, 0x0050, 0x0059, 0x005E, 0x004B, 0x004C, 0x0045, 0x0042,
0x006F, 0x0068, 0x0061, 0x0066, 0x0073, 0x0074, 0x007D, 0x007A,
0x0089, 0x008E, 0x0087, 0x0080, 0x0095, 0x0092, 0x009B, 0x009C,
0x00B1, 0x00B6, 0x00BF, 0x00B8, 0x00AD, 0x00AA, 0x00A3, 0x00A4,
0x00F9, 0x00FE, 0x00F7, 0x00F0, 0x00E5, 0x00E2, 0x00EB, 0x00EC,
0x00C1, 0x00C6, 0x00CF, 0x00C8, 0x00DD, 0x00DA, 0x00D3, 0x00D4,
0x0069, 0x006E, 0x0067, 0x0060, 0x0075, 0x0072, 0x007B, 0x007C,
0x0051, 0x0056, 0x005F, 0x0058, 0x004D, 0x004A, 0x0043, 0x0044,
0x0019, 0x001E, 0x0017, 0x0010, 0x0005, 0x0002, 0x000B, 0x000C,
0x0021, 0x0026, 0x002F, 0x0028, 0x003D, 0x003A, 0x0033, 0x0034,
0x004E, 0x0049, 0x0040, 0x0047, 0x0052, 0x0055, 0x005C, 0x005B,
0x0076, 0x0071, 0x0078, 0x007F, 0x006A, 0x006D, 0x0064, 0x0063,
0x003E, 0x0039, 0x0030, 0x0037, 0x0022, 0x0025, 0x002C, 0x002B,
0x0006, 0x0001, 0x0008, 0x000F, 0x001A, 0x001D, 0x0014, 0x0013,
0x00AE, 0x00A9, 0x00A0, 0x00A7, 0x00B2, 0x00B5, 0x00BC, 0x00BB,
0x0096, 0x0091, 0x0098, 0x009F, 0x008A, 0x008D, 0x0084, 0x0083,
0x00DE, 0x00D9, 0x00D0, 0x00D7, 0x00C2, 0x00C5, 0x00CC, 0x00CB,
0x00E6, 0x00E1, 0x00E8, 0x00EF, 0x00FA, 0x00FD, 0x00F4, 0x00F3,
};
// End of file
@@ -0,0 +1,350 @@
;;*****************************************************************************
;;! \file source/vcu2/vcu2_crc_16.asm
;;!
;;! \brief 16-bit CRC
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;;*****************************************************************************
;; global defines
;;*****************************************************************************
;; CRC Routine defines
;; Argument structure defines
ARG_SEEDVAL .set 0
ARG_NBYTES .set 2
ARG_PARITY .set 3
ARG_CRCRESULT .set 4
ARG_MSGBUFFER .set 6
ARG_CRCTABLE .set 8
;;*****************************************************************************
;; macros
;;*****************************************************************************
;;
;; MACRO : 'CRC_CONTEXT_SAVE'
;; SIZE : Number of WORDS/Number of Cycles 3
;; USAGE : Called on entry into CRC routine
;;
CRC_CONTEXT_SAVE .macro
PUSH XAR1
PUSH XAR2
PUSH XAR3
.endm
;;
;; MACRO : 'CRC_CONTEXT_RESTORE'
;; SIZE : Number of WORDS/Number of Cycles 3
;; USAGE : Called on exit from CRC routine
;;
CRC_CONTEXT_RESTORE .macro
POP XAR3
POP XAR2
POP XAR1
.endm
.if $defined(__TI_EABI__)
.if __TI_EABI__
.asg CRC_run16BitPoly1, _CRC_run16BitPoly1
.asg CRC_run16BitPoly2, _CRC_run16BitPoly2
.asg CRC_run16BitPoly1Reflected, _CRC_run16BitPoly1Reflected
.asg CRC_run16BitPoly2Reflected, _CRC_run16BitPoly2Reflected
.asg CRC_init16Bit, _CRC_init16Bit
.endif
.endif
;;*****************************************************************************
;; globals
;;*****************************************************************************
.global _CRC_run16BitPoly1
.global _CRC_run16BitPoly2
.global _CRC_run16BitPoly1Reflected
.global _CRC_run16BitPoly2Reflected
.global _CRC_init16Bit
;;*****************************************************************************
;; function definitions
;;*****************************************************************************
.text
;;
;; \brief Calculate the 16-bit CRC using polynomial 0x8005
;;
;; \param Handle to the structure, CRC_Obj(passed in XAR4)
;; - *+XAR4[0]: uint32_t seedValue -> Initial value of the CRC calculation
;; - *+XAR4[2]: uint16_t nMsgBytes -> the number of bytes in the message buffer
;; - *+XAR4[3]: CRC_parity_e parity -> start the CRC from the low byte (CRC_parity_even) or high byte (CRC_parity_odd) of the first word
;; - *+XAR4[4]: uint32_t crcResult -> the calculated CRC
;; - *+XAR4[6]: void *pMsgBuffer -> Pointer to the message buffer
;; - *+XAR4[8]: void *pCrcTable -> Pointer to the CRC lookup table
;;
;; \note
;; -
;;
;; \return CRC of the message(stored within the structure itself)
;;
_CRC_run16BitPoly1:
CRC_CONTEXT_SAVE
;MOVL XAR2, XAR4 ;*+XAR4[3bit] addressing wont support a larger structure
;might have to assign XAR2 to point to the structure and
;iterate through using XAR2++
;; Register Usage:
;; XAR0: Number of bytes to process
;; XAR1: Repeat block counter
;; XAR2: Pointer to iterate through the CRC object(possible future use)
;; XAR4: Points to the CRC object
;; XAR5: Points to the message buffer
;;
VCRCCLR ; Clear out the CRC result register
MOVL XAR0, *+XAR4[ARG_NBYTES] ; Load number of message bytes into AR0
VMOV32 VCRC, *+XAR4[ARG_SEEDVAL] ; Load seed value into the CRC result register
MOVL XAR5, *+XAR4[ARG_MSGBUFFER] ; XAR5 points to the message buffer
MOV AL, *+XAR4[ARG_PARITY] ; Check the parity
SBF _CRC_run16BitPoly1_Loop, EQ ; If Parity = LOW_BYTE, skip to loop
VCRC16P1H_1 *XAR5++ ; Parity = HIGH_BYTE, calculate high byte of the first word,
; ignore the low byte and proceed to next word
DEC AR0
SBF _CRC_run16BitPoly1_End, EQ ; Jump to end if no more bytes
_CRC_run16BitPoly1_Loop:
MOV AL, AR0
MOV AH, AR0
AND AL, #0xFFF8 ; Check to see if length greater than 8 bytes
; if true, handle the <8 bytes in a loop
; AL is now a multiple of 8
SBF _CRC_run16BitPoly1_LT8BytesLeft, EQ
LSR AL, #3 ; loop in 8 bytes at a time
MOV AR1, AL ; move count into AR1
SUB AR1, #1 ; subtract 1, accounts for the RPTB instruction i.e. it loops
; N + 1 times
.align 2 ; align at 32-bit boundary to remove penalty
; loop through the message 8 bytes at a time
RPTB _CRC_run16BitPoly1_RepeatBlock, AR1
VCRC16P1L_1 *XAR5
VCRC16P1H_1 *XAR5++
VCRC16P1L_1 *XAR5
VCRC16P1H_1 *XAR5++
VCRC16P1L_1 *XAR5
VCRC16P1H_1 *XAR5++
VCRC16P1L_1 *XAR5
VCRC16P1H_1 *XAR5++
_CRC_run16BitPoly1_RepeatBlock:
LSL AL, #3 ; multiply by 8 to get the pre RPTB count
SUB AH, AL ; AH holds the number of remaining bytes(<8)
SBF _CRC_run16BitPoly1_End, EQ ; if multiple of 8, AH is 0, done processing
MOV AR0, AH
_CRC_run16BitPoly1_LT8BytesLeft:
VCRC16P1L_1 *XAR5
DEC AR0
SBF _CRC_run16BitPoly1_End, EQ
VCRC16P1H_1 *XAR5++
DEC AR0
SBF _CRC_run16BitPoly1_LT8BytesLeft, NEQ
_CRC_run16BitPoly1_End:
VMOV32 *+XAR4[ARG_CRCRESULT], VCRC ; Save the result to the structure
CRC_CONTEXT_RESTORE
LRETR
;;*****************************************************************************
;;
;; \brief Calculate the 16-bit CRC using polynomial 0x1021
;;
;; \param Handle to the structure, CRC_Obj(passed in XAR4)
;; - *+XAR4[0]: uint32_t seedValue -> Initial value of the CRC calculation
;; - *+XAR4[2]: uint16_t nMsgBytes -> the number of bytes in the message buffer
;; - *+XAR4[3]: CRC_parity_e parity -> start the CRC from the low byte (CRC_parity_even) or high byte (CRC_parity_odd) of the first word
;; - *+XAR4[4]: uint32_t crcResult -> the calculated CRC
;; - *+XAR4[6]: void *pMsgBuffer -> Pointer to the message buffer
;; - *+XAR4[8]: void *pCrcTable -> Pointer to the CRC lookup table
;;
;; \note
;; -
;;
;; \return CRC of the message(stored within the structure itself)
;;
_CRC_run16BitPoly2:
CRC_CONTEXT_SAVE
MOVL XAR2, XAR4
;; Register Usage:
;; XAR0: Number of bytes to process
;; XAR1: Repeat block counter
;; XAR2: Pointer to iterate through the CRC object
;; XAR4: Points to the CRC object
;; XAR5: Points to the message buffer
;;
VCRCCLR ; Clear out the CRC result register
MOVL XAR0, *+XAR4[ARG_NBYTES] ; Load number of message bytes into AR0
VMOV32 VCRC, *+XAR4[ARG_SEEDVAL] ; Load seed value into the CRC result register
MOVL XAR5, *+XAR4[ARG_MSGBUFFER] ; XAR5 points to the message buffer
MOV AL, *+XAR4[ARG_PARITY] ; Check the parity
SBF _CRC_run16BitPoly2_Loop, EQ ; If Parity = LOW_BYTE, skip to loop
VCRC16P2H_1 *XAR5++ ; Parity = HIGH_BYTE, calculate high byte of the first word,
; ignore the low byte and proceed to next word
DEC AR0
SBF _CRC_run16BitPoly2_End, EQ ; Jump to end if no more bytes
_CRC_run16BitPoly2_Loop:
MOV AL, AR0
MOV AH, AR0
AND AL, #0xFFF8 ; Check to see if length greater than 8 bytes
; if true, handle the <8 bytes in a loop
; AL is now a multiple of 8
SBF _CRC_run16BitPoly2_LT8BytesLeft, EQ
LSR AL, #3 ; loop in 8 bytes at a time
MOV AR1, AL ; move count into AR1
SUB AR1, #1 ; subtract 1, accounts for the RPTB instruction i.e. it loops
; N + 1 times
.align 2 ; align at 32-bit boundary to remove penalty
; loop through the message 8 bytes at a time
RPTB _CRC_run16BitPoly2_RepeatBlock, AR1
VCRC16P2L_1 *XAR5
VCRC16P2H_1 *XAR5++
VCRC16P2L_1 *XAR5
VCRC16P2H_1 *XAR5++
VCRC16P2L_1 *XAR5
VCRC16P2H_1 *XAR5++
VCRC16P2L_1 *XAR5
VCRC16P2H_1 *XAR5++
_CRC_run16BitPoly2_RepeatBlock:
LSL AL, #3 ; multiply by 8 to get the pre RPTB count
SUB AH, AL ; AH holds the number of remaining bytes(<8)
SBF _CRC_run16BitPoly2_End, EQ ; if multiple of 8, AH is 0, done processing
MOV AR0, AH
_CRC_run16BitPoly2_LT8BytesLeft:
VCRC16P2L_1 *XAR5
DEC AR0
SBF _CRC_run16BitPoly2_End, EQ
VCRC16P2H_1 *XAR5++
DEC AR0
SBF _CRC_run16BitPoly2_LT8BytesLeft, NEQ
_CRC_run16BitPoly2_End:
VMOV32 *+XAR4[ARG_CRCRESULT], VCRC ; Save the result to the structure
CRC_CONTEXT_RESTORE
LRETR
;;*****************************************************************************
;;
;; \brief Calculate the 16-bit CRC using polynomial 0x8005 but with input bits reversed
;;
;; \param Handle to the structure, CRC_Obj(passed in XAR4)
;; - *+XAR4[0]: uint32_t seedValue -> Initial value of the CRC calculation
;; - *+XAR4[2]: uint16_t nMsgBytes -> the number of bytes in the message buffer
;; - *+XAR4[3]: CRC_parity_e parity -> start the CRC from the low byte (CRC_parity_even) or high byte (CRC_parity_odd) of the first word
;; - *+XAR4[4]: uint32_t crcResult -> the calculated CRC
;; - *+XAR4[6]: void *pMsgBuffer -> Pointer to the message buffer
;; - *+XAR4[8]: void *pCrcTable -> Pointer to the CRC lookup table
;;
;; \note
;; - actively sets the CRCMSGFLIP bit, each word has all its bits reversed prior to the
;; CRC being calculated
;;
;; \return CRC of the message(stored within the structure itself)
;;
_CRC_run16BitPoly1Reflected:
VSETCRCMSGFLIP
LCR _CRC_run16BitPoly1
VCLRCRCMSGFLIP
LRETR
;;*****************************************************************************
;;
;; \brief Calculate the 16-bit CRC using polynomial 0x1021 but with input bits reversed
;;
;; \param Handle to the structure, CRC_Obj(passed in XAR4)
;; - *+XAR4[0]: uint32_t seedValue -> Initial value of the CRC calculation
;; - *+XAR4[2]: uint16_t nMsgBytes -> the number of bytes in the message buffer
;; - *+XAR4[3]: CRC_parity_e parity -> start the CRC from the low byte (CRC_parity_even) or high byte (CRC_parity_odd) of the first word
;; - *+XAR4[4]: uint32_t crcResult -> the calculated CRC
;; - *+XAR4[6]: void *pMsgBuffer -> Pointer to the message buffer
;; - *+XAR4[8]: void *pCrcTable -> Pointer to the CRC lookup table
;;
;; \note
;; - actively sets the CRCMSGFLIP bit, each word has all its bits reversed prior to the
;; CRC being calculated
;;
;; \return CRC of the message(stored within the structure itself)
;;
_CRC_run16BitPoly2Reflected:
VSETCRCMSGFLIP
LCR _CRC_run16BitPoly2
VCLRCRCMSGFLIP
LRETR
;;*****************************************************************************
;;
;; \brief Initialize the 16-bit CRC
;;
;; Ensures that the CRCMSGFLIP bit is cleared, this ensures that the input
;; is interpreted in normal bit-order
;;
;; \param Handle to the structure, CRC_Obj(passed in XAR4)
;; - *+XAR4[0]: uint32_t seedValue -> Initial value of the CRC calculation
;; - *+XAR4[2]: uint16_t nMsgBytes -> the number of bytes in the message buffer
;; - *+XAR4[3]: CRC_parity_e parity -> start the CRC from the low byte (CRC_parity_even) or high byte (CRC_parity_odd) of the first word
;; - *+XAR4[4]: uint32_t crcResult -> the calculated CRC
;; - *+XAR4[6]: void *pMsgBuffer -> Pointer to the message buffer
;; - *+XAR4[8]: void *pCrcTable -> Pointer to the CRC lookup table
;;
;; \note
;; -
;;
_CRC_init16Bit:
VCLRCRCMSGFLIP
LRETR
;; End of file
@@ -0,0 +1,243 @@
;;*****************************************************************************
;;! \file source/vcu2/vcu2_crc_24.asm
;;!
;;! \brief 24-bit CRC
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;;*****************************************************************************
;; global defines
;;*****************************************************************************
;; CRC Routine defines
;; Argument structure defines
ARG_SEEDVAL .set 0
ARG_NBYTES .set 2
ARG_PARITY .set 3
ARG_CRCRESULT .set 4
ARG_MSGBUFFER .set 6
ARG_CRCTABLE .set 8
;;*****************************************************************************
;; macros
;;*****************************************************************************
;;
;; MACRO : 'CRC_CONTEXT_SAVE'
;; SIZE : Number of WORDS/Number of Cycles 3
;; USAGE : Called on entry into CRC routine
;;
CRC_CONTEXT_SAVE .macro
PUSH XAR1
PUSH XAR2
PUSH XAR3
.endm
;;
;; MACRO : 'CRC_CONTEXT_RESTORE'
;; SIZE : Number of WORDS/Number of Cycles 3
;; USAGE : Called on exit from CRC routine
;;
CRC_CONTEXT_RESTORE .macro
POP XAR3
POP XAR2
POP XAR1
.endm
.if $defined(__TI_EABI__)
.if __TI_EABI__
.asg CRC_run24Bit, _CRC_run24Bit
.asg CRC_run24BitReflected, _CRC_run24BitReflected
.asg CRC_init24Bit, _CRC_init24Bit
.endif
.endif
;;*****************************************************************************
;; globals
;;*****************************************************************************
.global _CRC_run24Bit
.global _CRC_run24BitReflected
.global _CRC_init24Bit
;;*****************************************************************************
;; function definitions
;;*****************************************************************************
.text
;;
;; \brief Calculate the 24-bit CRC using polynomial 0x5d6dcb
;;
;; \param Handle to the structure, CRC_Obj(passed in XAR4)
;; - *+XAR4[0]: uint32_t seedValue -> Initial value of the CRC calculation
;; - *+XAR4[2]: uint16_t nMsgBytes -> the number of bytes in the message buffer
;; - *+XAR4[3]: CRC_parity_e parity -> start the CRC from the low byte (CRC_parity_even) or high byte (CRC_parity_odd) of the first word
;; - *+XAR4[4]: uint32_t crcResult -> the calculated CRC
;; - *+XAR4[6]: void *pMsgBuffer -> Pointer to the message buffer
;; - *+XAR4[8]: void *pCrcTable -> Pointer to the CRC lookup table
;;
;; \note
;; -
;;
;; \return CRC of the message(stored within the structure itself)
;;
_CRC_run24Bit:
CRC_CONTEXT_SAVE
;MOVL XAR2, XAR4 ;*+XAR4[3bit] addressing wont support a larger structure
;might have to assign XAR2 to point to the structure and
;iterate through using XAR2++
;; Register Usage:
;; XAR0: Number of bytes to process
;; XAR1: Repeat block counter
;; XAR2: Pointer to iterate through the CRC object(possible future use)
;; XAR4: Points to the CRC object
;; XAR5: Points to the message buffer
;;
VCRCCLR ; Clear out the CRC result register
MOVL XAR0, *+XAR4[ARG_NBYTES] ; Load number of message bytes into AR0
VMOV32 VCRC, *+XAR4[ARG_SEEDVAL] ; Load seed value into the CRC result register
MOVL XAR5, *+XAR4[ARG_MSGBUFFER] ; XAR5 points to the message buffer
MOV AL, *+XAR4[ARG_PARITY] ; Check the parity
SBF _CRC_run24Bit_Loop, EQ ; If Parity = LOW_BYTE, skip to loop
VCRC24H_1 *XAR5++ ; Parity = HIGH_BYTE, calculate high byte of the first word,
; ignore the low byte and proceed to next word
DEC AR0
SBF _CRC_run24Bit_End, EQ ; Jump to end if no more bytes
_CRC_run24Bit_Loop:
MOV AL, AR0
MOV AH, AR0
AND AL, #0xFFF8 ; Check to see if length greater than 8 bytes
; if true, handle the <8 bytes in a loop
; AL is now a multiple of 8
SBF _CRC_run24Bit_LT8BytesLeft, EQ
LSR AL, #3 ; loop in 8 bytes at a time
MOV AR1, AL ; move count into AR1
SUB AR1, #1 ; subtract 1, accounts for the RPTB instruction i.e. it loops
; N + 1 times
.align 2 ; align at 32-bit boundary to remove penalty
; loop through the message 8 bytes at a time
RPTB _CRC_run24Bit_RepeatBlock, AR1
VCRC24L_1 *XAR5
VCRC24H_1 *XAR5++
VCRC24L_1 *XAR5
VCRC24H_1 *XAR5++
VCRC24L_1 *XAR5
VCRC24H_1 *XAR5++
VCRC24L_1 *XAR5
VCRC24H_1 *XAR5++
_CRC_run24Bit_RepeatBlock:
LSL AL, #3 ; multiply by 8 to get the pre RPTB count
SUB AH, AL ; AH holds the number of remaining bytes(<8)
SBF _CRC_run24Bit_End, EQ ; if multiple of 8, AH is 0, done processing
MOV AR0, AH
_CRC_run24Bit_LT8BytesLeft:
VCRC24L_1 *XAR5
DEC AR0
SBF _CRC_run24Bit_End, EQ
VCRC24H_1 *XAR5++
DEC AR0
SBF _CRC_run24Bit_LT8BytesLeft, NEQ
_CRC_run24Bit_End:
VMOV32 *+XAR4[ARG_CRCRESULT], VCRC ; Save the result to the structure
CRC_CONTEXT_RESTORE
LRETR
;;*****************************************************************************
;;
;; \brief Calculate the 24-bit CRC using polynomial 0x5d6dcb but with input bits reversed
;;
;; \param Handle to the structure, CRC_Obj(passed in XAR4)
;; - *+XAR4[0]: uint32_t seedValue -> Initial value of the CRC calculation
;; - *+XAR4[2]: uint16_t nMsgBytes -> the number of bytes in the message buffer
;; - *+XAR4[3]: CRC_parity_e parity -> start the CRC from the low byte (CRC_parity_even) or high byte (CRC_parity_odd) of the first word
;; - *+XAR4[4]: uint32_t crcResult -> the calculated CRC
;; - *+XAR4[6]: void *pMsgBuffer -> Pointer to the message buffer
;; - *+XAR4[8]: void *pCrcTable -> Pointer to the CRC lookup table
;;
;; \note
;; - actively sets the CRCMSGFLIP bit, each word has all its bits reversed prior to the
;; CRC being calculated
;;
;; \return CRC of the message(stored within the structure itself)
;;
_CRC_run24BitReflected:
VSETCRCMSGFLIP
LCR _CRC_run24Bit
VCLRCRCMSGFLIP
LRETR
;
;;*****************************************************************************
;;
;; \brief Initialize the 24-bit CRC
;;
;; Ensures that the CRCMSGFLIP bit is cleared, this ensures that the input
;; is interpreted in normal bit-order
;;
;; \param Handle to the structure, CRC_Obj(passed in XAR4)
;; - *+XAR4[0]: uint32_t seedValue -> Initial value of the CRC calculation
;; - *+XAR4[2]: uint16_t nMsgBytes -> the number of bytes in the message buffer
;; - *+XAR4[3]: CRC_parity_e parity -> start the CRC from the low byte (CRC_parity_even) or high byte (CRC_parity_odd) of the first word
;; - *+XAR4[4]: uint32_t crcResult -> the calculated CRC
;; - *+XAR4[6]: void *pMsgBuffer -> Pointer to the message buffer
;; - *+XAR4[8]: void *pCrcTable -> Pointer to the CRC lookup table
;;
;; \note
;; -
;;
_CRC_init24Bit:
VCLRCRCMSGFLIP
LRETR
;; End of file
@@ -0,0 +1,352 @@
;;*****************************************************************************
;;! \file source/vcu2/vcu2_crc_32.asm
;;!
;;! \brief 32-bit CRC
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;;*****************************************************************************
;; global defines
;;*****************************************************************************
;; CRC Routine defines
;; Argument structure defines
ARG_SEEDVAL .set 0
ARG_NBYTES .set 2
ARG_PARITY .set 3
ARG_CRCRESULT .set 4
ARG_MSGBUFFER .set 6
ARG_CRCTABLE .set 8
;;*****************************************************************************
;; macros
;;*****************************************************************************
;;
;; MACRO : 'CRC_CONTEXT_SAVE'
;; SIZE : Number of WORDS/Number of Cycles 3
;; USAGE : Called on entry into CRC routine
;;
CRC_CONTEXT_SAVE .macro
PUSH XAR1
PUSH XAR2
PUSH XAR3
.endm
;;
;; MACRO : 'CRC_CONTEXT_RESTORE'
;; SIZE : Number of WORDS/Number of Cycles 3
;; USAGE : Called on exit from CRC routine
;;
CRC_CONTEXT_RESTORE .macro
POP XAR3
POP XAR2
POP XAR1
.endm
.if $defined(__TI_EABI__)
.if __TI_EABI__
.asg CRC_run32BitPoly1, _CRC_run32BitPoly1
.asg CRC_run32BitPoly2, _CRC_run32BitPoly2
.asg CRC_run32BitPoly1Reflected, _CRC_run32BitPoly1Reflected
.asg CRC_run32BitPoly2Reflected, _CRC_run32BitPoly2Reflected
.asg CRC_init32Bit, _CRC_init32Bit
.endif
.endif
;;*****************************************************************************
;; globals
;;*****************************************************************************
.global _CRC_run32BitPoly1
.global _CRC_run32BitPoly2
.global _CRC_run32BitPoly1Reflected
.global _CRC_run32BitPoly2Reflected
.global _CRC_init32Bit
;;*****************************************************************************
;; function definitions
;;*****************************************************************************
.text
;;
;; \brief Calculate the 32-bit CRC using polynomial 0x04c11db7
;;
;; \param Handle to the structure, CRC_Obj(passed in XAR4)
;; - *+XAR4[0]: uint32_t seedValue -> Initial value of the CRC calculation
;; - *+XAR4[2]: uint16_t nMsgBytes -> the number of bytes in the message buffer
;; - *+XAR4[3]: CRC_parity_e parity -> start the CRC from the low byte (CRC_parity_even) or high byte (CRC_parity_odd) of the first word
;; - *+XAR4[4]: uint32_t crcResult -> the calculated CRC
;; - *+XAR4[6]: void *pMsgBuffer -> Pointer to the message buffer
;; - *+XAR4[8]: void *pCrcTable -> Pointer to the CRC lookup table
;;
;; \note
;; -
;;
;; \return CRC of the message(stored within the structure itself)
;;
_CRC_run32BitPoly1:
CRC_CONTEXT_SAVE
;MOVL XAR2, XAR4 ;*+XAR4[3bit] addressing wont support a larger structure
;might have to assign XAR2 to point to the structure and
;iterate through using XAR2++
;; Register Usage:
;; XAR0: Number of bytes to process
;; XAR1: Repeat block counter
;; XAR2: Pointer to iterate through the CRC object(possible future use)
;; XAR4: Points to the CRC object
;; XAR5: Points to the message buffer
;;
VCRCCLR ; Clear out the CRC result register
MOVL XAR0, *+XAR4[ARG_NBYTES] ; Load number of message bytes into AR0
VMOV32 VCRC, *+XAR4[ARG_SEEDVAL] ; Load seed value into the CRC result register
MOVL XAR5, *+XAR4[ARG_MSGBUFFER] ; XAR5 points to the message buffer
MOV AL, *+XAR4[ARG_PARITY] ; Check the parity
SBF _CRC_run32BitPoly1_Loop, EQ ; If Parity = LOW_BYTE, skip to loop
VCRC32H_1 *XAR5++ ; Parity = HIGH_BYTE, calculate high byte of the first word,
; ignore the low byte and proceed to next word
DEC AR0
SBF _CRC_run32BitPoly1_End, EQ ; Jump to end if no more bytes
_CRC_run32BitPoly1_Loop:
MOV AL, AR0
MOV AH, AR0
AND AL, #0xFFF8 ; Check to see if length greater than 8 bytes
; if true, handle the <8 bytes in a loop
; AL is now a multiple of 8
SBF _CRC_run32BitPoly1_LT8BytesLeft, EQ
LSR AL, #3 ; loop in 8 bytes at a time
MOV AR1, AL ; move count into AR1
SUB AR1, #1 ; subtract 1, accounts for the RPTB instruction i.e. it loops
; N + 1 times
.align 2 ; align at 32-bit boundary to remove penalty
; loop through the message 8 bytes at a time
RPTB _CRC_run32BitPoly1_RepeatBlock, AR1
VCRC32L_1 *XAR5
VCRC32H_1 *XAR5++
VCRC32L_1 *XAR5
VCRC32H_1 *XAR5++
VCRC32L_1 *XAR5
VCRC32H_1 *XAR5++
VCRC32L_1 *XAR5
VCRC32H_1 *XAR5++
_CRC_run32BitPoly1_RepeatBlock:
LSL AL, #3 ; multiply by 8 to get the pre RPTB count
SUB AH, AL ; AH holds the number of remaining bytes(<8)
SBF _CRC_run32BitPoly1_End, EQ ; if multiple of 8, AH is 0, done processing
MOV AR0, AH
_CRC_run32BitPoly1_LT8BytesLeft:
VCRC32L_1 *XAR5
DEC AR0
SBF _CRC_run32BitPoly1_End, EQ
VCRC32H_1 *XAR5++
DEC AR0
SBF _CRC_run32BitPoly1_LT8BytesLeft, NEQ
_CRC_run32BitPoly1_End:
VMOV32 *+XAR4[ARG_CRCRESULT], VCRC ; Save the result to the structure
CRC_CONTEXT_RESTORE
LRETR
;;*****************************************************************************
;;
;; \brief Calculate the 32-bit CRC using polynomial 0x1edc6f41
;;
;; \param Handle to the structure, CRC_Obj(passed in XAR4)
;; - *+XAR4[0]: uint32_t seedValue -> Initial value of the CRC calculation
;; - *+XAR4[2]: uint16_t nMsgBytes -> the number of bytes in the message buffer
;; - *+XAR4[3]: CRC_parity_e parity -> start the CRC from the low byte (CRC_parity_even) or high byte (CRC_parity_odd) of the first word
;; - *+XAR4[4]: uint32_t crcResult -> the calculated CRC
;; - *+XAR4[6]: void *pMsgBuffer -> Pointer to the message buffer
;; - *+XAR4[8]: void *pCrcTable -> Pointer to the CRC lookup table
;;
;; \note
;; -
;;
;; \return CRC of the message(stored within the structure itself)
;;
_CRC_run32BitPoly2:
CRC_CONTEXT_SAVE
MOVL XAR2, XAR4
;; Register Usage:
;; XAR0: Number of bytes to process
;; XAR1: Repeat block counter
;; XAR2: Pointer to iterate through the CRC object
;; XAR4: Points to the CRC object
;; XAR5: Points to the message buffer
;;
VCRCCLR ; Clear out the CRC result register
MOVL XAR0, *+XAR4[ARG_NBYTES] ; Load number of message bytes into AR0
VMOV32 VCRC, *+XAR4[ARG_SEEDVAL] ; Load seed value into the CRC result register
MOVL XAR5, *+XAR4[ARG_MSGBUFFER] ; XAR5 points to the message buffer
MOV AL, *+XAR4[ARG_PARITY] ; Check the parity
SBF _CRC_run32BitPoly2_Loop, EQ ; If Parity = LOW_BYTE, skip to loop
VCRC32P2H_1 *XAR5++ ; Parity = HIGH_BYTE, calculate high byte of the first word,
; ignore the low byte and proceed to next word
DEC AR0
SBF _CRC_run32BitPoly2_End, EQ ; Jump to end if no more bytes
_CRC_run32BitPoly2_Loop:
MOV AL, AR0
MOV AH, AR0
AND AL, #0xFFF8 ; Check to see if length greater than 8 bytes
; if true, handle the <8 bytes in a loop
; AL is now a multiple of 8
SBF _CRC_run32BitPoly2_LT8BytesLeft, EQ
LSR AL, #3 ; loop in 8 bytes at a time
MOV AR1, AL ; move count into AR1
SUB AR1, #1 ; subtract 1, accounts for the RPTB instruction i.e. it loops
; N + 1 times
.align 2 ; align at 32-bit boundary to remove penalty
; loop through the message 8 bytes at a time
RPTB _CRC_run32BitPoly2_RepeatBlock, AR1
VCRC32P2L_1 *XAR5
VCRC32P2H_1 *XAR5++
VCRC32P2L_1 *XAR5
VCRC32P2H_1 *XAR5++
VCRC32P2L_1 *XAR5
VCRC32P2H_1 *XAR5++
VCRC32P2L_1 *XAR5
VCRC32P2H_1 *XAR5++
_CRC_run32BitPoly2_RepeatBlock:
LSL AL, #3 ; multiply by 8 to get the pre RPTB count
SUB AH, AL ; AH holds the number of remaining bytes(<8)
SBF _CRC_run32BitPoly2_End, EQ ; if multiple of 8, AH is 0, done processing
MOV AR0, AH
_CRC_run32BitPoly2_LT8BytesLeft:
VCRC32P2L_1 *XAR5
DEC AR0
SBF _CRC_run32BitPoly2_End, EQ
VCRC32P2H_1 *XAR5++
DEC AR0
SBF _CRC_run32BitPoly2_LT8BytesLeft, NEQ
_CRC_run32BitPoly2_End:
VMOV32 *+XAR4[ARG_CRCRESULT], VCRC ; Save the result to the structure
CRC_CONTEXT_RESTORE
LRETR
;;*****************************************************************************
;;
;; \brief Calculate the 32-bit CRC using polynomial 0x04c11db7 but with input bits reversed
;;
;; \param Handle to the structure, CRC_Obj(passed in XAR4)
;; - *+XAR4[0]: uint32_t seedValue -> Initial value of the CRC calculation
;; - *+XAR4[2]: uint16_t nMsgBytes -> the number of bytes in the message buffer
;; - *+XAR4[3]: CRC_parity_e parity -> start the CRC from the low byte (CRC_parity_even) or high byte (CRC_parity_odd) of the first word
;; - *+XAR4[4]: uint32_t crcResult -> the calculated CRC
;; - *+XAR4[6]: void *pMsgBuffer -> Pointer to the message buffer
;; - *+XAR4[8]: void *pCrcTable -> Pointer to the CRC lookup table
;;
;; \note
;; - actively sets the CRCMSGFLIP bit, each word has all its bits reversed prior to the
;; CRC being calculated
;;
;; \return CRC of the message(stored within the structure itself)
;;
_CRC_run32BitPoly1Reflected:
VSETCRCMSGFLIP
LCR _CRC_run32BitPoly1
VCLRCRCMSGFLIP
LRETR
;;*****************************************************************************
;;
;; \brief Calculate the 32-bit CRC using polynomial 0x1edc6f41 but with input bits reversed
;;
;; \param Handle to the structure, CRC_Obj(passed in XAR4)
;; - *+XAR4[0]: uint32_t seedValue -> Initial value of the CRC calculation
;; - *+XAR4[2]: uint16_t nMsgBytes -> the number of bytes in the message buffer
;; - *+XAR4[3]: CRC_parity_e parity -> start the CRC from the low byte (CRC_parity_even) or high byte (CRC_parity_odd) of the first word
;; - *+XAR4[4]: uint32_t crcResult -> the calculated CRC
;; - *+XAR4[6]: void *pMsgBuffer -> Pointer to the message buffer
;; - *+XAR4[8]: void *pCrcTable -> Pointer to the CRC lookup table
;;
;; \note
;; - actively sets the CRCMSGFLIP bit, each word has all its bits reversed prior to the
;; CRC being calculated
;;
;; \return CRC of the message(stored within the structure itself)
;;
_CRC_run32BitPoly2Reflected:
VSETCRCMSGFLIP
LCR _CRC_run32BitPoly2
VCLRCRCMSGFLIP
LRETR
;;*****************************************************************************
;;
;; \brief Initialize the 32-bit CRC
;;
;; Ensures that the CRCMSGFLIP bit is cleared, this ensures that the input
;; is interpreted in normal bit-order
;;
;; \param Handle to the structure, CRC_Obj(passed in XAR4)
;; - *+XAR4[0]: uint32_t seedValue -> Initial value of the CRC calculation
;; - *+XAR4[2]: uint16_t nMsgBytes -> the number of bytes in the message buffer
;; - *+XAR4[3]: CRC_parity_e parity -> start the CRC from the low byte (CRC_parity_even) or high byte (CRC_parity_odd) of the first word
;; - *+XAR4[4]: uint32_t crcResult -> the calculated CRC
;; - *+XAR4[6]: void *pMsgBuffer -> Pointer to the message buffer
;; - *+XAR4[8]: void *pCrcTable -> Pointer to the CRC lookup table
;;
;; \note
;; -
;;
_CRC_init32Bit:
VCLRCRCMSGFLIP
LRETR
;; End of file
@@ -0,0 +1,240 @@
;;*****************************************************************************
;;! \file source/vcu2/vcu2_crc_8.asm
;;!
;;! \brief 8-bit CRC
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;;*****************************************************************************
;; global defines
;;*****************************************************************************
;; CRC Routine defines
;; Argument structure defines
ARG_SEEDVAL .set 0
ARG_NBYTES .set 2
ARG_PARITY .set 3
ARG_CRCRESULT .set 4
ARG_MSGBUFFER .set 6
ARG_CRCTABLE .set 8
;;*****************************************************************************
;; macros
;;*****************************************************************************
;;
;; MACRO : 'CRC_CONTEXT_SAVE'
;; SIZE : Number of WORDS/Number of Cycles 3
;; USAGE : Called on entry into CRC routine
;;
CRC_CONTEXT_SAVE .macro
PUSH XAR1
PUSH XAR2
PUSH XAR3
.endm
;;
;; MACRO : 'CRC_CONTEXT_RESTORE'
;; SIZE : Number of WORDS/Number of Cycles 3
;; USAGE : Called on exit from CRC routine
;;
CRC_CONTEXT_RESTORE .macro
POP XAR3
POP XAR2
POP XAR1
.endm
.if $defined(__TI_EABI__)
.if __TI_EABI__
.asg CRC_run8Bit, _CRC_run8Bit
.asg CRC_run8BitReflected, _CRC_run8BitReflected
.asg CRC_init8Bit, _CRC_init8Bit
.endif
.endif
;;*****************************************************************************
;; globals
;;*****************************************************************************
.global _CRC_run8Bit
.global _CRC_run8BitReflected
.global _CRC_init8Bit
;;*****************************************************************************
;; function definitions
;;*****************************************************************************
.text
;;
;; \brief Calculate the 8-bit CRC using polynomial 0x7
;;
;; \param Handle to the structure, CRC_Obj(passed in XAR4)
;; - *+XAR4[0]: uint32_t seedValue -> Initial value of the CRC calculation
;; - *+XAR4[2]: uint16_t nMsgBytes -> the number of bytes in the message buffer
;; - *+XAR4[3]: CRC_parity_e parity -> start the CRC from the low byte (CRC_parity_even) or high byte (CRC_parity_odd) of the first word
;; - *+XAR4[4]: uint32_t crcResult -> the calculated CRC
;; - *+XAR4[6]: void *pMsgBuffer -> Pointer to the message buffer
;; - *+XAR4[8]: void *pCrcTable -> Pointer to the CRC lookup table
;;
;; \note
;; -
;;
;; \return CRC of the message(stored within the structure itself)
;;
_CRC_run8Bit:
CRC_CONTEXT_SAVE
;MOVL XAR2, XAR4 ;*+XAR4[3bit] addressing wont support a larger structure
;might have to assign XAR2 to point to the structure and
;iterate through using XAR2++
;; Register Usage:
;; XAR0: Number of bytes to process
;; XAR1: Repeat block counter
;; XAR2: Pointer to iterate through the CRC object(possible future use)
;; XAR4: Points to the CRC object
;; XAR5: Points to the message buffer
;;
VCRCCLR ; Clear out the CRC result register
MOVL XAR0, *+XAR4[ARG_NBYTES] ; Load number of message bytes into AR0
VMOV32 VCRC, *+XAR4[ARG_SEEDVAL] ; Load seed value into the CRC result register
MOVL XAR5, *+XAR4[ARG_MSGBUFFER] ; XAR5 points to the message buffer
MOV AL, *+XAR4[ARG_PARITY] ; Check the parity
SBF _CRC_run8Bit_Loop, EQ ; If Parity = LOW_BYTE, skip to loop
VCRC8H_1 *XAR5++ ; Parity = HIGH_BYTE, calculate high byte of the first word,
; ignore the low byte and proceed to next word
DEC AR0
SBF _CRC_run8Bit_End, EQ ; Jump to end if no more bytes
_CRC_run8Bit_Loop:
MOV AL, AR0
MOV AH, AR0
AND AL, #0xFFF8 ; Check to see if length greater than 8 bytes
; if true, handle the <8 bytes in a loop
; AL is now a multiple of 8
SBF _CRC_run8Bit_LT8BytesLeft, EQ
LSR AL, #3 ; loop in 8 bytes at a time
MOV AR1, AL ; move count into AR1
SUB AR1, #1 ; subtract 1, accounts for the RPTB instruction i.e. it loops
; N + 1 times
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _CRC_run8Bit_RepeatBlock, AR1 ; loop through the message 8 bytes at a time
VCRC8L_1 *XAR5
VCRC8H_1 *XAR5++
VCRC8L_1 *XAR5
VCRC8H_1 *XAR5++
VCRC8L_1 *XAR5
VCRC8H_1 *XAR5++
VCRC8L_1 *XAR5
VCRC8H_1 *XAR5++
_CRC_run8Bit_RepeatBlock:
LSL AL, #3 ; multiply by 8 to get the pre RPTB count
SUB AH, AL ; AH holds the number of remaining bytes(<8)
SBF _CRC_run8Bit_End, EQ ; if multiple of 8, AH is 0, done processing
MOV AR0, AH
_CRC_run8Bit_LT8BytesLeft:
VCRC8L_1 *XAR5
DEC AR0
SBF _CRC_run8Bit_End, EQ
VCRC8H_1 *XAR5++
DEC AR0
SBF _CRC_run8Bit_LT8BytesLeft, NEQ
_CRC_run8Bit_End:
VMOV32 *+XAR4[ARG_CRCRESULT], VCRC ; Save the result to the structure
CRC_CONTEXT_RESTORE
LRETR
;;*****************************************************************************
;;
;; \brief Run the 8-bit CRC but with input bits reversed
;;
;; \param Handle to the structure, CRC_Obj(passed in XAR4)
;; - *+XAR4[0]: uint32_t seedValue -> Initial value of the CRC calculation
;; - *+XAR4[2]: uint16_t nMsgBytes -> the number of bytes in the message buffer
;; - *+XAR4[3]: CRC_parity_e parity -> start the CRC from the low byte (CRC_parity_even) or high byte (CRC_parity_odd) of the first word
;; - *+XAR4[4]: uint32_t crcResult -> the calculated CRC
;; - *+XAR4[6]: void *pMsgBuffer -> Pointer to the message buffer
;; - *+XAR4[8]: void *pCrcTable -> Pointer to the CRC lookup table
;;
;; \note
;; - actively sets the CRCMSGFLIP bit, each word has all its bits reversed prior to the
;; CRC being calculated
;;
_CRC_run8BitReflected:
VSETCRCMSGFLIP
LCR _CRC_run8Bit
VCLRCRCMSGFLIP
LRETR
;;*****************************************************************************
;;
;; \brief Initialize the 8-bit CRC
;;
;; Ensures that the CRCMSGFLIP bit is cleared, this ensures that the input
;; is interpreted in normal bit-order
;;
;; \param Handle to the structure, CRC_Obj(passed in XAR4)
;; - *+XAR4[0]: uint32_t seedValue -> Initial value of the CRC calculation
;; - *+XAR4[2]: uint16_t nMsgBytes -> the number of bytes in the message buffer
;; - *+XAR4[3]: CRC_parity_e parity -> start the CRC from the low byte (CRC_parity_even) or high byte (CRC_parity_odd) of the first word
;; - *+XAR4[4]: uint32_t crcResult -> the calculated CRC
;; - *+XAR4[6]: void *pMsgBuffer -> Pointer to the message buffer
;; - *+XAR4[8]: void *pCrcTable -> Pointer to the CRC lookup table
;;
;; \note
;; -
;;
_CRC_init8Bit:
VCLRCRCMSGFLIP
LRETR
;; End of file
@@ -0,0 +1,98 @@
;;*****************************************************************************
;;! \file source/vcu2/vcu2_crc_utils.asm
;;!
;;! \brief 8-bit CRC
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;;*****************************************************************************
;; global defines
;;*****************************************************************************
;; CRC Routine defines
;;*****************************************************************************
;; macros
;;*****************************************************************************
;;*****************************************************************************
;; globals
;;*****************************************************************************
.global _CRC_reset
;;*****************************************************************************
;; function definitions
;;*****************************************************************************
.text
;; \brief Workaround to the silicon issue of first VCU calculation on power up being
;; erroneous
;;
;; Details Due to the internal power-up state of the VCU module, it is possible
;; that the first CRC result will be incorrect. This condition applies to the
;; first result from each of the eight CRC instructions.
;; This rare condition can only occur after a power-on reset, but will not
;; necessarily occur on every power on. A warm reset will not cause this condition
;; to reappear.
;; Workaround(s) The application can reset the internal VCU CRC logic by
;; performing a CRC calculation of a single byte in the initialization routine.
;; This routine only needs to perform one CRC calculation and can use any of the
;; CRC instructions
;;
;;
_CRC_reset:
MOVB XAR7, #0
VCRC8L_1 *XAR7
VCRCCLR
LRETR
;; End of file
@@ -0,0 +1,294 @@
;;*****************************************************************************
;;! \file source/vcu2/vcu2_deinterleaver.asm
;;!
;;! \brief OFDM De-interleaver
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;*****************************************************************************
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;;*****************************************************************************
;; global defines
;;*****************************************************************************
;; DEINTERLEAVER Routine defines
;; Argument structure defines
ARG_OFF_INBUF .set 0
ARG_OFF_OUTBUF .set 2
ARG_OFF_SYMBOL .set 4
ARG_OFF_N .set 6
ARG_OFF_M .set 7
ARG_OFF_B .set 8
ARG_OFF_V .set 9
ARG_OFF_U .set 10
ARG_OFF_A .set 11
ARG_OFF_N_I .set 12
ARG_OFF_N_J .set 13
ARG_OFF_M_I .set 14
ARG_OFF_M_J .set 15
;; Stack defines
;;
;; |_______|
;; |_______|<- Stack Pointer(SP) <---SP
;; |_______|<- STK_ARG (SP-2)
;; |_______|<- STK_B (SP-4)
;; |_______|<- STK_V (SP-5)
;; |_______|<- STK_A (SP-6)
;; |_______|<- STK_U (SP-7)
;;
LOCAL_FRAME_SIZE .set 7
STK_ARG .set 2
STK_B .set 4
STK_V .set 5
STK_A .set 6
STK_U .set 7
;;*****************************************************************************
;; macros
;;*****************************************************************************
;;
;; MACRO : 'DEINTERLEAVER_CONTEXT_SAVE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on entry into DEINTERLEAVER routine
;;
DEINTERLEAVER_CONTEXT_SAVE .macro
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #LOCAL_FRAME_SIZE ; allocate stack space for local frame
; save VRx to stack
.endm
;;
;; MACRO : 'DEINTERLEAVER_CONTEXT_RESTORE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on exit from DEINTERLEAVER routine
;;
DEINTERLEAVER_CONTEXT_RESTORE .macro
SUBB SP, #LOCAL_FRAME_SIZE ; deallocate stack space for local frame
POP XAR3
POP XAR2
POP XAR1
.endm
;;*****************************************************************************
;; globals
;;*****************************************************************************
.if __TI_EABI__
.asg DEINTERLEAVER_run, _DEINTERLEAVER_run
.endif
.global _DEINTERLEAVER_run
;;*****************************************************************************
;; function definitions
;;*****************************************************************************
.text
;;
;; \brief De-interleave the symbols to get the original bits
;;
;; This piece of code implements the below algorithm:
;;
;; for (I=0;I<m; I++)
;; {
;; i = (a * I - u * J) % m;
;; j = (b * J - v * i) % n;
;; Y(i+j*m) = X(I);
;; }
;; - *+XAR4[0]: uint16_t *pInBuffer -> Pointer to the input buffer
;; - *+XAR4[2]: uint16_t *pOutBuffer -> Pointer to the input buffer
;; - *+XAR4[4]: uint16_t n -> number of OFDM symbols in each interleaving block
;; - *+XAR4[5]: uint16_t m -> number of sub carriers in each OFDM symbol
;; - *+XAR4[6]: uint16_t n_i -> Circular shift of the rows
;; - *+XAR4[7]: uint16_t n_j -> Circular shift of the rows
;; - *+XAR4[8]: uint16_t m_i -> Circular shift of the columns
;; - *+XAR4[9]: uint16_t m_j -> Circular shift of the columns
;;
;; \return De-interleaved bits(pointer to bits in the structure)
;;
;; Register Usage:
;; XAR0: index into the structure for elements at an OFF >7 from structure base
;; /index into the output buffer
;; XAR1: pointer to the output
;; XAR2: loop counter
;; XAR3: pointer to the input
;; XAR4: pointer to the structure
;; XAR5: symbol J
;; XAR6:
;; XAR7:
;; AL:
;; AH:
;; P:
;; T:
;;
_DEINTERLEAVER_run:
DEINTERLEAVER_CONTEXT_SAVE
MOVL XAR1, *+XAR4[ARG_OFF_OUTBUF] ; XAR1 -> output
MOVL XAR3, *+XAR4[ARG_OFF_INBUF] ; XAR3 -> output
MOVL XAR5, *+XAR4[ARG_OFF_SYMBOL] ; XAR5 -> symbol
MOVZ AR2, *+XAR4[ARG_OFF_M]
SUBB XAR2, #3 ; loop_counter = m - 3
MOV AR0, #ARG_OFF_B ; Save b,v to local frame
MOVL ACC, *+XAR4[AR0]
MOVL *-SP[STK_B], ACC
MOV AR0, #ARG_OFF_A ; Save a,u to local frame
MOVL ACC, *+XAR4[AR0]
MOVL *-SP[STK_A], ACC
MOVL XAR0, #0
VSETCPACK ; [Lo : Hi] -> [Real : Imag] packing
_DEINTERLEAVER_run_outerLoop:
VCLEARALL ; Initializes VR0L = I = 0
;;-------------------------------------------------------------------------
;; First Iteration
;;
VMOV32 VR4, *+XAR4[ARG_OFF_M] ; VR4H = m, VR4L = n
VMOV16 VR0H, *+XAR5[0] ; VR0H = J, VR0L = I
VMOV32 VR1, *-SP[STK_A] ; VR1H = u, VR1L = a
VMOV32 VR6, VR0 ; save current {J,I} in VR6
VCMPY VR3, VR2, VR1, VR0 ; VR3 = a*I - u*J | VR2 = a*J + u*I
VMOV16 VR0L, *+XAR5[0] ; DS1 | VR0L = J
VMOD32 VR0H, VR3, VR4H ; VR0H = (VR3 % VR4H) = i = (a*I - u*J) % m
VMOV32 VR1, *-SP[STK_B] ; DS1 | VR1H := v, VR1L := b
NOP ; DS2
NOP ; DS3
NOP ; DS4
NOP ; DS5
NOP ; DS6
NOP ; DS7
NOP ; DS8
;;-------------------------------------------------------------------------
;; Second Iteration
;;
VCMPY VR3, VR2, VR1, VR0 ; VR3 = b*J - v*i | VR2 = b*i + v*J
VMOV16 VR5L, VR0H ; DS1 | VR5L = i Save current i
VMOD32 VR5H, VR3, VR4L ; VR5H = (VR3 % VR4L) = j = (b*J - v*i) % n
|| VMOV32 VR0, VR6 ; VR0 = {J,I}
; compute j = (b * J - v * i) % n; load back saved {J,I}
VINC VR0L ; DS1 | increment I
|| VMOV32 VR1, *-SP[STK_A] ; | VR1H = u, VR1L = a ; load u, a
VCMPY VR3, VR2, VR1, VR0 ; DS2 | VR3 = a*I - u*J compute a * I - u * J
VMOV32 VR1, *-SP[STK_B] ; DS3 | DS1 | VR1H = v, VR1L = b load v, b
MOV AL, *XAR3++ ; DS4 | AL = X(I) load X(I)
NOP ; DS5
NOP ; DS6
VMOV32 VR6, VR0 ; DS7 | Save {J,I} in VR6
VMOV16 VR0L, *+XAR5[0] ; DS8 | VR0L = J load J
VMOD32 VR0H, VR3, VR4H ; VR0H = (VR3 % VR04H) = i = (a*I - u*J) % m;
VMPYADD VR5, VR5L, VR5H, VR4H ; DS1 | VR5 = VR5L + VR5H*VR4H = i + j*m compute i + j*m
NOP ; DS2 | DS1
NOP ; DS3 | DS2 -> One Extra NOP for BLDD
VMOV32 XAR0, VR5 ; DS4 | move VR5 to AR0
;;VMOV32 @XAR0,*(0:0x120a)
NOP ; DS5
NOP ; DS6
NOP ; DS7
;;-------------------------------------------------------------------------
;; Remaining but one Iterations (20 cycles)
;;
RPTB _DEINTERLEAVER_run_innerLoop, AR2 ; DS8 | Set Loop Start, Loop m-3 times
VCMPY VR3, VR2, VR1, VR0 ; VR3 = b*J - v*i compute b * J - v * i
VMOV16 VR5L, VR0H ; DS1 | VR5L = i Save current i
VMOD32 VR5H, VR3, VR4L ; VR5H = (VR3 % VR4L) = j = (b*J - v*i) % n
|| VMOV32 VR0, VR6 ; VR0 = {J,I} load back saved J,I
VINC VR0L ; DS1 | increment I
|| VMOV32 VR1, *-SP[STK_A] ; | VR1H = u, VR1L = a load u, a
MOV *+XAR1[AR0], AL ; DS2 | Save previous Y(i+j*m)
VCMPY VR3, VR2, VR1, VR0 ; DS3 | VR3 = a*I - u*J compute a * I - u * J
VMOV32 VR1, *-SP[STK_B] ; DS4 | DS1 | VR1H = v, VR1L = b load v, b
MOV AL, *XAR3++ ; DS5 | AL = X(I) load X(I)
NOP ; DS6
VMOV32 VR6, VR0 ; DS7 | VR6 = {J,I} save current {J,I}
VMOV16 VR0L, *+XAR5[0] ; DS8 | VR0L = J load J
VMOD32 VR0H, VR3, VR4H ; VR0H = (VR3 % VR4H) = i = (a*I - u*J) % m;
VMPYADD VR5, VR5L, VR5H, VR4H ; DS1 | VR5 = VR5L + VR5H*VR4H = i + j*m, compute i + j*m
NOP ; DS2 | DS1
NOP ; DS3 | DS2 -> One Extra NOP for BLDD
VMOV32 XAR0, VR5 ; DS4 | move VR5 to AR0
;;VMOV32 @XAR0,*(0:0x120a)
NOP ; DS5
NOP ; DS6
NOP ; DS7
NOP ; DS8
_DEINTERLEAVER_run_innerLoop:
;;-------------------------------------------------------------------------
;; Last iteration
;;
VCMPY VR3, VR2, VR1, VR0 ; VR3 = b*J - v*i compute b * J - v * i
VMOV16 VR5L, VR0H ; DS1 | VR5L = i Save current i
VMOD32 VR5H, VR3, VR4L ; VR5H = (VR3 % VR4L) = j = (b*J - v*i) % n;
NOP ; DS1
MOV *+XAR1[AR0], AL ; DS2 | Save previous Y(i+j*m)
NOP ; DS3
NOP ; DS4
MOV AL, *XAR3++ ; DS5 | AL = X(I) load X(I)
NOP ; DS6
NOP ; DS7
NOP ; DS8
VMPYADD VR5, VR5L, VR5H, VR4H ; VR5 = VR5L + VR5H*VR4H = i + j*m compute i + j*m
NOP ; DS1
NOP ; DS2 -> One Extra NOP for BLDD
VMOV32 XAR0, VR5 ; move VR5 to AR0
;;VMOV32 @XAR0,*(0:0x120a)
NOP ;
NOP ;
NOP ;
MOV *+XAR1[AR0], AL ; Save Y(i+j*m)
DEINTERLEAVER_CONTEXT_RESTORE
LRETR
;; End of file
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,980 @@
;;*****************************************************************************
;;! \file source/vcu2/vcu2_cfft_128.asm
;;!
;;! \brief 128-pt complex FFT
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;;*****************************************************************************
;; global defines
;;*****************************************************************************
;; FFT Routine defines
NSTAGES .set 7
NSAMPLES .set (1 << NSTAGES)
NSKIP .set 2*(512 / NSAMPLES) ;vcu0 largest table is stage9 i.e. 512 twiddles(used in unpack)
;the 2 in the numerator is for the size of the twiddle in words
STAGE1 .set 1
STAGE3 .set 3
STAGE5 .set 5
STAGE7 .set 7
;; Argument structure defines
ARG_INBUFFER .set 0
ARG_OUTBUFFER .set 2
ARG_TFTABLE .set 4
ARG_NSAMPLES .set 6
ARG_NSTAGES .set 7
ARG_TFSKIP .set 8
;; Stack defines
;;
;; |_______|
;; |_______|<- Stack Pointer(SP) <---SP
;; |_______|<- STK_ARG_PTR (SP-2)
;; |_______|<- STK_TFPTR (SP-4)
;;
LOCAL_FRAME_SIZE .set 4
STK_ARG_PTR .set 2
STK_TFPTR .set 4
;;*****************************************************************************
;; macros
;;*****************************************************************************
;;
;; MACRO : 'CFFT_CONTEXT_SAVE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on entry into FFT routine
;;
CFFT_CONTEXT_SAVE .macro
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #LOCAL_FRAME_SIZE ; allocate stack space for local frame
.endm
;;
;; MACRO : 'CFFT_CONTEXT_RESTORE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on exit from FFT routine
;;
CFFT_CONTEXT_RESTORE .macro
SUBB SP, #LOCAL_FRAME_SIZE ; deallocate stack space for local frame
POP XAR3
POP XAR2
POP XAR1
.endm
;;*****************************************************************************
;; globals
;;*****************************************************************************
.global _CFFT_run128Pt
.global _CFFT_init128Pt
.ref _vcu0_twiddleFactors
.ref _vcu2_twiddleFactors
;;*****************************************************************************
;; function definitions
;;*****************************************************************************
.text
;;
;; \brief Calculate the 128 pt Complex FFT
;;
;; \param Handle to the structure, CFFT_Obj(passed in XAR4)
;; - *+XAR4[0]: int16_t *pInBuffer -> input pointer
;; - *+XAR4[2]: int16_t *pOutBuffer -> work(Output) buffer pointer
;; - *+XAR4[4]: int16_t *pTwiddleFactors-> twiddle factor table pointer
;; - *+XAR4[6]: int16_t nSamples-> Number of data points
;; - *+XAR4[7]: int16_t nStages-> Number of FFT stages
;; - *+XAR4[8]: int16_t twiddleSkipStep-> Twiddle factor table search step
;;
;; \note
;; - This algorithm works on two buffers of size 2*N(32-bit complex) in ping-pong fashion
;; - N must be a power of 2 for this algorithm
;; - Must be of size N >= 16(2^4)
;; - This function actively sets CPACK=1 style complex packing
;; i.e. [Lo:Hi] => [Real:Imag], the input data must also be arranged in this format
;; - Sign extension is automatically done for right shift operations
;; - VSTATUS.RND=1, rounding is done for the right shift operation
;; - OVFR is set if signed overflow is detected for add/sub calculation in which destination is VRxL
;; - OVFI is set if signed overflow is detected for add/sub calculation in which destination is VRxH
;; - 16-bit signed results (before the shift right) are saturated if SAT = 1
;; - Make sure that input and output buffer pointer points to two diffrent
;; RAM blocks to avoid arbitration between reads and writes
;;
;; \return FFT of the input in the output buffer pointed to by CFFT_Obj.pOutBuffer
;;
_CFFT_run128Pt:
CFFT_CONTEXT_SAVE
MOVL *-SP[STK_ARG_PTR], XAR4
;; Computation Prep
VSETCPACK ; Set the CPACK bit to 1
;SETC SXM ; sign extension mode
; ISS says SXM is automatically done so check that it is
VSATON ; Turn ON Saturation
;;
;; Stages 1 and 2 Combined
;;
;; Notes:
;; - These stages use trivial twiddle factors: 1,-1,j and -j.
;; - C27x AMODE is required in this stage to facilitate the use of
;; the bit-reversed addressing mode with simultaneous ARP update i.e
;; VMOV32 mem32,VRx,ARPn
;; - Setting up the bit-reversed index in AR0
;; Assume N = 64, Since we have complex data its 2N or
;; 128(2^7) words to index i.e. we need 7 bits to address all locations(0-127)
;; we represent 1 as : b'0000001' -> 0x0001
;; bit reversed 1 as : b'1000000' -> 0x0040
;; N represented in hex is already 0x0040, so we load this directly to AR0
;; - Stages 1 and 2 arent affected by the SHR or SHL modifiers, results from all
;; operations are shifted right by 1 bit
;;
;; Register Usage:
;; XAR0: offset address(bit-reversed indexing)
;; XAR1: output storage pointer
;; XAR2: input pointer
;;
;; Stage 1 Stage 2
;; --XAR1,*BR0++---o----*-----o--------*--XAR2++-->
;; \ / \ /
;; \/ \ /
;; /\ \ /
;; / \ \/
;; --XAR1,*BR0++---o----*-----o---/\---*--XAR2++--->
;; \ / \ /
;; \ \
;; / \ / \
;; --XAR1,*BR0++---o----*-----o---\/---*--XAR2++-->
;; \ / /\
;; \/ / \
;; /\ / \
;; / \ / \
;; --XAR1,*BR0++---o----*-----o--------*--XAR2++--->
;;
_CFFT_run128Pt_stages1and2Combined:
;; local defines
S12_NBFLY .set (NSAMPLES / (2*2)) ; Number of 2x2 butterflies
S12_LOOP_COUNT .set S12_NBFLY - 2 ; Stage 1/2 loop count
MOVZ AR0, *+XAR4[ARG_NSAMPLES] ; AR0 := bit-reversed index 1
MOVL XAR2, *+XAR4[ARG_INBUFFER] ; XAR2 -> input buffer
MOVL XAR1, *+XAR4[ARG_OUTBUFFER] ; XAR1 -> output buffer
.lp_amode ; override assembler mode to C28x + C2xLP sysntax
SETC AMODE ; set AMODE to C2xLP addressing
NOP *,ARP2 ; ARP -> XAR2
VMOV32 VR0, *BR0++ ; VR0 := *(AR2 bradd AR0++) | VR0 := I0:R0
VMOV32 VR1, *BR0++ ; VR1 := *(AR2 bradd AR0++) | VR1 := I1:R1
VCFFT7 VR1, VR0, #1 ; VR2 = I2:R2 <- XAR1
|| VMOV32 VR2, *BR0++ ;[VR0H:VR0L] := [R0 - R1:R0 + R1] := [VR0L - VR1L:VR0L + VR1L]
;[VR1H:VR1L] := [I0 - I1:I0 + I1] := [VR0H - VR1H:VR0H + VR1H]
VMOV32 VR3, *BR0++ ; VR3 := I3:R3 <- XAR1
VCFFT8 VR3, VR2, #1 ;[VR2H:VR2L] := [R2 - R3:R2 + R3] := [VR2L - VR3L:VR2L + VR3L]
;[VR3H:VR3L] := [I2 - I3:I2 + I3] := [VR2H - VR3H:VR2H + VR3H]
VCFFT9 VR5, VR4, VR3, VR2, VR1, VR0, #1 ;[VR4H:VR4L] := [I0':R0'] := [(I0+I1) + (I2+I3):(R0+R1) + (R2+R3)] := [VR1L + VR3L:VR0L + VR2L]
;[VR5H:VR5L] := [I2':R2'] := [(I0+I1) - (I2+I3):(R0+R1) - (R2+R3)] := [VR1L VR3L:VR0L VR2L]
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _CFFT_run128Pt_stages1and2CombinedLoop, #S12_LOOP_COUNT
VCFFT10 VR7, VR6, VR3, VR2, VR1, VR0, #1 ; VR0 := I0:R0 <- *(AR2 bradd AR0++)
|| VMOV32 VR0, *BR0++ ;[VR6H:VR6L] := [I1':R1'] := [(I0-I1) - (R2-R3):(R0-R1) + (I2-I3)] := [VR1H VR2H:VR0H + VR3H]
;[VR7H:VR7L] := [I3':R3'] := [(I0-I1) + (R2-R3):(R0-R1) - (I2-I3)] := [VR1H + VR2H:VR0H VR3H]
VMOV32 VR1, *BR0++ ; VR1 := I1:R1 <- *(AR2 bradd AR0++)
VCFFT7 VR1, VR0, #1 ; VR2 := I2:R2 <- *(AR2 bradd AR0++)
|| VMOV32 VR2, *BR0++ ;[VR0H:VR0L] := [R0 - R1:R0 + R1] := [VR0L - VR1L:VR0L + VR1L]
;[VR1H:VR1L] := [I0 - I1:I0 + I1] := [VR0H - VR1H:VR0H + VR1H]
VMOV32 VR3, *BR0++ ; VR3 := I3:R3 <- *(AR2 bradd AR0++)
VCFFT8 VR3, VR2, #1 ; Save I0':R0' -> XAR1
|| VMOV32 *XAR1++, VR4 ;[VR2H:VR2L] := [R2 - R3:R2 + R3] := [VR2L - VR3L:VR2L + VR3L]
;[VR3H:VR3L] := [I2 - I3:I2 + I3] := [VR2H - VR3H:VR2H + VR3H]
VMOV32 *XAR1++, VR6 ; Save I1':R1' -> XAR1
VCFFT9 VR5, VR4, VR3, VR2, VR1, VR0, #1 ; Save I2':R2' -> XAR1
|| VMOV32 *XAR1++, VR5 ;[VR4H:VR4L] := [I0':R0'] := [(I0+I1) + (I2+I3):(R0+R1) + (R2+R3)] := [VR1L + VR3L:VR0L + VR2L]
;[VR5H:VR5L] := [I2':R2'] := [(I0+I1) - (I2+I3):(R0+R1) - (R2+R3)] := [VR1L VR3L:VR0L VR2L]
VMOV32 *++, VR7, ARP2 ; Save I3':R3' -> XAR1 | ARP -> XAR2
;VMOV32 *XAR1++, VR7, ARP2 ; Save I3':R3' -> XAR1 | ARP -> XAR2
;this form causes ARP to be XAR1 not XAR2
_CFFT_run128Pt_stages1and2CombinedLoop:
VCFFT10 VR7, VR6, VR3, VR2, VR1, VR0, #1 ;[VR6H:VR6L] := [I1':R1'] := [(I0-I1) - (R2-R3):(R0-R1) + (I2-I3)] := [VR1H VR2H:VR0H + VR3H]
;[VR7H:VR7L] := [I3':R3'] := [(I0-I1) + (R2-R3):(R0-R1) - (I2-I3)] := [VR1H + VR2H:VR0H VR3H]
VMOV32 *XAR1++, VR4 ; Save I0':R0' -> XAR1
VMOV32 *XAR1++, VR6 ; Save I1':R1' -> XAR1
VMOV32 *XAR1++, VR5 ; Save I2':R2' -> XAR1
VMOV32 *XAR1++, VR7 ; Save I3':R3' -> XAR1
_CFFT_run128Pt_stages1and2CombinedEnd:
.c28_amode ; change the assembler mode back to C28x
CLRC AMODE ; set AMODE back to C28x addressing
; C28_AMODE allows *XARn[#3bit] addressing
;;=============================================================================
;;
;; Stages 3 and 4 Combined
;;
;; Notes:
;; - These stages will use twiddle factors from the table, which are organized
;; as follows. Twiddles for stages 3 and 4 are interleaved
;; exp(2*pi*k1/N3) , k1 = {0,1,...N3/2-1}, N3 = 2^3
;; exp(2*pi*k2/N4) , k2 = {0,1,...N3/2-1}, N4 = 2^4
;; Cos(2*pi* 0/ 8) : Sin(2*pi* 0/ 8)
;; Cos(2*pi* 0/ 16) : Sin(2*pi* 0/ 16)
;; Cos(2*pi* 1/ 8) : Sin(2*pi* 1/ 8)
;; Cos(2*pi* 1/ 16) : Sin(2*pi* 1/ 16)
;; Cos(2*pi* 2/ 8) : Sin(2*pi* 2/ 8)
;; Cos(2*pi* 2/ 16) : Sin(2*pi* 2/ 16)
;; Cos(2*pi* 3/ 8) : Sin(2*pi* 3/ 8)
;; Cos(2*pi* 3/ 16) : Sin(2*pi* 3/ 16)
;;
;; - Stages 3 and 4 are affected by the SHR or SHL modifiers, results from all
;; operations are shifted right by SHR or left by SHL values
;; - XAR2, the output buffer from the previous stage is now the input to this stage
;;
;; Register Usage:
;; XAR0: butterfly lower ouput storage offset
;; XAR1: butterfly lower input storage offset
;; XAR2: pointer to even inputs(output of previous stage)
;; XAR3: pointer to twiddle factors
;; XAR4: pointer to odd inputs(output of previous stage)
;; XAR5: loop variable
;; XAR6: pointer to even outputs
;; XAR7: pointer to odd outputs
;;
;; Stage n Stage n+1
;; --XAR2-------------o----*---------o--------*------XAR6--->
;; \ / \ /
;; \/ \ /
;; /\ \ /
;; / \ \/
;; --XAR2[AR1]---XAR3-o----*---------o---/\---*--XAR6[AR0]--->
;; \ / \ /
;; \ \
;; / \ / \
;; --XAR4-------------o----*---XAR3--o---\/---*------XAR7--->
;; \ / /\
;; \/ / \
;; /\ / \
;; / \ / \
;; --XAR4[AR1]---XAR3-o----*---XAR3--o--------*--XAR7[AR0]--->
;;
_CFFT_run128Pt_stages3and4Combined:
;; local defines
S34_INPUT_OFFSET .set ARG_OUTBUFFER
S34_OUTPUT_OFFSET .set ARG_INBUFFER
S34_NBFLYS .set 1<<(STAGE3-1) ; Number of butterflys per group (2^(s-1))
S34_NGROUPS .set NSAMPLES/(2*S34_NBFLYS)
; Number of groups for this stage
S34_INSEP .set 2*(S34_NBFLYS) ; Input Seperation = (NBFLYs) * 2(size of complex inputs)
S34_OUTSEP .set S34_INSEP-2 ; Output Seperation
S34_GROUPSEP .set 4*S34_NBFLYS ; Seperation between the groups = NBFLYs * 2(inputs per butterfly) * 2(size of complex inputs)
S34_TFOFFSET .set 0 ; Twiddle factor table offset for stages 3 and 4
S56_TFOFFSET .set S34_TFOFFSET+4*S34_NBFLYS
; Twiddle factor table offset for stages 5 and 6
S34_INNER_LOOP_COUNT .set S34_NBFLYS-2 ; Repeat over the number of butterflies-2(last bfly done outside the loop, RPTB loops n+1 times)
S34_OUTER_LOOP_COUNT .set NSAMPLES/(4*S34_NBFLYS) - 1
; Outer loop count = N/(2(inputs per bfly)*2(words/input)*NBFLYS) - 1
S34_POST_INCREMENT .set 2*3*S34_NBFLYS ; Post-increment for all the data pointers
VSETSHR #15 ; SHR=15, does Q30 to Q15 conversion for VCFFTx Multiplications
VRNDON ; RND=1, turns on rounding during conversion from Q30 to Q15
;VSATON ; Turn ON Saturation
;; XAR2 XAR6
;; ---+-+----o--*---+----o-----*-----++-o-----------*--------o-----------------------*--+----------+-->>
;; G1| 2 \/ | \ / || \ / \ / . |
;; | | /\ | \ / || \ / \ / .XAR6++ |
;; ---+-v----o--*---|----o--X--*-----||-o--\-----/--*--------o--------------------/--*--+----------|-->>
;; 4 \/ \/ || \ \ / / \ \ / / | |
;; | /\ /\ 8| \ \ / / \ \ / / | |
;; ---+------o--*---v----o--X--*-----||-o--\--X--/--*--------o--\--------------/--/--*--6----------|-->>
;; G2| \/ / \ A| \ \/ \/ / \ \ \ / / / | |
;; | /\ / \ R| \ /\ /\ / \ \ \ / / / A |
;; ---+------o--*--------o-----*-----1|-o--X--X--X--*--------o--\--\--------/--/--/--*--R----------|-->>
;; || \/ \/ \/ \/ \ \ \ \ / / / / 0 |
;; XAR2[AR1]|| /\ /\ /\ /\ \ \ \ \ / / / / |XAR6[AR0] |
;; ---+------o--*--------o-----*-----v|-o--X--X--X--*--------o--\--\--\--X--/--/--/--*--v----------|-->>
;; G3| \/ \ / | / \/ \/ \ \ \ \ \/ \/ / / / |
;; | /\ \ / 16 / /\ /\ \ \ \ \ /\ /\ / / / 16
;; ---+------o--*--------o--X--*------|-o--/--X--\--*--------o--\--\--X--X--X--/--/--*-------------|-->>
;; \/ \/ | / / \ \ \ \ \/ \/ \/ \/ / / |
;; /\ /\ | / / \ \ \ \ /\ /\ /\ /\ / / |
;; ---+------o--*--------o--X--*------|-o--/-----\--*--------o--\--X--X--X--X--X--/--*-------------|-->>
;; G4| \/ / \ | / \ \ \/ \/ \/ \/ \/ \/ / |
;; | /\ / \ | / \ \ /\ /\ /\ /\ /\ /\ / |
;; ---+------o--*--------o-----*------|-o-----------*--------o--X--X--X--X--X--X--X--*-------------|-->>
;; | \/ \/ \/ \/ \/ \/ \/ \/ |
;; XAR4 | /\ /\ /\ /\ /\ /\ /\ /\ XAR7 |
;; ---+-+----o--*---+----o-----*-----+v-o-----------*--------o--X--X--X--X--X--X--X--*--+----------v-->>
;; G5| 2 \/ | \ / | \ / / \/ \/ \/ \/ \/ \/ \ .
;; | | /\ | \ / | \ / / /\ /\ /\ /\ /\ /\ \ .XAR7++
;; ---+-v----o--*---|----o--X--*-----|--o--\-----/--*--------o--/--X--X--X--X--X--\--*--+------------->>
;; 4 \/ \/ | \ \ / / / / \/ \/ \/ \/ \ \ |
;; | /\ /\ 8 \ \ / / / / /\ /\ /\ /\ \ \ 6
;; ---+------o--*---v----o--X--*-----|--o--\--X--/--*--------o--/--/--X--X--X--\--\--*--|------------->>
;; G6| \/ / \ A \ \/ \/ / / / / \/ \/ \ \ \ A
;; | /\ / \ R \ /\ /\ / / / / /\ /\ \ \ \ R
;; ---+------o--*--------o-----*-----1--o--X--X--X--*--------o--/--/--/--X--\--\--\--*--0------------->>
;; | \/ \/ \/ \/ / / / / \ \ \ \ |
;; XAR4[AR1]| /\ /\ /\ /\ / / / / \ \ \ \ |XAR7[AR0]
;; ---+------o--*--------o-----*-----v--o--X--X--X--*--------o--/--/--/-----\--\--\--*--v------------->>
;; G7| \/ \ / / \/ \/ \ / / / \ \ \
;; | /\ \ / / /\ /\ \ / / / \ \ \
;; ---+------o--*--------o--X--*--------o--/--X--\--*--------o--/--/-----------\--\--*---------------->>
;; \/ \/ / / \ \ / / \ \
;; /\ /\ / / \ \ / / \ \
;; ---+------o--*--------o--X--*--------o--/-----\--*--------o--/-----------------\--*---------------->>
;; G8| \/ / \ / \ / \
;; | /\ / \ / \ / \
;; ---+------o--*--------o-----*--------o-----------*--------o-----------------------*---------------->>
;; S1 S2 S3 S4
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the input data array at
;; the begining of every s & s+1 stage calculation.
;; Note that previous stage's output array is input for this stage
;MOVL XAR4, *-SP[STK_ARG_PTR] ; Restore the pointer argument to XAR4
; XAR4 is not used in stage 1 & 2
MOVL XAR2, *+XAR4[S34_INPUT_OFFSET] ; XAR2 -> I0:R0 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;; For stage s & s+1
;; These are the separation index for inputs and outputs
;; input_separation = 2* 2^(s-1)
;; For Stage 3 & 4, input_separation = 2 * 2^(3-1) = 8
;; For Stage 5 & 6, input_separation = 2 * 2^(5-1) = 32
;; For Stage 7 & 8, input_separation = 2 * 2^(7-1) = 128
;; And so on ....
MOVL XAR1, #S34_INSEP
;; ar0 is added with an XARn pointer which is post incremented (+2)
;; and hence ar0 = xar1-2
MOVL XAR0, #S34_OUTSEP
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;This pointer points to the begining of the 1st output of the combined
;; s & s+1 stage butterfly. Note that the input buffer of the previous
;; stage is used as output buffer for this stage due to ping-pong scheme
MOVL XAR6, *+XAR4[S34_OUTPUT_OFFSET] ; XAR6 -> first output
; I0'':R0'' pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;This pointer points to the 3rd output of the combined s & s+1 stage butterfly.
;;This pointer should be initialized as below
;;For Stage 3 & 4 = 2 * 2 * 2^(3-1) = 16
;;For Stage 5 & 6 = 2 * 2 * 2^(5-1) = 64
;;For Stage 7 & 8 = 2 * 2 * 2^(7-1) = 256
;;And so on ...
MOVL XAR7, XAR6
ADDB XAR7, #S34_GROUPSEP ; I2'':R2'' pointer
;;-------------------------------------------------------------------------
;;--------------------------------------------------
;;Initialize this pointer to the begining of the twiddle-factor
;;table for stage s & s+1
;;For Stage 3 & 4: 0 to [0 + 4 * 2^(3-1) - 1] = 0 to 15
;;For Stage 5 & 6: 16 to [16 + 4 * 2^(5-1) - 1] = 16 to 79
;;For Stage 7 & 8: 80 to [80 + 4 * 2^(7-1) - 1] = 80 to 335
;;And so on ....
MOVL XAR3, #_vcu2_twiddleFactors
;;ADDB XAR3, #S34_TFOFFSET
MOVL *-SP[STK_TFPTR], XAR3
;;--------------------------------------------------
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the 2nd set of butterflies used in
;; the 1st of the combined stages
;; Second Butterfly offset for stage s & s+1
;; = 2 * input_separation = 2 * 2 * 2^(s-1)
;; For Stage 3 & 4 = 2 * 2 * 2^(3-1) = 16
;; For Stage 5 & 6 = 2 * 2 * 2^(5-1) = 64
;; For Stage 7 & 8 = 2 * 2 * 2^(7-1) = 256
;; And so on ...
;;
MOVL XAR4, XAR2
ADDB XAR4, #S34_GROUPSEP ; I2:R2 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;Outer loop
;; For Stage s & s+1, combined
;; no_of_inner_but = 2^(s-1) = 2^(3-1) = 4
;; no_of_outer_loop = size/(2*no_of_inner_but*2)-1 = 128/(2*4*2) = 8-1 = 7
MOVL XAR5, #S34_OUTER_LOOP_COUNT ; Initialize outer loop counter
; used in BANZ
;;-------------------------------------------------------------------------
_CFFT_run128Pt_stages3and4OuterLoop:
MOVL XAR3, *-SP[STK_TFPTR] ; Reset the twiddle factor table pointer
;.lp_amode ; override assembler mode to C28x + C2xLP sysntax
;SETC AMODE ; set AMODE to C2xLP addressing
; Inner Butterfly Loop
VMOV32 VR5, *+XAR4[AR1] ; VR5 = I3:R3
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VMOV32 VR7, *XAR4++ ; VR7 = I2:R2
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VCFFT1 VR2, VR5, VR4 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1): R3*Cos(1) + I3*Sin(1)]
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #1 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1): R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H : R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H : R2 - VR2L]
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _CFFT_run128Pt_stages3and4InnerLoop, #S34_INNER_LOOP_COUNT
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #1 ; VR5 = I3:R3
|| VMOV32 VR5, *+XAR4[AR1] ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2): R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H : R0 + VR2L]
;[VR3H:VR3L] = [I1':R1'] = [I0 - VR2H : R0 - VR2L]
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VCFFT4 VR4, VR2, VR1, VR0, #1 ; VR7 = I2:R2
|| VMOV32 VR7, *XAR4++ ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2): I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0'':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2'] = [I0' - VR2H: R0' - VR2L]
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VMOV32 *XAR6++, VR0 ; [I0'':R0''] = VR0
VCFFT5 VR5, VR4, VR3, VR2, VR1, VR0, #1 ;[I2'':R2''] = VR1
|| VMOV32 *XAR7++, VR1 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1):R3*Cos(1) + I3*Sin(1)]
;[VR0H:VR0L] = [I1':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I1' + VR2H: R1' - VR2L]
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VMOV32 *+XAR6[AR0], VR0 ;[I1'':R1''] = VR0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #1 ;[I3'':R3''] = VR1
|| VMOV32 *+XAR7[AR0], VR1 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1):R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H: R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H: R2 - VR2L]
_CFFT_run128Pt_stages3and4InnerLoop:
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #1 ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2):R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H: R0 + VR2L]
;[VR1H:VR1L] = [I1':R1'] = [I0 - VR2H: R0 - VR2L]
NOP
VCFFT4 VR4, VR2, VR1, VR0, #1 ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2):I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2''] = [I0' - VR2H: R0' - VR2L]
NOP
VMOV32 *XAR6++, VR0 ;[I0'':R0''] = VR0
VCFFT6 VR3, VR2, VR1, VR0, #1 ;[I2'':R2''] = VR1
|| VMOV32 *XAR7++, VR1 ;[VR0H:VR0L] = [I1'':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3'':R3''] = [I1' + VR2H: R1' - VR2L]
NOP
VMOV32 *+XAR6[AR0], VR0 ;[I1'':R1''] = VR0
VMOV32 *+XAR7[AR0], VR1 ;[I3'':R3''] = VR1
;;--------------------------------------------------
;;Increment all these pointers with 2 * 3*2^(s-1)
;;for Stage 3 & 4, increment by 2 * 3 * 2^(3-1) = 24
;;for Stage 5 & 6, increment by 2 * 3 * 2^(5-1) = 96
;;for Stage 7 & 8, increment by 2 * 3 * 2^(7-1) = 384
ADDB XAR2, #S34_POST_INCREMENT
ADDB XAR4, #S34_POST_INCREMENT
ADDB XAR6, #S34_POST_INCREMENT
ADDB XAR7, #S34_POST_INCREMENT
;;--------------------------------------------------
BANZ _CFFT_run128Pt_stages3and4OuterLoop, AR5--
_CFFT_run128Pt_stages3and4CombinedEnd:
;.c28_amode ; change the assembler mode back to C28x
;CLRC AMODE ; set AMODE back to C28x addressing
; C28_AMODE allows *XARn[#3bit] addressing
; Stage 1 & 2 require AMODE others dont
;;=============================================================================
;;
;; Stages 5 and 6 Combined
;;
;; Notes:
;; - These stages will use twiddle factors from the table, which are organized
;; as follows. Twiddles for stages 5 and 6 are interleaved
;; exp(2*pi*k1/N5) , k1 = {0,1,...N5/2-1}, N5 = 2^5
;; exp(2*pi*k2/N6) , k2 = {0,1,...N5/2-1}, N6 = 2^6
;; - Stages 5 and 6 are affected by the SHR or SHL modifiers, results from all
;; operations are shifted right by SHR or left by SHL values
;; - XAR2, the pointer to the inputs, now points back to the input table
;;
;; Register Usage:
;; XAR0: butterfly lower ouput storage offset
;; XAR1: butterfly lower input storage offset
;; XAR2: pointer to even inputs(output of previous stage)
;; XAR3: pointer to twiddle factors
;; XAR4: pointer to odd inputs(output of previous stage)
;; XAR5: loop variable
;; XAR6: pointer to even outputs
;; XAR7: pointer to odd outputs
;;
;; Stage n Stage n+1
;; --XAR2-------------o----*---------o--------*------XAR6--->
;; \ / \ /
;; \/ \ /
;; /\ \ /
;; / \ \/
;; --XAR2[AR1]---XAR3-o----*---------o---/\---*--XAR6[AR0]--->
;; \ / \ /
;; \ \
;; / \ / \
;; --XAR4-------------o----*---XAR3--o---\/---*------XAR7--->
;; \ / /\
;; \/ / \
;; /\ / \
;; / \ / \
;; --XAR4[AR1]---XAR3-o----*---XAR3--o--------*--XAR7[AR0]--->
;;
_CFFT_run128Pt_stages5and6Combined:
;; local defines
S56_INPUT_OFFSET .set ARG_INBUFFER
S56_OUTPUT_OFFSET .set ARG_OUTBUFFER
S56_NBFLYS .set 1<<(STAGE5-1) ; Number of butterflys per group (2^(s-1))
S56_NGROUPS .set NSAMPLES/(2*S56_NBFLYS)
; Number of groups for this stage
S56_INSEP .set 2*(S56_NBFLYS) ; Input Seperation = (NBFLYs) * 2(size of complex inputs)
S56_OUTSEP .set S56_INSEP-2 ; Output Seperation
S56_GROUPSEP .set 4*S56_NBFLYS ; Seperation between the groups = NBFLYs * 2(inputs per butterfly) * 2(size of complex inputs)
S7_TFOFFSET .set 1<<STAGE5
; Twiddle factor table offset for stage 7 from start of vcu0_twiddlefactors
S56_INNER_LOOP_COUNT .set S56_NBFLYS-2 ; Repeat over the number of butterflies-2(last bfly done outside the loop, RPTB loops n+1 times)
S56_OUTER_LOOP_COUNT .set NSAMPLES/(4*S56_NBFLYS) - 1
; Outer loop count = N/(2(inputs per bfly)*2(words/input)*NBFLYS) - 1
S56_POST_INCREMENT .set 2*3*S56_NBFLYS ; Post-increment for all the data pointers
; Set once in stage 3 & 4, dont set again
;VSETSHR #15 ; SHR=15, does Q30 to Q15 conversion for VCFFTx Multiplications
;VRNDON ; RND=1, turns on rounding during conversion from Q30 to Q15
;VSATON ; Turn ON Saturation
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the input data array at
;; the begining of every s & s+1 stage calculation.
;; Note that previous stage's output array is input for this stage
MOVL XAR4, *-SP[STK_ARG_PTR] ; Restore the pointer argument to XAR4
MOVL XAR2, *+XAR4[S56_INPUT_OFFSET] ; XAR2 -> I0:R0 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;; For stage s & s+1
;; These are the separation index for inputs and outputs
;; input_separation = 2* 2^(s-1)
;; For Stage 3 & 4, input_separation = 2 * 2^(3-1) = 8
;; For Stage 5 & 6, input_separation = 2 * 2^(5-1) = 32
;; For Stage 7 & 8, input_separation = 2 * 2^(7-1) = 128
;; And so on ....
MOVL XAR1, #S56_INSEP
;; ar0 is added with an XARn pointer which is post incremented (+2)
;; and hence ar0 = xar1-2
MOVL XAR0, #S56_OUTSEP
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;This pointer points to the begining of the 1st output of the combined
;; s & s+1 stage butterfly. Note that the input buffer of the previous
;; stage is used as output buffer for this stage due to ping-pong scheme
MOVL XAR6, *+XAR4[S56_OUTPUT_OFFSET] ; XAR6 -> first output
; I0'':R0'' pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;This pointer points to the 3rd output of the combined s & s+1 stage butterfly.
;;This pointer should be initialized as below
;;For Stage 3 & 4 = 2 * 2 * 2^(3-1) = 16
;;For Stage 5 & 6 = 2 * 2 * 2^(5-1) = 64
;;For Stage 7 & 8 = 2 * 2 * 2^(7-1) = 256
;;And so on ...
MOVL XAR7, XAR6
ADDB XAR7, #S56_GROUPSEP ; I2'':R2'' pointer
;;-------------------------------------------------------------------------
;;--------------------------------------------------
;;Initialize this pointer to the begining of the twiddle-factor
;;table for stage s & s+1
;;For Stage 3 & 4: 0 to [0 + 4 * 2^(3-1) - 1] = 0 to 15
;;For Stage 5 & 6: 16 to [16 + 4 * 2^(5-1) - 1] = 16 to 79
;;For Stage 7 & 8: 80 to [80 + 4 * 2^(7-1) - 1] = 80 to 335
;;And so on ....
MOVL XAR3, #_vcu2_twiddleFactors
ADDB XAR3, #S56_TFOFFSET
MOVL *-SP[STK_TFPTR], XAR3
;;--------------------------------------------------
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the 2nd set of butterflies used in
;; the 1st of the combined stages
;; Second Butterfly offset for stage s & s+1
;; = 2 * input_separation = 2 * 2 * 2^(s-1)
;; For Stage 3 & 4 = 2 * 2 * 2^(3-1) = 16
;; For Stage 5 & 6 = 2 * 2 * 2^(5-1) = 64
;; For Stage 7 & 8 = 2 * 2 * 2^(7-1) = 256
;; And so on ...
;;
MOVL XAR4, XAR2
ADDB XAR4, #S56_GROUPSEP ; I2:R2 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;Outer loop
;; For Stage s & s+1, combined
;; no_of_inner_but = 2^(s-1) = 2^(3-1) = 4
;; no_of_outer_loop = size/(2*no_of_inner_but*2)-1 = 128/(2*16*2) = 2-1 = 1
MOVL XAR5, #S56_OUTER_LOOP_COUNT ; Initialize outer loop counter
; used in BANZ
;;-------------------------------------------------------------------------
_CFFT_run128Pt_stages5and6OuterLoop:
MOVL XAR3, *-SP[STK_TFPTR] ; Reset the twiddle factor table pointer
;.lp_amode ; override assembler mode to C28x + C2xLP sysntax
;SETC AMODE ; set AMODE to C2xLP addressing
; Inner Butterfly Loop
VMOV32 VR5, *+XAR4[AR1] ; VR5 = I3:R3
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VMOV32 VR7, *XAR4++ ; VR7 = I2:R2
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VCFFT1 VR2, VR5, VR4 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1): R3*Cos(1) + I3*Sin(1)]
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #1 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1): R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H : R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H : R2 - VR2L]
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _CFFT_run128Pt_stages5and6InnerLoop, #S56_INNER_LOOP_COUNT
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #1 ; VR5 = I3:R3
|| VMOV32 VR5, *+XAR4[AR1] ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2): R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H : R0 + VR2L]
;[VR3H:VR3L] = [I1':R1'] = [I0 - VR2H : R0 - VR2L]
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VCFFT4 VR4, VR2, VR1, VR0, #1 ; VR7 = I2:R2
|| VMOV32 VR7, *XAR4++ ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2): I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0'':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2'] = [I0' - VR2H: R0' - VR2L]
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VMOV32 *XAR6++, VR0 ; [I0'':R0''] = VR0
VCFFT5 VR5, VR4, VR3, VR2, VR1, VR0, #1 ;[I2'':R2''] = VR1
|| VMOV32 *XAR7++, VR1 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1):R3*Cos(1) + I3*Sin(1)]
;[VR0H:VR0L] = [I1':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I1' + VR2H: R1' - VR2L]
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VMOV32 *+XAR6[AR0], VR0 ;[I1'':R1''] = VR0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #1 ;[I3'':R3''] = VR1
|| VMOV32 *+XAR7[AR0], VR1 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1):R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H: R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H: R2 - VR2L]
_CFFT_run128Pt_stages5and6InnerLoop:
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #1 ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2):R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H: R0 + VR2L]
;[VR1H:VR1L] = [I1':R1'] = [I0 - VR2H: R0 - VR2L]
NOP
VCFFT4 VR4, VR2, VR1, VR0, #1 ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2):I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2''] = [I0' - VR2H: R0' - VR2L]
NOP
VMOV32 *XAR6++, VR0 ;[I0'':R0''] = VR0
VCFFT6 VR3, VR2, VR1, VR0, #1 ;[I2'':R2''] = VR1
|| VMOV32 *XAR7++, VR1 ;[VR0H:VR0L] = [I1'':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3'':R3''] = [I1' + VR2H: R1' - VR2L]
NOP
VMOV32 *+XAR6[AR0], VR0 ;[I1'':R1''] = VR0
VMOV32 *+XAR7[AR0], VR1 ;[I3'':R3''] = VR1
;;--------------------------------------------------
;;Increment all these pointers with 2 * 3*2^(s-1)
;;for Stage 3 & 4, increment by 2 * 3 * 2^(3-1) = 24
;;for Stage 5 & 6, increment by 2 * 3 * 2^(5-1) = 96
;;for Stage 7 & 8, increment by 2 * 3 * 2^(7-1) = 384
ADDB XAR2, #S56_POST_INCREMENT
ADDB XAR4, #S56_POST_INCREMENT
ADDB XAR6, #S56_POST_INCREMENT
ADDB XAR7, #S56_POST_INCREMENT
;;--------------------------------------------------
BANZ _CFFT_run128Pt_stages5and6OuterLoop, AR5--
_CFFT_run128Pt_stages5and6CombinedEnd:
;.c28_amode ; change the assembler mode back to C28x
;CLRC AMODE ; set AMODE back to C28x addressing
; C28_AMODE allows *XARn[#3bit] addressing
;;=============================================================================
;;
;; Stage 7
;;
;; Notes:
;; - These stages will use twiddle factors from the table, which are organized
;; as follows.
;; exp(2*pi*k1/N7) , k1 = {0,1,...N7-1}, N7 = 2^7
;; - Stages 7 is affected by the SHR or SHL modifiers, results from all
;; operations are shifted right by SHR or left by SHL values
;; - XAR2, the pointer to the inputs, now points to the output buffer
;; - This stage uses the VCMPY instruction that is dependent on the CPACK
;; bit, ensure that the CPACK bit = 1 i.e the low word is real
;; - This single stage changes the SHR and SHL values
;;
;; Register Usage:
;; XAR1: butterfly lower input/output storage offset
;; XAR2: pointer to even inputs(output of previous stage)
;; XAR4: pointer to structure(not used in the calculations)
;; XAR6: pointer to twiddle factors
;;
;; Stage n
;; --XAR2-------------o----*-------XAR3--->
;; \ /
;; \/
;; /\
;; / \
;; --XAR2[AR1]---XAR6-o----*---XAR3[AR1]--->
;;
;;
_CFFT_run128Pt_stage7:
;; local defines
S7_INPUT_OFFSET .set ARG_OUTBUFFER
S7_OUTPUT_OFFSET .set ARG_INBUFFER
S7_NBFLYS .set 1<<(STAGE7-1) ; Number of butterflys per group (2^(s-1))
S7_NGROUPS .set NSAMPLES/(2*S7_NBFLYS)
; Number of groups for this stage
S7_IOSEP .set 2*(S7_NBFLYS)-2 ; Input/Output Seperation = (NBFLYs) * 2(size of complex inputs)
; we add this offset to an incremented pointer hence the -2
S7_LOOP_COUNT .set S7_NBFLYS-3 ; Repeat over the number of butterflies-3
; (first and last bfly done outside the loop & RPTB loops n+1 times)
VSETSHR #16 ; SHR=16, scales down for VCADD/SUB operations
VSETSHL #15 ; SHR=15, scales down for VCADD/SUB operations
; The rest are set at the beginning of combined stages 1 & 2
;VRNDON ; RND=1, turns on rounding during conversion from Q30 to Q15
;VSATON ; Turn ON Saturation
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the input data array
;; Note that previous stage's output array is input for this stage
MOVL XAR4, *-SP[STK_ARG_PTR] ; Restore the pointer argument to XAR4
MOVL XAR2, *+XAR4[S7_INPUT_OFFSET] ; XAR2 -> I0:R0 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;; For stage s & s+1
;; These are the separation index for inputs and outputs
;; input_separation = 2* 2^(s-1)
;; For Stage 3 & 4, input_separation = 2 * 2^(3-1) = 8
;; For Stage 5 & 6, input_separation = 2 * 2^(5-1) = 32
;; For Stage 7 & 8, input_separation = 2 * 2^(7-1) = 128
;; And so on ....
MOVL XAR1, #S7_IOSEP
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the output of the butterfly.
;; Note that the input buffer of the previous stage is used as output
;; buffer for this stage due to ping-pong scheme
MOVL XAR3, *+XAR4[S7_OUTPUT_OFFSET] ; XAR3 -> output
; I0':R0' pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;Initialize this pointer to the begining of the twiddle-factor
;;table for stage
;;For Stage 3 & 4: 0 to [0 + 4 * 2^(3-1) - 1] = 0 to 15
;;For Stage 5 & 6: 16 to [16 + 4 * 2^(5-1) - 1] = 16 to 79
;;For Stage 7 & 8: 80 to [80 + 4 * 2^(7-1) - 1] = 80 to 335
;;And so on ....
MOVL XAR6, #_vcu0_twiddleFactors
ADDB XAR6, #S7_TFOFFSET
;MOVL *-SP[STK_TFPTR], XAR6
;Dont need to reset twiddle factor table pointer in single stages
;;-------------------------------------------------------------------------
VMOV32 VR4, *XAR2++ ; VR4 = I0:R0
VMOV32 VR1, *+XAR2[AR1] ; VR1 = I1:R1
VMOV32 VR0, *XAR6++ ; VR0 = Sin(1):Cos(1)
VCMPY VR3, VR2, VR1, VR0 ; VR0 = Sin(2):Cos(2)
|| VMOV32 VR0, *XAR6++ ; VR2 = I1*Cos(1) + R1*Sin(1)
; VR3 = R1*Cos(1) - I1*Sin(1)
NOP ; (delay slot of VCMPY)
VCDSUB16 VR6, VR4, VR3, VR2 ;[VR6H:VR6L] = [(I0<<SHL VR2)>>SHR : (R0<<SHL - VR3)>>SHR]
VCDADD16 VR5, VR4, VR3, VR2 ; VR4 = I0:R0 (next butterfly)
|| VMOV32 VR4, *XAR2++ ;[VR5H:VR5L] = [(I0<<SHL + VR2)>>SHR : (R0<<SHL + VR3)>>SHR]
VMOV32 VR1, *+XAR2[AR1] ; VR1 = I1:R1 (next butterfly)
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _CFFT_run128Pt_stage7Loop, #S7_LOOP_COUNT
VCMPY VR3, VR2, VR1, VR0 ;[I0':R0'] = VR5
|| VMOV32 *XAR3++, VR5 ; VR2 = I1*Cos(n) + R1*Sin(n)
; VR3 = R1*Cos(n) - I1*Sin(n)
VMOV32 *+XAR3[AR1], VR6 ; [I1':R1'] = VR5
VCDSUB16 VR6, VR4, VR3, VR2 ; VR0 = Sin(n):Cos(n)
|| VMOV32 VR0, *XAR6++ ;[VR6H:VR6L] = [(I0<<SHL VR2)>>SHR : (R0<<SHL - VR3)>>SHR]
VCDADD16 VR5, VR4, VR3, VR2 ; VR4 = I0:R0 (next butterfly)
|| VMOV32 VR4, *XAR2++ ;[VR5H:VR5L] = [(I0<<SHL + VR2)>>SHR : (R0<<SHL + VR3)>>SHR]
VMOV32 VR1, *+XAR2[AR1] ; VR1 = I1:R1 (next butterfly)
_CFFT_run128Pt_stage7Loop:
VCMPY VR3, VR2, VR1, VR0 ;[I0':R0'] = VR5
|| VMOV32 *XAR3++, VR5 ; VR2 = I1*Cos(n) + R1*Sin(n)
; VR3 = R1*Cos(n) - I1*Sin(n)
VMOV32 *+XAR3[AR1], VR6 ;[I1':R1'] = VR5
VCDSUB16 VR6, VR4, VR3, VR2 ;[VR6H:VR6L] = [(I0<<SHL VR2)>>SHR : (R0<<SHL - VR3)>>SHR]
VCDADD16 VR5, VR4, VR3, VR2 ;[VR5H:VR5L] = [(I0<<SHL + VR2)>>SHR : (R0<<SHL + VR3)>>SHR]
VMOV32 *XAR3++, VR5 ;[I0':R0'] = VR5
VMOV32 *+XAR3[AR1], VR6 ;[I1':R1'] = VR5
;;=============================================================================
;; Switch the input/output pointers
;; Register Usage:
;; ACC: temporary storage
;; P : temporary storage
;;
MOVL XAR4, *-SP[STK_ARG_PTR] ; Restore the pointer argument to XAR4
MOVL ACC, *+XAR4[ARG_INBUFFER]
MOVL P, *+XAR4[ARG_OUTBUFFER]
MOVL *+XAR4[ARG_INBUFFER], P
MOVL *+XAR4[ARG_OUTBUFFER], ACC
;;=============================================================================
CFFT_CONTEXT_RESTORE
LRETR
;;*****************************************************************************
;;
;; \brief Initialize the 128pt Complex FFT
;;
;; \param Handle to the structure, CFFT_Obj(passed in XAR4)
;; - *+XAR4[0]: int16_t *pInBuffer -> input pointer
;; - *+XAR4[2]: int16_t *pOutBuffer -> work(Output) buffer pointer
;; - *+XAR4[4]: int16_t *pTwiddleFactors-> twiddle factor table pointer
;; - *+XAR4[6]: int16_t nSamples-> Number of data points
;; - *+XAR4[7]: int16_t nStages-> Number of FFT stages
;; - *+XAR4[8]: int16_t twiddleSkipStep-> Twiddle factor table search step
;;
;;
_CFFT_init128Pt:
;;
;; Register Usage:
;; XAR0: index into the structure
;; XAR1: Number of samples
;; XAR2: Number of stages
;; XAR3: Pointer to twiddle factor table
;; XAR4: Pointer to the CFFT structure
;; XAR5:
;; XAR6:
;; XAR7: Twiddle skip factor
;;
CFFT_CONTEXT_SAVE
MOV AR0, #ARG_TFTABLE
MOVL XAR3, #_vcu2_twiddleFactors
MOVL *+XAR4[AR0], XAR3
MOV AR0, #ARG_NSAMPLES
MOVL XAR1, #NSAMPLES
MOV *+XAR4[AR0], AR1
MOV AR0, #ARG_NSTAGES
MOVL XAR2, #NSTAGES
MOV *+XAR4[AR0], AR2
MOV AR0, #ARG_TFSKIP
MOVL XAR7, #NSKIP
MOV *+XAR4[AR0], AR7
CFFT_CONTEXT_RESTORE
LRETR
;; End of file
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,739 @@
;;*****************************************************************************
;;! \file source/vcu2/vcu2_cfft_32.asm
;;!
;;! \brief 32-pt complex FFT
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;;*****************************************************************************
;; global defines
;;*****************************************************************************
;; FFT Routine defines
NSTAGES .set 5
NSAMPLES .set (1 << NSTAGES)
NSKIP .set 2*(512 / NSAMPLES) ;vcu0 largest table is stage9 i.e. 512 twiddles(used in unpack)
;the 2 in the numerator is for the size of the twiddle in words
STAGE1 .set 1
STAGE3 .set 3
STAGE5 .set 5
STAGE7 .set 7
;; Argument structure defines
ARG_INBUFFER .set 0
ARG_OUTBUFFER .set 2
ARG_TFTABLE .set 4
ARG_NSAMPLES .set 6
ARG_NSTAGES .set 7
ARG_TFSKIP .set 8
;; Stack defines
;;
;; |_______|
;; |_______|<- Stack Pointer(SP) <---SP
;; |_______|<- STK_ARG_PTR (SP-2)
;; |_______|<- STK_TFPTR (SP-4)
;;
LOCAL_FRAME_SIZE .set 4
STK_ARG_PTR .set 2
STK_TFPTR .set 4
;;*****************************************************************************
;; macros
;;*****************************************************************************
;;
;; MACRO : 'CFFT_CONTEXT_SAVE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on entry into FFT routine
;;
CFFT_CONTEXT_SAVE .macro
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #LOCAL_FRAME_SIZE ; allocate stack space for local frame
.endm
;;
;; MACRO : 'CFFT_CONTEXT_RESTORE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on exit from FFT routine
;;
CFFT_CONTEXT_RESTORE .macro
SUBB SP, #LOCAL_FRAME_SIZE ; deallocate stack space for local frame
POP XAR3
POP XAR2
POP XAR1
.endm
;;*****************************************************************************
;; globals
;;*****************************************************************************
.global _CFFT_run32Pt
.global _CFFT_init32Pt
.ref _vcu0_twiddleFactors
.ref _vcu2_twiddleFactors
;;*****************************************************************************
;; function definitions
;;*****************************************************************************
.text
;;
;; \brief Calculate the 32 pt Complex FFT
;;
;; \param Handle to the structure, CFFT_Obj(passed in XAR4)
;; - *+XAR4[0]: int16_t *pInBuffer -> input pointer
;; - *+XAR4[2]: int16_t *pOutBuffer -> work(Output) buffer pointer
;; - *+XAR4[4]: int16_t *pTwiddleFactors-> twiddle factor table pointer
;; - *+XAR4[6]: int16_t nSamples-> Number of data points
;; - *+XAR4[7]: int16_t nStages-> Number of FFT stages
;; - *+XAR4[8]: int16_t twiddleSkipStep-> Twiddle factor table search step
;;
;; \note
;; - This algorithm works on two buffers of size 2*N(32-bit complex) in ping-pong fashion
;; - N must be a power of 2 for this algorithm
;; - Must be of size N >= 16(2^4)
;; - This function actively sets CPACK=1 style complex packing
;; i.e. [Lo:Hi] => [Real:Imag], the input data must also be arranged in this format
;; - Sign extension is automatically done for right shift operations
;; - VSTATUS.RND=1, rounding is done for the right shift operation
;; - OVFR is set if signed overflow is detected for add/sub calculation in which destination is VRxL
;; - OVFI is set if signed overflow is detected for add/sub calculation in which destination is VRxH
;; - 16-bit signed results (before the shift right) are saturated if SAT = 1
;; - Make sure that input and output buffer pointer points to two diffrent
;; RAM blocks to avoid arbitration between reads and writes
;;
;; \return FFT of the input in the output buffer pointed to by CFFT_Obj.pOutBuffer
;;
_CFFT_run32Pt:
CFFT_CONTEXT_SAVE
MOVL *-SP[STK_ARG_PTR], XAR4
;; Computation Prep
VSETCPACK ; Set the CPACK bit to 1
;SETC SXM ; sign extension mode
; ISS says SXM is automatically done so check that it is
VSATON ; Turn ON Saturation
;;
;; Stages 1 and 2 Combined
;;
;; Notes:
;; - These stages use trivial twiddle factors: 1,-1,j and -j.
;; - C27x AMODE is required in this stage to facilitate the use of
;; the bit-reversed addressing mode with simultaneous ARP update i.e
;; VMOV32 mem32,VRx,ARPn
;; - Setting up the bit-reversed index in AR0
;; Assume N = 64, Since we have complex data its 2N or
;; 128(2^7) words to index i.e. we need 7 bits to address all locations(0-127)
;; we represent 1 as : b'0000001' -> 0x0001
;; bit reversed 1 as : b'1000000' -> 0x0040
;; N represented in hex is already 0x0040, so we load this directly to AR0
;; - Stages 1 and 2 arent affected by the SHR or SHL modifiers, results from all
;; operations are shifted right by 1 bit
;;
;; Register Usage:
;; XAR0: offset address(bit-reversed indexing)
;; XAR1: output storage pointer
;; XAR2: input pointer
;;
;; Stage 1 Stage 2
;; --XAR1,*BR0++---o----*-----o--------*--XAR2++-->
;; \ / \ /
;; \/ \ /
;; /\ \ /
;; / \ \/
;; --XAR1,*BR0++---o----*-----o---/\---*--XAR2++--->
;; \ / \ /
;; \ \
;; / \ / \
;; --XAR1,*BR0++---o----*-----o---\/---*--XAR2++-->
;; \ / /\
;; \/ / \
;; /\ / \
;; / \ / \
;; --XAR1,*BR0++---o----*-----o--------*--XAR2++--->
;;
_CFFT_run32Pt_stages1and2Combined:
;; local defines
S12_NBFLY .set (NSAMPLES / (2*2)) ; Number of 2x2 butterflies
S12_LOOP_COUNT .set S12_NBFLY - 2 ; Stage 1/2 loop count
MOVZ AR0, *+XAR4[ARG_NSAMPLES] ; AR0 := bit-reversed index 1
MOVL XAR2, *+XAR4[ARG_INBUFFER] ; XAR2 -> input buffer
MOVL XAR1, *+XAR4[ARG_OUTBUFFER] ; XAR1 -> output buffer
.lp_amode ; override assembler mode to C28x + C2xLP sysntax
SETC AMODE ; set AMODE to C2xLP addressing
NOP *,ARP2 ; ARP -> XAR2
VMOV32 VR0, *BR0++ ; VR0 := *(AR2 bradd AR0++) | VR0 := I0:R0
VMOV32 VR1, *BR0++ ; VR1 := *(AR2 bradd AR0++) | VR1 := I1:R1
VCFFT7 VR1, VR0, #1 ; VR2 = I2:R2 <- XAR1
|| VMOV32 VR2, *BR0++ ;[VR0H:VR0L] := [R0 - R1:R0 + R1] := [VR0L - VR1L:VR0L + VR1L]
;[VR1H:VR1L] := [I0 - I1:I0 + I1] := [VR0H - VR1H:VR0H + VR1H]
VMOV32 VR3, *BR0++ ; VR3 := I3:R3 <- XAR1
VCFFT8 VR3, VR2, #1 ;[VR2H:VR2L] := [R2 - R3:R2 + R3] := [VR2L - VR3L:VR2L + VR3L]
;[VR3H:VR3L] := [I2 - I3:I2 + I3] := [VR2H - VR3H:VR2H + VR3H]
VCFFT9 VR5, VR4, VR3, VR2, VR1, VR0, #1 ;[VR4H:VR4L] := [I0':R0'] := [(I0+I1) + (I2+I3):(R0+R1) + (R2+R3)] := [VR1L + VR3L:VR0L + VR2L]
;[VR5H:VR5L] := [I2':R2'] := [(I0+I1) - (I2+I3):(R0+R1) - (R2+R3)] := [VR1L VR3L:VR0L VR2L]
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _CFFT_run32Pt_stages1and2CombinedLoop, #S12_LOOP_COUNT
VCFFT10 VR7, VR6, VR3, VR2, VR1, VR0, #1 ; VR0 := I0:R0 <- *(AR2 bradd AR0++)
|| VMOV32 VR0, *BR0++ ;[VR6H:VR6L] := [I1':R1'] := [(I0-I1) - (R2-R3):(R0-R1) + (I2-I3)] := [VR1H VR2H:VR0H + VR3H]
;[VR7H:VR7L] := [I3':R3'] := [(I0-I1) + (R2-R3):(R0-R1) - (I2-I3)] := [VR1H + VR2H:VR0H VR3H]
VMOV32 VR1, *BR0++ ; VR1 := I1:R1 <- *(AR2 bradd AR0++)
VCFFT7 VR1, VR0, #1 ; VR2 := I2:R2 <- *(AR2 bradd AR0++)
|| VMOV32 VR2, *BR0++ ;[VR0H:VR0L] := [R0 - R1:R0 + R1] := [VR0L - VR1L:VR0L + VR1L]
;[VR1H:VR1L] := [I0 - I1:I0 + I1] := [VR0H - VR1H:VR0H + VR1H]
VMOV32 VR3, *BR0++ ; VR3 := I3:R3 <- *(AR2 bradd AR0++)
VCFFT8 VR3, VR2, #1 ; Save I0':R0' -> XAR1
|| VMOV32 *XAR1++, VR4 ;[VR2H:VR2L] := [R2 - R3:R2 + R3] := [VR2L - VR3L:VR2L + VR3L]
;[VR3H:VR3L] := [I2 - I3:I2 + I3] := [VR2H - VR3H:VR2H + VR3H]
VMOV32 *XAR1++, VR6 ; Save I1':R1' -> XAR1
VCFFT9 VR5, VR4, VR3, VR2, VR1, VR0, #1 ; Save I2':R2' -> XAR1
|| VMOV32 *XAR1++, VR5 ;[VR4H:VR4L] := [I0':R0'] := [(I0+I1) + (I2+I3):(R0+R1) + (R2+R3)] := [VR1L + VR3L:VR0L + VR2L]
;[VR5H:VR5L] := [I2':R2'] := [(I0+I1) - (I2+I3):(R0+R1) - (R2+R3)] := [VR1L VR3L:VR0L VR2L]
VMOV32 *++, VR7, ARP2 ; Save I3':R3' -> XAR1 | ARP -> XAR2
;VMOV32 *XAR1++, VR7, ARP2 ; Save I3':R3' -> XAR1 | ARP -> XAR2
;this form causes ARP to be XAR1 not XAR2
_CFFT_run32Pt_stages1and2CombinedLoop:
VCFFT10 VR7, VR6, VR3, VR2, VR1, VR0, #1 ;[VR6H:VR6L] := [I1':R1'] := [(I0-I1) - (R2-R3):(R0-R1) + (I2-I3)] := [VR1H VR2H:VR0H + VR3H]
;[VR7H:VR7L] := [I3':R3'] := [(I0-I1) + (R2-R3):(R0-R1) - (I2-I3)] := [VR1H + VR2H:VR0H VR3H]
VMOV32 *XAR1++, VR4 ; Save I0':R0' -> XAR1
VMOV32 *XAR1++, VR6 ; Save I1':R1' -> XAR1
VMOV32 *XAR1++, VR5 ; Save I2':R2' -> XAR1
VMOV32 *XAR1++, VR7 ; Save I3':R3' -> XAR1
_CFFT_run32Pt_stages1and2CombinedEnd:
.c28_amode ; change the assembler mode back to C28x
CLRC AMODE ; set AMODE back to C28x addressing
; C28_AMODE allows *XARn[#3bit] addressing
;;=============================================================================
;;
;; Stages 3 and 4 Combined
;;
;; Notes:
;; - These stages will use twiddle factors from the table, which are organized
;; as follows. Twiddles for stages 3 and 4 are interleaved
;; exp(2*pi*k1/N3) , k1 = {0,1,...N3/2-1}, N3 = 2^3
;; exp(2*pi*k2/N4) , k2 = {0,1,...N3/2-1}, N4 = 2^4
;; Cos(2*pi* 0/ 8) : Sin(2*pi* 0/ 8)
;; Cos(2*pi* 0/ 16) : Sin(2*pi* 0/ 16)
;; Cos(2*pi* 1/ 8) : Sin(2*pi* 1/ 8)
;; Cos(2*pi* 1/ 16) : Sin(2*pi* 1/ 16)
;; Cos(2*pi* 2/ 8) : Sin(2*pi* 2/ 8)
;; Cos(2*pi* 2/ 16) : Sin(2*pi* 2/ 16)
;; Cos(2*pi* 3/ 8) : Sin(2*pi* 3/ 8)
;; Cos(2*pi* 3/ 16) : Sin(2*pi* 3/ 16)
;;
;; - Stages 3 and 4 are affected by the SHR or SHL modifiers, results from all
;; operations are shifted right by SHR or left by SHL values
;; - XAR2, the output buffer from the previous stage is now the input to this stage
;;
;; Register Usage:
;; XAR0: butterfly lower ouput storage offset
;; XAR1: butterfly lower input storage offset
;; XAR2: pointer to even inputs(output of previous stage)
;; XAR3: pointer to twiddle factors
;; XAR4: pointer to odd inputs(output of previous stage)
;; XAR5: loop variable
;; XAR6: pointer to even outputs
;; XAR7: pointer to odd outputs
;;
;; Stage n Stage n+1
;; --XAR2-------------o----*---------o--------*------XAR6--->
;; \ / \ /
;; \/ \ /
;; /\ \ /
;; / \ \/
;; --XAR2[AR1]---XAR3-o----*---------o---/\---*--XAR6[AR0]--->
;; \ / \ /
;; \ \
;; / \ / \
;; --XAR4-------------o----*---XAR3--o---\/---*------XAR7--->
;; \ / /\
;; \/ / \
;; /\ / \
;; / \ / \
;; --XAR4[AR1]---XAR3-o----*---XAR3--o--------*--XAR7[AR0]--->
;;
_CFFT_run32Pt_stages3and4Combined:
;; local defines
S34_INPUT_OFFSET .set ARG_OUTBUFFER
S34_OUTPUT_OFFSET .set ARG_INBUFFER
S34_NBFLYS .set 1<<(STAGE3-1) ; Number of butterflys per group (2^(s-1))
S34_NGROUPS .set NSAMPLES/(2*S34_NBFLYS)
; Number of groups for this stage
S34_INSEP .set 2*(S34_NBFLYS) ; Input Seperation = (NBFLYs) * 2(size of complex inputs)
S34_OUTSEP .set S34_INSEP-2 ; Output Seperation
S34_GROUPSEP .set 4*S34_NBFLYS ; Seperation between the groups = NBFLYs * 2(inputs per butterfly) * 2(size of complex inputs)
S34_TFOFFSET .set 0 ; Twiddle factor table offset for stages 3 and 4
S5_TFOFFSET .set S34_TFOFFSET+4*S34_NBFLYS
; Twiddle factor table offset for stages 5 and 6
S34_INNER_LOOP_COUNT .set S34_NBFLYS-2 ; Repeat over the number of butterflies-2(last bfly done outside the loop, RPTB loops n+1 times)
S34_OUTER_LOOP_COUNT .set NSAMPLES/(4*S34_NBFLYS) - 1
; Outer loop count = N/(2(inputs per bfly)*2(words/input)*NBFLYS) - 1
S34_POST_INCREMENT .set 2*3*S34_NBFLYS ; Post-increment for all the data pointers
VSETSHR #15 ; SHR=15, does Q30 to Q15 conversion for VCFFTx Multiplications
VRNDON ; RND=1, turns on rounding during conversion from Q30 to Q15
;VSATON ; Turn ON Saturation
;; XAR2 XAR6
;; ---+-+----o--*---+----o-----*-----++-o-----------*--------o-----------------------*--+----------+-->>
;; G1| 2 \/ | \ / || \ / \ / . |
;; | | /\ | \ / || \ / \ / .XAR6++ |
;; ---+-v----o--*---|----o--X--*-----||-o--\-----/--*--------o--------------------/--*--+----------|-->>
;; 4 \/ \/ || \ \ / / \ \ / / | |
;; | /\ /\ 8| \ \ / / \ \ / / | |
;; ---+------o--*---v----o--X--*-----||-o--\--X--/--*--------o--\--------------/--/--*--6----------|-->>
;; G2| \/ / \ A| \ \/ \/ / \ \ \ / / / | |
;; | /\ / \ R| \ /\ /\ / \ \ \ / / / A |
;; ---+------o--*--------o-----*-----1|-o--X--X--X--*--------o--\--\--------/--/--/--*--R----------|-->>
;; || \/ \/ \/ \/ \ \ \ \ / / / / 0 |
;; XAR2[AR1]|| /\ /\ /\ /\ \ \ \ \ / / / / |XAR6[AR0] |
;; ---+------o--*--------o-----*-----v|-o--X--X--X--*--------o--\--\--\--X--/--/--/--*--v----------|-->>
;; G3| \/ \ / | / \/ \/ \ \ \ \ \/ \/ / / / |
;; | /\ \ / 16 / /\ /\ \ \ \ \ /\ /\ / / / 16
;; ---+------o--*--------o--X--*------|-o--/--X--\--*--------o--\--\--X--X--X--/--/--*-------------|-->>
;; \/ \/ | / / \ \ \ \ \/ \/ \/ \/ / / |
;; /\ /\ | / / \ \ \ \ /\ /\ /\ /\ / / |
;; ---+------o--*--------o--X--*------|-o--/-----\--*--------o--\--X--X--X--X--X--/--*-------------|-->>
;; G4| \/ / \ | / \ \ \/ \/ \/ \/ \/ \/ / |
;; | /\ / \ | / \ \ /\ /\ /\ /\ /\ /\ / |
;; ---+------o--*--------o-----*------|-o-----------*--------o--X--X--X--X--X--X--X--*-------------|-->>
;; | \/ \/ \/ \/ \/ \/ \/ \/ |
;; XAR4 | /\ /\ /\ /\ /\ /\ /\ /\ XAR7 |
;; ---+-+----o--*---+----o-----*-----+v-o-----------*--------o--X--X--X--X--X--X--X--*--+----------v-->>
;; G5| 2 \/ | \ / | \ / / \/ \/ \/ \/ \/ \/ \ .
;; | | /\ | \ / | \ / / /\ /\ /\ /\ /\ /\ \ .XAR7++
;; ---+-v----o--*---|----o--X--*-----|--o--\-----/--*--------o--/--X--X--X--X--X--\--*--+------------->>
;; 4 \/ \/ | \ \ / / / / \/ \/ \/ \/ \ \ |
;; | /\ /\ 8 \ \ / / / / /\ /\ /\ /\ \ \ 6
;; ---+------o--*---v----o--X--*-----|--o--\--X--/--*--------o--/--/--X--X--X--\--\--*--|------------->>
;; G6| \/ / \ A \ \/ \/ / / / / \/ \/ \ \ \ A
;; | /\ / \ R \ /\ /\ / / / / /\ /\ \ \ \ R
;; ---+------o--*--------o-----*-----1--o--X--X--X--*--------o--/--/--/--X--\--\--\--*--0------------->>
;; | \/ \/ \/ \/ / / / / \ \ \ \ |
;; XAR4[AR1]| /\ /\ /\ /\ / / / / \ \ \ \ |XAR7[AR0]
;; ---+------o--*--------o-----*-----v--o--X--X--X--*--------o--/--/--/-----\--\--\--*--v------------->>
;; G7| \/ \ / / \/ \/ \ / / / \ \ \
;; | /\ \ / / /\ /\ \ / / / \ \ \
;; ---+------o--*--------o--X--*--------o--/--X--\--*--------o--/--/-----------\--\--*---------------->>
;; \/ \/ / / \ \ / / \ \
;; /\ /\ / / \ \ / / \ \
;; ---+------o--*--------o--X--*--------o--/-----\--*--------o--/-----------------\--*---------------->>
;; G8| \/ / \ / \ / \
;; | /\ / \ / \ / \
;; ---+------o--*--------o-----*--------o-----------*--------o-----------------------*---------------->>
;; S1 S2 S3 S4
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the input data array at
;; the begining of every s & s+1 stage calculation.
;; Note that previous stage's output array is input for this stage
;MOVL XAR4, *-SP[STK_ARG_PTR] ; Restore the pointer argument to XAR4
; XAR4 is not used in stage 1 & 2
MOVL XAR2, *+XAR4[S34_INPUT_OFFSET] ; XAR2 -> I0:R0 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;; For stage s & s+1
;; These are the separation index for inputs and outputs
;; input_separation = 2* 2^(s-1)
;; For Stage 3 & 4, input_separation = 2 * 2^(3-1) = 8
;; For Stage 5 & 6, input_separation = 2 * 2^(5-1) = 32
;; For Stage 7 & 8, input_separation = 2 * 2^(7-1) = 128
;; And so on ....
MOVL XAR1, #S34_INSEP
;; ar0 is added with an XARn pointer which is post incremented (+2)
;; and hence ar0 = xar1-2
MOVL XAR0, #S34_OUTSEP
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;This pointer points to the begining of the 1st output of the combined
;; s & s+1 stage butterfly. Note that the input buffer of the previous
;; stage is used as output buffer for this stage due to ping-pong scheme
MOVL XAR6, *+XAR4[S34_OUTPUT_OFFSET] ; XAR6 -> first output
; I0'':R0'' pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;This pointer points to the 3rd output of the combined s & s+1 stage butterfly.
;;This pointer should be initialized as below
;;For Stage 3 & 4 = 2 * 2 * 2^(3-1) = 16
;;For Stage 5 & 6 = 2 * 2 * 2^(5-1) = 64
;;For Stage 7 & 8 = 2 * 2 * 2^(7-1) = 256
;;And so on ...
MOVL XAR7, XAR6
ADDB XAR7, #S34_GROUPSEP ; I2'':R2'' pointer
;;-------------------------------------------------------------------------
;;--------------------------------------------------
;;Initialize this pointer to the begining of the twiddle-factor
;;table for stage s & s+1
;;For Stage 3 & 4: 0 to [0 + 4 * 2^(3-1) - 1] = 0 to 15
;;For Stage 5 & 6: 16 to [16 + 4 * 2^(5-1) - 1] = 16 to 79
;;For Stage 7 & 8: 80 to [80 + 4 * 2^(7-1) - 1] = 80 to 335
;;And so on ....
MOVL XAR3, #_vcu2_twiddleFactors
;;ADDB XAR3, #S34_TFOFFSET
MOVL *-SP[STK_TFPTR], XAR3
;;--------------------------------------------------
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the 2nd set of butterflies used in
;; the 1st of the combined stages
;; Second Butterfly offset for stage s & s+1
;; = 2 * input_separation = 2 * 2 * 2^(s-1)
;; For Stage 3 & 4 = 2 * 2 * 2^(3-1) = 16
;; For Stage 5 & 6 = 2 * 2 * 2^(5-1) = 64
;; For Stage 7 & 8 = 2 * 2 * 2^(7-1) = 256
;; And so on ...
;;
MOVL XAR4, XAR2
ADDB XAR4, #S34_GROUPSEP ; I2:R2 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;Outer loop
;; For Stage s & s+1, combined
;; no_of_inner_but = 2^(s-1) = 2^(3-1) = 4
;; no_of_outer_loop = size/(2*no_of_inner_but*2)-1 = 32/(2*4*2) = 2-1 = 1
MOVL XAR5, #S34_OUTER_LOOP_COUNT ; Initialize outer loop counter
; used in BANZ
;;-------------------------------------------------------------------------
_CFFT_run32Pt_stages3and4OuterLoop:
MOVL XAR3, *-SP[STK_TFPTR] ; Reset the twiddle factor table pointer
;.lp_amode ; override assembler mode to C28x + C2xLP sysntax
;SETC AMODE ; set AMODE to C2xLP addressing
; Inner Butterfly Loop
VMOV32 VR5, *+XAR4[AR1] ; VR5 = I3:R3
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VMOV32 VR7, *XAR4++ ; VR7 = I2:R2
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VCFFT1 VR2, VR5, VR4 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1): R3*Cos(1) + I3*Sin(1)]
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #1 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1): R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H : R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H : R2 - VR2L]
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _CFFT_run32Pt_stages3and4InnerLoop, #S34_INNER_LOOP_COUNT
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #1 ; VR5 = I3:R3
|| VMOV32 VR5, *+XAR4[AR1] ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2): R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H : R0 + VR2L]
;[VR3H:VR3L] = [I1':R1'] = [I0 - VR2H : R0 - VR2L]
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VCFFT4 VR4, VR2, VR1, VR0, #1 ; VR7 = I2:R2
|| VMOV32 VR7, *XAR4++ ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2): I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0'':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2'] = [I0' - VR2H: R0' - VR2L]
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VMOV32 *XAR6++, VR0 ; [I0'':R0''] = VR0
VCFFT5 VR5, VR4, VR3, VR2, VR1, VR0, #1 ;[I2'':R2''] = VR1
|| VMOV32 *XAR7++, VR1 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1):R3*Cos(1) + I3*Sin(1)]
;[VR0H:VR0L] = [I1':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I1' + VR2H: R1' - VR2L]
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VMOV32 *+XAR6[AR0], VR0 ;[I1'':R1''] = VR0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #1 ;[I3'':R3''] = VR1
|| VMOV32 *+XAR7[AR0], VR1 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1):R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H: R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H: R2 - VR2L]
_CFFT_run32Pt_stages3and4InnerLoop:
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #1 ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2):R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H: R0 + VR2L]
;[VR1H:VR1L] = [I1':R1'] = [I0 - VR2H: R0 - VR2L]
NOP
VCFFT4 VR4, VR2, VR1, VR0, #1 ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2):I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2''] = [I0' - VR2H: R0' - VR2L]
NOP
VMOV32 *XAR6++, VR0 ;[I0'':R0''] = VR0
VCFFT6 VR3, VR2, VR1, VR0, #1 ;[I2'':R2''] = VR1
|| VMOV32 *XAR7++, VR1 ;[VR0H:VR0L] = [I1'':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3'':R3''] = [I1' + VR2H: R1' - VR2L]
NOP
VMOV32 *+XAR6[AR0], VR0 ;[I1'':R1''] = VR0
VMOV32 *+XAR7[AR0], VR1 ;[I3'':R3''] = VR1
;;--------------------------------------------------
;;Increment all these pointers with 2 * 3*2^(s-1)
;;for Stage 3 & 4, increment by 2 * 3 * 2^(3-1) = 24
;;for Stage 5 & 6, increment by 2 * 3 * 2^(5-1) = 96
;;for Stage 7 & 8, increment by 2 * 3 * 2^(7-1) = 384
ADDB XAR2, #S34_POST_INCREMENT
ADDB XAR4, #S34_POST_INCREMENT
ADDB XAR6, #S34_POST_INCREMENT
ADDB XAR7, #S34_POST_INCREMENT
;;--------------------------------------------------
BANZ _CFFT_run32Pt_stages3and4OuterLoop, AR5--
_CFFT_run32Pt_stages3and4CombinedEnd:
;.c28_amode ; change the assembler mode back to C28x
;CLRC AMODE ; set AMODE back to C28x addressing
; C28_AMODE allows *XARn[#3bit] addressing
; Stage 1 & 2 require AMODE others dont
;;=============================================================================
;;
;; Stage 5
;;
;; Notes:
;; - These stages will use twiddle factors from the table, which are organized
;; as follows.
;; exp(2*pi*k1/N5) , k1 = {0,1,...N5-1}, N5 = 2^5
;; - Stage 5 is affected by the SHR or SHL modifiers, results from all
;; operations are shifted right by SHR or left by SHL values
;; - XAR2, the pointer to the inputs, now points to the input buffer
;; - This stage uses the VCMPY instruction that is dependent on the CPACK
;; bit, ensure that the CPACK bit = 1 i.e the low word is real
;; - This single stage changes the SHR and SHL values
;;
;; Register Usage:
;; XAR1: butterfly lower input/output storage offset
;; XAR2: pointer to even inputs(output of previous stage)
;; XAR4: pointer to structure(not used in the calculations)
;; XAR6: pointer to twiddle factors
;;
;; Stage n
;; --XAR2-------------o----*-------XAR3--->
;; \ /
;; \/
;; /\
;; / \
;; --XAR2[AR1]---XAR6-o----*---XAR3[AR1]--->
;;
;;
_CFFT_run32Pt_stage5:
;; local defines
S5_INPUT_OFFSET .set ARG_INBUFFER
S5_OUTPUT_OFFSET .set ARG_OUTBUFFER
S5_NBFLYS .set 1<<(STAGE5-1) ; Number of butterflys per group (2^(s-1))
S5_NGROUPS .set NSAMPLES/(2*S5_NBFLYS)
; Number of groups for this stage
S5_IOSEP .set 2*(S5_NBFLYS)-2 ; Input/Output Seperation = (NBFLYs) * 2(size of complex inputs)
; we add this offset to an incremented pointer hence the -2
S5_LOOP_COUNT .set S5_NBFLYS-3 ; Repeat over the number of butterflies-3
; (first and last bfly done outside the loop & RPTB loops n+1 times)
VSETSHR #16 ; SHR=16, scales down for VCADD/SUB operations
VSETSHL #15 ; SHR=15, scales down for VCADD/SUB operations
; The rest are set at the beginning of combined stages 1 & 2
;VRNDON ; RND=1, turns on rounding during conversion from Q30 to Q15
;VSATON ; Turn ON Saturation
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the input data array
;; Note that previous stage's output array is input for this stage
MOVL XAR4, *-SP[STK_ARG_PTR] ; Restore the pointer argument to XAR4
MOVL XAR2, *+XAR4[S5_INPUT_OFFSET] ; XAR2 -> I0:R0 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;; For stage s & s+1
;; These are the separation index for inputs and outputs
;; input_separation = 2* 2^(s-1)
;; For Stage 3 & 4, input_separation = 2 * 2^(3-1) = 8
;; For Stage 5 & 6, input_separation = 2 * 2^(5-1) = 32
;; For Stage 7 & 8, input_separation = 2 * 2^(7-1) = 128
;; And so on ....
MOVL XAR1, #S5_IOSEP
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the output of the butterfly.
;; Note that the input buffer of the previous stage is used as output
;; buffer for this stage due to ping-pong scheme
MOVL XAR3, *+XAR4[S5_OUTPUT_OFFSET] ; XAR3 -> output
; I0':R0' pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;Initialize this pointer to the begining of the twiddle-factor
;;table for stage
;;For Stage 3 & 4: 0 to [0 + 4 * 2^(3-1) - 1] = 0 to 15
;;For Stage 5 & 6: 16 to [16 + 4 * 2^(5-1) - 1] = 16 to 79
;;For Stage 7 & 8: 80 to [80 + 4 * 2^(7-1) - 1] = 80 to 335
;;And so on ....
MOVL XAR6, #_vcu0_twiddleFactors
;ADDB XAR6, #S5_TFOFFSET
;MOVL *-SP[STK_TFPTR], XAR6
;Dont need to reset twiddle factor table pointer in single stages
;;-------------------------------------------------------------------------
VMOV32 VR4, *XAR2++ ; VR4 = I0:R0
VMOV32 VR1, *+XAR2[AR1] ; VR1 = I1:R1
VMOV32 VR0, *XAR6++ ; VR0 = Sin(1):Cos(1)
VCMPY VR3, VR2, VR1, VR0 ; VR0 = Sin(2):Cos(2)
|| VMOV32 VR0, *XAR6++ ; VR2 = I1*Cos(1) + R1*Sin(1)
; VR3 = R1*Cos(1) - I1*Sin(1)
NOP ; (delay slot of VCMPY)
VCDSUB16 VR6, VR4, VR3, VR2 ;[VR6H:VR6L] = [(I0<<SHL VR2)>>SHR : (R0<<SHL - VR3)>>SHR]
VCDADD16 VR5, VR4, VR3, VR2 ; VR4 = I0:R0 (next butterfly)
|| VMOV32 VR4, *XAR2++ ;[VR5H:VR5L] = [(I0<<SHL + VR2)>>SHR : (R0<<SHL + VR3)>>SHR]
VMOV32 VR1, *+XAR2[AR1] ; VR1 = I1:R1 (next butterfly)
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _CFFT_run32Pt_stage5Loop, #S5_LOOP_COUNT
VCMPY VR3, VR2, VR1, VR0 ;[I0':R0'] = VR5
|| VMOV32 *XAR3++, VR5 ; VR2 = I1*Cos(n) + R1*Sin(n)
; VR3 = R1*Cos(n) - I1*Sin(n)
VMOV32 *+XAR3[AR1], VR6 ; [I1':R1'] = VR5
VCDSUB16 VR6, VR4, VR3, VR2 ; VR0 = Sin(n):Cos(n)
|| VMOV32 VR0, *XAR6++ ;[VR6H:VR6L] = [(I0<<SHL VR2)>>SHR : (R0<<SHL - VR3)>>SHR]
VCDADD16 VR5, VR4, VR3, VR2 ; VR4 = I0:R0 (next butterfly)
|| VMOV32 VR4, *XAR2++ ;[VR5H:VR5L] = [(I0<<SHL + VR2)>>SHR : (R0<<SHL + VR3)>>SHR]
VMOV32 VR1, *+XAR2[AR1] ; VR1 = I1:R1 (next butterfly)
_CFFT_run32Pt_stage5Loop:
VCMPY VR3, VR2, VR1, VR0 ;[I0':R0'] = VR5
|| VMOV32 *XAR3++, VR5 ; VR2 = I1*Cos(n) + R1*Sin(n)
; VR3 = R1*Cos(n) - I1*Sin(n)
VMOV32 *+XAR3[AR1], VR6 ;[I1':R1'] = VR5
VCDSUB16 VR6, VR4, VR3, VR2 ;[VR6H:VR6L] = [(I0<<SHL VR2)>>SHR : (R0<<SHL - VR3)>>SHR]
VCDADD16 VR5, VR4, VR3, VR2 ;[VR5H:VR5L] = [(I0<<SHL + VR2)>>SHR : (R0<<SHL + VR3)>>SHR]
VMOV32 *XAR3++, VR5 ;[I0':R0'] = VR5
VMOV32 *+XAR3[AR1], VR6 ;[I1':R1'] = VR5
;;=============================================================================
CFFT_CONTEXT_RESTORE
LRETR
;;*****************************************************************************
;;
;; \brief Initialize the 32pt Complex FFT
;;
;; \param Handle to the structure, CFFT_Obj(passed in XAR4)
;; - *+XAR4[0]: int16_t *pInBuffer -> input pointer
;; - *+XAR4[2]: int16_t *pOutBuffer -> work(Output) buffer pointer
;; - *+XAR4[4]: int16_t *pTwiddleFactors-> twiddle factor table pointer
;; - *+XAR4[6]: int16_t nSamples-> Number of data points
;; - *+XAR4[7]: int16_t nStages-> Number of FFT stages
;; - *+XAR4[8]: int16_t twiddleSkipStep-> Twiddle factor table search step
;;
_CFFT_init32Pt:
;;
;; Register Usage:
;; XAR0: index into the structure
;; XAR1: Number of samples
;; XAR2: Number of stages
;; XAR3: Pointer to twiddle factor table
;; XAR4: Pointer to the CFFT structure
;; XAR5:
;; XAR6:
;; XAR7: Twiddle skip factor
;;
CFFT_CONTEXT_SAVE
MOV AR0, #ARG_TFTABLE
MOVL XAR3, #_vcu2_twiddleFactors
MOVL *+XAR4[AR0], XAR3
MOV AR0, #ARG_NSAMPLES
MOVL XAR1, #NSAMPLES
MOV *+XAR4[AR0], AR1
MOV AR0, #ARG_NSTAGES
MOVL XAR2, #NSTAGES
MOV *+XAR4[AR0], AR2
MOV AR0, #ARG_TFSKIP
MOVL XAR7, #NSKIP
MOV *+XAR4[AR0], AR7
CFFT_CONTEXT_RESTORE
LRETR
;; End of file
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,837 @@
;;*****************************************************************************
;;! \file source/vcu2/vcu2_cfft_64.asm
;;!
;;! \brief 64-pt complex FFT
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;;*****************************************************************************
;; global defines
;;*****************************************************************************
;; FFT Routine defines
NSTAGES .set 6
NSAMPLES .set (1 << NSTAGES)
NSKIP .set 2*(512 / NSAMPLES) ;vcu0 largest table is stage9 i.e. 512 twiddles(used in unpack)
;the 2 in the numerator is for the size of the twiddle in words
STAGE1 .set 1
STAGE3 .set 3
STAGE5 .set 5
STAGE7 .set 7
;; Argument structure defines
ARG_INBUFFER .set 0
ARG_OUTBUFFER .set 2
ARG_TFTABLE .set 4
ARG_NSAMPLES .set 6
ARG_NSTAGES .set 7
ARG_TFSKIP .set 8
;; Stack defines
;;
;; |_______|
;; |_______|<- Stack Pointer(SP) <---SP
;; |_______|<- STK_ARG_PTR (SP-2)
;; |_______|<- STK_TFPTR (SP-4)
;;
LOCAL_FRAME_SIZE .set 4
STK_ARG_PTR .set 2
STK_TFPTR .set 4
;;*****************************************************************************
;; macros
;;*****************************************************************************
;;
;; MACRO : 'CFFT_CONTEXT_SAVE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on entry into FFT routine
;;
CFFT_CONTEXT_SAVE .macro
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #LOCAL_FRAME_SIZE ; allocate stack space for local frame
.endm
;;
;; MACRO : 'CFFT_CONTEXT_RESTORE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on exit from FFT routine
;;
CFFT_CONTEXT_RESTORE .macro
SUBB SP, #LOCAL_FRAME_SIZE ; deallocate stack space for local frame
POP XAR3
POP XAR2
POP XAR1
.endm
;;*****************************************************************************
;; globals
;;*****************************************************************************
.global _CFFT_run64Pt
.global _CFFT_init64Pt
.ref _vcu0_twiddleFactors
.ref _vcu2_twiddleFactors
;;*****************************************************************************
;; function definitions
;;*****************************************************************************
.text
;;
;; \brief Calculate the 64 pt Complex FFT
;;
;; \param Handle to the structure, CFFT_Obj(passed in XAR4)
;; - *+XAR4[0]: int16_t *pInBuffer -> input pointer
;; - *+XAR4[2]: int16_t *pOutBuffer -> work(Output) buffer pointer
;; - *+XAR4[4]: int16_t *pTwiddleFactors-> twiddle factor table pointer
;; - *+XAR4[6]: int16_t nSamples-> Number of data points
;; - *+XAR4[7]: int16_t nStages-> Number of FFT stages
;; - *+XAR4[8]: int16_t twiddleSkipStep-> Twiddle factor table search step
;;
;; \note
;; - This algorithm works on two buffers of size 2*N(32-bit complex) in ping-pong fashion
;; - N must be a power of 2 for this algorithm
;; - Must be of size N >= 16(2^4)
;; - Assumes CPACK=1 style complex packing i.e. [Lo:Hi] => [Real:Imag], CPACK bit is ignored
;; - Sign extension is automatically done for right shift operations
;; - VSTATUS.RND=1, rounding is done for the right shift operation
;; - OVFR is set if signed overflow is detected for add/sub calculation in which destination is VRxL
;; - OVFI is set if signed overflow is detected for add/sub calculation in which destination is VRxH
;; - 16-bit signed results (before the shift right) are saturated if SAT = 1
;; - Make sure that input and output buffer pointer points to two diffrent
;; RAM blocks to avoid arbitration between reads and writes
;;
;; \return FFT of the input in the output buffer pointed to by CFFT_Obj.pOutBuffer
;;
_CFFT_run64Pt:
CFFT_CONTEXT_SAVE
MOVL *-SP[STK_ARG_PTR], XAR4
;; Computation Prep
VSETCPACK ; Set the CPACK bit to 1
;SETC SXM ; sign extension mode
; ISS says SXM is automatically done so check that it is
VSATON ; Turn ON Saturation
;;
;; Stages 1 and 2 Combined
;;
;; Notes:
;; - These stages use trivial twiddle factors: 1,-1,j and -j.
;; - C27x AMODE is required in this stage to facilitate the use of
;; the bit-reversed addressing mode with simultaneous ARP update i.e
;; VMOV32 mem32,VRx,ARPn
;; - Setting up the bit-reversed index in AR0
;; Assume N = 64, Since we have complex data its 2N or
;; 128(2^7) words to index i.e. we need 7 bits to address all locations(0-127)
;; we represent 1 as : b'0000001' -> 0x0001
;; bit reversed 1 as : b'1000000' -> 0x0040
;; N represented in hex is already 0x0040, so we load this directly to AR0
;; - Stages 1 and 2 arent affected by the SHR or SHL modifiers, results from all
;; operations are shifted right by 1 bit
;;
;; Register Usage:
;; XAR0: offset address(bit-reversed indexing)
;; XAR1: output storage pointer
;; XAR2: input pointer
;;
;; Stage 1 Stage 2
;; --XAR1,*BR0++---o----*-----o--------*--XAR2++-->
;; \ / \ /
;; \/ \ /
;; /\ \ /
;; / \ \/
;; --XAR1,*BR0++---o----*-----o---/\---*--XAR2++--->
;; \ / \ /
;; \ \
;; / \ / \
;; --XAR1,*BR0++---o----*-----o---\/---*--XAR2++-->
;; \ / /\
;; \/ / \
;; /\ / \
;; / \ / \
;; --XAR1,*BR0++---o----*-----o--------*--XAR2++--->
;;
_CFFT_run64Pt_stages1and2Combined:
;; local defines
S12_NBFLY .set (NSAMPLES / (2*2)) ; Number of 2x2 butterflies
S12_LOOP_COUNT .set S12_NBFLY - 2 ; Stage 1/2 loop count
MOVZ AR0, *+XAR4[ARG_NSAMPLES] ; AR0 := bit-reversed index 1
MOVL XAR2, *+XAR4[ARG_INBUFFER] ; XAR2 -> input buffer
MOVL XAR1, *+XAR4[ARG_OUTBUFFER] ; XAR1 -> output buffer
.lp_amode ; override assembler mode to C28x + C2xLP sysntax
SETC AMODE ; set AMODE to C2xLP addressing
NOP *,ARP2 ; ARP -> XAR2
VMOV32 VR0, *BR0++ ; VR0 := *(AR2 bradd AR0++) | VR0 := I0:R0
VMOV32 VR1, *BR0++ ; VR1 := *(AR2 bradd AR0++) | VR1 := I1:R1
VCFFT7 VR1, VR0, #1 ; VR2 = I2:R2 <- XAR1
|| VMOV32 VR2, *BR0++ ;[VR0H:VR0L] := [R0 - R1:R0 + R1] := [VR0L - VR1L:VR0L + VR1L]
;[VR1H:VR1L] := [I0 - I1:I0 + I1] := [VR0H - VR1H:VR0H + VR1H]
VMOV32 VR3, *BR0++ ; VR3 := I3:R3 <- XAR1
VCFFT8 VR3, VR2, #1 ;[VR2H:VR2L] := [R2 - R3:R2 + R3] := [VR2L - VR3L:VR2L + VR3L]
;[VR3H:VR3L] := [I2 - I3:I2 + I3] := [VR2H - VR3H:VR2H + VR3H]
VCFFT9 VR5, VR4, VR3, VR2, VR1, VR0, #1 ;[VR4H:VR4L] := [I0':R0'] := [(I0+I1) + (I2+I3):(R0+R1) + (R2+R3)] := [VR1L + VR3L:VR0L + VR2L]
;[VR5H:VR5L] := [I2':R2'] := [(I0+I1) - (I2+I3):(R0+R1) - (R2+R3)] := [VR1L VR3L:VR0L VR2L]
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _CFFT_run64Pt_stages1and2CombinedLoop, #S12_LOOP_COUNT
VCFFT10 VR7, VR6, VR3, VR2, VR1, VR0, #1 ; VR0 := I0:R0 <- *(AR2 bradd AR0++)
|| VMOV32 VR0, *BR0++ ;[VR6H:VR6L] := [I1':R1'] := [(I0-I1) - (R2-R3):(R0-R1) + (I2-I3)] := [VR1H VR2H:VR0H + VR3H]
;[VR7H:VR7L] := [I3':R3'] := [(I0-I1) + (R2-R3):(R0-R1) - (I2-I3)] := [VR1H + VR2H:VR0H VR3H]
VMOV32 VR1, *BR0++ ; VR1 := I1:R1 <- *(AR2 bradd AR0++)
VCFFT7 VR1, VR0, #1 ; VR2 := I2:R2 <- *(AR2 bradd AR0++)
|| VMOV32 VR2, *BR0++ ;[VR0H:VR0L] := [R0 - R1:R0 + R1] := [VR0L - VR1L:VR0L + VR1L]
;[VR1H:VR1L] := [I0 - I1:I0 + I1] := [VR0H - VR1H:VR0H + VR1H]
VMOV32 VR3, *BR0++ ; VR3 := I3:R3 <- *(AR2 bradd AR0++)
VCFFT8 VR3, VR2, #1 ; Save I0':R0' -> XAR1
|| VMOV32 *XAR1++, VR4 ;[VR2H:VR2L] := [R2 - R3:R2 + R3] := [VR2L - VR3L:VR2L + VR3L]
;[VR3H:VR3L] := [I2 - I3:I2 + I3] := [VR2H - VR3H:VR2H + VR3H]
VMOV32 *XAR1++, VR6 ; Save I1':R1' -> XAR1
VCFFT9 VR5, VR4, VR3, VR2, VR1, VR0, #1 ; Save I2':R2' -> XAR1
|| VMOV32 *XAR1++, VR5 ;[VR4H:VR4L] := [I0':R0'] := [(I0+I1) + (I2+I3):(R0+R1) + (R2+R3)] := [VR1L + VR3L:VR0L + VR2L]
;[VR5H:VR5L] := [I2':R2'] := [(I0+I1) - (I2+I3):(R0+R1) - (R2+R3)] := [VR1L VR3L:VR0L VR2L]
VMOV32 *++, VR7, ARP2 ; Save I3':R3' -> XAR1 | ARP -> XAR2
;VMOV32 *XAR1++, VR7, ARP2 ; Save I3':R3' -> XAR1 | ARP -> XAR2
;this form causes ARP to be XAR1 not XAR2
_CFFT_run64Pt_stages1and2CombinedLoop:
VCFFT10 VR7, VR6, VR3, VR2, VR1, VR0, #1 ;[VR6H:VR6L] := [I1':R1'] := [(I0-I1) - (R2-R3):(R0-R1) + (I2-I3)] := [VR1H VR2H:VR0H + VR3H]
;[VR7H:VR7L] := [I3':R3'] := [(I0-I1) + (R2-R3):(R0-R1) - (I2-I3)] := [VR1H + VR2H:VR0H VR3H]
VMOV32 *XAR1++, VR4 ; Save I0':R0' -> XAR1
VMOV32 *XAR1++, VR6 ; Save I1':R1' -> XAR1
VMOV32 *XAR1++, VR5 ; Save I2':R2' -> XAR1
VMOV32 *XAR1++, VR7 ; Save I3':R3' -> XAR1
_CFFT_run64Pt_stages1and2CombinedEnd:
.c28_amode ; change the assembler mode back to C28x
CLRC AMODE ; set AMODE back to C28x addressing
; C28_AMODE allows *XARn[#3bit] addressing
;;=============================================================================
;;
;; Stages 3 and 4 Combined
;;
;; Notes:
;; - These stages will use twiddle factors from the table, which are organized
;; as follows. Twiddles for stages 3 and 4 are interleaved
;; exp(2*pi*k1/N3) , k1 = {0,1,...N3/2-1}, N3 = 2^3
;; exp(2*pi*k2/N4) , k2 = {0,1,...N3/2-1}, N4 = 2^4
;; Cos(2*pi* 0/ 8) : Sin(2*pi* 0/ 8)
;; Cos(2*pi* 0/ 16) : Sin(2*pi* 0/ 16)
;; Cos(2*pi* 1/ 8) : Sin(2*pi* 1/ 8)
;; Cos(2*pi* 1/ 16) : Sin(2*pi* 1/ 16)
;; Cos(2*pi* 2/ 8) : Sin(2*pi* 2/ 8)
;; Cos(2*pi* 2/ 16) : Sin(2*pi* 2/ 16)
;; Cos(2*pi* 3/ 8) : Sin(2*pi* 3/ 8)
;; Cos(2*pi* 3/ 16) : Sin(2*pi* 3/ 16)
;;
;; - Stages 3 and 4 are affected by the SHR or SHL modifiers, results from all
;; operations are shifted right by SHR or left by SHL values
;; - XAR2, the output buffer from the previous stage is now the input to this stage
;;
;; Register Usage:
;; XAR0: butterfly lower ouput storage offset
;; XAR1: butterfly lower input storage offset
;; XAR2: pointer to even inputs(output of previous stage)
;; XAR3: pointer to twiddle factors
;; XAR4: pointer to odd inputs(output of previous stage)
;; XAR5: loop variable
;; XAR6: pointer to even outputs
;; XAR7: pointer to odd outputs
;;
;; Stage n Stage n+1
;; --XAR2-------------o----*---------o--------*------XAR6--->
;; \ / \ /
;; \/ \ /
;; /\ \ /
;; / \ \/
;; --XAR2[AR1]---XAR3-o----*---------o---/\---*--XAR6[AR0]--->
;; \ / \ /
;; \ \
;; / \ / \
;; --XAR4-------------o----*---XAR3--o---\/---*------XAR7--->
;; \ / /\
;; \/ / \
;; /\ / \
;; / \ / \
;; --XAR4[AR1]---XAR3-o----*---XAR3--o--------*--XAR7[AR0]--->
;;
_CFFT_run64Pt_stages3and4Combined:
;; local defines
S34_INPUT_OFFSET .set ARG_OUTBUFFER
S34_OUTPUT_OFFSET .set ARG_INBUFFER
S34_NBFLYS .set 1<<(STAGE3-1) ; Number of butterflys per group (2^(s-1))
S34_NGROUPS .set NSAMPLES/(2*S34_NBFLYS)
; Number of groups for this stage
S34_INSEP .set 2*(S34_NBFLYS) ; Input Seperation = (NBFLYs) * 2(size of complex inputs)
S34_OUTSEP .set S34_INSEP-2 ; Output Seperation
S34_GROUPSEP .set 4*S34_NBFLYS ; Seperation between the groups = NBFLYs * 2(inputs per butterfly) * 2(size of complex inputs)
S34_TFOFFSET .set 0 ; Twiddle factor table offset for stages 3 and 4
S56_TFOFFSET .set S34_TFOFFSET+4*S34_NBFLYS
; Twiddle factor table offset for stages 5 and 6
S34_INNER_LOOP_COUNT .set S34_NBFLYS-2 ; Repeat over the number of butterflies-2(last bfly done outside the loop, RPTB loops n+1 times)
S34_OUTER_LOOP_COUNT .set NSAMPLES/(4*S34_NBFLYS) - 1
; Outer loop count = N/(2(inputs per bfly)*2(words/input)*NBFLYS) - 1
S34_POST_INCREMENT .set 2*3*S34_NBFLYS ; Post-increment for all the data pointers
VSETSHR #15 ; SHR=15, does Q30 to Q15 conversion for VCFFTx Multiplications
VRNDON ; RND=1, turns on rounding during conversion from Q30 to Q15
;VSATON ; Turn ON Saturation
;; XAR2 XAR6
;; ---+-+----o--*---+----o-----*-----++-o-----------*--------o-----------------------*--+----------+-->>
;; G1| 2 \/ | \ / || \ / \ / . |
;; | | /\ | \ / || \ / \ / .XAR6++ |
;; ---+-v----o--*---|----o--X--*-----||-o--\-----/--*--------o--------------------/--*--+----------|-->>
;; 4 \/ \/ || \ \ / / \ \ / / | |
;; | /\ /\ 8| \ \ / / \ \ / / | |
;; ---+------o--*---v----o--X--*-----||-o--\--X--/--*--------o--\--------------/--/--*--6----------|-->>
;; G2| \/ / \ A| \ \/ \/ / \ \ \ / / / | |
;; | /\ / \ R| \ /\ /\ / \ \ \ / / / A |
;; ---+------o--*--------o-----*-----1|-o--X--X--X--*--------o--\--\--------/--/--/--*--R----------|-->>
;; || \/ \/ \/ \/ \ \ \ \ / / / / 0 |
;; XAR2[AR1]|| /\ /\ /\ /\ \ \ \ \ / / / / |XAR6[AR0] |
;; ---+------o--*--------o-----*-----v|-o--X--X--X--*--------o--\--\--\--X--/--/--/--*--v----------|-->>
;; G3| \/ \ / | / \/ \/ \ \ \ \ \/ \/ / / / |
;; | /\ \ / 16 / /\ /\ \ \ \ \ /\ /\ / / / 16
;; ---+------o--*--------o--X--*------|-o--/--X--\--*--------o--\--\--X--X--X--/--/--*-------------|-->>
;; \/ \/ | / / \ \ \ \ \/ \/ \/ \/ / / |
;; /\ /\ | / / \ \ \ \ /\ /\ /\ /\ / / |
;; ---+------o--*--------o--X--*------|-o--/-----\--*--------o--\--X--X--X--X--X--/--*-------------|-->>
;; G4| \/ / \ | / \ \ \/ \/ \/ \/ \/ \/ / |
;; | /\ / \ | / \ \ /\ /\ /\ /\ /\ /\ / |
;; ---+------o--*--------o-----*------|-o-----------*--------o--X--X--X--X--X--X--X--*-------------|-->>
;; | \/ \/ \/ \/ \/ \/ \/ \/ |
;; XAR4 | /\ /\ /\ /\ /\ /\ /\ /\ XAR7 |
;; ---+-+----o--*---+----o-----*-----+v-o-----------*--------o--X--X--X--X--X--X--X--*--+----------v-->>
;; G5| 2 \/ | \ / | \ / / \/ \/ \/ \/ \/ \/ \ .
;; | | /\ | \ / | \ / / /\ /\ /\ /\ /\ /\ \ .XAR7++
;; ---+-v----o--*---|----o--X--*-----|--o--\-----/--*--------o--/--X--X--X--X--X--\--*--+------------->>
;; 4 \/ \/ | \ \ / / / / \/ \/ \/ \/ \ \ |
;; | /\ /\ 8 \ \ / / / / /\ /\ /\ /\ \ \ 6
;; ---+------o--*---v----o--X--*-----|--o--\--X--/--*--------o--/--/--X--X--X--\--\--*--|------------->>
;; G6| \/ / \ A \ \/ \/ / / / / \/ \/ \ \ \ A
;; | /\ / \ R \ /\ /\ / / / / /\ /\ \ \ \ R
;; ---+------o--*--------o-----*-----1--o--X--X--X--*--------o--/--/--/--X--\--\--\--*--0------------->>
;; | \/ \/ \/ \/ / / / / \ \ \ \ |
;; XAR4[AR1]| /\ /\ /\ /\ / / / / \ \ \ \ |XAR7[AR0]
;; ---+------o--*--------o-----*-----v--o--X--X--X--*--------o--/--/--/-----\--\--\--*--v------------->>
;; G7| \/ \ / / \/ \/ \ / / / \ \ \
;; | /\ \ / / /\ /\ \ / / / \ \ \
;; ---+------o--*--------o--X--*--------o--/--X--\--*--------o--/--/-----------\--\--*---------------->>
;; \/ \/ / / \ \ / / \ \
;; /\ /\ / / \ \ / / \ \
;; ---+------o--*--------o--X--*--------o--/-----\--*--------o--/-----------------\--*---------------->>
;; G8| \/ / \ / \ / \
;; | /\ / \ / \ / \
;; ---+------o--*--------o-----*--------o-----------*--------o-----------------------*---------------->>
;; S1 S2 S3 S4
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the input data array at
;; the begining of every s & s+1 stage calculation.
;; Note that previous stage's output array is input for this stage
;MOVL XAR4, *-SP[STK_ARG_PTR] ; Restore the pointer argument to XAR4
; XAR4 is not used in stage 1 & 2
MOVL XAR2, *+XAR4[S34_INPUT_OFFSET] ; XAR2 -> I0:R0 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;; For stage s & s+1
;; These are the separation index for inputs and outputs
;; input_separation = 2* 2^(s-1)
;; For Stage 3 & 4, input_separation = 2 * 2^(3-1) = 8
;; For Stage 5 & 6, input_separation = 2 * 2^(5-1) = 32
;; For Stage 7 & 8, input_separation = 2 * 2^(7-1) = 128
;; And so on ....
MOVL XAR1, #S34_INSEP
;; ar0 is added with an XARn pointer which is post incremented (+2)
;; and hence ar0 = xar1-2
MOVL XAR0, #S34_OUTSEP
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;This pointer points to the begining of the 1st output of the combined
;; s & s+1 stage butterfly. Note that the input buffer of the previous
;; stage is used as output buffer for this stage due to ping-pong scheme
MOVL XAR6, *+XAR4[S34_OUTPUT_OFFSET] ; XAR6 -> first output
; I0'':R0'' pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;This pointer points to the 3rd output of the combined s & s+1 stage butterfly.
;;This pointer should be initialized as below
;;For Stage 3 & 4 = 2 * 2 * 2^(3-1) = 16
;;For Stage 5 & 6 = 2 * 2 * 2^(5-1) = 64
;;For Stage 7 & 8 = 2 * 2 * 2^(7-1) = 256
;;And so on ...
MOVL XAR7, XAR6
ADDB XAR7, #S34_GROUPSEP ; I2'':R2'' pointer
;;-------------------------------------------------------------------------
;;--------------------------------------------------
;;Initialize this pointer to the begining of the twiddle-factor
;;table for stage s & s+1
;;For Stage 3 & 4: 0 to [0 + 4 * 2^(3-1) - 1] = 0 to 15
;;For Stage 5 & 6: 16 to [16 + 4 * 2^(5-1) - 1] = 16 to 79
;;For Stage 7 & 8: 80 to [80 + 4 * 2^(7-1) - 1] = 80 to 335
;;And so on ....
MOVL XAR3, #_vcu2_twiddleFactors
;;ADDB XAR3, #S34_TFOFFSET
MOVL *-SP[STK_TFPTR], XAR3
;;--------------------------------------------------
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the 2nd set of butterflies used in
;; the 1st of the combined stages
;; Second Butterfly offset for stage s & s+1
;; = 2 * input_separation = 2 * 2 * 2^(s-1)
;; For Stage 3 & 4 = 2 * 2 * 2^(3-1) = 16
;; For Stage 5 & 6 = 2 * 2 * 2^(5-1) = 64
;; For Stage 7 & 8 = 2 * 2 * 2^(7-1) = 256
;; And so on ...
;;
MOVL XAR4, XAR2
ADDB XAR4, #S34_GROUPSEP ; I2:R2 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;Outer loop
;; For Stage s & s+1, combined
;; no_of_inner_but = 2^(s-1) = 2^(3-1) = 4
;; no_of_outer_loop = size/(2*no_of_inner_but*2)-1 = 64/(2*4*2) = 4-1 = 3
MOVL XAR5, #S34_OUTER_LOOP_COUNT ; Initialize outer loop counter
; used in BANZ
;;-------------------------------------------------------------------------
_CFFT_run64Pt_stages3and4OuterLoop:
MOVL XAR3, *-SP[STK_TFPTR] ; Reset the twiddle factor table pointer
;.lp_amode ; override assembler mode to C28x + C2xLP sysntax
;SETC AMODE ; set AMODE to C2xLP addressing
; Inner Butterfly Loop
VMOV32 VR5, *+XAR4[AR1] ; VR5 = I3:R3
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VMOV32 VR7, *XAR4++ ; VR7 = I2:R2
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VCFFT1 VR2, VR5, VR4 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1): R3*Cos(1) + I3*Sin(1)]
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #1 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1): R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H : R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H : R2 - VR2L]
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _CFFT_run64Pt_stages3and4InnerLoop, #S34_INNER_LOOP_COUNT
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #1 ; VR5 = I3:R3
|| VMOV32 VR5, *+XAR4[AR1] ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2): R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H : R0 + VR2L]
;[VR3H:VR3L] = [I1':R1'] = [I0 - VR2H : R0 - VR2L]
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VCFFT4 VR4, VR2, VR1, VR0, #1 ; VR7 = I2:R2
|| VMOV32 VR7, *XAR4++ ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2): I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0'':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2'] = [I0' - VR2H: R0' - VR2L]
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VMOV32 *XAR6++, VR0 ; [I0'':R0''] = VR0
VCFFT5 VR5, VR4, VR3, VR2, VR1, VR0, #1 ;[I2'':R2''] = VR1
|| VMOV32 *XAR7++, VR1 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1):R3*Cos(1) + I3*Sin(1)]
;[VR0H:VR0L] = [I1':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I1' + VR2H: R1' - VR2L]
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VMOV32 *+XAR6[AR0], VR0 ;[I1'':R1''] = VR0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #1 ;[I3'':R3''] = VR1
|| VMOV32 *+XAR7[AR0], VR1 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1):R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H: R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H: R2 - VR2L]
_CFFT_run64Pt_stages3and4InnerLoop:
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #1 ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2):R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H: R0 + VR2L]
;[VR1H:VR1L] = [I1':R1'] = [I0 - VR2H: R0 - VR2L]
NOP
VCFFT4 VR4, VR2, VR1, VR0, #1 ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2):I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2''] = [I0' - VR2H: R0' - VR2L]
NOP
VMOV32 *XAR6++, VR0 ;[I0'':R0''] = VR0
VCFFT6 VR3, VR2, VR1, VR0, #1 ;[I2'':R2''] = VR1
|| VMOV32 *XAR7++, VR1 ;[VR0H:VR0L] = [I1'':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3'':R3''] = [I1' + VR2H: R1' - VR2L]
NOP
VMOV32 *+XAR6[AR0], VR0 ;[I1'':R1''] = VR0
VMOV32 *+XAR7[AR0], VR1 ;[I3'':R3''] = VR1
;;--------------------------------------------------
;;Increment all these pointers with 2 * 3*2^(s-1)
;;for Stage 3 & 4, increment by 2 * 3 * 2^(3-1) = 24
;;for Stage 5 & 6, increment by 2 * 3 * 2^(5-1) = 96
;;for Stage 7 & 8, increment by 2 * 3 * 2^(7-1) = 384
ADDB XAR2, #S34_POST_INCREMENT
ADDB XAR4, #S34_POST_INCREMENT
ADDB XAR6, #S34_POST_INCREMENT
ADDB XAR7, #S34_POST_INCREMENT
;;--------------------------------------------------
BANZ _CFFT_run64Pt_stages3and4OuterLoop, AR5--
_CFFT_run64Pt_stages3and4CombinedEnd:
;.c28_amode ; change the assembler mode back to C28x
;CLRC AMODE ; set AMODE back to C28x addressing
; C28_AMODE allows *XARn[#3bit] addressing
; Stage 1 & 2 require AMODE others dont
;;=============================================================================
;;
;; Stages 5 and 6 Combined
;;
;; Notes:
;; - These stages will use twiddle factors from the table, which are organized
;; as follows. Twiddles for stages 5 and 6 are interleaved
;; exp(2*pi*k1/N5) , k1 = {0,1,...N5/2-1}, N5 = 2^5
;; exp(2*pi*k2/N6) , k2 = {0,1,...N5/2-1}, N6 = 2^6
;; - Stages 5 and 6 are affected by the SHR or SHL modifiers, results from all
;; operations are shifted right by SHR or left by SHL values
;; - XAR2, the pointer to the inputs, now points back to the input table
;;
;; Register Usage:
;; XAR0: butterfly lower ouput storage offset
;; XAR1: butterfly lower input storage offset
;; XAR2: pointer to even inputs(output of previous stage)
;; XAR3: pointer to twiddle factors
;; XAR4: pointer to odd inputs(output of previous stage)
;; XAR5: loop variable
;; XAR6: pointer to even outputs
;; XAR7: pointer to odd outputs
;;
;; Stage n Stage n+1
;; --XAR2-------------o----*---------o--------*------XAR6--->
;; \ / \ /
;; \/ \ /
;; /\ \ /
;; / \ \/
;; --XAR2[AR1]---XAR3-o----*---------o---/\---*--XAR6[AR0]--->
;; \ / \ /
;; \ \
;; / \ / \
;; --XAR4-------------o----*---XAR3--o---\/---*------XAR7--->
;; \ / /\
;; \/ / \
;; /\ / \
;; / \ / \
;; --XAR4[AR1]---XAR3-o----*---XAR3--o--------*--XAR7[AR0]--->
;;
_CFFT_run64Pt_stages5and6Combined:
;; local defines
S56_INPUT_OFFSET .set ARG_INBUFFER
S56_OUTPUT_OFFSET .set ARG_OUTBUFFER
S56_NBFLYS .set 1<<(STAGE5-1) ; Number of butterflys per group (2^(s-1))
S56_NGROUPS .set NSAMPLES/(2*S56_NBFLYS)
; Number of groups for this stage
S56_INSEP .set 2*(S56_NBFLYS) ; Input Seperation = (NBFLYs) * 2(size of complex inputs)
S56_OUTSEP .set S56_INSEP-2 ; Output Seperation
S56_GROUPSEP .set 4*S56_NBFLYS ; Seperation between the groups = NBFLYs * 2(inputs per butterfly) * 2(size of complex inputs)
S78_TFOFFSET .set S56_TFOFFSET+4*S56_NBFLYS
; Twiddle factor table offset for stages 7 and 8
S56_INNER_LOOP_COUNT .set S56_NBFLYS-2 ; Repeat over the number of butterflies-2(last bfly done outside the loop, RPTB loops n+1 times)
S56_OUTER_LOOP_COUNT .set NSAMPLES/(4*S56_NBFLYS) - 1
; Outer loop count = N/(2(inputs per bfly)*2(words/input)*NBFLYS) - 1
S56_POST_INCREMENT .set 2*3*S56_NBFLYS ; Post-increment for all the data pointers
; Set once in stage 3 & 4, dont set again
;VSETSHR #15 ; SHR=15, does Q30 to Q15 conversion for VCFFTx Multiplications
;VRNDON ; RND=1, turns on rounding during conversion from Q30 to Q15
;VSATON ; Turn ON Saturation
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the input data array at
;; the begining of every s & s+1 stage calculation.
;; Note that previous stage's output array is input for this stage
MOVL XAR4, *-SP[STK_ARG_PTR] ; Restore the pointer argument to XAR4
MOVL XAR2, *+XAR4[S56_INPUT_OFFSET] ; XAR2 -> I0:R0 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;; For stage s & s+1
;; These are the separation index for inputs and outputs
;; input_separation = 2* 2^(s-1)
;; For Stage 3 & 4, input_separation = 2 * 2^(3-1) = 8
;; For Stage 5 & 6, input_separation = 2 * 2^(5-1) = 32
;; For Stage 7 & 8, input_separation = 2 * 2^(7-1) = 128
;; And so on ....
MOVL XAR1, #S56_INSEP
;; ar0 is added with an XARn pointer which is post incremented (+2)
;; and hence ar0 = xar1-2
MOVL XAR0, #S56_OUTSEP
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;This pointer points to the begining of the 1st output of the combined
;; s & s+1 stage butterfly. Note that the input buffer of the previous
;; stage is used as output buffer for this stage due to ping-pong scheme
MOVL XAR6, *+XAR4[S56_OUTPUT_OFFSET] ; XAR6 -> first output
; I0'':R0'' pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;This pointer points to the 3rd output of the combined s & s+1 stage butterfly.
;;This pointer should be initialized as below
;;For Stage 3 & 4 = 2 * 2 * 2^(3-1) = 16
;;For Stage 5 & 6 = 2 * 2 * 2^(5-1) = 64
;;For Stage 7 & 8 = 2 * 2 * 2^(7-1) = 256
;;And so on ...
MOVL XAR7, XAR6
ADDB XAR7, #S56_GROUPSEP ; I2'':R2'' pointer
;;-------------------------------------------------------------------------
;;--------------------------------------------------
;;Initialize this pointer to the begining of the twiddle-factor
;;table for stage s & s+1
;;For Stage 3 & 4: 0 to [0 + 4 * 2^(3-1) - 1] = 0 to 15
;;For Stage 5 & 6: 16 to [16 + 4 * 2^(5-1) - 1] = 16 to 79
;;For Stage 7 & 8: 80 to [80 + 4 * 2^(7-1) - 1] = 80 to 335
;;And so on ....
MOVL XAR3, #_vcu2_twiddleFactors
ADDB XAR3, #S56_TFOFFSET
MOVL *-SP[STK_TFPTR], XAR3
;;--------------------------------------------------
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the 2nd set of butterflies used in
;; the 1st of the combined stages
;; Second Butterfly offset for stage s & s+1
;; = 2 * input_separation = 2 * 2 * 2^(s-1)
;; For Stage 3 & 4 = 2 * 2 * 2^(3-1) = 16
;; For Stage 5 & 6 = 2 * 2 * 2^(5-1) = 64
;; For Stage 7 & 8 = 2 * 2 * 2^(7-1) = 256
;; And so on ...
;;
MOVL XAR4, XAR2
ADDB XAR4, #S56_GROUPSEP ; I2:R2 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;Outer loop
;; For Stage s & s+1, combined
;; no_of_inner_but = 2^(s-1) = 2^(3-1) = 4
;; no_of_outer_loop = size/(2*no_of_inner_but*2)-1 = 64/(2*16*2) = 1-1 = 0
; MOVL XAR5, #S56_OUTER_LOOP_COUNT ; Initialize outer loop counter
; used in BANZ
; not required here
;;-------------------------------------------------------------------------
_CFFT_run64Pt_stages5and6OuterLoop:
MOVL XAR3, *-SP[STK_TFPTR] ; Reset the twiddle factor table pointer
;.lp_amode ; override assembler mode to C28x + C2xLP sysntax
;SETC AMODE ; set AMODE to C2xLP addressing
; Inner Butterfly Loop
VMOV32 VR5, *+XAR4[AR1] ; VR5 = I3:R3
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VMOV32 VR7, *XAR4++ ; VR7 = I2:R2
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VCFFT1 VR2, VR5, VR4 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1): R3*Cos(1) + I3*Sin(1)]
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #1 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1): R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H : R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H : R2 - VR2L]
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _CFFT_run64Pt_stages5and6InnerLoop, #S56_INNER_LOOP_COUNT
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #1 ; VR5 = I3:R3
|| VMOV32 VR5, *+XAR4[AR1] ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2): R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H : R0 + VR2L]
;[VR3H:VR3L] = [I1':R1'] = [I0 - VR2H : R0 - VR2L]
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VCFFT4 VR4, VR2, VR1, VR0, #1 ; VR7 = I2:R2
|| VMOV32 VR7, *XAR4++ ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2): I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0'':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2'] = [I0' - VR2H: R0' - VR2L]
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VMOV32 *XAR6++, VR0 ; [I0'':R0''] = VR0
VCFFT5 VR5, VR4, VR3, VR2, VR1, VR0, #1 ;[I2'':R2''] = VR1
|| VMOV32 *XAR7++, VR1 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1):R3*Cos(1) + I3*Sin(1)]
;[VR0H:VR0L] = [I1':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I1' + VR2H: R1' - VR2L]
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VMOV32 *+XAR6[AR0], VR0 ;[I1'':R1''] = VR0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #1 ;[I3'':R3''] = VR1
|| VMOV32 *+XAR7[AR0], VR1 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1):R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H: R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H: R2 - VR2L]
_CFFT_run64Pt_stages5and6InnerLoop:
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #1 ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2):R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H: R0 + VR2L]
;[VR1H:VR1L] = [I1':R1'] = [I0 - VR2H: R0 - VR2L]
NOP
VCFFT4 VR4, VR2, VR1, VR0, #1 ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2):I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2''] = [I0' - VR2H: R0' - VR2L]
NOP
VMOV32 *XAR6++, VR0 ;[I0'':R0''] = VR0
VCFFT6 VR3, VR2, VR1, VR0, #1 ;[I2'':R2''] = VR1
|| VMOV32 *XAR7++, VR1 ;[VR0H:VR0L] = [I1'':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3'':R3''] = [I1' + VR2H: R1' - VR2L]
NOP
VMOV32 *+XAR6[AR0], VR0 ;[I1'':R1''] = VR0
VMOV32 *+XAR7[AR0], VR1 ;[I3'':R3''] = VR1
;;--------------------------------------------------
;;Increment all these pointers with 2 * 3*2^(s-1)
;;for Stage 3 & 4, increment by 2 * 3 * 2^(3-1) = 24
;;for Stage 5 & 6, increment by 2 * 3 * 2^(5-1) = 96
;;for Stage 7 & 8, increment by 2 * 3 * 2^(7-1) = 384
;ADDB XAR2, #S56_POST_INCREMENT
;ADDB XAR4, #S56_POST_INCREMENT
;ADDB XAR6, #S56_POST_INCREMENT
;ADDB XAR7, #S56_POST_INCREMENT
;not required for the last of the combined stages
;;--------------------------------------------------
;BANZ _CFFT_run64Pt_stages5and6OuterLoop, AR5--
;not required for the last of the combined stages
_CFFT_run64Pt_stages5and6CombinedEnd:
;.c28_amode ; change the assembler mode back to C28x
;CLRC AMODE ; set AMODE back to C28x addressing
; C28_AMODE allows *XARn[#3bit] addressing
;;=============================================================================
CFFT_CONTEXT_RESTORE
LRETR
;;*****************************************************************************
;;
;; \brief Initialize the 64pt Complex FFT
;;
;; \param Handle to the structure, CFFT_Obj(passed in XAR4)
;; - *+XAR4[0]: int16_t *pInBuffer -> input pointer
;; - *+XAR4[2]: int16_t *pOutBuffer -> work(Output) buffer pointer
;; - *+XAR4[4]: int16_t *pTwiddleFactors-> twiddle factor table pointer
;; - *+XAR4[6]: int16_t nSamples-> Number of data points
;; - *+XAR4[7]: int16_t nStages-> Number of FFT stages
;; - *+XAR4[8]: int16_t twiddleSkipStep-> Twiddle factor table search step
;;
_CFFT_init64Pt:
;;
;; Register Usage:
;; XAR0: index into the structure
;; XAR1: Number of samples
;; XAR2: Number of stages
;; XAR3: Pointer to twiddle factor table
;; XAR4: Pointer to the CFFT structure
;; XAR5:
;; XAR6:
;; XAR7: Twiddle skip factor
;;
CFFT_CONTEXT_SAVE
MOV AR0, #ARG_TFTABLE
MOVL XAR3, #_vcu2_twiddleFactors
MOVL *+XAR4[AR0], XAR3
MOV AR0, #ARG_NSAMPLES
MOVL XAR1, #NSAMPLES
MOV *+XAR4[AR0], AR1
MOV AR0, #ARG_NSTAGES
MOVL XAR2, #NSTAGES
MOV *+XAR4[AR0], AR2
MOV AR0, #ARG_TFSKIP
MOVL XAR7, #NSKIP
MOV *+XAR4[AR0], AR7
CFFT_CONTEXT_RESTORE
LRETR
;; End of file
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,456 @@
;;*****************************************************************************
;;! \file source/vcu2/vcu2_cfft_utils.asm
;;!
;;! \brief FFT Utility Routines
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;*****************************************************************************
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;;*****************************************************************************
;; global defines
;;*****************************************************************************
;; FFT Routine defines
;; Argument structure defines
ARG_INBUFFER .set 0
ARG_OUTBUFFER .set 2
ARG_TFTABLE .set 4
ARG_NSAMPLES .set 6
ARG_NSTAGES .set 7
ARG_TFSKIP .set 8
;; Stack defines
;;
;; |_______|
;; |_______|<- Stack Pointer(SP) <---SP
;; |_______|<- STK_VR3L (SP-1)
;; |_______|<- STK_VR4L (SP-2)
;;
LOCAL_FRAME_SIZE .set 2
STK_VR3L .set 1
STK_VR4L .set 2
;;*****************************************************************************
;; macros
;;*****************************************************************************
;;
;; MACRO : 'CFFT_CONTEXT_SAVE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on entry into FFT routine
;;
CFFT_CONTEXT_SAVE .macro
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #LOCAL_FRAME_SIZE ; allocate stack space for local frame
.endm
;;
;; MACRO : 'CFFT_CONTEXT_RESTORE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on exit from FFT routine
;;
CFFT_CONTEXT_RESTORE .macro
SUBB SP, #LOCAL_FRAME_SIZE ; deallocate stack space for local frame
POP XAR3
POP XAR2
POP XAR1
.endm
;;*****************************************************************************
;; globals
;;*****************************************************************************
.global _CFFT_unpack
.global _CFFT_pack
.global _CFFT_conjugate
.ref _vcu0_twiddleFactors
;;*****************************************************************************
;; function definitions
;;*****************************************************************************
.text
;;
;; \brief Unpack the complex FFT output to get the FFT of two interleaved
;; real sequences
;;
;; In order to get the FFT of a real N-pt sequences, we treat the input as
;; an N/2 pt complex sequence, take its complex FFT, use the following properties
;; to get the N-pt fourier transform of the real sequence
;; \f[
;; FFT_{n}(k,f) = FFT_{N/2}(k,f_{e}) + e^{\frac{-j2{\pi}k}{N}}FFT_{N/2}(k,f_{o})
;; \f]
;; where \f$f_{e}\f$ is the even elements, \f$f_{o}\f$ the odd elements and
;; \f[
;; F_{e}(k) = \frac{Z(k) + Z(\frac{N}{2}-k)^{\ast}}{2}
;; F_{o}(k) = -j\frac{Z(k) - Z(\frac{N}{2}-k)^{\ast}}{2}
;; \f]
;; We get the first N/2 points of the FFT by combining the above two equations
;; \f[
;; F(k) = F_{e}(k) + e^{\frac{-j2{\pi}k}{N}}F_{o}(k)
;; \f]
;;
;; \param Handle to the structure, CFFT_Obj(passed in XAR4)
;; - *+XAR4[0]: int16_t *pInBuffer -> input pointer
;; - *+XAR4[2]: int16_t *pOutBuffer -> work(Output) buffer pointer
;; - *+XAR4[4]: int16_t *pTwiddleFactors-> twiddle factor table pointer
;; - *+XAR4[6]: int16_t nSamples-> Number of data points
;; - *+XAR4[7]: int16_t nStages-> Number of FFT stages
;; - *+XAR4[8]: int16_t twiddleSkipStep-> Twiddle factor table search step
;;
;; \note
;; - This function actively sets CPACK=1 style complex packing
;; i.e. [Lo:Hi] => [Real:Imag], the input data must also be arranged in this format
;; - Sign extension is automatically done for right shift operations
;; - VSTATUS.RND=1, rounding is done for the right shift operation
;; - OVFR is set if signed overflow is detected for add/sub calculation in which destination is VRxL
;; - OVFI is set if signed overflow is detected for add/sub calculation in which destination is VRxH
;; - 16-bit signed results (before the shift right) are saturated if SAT = 1
;;
;; \return FFT of the input in the output buffer pointed to by CFFT_Obj.pOutBuffer
;; \sa http://www.engineeringproductivitytools.com/stuff/T0001/PT10.HTM for the entire
;; derivation
;;
;; Register Usage:
;; XAR0: Twiddle Factor table index (increments in steps of "skip_step")
;; / Index into the structure
;; XAR1: Repeat block index
;; XAR2: Points to the beginning of the CFFT buffer
;; XAR3: Points to the end of the CFFT buffer
;; XAR4: Pointer to the CFFT structure
;; XAR5:
;; XAR6: Points to the twiddle factor table
;; XAR7:
;;
_CFFT_unpack:
;; NOTE: N is the number of complex samples
CFFT_CONTEXT_SAVE
SETC SXM ; Set sign extension mode
ZAPA
VSETCPACK ; VSTATUS.CPACK = 1
VSATON ; Turn on saturation
VRNDON ; Turn on rounding
VSETSHR #17 ; VSTATUS.SHIFTR = RIGHT_SHIFT (divide by 4)
VSETSHL #15 ; VSTATUS.SHIFTL = LEFT_SHIFT
MOVL XAR2, *+XAR4[ARG_OUTBUFFER] ; XAR2 -> Complex FFT output buffer
MOVL XAR6, #_vcu0_twiddleFactors+160 ; XAR6 -> Twiddle factor table(VCU-0) for stage 9
MOVL ACC, *+XAR4[ARG_NSAMPLES] ; ACC := N (number of complex samples)
MOV PL, AL ; PL := N
LSR AL, #1 ; AL := N/2 (the mid point)
SUB AL, #2 ; AL := (N/2 - 1) - 1(for RPTB)
MOVZ AR1, AL ; AR1 := (N/2 - 2)
MOV ACC, PL << 1 ; ACC := 2N
ADDL ACC, XAR2 ; ACC := 2N + ptr->output buffer (in words)
MOVL XAR3, ACC ; XAR3 -> end of output buffer
;; Process the first point X(0)
MOVL ACC, *XAR2 ; ACC := X(0)
ADD AL, AH ; AL := Xr(0) + Xi(0)
ADD AL, #1 ; AL := Xr(0) + Xi(0) + 1
ASR AL, #1 ; AL := (Xr(0) + Xi(0) + 1)/2
MOV AH, #0
MOVL *XAR2++, ACC ; X(0) := (Xr(0) + Xi(0) + 1)/2
;; Setup twiddle factor index
MOV AR0, #ARG_TFSKIP
MOV AH, *+XAR4[AR0] ; AH := Twiddle Skip Factor
LSR AH, 1 ; We want to go through all the W_N(n,k) twiddles and not the W_N/2(n,k) twiddles
MOV AR0, AH ; AR0 := AH, we want to start with the twiddle W(n,1)
;; Process points X(1)..X(N/2-1)
;;
;; W(k) = e^(-j*2*pi*k/N)
;; = cos(2*pi*k/N) - j sin(2*pi*k/N)
;; -jW(k) = e^-j*pi/2 x e^(-j*2*pi*k/N)
;; W'(k) = -sin(2*pi*k/N) + j(-cos(2*pi*k/N))
;; Take the original twiddle, flip Re and Im parts
;; and conjugate
;; W'(k) = (flip(W(k))*
;;
;; F_e(k) = 1/2{Z(k) + Z(N/2-k)*}
;; = 1/2{(VR2L+VR1L) + j(VR2H-VR1H)}
;; F_o(k) = -j{Z(k) - Z(N/2-k)*}/2
;; = -j{(VR2L-VR1L)+j(VR2H+VR1H)}/2
;; F_o(k) = -jF'_o(k)
;; F(k) = F_e(k) + W(k)F_o(k)
;; = F_e(k) - jW(k)F'_o(k)
;; = F_e(k) + W'(k)F'_o(k), for k = 0:N/2-1
;; F(k) = (F_e(k) - jW(k)F'_o(k))*
;; = F_e(k) + jW(k)F'_o(k)
;; = F_e(k) - W'(k)F'_o(k), for k = N/2+1:N-1
.align 2
RPTB _CFFT_unpack_loop, AR1
VMOV32 VR0, *+XAR6[AR0] ; VR0 := Twiddle Factor
ADD AR0, AH ; AR0 += AH (incrementing TF offset by the skip step)
VCFLIP VR0 ; VR0L + jVR0H -> VR0H + jVR0L
;VCCON VR0 ; W'(k) = VR0H - jVR0L / done with the VCCMPY later
VMOV32 VR2, *XAR2 ; Load the upper point
VMOV32 VR1, *--XAR3 ; Load the N/2 - k point
VITDLADDSUB VR4, VR3, VR2, VR1 ; [VR3L:VR3H] := [VR2L+VR1L:VR2H-VR1L]
; [VR4L:VR4H] := [VR2L-VR1L:VR2H+VR1L]
VMOV16 *-SP[STK_VR3L], VR3L ; Save VR3L, discard VR3H
VMOV16 *-SP[STK_VR4L], VR4L ; Save VR4L, discard VR4H
VITDHADDSUB VR4, VR3, VR2, VR1 ; [VR3L:VR3H] := [VR2L+VR1H:VR2H-VR1H]
; [VR4L:VR4H] := [VR2L-VR1H:VR2H+VR1H]
VMOV16 VR3L, *-SP[STK_VR3L] ; Discard VR3L, load with previous VR3L
VMOV16 VR4L, *-SP[STK_VR4L] ; Discard VR4L, load with previous VR4L
VMOV32 VR1, VR4 ; VR1 := VR4
VMOV32 VR4, VR3 ; VR4 := F_e(k)
VCCMPY VR3, VR2, VR1, VR0 ; VR3+jVR2 = (VR0L*VR1L + VR0H*VR1H)
VNOP ; + j(VR0L*VR1H - VR0H*VR1L)
VCDADD16 VR5, VR4, VR3, VR2 ; [VR5L:VR5H] = [(VR4L<<SHL+VR3)>>SHR:(VR4H<<SHL+VR2)>>SHR]
VCDSUB16 VR6, VR4, VR3, VR2 ; [VR6L:VR6H] = [(VR4L<<SHL-VR3)>>SHR:(VR4H<<SHL-VR2)>>SHR]
VCCON VR6
VMOV32 *XAR2++, VR5 ; Store (F_e(k) + W'(k)F'_o(k))
VMOV32 *XAR3, VR6 ; Store (F_e(k) - W'(k)F'_o(k)) at the back end of buffer
_CFFT_unpack_loop:
;; Process point F(N/4)
;; F(N/4) = 1/2({Z(N/4) +Z(N/2-N/4)*} -je^(-j*2*pi*N/4N){Z(N/4) -Z(N/2-N/4)*})
;; = 1/2({Z(N/4) +Z(N/4)*} -je^(-jpi/2){Z(N/4) -Z(N/4)*})
;; = 1/2({2 Re(Z(N/4)) } -j(-j){2 j Im(Z(N/4)) })
;; = Re(Z(N/4)) - j Im(Z(N/4))
;; = F(N/4)*
MOVL ACC, *--XAR3 ; Load the point F(N/4)
NEG AH
ASR AL, #1
ASR AH, #1
MOVL *XAR3, ACC
VCLRCPACK ; VSTATUS.CPACK = 0
CFFT_CONTEXT_RESTORE
LRETR
;;*****************************************************************************
;;
;; \brief Take the complex conjugate of the entries in an array of complex
;; numbers
;;
;; \param pBuffer Pointer to the buffer of complex data to be conjugated
;; \paran[in] size Size of the buffer (multiple of 2 32-bits locations)
;;
;; Register Usage:
;; XAR0:
;; XAR1: counter of the repeat block
;; XAR2:
;; XAR3:
;; XAR4: Pointer to the complex buffer
;; XAR5:
;; XAR6:
;; XAR7:
;; AH:
;; AL: Size of buffer(argument to the function)
_CFFT_conjugate:
PUSH XAR1
MOV AH, AL ; AH := size of buffer
ANDB AL, #0x0001 ; AL := remainder
TBIT AL, #0 ; Is the 0th bit 1? Set TC : Clear TC
ASR AH, #1 ; AH := size of buffer / 2
MOVZ AR1, AH
SUBB XAR1, #1 ; counter for RPTB
.align 2
RPTB _CFFT_conjugate_loop, AR1
VMOV32 VR0, *+XAR4[0]
VCCON VR0
VMOV32 *XAR4++, VR0
NOP
VMOV32 VR0, *+XAR4[0]
VCCON VR0
VMOV32 *XAR4++, VR0
NOP
_CFFT_conjugate_loop:
SB _CFFT_conjugate_end, NTC ;If TC Clear then jump to end
VMOV32 VR0, *+XAR4[0] ; else do one last complex conjugate
VCCON VR0
VMOV32 *XAR4++, VR0
_CFFT_conjugate_end:
POP XAR1
LRETR
;;*****************************************************************************
;; \brief Pack the input prior to running the inverse complex FFT to get
;; the real inverse FFT
;;
;; In order to reverse the process of the forward real FFT,
;;
;; \f[
;; F_{e}(k) = \frac{F(k) + F(\frac{N}{2}-k)^{\ast}}{2}
;; F_{o}(k) = \frac{F(k) - F(\frac{N}{2}-k)^{\ast}}{2} e^{\frac{j2{\pi}k}{N}}
;; \f]
;; where \f$f_{e}\f$ is the even elements, \f$f_{o}\f$ the odd elements.
;; The array for the IFFT then becomes:
;; \f[
;; Z(k) = F_{e}(k) + jF_{o}(k), \ k = 0...\frac{N}{2}-1
;; \f]
;;
;; \param Handle to the structure, CFFT_Obj(passed in XAR4)
;; - *+XAR4[0]: int16_t *pInBuffer -> input pointer
;; - *+XAR4[2]: int16_t *pOutBuffer -> work(Output) buffer pointer
;; - *+XAR4[4]: int16_t *pTwiddleFactors-> twiddle factor table pointer
;; - *+XAR4[6]: int16_t nSamples-> Number of data points
;; - *+XAR4[7]: int16_t nStages-> Number of FFT stages
;; - *+XAR4[8]: int16_t twiddleSkipStep-> Twiddle factor table search step
;;
;; \note
;; - This function actively sets CPACK=1 style complex packing
;; i.e. [Lo:Hi] => [Real:Imag], the input data must also be arranged in this format
;; - Sign extension is automatically done for right shift operations
;; - VSTATUS.RND=1, rounding is done for the right shift operation
;; - OVFR is set if signed overflow is detected for add/sub calculation in which destination is VRxL
;; - OVFI is set if signed overflow is detected for add/sub calculation in which destination is VRxH
;; - 16-bit signed results (before the shift right) are saturated if SAT = 1
;; - This is an in-place algorithm; the routine writes the output to the input buffer itself
;;
;; \return packed input ready for the IFFT in the input buffer pointed
;; to by CFFT_Obj.pInBuffer
;; \sa http://www.engineeringproductivitytools.com/stuff/T0001/PT10.HTM for the entire
;; derivation
;;
;; Register Usage:
;; XAR0: Index into the structure
;; XAR1: RPTB counter
;; XAR2: Pointer to the input buffer
;; XAR3: Points to lower half of the input buffer
;; XAR4: Pointer to the CFFT structure
;; XAR5:
;; XAR6: Pointer to twiddle factor table
;; XAR7:
;;
_CFFT_pack:
CFFT_CONTEXT_SAVE
VSETCPACK ; set CPACK bit to 1 [Lo:Hi] = [Re:Im]
SETC SXM ; Turn on sign extension mode
ZAPA
VSATON ; VSTATUS.SAT = 1
VRNDON ; VSTATUS.RND = 1
VSETSHR #17 ; VSTATUS.SHIFTR = RIGHT_SHIFT, scale by 4
VSETSHL #15 ; VSTATUS.SHIFTL = LEFT_SHIFT
MOVL XAR2, *+XAR4[ARG_INBUFFER] ; load input buffer base pointer
MOV AL, *+XAR4[ARG_NSAMPLES] ; load number of points (#complex_points)
MOV PL, AL ; save length
LSR AL, #1
SUB AL, #2 ; loop N/2-1 times (the -2 accounts for RPTB which loops N + 1 times)
MOVZ AR1, AL
MOV ACC, PL << 1 ; load number of points
ADDL ACC, XAR2 ; calculate lower half
MOVL XAR3, ACC
MOVL XAR6, #_vcu0_twiddleFactors+160 ; XAR6 -> Twiddle factor table(VCU-0) for stage 9
; process the first point X(0)
VMOV32 VR0, *XAR2 ; VR0 := X(0)
VCCON VR0 ;[VR0L:VR0H] = [VR0L:-VR0H] ([Re:-Im])
VMOV32 *XAR2++, VR0 ; Store back to memory
; set up twiddle factor index
MOV AR0, #ARG_TFSKIP
MOV AH, *+XAR4[AR0] ; AH := Twiddle Skip Factor
LSR AH, #1 ; Reduce skip factor by a factor of 2 (skip factor calculated
; based on 1024 entries, vcu0 twiddles only have 512 entries max)
MOV AR0, AH ; AR0 := AH, we want to start with the twiddle W(n,1)
;; Process points X(1)..X(N/2-1)
;;
;; W(k) = e^(+j*2*pi*k/N)
;; jW(k) = j(cos(2*pi*k/N) + jsin(2*pi*k/N))
;; W'(k) = -sin(2*pi*k/N) + j(cos(2*pi*k/N))
;; Take the original twiddle, conjugate it then flip Re and Im parts
;; W'(k) = (flip(W*(k))
;;
;; F_e(k) = 1/2{F(k) + F(N/2-k)*}
;; = 1/2{(VR2L+VR1L) + j(VR2H-VR1H)}
;; F_o'(k)= F_o(k)W'(k)
;; = +j/2{F(k) - F(N/2-k)*}e^{j*2*pi*k/N}
;; = 1/2{F(k) - F(N/2-k)*}W'(k)
;; = 1/2{(VR2L-VR1L) + j(VR2H+VR1H)}*{VR0L + jVR0H}
;; Z(k) = F_e(k) + jF_o(k) or F_e(k) + F_o'(k)
;;
.align 2
RPTB _CFFT_pack_loop, AR1
VMOV32 VR0, *+XAR6[AR0] ; VR0 := Twiddle Factor
;VCCON VR0 ; VR0L + jVR0H -> VR0L - jVR0H
VCFLIP VR0 ; VR0L - jVR0H -> -VR0H + jVR0L
ADD AR0, AH ; AR0 += AH (incrementing TF offset by the skip step)
VMOV32 VR2, *XAR2 ; Load the upper point
VMOV32 VR1, *--XAR3 ; Load the N/2 - k point
VITDLADDSUB VR4, VR3, VR2, VR1 ;[VR3L:VR3H] := [VR2L+VR1L:VR2H-VR1L]
;[VR4L:VR4H] := [VR2L-VR1L:VR2H+VR1L]
VMOV16 *-SP[STK_VR3L], VR3L ; Save VR3L, discard VR3H
VMOV16 *-SP[STK_VR4L], VR4L ; Save VR4L, discard VR4H
VITDHADDSUB VR4, VR3, VR2, VR1 ;[VR3L:VR3H] := [VR2L+VR1H:VR2H-VR1H]
;[VR4L:VR4H] := [VR2L-VR1H:VR2H+VR1H]
VMOV16 VR3L, *-SP[STK_VR3L] ; Discard VR3L, load with previous VR3L
VMOV16 VR4L, *-SP[STK_VR4L] ; Discard VR4L, load with previous VR4L
VMOV32 VR1, VR4 ; VR1 := VR4 (F_o(k))
VMOV32 VR4, VR3 ; VR4 := F_e(k)
; Calculate F_o'(k) = F_o(k)*(jW(k))
VCMPY VR3, VR2, VR1, VR0 ; VR3+jVR2 = (VR0L*VR1L + VR0H*VR1H)
VNOP ; + j(VR0L*VR1H - VR0H*VR1L)
VCDSUB16 VR6, VR4, VR3, VR2 ;[VR6L:VR6H] = [(VR4L<<SHL-VR3)>>SHR:(VR4H<<SHL-VR2)>>SHR]
VCDADD16 VR5, VR4, VR3, VR2 ;[VR5L:VR5H] = [(VR4L<<SHL+VR3)>>SHR:(VR4H<<SHL+VR2)>>SHR]
VMOV32 *XAR3, VR6
VCCON VR5 ; VR5L + jVR5H -> VR5L - jVR5H
VMOV32 *XAR2++, VR5
_CFFT_pack_loop:
;; Process point X(N/2)
;; X(N/2) = 0.5*X(N/2)
VMOV32 VR1, *XAR2 ; the center point, X(N/2) = 0.5(X(N/2))
VCSHR16 VR1 >> #1
VMOV32 *XAR2, VR1
CFFT_CONTEXT_RESTORE
LRETR
;; End of file
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,961 @@
;;*****************************************************************************
;;! \file source/vcu2/vcu2_icfft_128.asm
;;!
;;! \brief 128-pt complex inverse FFT
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;;*****************************************************************************
;; global defines
;;*****************************************************************************
;; FFT Routine defines
NSTAGES .set 7
NSAMPLES .set (1 << NSTAGES)
NSKIP .set 2*(512 / NSAMPLES) ;vcu0 largest table is stage9 i.e. 512 twiddles(used in unpack)
;the 2 in the numerator is for the size of the twiddle in words
STAGE1 .set 1
STAGE3 .set 3
STAGE5 .set 5
STAGE7 .set 7
;; Argument structure defines
ARG_INBUFFER .set 0
ARG_OUTBUFFER .set 2
ARG_TFTABLE .set 4
ARG_NSAMPLES .set 6
ARG_NSTAGES .set 7
ARG_TFSKIP .set 8
;; Stack defines
;;
;; |_______|
;; |_______|<- Stack Pointer(SP) <---SP
;; |_______|<- STK_ARG_PTR (SP-2)
;; |_______|<- STK_TFPTR (SP-4)
;;
LOCAL_FRAME_SIZE .set 4
STK_ARG_PTR .set 2
STK_TFPTR .set 4
;;*****************************************************************************
;; macros
;;*****************************************************************************
;;
;; MACRO : 'ICFFT_CONTEXT_SAVE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on entry into FFT routine
;;
ICFFT_CONTEXT_SAVE .macro
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #LOCAL_FRAME_SIZE ; allocate stack space for local frame
.endm
;;
;; MACRO : 'ICFFT_CONTEXT_RESTORE'
;; SIZE : Number of WORDS/Number of Cycles 14
;; USAGE : Called on exit from FFT routine
;;
ICFFT_CONTEXT_RESTORE .macro
SUBB SP, #LOCAL_FRAME_SIZE ; deallocate stack space for local frame
POP XAR3
POP XAR2
POP XAR1
.endm
;;*****************************************************************************
;; globals
;;*****************************************************************************
.global _ICFFT_run128Pt
.ref _vcu0_twiddleFactors
.ref _vcu2_twiddleFactors
;;*****************************************************************************
;; function definitions
;;*****************************************************************************
.text
;;
;; \brief Calculate the 128 pt Complex Inverse FFT
;;
;; \param Handle to the structure, ICFFT_Obj(passed in XAR4)
;; - *+XAR4[0]: int16_t *pInBuffer -> input pointer
;; - *+XAR4[2]: int16_t *pOutBuffer -> work(Output) buffer pointer
;; - *+XAR4[4]: int16_t *pTwiddleFactors-> twiddle factor table pointer
;; - *+XAR4[6]: int16_t nSamples-> Number of data points
;; - *+XAR4[7]: int16_t nStages-> Number of FFT stages
;; - *+XAR4[8]: int16_t twiddleSkipStep-> Twiddle factor table search step
;;
;; \note
;; - This algorithm works on two buffers of size 2*N(32-bit complex) in ping-pong fashion
;; - N must be a power of 2 for this algorithm
;; - Must be of size N >= 16(2^4)
;; - This function actively sets CPACK=1 style complex packing
;; i.e. [Lo:Hi] => [Real:Imag], the input data must also be arranged in this format
;; - Sign extension is automatically done for right shift operations
;; - VSTATUS.RND=1, rounding is done for the right shift operation
;; - OVFR is set if signed overflow is detected for add/sub calculation in which destination is VRxL
;; - OVFI is set if signed overflow is detected for add/sub calculation in which destination is VRxH
;; - 16-bit signed results (before the shift right) are saturated if SAT = 1
;; - Make sure that input and output buffer pointer points to two diffrent
;; RAM blocks to avoid arbitration between reads and writes
;;
;; \return FFT of the input in the output buffer pointed to by ICFFT_Obj.pOutBuffer
;;
_ICFFT_run128Pt:
ICFFT_CONTEXT_SAVE
MOVL *-SP[STK_ARG_PTR], XAR4
;; Computation Prep
VSETCPACK ; Set the CPACK bit to 1
;SETC SXM ; sign extension mode
; ISS says SXM is automatically done so check that it is
VSATON ; Turn ON Saturation
;;
;; Stages 1 and 2 Combined
;;
;; Notes:
;; - These stages use trivial twiddle factors: 1,-1,j and -j.
;; - C27x AMODE is required in this stage to facilitate the use of
;; the bit-reversed addressing mode with simultaneous ARP update i.e
;; VMOV32 mem32,VRx,ARPn
;; - Setting up the bit-reversed index in AR0
;; Assume N = 64, Since we have complex data its 2N or
;; 128(2^7) words to index i.e. we need 7 bits to address all locations(0-127)
;; we represent 1 as : b'0000001' -> 0x0001
;; bit reversed 1 as : b'1000000' -> 0x0040
;; N represented in hex is already 0x0040, so we load this directly to AR0
;; - Stages 1 and 2 arent affected by the SHR or SHL modifiers, results from all
;; operations are shifted right by 1 bit
;;
;; Register Usage:
;; XAR0: offset address(bit-reversed indexing)
;; XAR1: output storage pointer
;; XAR2: input pointer
;;
;; Stage 1 Stage 2
;; --XAR1,*BR0++---o----*-----o--------*--XAR2++-->
;; \ / \ /
;; \/ \ /
;; /\ \ /
;; / \ \/
;; --XAR1,*BR0++---o----*-----o---/\---*--XAR2++--->
;; \ / \ /
;; \ \
;; / \ / \
;; --XAR1,*BR0++---o----*-----o---\/---*--XAR2++-->
;; \ / /\
;; \/ / \
;; /\ / \
;; / \ / \
;; --XAR1,*BR0++---o----*-----o--------*--XAR2++--->
;;
_ICFFT_run128Pt_stages1and2Combined:
;; local defines
S12_NBFLY .set (NSAMPLES / (2*2)) ; Number of 2x2 butterflies
S12_LOOP_COUNT .set S12_NBFLY - 2 ; Stage 1/2 loop count
MOVZ AR0, *+XAR4[ARG_NSAMPLES] ; AR0 := bit-reversed index 1
MOVL XAR2, *+XAR4[ARG_INBUFFER] ; XAR2 -> input buffer
MOVL XAR1, *+XAR4[ARG_OUTBUFFER] ; XAR1 -> output buffer
.lp_amode ; override assembler mode to C28x + C2xLP sysntax
SETC AMODE ; set AMODE to C2xLP addressing
NOP *,ARP2 ; ARP -> XAR2
VMOV32 VR0, *BR0++ ; VR0 := *(AR2 bradd AR0++) | VR0 := I0:R0
VMOV32 VR1, *BR0++ ; VR1 := *(AR2 bradd AR0++) | VR1 := I1:R1
VCFFT7 VR1, VR0, #0 ; VR2 = I2:R2 <- XAR1
|| VMOV32 VR2, *BR0++ ;[VR0H:VR0L] := [R0 - R1:R0 + R1] := [VR0L - VR1L:VR0L + VR1L]
;[VR1H:VR1L] := [I0 - I1:I0 + I1] := [VR0H - VR1H:VR0H + VR1H]
VMOV32 VR3, *BR0++ ; VR3 := I3:R3 <- XAR1
VCFFT8 VR3, VR2, #0 ;[VR2H:VR2L] := [R2 - R3:R2 + R3] := [VR2L - VR3L:VR2L + VR3L]
;[VR3H:VR3L] := [I2 - I3:I2 + I3] := [VR2H - VR3H:VR2H + VR3H]
VCFFT9 VR5, VR4, VR3, VR2, VR1, VR0, #0 ;[VR4H:VR4L] := [I0':R0'] := [(I0+I1) + (I2+I3):(R0+R1) + (R2+R3)] := [VR1L + VR3L:VR0L + VR2L]
;[VR5H:VR5L] := [I2':R2'] := [(I0+I1) - (I2+I3):(R0+R1) - (R2+R3)] := [VR1L VR3L:VR0L VR2L]
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _ICFFT_run128Pt_stages1and2CombinedLoop, #S12_LOOP_COUNT
VCFFT10 VR7, VR6, VR3, VR2, VR1, VR0, #0 ; VR0 := I0:R0 <- *(AR2 bradd AR0++)
|| VMOV32 VR0, *BR0++ ;[VR6H:VR6L] := [I1':R1'] := [(I0-I1) - (R2-R3):(R0-R1) + (I2-I3)] := [VR1H VR2H:VR0H + VR3H]
;[VR7H:VR7L] := [I3':R3'] := [(I0-I1) + (R2-R3):(R0-R1) - (I2-I3)] := [VR1H + VR2H:VR0H VR3H]
VMOV32 VR1, *BR0++ ; VR1 := I1:R1 <- *(AR2 bradd AR0++)
VCFFT7 VR1, VR0, #0 ; VR2 := I2:R2 <- *(AR2 bradd AR0++)
|| VMOV32 VR2, *BR0++ ;[VR0H:VR0L] := [R0 - R1:R0 + R1] := [VR0L - VR1L:VR0L + VR1L]
;[VR1H:VR1L] := [I0 - I1:I0 + I1] := [VR0H - VR1H:VR0H + VR1H]
VMOV32 VR3, *BR0++ ; VR3 := I3:R3 <- *(AR2 bradd AR0++)
VCFFT8 VR3, VR2, #0 ; Save I0':R0' -> XAR1
|| VMOV32 *XAR1++, VR4 ;[VR2H:VR2L] := [R2 - R3:R2 + R3] := [VR2L - VR3L:VR2L + VR3L]
;[VR3H:VR3L] := [I2 - I3:I2 + I3] := [VR2H - VR3H:VR2H + VR3H]
VMOV32 *XAR1++, VR6 ; Save I1':R1' -> XAR1
VCFFT9 VR5, VR4, VR3, VR2, VR1, VR0, #0 ; Save I2':R2' -> XAR1
|| VMOV32 *XAR1++, VR5 ;[VR4H:VR4L] := [I0':R0'] := [(I0+I1) + (I2+I3):(R0+R1) + (R2+R3)] := [VR1L + VR3L:VR0L + VR2L]
;[VR5H:VR5L] := [I2':R2'] := [(I0+I1) - (I2+I3):(R0+R1) - (R2+R3)] := [VR1L VR3L:VR0L VR2L]
VMOV32 *++, VR7, ARP2 ; Save I3':R3' -> XAR1 | ARP -> XAR2
;VMOV32 *XAR1++, VR7, ARP2 ; Save I3':R3' -> XAR1 | ARP -> XAR2
;this form causes ARP to be XAR1 not XAR2
_ICFFT_run128Pt_stages1and2CombinedLoop:
VCFFT10 VR7, VR6, VR3, VR2, VR1, VR0, #0 ;[VR6H:VR6L] := [I1':R1'] := [(I0-I1) - (R2-R3):(R0-R1) + (I2-I3)] := [VR1H VR2H:VR0H + VR3H]
;[VR7H:VR7L] := [I3':R3'] := [(I0-I1) + (R2-R3):(R0-R1) - (I2-I3)] := [VR1H + VR2H:VR0H VR3H]
VMOV32 *XAR1++, VR4 ; Save I0':R0' -> XAR1
VMOV32 *XAR1++, VR6 ; Save I1':R1' -> XAR1
VMOV32 *XAR1++, VR5 ; Save I2':R2' -> XAR1
VMOV32 *XAR1++, VR7 ; Save I3':R3' -> XAR1
_ICFFT_run128Pt_stages1and2CombinedEnd:
.c28_amode ; change the assembler mode back to C28x
CLRC AMODE ; set AMODE back to C28x addressing
; C28_AMODE allows *XARn[#3bit] addressing
;;=============================================================================
;;
;; Stages 3 and 4 Combined
;;
;; Notes:
;; - These stages will use twiddle factors from the table, which are organized
;; as follows. Twiddles for stages 3 and 4 are interleaved
;; exp(2*pi*k1/N3) , k1 = {0,1,...N3/2-1}, N3 = 2^3
;; exp(2*pi*k2/N4) , k2 = {0,1,...N3/2-1}, N4 = 2^4
;; Cos(2*pi* 0/ 8) : Sin(2*pi* 0/ 8)
;; Cos(2*pi* 0/ 16) : Sin(2*pi* 0/ 16)
;; Cos(2*pi* 1/ 8) : Sin(2*pi* 1/ 8)
;; Cos(2*pi* 1/ 16) : Sin(2*pi* 1/ 16)
;; Cos(2*pi* 2/ 8) : Sin(2*pi* 2/ 8)
;; Cos(2*pi* 2/ 16) : Sin(2*pi* 2/ 16)
;; Cos(2*pi* 3/ 8) : Sin(2*pi* 3/ 8)
;; Cos(2*pi* 3/ 16) : Sin(2*pi* 3/ 16)
;;
;; - Stages 3 and 4 are affected by the SHR or SHL modifiers, results from all
;; operations are shifted right by SHR or left by SHL values
;; - XAR2, the output buffer from the previous stage is now the input to this stage
;;
;; Register Usage:
;; XAR0: butterfly lower ouput storage offset
;; XAR1: butterfly lower input storage offset
;; XAR2: pointer to even inputs(output of previous stage)
;; XAR3: pointer to twiddle factors
;; XAR4: pointer to odd inputs(output of previous stage)
;; XAR5: loop variable
;; XAR6: pointer to even outputs
;; XAR7: pointer to odd outputs
;;
;; Stage n Stage n+1
;; --XAR2-------------o----*---------o--------*------XAR6--->
;; \ / \ /
;; \/ \ /
;; /\ \ /
;; / \ \/
;; --XAR2[AR1]---XAR3-o----*---------o---/\---*--XAR6[AR0]--->
;; \ / \ /
;; \ \
;; / \ / \
;; --XAR4-------------o----*---XAR3--o---\/---*------XAR7--->
;; \ / /\
;; \/ / \
;; /\ / \
;; / \ / \
;; --XAR4[AR1]---XAR3-o----*---XAR3--o--------*--XAR7[AR0]--->
;;
_ICFFT_run128Pt_stages3and4Combined:
;; local defines
S34_INPUT_OFFSET .set ARG_OUTBUFFER
S34_OUTPUT_OFFSET .set ARG_INBUFFER
S34_NBFLYS .set 1<<(STAGE3-1) ; Number of butterflys per group (2^(s-1))
S34_NGROUPS .set NSAMPLES/(2*S34_NBFLYS)
; Number of groups for this stage
S34_INSEP .set 2*(S34_NBFLYS) ; Input Seperation = (NBFLYs) * 2(size of complex inputs)
S34_OUTSEP .set S34_INSEP-2 ; Output Seperation
S34_GROUPSEP .set 4*S34_NBFLYS ; Seperation between the groups = NBFLYs * 2(inputs per butterfly) * 2(size of complex inputs)
S34_TFOFFSET .set 0 ; Twiddle factor table offset for stages 3 and 4
S56_TFOFFSET .set S34_TFOFFSET+4*S34_NBFLYS
; Twiddle factor table offset for stages 5 and 6
S34_INNER_LOOP_COUNT .set S34_NBFLYS-2 ; Repeat over the number of butterflies-2(last bfly done outside the loop, RPTB loops n+1 times)
S34_OUTER_LOOP_COUNT .set NSAMPLES/(4*S34_NBFLYS) - 1
; Outer loop count = N/(2(inputs per bfly)*2(words/input)*NBFLYS) - 1
S34_POST_INCREMENT .set 2*3*S34_NBFLYS ; Post-increment for all the data pointers
VSETSHR #15 ; SHR=15, does Q30 to Q15 conversion for VCFFTx Multiplications
VRNDON ; RND=1, turns on rounding during conversion from Q30 to Q15
;VSATON ; Turn ON Saturation
;; XAR2 XAR6
;; ---+-+----o--*---+----o-----*-----++-o-----------*--------o-----------------------*--+----------+-->>
;; G1| 2 \/ | \ / || \ / \ / . |
;; | | /\ | \ / || \ / \ / .XAR6++ |
;; ---+-v----o--*---|----o--X--*-----||-o--\-----/--*--------o--------------------/--*--+----------|-->>
;; 4 \/ \/ || \ \ / / \ \ / / | |
;; | /\ /\ 8| \ \ / / \ \ / / | |
;; ---+------o--*---v----o--X--*-----||-o--\--X--/--*--------o--\--------------/--/--*--6----------|-->>
;; G2| \/ / \ A| \ \/ \/ / \ \ \ / / / | |
;; | /\ / \ R| \ /\ /\ / \ \ \ / / / A |
;; ---+------o--*--------o-----*-----1|-o--X--X--X--*--------o--\--\--------/--/--/--*--R----------|-->>
;; || \/ \/ \/ \/ \ \ \ \ / / / / 0 |
;; XAR2[AR1]|| /\ /\ /\ /\ \ \ \ \ / / / / |XAR6[AR0] |
;; ---+------o--*--------o-----*-----v|-o--X--X--X--*--------o--\--\--\--X--/--/--/--*--v----------|-->>
;; G3| \/ \ / | / \/ \/ \ \ \ \ \/ \/ / / / |
;; | /\ \ / 16 / /\ /\ \ \ \ \ /\ /\ / / / 16
;; ---+------o--*--------o--X--*------|-o--/--X--\--*--------o--\--\--X--X--X--/--/--*-------------|-->>
;; \/ \/ | / / \ \ \ \ \/ \/ \/ \/ / / |
;; /\ /\ | / / \ \ \ \ /\ /\ /\ /\ / / |
;; ---+------o--*--------o--X--*------|-o--/-----\--*--------o--\--X--X--X--X--X--/--*-------------|-->>
;; G4| \/ / \ | / \ \ \/ \/ \/ \/ \/ \/ / |
;; | /\ / \ | / \ \ /\ /\ /\ /\ /\ /\ / |
;; ---+------o--*--------o-----*------|-o-----------*--------o--X--X--X--X--X--X--X--*-------------|-->>
;; | \/ \/ \/ \/ \/ \/ \/ \/ |
;; XAR4 | /\ /\ /\ /\ /\ /\ /\ /\ XAR7 |
;; ---+-+----o--*---+----o-----*-----+v-o-----------*--------o--X--X--X--X--X--X--X--*--+----------v-->>
;; G5| 2 \/ | \ / | \ / / \/ \/ \/ \/ \/ \/ \ .
;; | | /\ | \ / | \ / / /\ /\ /\ /\ /\ /\ \ .XAR7++
;; ---+-v----o--*---|----o--X--*-----|--o--\-----/--*--------o--/--X--X--X--X--X--\--*--+------------->>
;; 4 \/ \/ | \ \ / / / / \/ \/ \/ \/ \ \ |
;; | /\ /\ 8 \ \ / / / / /\ /\ /\ /\ \ \ 6
;; ---+------o--*---v----o--X--*-----|--o--\--X--/--*--------o--/--/--X--X--X--\--\--*--|------------->>
;; G6| \/ / \ A \ \/ \/ / / / / \/ \/ \ \ \ A
;; | /\ / \ R \ /\ /\ / / / / /\ /\ \ \ \ R
;; ---+------o--*--------o-----*-----1--o--X--X--X--*--------o--/--/--/--X--\--\--\--*--0------------->>
;; | \/ \/ \/ \/ / / / / \ \ \ \ |
;; XAR4[AR1]| /\ /\ /\ /\ / / / / \ \ \ \ |XAR7[AR0]
;; ---+------o--*--------o-----*-----v--o--X--X--X--*--------o--/--/--/-----\--\--\--*--v------------->>
;; G7| \/ \ / / \/ \/ \ / / / \ \ \
;; | /\ \ / / /\ /\ \ / / / \ \ \
;; ---+------o--*--------o--X--*--------o--/--X--\--*--------o--/--/-----------\--\--*---------------->>
;; \/ \/ / / \ \ / / \ \
;; /\ /\ / / \ \ / / \ \
;; ---+------o--*--------o--X--*--------o--/-----\--*--------o--/-----------------\--*---------------->>
;; G8| \/ / \ / \ / \
;; | /\ / \ / \ / \
;; ---+------o--*--------o-----*--------o-----------*--------o-----------------------*---------------->>
;; S1 S2 S3 S4
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the input data array at
;; the begining of every s & s+1 stage calculation.
;; Note that previous stage's output array is input for this stage
;MOVL XAR4, *-SP[STK_ARG_PTR] ; Restore the pointer argument to XAR4
; XAR4 is not used in stage 1 & 2
MOVL XAR2, *+XAR4[S34_INPUT_OFFSET] ; XAR2 -> I0:R0 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;; For stage s & s+1
;; These are the separation index for inputs and outputs
;; input_separation = 2* 2^(s-1)
;; For Stage 3 & 4, input_separation = 2 * 2^(3-1) = 8
;; For Stage 5 & 6, input_separation = 2 * 2^(5-1) = 32
;; For Stage 7 & 8, input_separation = 2 * 2^(7-1) = 128
;; And so on ....
MOVL XAR1, #S34_INSEP
;; ar0 is added with an XARn pointer which is post incremented (+2)
;; and hence ar0 = xar1-2
MOVL XAR0, #S34_OUTSEP
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;This pointer points to the begining of the 1st output of the combined
;; s & s+1 stage butterfly. Note that the input buffer of the previous
;; stage is used as output buffer for this stage due to ping-pong scheme
MOVL XAR6, *+XAR4[S34_OUTPUT_OFFSET] ; XAR6 -> first output
; I0'':R0'' pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;This pointer points to the 3rd output of the combined s & s+1 stage butterfly.
;;This pointer should be initialized as below
;;For Stage 3 & 4 = 2 * 2 * 2^(3-1) = 16
;;For Stage 5 & 6 = 2 * 2 * 2^(5-1) = 64
;;For Stage 7 & 8 = 2 * 2 * 2^(7-1) = 256
;;And so on ...
MOVL XAR7, XAR6
ADDB XAR7, #S34_GROUPSEP ; I2'':R2'' pointer
;;-------------------------------------------------------------------------
;;--------------------------------------------------
;;Initialize this pointer to the begining of the twiddle-factor
;;table for stage s & s+1
;;For Stage 3 & 4: 0 to [0 + 4 * 2^(3-1) - 1] = 0 to 15
;;For Stage 5 & 6: 16 to [16 + 4 * 2^(5-1) - 1] = 16 to 79
;;For Stage 7 & 8: 80 to [80 + 4 * 2^(7-1) - 1] = 80 to 335
;;And so on ....
MOVL XAR3, #_vcu2_twiddleFactors
;;ADDB XAR3, #S34_TFOFFSET
MOVL *-SP[STK_TFPTR], XAR3
;;--------------------------------------------------
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the 2nd set of butterflies used in
;; the 1st of the combined stages
;; Second Butterfly offset for stage s & s+1
;; = 2 * input_separation = 2 * 2 * 2^(s-1)
;; For Stage 3 & 4 = 2 * 2 * 2^(3-1) = 16
;; For Stage 5 & 6 = 2 * 2 * 2^(5-1) = 64
;; For Stage 7 & 8 = 2 * 2 * 2^(7-1) = 256
;; And so on ...
;;
MOVL XAR4, XAR2
ADDB XAR4, #S34_GROUPSEP ; I2:R2 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;Outer loop
;; For Stage s & s+1, combined
;; no_of_inner_but = 2^(s-1) = 2^(3-1) = 4
;; no_of_outer_loop = size/(2*no_of_inner_but*2)-1 = 128/(2*4*2) = 8-1 = 7
MOVL XAR5, #S34_OUTER_LOOP_COUNT ; Initialize outer loop counter
; used in BANZ
;;-------------------------------------------------------------------------
_ICFFT_run128Pt_stages3and4OuterLoop:
MOVL XAR3, *-SP[STK_TFPTR] ; Reset the twiddle factor table pointer
;.lp_amode ; override assembler mode to C28x + C2xLP sysntax
;SETC AMODE ; set AMODE to C2xLP addressing
; Inner Butterfly Loop
VMOV32 VR5, *+XAR4[AR1] ; VR5 = I3:R3
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VMOV32 VR7, *XAR4++ ; VR7 = I2:R2
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VCFFT1 VR2, VR5, VR4 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1): R3*Cos(1) + I3*Sin(1)]
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #0 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1): R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H : R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H : R2 - VR2L]
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _ICFFT_run128Pt_stages3and4InnerLoop, #S34_INNER_LOOP_COUNT
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #0 ; VR5 = I3:R3
|| VMOV32 VR5, *+XAR4[AR1] ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2): R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H : R0 + VR2L]
;[VR3H:VR3L] = [I1':R1'] = [I0 - VR2H : R0 - VR2L]
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VCFFT4 VR4, VR2, VR1, VR0, #0 ; VR7 = I2:R2
|| VMOV32 VR7, *XAR4++ ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2): I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0'':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2'] = [I0' - VR2H: R0' - VR2L]
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VMOV32 *XAR6++, VR0 ; [I0'':R0''] = VR0
VCFFT5 VR5, VR4, VR3, VR2, VR1, VR0, #0 ;[I2'':R2''] = VR1
|| VMOV32 *XAR7++, VR1 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1):R3*Cos(1) + I3*Sin(1)]
;[VR0H:VR0L] = [I1':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I1' + VR2H: R1' - VR2L]
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VMOV32 *+XAR6[AR0], VR0 ;[I1'':R1''] = VR0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #0 ;[I3'':R3''] = VR1
|| VMOV32 *+XAR7[AR0], VR1 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1):R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H: R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H: R2 - VR2L]
_ICFFT_run128Pt_stages3and4InnerLoop:
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #0 ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2):R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H: R0 + VR2L]
;[VR1H:VR1L] = [I1':R1'] = [I0 - VR2H: R0 - VR2L]
NOP
VCFFT4 VR4, VR2, VR1, VR0, #0 ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2):I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2''] = [I0' - VR2H: R0' - VR2L]
NOP
VMOV32 *XAR6++, VR0 ;[I0'':R0''] = VR0
VCFFT6 VR3, VR2, VR1, VR0, #0 ;[I2'':R2''] = VR1
|| VMOV32 *XAR7++, VR1 ;[VR0H:VR0L] = [I1'':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3'':R3''] = [I1' + VR2H: R1' - VR2L]
NOP
VMOV32 *+XAR6[AR0], VR0 ;[I1'':R1''] = VR0
VMOV32 *+XAR7[AR0], VR1 ;[I3'':R3''] = VR1
;;--------------------------------------------------
;;Increment all these pointers with 2 * 3*2^(s-1)
;;for Stage 3 & 4, increment by 2 * 3 * 2^(3-1) = 24
;;for Stage 5 & 6, increment by 2 * 3 * 2^(5-1) = 96
;;for Stage 7 & 8, increment by 2 * 3 * 2^(7-1) = 384
ADDB XAR2, #S34_POST_INCREMENT
ADDB XAR4, #S34_POST_INCREMENT
ADDB XAR6, #S34_POST_INCREMENT
ADDB XAR7, #S34_POST_INCREMENT
;;--------------------------------------------------
BANZ _ICFFT_run128Pt_stages3and4OuterLoop, AR5--
_ICFFT_run128Pt_stages3and4CombinedEnd:
;.c28_amode ; change the assembler mode back to C28x
;CLRC AMODE ; set AMODE back to C28x addressing
; C28_AMODE allows *XARn[#3bit] addressing
; Stage 1 & 2 require AMODE others dont
;;=============================================================================
;;
;; Stages 5 and 6 Combined
;;
;; Notes:
;; - These stages will use twiddle factors from the table, which are organized
;; as follows. Twiddles for stages 5 and 6 are interleaved
;; exp(2*pi*k1/N5) , k1 = {0,1,...N5/2-1}, N5 = 2^5
;; exp(2*pi*k2/N6) , k2 = {0,1,...N5/2-1}, N6 = 2^6
;; - Stages 5 and 6 are affected by the SHR or SHL modifiers, results from all
;; operations are shifted right by SHR or left by SHL values
;; - XAR2, the pointer to the inputs, now points back to the input table
;;
;; Register Usage:
;; XAR0: butterfly lower ouput storage offset
;; XAR1: butterfly lower input storage offset
;; XAR2: pointer to even inputs(output of previous stage)
;; XAR3: pointer to twiddle factors
;; XAR4: pointer to odd inputs(output of previous stage)
;; XAR5: loop variable
;; XAR6: pointer to even outputs
;; XAR7: pointer to odd outputs
;;
;; Stage n Stage n+1
;; --XAR2-------------o----*---------o--------*------XAR6--->
;; \ / \ /
;; \/ \ /
;; /\ \ /
;; / \ \/
;; --XAR2[AR1]---XAR3-o----*---------o---/\---*--XAR6[AR0]--->
;; \ / \ /
;; \ \
;; / \ / \
;; --XAR4-------------o----*---XAR3--o---\/---*------XAR7--->
;; \ / /\
;; \/ / \
;; /\ / \
;; / \ / \
;; --XAR4[AR1]---XAR3-o----*---XAR3--o--------*--XAR7[AR0]--->
;;
_ICFFT_run128Pt_stages5and6Combined:
;; local defines
S56_INPUT_OFFSET .set ARG_INBUFFER
S56_OUTPUT_OFFSET .set ARG_OUTBUFFER
S56_NBFLYS .set 1<<(STAGE5-1) ; Number of butterflys per group (2^(s-1))
S56_NGROUPS .set NSAMPLES/(2*S56_NBFLYS)
; Number of groups for this stage
S56_INSEP .set 2*(S56_NBFLYS) ; Input Seperation = (NBFLYs) * 2(size of complex inputs)
S56_OUTSEP .set S56_INSEP-2 ; Output Seperation
S56_GROUPSEP .set 4*S56_NBFLYS ; Seperation between the groups = NBFLYs * 2(inputs per butterfly) * 2(size of complex inputs)
S7_TFOFFSET .set 1<<STAGE5
; Twiddle factor table offset for stage 7 from start of vcu0_twiddlefactors
S56_INNER_LOOP_COUNT .set S56_NBFLYS-2 ; Repeat over the number of butterflies-2(last bfly done outside the loop, RPTB loops n+1 times)
S56_OUTER_LOOP_COUNT .set NSAMPLES/(4*S56_NBFLYS) - 1
; Outer loop count = N/(2(inputs per bfly)*2(words/input)*NBFLYS) - 1
S56_POST_INCREMENT .set 2*3*S56_NBFLYS ; Post-increment for all the data pointers
; Set once in stage 3 & 4, dont set again
;VSETSHR #15 ; SHR=15, does Q30 to Q15 conversion for VCFFTx Multiplications
;VRNDON ; RND=1, turns on rounding during conversion from Q30 to Q15
;VSATON ; Turn ON Saturation
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the input data array at
;; the begining of every s & s+1 stage calculation.
;; Note that previous stage's output array is input for this stage
MOVL XAR4, *-SP[STK_ARG_PTR] ; Restore the pointer argument to XAR4
MOVL XAR2, *+XAR4[S56_INPUT_OFFSET] ; XAR2 -> I0:R0 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;; For stage s & s+1
;; These are the separation index for inputs and outputs
;; input_separation = 2* 2^(s-1)
;; For Stage 3 & 4, input_separation = 2 * 2^(3-1) = 8
;; For Stage 5 & 6, input_separation = 2 * 2^(5-1) = 32
;; For Stage 7 & 8, input_separation = 2 * 2^(7-1) = 128
;; And so on ....
MOVL XAR1, #S56_INSEP
;; ar0 is added with an XARn pointer which is post incremented (+2)
;; and hence ar0 = xar1-2
MOVL XAR0, #S56_OUTSEP
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;This pointer points to the begining of the 1st output of the combined
;; s & s+1 stage butterfly. Note that the input buffer of the previous
;; stage is used as output buffer for this stage due to ping-pong scheme
MOVL XAR6, *+XAR4[S56_OUTPUT_OFFSET] ; XAR6 -> first output
; I0'':R0'' pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;This pointer points to the 3rd output of the combined s & s+1 stage butterfly.
;;This pointer should be initialized as below
;;For Stage 3 & 4 = 2 * 2 * 2^(3-1) = 16
;;For Stage 5 & 6 = 2 * 2 * 2^(5-1) = 64
;;For Stage 7 & 8 = 2 * 2 * 2^(7-1) = 256
;;And so on ...
MOVL XAR7, XAR6
ADDB XAR7, #S56_GROUPSEP ; I2'':R2'' pointer
;;-------------------------------------------------------------------------
;;--------------------------------------------------
;;Initialize this pointer to the begining of the twiddle-factor
;;table for stage s & s+1
;;For Stage 3 & 4: 0 to [0 + 4 * 2^(3-1) - 1] = 0 to 15
;;For Stage 5 & 6: 16 to [16 + 4 * 2^(5-1) - 1] = 16 to 79
;;For Stage 7 & 8: 80 to [80 + 4 * 2^(7-1) - 1] = 80 to 335
;;And so on ....
MOVL XAR3, #_vcu2_twiddleFactors
ADDB XAR3, #S56_TFOFFSET
MOVL *-SP[STK_TFPTR], XAR3
;;--------------------------------------------------
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the 2nd set of butterflies used in
;; the 1st of the combined stages
;; Second Butterfly offset for stage s & s+1
;; = 2 * input_separation = 2 * 2 * 2^(s-1)
;; For Stage 3 & 4 = 2 * 2 * 2^(3-1) = 16
;; For Stage 5 & 6 = 2 * 2 * 2^(5-1) = 64
;; For Stage 7 & 8 = 2 * 2 * 2^(7-1) = 256
;; And so on ...
;;
MOVL XAR4, XAR2
ADDB XAR4, #S56_GROUPSEP ; I2:R2 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;Outer loop
;; For Stage s & s+1, combined
;; no_of_inner_but = 2^(s-1) = 2^(3-1) = 4
;; no_of_outer_loop = size/(2*no_of_inner_but*2)-1 = 128/(2*16*2) = 2-1 = 1
MOVL XAR5, #S56_OUTER_LOOP_COUNT ; Initialize outer loop counter
; used in BANZ
;;-------------------------------------------------------------------------
_ICFFT_run128Pt_stages5and6OuterLoop:
MOVL XAR3, *-SP[STK_TFPTR] ; Reset the twiddle factor table pointer
;.lp_amode ; override assembler mode to C28x + C2xLP sysntax
;SETC AMODE ; set AMODE to C2xLP addressing
; Inner Butterfly Loop
VMOV32 VR5, *+XAR4[AR1] ; VR5 = I3:R3
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VMOV32 VR7, *XAR4++ ; VR7 = I2:R2
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VCFFT1 VR2, VR5, VR4 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1): R3*Cos(1) + I3*Sin(1)]
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #0 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1): R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H : R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H : R2 - VR2L]
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _ICFFT_run128Pt_stages5and6InnerLoop, #S56_INNER_LOOP_COUNT
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #0 ; VR5 = I3:R3
|| VMOV32 VR5, *+XAR4[AR1] ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2): R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H : R0 + VR2L]
;[VR3H:VR3L] = [I1':R1'] = [I0 - VR2H : R0 - VR2L]
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VCFFT4 VR4, VR2, VR1, VR0, #0 ; VR7 = I2:R2
|| VMOV32 VR7, *XAR4++ ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2): I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0'':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2'] = [I0' - VR2H: R0' - VR2L]
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VMOV32 *XAR6++, VR0 ; [I0'':R0''] = VR0
VCFFT5 VR5, VR4, VR3, VR2, VR1, VR0, #0 ;[I2'':R2''] = VR1
|| VMOV32 *XAR7++, VR1 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1):R3*Cos(1) + I3*Sin(1)]
;[VR0H:VR0L] = [I1':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I1' + VR2H: R1' - VR2L]
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VMOV32 *+XAR6[AR0], VR0 ;[I1'':R1''] = VR0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #0 ;[I3'':R3''] = VR1
|| VMOV32 *+XAR7[AR0], VR1 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1):R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H: R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H: R2 - VR2L]
_ICFFT_run128Pt_stages5and6InnerLoop:
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #0 ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2):R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H: R0 + VR2L]
;[VR1H:VR1L] = [I1':R1'] = [I0 - VR2H: R0 - VR2L]
NOP
VCFFT4 VR4, VR2, VR1, VR0, #0 ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2):I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2''] = [I0' - VR2H: R0' - VR2L]
NOP
VMOV32 *XAR6++, VR0 ;[I0'':R0''] = VR0
VCFFT6 VR3, VR2, VR1, VR0, #0 ;[I2'':R2''] = VR1
|| VMOV32 *XAR7++, VR1 ;[VR0H:VR0L] = [I1'':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3'':R3''] = [I1' + VR2H: R1' - VR2L]
NOP
VMOV32 *+XAR6[AR0], VR0 ;[I1'':R1''] = VR0
VMOV32 *+XAR7[AR0], VR1 ;[I3'':R3''] = VR1
;;--------------------------------------------------
;;Increment all these pointers with 2 * 3*2^(s-1)
;;for Stage 3 & 4, increment by 2 * 3 * 2^(3-1) = 24
;;for Stage 5 & 6, increment by 2 * 3 * 2^(5-1) = 96
;;for Stage 7 & 8, increment by 2 * 3 * 2^(7-1) = 384
ADDB XAR2, #S56_POST_INCREMENT
ADDB XAR4, #S56_POST_INCREMENT
ADDB XAR6, #S56_POST_INCREMENT
ADDB XAR7, #S56_POST_INCREMENT
;;--------------------------------------------------
BANZ _ICFFT_run128Pt_stages5and6OuterLoop, AR5--
_ICFFT_run128Pt_stages5and6CombinedEnd:
;.c28_amode ; change the assembler mode back to C28x
;CLRC AMODE ; set AMODE back to C28x addressing
; C28_AMODE allows *XARn[#3bit] addressing
;;=============================================================================
;;
;; Stage 7
;;
;; Notes:
;; - These stages will use twiddle factors from the table, which are organized
;; as follows.
;; exp(2*pi*k1/N7) , k1 = {0,1,...N7-1}, N7 = 2^7
;; - Stages 7 is affected by the SHR or SHL modifiers, results from all
;; operations are shifted right by SHR or left by SHL values
;; - XAR2, the pointer to the inputs, now points to the output buffer
;; - This stage uses the VCMPY instruction that is dependent on the CPACK
;; bit, ensure that the CPACK bit = 1 i.e the low word is real
;; - This single stage changes the SHR and SHL values
;;
;; Register Usage:
;; XAR0: butterfly lower output storage offset
;; XAR1: butterfly lower input storage offset (output offset 1st bfly only)
;; XAR2: pointer to even inputs(output of previous stage)
;; XAR4: pointer to structure(not used in the calculations)
;; XAR6: pointer to twiddle factors
;;
;; Stage n
;; --XAR2-------------o----*-------XAR3--->
;; \ /
;; \/
;; /\
;; / \
;; --XAR2[AR1]---XAR6-o----*---XAR3[AR0]--->
;;
;;
_ICFFT_run128Pt_stage7:
;; local defines
S7_INPUT_OFFSET .set ARG_OUTBUFFER
S7_OUTPUT_OFFSET .set ARG_INBUFFER
S7_NBFLYS .set 1<<(STAGE7-1) ; Number of butterflys per group (2^(s-1))
S7_NGROUPS .set NSAMPLES/(2*S7_NBFLYS)
; Number of groups for this stage
S7_IOSEP .set 2*(S7_NBFLYS)-2 ; Input/Output Seperation = (NBFLYs) * 2(size of complex inputs)
; we add this offset to an incremented pointer hence the -2
S7_LOOP_COUNT .set S7_NBFLYS-4 ; Repeat over the number of butterflies-3
; (first, second and last bfly done outside the loop & RPTB loops n+1 times)
VSETSHR #15 ; SHR=15, do not divide by 2
;VSETSHR #16 ; SHR=16, scales down for VCADD/SUB operations
VSETSHL #15 ; SHR=15, scales down for VCADD/SUB operations
; The rest are set at the beginning of combined stages 1 & 2
;VRNDON ; RND=1, turns on rounding during conversion from Q30 to Q15
;VSATON ; Turn ON Saturation
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the input data array
;; Note that previous stage's output array is input for this stage
MOVL XAR4, *-SP[STK_ARG_PTR] ; Restore the pointer argument to XAR4
MOVL XAR2, *+XAR4[S7_INPUT_OFFSET] ; XAR2 -> I0:R0 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;; For stage s & s+1
;; These are the separation index for inputs and outputs
;; input_separation = 2* 2^(s-1)
;; For Stage 3 & 4, input_separation = 2 * 2^(3-1) = 8
;; For Stage 5 & 6, input_separation = 2 * 2^(5-1) = 32
;; For Stage 7 & 8, input_separation = 2 * 2^(7-1) = 128
;; And so on ....
MOVL XAR1, #S7_IOSEP
MOVL XAR0, #(S7_IOSEP+2) ; AR0 = N/2
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the output of the butterfly.
;; Note that the input buffer of the previous stage is used as output
;; buffer for this stage due to ping-pong scheme
MOVL XAR3, *+XAR4[S7_OUTPUT_OFFSET] ; XAR3 -> output
; I0':R0' pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;Initialize this pointer to the begining of the twiddle-factor
;;table for stage
;;For Stage 3 & 4: 0 to [0 + 4 * 2^(3-1) - 1] = 0 to 15
;;For Stage 5 & 6: 16 to [16 + 4 * 2^(5-1) - 1] = 16 to 79
;;For Stage 7 & 8: 80 to [80 + 4 * 2^(7-1) - 1] = 80 to 335
;;And so on ....
MOVL XAR6, #_vcu0_twiddleFactors
ADDB XAR6, #S7_TFOFFSET
;MOVL *-SP[STK_TFPTR], XAR6
;Dont need to reset twiddle factor table pointer in single stages
;;-------------------------------------------------------------------------
VMOV32 VR4, *XAR2++ ; VR4 = I0:R0
VMOV32 VR1, *+XAR2[AR1] ; VR1 = I1:R1
VMOV32 VR0, *XAR6++ ; VR0 = Sin(1):Cos(1)
VCMPY VR3, VR2, VR1, VR0 ; VR0 = Sin(2):Cos(2)
|| VMOV32 VR0, *XAR6++ ; VR2 = I1*Cos(1) + R1*Sin(1)
; VR3 = R1*Cos(1) - I1*Sin(1)
NOP ; (delay slot of VCMPY)
VCDSUB16 VR6, VR4, VR3, VR2 ;[VR6H:VR6L] = [(I0<<SHL VR2)>>SHR : (R0<<SHL - VR3)>>SHR]
VCDADD16 VR5, VR4, VR3, VR2 ; VR4 = I0:R0 (next butterfly)
|| VMOV32 VR4, *XAR2++ ;[VR5H:VR5L] = [(I0<<SHL + VR2)>>SHR : (R0<<SHL + VR3)>>SHR]
VMOV32 VR1, *+XAR2[AR1] ; VR1 = I1:R1 (next butterfly)
VCMPY VR3, VR2, VR1, VR0 ;[I0':R0'] = VR5
|| VMOV32 *XAR3++, VR5 ; VR2 = I1*Cos(n) + R1*Sin(n)
; VR3 = R1*Cos(n) - I1*Sin(n)
VMOV32 *+XAR3[AR1], VR6 ; [I1':R1'] = VR6
; Store the DC element at the 0th location
ADDB XAR3, #S7_IOSEP ; Set the output pointer to the half way point XAR3 -> X(N/2)
; Store all subsequent points in the reverse order
VCDSUB16 VR6, VR4, VR3, VR2 ; VR0 = Sin(n):Cos(n)
|| VMOV32 VR0, *XAR6++ ;[VR6H:VR6L] = [(I0<<SHL VR2)>>SHR : (R0<<SHL - VR3)>>SHR]
VCDADD16 VR5, VR4, VR3, VR2 ; VR4 = I0:R0 (next butterfly)
|| VMOV32 VR4, *XAR2++ ;[VR5H:VR5L] = [(I0<<SHL + VR2)>>SHR : (R0<<SHL + VR3)>>SHR]
VMOV32 VR1, *+XAR2[AR1] ; VR1 = I1:R1 (next butterfly)
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _ICFFT_run128Pt_stage7Loop, #S7_LOOP_COUNT
VCMPY VR3, VR2, VR1, VR0 ;[I1':R1'] = VR6
|| VMOV32 *--XAR3, VR6 ; VR2 = I1*Cos(n) + R1*Sin(n)
; VR3 = R1*Cos(n) - I1*Sin(n)
VMOV32 *+XAR3[AR0], VR5 ;[I0':R0'] = VR5
VCDSUB16 VR6, VR4, VR3, VR2 ; VR0 = Sin(n):Cos(n)
|| VMOV32 VR0, *XAR6++ ;[VR6H:VR6L] = [(I0<<SHL VR2)>>SHR : (R0<<SHL - VR3)>>SHR]
VCDADD16 VR5, VR4, VR3, VR2 ; VR4 = I0:R0 (next butterfly)
|| VMOV32 VR4, *XAR2++ ;[VR5H:VR5L] = [(I0<<SHL + VR2)>>SHR : (R0<<SHL + VR3)>>SHR]
VMOV32 VR1, *+XAR2[AR1] ; VR1 = I1:R1 (next butterfly)
_ICFFT_run128Pt_stage7Loop:
VCMPY VR3, VR2, VR1, VR0 ;[I1':R1'] = VR6
|| VMOV32 *--XAR3, VR6 ; VR2 = I1*Cos(n) + R1*Sin(n)
; VR3 = R1*Cos(n) - I1*Sin(n)
VMOV32 *+XAR3[AR0], VR5 ;[I0':R0'] = VR5
VCDSUB16 VR6, VR4, VR3, VR2 ;[VR6H:VR6L] = [(I0<<SHL VR2)>>SHR : (R0<<SHL - VR3)>>SHR]
VCDADD16 VR5, VR4, VR3, VR2 ;[VR5H:VR5L] = [(I0<<SHL + VR2)>>SHR : (R0<<SHL + VR3)>>SHR]
VMOV32 *--XAR3, VR6 ;[I1':R1'] = VR6
VMOV32 *+XAR3[AR0], VR5 ;[I0':R0'] = VR5
;;=============================================================================
;; Switch the input/output pointers
;; Register Usage:
;; ACC: temporary storage
;; P : temporary storage
;;
MOVL XAR4, *-SP[STK_ARG_PTR] ; Restore the pointer argument to XAR4
MOVL ACC, *+XAR4[ARG_INBUFFER]
MOVL P, *+XAR4[ARG_OUTBUFFER]
MOVL *+XAR4[ARG_INBUFFER], P
MOVL *+XAR4[ARG_OUTBUFFER], ACC
;;=============================================================================
ICFFT_CONTEXT_RESTORE
LRETR
;; End of file
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,719 @@
;;*****************************************************************************
;;! \file source/vcu2/vcu2_icfft_32.asm
;;!
;;! \brief 32-pt complex inverse FFT
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;;*****************************************************************************
;; global defines
;;*****************************************************************************
;; FFT Routine defines
NSTAGES .set 5
NSAMPLES .set (1 << NSTAGES)
NSKIP .set 2*(512 / NSAMPLES) ;vcu0 largest table is stage9 i.e. 512 twiddles(used in unpack)
;the 2 in the numerator is for the size of the twiddle in words
STAGE1 .set 1
STAGE3 .set 3
STAGE5 .set 5
STAGE7 .set 7
;; Argument structure defines
ARG_INBUFFER .set 0
ARG_OUTBUFFER .set 2
ARG_TFTABLE .set 4
ARG_NSAMPLES .set 6
ARG_NSTAGES .set 7
ARG_TFSKIP .set 8
;; Stack defines
;;
;; |_______|
;; |_______|<- Stack Pointer(SP) <---SP
;; |_______|<- STK_ARG_PTR (SP-2)
;; |_______|<- STK_TFPTR (SP-4)
;;
LOCAL_FRAME_SIZE .set 4
STK_ARG_PTR .set 2
STK_TFPTR .set 4
;;*****************************************************************************
;; macros
;;*****************************************************************************
;;
;; MACRO : 'ICFFT_CONTEXT_SAVE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on entry into FFT routine
;;
ICFFT_CONTEXT_SAVE .macro
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #LOCAL_FRAME_SIZE ; allocate stack space for local frame
.endm
;;
;; MACRO : 'ICFFT_CONTEXT_RESTORE'
;; SIZE : Number of WORDS/Number of Cycles 14
;; USAGE : Called on exit from FFT routine
;;
ICFFT_CONTEXT_RESTORE .macro
SUBB SP, #LOCAL_FRAME_SIZE ; deallocate stack space for local frame
POP XAR3
POP XAR2
POP XAR1
.endm
;;*****************************************************************************
;; globals
;;*****************************************************************************
.global _ICFFT_run32Pt
.ref _vcu0_twiddleFactors
.ref _vcu2_twiddleFactors
;;*****************************************************************************
;; function definitions
;;*****************************************************************************
.text
;;
;; \brief Calculate the 32 pt Complex FFT
;;
;; \param Handle to the structure, CFFT_Obj(passed in XAR4)
;; - *+XAR4[0]: int16_t *pInBuffer -> input pointer
;; - *+XAR4[2]: int16_t *pOutBuffer -> work(Output) buffer pointer
;; - *+XAR4[4]: int16_t *pTwiddleFactors-> twiddle factor table pointer
;; - *+XAR4[6]: int16_t nSamples-> Number of data points
;; - *+XAR4[7]: int16_t nStages-> Number of FFT stages
;; - *+XAR4[8]: int16_t twiddleSkipStep-> Twiddle factor table search step
;;
;; \note
;; - This algorithm works on two buffers of size 2*N(32-bit complex) in ping-pong fashion
;; - N must be a power of 2 for this algorithm
;; - Must be of size N >= 16(2^4)
;; - This function actively sets CPACK=1 style complex packing
;; i.e. [Lo:Hi] => [Real:Imag], the input data must also be arranged in this format
;; - Sign extension is automatically done for right shift operations
;; - VSTATUS.RND=1, rounding is done for the right shift operation
;; - OVFR is set if signed overflow is detected for add/sub calculation in which destination is VRxL
;; - OVFI is set if signed overflow is detected for add/sub calculation in which destination is VRxH
;; - 16-bit signed results (before the shift right) are saturated if SAT = 1
;; - Make sure that input and output buffer pointer points to two diffrent
;; RAM blocks to avoid arbitration between reads and writes
;;
;; \return FFT of the input in the output buffer pointed to by ICFFT_Obj.pOutBuffer
;;
_ICFFT_run32Pt:
ICFFT_CONTEXT_SAVE
MOVL *-SP[STK_ARG_PTR], XAR4
;; Computation Prep
VSETCPACK ; Set the CPACK bit to 1
;SETC SXM ; sign extension mode
; ISS says SXM is automatically done so check that it is
VSATON ; Turn ON Saturation
;;
;; Stages 1 and 2 Combined
;;
;; Notes:
;; - These stages use trivial twiddle factors: 1,-1,j and -j.
;; - C27x AMODE is required in this stage to facilitate the use of
;; the bit-reversed addressing mode with simultaneous ARP update i.e
;; VMOV32 mem32,VRx,ARPn
;; - Setting up the bit-reversed index in AR0
;; Assume N = 64, Since we have complex data its 2N or
;; 128(2^7) words to index i.e. we need 7 bits to address all locations(0-127)
;; we represent 1 as : b'0000001' -> 0x0001
;; bit reversed 1 as : b'1000000' -> 0x0040
;; N represented in hex is already 0x0040, so we load this directly to AR0
;; - Stages 1 and 2 arent affected by the SHR or SHL modifiers, results from all
;; operations are shifted right by 1 bit
;;
;; Register Usage:
;; XAR0: offset address(bit-reversed indexing)
;; XAR1: output storage pointer
;; XAR2: input pointer
;;
;; Stage 1 Stage 2
;; --XAR1,*BR0++---o----*-----o--------*--XAR2++-->
;; \ / \ /
;; \/ \ /
;; /\ \ /
;; / \ \/
;; --XAR1,*BR0++---o----*-----o---/\---*--XAR2++--->
;; \ / \ /
;; \ \
;; / \ / \
;; --XAR1,*BR0++---o----*-----o---\/---*--XAR2++-->
;; \ / /\
;; \/ / \
;; /\ / \
;; / \ / \
;; --XAR1,*BR0++---o----*-----o--------*--XAR2++--->
;;
_ICFFT_run32Pt_stages1and2Combined:
;; local defines
S12_NBFLY .set (NSAMPLES / (2*2)) ; Number of 2x2 butterflies
S12_LOOP_COUNT .set S12_NBFLY - 2 ; Stage 1/2 loop count
MOVZ AR0, *+XAR4[ARG_NSAMPLES] ; AR0 := bit-reversed index 1
MOVL XAR2, *+XAR4[ARG_INBUFFER] ; XAR2 -> input buffer
MOVL XAR1, *+XAR4[ARG_OUTBUFFER] ; XAR1 -> output buffer
.lp_amode ; override assembler mode to C28x + C2xLP sysntax
SETC AMODE ; set AMODE to C2xLP addressing
NOP *,ARP2 ; ARP -> XAR2
VMOV32 VR0, *BR0++ ; VR0 := *(AR2 bradd AR0++) | VR0 := I0:R0
VMOV32 VR1, *BR0++ ; VR1 := *(AR2 bradd AR0++) | VR1 := I1:R1
VCFFT7 VR1, VR0, #0 ; VR2 = I2:R2 <- XAR1
|| VMOV32 VR2, *BR0++ ;[VR0H:VR0L] := [R0 - R1:R0 + R1] := [VR0L - VR1L:VR0L + VR1L]
;[VR1H:VR1L] := [I0 - I1:I0 + I1] := [VR0H - VR1H:VR0H + VR1H]
VMOV32 VR3, *BR0++ ; VR3 := I3:R3 <- XAR1
VCFFT8 VR3, VR2, #0 ;[VR2H:VR2L] := [R2 - R3:R2 + R3] := [VR2L - VR3L:VR2L + VR3L]
;[VR3H:VR3L] := [I2 - I3:I2 + I3] := [VR2H - VR3H:VR2H + VR3H]
VCFFT9 VR5, VR4, VR3, VR2, VR1, VR0, #0 ;[VR4H:VR4L] := [I0':R0'] := [(I0+I1) + (I2+I3):(R0+R1) + (R2+R3)] := [VR1L + VR3L:VR0L + VR2L]
;[VR5H:VR5L] := [I2':R2'] := [(I0+I1) - (I2+I3):(R0+R1) - (R2+R3)] := [VR1L VR3L:VR0L VR2L]
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _ICFFT_run32Pt_stages1and2CombinedLoop, #S12_LOOP_COUNT
VCFFT10 VR7, VR6, VR3, VR2, VR1, VR0, #0 ; VR0 := I0:R0 <- *(AR2 bradd AR0++)
|| VMOV32 VR0, *BR0++ ;[VR6H:VR6L] := [I1':R1'] := [(I0-I1) - (R2-R3):(R0-R1) + (I2-I3)] := [VR1H VR2H:VR0H + VR3H]
;[VR7H:VR7L] := [I3':R3'] := [(I0-I1) + (R2-R3):(R0-R1) - (I2-I3)] := [VR1H + VR2H:VR0H VR3H]
VMOV32 VR1, *BR0++ ; VR1 := I1:R1 <- *(AR2 bradd AR0++)
VCFFT7 VR1, VR0, #0 ; VR2 := I2:R2 <- *(AR2 bradd AR0++)
|| VMOV32 VR2, *BR0++ ;[VR0H:VR0L] := [R0 - R1:R0 + R1] := [VR0L - VR1L:VR0L + VR1L]
;[VR1H:VR1L] := [I0 - I1:I0 + I1] := [VR0H - VR1H:VR0H + VR1H]
VMOV32 VR3, *BR0++ ; VR3 := I3:R3 <- *(AR2 bradd AR0++)
VCFFT8 VR3, VR2, #0 ; Save I0':R0' -> XAR1
|| VMOV32 *XAR1++, VR4 ;[VR2H:VR2L] := [R2 - R3:R2 + R3] := [VR2L - VR3L:VR2L + VR3L]
;[VR3H:VR3L] := [I2 - I3:I2 + I3] := [VR2H - VR3H:VR2H + VR3H]
VMOV32 *XAR1++, VR6 ; Save I1':R1' -> XAR1
VCFFT9 VR5, VR4, VR3, VR2, VR1, VR0, #0 ; Save I2':R2' -> XAR1
|| VMOV32 *XAR1++, VR5 ;[VR4H:VR4L] := [I0':R0'] := [(I0+I1) + (I2+I3):(R0+R1) + (R2+R3)] := [VR1L + VR3L:VR0L + VR2L]
;[VR5H:VR5L] := [I2':R2'] := [(I0+I1) - (I2+I3):(R0+R1) - (R2+R3)] := [VR1L VR3L:VR0L VR2L]
VMOV32 *++, VR7, ARP2 ; Save I3':R3' -> XAR1 | ARP -> XAR2
;VMOV32 *XAR1++, VR7, ARP2 ; Save I3':R3' -> XAR1 | ARP -> XAR2
;this form causes ARP to be XAR1 not XAR2
_ICFFT_run32Pt_stages1and2CombinedLoop:
VCFFT10 VR7, VR6, VR3, VR2, VR1, VR0, #0 ;[VR6H:VR6L] := [I1':R1'] := [(I0-I1) - (R2-R3):(R0-R1) + (I2-I3)] := [VR1H VR2H:VR0H + VR3H]
;[VR7H:VR7L] := [I3':R3'] := [(I0-I1) + (R2-R3):(R0-R1) - (I2-I3)] := [VR1H + VR2H:VR0H VR3H]
VMOV32 *XAR1++, VR4 ; Save I0':R0' -> XAR1
VMOV32 *XAR1++, VR6 ; Save I1':R1' -> XAR1
VMOV32 *XAR1++, VR5 ; Save I2':R2' -> XAR1
VMOV32 *XAR1++, VR7 ; Save I3':R3' -> XAR1
_ICFFT_run32Pt_stages1and2CombinedEnd:
.c28_amode ; change the assembler mode back to C28x
CLRC AMODE ; set AMODE back to C28x addressing
; C28_AMODE allows *XARn[#3bit] addressing
;;=============================================================================
;;
;; Stages 3 and 4 Combined
;;
;; Notes:
;; - These stages will use twiddle factors from the table, which are organized
;; as follows. Twiddles for stages 3 and 4 are interleaved
;; exp(2*pi*k1/N3) , k1 = {0,1,...N3/2-1}, N3 = 2^3
;; exp(2*pi*k2/N4) , k2 = {0,1,...N3/2-1}, N4 = 2^4
;; Cos(2*pi* 0/ 8) : Sin(2*pi* 0/ 8)
;; Cos(2*pi* 0/ 16) : Sin(2*pi* 0/ 16)
;; Cos(2*pi* 1/ 8) : Sin(2*pi* 1/ 8)
;; Cos(2*pi* 1/ 16) : Sin(2*pi* 1/ 16)
;; Cos(2*pi* 2/ 8) : Sin(2*pi* 2/ 8)
;; Cos(2*pi* 2/ 16) : Sin(2*pi* 2/ 16)
;; Cos(2*pi* 3/ 8) : Sin(2*pi* 3/ 8)
;; Cos(2*pi* 3/ 16) : Sin(2*pi* 3/ 16)
;;
;; - Stages 3 and 4 are affected by the SHR or SHL modifiers, results from all
;; operations are shifted right by SHR or left by SHL values
;; - XAR2, the output buffer from the previous stage is now the input to this stage
;;
;; Register Usage:
;; XAR0: butterfly lower ouput storage offset
;; XAR1: butterfly lower input storage offset
;; XAR2: pointer to even inputs(output of previous stage)
;; XAR3: pointer to twiddle factors
;; XAR4: pointer to odd inputs(output of previous stage)
;; XAR5: loop variable
;; XAR6: pointer to even outputs
;; XAR7: pointer to odd outputs
;;
;; Stage n Stage n+1
;; --XAR2-------------o----*---------o--------*------XAR6--->
;; \ / \ /
;; \/ \ /
;; /\ \ /
;; / \ \/
;; --XAR2[AR1]---XAR3-o----*---------o---/\---*--XAR6[AR0]--->
;; \ / \ /
;; \ \
;; / \ / \
;; --XAR4-------------o----*---XAR3--o---\/---*------XAR7--->
;; \ / /\
;; \/ / \
;; /\ / \
;; / \ / \
;; --XAR4[AR1]---XAR3-o----*---XAR3--o--------*--XAR7[AR0]--->
;;
_ICFFT_run32Pt_stages3and4Combined:
;; local defines
S34_INPUT_OFFSET .set ARG_OUTBUFFER
S34_OUTPUT_OFFSET .set ARG_INBUFFER
S34_NBFLYS .set 1<<(STAGE3-1) ; Number of butterflys per group (2^(s-1))
S34_NGROUPS .set NSAMPLES/(2*S34_NBFLYS)
; Number of groups for this stage
S34_INSEP .set 2*(S34_NBFLYS) ; Input Seperation = (NBFLYs) * 2(size of complex inputs)
S34_OUTSEP .set S34_INSEP-2 ; Output Seperation
S34_GROUPSEP .set 4*S34_NBFLYS ; Seperation between the groups = NBFLYs * 2(inputs per butterfly) * 2(size of complex inputs)
S34_TFOFFSET .set 0 ; Twiddle factor table offset for stages 3 and 4
S5_TFOFFSET .set S34_TFOFFSET+4*S34_NBFLYS
; Twiddle factor table offset for stages 5 and 6
S34_INNER_LOOP_COUNT .set S34_NBFLYS-2 ; Repeat over the number of butterflies-2(last bfly done outside the loop, RPTB loops n+1 times)
S34_OUTER_LOOP_COUNT .set NSAMPLES/(4*S34_NBFLYS) - 1
; Outer loop count = N/(2(inputs per bfly)*2(words/input)*NBFLYS) - 1
S34_POST_INCREMENT .set 2*3*S34_NBFLYS ; Post-increment for all the data pointers
VSETSHR #15 ; SHR=15, does Q30 to Q15 conversion for VCFFTx Multiplications
VRNDON ; RND=1, turns on rounding during conversion from Q30 to Q15
;VSATON ; Turn ON Saturation
;; XAR2 XAR6
;; ---+-+----o--*---+----o-----*-----++-o-----------*--------o-----------------------*--+----------+-->>
;; G1| 2 \/ | \ / || \ / \ / . |
;; | | /\ | \ / || \ / \ / .XAR6++ |
;; ---+-v----o--*---|----o--X--*-----||-o--\-----/--*--------o--------------------/--*--+----------|-->>
;; 4 \/ \/ || \ \ / / \ \ / / | |
;; | /\ /\ 8| \ \ / / \ \ / / | |
;; ---+------o--*---v----o--X--*-----||-o--\--X--/--*--------o--\--------------/--/--*--6----------|-->>
;; G2| \/ / \ A| \ \/ \/ / \ \ \ / / / | |
;; | /\ / \ R| \ /\ /\ / \ \ \ / / / A |
;; ---+------o--*--------o-----*-----1|-o--X--X--X--*--------o--\--\--------/--/--/--*--R----------|-->>
;; || \/ \/ \/ \/ \ \ \ \ / / / / 0 |
;; XAR2[AR1]|| /\ /\ /\ /\ \ \ \ \ / / / / |XAR6[AR0] |
;; ---+------o--*--------o-----*-----v|-o--X--X--X--*--------o--\--\--\--X--/--/--/--*--v----------|-->>
;; G3| \/ \ / | / \/ \/ \ \ \ \ \/ \/ / / / |
;; | /\ \ / 16 / /\ /\ \ \ \ \ /\ /\ / / / 16
;; ---+------o--*--------o--X--*------|-o--/--X--\--*--------o--\--\--X--X--X--/--/--*-------------|-->>
;; \/ \/ | / / \ \ \ \ \/ \/ \/ \/ / / |
;; /\ /\ | / / \ \ \ \ /\ /\ /\ /\ / / |
;; ---+------o--*--------o--X--*------|-o--/-----\--*--------o--\--X--X--X--X--X--/--*-------------|-->>
;; G4| \/ / \ | / \ \ \/ \/ \/ \/ \/ \/ / |
;; | /\ / \ | / \ \ /\ /\ /\ /\ /\ /\ / |
;; ---+------o--*--------o-----*------|-o-----------*--------o--X--X--X--X--X--X--X--*-------------|-->>
;; | \/ \/ \/ \/ \/ \/ \/ \/ |
;; XAR4 | /\ /\ /\ /\ /\ /\ /\ /\ XAR7 |
;; ---+-+----o--*---+----o-----*-----+v-o-----------*--------o--X--X--X--X--X--X--X--*--+----------v-->>
;; G5| 2 \/ | \ / | \ / / \/ \/ \/ \/ \/ \/ \ .
;; | | /\ | \ / | \ / / /\ /\ /\ /\ /\ /\ \ .XAR7++
;; ---+-v----o--*---|----o--X--*-----|--o--\-----/--*--------o--/--X--X--X--X--X--\--*--+------------->>
;; 4 \/ \/ | \ \ / / / / \/ \/ \/ \/ \ \ |
;; | /\ /\ 8 \ \ / / / / /\ /\ /\ /\ \ \ 6
;; ---+------o--*---v----o--X--*-----|--o--\--X--/--*--------o--/--/--X--X--X--\--\--*--|------------->>
;; G6| \/ / \ A \ \/ \/ / / / / \/ \/ \ \ \ A
;; | /\ / \ R \ /\ /\ / / / / /\ /\ \ \ \ R
;; ---+------o--*--------o-----*-----1--o--X--X--X--*--------o--/--/--/--X--\--\--\--*--0------------->>
;; | \/ \/ \/ \/ / / / / \ \ \ \ |
;; XAR4[AR1]| /\ /\ /\ /\ / / / / \ \ \ \ |XAR7[AR0]
;; ---+------o--*--------o-----*-----v--o--X--X--X--*--------o--/--/--/-----\--\--\--*--v------------->>
;; G7| \/ \ / / \/ \/ \ / / / \ \ \
;; | /\ \ / / /\ /\ \ / / / \ \ \
;; ---+------o--*--------o--X--*--------o--/--X--\--*--------o--/--/-----------\--\--*---------------->>
;; \/ \/ / / \ \ / / \ \
;; /\ /\ / / \ \ / / \ \
;; ---+------o--*--------o--X--*--------o--/-----\--*--------o--/-----------------\--*---------------->>
;; G8| \/ / \ / \ / \
;; | /\ / \ / \ / \
;; ---+------o--*--------o-----*--------o-----------*--------o-----------------------*---------------->>
;; S1 S2 S3 S4
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the input data array at
;; the begining of every s & s+1 stage calculation.
;; Note that previous stage's output array is input for this stage
;MOVL XAR4, *-SP[STK_ARG_PTR] ; Restore the pointer argument to XAR4
; XAR4 is not used in stage 1 & 2
MOVL XAR2, *+XAR4[S34_INPUT_OFFSET] ; XAR2 -> I0:R0 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;; For stage s & s+1
;; These are the separation index for inputs and outputs
;; input_separation = 2* 2^(s-1)
;; For Stage 3 & 4, input_separation = 2 * 2^(3-1) = 8
;; For Stage 5 & 6, input_separation = 2 * 2^(5-1) = 32
;; For Stage 7 & 8, input_separation = 2 * 2^(7-1) = 128
;; And so on ....
MOVL XAR1, #S34_INSEP
;; ar0 is added with an XARn pointer which is post incremented (+2)
;; and hence ar0 = xar1-2
MOVL XAR0, #S34_OUTSEP
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;This pointer points to the begining of the 1st output of the combined
;; s & s+1 stage butterfly. Note that the input buffer of the previous
;; stage is used as output buffer for this stage due to ping-pong scheme
MOVL XAR6, *+XAR4[S34_OUTPUT_OFFSET] ; XAR6 -> first output
; I0'':R0'' pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;This pointer points to the 3rd output of the combined s & s+1 stage butterfly.
;;This pointer should be initialized as below
;;For Stage 3 & 4 = 2 * 2 * 2^(3-1) = 16
;;For Stage 5 & 6 = 2 * 2 * 2^(5-1) = 64
;;For Stage 7 & 8 = 2 * 2 * 2^(7-1) = 256
;;And so on ...
MOVL XAR7, XAR6
ADDB XAR7, #S34_GROUPSEP ; I2'':R2'' pointer
;;-------------------------------------------------------------------------
;;--------------------------------------------------
;;Initialize this pointer to the begining of the twiddle-factor
;;table for stage s & s+1
;;For Stage 3 & 4: 0 to [0 + 4 * 2^(3-1) - 1] = 0 to 15
;;For Stage 5 & 6: 16 to [16 + 4 * 2^(5-1) - 1] = 16 to 79
;;For Stage 7 & 8: 80 to [80 + 4 * 2^(7-1) - 1] = 80 to 335
;;And so on ....
MOVL XAR3, #_vcu2_twiddleFactors
;;ADDB XAR3, #S34_TFOFFSET
MOVL *-SP[STK_TFPTR], XAR3
;;--------------------------------------------------
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the 2nd set of butterflies used in
;; the 1st of the combined stages
;; Second Butterfly offset for stage s & s+1
;; = 2 * input_separation = 2 * 2 * 2^(s-1)
;; For Stage 3 & 4 = 2 * 2 * 2^(3-1) = 16
;; For Stage 5 & 6 = 2 * 2 * 2^(5-1) = 64
;; For Stage 7 & 8 = 2 * 2 * 2^(7-1) = 256
;; And so on ...
;;
MOVL XAR4, XAR2
ADDB XAR4, #S34_GROUPSEP ; I2:R2 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;Outer loop
;; For Stage s & s+1, combined
;; no_of_inner_but = 2^(s-1) = 2^(3-1) = 4
;; no_of_outer_loop = size/(2*no_of_inner_but*2)-1 = 32/(2*4*2) = 2-1 = 1
MOVL XAR5, #S34_OUTER_LOOP_COUNT ; Initialize outer loop counter
; used in BANZ
;;-------------------------------------------------------------------------
_ICFFT_run32Pt_stages3and4OuterLoop:
MOVL XAR3, *-SP[STK_TFPTR] ; Reset the twiddle factor table pointer
;.lp_amode ; override assembler mode to C28x + C2xLP sysntax
;SETC AMODE ; set AMODE to C2xLP addressing
; Inner Butterfly Loop
VMOV32 VR5, *+XAR4[AR1] ; VR5 = I3:R3
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VMOV32 VR7, *XAR4++ ; VR7 = I2:R2
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VCFFT1 VR2, VR5, VR4 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1): R3*Cos(1) + I3*Sin(1)]
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #0 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1): R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H : R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H : R2 - VR2L]
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _ICFFT_run32Pt_stages3and4InnerLoop, #S34_INNER_LOOP_COUNT
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #0 ; VR5 = I3:R3
|| VMOV32 VR5, *+XAR4[AR1] ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2): R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H : R0 + VR2L]
;[VR3H:VR3L] = [I1':R1'] = [I0 - VR2H : R0 - VR2L]
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VCFFT4 VR4, VR2, VR1, VR0, #0 ; VR7 = I2:R2
|| VMOV32 VR7, *XAR4++ ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2): I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0'':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2'] = [I0' - VR2H: R0' - VR2L]
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VMOV32 *XAR6++, VR0 ; [I0'':R0''] = VR0
VCFFT5 VR5, VR4, VR3, VR2, VR1, VR0, #0 ;[I2'':R2''] = VR1
|| VMOV32 *XAR7++, VR1 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1):R3*Cos(1) + I3*Sin(1)]
;[VR0H:VR0L] = [I1':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I1' + VR2H: R1' - VR2L]
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VMOV32 *+XAR6[AR0], VR0 ;[I1'':R1''] = VR0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #0 ;[I3'':R3''] = VR1
|| VMOV32 *+XAR7[AR0], VR1 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1):R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H: R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H: R2 - VR2L]
_ICFFT_run32Pt_stages3and4InnerLoop:
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #0 ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2):R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H: R0 + VR2L]
;[VR1H:VR1L] = [I1':R1'] = [I0 - VR2H: R0 - VR2L]
NOP
VCFFT4 VR4, VR2, VR1, VR0, #0 ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2):I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2''] = [I0' - VR2H: R0' - VR2L]
NOP
VMOV32 *XAR6++, VR0 ;[I0'':R0''] = VR0
VCFFT6 VR3, VR2, VR1, VR0, #0 ;[I2'':R2''] = VR1
|| VMOV32 *XAR7++, VR1 ;[VR0H:VR0L] = [I1'':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3'':R3''] = [I1' + VR2H: R1' - VR2L]
NOP
VMOV32 *+XAR6[AR0], VR0 ;[I1'':R1''] = VR0
VMOV32 *+XAR7[AR0], VR1 ;[I3'':R3''] = VR1
;;--------------------------------------------------
;;Increment all these pointers with 2 * 3*2^(s-1)
;;for Stage 3 & 4, increment by 2 * 3 * 2^(3-1) = 24
;;for Stage 5 & 6, increment by 2 * 3 * 2^(5-1) = 96
;;for Stage 7 & 8, increment by 2 * 3 * 2^(7-1) = 384
ADDB XAR2, #S34_POST_INCREMENT
ADDB XAR4, #S34_POST_INCREMENT
ADDB XAR6, #S34_POST_INCREMENT
ADDB XAR7, #S34_POST_INCREMENT
;;--------------------------------------------------
BANZ _ICFFT_run32Pt_stages3and4OuterLoop, AR5--
_ICFFT_run32Pt_stages3and4CombinedEnd:
;.c28_amode ; change the assembler mode back to C28x
;CLRC AMODE ; set AMODE back to C28x addressing
; C28_AMODE allows *XARn[#3bit] addressing
; Stage 1 & 2 require AMODE others dont
;;=============================================================================
;;
;; Stage 5
;;
;; Notes:
;; - These stages will use twiddle factors from the table, which are organized
;; as follows.
;; exp(2*pi*k1/N5) , k1 = {0,1,...N5-1}, N5 = 2^5
;; - Stage 5 is affected by the SHR or SHL modifiers, results from all
;; operations are shifted right by SHR or left by SHL values
;; - XAR2, the pointer to the inputs, now points to the input buffer
;; - This stage uses the VCMPY instruction that is dependent on the CPACK
;; bit, ensure that the CPACK bit = 1 i.e the low word is real
;; - This single stage changes the SHR and SHL values
;;
;; Register Usage:
;; XAR0: butterfly lower output storage offset
;; XAR1: butterfly lower input storage offset (output offset 1st bfly only)
;; XAR2: pointer to even inputs(output of previous stage)
;; XAR4: pointer to structure(not used in the calculations)
;; XAR6: pointer to twiddle factors
;;
;; Stage n
;; --XAR2-------------o----*-------XAR3--->
;; \ /
;; \/
;; /\
;; / \
;; --XAR2[AR1]---XAR6-o----*---XAR3[AR0]--->
;;
;;
_ICFFT_run32Pt_stage5:
;; local defines
S5_INPUT_OFFSET .set ARG_INBUFFER
S5_OUTPUT_OFFSET .set ARG_OUTBUFFER
S5_NBFLYS .set 1<<(STAGE5-1) ; Number of butterflys per group (2^(s-1))
S5_NGROUPS .set NSAMPLES/(2*S5_NBFLYS)
; Number of groups for this stage
S5_IOSEP .set 2*(S5_NBFLYS)-2 ; Input/Output Seperation = (NBFLYs) * 2(size of complex inputs)
; we add this offset to an incremented pointer hence the -2
S5_LOOP_COUNT .set S5_NBFLYS-4 ; Repeat over the number of butterflies-3
; (first, second and last bfly done outside the loop & RPTB loops n+1 times)
VSETSHR #15 ; SHR=15, do not divide by 2
;VSETSHR #16 ; SHR=16, scales down for VCADD/SUB operations
VSETSHL #15 ; SHR=15, scales down for VCADD/SUB operations
; The rest are set at the beginning of combined stages 1 & 2
;VRNDON ; RND=1, turns on rounding during conversion from Q30 to Q15
;VSATON ; Turn ON Saturation
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the input data array
;; Note that previous stage's output array is input for this stage
MOVL XAR4, *-SP[STK_ARG_PTR] ; Restore the pointer argument to XAR4
MOVL XAR2, *+XAR4[S5_INPUT_OFFSET] ; XAR2 -> I0:R0 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;; For stage s & s+1
;; These are the separation index for inputs and outputs
;; input_separation = 2* 2^(s-1)
;; For Stage 3 & 4, input_separation = 2 * 2^(3-1) = 8
;; For Stage 5 & 6, input_separation = 2 * 2^(5-1) = 32
;; For Stage 7 & 8, input_separation = 2 * 2^(7-1) = 128
;; And so on ....
MOVL XAR1, #S5_IOSEP
MOVL XAR0, #(S5_IOSEP+2) ; AR0 = N/2
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the output of the butterfly.
;; Note that the input buffer of the previous stage is used as output
;; buffer for this stage due to ping-pong scheme
MOVL XAR3, *+XAR4[S5_OUTPUT_OFFSET] ; XAR3 -> output
; I0':R0' pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;Initialize this pointer to the begining of the twiddle-factor
;;table for stage
;;For Stage 3 & 4: 0 to [0 + 4 * 2^(3-1) - 1] = 0 to 15
;;For Stage 5 & 6: 16 to [16 + 4 * 2^(5-1) - 1] = 16 to 79
;;For Stage 7 & 8: 80 to [80 + 4 * 2^(7-1) - 1] = 80 to 335
;;And so on ....
MOVL XAR6, #_vcu0_twiddleFactors
;ADDB XAR6, #S5_TFOFFSET
;MOVL *-SP[STK_TFPTR], XAR6
;Dont need to reset twiddle factor table pointer in single stages
;;-------------------------------------------------------------------------
VMOV32 VR4, *XAR2++ ; VR4 = I0:R0
VMOV32 VR1, *+XAR2[AR1] ; VR1 = I1:R1
VMOV32 VR0, *XAR6++ ; VR0 = Sin(1):Cos(1)
VCMPY VR3, VR2, VR1, VR0 ; VR0 = Sin(2):Cos(2)
|| VMOV32 VR0, *XAR6++ ; VR2 = I1*Cos(1) + R1*Sin(1)
; VR3 = R1*Cos(1) - I1*Sin(1)
NOP ; (delay slot of VCMPY)
VCDSUB16 VR6, VR4, VR3, VR2 ;[VR6H:VR6L] = [(I0<<SHL VR2)>>SHR : (R0<<SHL - VR3)>>SHR]
VCDADD16 VR5, VR4, VR3, VR2 ; VR4 = I0:R0 (next butterfly)
|| VMOV32 VR4, *XAR2++ ;[VR5H:VR5L] = [(I0<<SHL + VR2)>>SHR : (R0<<SHL + VR3)>>SHR]
VMOV32 VR1, *+XAR2[AR1] ; VR1 = I1:R1 (next butterfly)
VCMPY VR3, VR2, VR1, VR0 ;[I0':R0'] = VR5
|| VMOV32 *XAR3++, VR5 ; VR2 = I1*Cos(n) + R1*Sin(n)
; VR3 = R1*Cos(n) - I1*Sin(n)
VMOV32 *+XAR3[AR1], VR6 ; [I1':R1'] = VR6
; Store the DC element at the 0th location
ADDB XAR3, #S5_IOSEP ; Set the output pointer to the half way point XAR3 -> X(N/2)
; Store all subsequent points in the reverse order
VCDSUB16 VR6, VR4, VR3, VR2 ; VR0 = Sin(n):Cos(n)
|| VMOV32 VR0, *XAR6++ ;[VR6H:VR6L] = [(I0<<SHL VR2)>>SHR : (R0<<SHL - VR3)>>SHR]
VCDADD16 VR5, VR4, VR3, VR2 ; VR4 = I0:R0 (next butterfly)
|| VMOV32 VR4, *XAR2++ ;[VR5H:VR5L] = [(I0<<SHL + VR2)>>SHR : (R0<<SHL + VR3)>>SHR]
VMOV32 VR1, *+XAR2[AR1] ; VR1 = I1:R1 (next butterfly)
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _ICFFT_run32Pt_stage5Loop, #S5_LOOP_COUNT
VCMPY VR3, VR2, VR1, VR0 ;[I1':R1'] = VR6
|| VMOV32 *--XAR3, VR6 ; VR2 = I1*Cos(n) + R1*Sin(n)
; VR3 = R1*Cos(n) - I1*Sin(n)
VMOV32 *+XAR3[AR0], VR5 ;[I0':R0'] = VR5
VCDSUB16 VR6, VR4, VR3, VR2 ; VR0 = Sin(n):Cos(n)
|| VMOV32 VR0, *XAR6++ ;[VR6H:VR6L] = [(I0<<SHL VR2)>>SHR : (R0<<SHL - VR3)>>SHR]
VCDADD16 VR5, VR4, VR3, VR2 ; VR4 = I0:R0 (next butterfly)
|| VMOV32 VR4, *XAR2++ ;[VR5H:VR5L] = [(I0<<SHL + VR2)>>SHR : (R0<<SHL + VR3)>>SHR]
VMOV32 VR1, *+XAR2[AR1] ; VR1 = I1:R1 (next butterfly)
_ICFFT_run32Pt_stage5Loop:
VCMPY VR3, VR2, VR1, VR0 ;[I1':R1'] = VR6
|| VMOV32 *--XAR3, VR6 ; VR2 = I1*Cos(n) + R1*Sin(n)
; VR3 = R1*Cos(n) - I1*Sin(n)
VMOV32 *+XAR3[AR0], VR5 ;[I0':R0'] = VR5
VCDSUB16 VR6, VR4, VR3, VR2 ;[VR6H:VR6L] = [(I0<<SHL VR2)>>SHR : (R0<<SHL - VR3)>>SHR]
VCDADD16 VR5, VR4, VR3, VR2 ;[VR5H:VR5L] = [(I0<<SHL + VR2)>>SHR : (R0<<SHL + VR3)>>SHR]
VMOV32 *--XAR3, VR6 ;[I1':R1'] = VR6
VMOV32 *+XAR3[AR0], VR5 ;[I0':R0'] = VR5
;;=============================================================================
ICFFT_CONTEXT_RESTORE
LRETR
;; End of file
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,847 @@
;;*****************************************************************************
;;! \file source/vcu2/vcu2_icfft_64.asm
;;!
;;! \brief 64-pt complex inverse FFT
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
;;
;;*****************************************************************************
;; global defines
;;*****************************************************************************
;; FFT Routine defines
NSTAGES .set 6
NSAMPLES .set (1 << NSTAGES)
NSKIP .set 2*(512 / NSAMPLES) ;vcu0 largest table is stage9 i.e. 512 twiddles(used in unpack)
;the 2 in the numerator is for the size of the twiddle in words
STAGE1 .set 1
STAGE3 .set 3
STAGE5 .set 5
STAGE7 .set 7
;; Argument structure defines
ARG_INBUFFER .set 0
ARG_OUTBUFFER .set 2
ARG_TFTABLE .set 4
ARG_NSAMPLES .set 6
ARG_NSTAGES .set 7
ARG_TFSKIP .set 8
;; Stack defines
;;
;; |_______|
;; |_______|<- Stack Pointer(SP) <---SP
;; |_______|<- STK_ARG_PTR (SP-2)
;; |_______|<- STK_TFPTR (SP-4)
;;
LOCAL_FRAME_SIZE .set 4
STK_ARG_PTR .set 2
STK_TFPTR .set 4
;;*****************************************************************************
;; macros
;;*****************************************************************************
;;
;; MACRO : 'ICFFT_CONTEXT_SAVE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on entry into FFT routine
;;
ICFFT_CONTEXT_SAVE .macro
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #LOCAL_FRAME_SIZE ; allocate stack space for local frame
.endm
;;
;; MACRO : 'ICFFT_CONTEXT_RESTORE'
;; SIZE : Number of WORDS/Number of Cycles 14
;; USAGE : Called on exit from FFT routine
;;
ICFFT_CONTEXT_RESTORE .macro
SUBB SP, #LOCAL_FRAME_SIZE ; deallocate stack space for local frame
POP XAR3
POP XAR2
POP XAR1
.endm
;;*****************************************************************************
;; globals
;;*****************************************************************************
.global _ICFFT_run64Pt
.ref _vcu0_twiddleFactors
.ref _vcu2_twiddleFactors
;;*****************************************************************************
;; function definitions
;;*****************************************************************************
.text
;;
;; \brief Calculate the 64 pt Complex Inverse FFT
;;
;; \param Handle to the structure, ICFFT_Obj(passed in XAR4)
;; - *+XAR4[0]: int16_t *pInBuffer -> input pointer
;; - *+XAR4[2]: int16_t *pOutBuffer -> work(Output) buffer pointer
;; - *+XAR4[4]: int16_t *pTwiddleFactors-> twiddle factor table pointer
;; - *+XAR4[6]: int16_t nSamples-> Number of data points
;; - *+XAR4[7]: int16_t nStages-> Number of FFT stages
;; - *+XAR4[8]: int16_t twiddleSkipStep-> Twiddle factor table search step
;;
;; \note
;; - This algorithm works on two buffers of size 2*N(32-bit complex) in ping-pong fashion
;; - N must be a power of 2 for this algorithm
;; - Must be of size N >= 16(2^4)
;; - Assumes CPACK=1 style complex packing i.e. [Lo:Hi] => [Real:Imag], CPACK bit is ignored
;; - Sign extension is automatically done for right shift operations
;; - VSTATUS.RND=1, rounding is done for the right shift operation
;; - OVFR is set if signed overflow is detected for add/sub calculation in which destination is VRxL
;; - OVFI is set if signed overflow is detected for add/sub calculation in which destination is VRxH
;; - 16-bit signed results (before the shift right) are saturated if SAT = 1
;; - Make sure that input and output buffer pointer points to two diffrent
;; RAM blocks to avoid arbitration between reads and writes
;;
;; \return FFT of the input in the output buffer pointed to by ICFFT_Obj.pOutBuffer
;;
_ICFFT_run64Pt:
ICFFT_CONTEXT_SAVE
MOVL *-SP[STK_ARG_PTR], XAR4
;; Computation Prep
VSETCPACK ; Set the CPACK bit to 1
;SETC SXM ; sign extension mode
; ISS says SXM is automatically done so check that it is
VSATON ; Turn ON Saturation
;;
;; Stages 1 and 2 Combined
;;
;; Notes:
;; - These stages use trivial twiddle factors: 1,-1,j and -j.
;; - C27x AMODE is required in this stage to facilitate the use of
;; the bit-reversed addressing mode with simultaneous ARP update i.e
;; VMOV32 mem32,VRx,ARPn
;; - Setting up the bit-reversed index in AR0
;; Assume N = 64, Since we have complex data its 2N or
;; 128(2^7) words to index i.e. we need 7 bits to address all locations(0-127)
;; we represent 1 as : b'0000001' -> 0x0001
;; bit reversed 1 as : b'1000000' -> 0x0040
;; N represented in hex is already 0x0040, so we load this directly to AR0
;; - Stages 1 and 2 arent affected by the SHR or SHL modifiers, results from all
;; operations are shifted right by 1 bit
;;
;; Register Usage:
;; XAR0: offset address(bit-reversed indexing)
;; XAR1: output storage pointer
;; XAR2: input pointer
;;
;; Stage 1 Stage 2
;; --XAR1,*BR0++---o----*-----o--------*--XAR2++-->
;; \ / \ /
;; \/ \ /
;; /\ \ /
;; / \ \/
;; --XAR1,*BR0++---o----*-----o---/\---*--XAR2++--->
;; \ / \ /
;; \ \
;; / \ / \
;; --XAR1,*BR0++---o----*-----o---\/---*--XAR2++-->
;; \ / /\
;; \/ / \
;; /\ / \
;; / \ / \
;; --XAR1,*BR0++---o----*-----o--------*--XAR2++--->
;;
_ICFFT_run64Pt_stages1and2Combined:
;; local defines
S12_NBFLY .set (NSAMPLES / (2*2)) ; Number of 2x2 butterflies
S12_LOOP_COUNT .set S12_NBFLY - 2 ; Stage 1/2 loop count
MOVZ AR0, *+XAR4[ARG_NSAMPLES] ; AR0 := bit-reversed index 1
MOVL XAR2, *+XAR4[ARG_INBUFFER] ; XAR2 -> input buffer
MOVL XAR1, *+XAR4[ARG_OUTBUFFER] ; XAR1 -> output buffer
.lp_amode ; override assembler mode to C28x + C2xLP sysntax
SETC AMODE ; set AMODE to C2xLP addressing
NOP *,ARP2 ; ARP -> XAR2
VMOV32 VR0, *BR0++ ; VR0 := *(AR2 bradd AR0++) | VR0 := I0:R0
VMOV32 VR1, *BR0++ ; VR1 := *(AR2 bradd AR0++) | VR1 := I1:R1
VCFFT7 VR1, VR0, #0 ; VR2 = I2:R2 <- XAR1
|| VMOV32 VR2, *BR0++ ;[VR0H:VR0L] := [R0 - R1:R0 + R1] := [VR0L - VR1L:VR0L + VR1L]
;[VR1H:VR1L] := [I0 - I1:I0 + I1] := [VR0H - VR1H:VR0H + VR1H]
VMOV32 VR3, *BR0++ ; VR3 := I3:R3 <- XAR1
VCFFT8 VR3, VR2, #0 ;[VR2H:VR2L] := [R2 - R3:R2 + R3] := [VR2L - VR3L:VR2L + VR3L]
;[VR3H:VR3L] := [I2 - I3:I2 + I3] := [VR2H - VR3H:VR2H + VR3H]
VCFFT9 VR5, VR4, VR3, VR2, VR1, VR0, #0 ;[VR4H:VR4L] := [I0':R0'] := [(I0+I1) + (I2+I3):(R0+R1) + (R2+R3)] := [VR1L + VR3L:VR0L + VR2L]
;[VR5H:VR5L] := [I2':R2'] := [(I0+I1) - (I2+I3):(R0+R1) - (R2+R3)] := [VR1L VR3L:VR0L VR2L]
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _ICFFT_run64Pt_stages1and2CombinedLoop, #S12_LOOP_COUNT
VCFFT10 VR7, VR6, VR3, VR2, VR1, VR0, #0 ; VR0 := I0:R0 <- *(AR2 bradd AR0++)
|| VMOV32 VR0, *BR0++ ;[VR6H:VR6L] := [I1':R1'] := [(I0-I1) - (R2-R3):(R0-R1) + (I2-I3)] := [VR1H VR2H:VR0H + VR3H]
;[VR7H:VR7L] := [I3':R3'] := [(I0-I1) + (R2-R3):(R0-R1) - (I2-I3)] := [VR1H + VR2H:VR0H VR3H]
VMOV32 VR1, *BR0++ ; VR1 := I1:R1 <- *(AR2 bradd AR0++)
VCFFT7 VR1, VR0, #0 ; VR2 := I2:R2 <- *(AR2 bradd AR0++)
|| VMOV32 VR2, *BR0++ ;[VR0H:VR0L] := [R0 - R1:R0 + R1] := [VR0L - VR1L:VR0L + VR1L]
;[VR1H:VR1L] := [I0 - I1:I0 + I1] := [VR0H - VR1H:VR0H + VR1H]
VMOV32 VR3, *BR0++ ; VR3 := I3:R3 <- *(AR2 bradd AR0++)
VCFFT8 VR3, VR2, #0 ; Save I0':R0' -> XAR1
|| VMOV32 *XAR1++, VR4 ;[VR2H:VR2L] := [R2 - R3:R2 + R3] := [VR2L - VR3L:VR2L + VR3L]
;[VR3H:VR3L] := [I2 - I3:I2 + I3] := [VR2H - VR3H:VR2H + VR3H]
VMOV32 *XAR1++, VR6 ; Save I1':R1' -> XAR1
VCFFT9 VR5, VR4, VR3, VR2, VR1, VR0, #0 ; Save I2':R2' -> XAR1
|| VMOV32 *XAR1++, VR5 ;[VR4H:VR4L] := [I0':R0'] := [(I0+I1) + (I2+I3):(R0+R1) + (R2+R3)] := [VR1L + VR3L:VR0L + VR2L]
;[VR5H:VR5L] := [I2':R2'] := [(I0+I1) - (I2+I3):(R0+R1) - (R2+R3)] := [VR1L VR3L:VR0L VR2L]
VMOV32 *++, VR7, ARP2 ; Save I3':R3' -> XAR1 | ARP -> XAR2
;VMOV32 *XAR1++, VR7, ARP2 ; Save I3':R3' -> XAR1 | ARP -> XAR2
;this form causes ARP to be XAR1 not XAR2
_ICFFT_run64Pt_stages1and2CombinedLoop:
VCFFT10 VR7, VR6, VR3, VR2, VR1, VR0, #0 ;[VR6H:VR6L] := [I1':R1'] := [(I0-I1) - (R2-R3):(R0-R1) + (I2-I3)] := [VR1H VR2H:VR0H + VR3H]
;[VR7H:VR7L] := [I3':R3'] := [(I0-I1) + (R2-R3):(R0-R1) - (I2-I3)] := [VR1H + VR2H:VR0H VR3H]
VMOV32 *XAR1++, VR4 ; Save I0':R0' -> XAR1
VMOV32 *XAR1++, VR6 ; Save I1':R1' -> XAR1
VMOV32 *XAR1++, VR5 ; Save I2':R2' -> XAR1
VMOV32 *XAR1++, VR7 ; Save I3':R3' -> XAR1
_ICFFT_run64Pt_stages1and2CombinedEnd:
.c28_amode ; change the assembler mode back to C28x
CLRC AMODE ; set AMODE back to C28x addressing
; C28_AMODE allows *XARn[#3bit] addressing
;;=============================================================================
;;
;; Stages 3 and 4 Combined
;;
;; Notes:
;; - These stages will use twiddle factors from the table, which are organized
;; as follows. Twiddles for stages 3 and 4 are interleaved
;; exp(2*pi*k1/N3) , k1 = {0,1,...N3/2-1}, N3 = 2^3
;; exp(2*pi*k2/N4) , k2 = {0,1,...N3/2-1}, N4 = 2^4
;; Cos(2*pi* 0/ 8) : Sin(2*pi* 0/ 8)
;; Cos(2*pi* 0/ 16) : Sin(2*pi* 0/ 16)
;; Cos(2*pi* 1/ 8) : Sin(2*pi* 1/ 8)
;; Cos(2*pi* 1/ 16) : Sin(2*pi* 1/ 16)
;; Cos(2*pi* 2/ 8) : Sin(2*pi* 2/ 8)
;; Cos(2*pi* 2/ 16) : Sin(2*pi* 2/ 16)
;; Cos(2*pi* 3/ 8) : Sin(2*pi* 3/ 8)
;; Cos(2*pi* 3/ 16) : Sin(2*pi* 3/ 16)
;;
;; - Stages 3 and 4 are affected by the SHR or SHL modifiers, results from all
;; operations are shifted right by SHR or left by SHL values
;; - XAR2, the output buffer from the previous stage is now the input to this stage
;;
;; Register Usage:
;; XAR0: butterfly lower ouput storage offset
;; XAR1: butterfly lower input storage offset
;; XAR2: pointer to even inputs(output of previous stage)
;; XAR3: pointer to twiddle factors
;; XAR4: pointer to odd inputs(output of previous stage)
;; XAR5: loop variable
;; XAR6: pointer to even outputs
;; XAR7: pointer to odd outputs
;;
;; Stage n Stage n+1
;; --XAR2-------------o----*---------o--------*------XAR6--->
;; \ / \ /
;; \/ \ /
;; /\ \ /
;; / \ \/
;; --XAR2[AR1]---XAR3-o----*---------o---/\---*--XAR6[AR0]--->
;; \ / \ /
;; \ \
;; / \ / \
;; --XAR4-------------o----*---XAR3--o---\/---*------XAR7--->
;; \ / /\
;; \/ / \
;; /\ / \
;; / \ / \
;; --XAR4[AR1]---XAR3-o----*---XAR3--o--------*--XAR7[AR0]--->
;;
_ICFFT_run64Pt_stages3and4Combined:
;; local defines
S34_INPUT_OFFSET .set ARG_OUTBUFFER
S34_OUTPUT_OFFSET .set ARG_INBUFFER
S34_NBFLYS .set 1<<(STAGE3-1) ; Number of butterflys per group (2^(s-1))
S34_NGROUPS .set NSAMPLES/(2*S34_NBFLYS)
; Number of groups for this stage
S34_INSEP .set 2*(S34_NBFLYS) ; Input Seperation = (NBFLYs) * 2(size of complex inputs)
S34_OUTSEP .set S34_INSEP-2 ; Output Seperation
S34_GROUPSEP .set 4*S34_NBFLYS ; Seperation between the groups = NBFLYs * 2(inputs per butterfly) * 2(size of complex inputs)
S34_TFOFFSET .set 0 ; Twiddle factor table offset for stages 3 and 4
S56_TFOFFSET .set S34_TFOFFSET+4*S34_NBFLYS
; Twiddle factor table offset for stages 5 and 6
S34_INNER_LOOP_COUNT .set S34_NBFLYS-2 ; Repeat over the number of butterflies-2(last bfly done outside the loop, RPTB loops n+1 times)
S34_OUTER_LOOP_COUNT .set NSAMPLES/(4*S34_NBFLYS) - 1
; Outer loop count = N/(2(inputs per bfly)*2(words/input)*NBFLYS) - 1
S34_POST_INCREMENT .set 2*3*S34_NBFLYS ; Post-increment for all the data pointers
VSETSHR #15 ; SHR=15, does Q30 to Q15 conversion for VCFFTx Multiplications
VRNDON ; RND=1, turns on rounding during conversion from Q30 to Q15
;VSATON ; Turn ON Saturation
;; XAR2 XAR6
;; ---+-+----o--*---+----o-----*-----++-o-----------*--------o-----------------------*--+----------+-->>
;; G1| 2 \/ | \ / || \ / \ / . |
;; | | /\ | \ / || \ / \ / .XAR6++ |
;; ---+-v----o--*---|----o--X--*-----||-o--\-----/--*--------o--------------------/--*--+----------|-->>
;; 4 \/ \/ || \ \ / / \ \ / / | |
;; | /\ /\ 8| \ \ / / \ \ / / | |
;; ---+------o--*---v----o--X--*-----||-o--\--X--/--*--------o--\--------------/--/--*--6----------|-->>
;; G2| \/ / \ A| \ \/ \/ / \ \ \ / / / | |
;; | /\ / \ R| \ /\ /\ / \ \ \ / / / A |
;; ---+------o--*--------o-----*-----1|-o--X--X--X--*--------o--\--\--------/--/--/--*--R----------|-->>
;; || \/ \/ \/ \/ \ \ \ \ / / / / 0 |
;; XAR2[AR1]|| /\ /\ /\ /\ \ \ \ \ / / / / |XAR6[AR0] |
;; ---+------o--*--------o-----*-----v|-o--X--X--X--*--------o--\--\--\--X--/--/--/--*--v----------|-->>
;; G3| \/ \ / | / \/ \/ \ \ \ \ \/ \/ / / / |
;; | /\ \ / 16 / /\ /\ \ \ \ \ /\ /\ / / / 16
;; ---+------o--*--------o--X--*------|-o--/--X--\--*--------o--\--\--X--X--X--/--/--*-------------|-->>
;; \/ \/ | / / \ \ \ \ \/ \/ \/ \/ / / |
;; /\ /\ | / / \ \ \ \ /\ /\ /\ /\ / / |
;; ---+------o--*--------o--X--*------|-o--/-----\--*--------o--\--X--X--X--X--X--/--*-------------|-->>
;; G4| \/ / \ | / \ \ \/ \/ \/ \/ \/ \/ / |
;; | /\ / \ | / \ \ /\ /\ /\ /\ /\ /\ / |
;; ---+------o--*--------o-----*------|-o-----------*--------o--X--X--X--X--X--X--X--*-------------|-->>
;; | \/ \/ \/ \/ \/ \/ \/ \/ |
;; XAR4 | /\ /\ /\ /\ /\ /\ /\ /\ XAR7 |
;; ---+-+----o--*---+----o-----*-----+v-o-----------*--------o--X--X--X--X--X--X--X--*--+----------v-->>
;; G5| 2 \/ | \ / | \ / / \/ \/ \/ \/ \/ \/ \ .
;; | | /\ | \ / | \ / / /\ /\ /\ /\ /\ /\ \ .XAR7++
;; ---+-v----o--*---|----o--X--*-----|--o--\-----/--*--------o--/--X--X--X--X--X--\--*--+------------->>
;; 4 \/ \/ | \ \ / / / / \/ \/ \/ \/ \ \ |
;; | /\ /\ 8 \ \ / / / / /\ /\ /\ /\ \ \ 6
;; ---+------o--*---v----o--X--*-----|--o--\--X--/--*--------o--/--/--X--X--X--\--\--*--|------------->>
;; G6| \/ / \ A \ \/ \/ / / / / \/ \/ \ \ \ A
;; | /\ / \ R \ /\ /\ / / / / /\ /\ \ \ \ R
;; ---+------o--*--------o-----*-----1--o--X--X--X--*--------o--/--/--/--X--\--\--\--*--0------------->>
;; | \/ \/ \/ \/ / / / / \ \ \ \ |
;; XAR4[AR1]| /\ /\ /\ /\ / / / / \ \ \ \ |XAR7[AR0]
;; ---+------o--*--------o-----*-----v--o--X--X--X--*--------o--/--/--/-----\--\--\--*--v------------->>
;; G7| \/ \ / / \/ \/ \ / / / \ \ \
;; | /\ \ / / /\ /\ \ / / / \ \ \
;; ---+------o--*--------o--X--*--------o--/--X--\--*--------o--/--/-----------\--\--*---------------->>
;; \/ \/ / / \ \ / / \ \
;; /\ /\ / / \ \ / / \ \
;; ---+------o--*--------o--X--*--------o--/-----\--*--------o--/-----------------\--*---------------->>
;; G8| \/ / \ / \ / \
;; | /\ / \ / \ / \
;; ---+------o--*--------o-----*--------o-----------*--------o-----------------------*---------------->>
;; S1 S2 S3 S4
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the input data array at
;; the begining of every s & s+1 stage calculation.
;; Note that previous stage's output array is input for this stage
;MOVL XAR4, *-SP[STK_ARG_PTR] ; Restore the pointer argument to XAR4
; XAR4 is not used in stage 1 & 2
MOVL XAR2, *+XAR4[S34_INPUT_OFFSET] ; XAR2 -> I0:R0 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;; For stage s & s+1
;; These are the separation index for inputs and outputs
;; input_separation = 2* 2^(s-1)
;; For Stage 3 & 4, input_separation = 2 * 2^(3-1) = 8
;; For Stage 5 & 6, input_separation = 2 * 2^(5-1) = 32
;; For Stage 7 & 8, input_separation = 2 * 2^(7-1) = 128
;; And so on ....
MOVL XAR1, #S34_INSEP
;; ar0 is added with an XARn pointer which is post incremented (+2)
;; and hence ar0 = xar1-2
MOVL XAR0, #S34_OUTSEP
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;This pointer points to the begining of the 1st output of the combined
;; s & s+1 stage butterfly. Note that the input buffer of the previous
;; stage is used as output buffer for this stage due to ping-pong scheme
MOVL XAR6, *+XAR4[S34_OUTPUT_OFFSET] ; XAR6 -> first output
; I0'':R0'' pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;This pointer points to the 3rd output of the combined s & s+1 stage butterfly.
;;This pointer should be initialized as below
;;For Stage 3 & 4 = 2 * 2 * 2^(3-1) = 16
;;For Stage 5 & 6 = 2 * 2 * 2^(5-1) = 64
;;For Stage 7 & 8 = 2 * 2 * 2^(7-1) = 256
;;And so on ...
MOVL XAR7, XAR6
ADDB XAR7, #S34_GROUPSEP ; I2'':R2'' pointer
;;-------------------------------------------------------------------------
;;--------------------------------------------------
;;Initialize this pointer to the begining of the twiddle-factor
;;table for stage s & s+1
;;For Stage 3 & 4: 0 to [0 + 4 * 2^(3-1) - 1] = 0 to 15
;;For Stage 5 & 6: 16 to [16 + 4 * 2^(5-1) - 1] = 16 to 79
;;For Stage 7 & 8: 80 to [80 + 4 * 2^(7-1) - 1] = 80 to 335
;;And so on ....
MOVL XAR3, #_vcu2_twiddleFactors
;;ADDB XAR3, #S34_TFOFFSET
MOVL *-SP[STK_TFPTR], XAR3
;;--------------------------------------------------
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the 2nd set of butterflies used in
;; the 1st of the combined stages
;; Second Butterfly offset for stage s & s+1
;; = 2 * input_separation = 2 * 2 * 2^(s-1)
;; For Stage 3 & 4 = 2 * 2 * 2^(3-1) = 16
;; For Stage 5 & 6 = 2 * 2 * 2^(5-1) = 64
;; For Stage 7 & 8 = 2 * 2 * 2^(7-1) = 256
;; And so on ...
;;
MOVL XAR4, XAR2
ADDB XAR4, #S34_GROUPSEP ; I2:R2 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;Outer loop
;; For Stage s & s+1, combined
;; no_of_inner_but = 2^(s-1) = 2^(3-1) = 4
;; no_of_outer_loop = size/(2*no_of_inner_but*2)-1 = 64/(2*4*2) = 4-1 = 3
MOVL XAR5, #S34_OUTER_LOOP_COUNT ; Initialize outer loop counter
; used in BANZ
;;-------------------------------------------------------------------------
_ICFFT_run64Pt_stages3and4OuterLoop:
MOVL XAR3, *-SP[STK_TFPTR] ; Reset the twiddle factor table pointer
;.lp_amode ; override assembler mode to C28x + C2xLP sysntax
;SETC AMODE ; set AMODE to C2xLP addressing
; Inner Butterfly Loop
VMOV32 VR5, *+XAR4[AR1] ; VR5 = I3:R3
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VMOV32 VR7, *XAR4++ ; VR7 = I2:R2
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VCFFT1 VR2, VR5, VR4 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1): R3*Cos(1) + I3*Sin(1)]
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #0 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1): R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H : R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H : R2 - VR2L]
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _ICFFT_run64Pt_stages3and4InnerLoop, #S34_INNER_LOOP_COUNT
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #0 ; VR5 = I3:R3
|| VMOV32 VR5, *+XAR4[AR1] ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2): R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H : R0 + VR2L]
;[VR3H:VR3L] = [I1':R1'] = [I0 - VR2H : R0 - VR2L]
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VCFFT4 VR4, VR2, VR1, VR0, #0 ; VR7 = I2:R2
|| VMOV32 VR7, *XAR4++ ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2): I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0'':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2'] = [I0' - VR2H: R0' - VR2L]
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VMOV32 *XAR6++, VR0 ; [I0'':R0''] = VR0
VCFFT5 VR5, VR4, VR3, VR2, VR1, VR0, #0 ;[I2'':R2''] = VR1
|| VMOV32 *XAR7++, VR1 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1):R3*Cos(1) + I3*Sin(1)]
;[VR0H:VR0L] = [I1':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I1' + VR2H: R1' - VR2L]
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VMOV32 *+XAR6[AR0], VR0 ;[I1'':R1''] = VR0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #0 ;[I3'':R3''] = VR1
|| VMOV32 *+XAR7[AR0], VR1 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1):R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H: R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H: R2 - VR2L]
_ICFFT_run64Pt_stages3and4InnerLoop:
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #0 ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2):R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H: R0 + VR2L]
;[VR1H:VR1L] = [I1':R1'] = [I0 - VR2H: R0 - VR2L]
NOP
VCFFT4 VR4, VR2, VR1, VR0, #0 ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2):I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2''] = [I0' - VR2H: R0' - VR2L]
NOP
VMOV32 *XAR6++, VR0 ;[I0'':R0''] = VR0
VCFFT6 VR3, VR2, VR1, VR0, #0 ;[I2'':R2''] = VR1
|| VMOV32 *XAR7++, VR1 ;[VR0H:VR0L] = [I1'':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3'':R3''] = [I1' + VR2H: R1' - VR2L]
NOP
VMOV32 *+XAR6[AR0], VR0 ;[I1'':R1''] = VR0
VMOV32 *+XAR7[AR0], VR1 ;[I3'':R3''] = VR1
;;--------------------------------------------------
;;Increment all these pointers with 2 * 3*2^(s-1)
;;for Stage 3 & 4, increment by 2 * 3 * 2^(3-1) = 24
;;for Stage 5 & 6, increment by 2 * 3 * 2^(5-1) = 96
;;for Stage 7 & 8, increment by 2 * 3 * 2^(7-1) = 384
ADDB XAR2, #S34_POST_INCREMENT
ADDB XAR4, #S34_POST_INCREMENT
ADDB XAR6, #S34_POST_INCREMENT
ADDB XAR7, #S34_POST_INCREMENT
;;--------------------------------------------------
BANZ _ICFFT_run64Pt_stages3and4OuterLoop, AR5--
_ICFFT_run64Pt_stages3and4CombinedEnd:
;.c28_amode ; change the assembler mode back to C28x
;CLRC AMODE ; set AMODE back to C28x addressing
; C28_AMODE allows *XARn[#3bit] addressing
; Stage 1 & 2 require AMODE others dont
;;=============================================================================
;;
;; Stages 5 and 6 Combined
;;
;; Notes:
;; - These stages will use twiddle factors from the table, which are organized
;; as follows. Twiddles for stages 5 and 6 are interleaved
;; exp(2*pi*k1/N5) , k1 = {0,1,...N5/2-1}, N5 = 2^5
;; exp(2*pi*k2/N6) , k2 = {0,1,...N5/2-1}, N6 = 2^6
;; - Stages 5 and 6 are affected by the SHR or SHL modifiers, results from all
;; operations are shifted right by SHR or left by SHL values
;; - XAR2, the pointer to the inputs, now points back to the input table
;;
;; Register Usage:
;; XAR0: butterfly lower ouput storage offset
;; XAR1: butterfly lower input storage offset
;; XAR2: pointer to even inputs(output of previous stage)
;; XAR3: pointer to twiddle factors
;; XAR4: pointer to odd inputs(output of previous stage)
;; XAR5: loop variable
;; XAR6: pointer to even outputs
;; XAR7: pointer to odd outputs
;;
;; Stage n Stage n+1 x(0) x(n), n = {1, N-1}
;; --XAR2-------------o----*---------o--------*------XAR6--------XAR7[AR0]---------->
;; \ / \ / ^
;; \/ \ / |
;; /\ \ / AR0 = 2*AR0
;; / \ \/
;; --XAR2[AR1]---XAR3-o----*---------o---/\---*--XAR7[AR0]-------XAR6[AR0]---------->
;; \ / \ /
;; \ \
;; / \ / \
;; --XAR4-------------o----*---XAR3--o---\/---*------XAR7--------XAR7-- ------------>
;; \ / /\
;; \/ / \
;; /\ / \
;; / \ / \
;; --XAR4[AR1]---XAR3-o----*---XAR3--o--------*--XAR6[AR0]-------XAR6-- ------------>
;;
_ICFFT_run64Pt_stages5and6Combined:
;; local defines
S56_INPUT_OFFSET .set ARG_INBUFFER
S56_OUTPUT_OFFSET .set ARG_OUTBUFFER
S56_NBFLYS .set 1<<(STAGE5-1) ; Number of butterflys per group (2^(s-1))
S56_NGROUPS .set NSAMPLES/(2*S56_NBFLYS)
; Number of groups for this stage
S56_INSEP .set 2*(S56_NBFLYS) ; Input Seperation = (NBFLYs) * 2(size of complex inputs)
S56_OUTSEP .set S56_INSEP ; Output Seperation
S56_GROUPSEP .set 4*S56_NBFLYS ; Seperation between the groups = NBFLYs * 2(inputs per butterfly) * 2(size of complex inputs)
S78_TFOFFSET .set S56_TFOFFSET+4*S56_NBFLYS
; Twiddle factor table offset for stages 7 and 8
S56_INNER_LOOP_COUNT .set S56_NBFLYS-3 ; Repeat over the number of butterflies-2(first + last bfly done outside the loop, RPTB loops n+1 times)
S56_OUTER_LOOP_COUNT .set NSAMPLES/(4*S56_NBFLYS) - 1
; Outer loop count = N/(2(inputs per bfly)*2(words/input)*NBFLYS) - 1
S56_POST_INCREMENT .set 2*3*S56_NBFLYS ; Post-increment for all the data pointers
; Set once in stage 3 & 4, dont set again
;VSETSHR #15 ; SHR=15, does Q30 to Q15 conversion for VCFFTx Multiplications
;VRNDON ; RND=1, turns on rounding during conversion from Q30 to Q15
;VSATON ; Turn ON Saturation
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the input data array at
;; the begining of every s & s+1 stage calculation.
;; Note that previous stage's output array is input for this stage
MOVL XAR4, *-SP[STK_ARG_PTR] ; Restore the pointer argument to XAR4
MOVL XAR2, *+XAR4[S56_INPUT_OFFSET] ; XAR2 -> I0:R0 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;; For stage s & s+1
;; These are the separation index for inputs and outputs
;; input_separation = 2* 2^(s-1)
;; For Stage 3 & 4, input_separation = 2 * 2^(3-1) = 8
;; For Stage 5 & 6, input_separation = 2 * 2^(5-1) = 32
;; For Stage 7 & 8, input_separation = 2 * 2^(7-1) = 128
;; And so on ....
MOVL XAR1, #S56_INSEP
;; ar0 is added with an XARn pointer which is post incremented (+2)
;; and hence ar0 = xar1-2
MOVL XAR0, #S56_OUTSEP
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;This pointer points to the begining of the 1st output of the combined
;; s & s+1 stage butterfly. Note that the input buffer of the previous
;; stage is used as output buffer for this stage due to ping-pong scheme
MOVL XAR6, *+XAR4[S56_OUTPUT_OFFSET] ; XAR6 -> first output
; I0'':R0'' pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;This pointer points to the 3rd output of the combined s & s+1 stage butterfly.
;;This pointer should be initialized as below
;;For Stage 3 & 4 = 2 * 2 * 2^(3-1) = 16
;;For Stage 5 & 6 = 2 * 2 * 2^(5-1) = 64
;;For Stage 7 & 8 = 2 * 2 * 2^(7-1) = 256
;;And so on ...
MOVL XAR7, XAR6
ADDB XAR7, #S56_GROUPSEP ; I2'':R2'' pointer
;;-------------------------------------------------------------------------
;;--------------------------------------------------
;;Initialize this pointer to the begining of the twiddle-factor
;;table for stage s & s+1
;;For Stage 3 & 4: 0 to [0 + 4 * 2^(3-1) - 1] = 0 to 15
;;For Stage 5 & 6: 16 to [16 + 4 * 2^(5-1) - 1] = 16 to 79
;;For Stage 7 & 8: 80 to [80 + 4 * 2^(7-1) - 1] = 80 to 335
;;And so on ....
MOVL XAR3, #_vcu2_twiddleFactors
ADDB XAR3, #S56_TFOFFSET
MOVL *-SP[STK_TFPTR], XAR3
;;--------------------------------------------------
;;-------------------------------------------------------------------------
;; This pointer points to the begining of the 2nd set of butterflies used in
;; the 1st of the combined stages
;; Second Butterfly offset for stage s & s+1
;; = 2 * input_separation = 2 * 2 * 2^(s-1)
;; For Stage 3 & 4 = 2 * 2 * 2^(3-1) = 16
;; For Stage 5 & 6 = 2 * 2 * 2^(5-1) = 64
;; For Stage 7 & 8 = 2 * 2 * 2^(7-1) = 256
;; And so on ...
;;
MOVL XAR4, XAR2
ADDB XAR4, #S56_GROUPSEP ; I2:R2 pointer
;;-------------------------------------------------------------------------
;;-------------------------------------------------------------------------
;;Outer loop
;; For Stage s & s+1, combined
;; no_of_inner_but = 2^(s-1) = 2^(3-1) = 4
;; no_of_outer_loop = size/(2*no_of_inner_but*2)-1 = 64/(2*16*2) = 1-1 = 0
; MOVL XAR5, #S56_OUTER_LOOP_COUNT ; Initialize outer loop counter
; used in BANZ
; not required here
;;-------------------------------------------------------------------------
_ICFFT_run64Pt_stages5and6OuterLoop:
MOVL XAR3, *-SP[STK_TFPTR] ; Reset the twiddle factor table pointer
;.lp_amode ; override assembler mode to C28x + C2xLP sysntax
;SETC AMODE ; set AMODE to C2xLP addressing
; Inner Butterfly Loop
VMOV32 VR5, *+XAR4[AR1] ; VR5 = I3:R3
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VMOV32 VR7, *XAR4++ ; VR7 = I2:R2
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VCFFT1 VR2, VR5, VR4 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1): R3*Cos(1) + I3*Sin(1)]
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #0 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1): R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H : R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H : R2 - VR2L]
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #0 ; VR5 = I3:R3
|| VMOV32 VR5, *+XAR4[AR1] ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2): R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H : R0 + VR2L]
;[VR3H:VR3L] = [I1':R1'] = [I0 - VR2H : R0 - VR2L]
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VCFFT4 VR4, VR2, VR1, VR0, #0 ; VR7 = I2:R2
|| VMOV32 VR7, *XAR4++ ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2): I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0'':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2'] = [I0' - VR2H: R0' - VR2L]
NOP
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VMOV32 *+XAR6[0], VR0 ; [I0'':R0''] = VR0
VCFFT5 VR5, VR4, VR3, VR2, VR1, VR0, #0 ;[I2'':R2''] = VR1
|| VMOV32 *+XAR7[0], VR1 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1):R3*Cos(1) + I3*Sin(1)]
;[VR0H:VR0L] = [I1':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I1' + VR2H: R1' - VR2L]
NOP
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VMOV32 *+XAR7[AR0], VR0 ;[I1'':R1''] = VR0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #0 ;[I3'':R3''] = VR1
|| VMOV32 *+XAR6[AR0], VR1 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1):R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H: R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H: R2 - VR2L]
ADDB XAR6, #S56_OUTSEP ; XAR6 += S56_OUTSEP
ADDB XAR0, #(S56_OUTSEP-2) ; AR0 := AR0 + S56_OUTSEP-2(double the offset)
.align 2 ; align at 32-bit boundary to remove penalty
RPTB _ICFFT_run64Pt_stages5and6InnerLoop, #S56_INNER_LOOP_COUNT
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #0 ; VR5 = I3:R3
|| VMOV32 VR5, *+XAR4[AR1] ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2): R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H : R0 + VR2L]
;[VR3H:VR3L] = [I1':R1'] = [I0 - VR2H : R0 - VR2L]
VMOV32 VR6, *+XAR2[AR1] ; VR6 = I1:R1
VCFFT4 VR4, VR2, VR1, VR0, #0 ; VR7 = I2:R2
|| VMOV32 VR7, *XAR4++ ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2): I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0'':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2'] = [I0' - VR2H: R0' - VR2L]
NOP
VMOV32 VR4, *XAR3++ ; VR4 = Sin(1):Cos(1)
VMOV32 *+XAR7[AR0], VR0 ; [I0'':R0''] = VR0
VCFFT5 VR5, VR4, VR3, VR2, VR1, VR0, #0 ;[I2'':R2''] = VR1
|| VMOV32 *--XAR7, VR1 ;[VR2H:VR2L] = [I3*Cos(1) - R3*Sin(1):R3*Cos(1) + I3*Sin(1)]
;[VR0H:VR0L] = [I1':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I1' + VR2H: R1' - VR2L]
NOP
VMOV32 VR5, *XAR2++ ; VR5 = I0:R0
VMOV32 *+XAR6[AR0], VR0 ;[I1'':R1''] = VR0
VCFFT2 VR7, VR6, VR4, VR2, VR1, VR0, #0 ;[I3'':R3''] = VR1
|| VMOV32 *--XAR6, VR1 ;[VR2H:VR2L] = [I1*Cos(1) - R1*Sin(1):R1*Cos(1) + I1*Sin(1)]
;[VR0H:VR0L] = [I2':R2'] = [I2 + VR2H: R2 + VR2L]
;[VR1H:VR1L] = [I3':R3'] = [I2 - VR2H: R2 - VR2L]
_ICFFT_run64Pt_stages5and6InnerLoop:
VMOV32 VR4, *XAR3++ ; VR4 = Sin(2):Cos(2)
VCFFT3 VR5, VR4, VR3, VR2, VR0, #0 ;[VR2H:VR2L] = [I2'*Cos(2) - R2'*Sin(2):R2'*Cos(2) + I2'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0 + VR2H: R0 + VR2L]
;[VR1H:VR1L] = [I1':R1'] = [I0 - VR2H: R0 - VR2L]
NOP
VCFFT4 VR4, VR2, VR1, VR0, #0 ;[VR2H:VR2L] = [R3'*Cos(2) + I3'*Sin(2):I3'*Cos(2) - R3'*Sin(2)]
;[VR0H:VR0L] = [I0':R0'] = [I0' + VR2H: R0' + VR2L]
;[VR1H:VR1L] = [I2'':R2''] = [I0' - VR2H: R0' - VR2L]
NOP
VMOV32 *+XAR7[AR0], VR0 ;[I0'':R0''] = VR0
VCFFT6 VR3, VR2, VR1, VR0, #0 ;[I2'':R2''] = VR1
|| VMOV32 *--XAR7, VR1 ;[VR0H:VR0L] = [I1'':R1'] = [I1' - VR2H: R1' + VR2L]
;[VR1H:VR1L] = [I3'':R3''] = [I1' + VR2H: R1' - VR2L]
NOP
VMOV32 *+XAR6[AR0], VR0 ;[I1'':R1''] = VR0
VMOV32 *--XAR6, VR1 ;[I3'':R3''] = VR1
;;--------------------------------------------------
;;Increment all these pointers with 2 * 3*2^(s-1)
;;for Stage 3 & 4, increment by 2 * 3 * 2^(3-1) = 24
;;for Stage 5 & 6, increment by 2 * 3 * 2^(5-1) = 96
;;for Stage 7 & 8, increment by 2 * 3 * 2^(7-1) = 384
;ADDB XAR2, #S56_POST_INCREMENT
;ADDB XAR4, #S56_POST_INCREMENT
;ADDB XAR6, #S56_POST_INCREMENT
;ADDB XAR7, #S56_POST_INCREMENT
;not required for the last of the combined stages
;;--------------------------------------------------
;BANZ _ICFFT_run64Pt_stages5and6OuterLoop, AR5--
;not required for the last of the combined stages
_ICFFT_run64Pt_stages5and6CombinedEnd:
;.c28_amode ; change the assembler mode back to C28x
;CLRC AMODE ; set AMODE back to C28x addressing
; C28_AMODE allows *XARn[#3bit] addressing
;;=============================================================================
ICFFT_CONTEXT_RESTORE
LRETR
;; End of file
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,275 @@
;;*****************************************************************************
;;! \file source/vcu2/reed_solomon/vcu2_reedsolomon_calcsyndrome.asm
;;!
;;! \brief Calculate the syndromes of the received code using
;;! Horner's method
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
.cdecls C, LIST, "vcu2_types.h", "vcu2_reedsolomon_decoder.h"
;;*****************************************************************************
;; defines
;;*****************************************************************************
;; REEDSOLOMON_DECODER Routine defines
;; Argument structure defines
ARG_N .set 0
ARG_K .set 1
ARG_T .set 2
ARG_NROOTS .set 3
ARG_PSYNDROME .set 4
ARG_PLAMBDA .set 6
ARG_POMEGA .set 8
ARG_PPACKEDALPHA .set 10
ARG_PPACKEDBETA .set 12
ARG_PRSEXPTABLE .set 14
ARG_PRSLOGTABLE .set 16
ARG_PERRLOC .set 18
;; Stack defines
;;
;; |_______|
;; |_______|<- Stack Pointer (SP) <---SP
;; |_______|<- STK_PDATA (SP-2)
;; |_______|<- STK_GFPARAM (SP-4)
;;
LOCAL_FRAME_SIZE .set 4
STK_PDATA .set 2
STK_GFPARAM .set 4
;;*****************************************************************************
;; macros
;;*****************************************************************************
;;
;; MACRO : 'REEDSOLOMON_DECODER_CONTEXT_SAVE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on entry into Reed solomon decoder routine
;;
REEDSOLOMON_DECODER_CONTEXT_SAVE .macro
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #LOCAL_FRAME_SIZE ; allocate stack space for local frame
.endm
;;
;; MACRO : 'REEDSOLOMON_DECODER_CONTEXT_RESTORE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on exit from Reed solomon decoder routine
;;
REEDSOLOMON_DECODER_CONTEXT_RESTORE .macro
SUBB SP, #LOCAL_FRAME_SIZE ; deallocate stack space for local frame
POP XAR3
POP XAR2
POP XAR1
.endm
;;*****************************************************************************
;; globals
;;*****************************************************************************
.global _REEDSOLOMON_DECODER_calcSyndrome
;;*****************************************************************************
;; function definitions
;;*****************************************************************************
.text
;; \brief Syndrome calculation function (Horner's Method)
;;
;; \param[in] hndRSDecoder handle to the Reed Solomon Decoder object
;; - *+XAR4[0]: n ->number of codeword symbols (bytes) in a block
;; - *+XAR4[1]: k ->number of message symbols (bytes) in a block
;; - *+XAR4[2]: t ->number of correctable errors in the block
;; - *+XAR4[3]: nRoots ->number of roots for the code generator polynomial
;; - *+XAR4[4]: *pSyndrome ->pointer to the syndromes
;; - *+XAR4[6]: *pLambda ->pointer to the error locator polynomial coefficients
;; - *+XAR4[8]: *pOmega ->pointer to the error magnitude polynomial coefficients
;; - *+XAR4[10]: *pPackedAlpha ->Pointer to the roots of the code generator polynomial \f$ x + \alpha^{i}\f$
;; - *+XAR4[12]: *pPackedBeta ->Pointer to the first 2t elements of the GF(2^n)
;; - *+XAR4[14]: *pRS_expTable ->Pointer to the lookup table (roots of the extension Galois Field)
;; that converts index to decimal form
;; - *+XAR4[16]: *pRS_logTable ->Pointer to the lookup table (roots of the extension Galois Field)
;; that converts decimal to index form
;; - *+XAR4[18]: *pErrorLoc ->Pointer to the error (location, value) pairs
;;
;; \param[in] pData (XAR5) pointer to the data
;; \param[in] nBytes (AL) number of bytes
;;
_REEDSOLOMON_DECODER_calcSyndrome:
;; Local Defines
CODEGENPOLY .set 0x1D
;;
;; Register Usage:
;; XAR0: Outer loop counter
;; XAR1: index into structure
;; XAR2: number of roots/ polynomial
;; XAR3: pointer to the roots
;; XAR4: pointer to the decoder object
;; XAR5: pointer to the data
;; XAR6: RPTB counter
;; XAR7: Points to syndrome
;; T : number of bytes (n)
;; AH : number of roots
;; AL : number of bytes (n)
REEDSOLOMON_DECODER_CONTEXT_SAVE
MOV AR1, #ARG_PSYNDROME
MOVL XAR7, *+XAR4[AR1]
MOVL *-SP[STK_PDATA], XAR5 ; save off pData
MOV AH, *+XAR4[ARG_NROOTS] ; AH = NROOTS
MOV T, AL ; AL = nBytes
AND T, #0x3 ; nBytes multiple of 4?
LSR AL, 2 ; nBytes >> 2
ADDB AL, #-1
MOVZ AR6, @AL ; AR6 = loop counter
MOVZ AR2, AH ; save T2
LSR AH, #2 ; T2 / 4
SUB AH, #1 ; subtract 1
MOVZ AR0, @AH ; counter for outer loop
MOV AH, AR2 ; reload T2
SUB AH, #1
LSL AH, #8
ADD AH, #CODEGENPOLY ; polynomial = x^8+x^4+x^3+x^2+1
MOV *-SP[STK_GFPARAM], AH ; Save to stack
EDIS
VGFINIT *-SP[STK_GFPARAM] ; Initialize polynomial in VCU2
VCLEARALL ; Clear all VCU Registers
MOV AR1, #ARG_PPACKEDALPHA
MOVL XAR3, *+XAR4[AR1] ; point to root table
_REEDSOLOMON_DECODER_calcSyndrome_outerLoop:
VPACK4 VR0, *XAR5, #0 ; VR0[31:0] = R0_R0_R0_R0 (pack byte 0 of data)
EDIS
VMOV32 VR1, *XAR3++ ; VR1[31:0] = alpha**4, alpha**3, alpha**2, alpha**1
VCLEAR VR2 ; In place of NOP
; Initialize S_0123
;;=============================================================================
;; Computing the syndromes
;;
;; The syndromes are the remainders from dividing the received polynomial
;; (with embedded error) by all the factors (roots) of the code generator poly
;; R(x)/(x + alpha**i) = Q_i(x) + S_i/(x + alpha**i)
;; S_i = Q_i(x)*(x + alpha**i) + R(x)
;; When x = alpha**i we get
;; S_i = R(alpha**i) and this is a number not a polynomial
;; Let a[i] be the ith root alpha**i, T = 2t - 1
;; the array indexing begins from 0 but the first root is alpha**1 (a[0])
;; S_0 = R[N-1]*(a[0])^N-1 + R[N-2]*(a[0])^N-2 + ... + R[0]
;; S_1 = R[N-1]*(a[1])^N-1 + R[N-2]*(a[1])^N-2 + ... + R[0]
;; S_2 = R[N-1]*(a[2])^N-1 + R[N-2]*(a[2])^N-2 + ... + R[0]
;; ...
;; S_T = R[N-1]*(a[T])^N-1 + R[N-2]*(a[T])^N-2 + ... + R[0]
;; S_i = (((R[N-1]*a[i] + R[N-2])a[i] + R[N-3])a[i] + ... + R[0])
;; The operations can be pipelined as follows
;; 0 0 0 0 -> VR2 (accumulator)
;; * a[1] a[2] a[3] a[4] -> VR1 (roots)
;; -------------------------------------------
;; + R[N-1] R[N-1] R[N-1] R[N-1] -> VR0 packed data bytes
;; = -> VR2
;; * a[1] a[2] a[3] a[4] -> VR1 (roots)
;; -------------------------------------------
;; + R[N-2] R[N-2] R[N-2] R[N-2] -> VR0 packed data bytes
;; = -> VR2
;; * a[1] a[2] a[3] a[4] -> VR1 (roots)
;; -------------------------------------------
;; ...
;; + R[1] R[1] R[1] R[1] -> VR0 packed data bytes
;; = -> VR2
;; * a[1] a[2] a[3] a[4] -> VR1 (roots)
;; -------------------------------------------
;; + R[0] R[0] R[0] R[0] -> VR0 packed data bytes
;; = S_1 S_2 S_3 S_4 -> VR2 (packed syndromes)
;;=============================================================================
.align 2
RPTB _REEDSOLOMON_DECODER_calcSyndrome_innerLoop, AR6
VGFMAC4 VR2, VR1, VR0 ; VR2[Bx] = (VR2[Bx]*VR1[Bx])^VR0[Bx]
|| VPACK4 VR0, *+XAR5[0], #1 ; VR0[31:0] = R1_R1_R1_R1 (pack next byte of data)
VGFMAC4 VR2, VR1, VR0 ; VR2[Bx] = (VR2[Bx]*VR1[Bx])^VR0[Bx]
|| VPACK4 VR0, *+XAR5[0], #2 ; VR0[31:0] = R2_R2_R2_R2 (pack next byte of data)
VGFMAC4 VR2, VR1, VR0 ; VR2[Bx] = (VR2[Bx]*VR1[Bx])^VR0[Bx]
|| VPACK4 VR0, *XAR5++, #3 ; VR0[31:0] = R3_R3_R3_R3 (pack next byte of data)
VGFMAC4 VR2, VR1, VR0 ; VR2[Bx] = (VR2[Bx]*VR1[Bx])^VR0[Bx]
|| VPACK4 VR0, *+XAR5[0], #0
NOP
_REEDSOLOMON_DECODER_calcSyndrome_innerLoop:
;;-------------------------------------------------------------------------
;; Process any remaining bytes (n % 4)
;;-------------------------------------------------------------------------
CMP T, #0 ; if no bytes left store syndrome
SBF _REEDSOLOMON_DECODER_calcSyndrome_store, EQ
VGFMAC4 VR2, VR1, VR0
|| VPACK4 VR0, *+XAR5[0], #1 ; one extra byte
CMP T, #1 ; if no bytes left store syndrome
SBF _REEDSOLOMON_DECODER_calcSyndrome_store, EQ
VGFMAC4 VR2, VR1, VR0
|| VPACK4 VR0, *+XAR5[0], #2 ; two extra bytes
CMP T, #2 ; if no bytes left store syndrome
SBF _REEDSOLOMON_DECODER_calcSyndrome_store, EQ
VGFMAC4 VR2, VR1, VR0 ; three extra bytes
;;-------------------------------------------------------------------------
;; store 4 syndromes at a time
;;-------------------------------------------------------------------------
_REEDSOLOMON_DECODER_calcSyndrome_store:
VMOV32 *XAR7++, VR2 ; save to Object->pSyndrome
MOVL XAR5, *-SP[STK_PDATA] ; restore pData
; if all syndromes not done: loop back
BANZ _REEDSOLOMON_DECODER_calcSyndrome_outerLoop, AR0--
; else return
REEDSOLOMON_DECODER_CONTEXT_RESTORE
LRETR
;; End of File
@@ -0,0 +1,382 @@
;;*****************************************************************************
;;! \file source/vcu2/reed_solomon/vcu2_reedsolomon_chienforney.asm
;;!
;;! \brief Chien search and Forney Algorithm
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
.cdecls C, LIST, "vcu2_types.h", "vcu2_reedsolomon_decoder.h"
;;*****************************************************************************
;; defines
;;*****************************************************************************
;; REEDSOLOMON_DECODER Routine defines
;; Argument structure defines
ARG_N .set 0
ARG_K .set 1
ARG_T .set 2
ARG_NROOTS .set 3
ARG_PSYNDROME .set 4
ARG_PLAMBDA .set 6
ARG_POMEGA .set 8
ARG_PPACKEDALPHA .set 10
ARG_PPACKEDBETA .set 12
ARG_PRSEXPTABLE .set 14
ARG_PRSLOGTABLE .set 16
ARG_PERRLOC .set 18
;; Stack defines
;;
;; |_______|
;; |_______|<- Stack Pointer (SP) <---SP
;; |_______|<- STK_PARG (SP-2)
;; |_______|<- STK_DELTA (SP-4)
;; |_______|<- STK_GAMMA (SP-6)
;; |_______|<- STK_ODDPOLY (SP-8)
;; |_______|<- STK_EVENPOLY (SP-10)
;;
LOCAL_FRAME_SIZE .set 10
STK_PARG .set 2
STK_DELTA .set 4
STK_GAMMA .set 6
STK_ODDPOLY .set 8
STK_EVENPOLY .set 10
;;*****************************************************************************
;; macros
;;*****************************************************************************
;;
;; MACRO : 'REEDSOLOMON_DECODER_CONTEXT_SAVE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on entry into Reed solomon decoder routine
;;
REEDSOLOMON_DECODER_CONTEXT_SAVE .macro
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #LOCAL_FRAME_SIZE ; allocate stack space for local frame
.endm
;;
;; MACRO : 'REEDSOLOMON_DECODER_CONTEXT_RESTORE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on exit from Reed solomon decoder routine
;;
REEDSOLOMON_DECODER_CONTEXT_RESTORE .macro
SUBB SP, #LOCAL_FRAME_SIZE ; deallocate stack space for local frame
POP XAR3
POP XAR2
POP XAR1
.endm
;;
;; MACRO : 'GFINV'
;; SIZE : Number of WORDS/Number of Cycles 15
;; USAGE : Galois Field Inversion
;; For any field element x, x^(2^m-1) = 1
;; => inverse of x = x^-1 = x^(2^m-2)
;;
GFINV: .macro
VMOVZI VR0, #1
; 2^m-2 times, this is for m=8
VGFMPY4 VR2, VR2, VR2
VGFMPY4 VR0, VR0, VR2
VGFMPY4 VR2, VR2, VR2
VGFMPY4 VR0, VR0, VR2
VGFMPY4 VR2, VR2, VR2
VGFMPY4 VR0, VR0, VR2
VGFMPY4 VR2, VR2, VR2
VGFMPY4 VR0, VR0, VR2
VGFMPY4 VR2, VR2, VR2
VGFMPY4 VR0, VR0, VR2
VGFMPY4 VR2, VR2, VR2
VGFMPY4 VR0, VR0, VR2
VGFMPY4 VR2, VR2, VR2
VGFMPY4 VR2, VR0, VR2
.endm
;;*****************************************************************************
;; globals
;;*****************************************************************************
.global _REEDSOLOMON_DECODER_chienForney
;;*****************************************************************************
;; function definitions
;;*****************************************************************************
.text
;; \brief Chien Search and Forney's Algorithm
;;
;; This function implements Chien search to find roots
;; of the error locator polynomial and Forney's algorithm to compute error
;; values using the error locator and error evaluator polynomials
;;
;; \param[in] hndRSDecoder handle to the Reed Solomon Decoder object
;; - *+XAR4[0]: n ->number of codeword symbols (bytes) in a block
;; - *+XAR4[1]: k ->number of message symbols (bytes) in a block
;; - *+XAR4[2]: t ->number of correctable errors in the block
;; - *+XAR4[3]: nRoots ->number of roots for the code generator polynomial
;; - *+XAR4[4]: *pSyndrome ->pointer to the syndromes
;; - *+XAR4[6]: *pLambda ->pointer to the error locator polynomial coefficients
;; - *+XAR4[8]: *pOmega ->pointer to the error magnitude polynomial coefficients
;; - *+XAR4[10]: *pPackedAlpha ->Pointer to the roots of the code generator polynomial \f$ x + \alpha^{i}\f$
;; - *+XAR4[12]: *pPackedBeta ->Pointer to the first 2t elements of the GF(2^n)
;; - *+XAR4[14]: *pRS_expTable ->Pointer to the lookup table (roots of the extension Galois Field)
;; that converts index to decimal form
;; - *+XAR4[16]: *pRS_logTable ->Pointer to the lookup table (roots of the extension Galois Field)
;; that converts decimal to index form
;; - *+XAR4[18]: *pErrorLoc ->Pointer to the error (location, value) pairs
;; \param[in] nBytes (AL) number of bytes
;;
_REEDSOLOMON_DECODER_chienForney:
;; Local Defines
;;
;; Register Usage:
;; XAR0: index into the structure
;; XAR1: byte counter
;; XAR2: pointer to the betas
;; XAR3: pointer to the error locations
;; XAR4: pointer to the decoder object/
;; pointer to the lambdas
;; XAR5: pointer to the omegas
;; XAR6: loop counter
;; XAR7: counter for shortened code update
;; T :
;; AL : number of bytes
;; AH :
;; VR1 :
;; VR3 :
;; VR4 :
;; VR5 :
;; VR6 :
;; VR7 :
REEDSOLOMON_DECODER_CONTEXT_SAVE
MOVB AH, #255
SUB AH, AL ; k = 255 - nBytes
MOV T, AH
AND T, #0x1 ; loop udpates 2 @ a time
LSR AH, #1
ADDB AH, #-1
MOVZ AR7, @AH ; AR7 = counter for shortened code update
ADDB AL, #-1
MOVZ AR6, @AL ; AR6 = loop counter
MOV AR0, #ARG_PPACKEDBETA
MOVL XAR2, *+XAR4[AR0] ; XAR2 = beta pointer
MOV AR0, #ARG_PERRLOC
MOVL XAR3, *+XAR4[AR0] ; XAR3 = err pointer
MOV AR0, #ARG_POMEGA
MOVL XAR5, *+XAR4[AR0] ; XAR5 = omega pointer
MOVL *-SP[#STK_PARG], XAR4 ; save structure pointer to stack
MOV AR0, #ARG_PLAMBDA
MOVL XAR4, *+XAR4[AR0] ; XAR4 = lambda pointer
;;=============================================================================
;; Update lambdaEval and gammEval only for shortened code
;;=============================================================================
VMOV32 VR3, *+XAR4[0] ; VR3[31:0] = lambdaEval3_2_1_0
VMOV32 VR4, *+XAR4[2] ; VR4[31:0] = lambdaEval7_6_5_4
VMOV32 VR5, *+XAR4[4] ; VR5[31:0] = X_X_X_lambdaEval8
VMOV32 VR6, *+XAR5[0] ; VR6[31:0] = gamma3_2_1_0
VMOV32 VR7, *+XAR5[2] ; VR7[31:0] = gamma7_6_5_4
VMOV32 VR0, *+XAR2[0] ; VR0[31:0] = beta3_2_1_0
VMOV32 VR1, *+XAR2[0] ; VR1[31:0] = beta3_2_1_0
; VR1 = use LSB only for root update, can optimize later!!!
.align 2
RPTB _REEDSOLOMON_DECODER_chienForney_updateLoop, AR7
VGFMPY4 VR3, VR0, VR3 ; Update lambdaEval_3_2_1_0
|| VMOV32 VR0, *+XAR2[2] ; VR0[31:0] = beta7_6_5_4
VGFMPY4 VR4, VR0, VR4 ; Update lambdaEval_7_6_5_4
|| VMOV32 VR0, *+XAR2[4] ; VR0[31:0] = X_X_X_beta8
VGFMPY4 VR5, VR0, VR5 ; Update X_X_X_lambdaEval8
|| VMOV32 VR0, *+XAR2[0] ; VR0[31:0] = beta3_2_1_0
VGFMPY4 VR6, VR0, VR6 ; Update gammaEval_3_2_1_0
|| VMOV32 VR0, *+XAR2[2] ; VR0[31:0] = beta7_6_5_4
VGFMPY4 VR7, VR0, VR7 ; Update gammaEval_7_6_5_4
|| VMOV32 VR0, *+XAR2[0] ; VR0[31:0] = beta3_2_1_0
VGFMPY4 VR1, VR0, VR1 ; Update root
VGFMPY4 VR3, VR0, VR3 ; Update lambdaEval_3_2_1_0
|| VMOV32 VR0, *+XAR2[2] ; VR0[31:0] = beta7_6_5_4
VGFMPY4 VR4, VR0, VR4 ; Update lambdaEval_7_6_5_4
|| VMOV32 VR0, *+XAR2[4] ; VR0[31:0] = X_X_X_beta8
VGFMPY4 VR5, VR0, VR5 ; Update X_X_X_lambdaEval8
|| VMOV32 VR0, *+XAR2[0] ; VR0[31:0] = beta3_2_1_0
VGFMPY4 VR6, VR0, VR6 ; Update gammaEval_3_2_1_0
|| VMOV32 VR0, *+XAR2[2] ; VR0[31:0] = beta7_6_5_4
VGFMPY4 VR7, VR0, VR7 ; Update gammaEval_7_6_5_4
|| VMOV32 VR0, *+XAR2[0] ; VR0[31:0] = beta3_2_1_0
VGFMPY4 VR1, VR0, VR1 ; Update root
_REEDSOLOMON_DECODER_chienForney_updateLoop:
; initialize counters
MOVL XAR1, #0 ; byte counter = 0
MOVL XAR4, #0 ; numroots = 0
CMP T, #0
SBF _REEDSOLOMON_DECODER_chienForney_loop, EQ
;;=============================================================================
;; if odd
;;=============================================================================
VGFMPY4 VR3, VR0, VR3 ; Update lambdaEval_3_2_1_0
|| VMOV32 VR0, *+XAR2[2] ; VR0[31:0] = beta7_6_5_4
VGFMPY4 VR4, VR0, VR4 ; Update lambdaEval_7_6_5_4
|| VMOV32 VR0, *+XAR2[4] ; VR0[31:0] = X_X_X_beta8
VGFMPY4 VR5, VR0, VR5 ; Update X_X_X_lambdaEval8
|| VMOV32 VR0, *+XAR2[0] ; VR0[31:0] = beta3_2_1_0
VGFMPY4 VR6, VR0, VR6 ; Update gammaEval_3_2_1_0
|| VMOV32 VR0, *+XAR2[2] ; VR0[31:0] = beta7_6_5_4
VGFMPY4 VR7, VR0, VR7 ; Update gammaEval_7_6_5_4
|| VMOV32 VR0, *+XAR2[0] ; VR0[31:0] = beta3_2_1_0
VGFMPY4 VR1, VR0, VR1 ; Update root
;;=============================================================================
;; Evaluate lambda/omega @ each data byte position
;;=============================================================================
_REEDSOLOMON_DECODER_chienForney_loop:
;;=============================================================================
;; Evaluate poly (lambdaEval and gammaEval are stored in VR registers)
;;=============================================================================
VGFMPY4 VR6, VR0, VR6 ; Update gammaEval_3_2_1_0
|| VMOV32 VR0, *+XAR2[2] ; VR0[31:0] = beta7_6_5_4
VGFMPY4 VR7, VR0, VR7 ; Update gammaEval_7_6_5_4
|| VMOV32 VR0, *+XAR2[0] ; VR0[31:0] = beta3_2_1_0
VGFMPY4 VR3, VR0, VR3 ; Update lambdaEval_3_2_1_0
|| VMOV32 VR0, *+XAR2[2] ; VR0[31:0] = beta7_6_5_4
VGFMPY4 VR4, VR0, VR4 ; Update lambdaEval_7_6_5_4
|| VMOV32 VR0, *+XAR2[4] ; VR0[31:0] = X_X_X_beta8
VGFMPY4 VR5, VR0, VR5 ; Update X_X_X_lambdaEval8
|| VMOV32 VR0, *+XAR2[0] ; VR0[31:0] = beta3_2_1_0
VCLEAR VR2
VGFACC VR2, VR3, #1010B ; odd poly
VGFACC VR2, VR4, #1010B ; odd poly
VMOV32 *-SP[STK_ODDPOLY], VR2 ; save odd poly to the stack
VCLEAR VR2
VGFACC VR2, VR3, #0101B ; even poly
VGFACC VR2, VR4, #0101B ; even poly
VGFACC VR2, VR5, #0001B
VMOV32 *-SP[STK_EVENPOLY], VR2
MOVL ACC, *-SP[STK_EVENPOLY]
;;=============================================================================
;; if (lambdapoly == 0), then error
;;=============================================================================
CMP AL, *-SP[STK_ODDPOLY] ; even poly = odd poly?
SBF _REEDSOLOMON_DECODER_chienForney_nonZero, NEQ
GFINV ; GFINV (oddpoly)
; MACRO using VR0 as tmp, ip/op: VR2
VCLEAR VR0
VGFACC VR0, VR6, #1111B ; gamma poly
VGFACC VR0, VR7, #1111B ; gamma poly
VGFMPY4 VR2, VR2, VR0 ; GFMPY (gamma_poly, GFINV(odd_poly)
VLSHL32 VR2, #8 ; shift to multiply with correct root
VGFMPY4 VR2, VR2, VR1 ; val = gamma_poly *root / odd_poly
|| VMOV32 VR0, *+XAR2[0] ; VR0[31:0] = beta3_2_1_0
VMOV32 *-SP[STK_ODDPOLY], VR2
MOV ACC, *-SP[STK_ODDPOLY] << #8 ; AH = VR2
AND AH, #0xFF
MOV *XAR3++, AR1 ; store error byte position
MOV *XAR3++, AH ; store error value
ADDB XAR4, #1 ; numroots++
_REEDSOLOMON_DECODER_chienForney_nonZero:
VGFMPY4 VR1, VR0, VR1 ; Update root
ADDB XAR1, #1 ; byte counter++
BANZ _REEDSOLOMON_DECODER_chienForney_loop, AR6--
;;=============================================================================
;; Check for decode ok/fail
;; No roots of lambda should repeat, # of roots should = degree of lambda
;;=============================================================================
MOV *+XAR3[0], AR4 ; save number of error last
REEDSOLOMON_DECODER_CONTEXT_RESTORE
LRETR
;; End of File
@@ -0,0 +1,426 @@
;;*****************************************************************************
;;! \file source/vcu2/reed_solomon/vcu2_reedsolomon_invbkampmssy.asm
;;!
;;! \brief Inversionless Berlekamp Massey Algorithm
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
.cdecls C, LIST, "vcu2_types.h", "vcu2_reedsolomon_decoder.h"
;;*****************************************************************************
;; defines
;;*****************************************************************************
;; REEDSOLOMON_DECODER Routine defines
;; Argument structure defines
ARG_N .set 0
ARG_K .set 1
ARG_T .set 2
ARG_NROOTS .set 3
ARG_PSYNDROME .set 4
ARG_PLAMBDA .set 6
ARG_POMEGA .set 8
ARG_PPACKEDALPHA .set 10
ARG_PPACKEDBETA .set 12
ARG_PRSEXPTABLE .set 14
ARG_PRSLOGTABLE .set 16
ARG_PERRLOC .set 18
;; Stack defines
;;
;; |_______|
;; |_______|<- Stack Pointer (SP) <---SP
;; |_______|<- STK_PDATA (SP-2)
;; |_______|<- STK_DELTA (SP-4)
;; |_______|<- STK_GAMMA (SP-6)
;; |_______|<- STK_K (SP-8)
;; |_______|<- STK_B3_2_1_0 (SP-10)
;; |_______|<- STK_B7_6_5_4 (SP-12)
;; |_______|<- STK_X_X_X_B8 (SP-14)
;; |_______|<- STK_TEMP (SP-16)
;; | ... | : :
;; |_______|<- STK_TEMP_END (SP-24)
;;
LOCAL_FRAME_SIZE .set 24
STK_PDATA .set 2
STK_DELTA .set 4
STK_GAMMA .set 6
STK_K .set 8
STK_B3_2_1_0 .set 10
STK_B7_6_5_4 .set 12
STK_X_X_X_B8 .set 14
STK_TEMP .set 16
STK_TEMP_END .set 24
;;*****************************************************************************
;; macros
;;*****************************************************************************
;;
;; MACRO : 'REEDSOLOMON_DECODER_CONTEXT_SAVE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on entry into Reed solomon decoder routine
;;
REEDSOLOMON_DECODER_CONTEXT_SAVE .macro
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #LOCAL_FRAME_SIZE ; allocate stack space for local frame
.endm
;;
;; MACRO : 'REEDSOLOMON_DECODER_CONTEXT_RESTORE'
;; SIZE : Number of WORDS/Number of Cycles 14
;; USAGE : Called on exit from Reed solomon decoder routine
;;
REEDSOLOMON_DECODER_CONTEXT_RESTORE .macro
SUBB SP, #LOCAL_FRAME_SIZE ; deallocate stack space for local frame
POP XAR3
POP XAR2
POP XAR1
.endm
;;*****************************************************************************
;; globals
;;*****************************************************************************
.global _REEDSOLOMON_DECODER_berlekampMassey
_REEDSOLOMON_DECODER_berlekampMassey_K:
.long 0x1, 0x0, 0x0, 0x3, 0x0, 0x0
.long 0x7, 0x0, 0x0, 0xF, 0x0, 0x0
.long 0xF, 0x1, 0x0, 0xF, 0x3, 0x0
.long 0xF, 0x7, 0x0, 0xF, 0xF, 0x0
.long 0xF, 0xF, 0x1, 0xF, 0xF, 0x1
.long 0xF, 0xF, 0x1, 0xF, 0xF, 0x1
.long 0xF, 0xF, 0x1, 0xF, 0xF, 0x1
.long 0xF, 0xF, 0x1, 0xF, 0xF, 0x1
;;*****************************************************************************
;; function definitions
;;*****************************************************************************
.text
;; \brief Inversionless Berlekamp Massey Algorithm to find the coefficients
;; of the error locator polynomial
;;
;; \param[in] hndRSDecoder handle to the Reed Solomon Decoder object
;; - *+XAR4[0]: n ->number of codeword symbols (bytes) in a block
;; - *+XAR4[1]: k ->number of message symbols (bytes) in a block
;; - *+XAR4[2]: t ->number of correctable errors in the block
;; - *+XAR4[3]: nRoots ->number of roots for the code generator polynomial
;; - *+XAR4[4]: *pSyndrome ->pointer to the syndromes
;; - *+XAR4[6]: *pLambda ->pointer to the error locator polynomial coefficients
;; - *+XAR4[8]: *pOmega ->pointer to the error magnitude polynomial coefficients
;; - *+XAR4[10]: *pPackedAlpha ->Pointer to the roots of the code generator polynomial \f$ x + \alpha^{i}\f$
;; - *+XAR4[12]: *pPackedBeta ->Pointer to the first 2t elements of the GF(2^n)
;; - *+XAR4[14]: *pRS_expTable ->Pointer to the lookup table (roots of the extension Galois Field)
;; that converts index to decimal form
;; - *+XAR4[16]: *pRS_logTable ->Pointer to the lookup table (roots of the extension Galois Field)
;; that converts decimal to index form
;; - *+XAR4[18]: *pErrorLoc ->Pointer to the error (location, value) pairs
;;
_REEDSOLOMON_DECODER_berlekampMassey:
;; Local Defines
;;
;; Register Usage:
;; XAR0: Index into the structure
;; XAR1: Counter for syndrome load
;; XAR2: pointer to the syndrome
;; XAR3: pointer to the lambda polynomial
;; XAR4: pointer to the decoder object
;; XAR5: points to a temporary buffer
;; XAR6: loop counter
;; XAR7: GFADD #K | pointer to the omega polynomial
;; T :
;; AL :
;; AH :
;; VR3 : lambdaEval3_2_1_0
;; VR4 : lambdaEval7_6_5_4
;; VR5 : X_X_X_lambdaEval8
;; VR6 : gammaEval_3_2_1_0
;; VR7 : gammaEval_7_6_5_4
REEDSOLOMON_DECODER_CONTEXT_SAVE
MOV AR0, #ARG_PLAMBDA
MOVL XAR3, *+XAR4[AR0] ; XAR3 -> pLambda
MOV AR0, #ARG_PSYNDROME
MOVL XAR2, *+XAR4[AR0] ; XAR2 -> pSyndrome
MOVZ AR5, SP ; XAR5 -> temp buffer
SUBB XAR5, #STK_TEMP_END
MOV AL, *+XAR4[#ARG_T] ; AL = t (not T = 2t)
LSR AL, #1 ; = t/2
SUB AL, #1 ; = t/2 - 1
MOVZ AR6, AL ; loop counter = t/2 - 1
MOVL XAR7, #_REEDSOLOMON_DECODER_berlekampMassey_K
;;=============================================================================
;; Initialization
;;=============================================================================
MOVB XAR1, #0
MOV AL, #1
MOV AH, #0
MOVL *+XAR3[0], ACC ; l3_2_1_0 = 0_0_0_1
MOVL *-SP[STK_GAMMA], ACC ; gamma = 1
MOVL *-SP[STK_B3_2_1_0], ACC ; B3_2_1_0 = 0_0_0_1
MOV AL, #0
MOVL *-SP[STK_K], ACC ; k = 0
MOVL *+XAR3[2], ACC ; l7_6_5_4 = 0_0_0_0
MOVL *+XAR3[4], ACC ; l8 = 0
MOVL *-SP[STK_B7_6_5_4], ACC ; B7_6_5_4 = 0_0_0_0
MOVL *-SP[STK_X_X_X_B8], ACC ; B8 = 0
VCLEARALL ; clear all VCU registers
;;=============================================================================
;; Iterations
;;=============================================================================
_REEDSOLOMON_DECODER_berlekampMassey_iteration:
VMOV32 VR1, *+XAR2[AR1] ; VR1 = s3_2_1_0
; VR1 = s7_6_5_4
; VR1 = s11_10_9_8
; VR1 = s15_14_13_12
VREVB VR1 ; reverse bytes
VMOV32 *-SP[STK_TEMP], VR1
MOVB XAR0, #3 ; loop counter
_REEDSOLOMON_DECODER_berlekampMassey_loop:
;;=============================================================================
;; Compute Delta = sum(lambda[j] * S[k-j]), 0<j<k
;; VR1, VR2, VR3, VR4 no reuse (syndromes in reverse order + shift)
;;=============================================================================
VMOV32 VR1, *-SP[STK_TEMP] ; VR1 = s3_2_1_0
VMOV32 VR5, VR2 ; VR5 = VR2
VMOV32 VR6, VR3 ; VR6 = VR3
VSHLMB VR4, VR6 ; VR4, VR3, VR2 S in reverse order
VSHLMB VR3, VR5
VSHLMB VR2, VR1
VCLEAR VR5
VMOV32 VR0, *+XAR3[0] ; VR0 = l3_2_1_0
VGFMPY4 VR6, VR0, VR2
VMOV32 VR7, *XAR7++ ; VR7 = #K
VGFACC VR5, VR6, VR7
|| VMOV32 VR0, *+XAR3[2] ; VR0 = l7_6_5_4
VGFMPY4 VR6, VR0, VR3
VMOV32 VR7, *XAR7++ ; VR7 = #K
VGFACC VR5, VR6, VR7
|| VMOV32 VR0, *+XAR3[4] ; VR0 = X_X_X_l8
VGFMPY4 VR6, VR0, VR4
VMOV32 VR7, *XAR7++ ; VR7 = #K
VGFACC VR5, VR6, VR7
VMOV32 *-SP[STK_DELTA], VR5 ; save delta
VMOV32 *-SP[STK_TEMP], VR1 ; save shifted S
;;=============================================================================
;; Compute lambda
;; VR5, VR6, VR7 stores lambdaEval
;;=============================================================================
VMOV32 VR5, *-SP[STK_B3_2_1_0] ; B3_B2_B1_B0
VMOV32 VR6, *-SP[STK_B7_6_5_4] ; B7_B6_B5_B4
VMOV32 VR7, VR6
VSHLMB VR6, VR5 ; VR6 = B6_B5_B4_B3, VR5 = B2_B1_B0_NA
VLSHR32 VR7, #24 ; VR7 = X_X_X_B7
VPACK4 VR0, *-SP[STK_DELTA], #0 ; delta repeat 4
VGFMPY4 VR5, VR0, VR5 ; VR5 = delta_B210X
VGFMPY4 VR6, VR0, VR6 ; VR6 = delta_B6543
VGFMPY4 VR7, VR0, VR7 ; VR7 = delta_XXXB7
VPACK4 VR0, *-SP[STK_GAMMA], #0 ; gamma repeat 4
VMOV32 VR1, *+XAR3[0] ; VR1 = l3_l2_l1_l0
VGFMPY4 VR1, VR0, VR1 ; VR1 = gamma_l3210
VGFADD4 VR5, VR1, VR5, #0xE ; VR5 = l_new3210
VMOV32 VR1, *+XAR3[2] ; VR1 = l4_l5_l6_l7
VGFMPY4 VR1, VR0, VR1 ; VR1 = gamma_l4567
VGFADD4 VR6, VR6, VR1, #0xF ; VR6 = l_new7654
VMOV32 VR1, *+XAR3[4] ; VR1 = X_X_X_l8
VGFMPY4 VR1, VR0, VR1 ; VR1 = gamma_l8
VGFADD4 VR7, VR7, VR1, #0x1 ; VR7 = l_new8
;;=============================================================================
;; Decision
;;=============================================================================
;; if((delta != 0) && (k >= 0))
CMP *-SP[STK_DELTA], #0 ; delta != 0
BF _REEDSOLOMON_DECODER_berlekampMassey_cond1, EQ
CMP *-SP[STK_K], #0 ; k >= 0
BF _REEDSOLOMON_DECODER_berlekampMassey_cond1, LT
MOVL ACC, *-SP[STK_DELTA]
MOVL *-SP[STK_GAMMA], ACC ; gamma = delta
MOVL ACC, *-SP[STK_K]
ADDB AL, #1
NEG ACC
MOVL *-SP[STK_K], ACC ; k_new = -(k + 1);
MOVL ACC, *+XAR3[0] ; copy l_p to B
MOVL *-SP[STK_B3_2_1_0], ACC
MOVL ACC, *+XAR3[2]
MOVL *-SP[STK_B7_6_5_4], ACC
MOVL ACC, *+XAR3[4]
MOVL *-SP[STK_X_X_X_B8], ACC
SB _REEDSOLOMON_DECODER_berlekampMassey_lambdaUpdate, UNC
_REEDSOLOMON_DECODER_berlekampMassey_cond1:
MOVL ACC, *-SP[STK_K]
ADD ACC, #1
MOVL *-SP[STK_K], ACC ; k_new = k + 1
VMOV32 VR1, *-SP[STK_B7_6_5_4] ; VR1 = B7_B6_B5_B4
VLSHR32 VR1, #24 ; VR1 = X_X_X_B7
VMOV32 *-SP[STK_X_X_X_B8], VR1
VMOV32 VR1, *-SP[STK_B7_6_5_4] ; VR1 = B7_B6_B5_B4
VMOV32 VR0, *-SP[STK_B3_2_1_0] ; VR0 = B3_B2_B1_B0
VSHLMB VR1, VR0 ; VR1 = B6543, VR0=B210_00
NOP
VMOV32 *-SP[STK_B7_6_5_4], VR1 ; B = B6_B5_B4_B3
VMOV32 *-SP[STK_B3_2_1_0], VR0 ; B = B2_B1_B0_0
_REEDSOLOMON_DECODER_berlekampMassey_lambdaUpdate:
VMOV32 *+XAR3[0], VR5 ; l = l_new
VMOV32 *+XAR3[2], VR6
VMOV32 *+XAR3[4], VR7
BANZ _REEDSOLOMON_DECODER_berlekampMassey_loop, AR0--
ADDB XAR1, #2
BANZ _REEDSOLOMON_DECODER_berlekampMassey_iteration, AR6--
;;=============================================================================
;; omega (error eval poly)
;;=============================================================================
MOVB XAR1, #0
MOV AL, *+XAR4[#ARG_T] ; AL = t
LSR AL, #2 ; = t/4
SUB AL, #1 ; = t/4 - 1
MOVZ AR6, @AL ; AR6 = loop counter
MOVL XAR7, #_REEDSOLOMON_DECODER_berlekampMassey_K
_REEDSOLOMON_DECODER_berlekampMassey_omega:
VMOV32 VR1, *+XAR2[AR1] ; VR1 = s3_2_1_0
; VR1 = s7_6_5_4
VREVB VR1 ; reverse bytes
.align 2
RPTB _REEDSOLOMON_DECODER_berlekampMassey_omegaLoop, #3
;;=============================================================================
;; Compute omega = sum(lambda[j] * S[k-j]), 0<j<k
;; VR1, VR2, VR3, VR4 no reuse (syndromes in reverse order + shift)
;;=============================================================================
VMOV32 VR5, VR2 ; VR5 = VR2
VSHLMB VR3, VR5 ; VR4, VR3, VR2 S in reverse order
VSHLMB VR2, VR1
VCLEAR VR5
VMOV32 VR0, *+XAR3[0] ; VR0 = l3_2_1_0
VGFMPY4 VR6, VR0, VR2
VMOV32 VR7, *XAR7++ ; VR7 = #K
VGFACC VR5, VR6, VR7
|| VMOV32 VR0, *+XAR3[2] ; VR0 = l4_5_6_7
VGFMPY4 VR6, VR0, VR3
VMOV32 VR7, *XAR7++ ; VR7 = #K
ADDB XAR7, #2
VGFACC VR5, VR6, VR7
VMOV16 *XAR5++, VR5L ; omega
_REEDSOLOMON_DECODER_berlekampMassey_omegaLoop:
ADDB XAR1, #2
BANZ _REEDSOLOMON_DECODER_berlekampMassey_omega, AR6--
;;=============================================================================
; pack omega
;;=============================================================================
MOV AR0, #ARG_POMEGA
MOVL XAR7, *+XAR4[AR0]
MOVZ AR5, @SP
SUBB XAR5, #STK_TEMP_END ; XAR5 -> temporary buffer
MOVB AL.LSB, *XAR5++
MOVB AL.MSB, *XAR5++
MOVB AH.LSB, *XAR5++
MOVB AH.MSB, *XAR5++
MOV *XAR7++, AL
MOV *XAR7++, AH
MOVB AL.LSB, *XAR5++
MOVB AL.MSB, *XAR5++
MOVB AH.LSB, *XAR5++
MOVB AH.MSB, *XAR5++
MOV *XAR7++, AL
MOV *XAR7, AH
REEDSOLOMON_DECODER_CONTEXT_RESTORE
LRETR
;; End of File
@@ -0,0 +1,260 @@
;;*****************************************************************************
;;! \file source/vcu2/reed_solomon/vcu2_reedsolomon_n255k239.asm
;;!
;;! \brief Reed Solomon Decoder (n,k = 255, 239)
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
.cdecls C, LIST, "vcu2_types.h", "vcu2_reedsolomon_decoder.h"
;;*****************************************************************************
;; defines
;;*****************************************************************************
;; REEDSOLOMON_DECODER Routine defines
;; Argument structure defines
ARG_N .set 0
ARG_K .set 1
ARG_T .set 2
ARG_NROOTS .set 3
ARG_PSYNDROME .set 4
ARG_PLAMBDA .set 6
ARG_POMEGA .set 8
ARG_PPACKEDALPHA .set 10
ARG_PPACKEDBETA .set 12
ARG_PRSEXPTABLE .set 14
ARG_PRSLOGTABLE .set 16
ARG_PERRLOC .set 18
;; Stack defines
;;
;; |_______|
;; |_______|<- Stack Pointer (SP) <---SP
;; |_______|<- STK_NBYTES (SP-2)
;; |_______|<- STK_PDATA (SP-4)
;;
LOCAL_FRAME_SIZE .set 4
STK_NBYTES .set 2
STK_PDATA .set 4
;;*****************************************************************************
;; macros
;;*****************************************************************************
;;
;; MACRO : 'REEDSOLOMON_DECODER_CONTEXT_SAVE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on entry into Reed solomon decoder routine
;;
REEDSOLOMON_DECODER_CONTEXT_SAVE .macro
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #LOCAL_FRAME_SIZE ; allocate stack space for local frame
.endm
;;
;; MACRO : 'REEDSOLOMON_DECODER_CONTEXT_RESTORE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on exit from Reed solomon decoder routine
;;
REEDSOLOMON_DECODER_CONTEXT_RESTORE .macro
SUBB SP, #LOCAL_FRAME_SIZE ; deallocate stack space for local frame
POP XAR3
POP XAR2
POP XAR1
.endm
;;*****************************************************************************
;; globals
;;*****************************************************************************
.if __TI_EABI__
.asg REEDSOLOMON_DECODER_runN255K239, _REEDSOLOMON_DECODER_runN255K239
.asg REEDSOLOMON_DECODER_initN255K239, _REEDSOLOMON_DECODER_initN255K239
.endif
.global _REEDSOLOMON_DECODER_runN255K239
.global _REEDSOLOMON_DECODER_initN255K239
.ref _REEDSOLOMON_DECODER_calcSyndrome
.ref _REEDSOLOMON_DECODER_berlekampMassey
.ref _REEDSOLOMON_DECODER_chienForney
;;*****************************************************************************
;; function definitions
;;*****************************************************************************
.text
;; \brief Runs the Reed Solomon Decoder (n,k = 255, 239)
;;
;; \param[in] hndRSDecoder handle to the Reed Solomon Decoder object
;; - *+XAR4[0]: n ->number of codeword symbols (bytes) in a block
;; - *+XAR4[1]: k ->number of message symbols (bytes) in a block
;; - *+XAR4[2]: t ->number of correctable errors in the block
;; - *+XAR4[3]: nRoots ->number of roots for the code generator polynomial
;; - *+XAR4[4]: *pSyndrome ->pointer to the syndromes
;; - *+XAR4[6]: *pLambda ->pointer to the error locator polynomial coefficients
;; - *+XAR4[8]: *pOmega ->pointer to the error magnitude polynomial coefficients
;; - *+XAR4[10]: *pPackedAlpha ->Pointer to the roots of the code generator polynomial \f$ x + \alpha^{i}\f$
;; - *+XAR4[12]: *pPackedBeta ->Pointer to the first 2t elements of the GF(2^n)
;; - *+XAR4[14]: *pRS_expTable ->Pointer to the lookup table (roots of the extension Galois Field)
;; that converts index to decimal form
;; - *+XAR4[16]: *pRS_logTable ->Pointer to the lookup table (roots of the extension Galois Field)
;; that converts decimal to index form
;; - *+XAR4[18]: *pErrorLoc ->Pointer to the error (location, value) pairs
;;
;; \param[in] pData (XAR5) pointer to the data
;; \param[in] nBytes (AL) number of bytes in the message
;;
_REEDSOLOMON_DECODER_runN255K239:
;; Local Defines
;;
;; Register Usage:
;; XAR0:
;; XAR1:
;; XAR2:
;; XAR3:
;; XAR4: pointer to the structure
;; XAR5: pointer to the data
;; XAR6:
;; XAR7:
;; AL: number of message bytes
;; AH:
REEDSOLOMON_DECODER_CONTEXT_SAVE
MOV *-SP[STK_NBYTES], AL
MOVL *-SP[STK_PDATA], XAR5
LCR _REEDSOLOMON_DECODER_calcSyndrome
MOVL XAR5, *-SP[STK_PDATA]
LCR _REEDSOLOMON_DECODER_berlekampMassey
MOV AL, *-SP[STK_NBYTES]
MOVL XAR5, *-SP[STK_PDATA]
LCR _REEDSOLOMON_DECODER_chienForney
REEDSOLOMON_DECODER_CONTEXT_RESTORE
LRETR
;;*****************************************************************************
;; \brief Initializes the Reed Solomon Decoder object
;;
;; \param[in] hndRSDecoder handle to the Reed Solomon Decoder object
;; - *+XAR4[0]: n ->number of codeword symbols (bytes) in a block
;; - *+XAR4[1]: k ->number of message symbols (bytes) in a block
;; - *+XAR4[2]: t ->number of correctable errors in the block
;; - *+XAR4[3]: nRoots ->number of roots for the code generator polynomial
;; - *+XAR4[4]: *pSyndrome ->pointer to the syndromes
;; - *+XAR4[6]: *pLambda ->pointer to the error locator polynomial coefficients
;; - *+XAR4[8]: *pOmega ->pointer to the error magnitude polynomial coefficients
;; - *+XAR4[10]: *pPackedAlpha ->Pointer to the roots of the code generator polynomial \f$ x + \alpha^{i}\f$
;; - *+XAR4[12]: *pPackedBeta ->Pointer to the first 2t elements of the GF(2^n)
;; - *+XAR4[14]: *pRS_expTable ->Pointer to the lookup table (roots of the extension Galois Field)
;; that converts index to decimal form
;; - *+XAR4[16]: *pRS_logTable ->Pointer to the lookup table (roots of the extension Galois Field)
;; that converts decimal to index form
;; - *+XAR4[18]: *pErrorLoc ->Pointer to the error (location, value) pairs
;;
;; \param[in] pSyndrome (XAR5) pointer to the syndromes
;; \param[in] pLambda (*-SP[4]) pointer to the syndromes
;; \param[in] pOmega (*-SP[6]) pointer to the syndromes
;; \param[in] pPackedAlpha (*-SP[8])Pointer to the roots of the generator polynomial \f$ x + \alpha^{i}\f$
;; \param[in] pPackedBeta (*-SP[10])Pointer to the roots of the generator polynomial \f$ x + \beta^{i}\f$
;; \param[in] pRS_expTable (*-SP[12])pointer to the lookup table that converts index to decimal form
;; \param[in] pRS_logTable (*-SP[14])pointer to the lookup table that converts decimal to index form
;; \param[in] pErrorLoc (*-SP[16])Pointer to the error (location, value) pairs
_REEDSOLOMON_DECODER_initN255K239:
;; Local Defines
STK_PLAMBDA .set (LOCAL_FRAME_SIZE + 6 + 4 )
STK_POMEGA .set (LOCAL_FRAME_SIZE + 6 + 6 )
STK_PPACKEDALPHA .set (LOCAL_FRAME_SIZE + 6 + 8 )
STK_PPACKEDBETA .set (LOCAL_FRAME_SIZE + 6 + 10 )
STK_PRSEXPTABLE .set (LOCAL_FRAME_SIZE + 6 + 12 )
STK_PRSLOGTABLE .set (LOCAL_FRAME_SIZE + 6 + 14 )
STK_PERRORLOC .set (LOCAL_FRAME_SIZE + 6 + 16 )
;;
;; Register Usage:
;; XAR0: index into the structure
;; XAR1: Pointer to the pPackedAlpha, pPackedBeta,
;; RS_expTable, RS_logTable,
;; lambda, omega,error location 2-tuples
;; XAR2:
;; XAR3:
;; XAR4: pointer to the structure
;; XAR5: pointer to the syndromes
;; XAR6:
;; XAR7:
;;
REEDSOLOMON_DECODER_CONTEXT_SAVE
MOV *+XAR4[ARG_N], #RS_BLOCK_N
MOV *+XAR4[ARG_K], #RS_BLOCK_K
MOV *+XAR4[ARG_T], #RS_BLOCK_T
MOV *+XAR4[ARG_NROOTS], #RS_NROOTS
MOV AR0, #ARG_PSYNDROME
MOVL *+XAR4[AR0], XAR5
MOV AR0, #ARG_PLAMBDA
MOVL XAR1, *-SP[STK_PLAMBDA]
MOVL *+XAR4[AR0], XAR1
MOV AR0, #ARG_POMEGA
MOVL XAR1, *-SP[STK_POMEGA]
MOVL *+XAR4[AR0], XAR1
MOV AR0, #ARG_PPACKEDALPHA
MOVL XAR1, *-SP[STK_PPACKEDALPHA]
MOVL *+XAR4[AR0], XAR1
MOV AR0, #ARG_PPACKEDBETA
MOVL XAR1, *-SP[STK_PPACKEDBETA]
MOVL *+XAR4[AR0], XAR1
MOV AR0, #ARG_PRSEXPTABLE
MOVL XAR1, *-SP[STK_PRSEXPTABLE]
MOVL *+XAR4[AR0], XAR1
MOV AR0, #ARG_PRSLOGTABLE
MOVL XAR1, *-SP[STK_PRSLOGTABLE]
MOVL *+XAR4[AR0], XAR1
MOV AR0, #ARG_PERRLOC
MOVL XAR1, *-SP[STK_PERRORLOC]
MOVL *+XAR4[AR0], XAR1
REEDSOLOMON_DECODER_CONTEXT_RESTORE
LRETR
;; End of File
@@ -0,0 +1,557 @@
;;*****************************************************************************
;;! \file source/vcu2/vcu2_viterbi_k4_cr12_plc.asm
;;!
;;! \brief Viterbi Decoding K = 4, CR = 1/2
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
.cdecls C, LIST, "vcu2_types.h"
;;*****************************************************************************
;; defines
;;*****************************************************************************
;; VITERBI Routine defines
CONSTRAINT_LENGTH .set 4
NSTATES .set 1 << (CONSTRAINT_LENGTH - 1)
FRAME_LENGTH .set 64
BLOCK_SIZE .set 64
NSTAGES_DECODING_DEPTH .set 64
MODE_DECODEALL .set 0
MODE_OVERLAPINIT .set 1
MODE_OVERLAPDECODE .set 2
MODE_OVERLAPLAST .set 3
;; Argument structure defines
ARG_INBUFFER .set 0
ARG_OUTBUFFER .set 2
ARG_TRANSHIST .set 4
ARG_BMSELINIT .set 6
ARG_SMETRICINIT .set 8
ARG_NBITS .set 9
ARG_CONSTRAINT .set 10
ARG_NSTATES .set 11
ARG_CODERATE .set 12
ARG_MODE .set 13
ARG_TRANS_S1 .set 14
ARG_TRANS_S2 .set 16
ARG_TRANS_W1 .set 18
ARG_TRANS_W2 .set 20
ARG_TRANS_TMP .set 22
;; Stack defines
;;
;; |_______|
;; |_______|<- Stack Pointer (SP) <---SP
;; |_______|<- STK_VR0 (SP-2)
;; |_______|<- STK_VR1 (SP-4)
;; |_______|<- STK_VR2 (SP-6)
;; |_______|<- STK_VR3 (SP-8)
;; |_______|<- STK_VR4 (SP-10)
;; |_______|<- STK_VR5 (SP-12)
;; |_______|<- STK_VR6 (SP-14)
;; |_______|<- STK_VR7 (SP-16)
;; |_______|<- STK_VR8 (SP-18)
;; |_______|<- STK_ARG_PTR (SP-20)
;; |_______|<- STK_ARG_MODE (SP-22)
;; |_______|<- STK_ARG_NBITS (SP-24)
;;
LOCAL_FRAME_SIZE .set 6
STK_ARG_PTR .set 2
STK_ARG_MODE .set 4
STK_ARG_NBITS .set 6
;;*****************************************************************************
;; macros
;;*****************************************************************************
;;
;; MACRO : 'VITERBI_DECODER_CONTEXT_SAVE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on entry into Viterbi Decoder routine
;;
VITERBI_DECODER_CONTEXT_SAVE .macro
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #LOCAL_FRAME_SIZE ; allocate stack space for local frame
.endm
;;
;; MACRO : 'VITERBI_DECODER_CONTEXT_RESTORE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on exit from Viterbi Decoder routine
;;
VITERBI_DECODER_CONTEXT_RESTORE .macro
SUBB SP, #LOCAL_FRAME_SIZE ; deallocate stack space for local frame
POP XAR3
POP XAR2
POP XAR1
.endm
;;*****************************************************************************
;; globals
;;*****************************************************************************
.if __TI_EABI__
.asg VITERBI_DECODER_runK4CR12, _VITERBI_DECODER_runK4CR12
.asg VITERBI_DECODER_initK4CR12, _VITERBI_DECODER_initK4CR12
.asg VITERBI_DECODER_rescaleK4CR12, _VITERBI_DECODER_rescaleK4CR12
.endif
.global _VITERBI_DECODER_runK4CR12
.global _VITERBI_DECODER_initK4CR12
.global _VITERBI_DECODER_rescaleK4CR12
_rescaleBuffer .usect ".ebss", 64, 1, 1
;;*****************************************************************************
;; function definitions
;;*****************************************************************************
.text
;;
;; \brief
;;
;; \param Handle to the structure, VITERBI_DECODER_Obj(passed in XAR4)
;; - *+XAR4[0]: *pInBuffer -> Input buffer pointer
;; - *+XAR4[2]: *pOutBuffer -> Output buffer pointer
;; - *+XAR4[4]: *pTransitionHistory -> Transition History bits pointer
;; - *+XAR4[6]: *pBMSELInit -> Initialization value for the BMSEL register
;; - *+XAR4[8]: stateMetricInit -> Initialization value for the state metrics
;; - *+XAR4[9]: nBits -> Number of bits to be decoded
;; - *+XAR4[10]: constraintLength -> Constraint Length, i.e. K
;; - *+XAR4[11]: nStates -> #states = 2^(K - 1)
;; - *+XAR4[12]: codeRate -> The symbol code rate
;; - *+XAR4[13]: mode -> Viterbi mode enumerator
;; - *+XAR4[14]: *pTransitionStart1 -> Points to the start of the tranistion history buffer
;; - *+XAR4[16]: *pTransitionStart2 -> Points to the mid of the tranistion history buffer
;; - *+XAR4[18]: *pTransitionWrap1 -> Points to the mid of the tranistion history buffer
;; - *+XAR4[20]: *pTransitionWrap2 -> Points to the end of the tranistion history buffer
;; - *+XAR4[22]: *pTransitionTemp -> Points to a temporary(scratch) tranistion history buffer
;; \note
;; - The transition history buffer will have 5 pointers associated with it
;; - pTransitionHistory(hist_p): start of the transition history buffer
;; - pTransitionStart1(S1_p): points to where the transition update should start
;; - pTransitionStart2(S2_p: points to the mid point of the overlap(S1_p + 4*nUnencodedBits)
;; - pTransitionWrap1(W1_p): points to where trace overlap 2 should go (wrap, S1_p + 4*nUnencodedBits)
;; - pTransitionWrap2(W2_p): points to the end of the overlap(S1_p + 2*4*nUnencodedBits)
;;
;; CBITS = 128(coded bits per block)
;; UBITS = CBITS/2 = 64(uncoded bits per block)
;; UWORDS = 4 (4 words required to store UBITS)
;;
;; Transition history(bits per stage)--->
;; <-------64 bits----->
;; +----+----+----+----+ ^
;; S1_p->hist_p->| | | | | |
;; ^ | | | | | |
;; | | | | | | |
;; | | | | | | |
;; 4*UBITS | | | | | |
;; | | | | | | |
;; | | | | | | |
;; | | | | | | |
;; v | | | | | |
;; S2_p->W1_p->| | | | | 128 stages
;; ^ | | | | | |
;; | | | | | | |
;; | | | | | | |
;; 4*UBITS | | | | | |
;; | | | | | | |
;; | | | | | | |
;; | | | | | | |
;; v | | | | | |
;; W2_p->| | | | | |
;; +----+----+----+----+ v
;;
;; \return Decoded bits in the output buffer pointed by the VITERBI_DECODER_Obj.pOutBuffer
;;
_VITERBI_DECODER_runK4CR12:
VITERBI_DECODER_CONTEXT_SAVE
VSETOPACK ; VSTATUS.OPACK = 1, start packing the decoded
; bits from trace back into VT1 starting from the
; MSb, this obviates the need to manually flip the
; result each time
SETC SXM ; Sign extension mode
SETC OVM ; Overflow mode(no saturation)
;;=============================================================================
;;
;; Register Usage
;; XAR0: Index into the structure members that exceed index of 7 from start of structure
;; /traceback overlap inner loop counter
;; /temp pointer to structure in the pointer swaps
;; XAR1: Pointer to the input LLR
;; /Index into the structure members that exceed index of 7 from start of structure
;; XAR2: Branch Metric Select
;; XAR3: Pointer to the Transition History Array(as well as S1_p, W1_p depending on modes)
;; /used in pointer swaps
;; XAR4: Pointer to the viterbi structure
;; XAR5: Output array
;; /used in pointer swaps
;; XAR6: Loop counter
;; XAR7: points to the temporary transition bit array
;; /Loop counter for metric update when nBits < 8
;; AL: Number of Input bits
;; AH:
;;
MOV AR0, #ARG_MODE
MOV AL, *+XAR4[AR0] ; Save the mode to the stack
MOV *-SP[STK_ARG_MODE], AL
MOVL XAR5, *+XAR4[ARG_OUTBUFFER] ; XAR5 -> output_array
MOV AR0, #ARG_NBITS
MOV AL, *+XAR4[AR0]
LSR AL, #1 ; AL = nBits/2
MOV *-SP[STK_ARG_NBITS], AL ; Save the number of bits to the stack
CMP AL, #0 ; Check if the number of output bits are not zero
BF _VITERBI_DECODER_runK4CR12_nonZeroACS, NEQ ; if so jump to the metric calculations
; Since nBits == 0 at this point
MOV AR0, #ARG_TRANS_W1 ; We need only proceed to traceback, Load the
MOVL XAR3, *+XAR4[AR0] ; the Wrap pointer(to the transition history buffer)
; and proceed to the decode phase directly
BF _VITERBI_DECODER_runK4CR12_overlapDecode, UNC
_VITERBI_DECODER_runK4CR12_nonZeroACS:
MOVZ AR7, AL ; AR7 = (nBits/2)
LSR AL, #1 ; AL = (nBits/2)/2. We process two stages per RPTB
SUBB AL, #2 ; loop_counter = nBits/4 - 1 - 1.
MOVZ AR6, AL ; we process 2 bits per stage and 2 stages per iteration of the RPTB which will
; itself iterates N+1 hence the first -1. The last two stages are performed outside the RPTB
; hence the second -1
MOVL XAR1,*+XAR4[ARG_INBUFFER]
MOVL XAR3,*+XAR4[ARG_TRANSHIST]
; if(mode==0/1) jump to metric calculations
; We wont be using the S1_p in this case
CMP *-SP[STK_ARG_MODE], #MODE_OVERLAPDECODE
BF _VITERBI_DECODER_runK4CR12_metricUpdate, LT
;else if(mode==2/3) we need to start saving transition bits to
MOV AR0, #ARG_TRANS_S1 ;address pointed to be S1_p
MOVL XAR3, *+XAR4[AR0]
_VITERBI_DECODER_runK4CR12_metricUpdate:
MOVL XAR2, *+XAR4[ARG_BMSELINIT] ; Initialize the BMSEL register for butterfly 0 to K-1
VMOV32 VR2, *XAR2 ; Initialize BMSEL for butterfly 0 to 7
VITBM2 VR0, *XAR1++ ; Calculate and store BMs in VR0L and VR0H
MOV AL, AR7 ; AL = AR7 i.e. (nBits/2) - 1
CMPB AL, #8 ; if(AL < 8) jump to metric(less than 8) calculations
BF _VITERBI_DECODER_runK4CR12_lessThan8MetricUpdate, LT
ANDB AL, #0x1 ; if(AL is odd)jump to metric(odd bits) calculations
BF _VITERBI_DECODER_runK4CR12_oddBitsMetricUpdate, NEQ
; else proceed with regular 2 stage RPTB metric updates
.align 2
RPTB _VITERBI_DECODER_runK4CR12_metricUpdateLoop, AR6
VITSTAGE ; Compute NSTATES/2 butterflies in parallel,
|| VITBM2 VR0, *XAR1++ ; compute branch metrics for next butterfly
VMOV32 *XAR3++, VT1 ; Store VT1
VMOV32 *XAR3++, VT0 ; Store VT0
VITSTAGE ; Compute NSTATES/2 butterflies in parallel,
|| VITBM2 VR0, *XAR1++ ; compute branch metrics for next butterfly
VMOV32 *XAR3++, VT1 ; Store VT1
VMOV32 *XAR3++, VT0 ; Store VT0
_VITERBI_DECODER_runK4CR12_metricUpdateLoop:
VITSTAGE ; Compute NSTATES/2 butterflies in parallel,
|| VITBM2 VR0, *XAR1++ ; compute branch metrics for next butterfly
VMOV32 *XAR3++, VT1 ; Store VT1
VMOV32 *XAR3++, VT0 ; Store VT0
VITSTAGE ; Compute NSTATES/2 butterflies in parallel,
VMOV32 *XAR3++, VT1 ; Store VT1
VMOV32 *XAR3++, VT0 ; Store VT0
_VITERBI_DECODER_runK4CR12_metricUpdateEnd:
BF _VITERBI_DECODER_runK4CR12_lessThan8MetricUpdateEnd, UNC
_VITERBI_DECODER_runK4CR12_oddBitsMetricUpdate:
_VITERBI_DECODER_runK4CR12_lessThan8MetricUpdate:
SUBB XAR7, #1 ; AR7 = (nBits/2) - 1
_VITERBI_DECODER_runK4CR12_lessThan8MetricUpdateLoop:
VITSTAGE ; Compute NSTATES/2 butterflies in parallel,
|| VITBM2 VR0, *XAR1++ ; compute branch metrics for next butterfly
VMOV32 *XAR3++, VT1 ; Store VT1
VMOV32 *XAR3++, VT0 ; Store VT0
BANZ _VITERBI_DECODER_runK4CR12_lessThan8MetricUpdateLoop, AR7--
_VITERBI_DECODER_runK4CR12_lessThan8MetricUpdateEnd:
; if(mode==1), we are processing first block so no trace/decode
CMP *-SP[STK_ARG_MODE], #MODE_OVERLAPINIT
BF _VITERBI_DECODER_runK4CR12_toggleSPointers, EQ
ZAPA ; else if(mode==2/3), we have calculated state metrics proceed to trace/decode
CMP *-SP[STK_ARG_MODE], #MODE_DECODEALL
BF _VITERBI_DECODER_runK4CR12_overlapDecode, NEQ
; else if(mode==0), we need to traceback in 1-shot(32-bit word per output bit)
MOV AL, *-SP[STK_ARG_NBITS] ; loop_counter = UBITS - (K-1) - 1 (last -1 is to account for loop iteration)
MOVZ AR6, AL ; UBITS = nBits/2
SUBB XAR6, #((CONSTRAINT_LENGTH-1)+1) ; K = constraint length
LSL AL, #1 ; AL = 2(sizeof 32-bits) * (nBits/2)
MOV AR0, #ARG_TRANS_TMP
MOVL XAR7, *+XAR4[AR0] ; XAR7 -> pTransitionTemp[nBits]
ADDL XAR7, ACC
RPT #((CONSTRAINT_LENGTH-1)*2 - 1 ) ; Zero out the last (K-1)*2 output bits
|| MOV *--XAR7, AH ;
; XAR7 -> pTransitionTemp[nBits - (K-1)]
VCLEAR VR0
VCLEAR VR1
_VITERBI_DECODER_runK4CR12_tracebackLoop1:
VMOV32 VT0, *--XAR3
VMOV32 VT1, *--XAR3
VTRACE *--XAR7, VR0, VT0, VT1
BANZ _VITERBI_DECODER_runK4CR12_tracebackLoop1, AR6--
; The end of MODE_DECODEALL, proceed to exit
BF _VITERBI_DECODER_runK4CR12_toggleWPointers, UNC
; mode == 2/3
_VITERBI_DECODER_runK4CR12_overlapDecode:
MOV AL, *-SP[STK_ARG_NBITS] ; loop_counter = (nBits/2 - 1)
MOVZ AR6, AL
SUBB XAR6, #1
;V.C.130218-not needed
;MOV AR0, #ARG_TRANS_TMP
;MOVL XAR7, *+XAR4[AR0]
VCLEAR VR0
VCLEAR VR1
; if(mode==2) go to trace/decode of regular sized block
CMP *-SP[STK_ARG_MODE], #MODE_OVERLAPLAST
BF _VITERBI_DECODER_runK4CR12_tracebackLoopOverlap1, NEQ
; else(mode==3) trace/decode of irregular sized block
ADDB XAR6, #(BLOCK_SIZE - (CONSTRAINT_LENGTH-1))
MOV AL, AR6 ; loop_counter = [((nBits/2 - 1) + (nBits/2 - (K-1))] {prev_blk + cur_blk -2*(K-1) -1(loop)}
AND AL, #0x1F ;
MOV AR0, AL ; inner_loop_counter = loop_counter % 32
; mode == 3 OVERLAPLAST
_VITERBI_DECODER_runK4CR12_tracebackLoopOverlap0:
VMOV32 VT0, *--XAR3
VMOV32 VT1, *--XAR3
VTRACE VR1, VR0, VT0, VT1
;if(trace<32 bits) goto overlap0 end
BANZ _VITERBI_DECODER_runK4CR12_tracebackLoopOverlap0End, AR0--
VREVB VR1 ; Reverse VR1
VMOV32 *--XAR5, VR1 ;else(32-bits were traced and accumulated) store to output memory
MOVB XAR0, #31 ; inner_loop_counter += 32
_VITERBI_DECODER_runK4CR12_tracebackLoopOverlap0End:
MOV AL, AR6 ;if(loop_counter!=(nBits/2 - (K-1))) goto end1 of overlap 0
CMPB AL, #(BLOCK_SIZE - (CONSTRAINT_LENGTH-1))
BF _VITERBI_DECODER_runK4CR12_tracebackLoopOverlap0End1, NEQ
MOV AR1, #ARG_TRANS_W1 ;else(loop_counter==(nBits/2 - (K-1)))switch trans history pointer from S1 to W1
MOVL XAR3, *+XAR4[AR1]
;if(loop_counter!=0) goto overlap 0
_VITERBI_DECODER_runK4CR12_tracebackLoopOverlap0End1:
BANZ _VITERBI_DECODER_runK4CR12_tracebackLoopOverlap0, AR6--
;else(loop_counter==0) goto toggle S pointers
BF _VITERBI_DECODER_runK4CR12_toggleSPointers, UNC
; mode == 2 OVERLAPDECODE
_VITERBI_DECODER_runK4CR12_tracebackLoopOverlap1:
; For any viterbi stage K
VMOV32 VT0, *--XAR3
VMOV32 VT1, *--XAR3
VTRACE VR1, VR0, VT0, VT1
;if(loop_counter!=0) goto overlap 1
BANZ _VITERBI_DECODER_runK4CR12_tracebackLoopOverlap1, AR6--
;else(loop_counter==0), trace/decode from 2nd half of block
MOV AR0, #ARG_TRANS_W1 ;The 2nd half of the block actually produces decode bits to output
MOVL XAR3, *+XAR4[AR0] ;when overlapping is used
VMOV32 VT0, *--XAR3
.align 2 ;Decoding the first 32-bits, 3 of which are already in VR1 from overlap 1
NOP ;odd aligning the repeat block
RPTB _VITERBI_DECODER_runK4CR12_tracebackLoopOverlap2, #13
VMOV32 VT1, *--XAR3
VTRACE VR1, VR0, VT0, VT1
|| VMOV32 VT0, *--XAR3
VMOV32 VT1, *--XAR3
VTRACE VR1, VR0, VT0, VT1
|| VMOV32 VT0, *--XAR3
_VITERBI_DECODER_runK4CR12_tracebackLoopOverlap2:
VMOV32 VT1, *--XAR3
VTRACE VR1, VR0, VT0, VT1
|| VMOV32 VT0, *--XAR3
VREVB VR1 ; Reverse VR1
VMOV32 *+XAR5[2], VR1
.align 2 ;Decoding the second 32-bits
NOP ;odd aligning the repeat block
RPTB _VITERBI_DECODER_runK4CR12_tracebackLoopOverlap3, #15
VMOV32 VT1, *--XAR3
VTRACE VR1, VR0, VT0, VT1
|| VMOV32 VT0, *--XAR3
VMOV32 VT1, *--XAR3
VTRACE VR1, VR0, VT0, VT1
|| VMOV32 VT0, *--XAR3
_VITERBI_DECODER_runK4CR12_tracebackLoopOverlap3:
VREVB VR1 ; Reverse VR1
VMOV32 *XAR5, VR1
_VITERBI_DECODER_runK4CR12_toggleWPointers:
MOVL XAR0, XAR4
ADDB XAR0, #ARG_TRANS_W1
MOVL XAR3, *XAR0++
MOVL XAR5, *XAR0
MOVL *XAR0, XAR3
MOVL *--XAR0, XAR5
_VITERBI_DECODER_runK4CR12_toggleSPointers:
MOVL XAR0, XAR4
ADDB XAR0, #ARG_TRANS_S1
MOVL XAR3, *XAR0++
MOVL XAR5, *XAR0
MOVL *XAR0, XAR3
MOVL *--XAR0, XAR5
VITERBI_DECODER_CONTEXT_RESTORE
LRETR
;;*****************************************************************************
;;
;; \brief Initializes the constraint length and state metrics
;;
;; \param Handle to the structure, VITERBI_DECODER_Obj(passed in XAR4)
;; - *+XAR4[0]: *pInBuffer -> Input buffer pointer
;; - *+XAR4[2]: *pOutBuffer -> Output buffer pointer
;; - *+XAR4[4]: *pTransitionHistory -> Transition History bits pointer
;; - *+XAR4[6]: *pBMSELInit -> Initialization value for the BMSEL register
;; - *+XAR4[8]: stateMetricInit -> Initialization value for the state metrics
;; - *+XAR4[9]: nBits -> Number of bits to be decoded
;; - *+XAR4[10]: constraintLength -> Constraint Length, i.e. K
;; - *+XAR4[11]: nStates -> #states = 2^(K - 1)
;; - *+XAR4[12]: codeRate -> The symbol code rate
;; - *+XAR4[13]: mode -> Viterbi mode enumerator
;; - *+XAR4[14]: *pTransitionStart1 -> Points to the start of the tranistion history buffer
;; - *+XAR4[16]: *pTransitionStart2 -> Points to the mid of the tranistion history buffer
;; - *+XAR4[18]: *pTransitionWrap1 -> Points to the mid of the tranistion history buffer
;; - *+XAR4[20]: *pTransitionWrap2 -> Points to the end of the tranistion history buffer
;; - *+XAR4[22]: *pTransitionTemp -> Points to a temporary(scratch) tranistion history buffer
;;
_VITERBI_DECODER_initK4CR12:
VTCLEAR ; Clear the transition history
VSETK #CONSTRAINT_LENGTH ; Set constraint length
MOV AR0, #ARG_SMETRICINIT
VSMINIT *+XAR4[AR0] ; Initialize the state metrics
LRETR
;;*****************************************************************************
;;
;; \brief Rescale the state metrics to prevent overflow
;;
;; \param Handle to the structure, VITERBI_DECODER_Obj(passed in XAR4)
;; - *+XAR4[0]: *pInBuffer -> Input buffer pointer
;; - *+XAR4[2]: *pOutBuffer -> Output buffer pointer
;; - *+XAR4[4]: *pTransitionHistory -> Transition History bits pointer
;; - *+XAR4[6]: *pBMSELInit -> Initialization value for the BMSEL register
;; - *+XAR4[8]: stateMetricInit -> Initialization value for the state metrics
;; - *+XAR4[9]: nBits -> Number of bits to be decoded
;; - *+XAR4[10]: constraintLength -> Constraint Length, i.e. K
;; - *+XAR4[11]: nStates -> #states = 2^(K - 1)
;; - *+XAR4[12]: codeRate -> The symbol code rate
;; - *+XAR4[13]: mode -> Viterbi mode enumerator
;; - *+XAR4[14]: *pTransitionStart1 -> Points to the start of the tranistion history buffer
;; - *+XAR4[16]: *pTransitionStart2 -> Points to the mid of the tranistion history buffer
;; - *+XAR4[18]: *pTransitionWrap1 -> Points to the mid of the tranistion history buffer
;; - *+XAR4[20]: *pTransitionWrap2 -> Points to the end of the tranistion history buffer
;; - *+XAR4[22]: *pTransitionTemp -> Points to a temporary(scratch) tranistion history buffer
;;
;;=============================================================================
;;
;; Register Usage
;; XAR0:
;; XAR1:
;; XAR2: loop counter
;; XAR3:
;; XAR4: Pointer to the viterbi structure
;; XAR5: Pointer to state metrics
;; XAR6: copy of XAR5
;; XAR7:
;; AL: min metric
;; AH:
;;
_VITERBI_DECODER_rescaleK4CR12:
PUSH XAR2 ; save XAR2
SETC SXM, OVM ; set sign extension and overflow mode
MOV AL, #0x7FFF ; AL will store the minimum metric
MOVL XAR5, #_rescaleBuffer ; Load address of rescale buffer into XAR5
MOVL XAR6, XAR5
MOVL XAR7, XAR5
VMOV32 *XAR5++, VSM7: VSM6
VMOV32 *XAR5++, VSM5: VSM4
VMOV32 *XAR5++, VSM3: VSM2
VMOV32 *XAR5++, VSM1: VSM0
RPT #(NSTATES - 1)
|| MIN AL, *--XAR5
MOV AR2, #((NSTATES >> 3)-1)
_VITERBI_DECODER_rescaleK7CR12_loop:
SUB *XAR6++ , AL
SUB *XAR6++ , AL
SUB *XAR6++ , AL
SUB *XAR6++ , AL
SUB *XAR6++ , AL
SUB *XAR6++ , AL
SUB *XAR6++ , AL
SUB *XAR6++ , AL
BANZ _VITERBI_DECODER_rescaleK7CR12_loop, AR2--
VMOV32 VSM7: VSM6 , *XAR7++
VMOV32 VSM5: VSM4 , *XAR7++
VMOV32 VSM3: VSM2 , *XAR7++
VMOV32 VSM1: VSM0 , *XAR7
POP XAR2 ; restore XAR2
LRETR
;; End of File
@@ -0,0 +1,621 @@
;;*****************************************************************************
;;! \file source/vcu2/vcu2_viterbi_k7_cr12_plc.asm
;;!
;;! \brief Viterbi Decoding K = 7, CR = 1/2
;;#############################################################################
;;!
;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated -
;;! All rights reserved not granted herein.
;;! Limited License.
;;!
;;! Texas Instruments Incorporated grants a world-wide, royalty-free,
;;! non-exclusive license under copyrights and patents it now or hereafter
;;! owns or controls to make, have made, use, import, offer to sell and sell
;;! ("Utilize") this software subject to the terms herein. With respect to the
;;! foregoing patent license, such license is granted solely to the extent that
;;! any such patent is necessary to Utilize the software alone. The patent
;;! license shall not apply to any combinations which include this software,
;;! other than combinations with devices manufactured by or for TI
;;! ("TI Devices").
;;! No hardware patent is licensed hereunder.
;;!
;;! Redistributions must preserve existing copyright notices and reproduce this
;;! license (including the above copyright notice and the disclaimer and
;;! (if applicable) source code license limitations below) in the documentation
;;! and/or other materials provided with the distribution.
;;!
;;! Redistribution and use in binary form, without modification, are permitted
;;! provided that the following conditions are met:
;;!
;;! * No reverse engineering, decompilation, or disassembly of this software is
;;! permitted with respect to any software provided in binary form.
;;! * Any redistribution and use are licensed by TI for use only
;;! with TI Devices.
;;! * Nothing shall obligate TI to provide you with source code for the
;;! software licensed and provided to you in object code.
;;!
;;! If software source code is provided to you, modification and redistribution
;;! of the source code are permitted provided that the following conditions
;;! are met:
;;!
;;! * any redistribution and use of the source code, including any resulting
;;! derivative works, are licensed by TI for use only with TI Devices.
;;! * any redistribution and use of any object code compiled from the source
;;! code and any resulting derivative works, are licensed by TI for use
;;! only with TI Devices.
;;!
;;! Neither the name of Texas Instruments Incorporated nor the names of its
;;! suppliers may be used to endorse or promote products derived from this
;;! software without specific prior written permission.
;;#############################################################################
;;
;;
;;*****************************************************************************
;;
;;*****************************************************************************
;; includes
;;*****************************************************************************
.cdecls C, LIST, "vcu2_types.h"
;;*****************************************************************************
;; defines
;;*****************************************************************************
;; VITERBI Routine defines
CONSTRAINT_LENGTH .set 7
NSTATES .set 1 << (CONSTRAINT_LENGTH - 1)
FRAME_LENGTH .set 64
BLOCK_SIZE .set 64
NSTAGES_DECODING_DEPTH .set 64
MODE_DECODEALL .set 0
MODE_OVERLAPINIT .set 1
MODE_OVERLAPDECODE .set 2
MODE_OVERLAPLAST .set 3
;; Argument structure defines
ARG_INBUFFER .set 0
ARG_OUTBUFFER .set 2
ARG_TRANSHIST .set 4
ARG_BMSELINIT .set 6
ARG_SMETRICINIT .set 8
ARG_NBITS .set 9
ARG_CONSTRAINT .set 10
ARG_NSTATES .set 11
ARG_CODERATE .set 12
ARG_MODE .set 13
ARG_TRANS_S1 .set 14
ARG_TRANS_S2 .set 16
ARG_TRANS_W1 .set 18
ARG_TRANS_W2 .set 20
ARG_TRANS_TMP .set 22
;; Stack defines
;;
;; |_______|
;; |_______|<- Stack Pointer (SP) <---SP
;; |_______|<- STK_ARG_PTR (SP-2)
;; |_______|<- STK_ARG_MODE (SP-4)
;; |_______|<- STK_ARG_NBITS (SP-6)
;;
LOCAL_FRAME_SIZE .set 6
STK_ARG_PTR .set 2
STK_ARG_MODE .set 4
STK_ARG_NBITS .set 6
;;*****************************************************************************
;; macros
;;*****************************************************************************
;;
;; MACRO : 'VITERBI_DECODER_CONTEXT_SAVE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on entry into viterbi decoder routine
;;
VITERBI_DECODER_CONTEXT_SAVE .macro
PUSH XAR1
PUSH XAR2
PUSH XAR3
ADDB SP, #LOCAL_FRAME_SIZE ; allocate stack space for local frame
.endm
;;
;; MACRO : 'VITERBI_DECODER_CONTEXT_RESTORE'
;; SIZE : Number of WORDS/Number of Cycles 4
;; USAGE : Called on exit from viterbi decoder routine
;;
VITERBI_DECODER_CONTEXT_RESTORE .macro
SUBB SP, #LOCAL_FRAME_SIZE ; deallocate stack space for local frame
POP XAR3
POP XAR2
POP XAR1
.endm
;;*****************************************************************************
;; globals
;;*****************************************************************************
.if __TI_EABI__
.asg VITERBI_DECODER_runK7CR12, _VITERBI_DECODER_runK7CR12
.asg VITERBI_DECODER_initK7CR12, _VITERBI_DECODER_initK7CR12
.asg VITERBI_DECODER_rescaleK7CR12, _VITERBI_DECODER_rescaleK7CR12
.endif
.global _VITERBI_DECODER_runK7CR12
.global _VITERBI_DECODER_initK7CR12
.global _VITERBI_DECODER_rescaleK7CR12
_rescaleBuffer .usect ".ebss", 64, 1, 1
;;*****************************************************************************
;; function definitions
;;*****************************************************************************
.text
;;
;; \brief
;;
;; \param Handle to the structure, VITERBI_DECODER_DECODER_Obj(passed in XAR4)
;; - *+XAR4[0]: *pInBuffer -> Input buffer pointer
;; - *+XAR4[2]: *pOutBuffer -> Output buffer pointer
;; - *+XAR4[4]: *pTransitionHistory -> Transition History bits pointer
;; - *+XAR4[6]: *pBMSELInit -> Initialization value for the BMSEL register
;; - *+XAR4[8]: stateMetricInit -> Initialization value for the state metrics
;; - *+XAR4[9]: nBits -> Number of bits to be decoded
;; - *+XAR4[10]: constraintLength -> Constraint Length, i.e. K
;; - *+XAR4[11]: nStates -> #states = 2^(K - 1)
;; - *+XAR4[12]: codeRate -> The symbol code rate
;; - *+XAR4[13]: mode -> Viterbi mode enumerator
;; - *+XAR4[14]: *pTransitionStart1 -> Points to the start of the tranistion history buffer
;; - *+XAR4[16]: *pTransitionStart2 -> Points to the mid of the tranistion history buffer
;; - *+XAR4[18]: *pTransitionWrap1 -> Points to the mid of the tranistion history buffer
;; - *+XAR4[20]: *pTransitionWrap2 -> Points to the end of the tranistion history buffer
;; - *+XAR4[22]: *pTransitionTemp -> Points to a temporary(scratch) tranistion history buffer
;; \note
;; - The transition history buffer will have 5 pointers associated with it
;; - pTransitionHistory(hist_p): start of the transition history buffer
;; - pTransitionStart1(S1_p): points to where the transition update should start
;; - pTransitionStart2(S2_p: points to the mid point of the overlap(S1_p + 4*nUnencodedBits)
;; - pTransitionWrap1(W1_p): points to where trace overlap 2 should go (wrap, S1_p + 4*nUnencodedBits)
;; - pTransitionWrap2(W2_p): points to the end of the overlap(S1_p + 2*4*nUnencodedBits)
;;
;; CBITS = 128(coded bits per block)
;; UBITS = CBITS/2 = 64(uncoded bits per block)
;; UWORDS = 4 (4 words required to store UBITS)
;;
;; Transition history(bits per stage)--->
;; <-------64 bits----->
;; +----+----+----+----+ ^
;; S1_p->hist_p->| | | | | |
;; ^ | | | | | |
;; | | | | | | |
;; | | | | | | |
;; 4*UBITS | | | | | |
;; | | | | | | |
;; | | | | | | |
;; | | | | | | |
;; v | | | | | |
;; S2_p->W1_p->| | | | | 128 stages
;; ^ | | | | | |
;; | | | | | | |
;; | | | | | | |
;; 4*UBITS | | | | | |
;; | | | | | | |
;; | | | | | | |
;; | | | | | | |
;; v | | | | | |
;; W2_p->| | | | | |
;; +----+----+----+----+ v
;;
;; \return Decoded bits in the output buffer pointed by the VITERBI_DECODER_DECODER_Obj.pOutBuffer
;;
_VITERBI_DECODER_runK7CR12:
VITERBI_DECODER_CONTEXT_SAVE
;V.C.130217- suppose you have an input sequence 0x03020100, you would encode
; in the seqence 00, 01, 02 and 03. You decode in the exact opposite
; sequence 03, 02, 01 and 00 but with OPACK you pack from MSb of VR0 and
; end up with 0x00010203.
;
; Disabling OPACK, decode in order 03, 02, 01 and 00. PACK from lower end of VR0
; meaning your output looks like 0xc0408000, i.e. bit-reversed at each byte
;
; Using BITFLIP will reverse the register end to end so you endup with 0x00010203
; anyways, but we can use the Galois field instruction VREB to set it to 0x03020100
; (enable OPACK in this case)
;
VSETOPACK ; VSTATUS.OPACK = 1, start packing the decoded
; bits from trace back into VT1 starting from the
; MSb, this obviates the need to manually flip the
; result each time
SETC SXM ; Sign extension mode
SETC OVM ; Overflow mode(no saturation)
;;=============================================================================
;;
;; Register Usage
;; XAR0: Index into the structure members that exceed index of 7 from start of structure
;; /traceback overlap inner loop counter
;; /temp pointer to structure in the pointer swaps
;; XAR1: Pointer to the input LLR
;; /Index into the structure members that exceed index of 7 from start of structure
;; XAR2: Branch Metric Select
;; XAR3: Pointer to the Transition History Array(as well as S1_p, W1_p depending on modes)
;; /used in pointer swaps
;; XAR4: Pointer to the viterbi structure
;; XAR5: Output array
;; /used in pointer swaps
;; XAR6: Loop counter
;; XAR7: points to the temporary transition bit array
;; /Loop counter for metric update when nBits < 8
;; AL: Number of Input bits
;; AH:
;;
MOV AR0, #ARG_MODE
MOV AL, *+XAR4[AR0] ; Save the mode to the stack
MOV *-SP[STK_ARG_MODE], AL
MOVL XAR5, *+XAR4[ARG_OUTBUFFER] ; XAR5 -> output_array
MOV AR0, #ARG_NBITS
MOV AL, *+XAR4[AR0]
LSR AL, #1 ; AL = nBits/2
MOV *-SP[STK_ARG_NBITS], AL ; Save the number of bits to the stack
CMP AL, #0 ; Check if the number of output bits are not zero
BF _VITERBI_DECODER_runK7CR12_nonZeroACS, NEQ ; if so jump to the metric calculations
; Since nBits == 0 at this point
MOV AR0, #ARG_TRANS_W1 ; We need only proceed to traceback, Load the
MOVL XAR3, *+XAR4[AR0] ; the Wrap pointer(to the transition history buffer)
; and proceed to the decode phase directly
BF _VITERBI_DECODER_runK7CR12_overlapDecode, UNC
_VITERBI_DECODER_runK7CR12_nonZeroACS:
MOVZ AR7, AL ; AR7 = (nBits/2)
LSR AL, #1 ; AL = (nBits/2)/2. We process two stages per RPTB
SUBB AL, #2 ; loop_counter = nBits/4 - 1 - 1.
MOVZ AR6, AL ; we process 2 bits per stage and 2 stages per iteration of the RPTB which will
; itself iterates N+1 hence the first -1. The last two stages are performed outside the RPTB
; hence the second -1
MOVL XAR1,*+XAR4[ARG_INBUFFER]
MOVL XAR3,*+XAR4[ARG_TRANSHIST]
; if(mode==0/1) jump to metric calculations
; We wont be using the S1_p in this case
CMP *-SP[STK_ARG_MODE], #MODE_OVERLAPDECODE
BF _VITERBI_DECODER_runK7CR12_metricUpdate, LT
;else if(mode==2/3) we need to start saving transition bits to
MOV AR0, #ARG_TRANS_S1 ;address pointed to be S1_p
MOVL XAR3, *+XAR4[AR0]
_VITERBI_DECODER_runK7CR12_metricUpdate:
MOVL XAR2, *+XAR4[ARG_BMSELINIT] ; Initialize the BMSEL register for butterfly 0 to K-1
VMOV32 VR2, *XAR2++ ; Initialize BMSEL for butterfly 0 to 7
VMOV32 VR3, *XAR2++ ; Initialize BMSEL for butterfly 8 to 15
VMOV32 VR4, *XAR2++ ; Initialize BMSEL for butterfly 16 to 23
VMOV32 VR5, *XAR2++ ; Initialize BMSEL for butterfly 24 to 31
VITBM2 VR0, *XAR1++ ; Calculate and store BMs in VR0L and VR0H
MOV AL, AR7 ; AL = AR7 i.e. (nBits/2)
CMPB AL, #8 ; if(AL < 8) jump to metric(less than 8) calculations
BF _VITERBI_DECODER_runK7CR12_lessThan8MetricUpdate, LT
ANDB AL, #0x1 ; if(AL is odd)jump to metric(odd bits) calculations
BF _VITERBI_DECODER_runK7CR12_oddBitsMetricUpdate, NEQ
; else proceed with regular 2 stage RPTB metric updates
.align 2
RPTB _VITERBI_DECODER_runK7CR12_metricUpdateLoop, AR6
VITSTAGE ; Compute NSTATES/2 butterflies in parallel,
|| VITBM2 VR0, *XAR1++ ; compute branch metrics for next butterfly
VMOV32 *XAR3++, VT1 ; Store VT1
VMOV32 *XAR3++, VT0 ; Store VT0
VITSTAGE ; Compute NSTATES/2 butterflies in parallel,
|| VITBM2 VR0, *XAR1++ ; compute branch metrics for next butterfly
VMOV32 *XAR3++, VT1 ; Store VT1
VMOV32 *XAR3++, VT0 ; Store VT0
_VITERBI_DECODER_runK7CR12_metricUpdateLoop:
VITSTAGE ; Compute NSTATES/2 butterflies in parallel,
|| VITBM2 VR0, *XAR1++ ; compute branch metrics for next butterfly
VMOV32 *XAR3++, VT1 ; Store VT1
VMOV32 *XAR3++, VT0 ; Store VT0
VITSTAGE ; Compute NSTATES/2 butterflies in parallel,
VMOV32 *XAR3++, VT1 ; Store VT1
VMOV32 *XAR3++, VT0 ; Store VT0
_VITERBI_DECODER_runK7CR12_metricUpdateEnd:
BF _VITERBI_DECODER_runK7CR12_lessThan8MetricUpdateEnd, UNC
_VITERBI_DECODER_runK7CR12_oddBitsMetricUpdate:
_VITERBI_DECODER_runK7CR12_lessThan8MetricUpdate:
SUBB XAR7, #1 ; AR7 = (nBits/2) - 1
_VITERBI_DECODER_runK7CR12_lessThan8MetricUpdateLoop:
VITSTAGE ; Compute NSTATES/2 butterflies in parallel,
|| VITBM2 VR0, *XAR1++ ; compute branch metrics for next butterfly
VMOV32 *XAR3++, VT1 ; Store VT1
VMOV32 *XAR3++, VT0 ; Store VT0
BANZ _VITERBI_DECODER_runK7CR12_lessThan8MetricUpdateLoop, AR7--
_VITERBI_DECODER_runK7CR12_lessThan8MetricUpdateEnd:
; if(mode==1), we are processing first block so no trace/decode
CMP *-SP[STK_ARG_MODE], #MODE_OVERLAPINIT
BF _VITERBI_DECODER_runK7CR12_toggleSPointers, EQ
ZAPA ; else if(mode==2/3), we have calculated state metrics proceed to trace/decode
CMP *-SP[STK_ARG_MODE], #MODE_DECODEALL
BF _VITERBI_DECODER_runK7CR12_overlapDecode, NEQ
; else if(mode==0), we need to traceback in 1-shot(32-bit word per output bit)
MOV AL, *-SP[STK_ARG_NBITS] ; loop_counter = UBITS - (K-1) - 1 (last -1 is to account for loop iteration)
MOVZ AR6, AL ; UBITS = nBits/2
SUBB XAR6, #((CONSTRAINT_LENGTH-1)+1) ; K = constraint length
LSL AL, #1 ; AL = 2(sizeof 32-bits) * (nBits/2)
MOV AR0, #ARG_TRANS_TMP
MOVL XAR7, *+XAR4[AR0] ; XAR7 -> pTransitionTemp[nBits]
ADDL XAR7, ACC
RPT #((CONSTRAINT_LENGTH-1)*2 - 1 ) ; Zero out the last (K-1)*2 output bits
|| MOV *--XAR7, AH ;
; XAR7 -> pTransitionTemp[nBits - (K-1)]
VCLEAR VR0
VCLEAR VR1
_VITERBI_DECODER_runK7CR12_tracebackLoop1:
VMOV32 VT0, *--XAR3
VMOV32 VT1, *--XAR3
VTRACE *--XAR7, VR0, VT0, VT1
BANZ _VITERBI_DECODER_runK7CR12_tracebackLoop1, AR6--
; The end of MODE_DECODEALL, proceed to exit
BF _VITERBI_DECODER_runK7CR12_toggleWPointers, UNC
; mode == 2/3
_VITERBI_DECODER_runK7CR12_overlapDecode:
MOV AL, *-SP[STK_ARG_NBITS] ; loop_counter = (nBits/2 - 1)
MOVZ AR6, AL
SUBB XAR6, #1
;V.C.130218-not needed
;MOV AR0, #ARG_TRANS_TMP
;MOVL XAR7, *+XAR4[AR0]
VCLEAR VR0
VCLEAR VR1
; if(mode==2) go to trace/decode of regular sized block
CMP *-SP[STK_ARG_MODE], #MODE_OVERLAPLAST
BF _VITERBI_DECODER_runK7CR12_tracebackLoopOverlap1, NEQ
; else(mode==3) trace/decode of irregular sized block
; note: loop_counter = 64-(K-1)-1, but when nBits = 0 AR6 = -1
; so we must compensate for the -1 by making loop_counter = 64-(K-1)
ADDB XAR6, #(BLOCK_SIZE - (CONSTRAINT_LENGTH-1))
MOV AL, AR6 ; loop_counter = [((nBits/2 - 1) + (nBits/2 - (K-1))] {prev_blk + cur_blk -2*(K-1) -1(loop)}
AND AL, #0x1F ;
MOV AR0, AL ; inner_loop_counter = loop_counter % 32
; mode == 3 OVERLAPLAST
_VITERBI_DECODER_runK7CR12_tracebackLoopOverlap0:
VMOV32 VT0, *--XAR3
VMOV32 VT1, *--XAR3
VTRACE VR1, VR0, VT0, VT1
;if(trace<32 bits) goto overlap0 end
BANZ _VITERBI_DECODER_runK7CR12_tracebackLoopOverlap0End, AR0--
VREVB VR1 ; Reverse VR1
VMOV32 *--XAR5, VR1 ;else(32-bits were traced and accumulated) store to output memory
MOVB XAR0, #31 ; inner_loop_counter += 32
_VITERBI_DECODER_runK7CR12_tracebackLoopOverlap0End:
MOV AL, AR6 ;if(loop_counter!=(nBits/2 - (K-1))) goto end1 of overlap 0
CMPB AL, #(BLOCK_SIZE - (CONSTRAINT_LENGTH-1))
BF _VITERBI_DECODER_runK7CR12_tracebackLoopOverlap0End1, NEQ
MOV AR1, #ARG_TRANS_W1 ;else(loop_counter==(nBits/2 - (K-1)))switch trans history pointer from S1 to W1
MOVL XAR3, *+XAR4[AR1]
;if(loop_counter!=0) goto overlap 0
_VITERBI_DECODER_runK7CR12_tracebackLoopOverlap0End1:
BANZ _VITERBI_DECODER_runK7CR12_tracebackLoopOverlap0, AR6--
;else(loop_counter==0) goto toggle S pointers
BF _VITERBI_DECODER_runK7CR12_toggleSPointers, UNC
; mode == 2 OVERLAPDECODE
_VITERBI_DECODER_runK7CR12_tracebackLoopOverlap1:
; For any viterbi stage K
VMOV32 VT0, *--XAR3
VMOV32 VT1, *--XAR3
VTRACE VR1, VR0, VT0, VT1
;if(loop_counter!=0) goto overlap 1
BANZ _VITERBI_DECODER_runK7CR12_tracebackLoopOverlap1, AR6--
;else(loop_counter==0), trace/decode from 2nd half of block
MOV AR0, #ARG_TRANS_W1 ;The 2nd half of the block actually produces decode bits to output
MOVL XAR3, *+XAR4[AR0] ;when overlapping is used
VMOV32 VT0, *--XAR3
.align 2 ;Decoding the first 32-bits, 6 of which are already in VR1 from overlap 1
NOP ;odd aligning the repeat block
RPTB _VITERBI_DECODER_runK7CR12_tracebackLoopOverlap2, #12
VMOV32 VT1, *--XAR3
VTRACE VR1, VR0, VT0, VT1
|| VMOV32 VT0, *--XAR3
VMOV32 VT1, *--XAR3
VTRACE VR1, VR0, VT0, VT1
|| VMOV32 VT0, *--XAR3
_VITERBI_DECODER_runK7CR12_tracebackLoopOverlap2:
VREVB VR1 ; Reverse VR1
VMOV32 *+XAR5[2], VR1
.align 2 ;Decoding the second 32-bits
NOP ;odd aligning the repeat block
RPTB _VITERBI_DECODER_runK7CR12_tracebackLoopOverlap3, #15
VMOV32 VT1, *--XAR3
VTRACE VR1, VR0, VT0, VT1
|| VMOV32 VT0, *--XAR3
VMOV32 VT1, *--XAR3
VTRACE VR1, VR0, VT0, VT1
|| VMOV32 VT0, *--XAR3
_VITERBI_DECODER_runK7CR12_tracebackLoopOverlap3:
VREVB VR1 ; Reverse VR1
VMOV32 *XAR5, VR1
_VITERBI_DECODER_runK7CR12_toggleWPointers:
MOVL XAR0, XAR4
ADDB XAR0, #ARG_TRANS_W1
MOVL XAR3, *XAR0++
MOVL XAR5, *XAR0
MOVL *XAR0, XAR3
MOVL *--XAR0, XAR5
_VITERBI_DECODER_runK7CR12_toggleSPointers:
MOVL XAR0, XAR4
ADDB XAR0, #ARG_TRANS_S1
MOVL XAR3, *XAR0++
MOVL XAR5, *XAR0
MOVL *XAR0, XAR3
MOVL *--XAR0, XAR5
VITERBI_DECODER_CONTEXT_RESTORE
LRETR
;;*****************************************************************************
;;
;; \brief Initializes the constraint length and state metrics
;;
;; \param Handle to the structure, VITERBI_DECODER_Obj(passed in XAR4)
;; - *+XAR4[0]: *pInBuffer -> Input buffer pointer
;; - *+XAR4[2]: *pOutBuffer -> Output buffer pointer
;; - *+XAR4[4]: *pTransitionHistory -> Transition History bits pointer
;; - *+XAR4[6]: *pBMSELInit -> Initialization value for the BMSEL register
;; - *+XAR4[8]: stateMetricInit -> Initialization value for the state metrics
;; - *+XAR4[9]: nBits -> Number of bits to be decoded
;; - *+XAR4[10]: constraintLength -> Constraint Length, i.e. K
;; - *+XAR4[11]: nStates -> #states = 2^(K - 1)
;; - *+XAR4[12]: codeRate -> The symbol code rate
;; - *+XAR4[13]: mode -> Viterbi mode enumerator
;; - *+XAR4[14]: *pTransitionStart1 -> Points to the start of the tranistion history buffer
;; - *+XAR4[16]: *pTransitionStart2 -> Points to the mid of the tranistion history buffer
;; - *+XAR4[18]: *pTransitionWrap1 -> Points to the mid of the tranistion history buffer
;; - *+XAR4[20]: *pTransitionWrap2 -> Points to the end of the tranistion history buffer
;; - *+XAR4[22]: *pTransitionTemp -> Points to a temporary(scratch) tranistion history buffer
;;
_VITERBI_DECODER_initK7CR12:
VTCLEAR ; Clear the transition bits
VSETK #CONSTRAINT_LENGTH ; Set constraint length
MOV AR0, #ARG_SMETRICINIT
VSMINIT *+XAR4[AR0] ; Initialize the state metrics
LRETR
;;*****************************************************************************
;;
;; \brief Rescale the state metrics to prevent overflow
;;
;; \param Handle to the structure, VITERBI_DECODER_Obj(passed in XAR4)
;; - *+XAR4[0]: *pInBuffer -> Input buffer pointer
;; - *+XAR4[2]: *pOutBuffer -> Output buffer pointer
;; - *+XAR4[4]: *pTransitionHistory -> Transition History bits pointer
;; - *+XAR4[6]: *pBMSELInit -> Initialization value for the BMSEL register
;; - *+XAR4[8]: stateMetricInit -> Initialization value for the state metrics
;; - *+XAR4[9]: nBits -> Number of bits to be decoded
;; - *+XAR4[10]: constraintLength -> Constraint Length, i.e. K
;; - *+XAR4[11]: nStates -> #states = 2^(K - 1)
;; - *+XAR4[12]: codeRate -> The symbol code rate
;; - *+XAR4[13]: mode -> Viterbi mode enumerator
;; - *+XAR4[14]: *pTransitionStart1 -> Points to the start of the tranistion history buffer
;; - *+XAR4[16]: *pTransitionStart2 -> Points to the mid of the tranistion history buffer
;; - *+XAR4[18]: *pTransitionWrap1 -> Points to the mid of the tranistion history buffer
;; - *+XAR4[20]: *pTransitionWrap2 -> Points to the end of the tranistion history buffer
;; - *+XAR4[22]: *pTransitionTemp -> Points to a temporary(scratch) tranistion history buffer
;;
;; \notes
;; - CAUTION: VCU regs being memory mapped is internal info, find alternative to this function
;;
;;=============================================================================
;;
;; Register Usage
;; XAR0:
;; XAR1:
;; XAR2: loop counter
;; XAR3:
;; XAR4: Pointer to the viterbi structure
;; XAR5: Pointer to state metrics
;; XAR6: copy of XAR5
;; XAR7:
;; AL: min metric
;; AH:
;;
_VITERBI_DECODER_rescaleK7CR12:
PUSH XAR2 ; save off XAR2
SETC SXM, OVM ; set sign extension and overflow mode
MOV AL, #0x7FFF ; AL will store the minimum metric
MOVL XAR5, #_rescaleBuffer ; Load address of rescale buffer into XAR5
MOVL XAR6, XAR5
MOVL XAR7, XAR5
VMOV32 *XAR5++, VSM63: VSM62
VMOV32 *XAR5++, VSM61: VSM60
VMOV32 *XAR5++, VSM59: VSM58
VMOV32 *XAR5++, VSM57: VSM56
VMOV32 *XAR5++, VSM55: VSM54
VMOV32 *XAR5++, VSM53: VSM52
VMOV32 *XAR5++, VSM51: VSM50
VMOV32 *XAR5++, VSM49: VSM48
VMOV32 *XAR5++, VSM47: VSM46
VMOV32 *XAR5++, VSM45: VSM44
VMOV32 *XAR5++, VSM43: VSM42
VMOV32 *XAR5++, VSM41: VSM40
VMOV32 *XAR5++, VSM39: VSM38
VMOV32 *XAR5++, VSM37: VSM36
VMOV32 *XAR5++, VSM35: VSM34
VMOV32 *XAR5++, VSM33: VSM32
VMOV32 *XAR5++, VSM31: VSM30
VMOV32 *XAR5++, VSM29: VSM28
VMOV32 *XAR5++, VSM27: VSM26
VMOV32 *XAR5++, VSM25: VSM24
VMOV32 *XAR5++, VSM23: VSM22
VMOV32 *XAR5++, VSM21: VSM20
VMOV32 *XAR5++, VSM19: VSM18
VMOV32 *XAR5++, VSM17: VSM16
VMOV32 *XAR5++, VSM15: VSM14
VMOV32 *XAR5++, VSM13: VSM12
VMOV32 *XAR5++, VSM11: VSM10
VMOV32 *XAR5++, VSM9: VSM8
VMOV32 *XAR5++, VSM7: VSM6
VMOV32 *XAR5++, VSM5: VSM4
VMOV32 *XAR5++, VSM3: VSM2
VMOV32 *XAR5++, VSM1: VSM0
RPT #(NSTATES - 1)
|| MIN AL, *--XAR5
MOV AR2, #((NSTATES >> 3)-1)
_VITERBI_DECODER_rescaleK7CR12_loop:
SUB *XAR6++ , AL
SUB *XAR6++ , AL
SUB *XAR6++ , AL
SUB *XAR6++ , AL
SUB *XAR6++ , AL
SUB *XAR6++ , AL
SUB *XAR6++ , AL
SUB *XAR6++ , AL
BANZ _VITERBI_DECODER_rescaleK7CR12_loop, AR2--
VMOV32 VSM63: VSM62, *XAR7++
VMOV32 VSM61: VSM60, *XAR7++
VMOV32 VSM59: VSM58, *XAR7++
VMOV32 VSM57: VSM56, *XAR7++
VMOV32 VSM55: VSM54, *XAR7++
VMOV32 VSM53: VSM52, *XAR7++
VMOV32 VSM51: VSM50, *XAR7++
VMOV32 VSM49: VSM48, *XAR7++
VMOV32 VSM47: VSM46, *XAR7++
VMOV32 VSM45: VSM44, *XAR7++
VMOV32 VSM43: VSM42, *XAR7++
VMOV32 VSM41: VSM40, *XAR7++
VMOV32 VSM39: VSM38, *XAR7++
VMOV32 VSM37: VSM36, *XAR7++
VMOV32 VSM35: VSM34, *XAR7++
VMOV32 VSM33: VSM32, *XAR7++
VMOV32 VSM31: VSM30, *XAR7++
VMOV32 VSM29: VSM28, *XAR7++
VMOV32 VSM27: VSM26, *XAR7++
VMOV32 VSM25: VSM24, *XAR7++
VMOV32 VSM23: VSM22, *XAR7++
VMOV32 VSM21: VSM20, *XAR7++
VMOV32 VSM19: VSM18, *XAR7++
VMOV32 VSM17: VSM16, *XAR7++
VMOV32 VSM15: VSM14, *XAR7++
VMOV32 VSM13: VSM12, *XAR7++
VMOV32 VSM11: VSM10 , *XAR7++
VMOV32 VSM9: VSM8 , *XAR7++
VMOV32 VSM7: VSM6 , *XAR7++
VMOV32 VSM5: VSM4 , *XAR7++
VMOV32 VSM3: VSM2 , *XAR7++
VMOV32 VSM1: VSM0 , *XAR7
POP XAR2
LRETR
;; End of File