mirror of
https://github.com/marqs85/ossc
synced 2025-04-09 22:56:34 +03:00
225 lines
11 KiB
C
225 lines
11 KiB
C
/******************************************************************************
|
|
* *
|
|
* License Agreement *
|
|
* *
|
|
* Copyright (c) 2008 Altera Corporation, San Jose, California, USA. *
|
|
* All rights reserved. *
|
|
* *
|
|
* Permission is hereby granted, free of charge, to any person obtaining a *
|
|
* copy of this software and associated documentation files (the "Software"), *
|
|
* to deal in the Software without restriction, including without limitation *
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
|
|
* and/or sell copies of the Software, and to permit persons to whom the *
|
|
* Software is furnished to do so, subject to the following conditions: *
|
|
* *
|
|
* The above copyright notice and this permission notice shall be included in *
|
|
* all copies or substantial portions of the Software. *
|
|
* *
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
|
|
* DEALINGS IN THE SOFTWARE. *
|
|
* *
|
|
* This agreement shall be governed in all respects by the laws of the State *
|
|
* of California and by the laws of the United States of America. *
|
|
* Altera does not recommend, suggest or require that this reference design *
|
|
* file be used in conjunction or combination with any other product. *
|
|
******************************************************************************/
|
|
|
|
|
|
/******************************************************************************
|
|
* Author - JCJB *
|
|
* *
|
|
* This design uses the following CRC-32 implementations: *
|
|
* *
|
|
* --> Software - Uses modulo 2 division to perform the remainder calculation. *
|
|
* --> Optimized Software - Uses a lookup table of all possible division *
|
|
* values. The calculation operates on 8 bit data. *
|
|
* --> Custom Instruction - Uses a parallel hardware CRC circuit to calculate *
|
|
* the remainder. The calculation operates on 8, *
|
|
* 16, 24, or 32 bit data. *
|
|
* *
|
|
* The software implementations can be changed to CRC-16 or CRC-CCITT however *
|
|
* the custom instruction must be modified as well to support the same *
|
|
* standard. Simply use the values defined in crc.h to change the standard *
|
|
* used (using the same values in the hardware parameterization) or define *
|
|
* your own standard. *
|
|
*******************************************************************************/
|
|
|
|
#include "system.h"
|
|
#include "stdio.h"
|
|
#include "crc.h"
|
|
#include "ci_crc.h"
|
|
#include "sys/alt_timestamp.h"
|
|
#include "stdlib.h"
|
|
|
|
|
|
/* Modify these values to adjust the test being performed */
|
|
#define NUMBER_OF_BUFFERS 32
|
|
#define BUFFER_SIZE 256 /* in bytes */
|
|
|
|
/* Change the name of memory device according to what you are using
|
|
* e.g.: DDR_SDRAM_0 ##_SPAN
|
|
* SSRAM_0 ##_SPAN
|
|
*/
|
|
#define MEMORY_DEVICE_SIZE 32768
|
|
|
|
|
|
/* Make sure there is room left for Nios II text, rodata, rwdata, stack,
|
|
* and heap. This software and the buffer space must fit within the
|
|
* size of memory device. A total of 1.5 MBytes is reserved. If BUFFER_SIZE
|
|
* is a multiple of four then exactly 256kB will be left, otherwise is
|
|
* amount will be less since the column dimension needs some padding to
|
|
* stay 32 bit aligned
|
|
*/
|
|
#if ((BUFFER_SIZE * NUMBER_OF_BUFFERS) >= MEMORY_DEVICE_SIZE - 10000)
|
|
#error Your buffer space has exceeded the maximum allowable space. Please\
|
|
reduce the buffer space so that there is enough room to hold Nios II\
|
|
code.
|
|
#endif
|
|
|
|
|
|
/* This will line up the data onto a 32 bit (or greater) boundary. A 2d array
|
|
* is being used here for simplicity. The first dimension represents a byte
|
|
* of data and the second dimension represents an individual buffer
|
|
*/
|
|
#if ((BUFFER_SIZE & 0x3) == 0)
|
|
unsigned char data_buffer_region[NUMBER_OF_BUFFERS][BUFFER_SIZE] __attribute__ ((aligned(4)));
|
|
#else /* need to allocate extra bytes so that all buffers start on a 32 bit
|
|
boundaries by rounding up the column dimension to the next power of 4
|
|
*/
|
|
unsigned char data_buffer_region[NUMBER_OF_BUFFERS][BUFFER_SIZE + 4 - (BUFFER_SIZE&0x3)] __attribute__ ((aligned(4)));
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
int main()
|
|
{
|
|
unsigned long buffer_counter, data_counter;
|
|
unsigned long sw_slow_results[NUMBER_OF_BUFFERS];
|
|
unsigned long sw_fast_results[NUMBER_OF_BUFFERS];
|
|
unsigned long ci_results[NUMBER_OF_BUFFERS];
|
|
unsigned char random_data = 0x5A;
|
|
//unsigned long sw_slow_timeA, sw_slow_timeB;
|
|
// unsigned long sw_fast_timeA, sw_fast_timeB;
|
|
// unsigned long ci_timeA, ci_timeB;
|
|
|
|
alt_u32 sw_slow_timeA, sw_slow_timeB;
|
|
alt_u32 sw_fast_timeA, sw_fast_timeB;
|
|
alt_u32 ci_timeA, ci_timeB;
|
|
|
|
|
|
printf("+-----------------------------------------------------------+\n");
|
|
printf("| Comparison between software and custom instruction CRC32 |\n");
|
|
printf("+-----------------------------------------------------------+\n\n\n");
|
|
|
|
printf("System specification\n");
|
|
printf("--------------------\n");
|
|
|
|
printf("System clock speed = %lu MHz\n", (unsigned long)ALT_CPU_FREQ /(unsigned long)1000000);
|
|
printf("Number of buffer locations = %d\n", NUMBER_OF_BUFFERS);
|
|
printf("Size of each buffer = %d bytes\n\n\n", BUFFER_SIZE);
|
|
|
|
|
|
/* Initializing the data buffers */
|
|
printf("Initializing all of the buffers with pseudo-random data\n");
|
|
printf("-------------------------------------------------------\n");
|
|
for(buffer_counter = 0; buffer_counter < NUMBER_OF_BUFFERS; buffer_counter++)
|
|
{
|
|
for(data_counter = 0; data_counter < BUFFER_SIZE; data_counter++)
|
|
{
|
|
data_buffer_region[buffer_counter][data_counter] = random_data;
|
|
random_data = (random_data >> 4) + (random_data << 4) + (data_counter & 0xFF);
|
|
}
|
|
}
|
|
printf("Initialization completed\n\n\n");
|
|
|
|
|
|
if(alt_timestamp_start() < 0) // starts the timestamp timer
|
|
{
|
|
printf("Please add the high resolution timer to the timestamp timer setting in the syslib properties page.\n");
|
|
exit(1);
|
|
}
|
|
|
|
|
|
/* Slow software CRC based on a modulo 2 division implementation */
|
|
printf("Running the software CRC\n");
|
|
printf("------------------------\n");
|
|
sw_slow_timeA = alt_timestamp();
|
|
|
|
for(buffer_counter = 0; buffer_counter < NUMBER_OF_BUFFERS; buffer_counter++)
|
|
{
|
|
sw_slow_results[buffer_counter] = crcSlow(data_buffer_region[buffer_counter], BUFFER_SIZE);
|
|
}
|
|
sw_slow_timeB = alt_timestamp();
|
|
|
|
printf("Completed\n\n\n");
|
|
|
|
|
|
/* Fast software CRC based on a lookup table implementation */
|
|
crcInit();
|
|
printf("Running the optimized software CRC\n");
|
|
printf("----------------------------------\n");
|
|
sw_fast_timeA = alt_timestamp();
|
|
for(buffer_counter = 0; buffer_counter < NUMBER_OF_BUFFERS; buffer_counter++)
|
|
{
|
|
sw_fast_results[buffer_counter] = crcFast(data_buffer_region[buffer_counter], BUFFER_SIZE);
|
|
}
|
|
sw_fast_timeB = alt_timestamp();
|
|
printf("Completed\n\n\n");
|
|
|
|
|
|
/* Custom instruction CRC */
|
|
printf("Running the custom instruction CRC\n");
|
|
printf("----------------------------------\n");
|
|
ci_timeA = alt_timestamp();
|
|
for(buffer_counter = 0; buffer_counter < NUMBER_OF_BUFFERS; buffer_counter++)
|
|
{
|
|
ci_results[buffer_counter] = crcCI(data_buffer_region[buffer_counter], BUFFER_SIZE);
|
|
}
|
|
ci_timeB = alt_timestamp();
|
|
printf("Completed\n\n\n");
|
|
|
|
/* Validation of results */
|
|
printf("Validating the CRC results from all implementations\n");
|
|
printf("----------------------------------------------------\n");
|
|
for(buffer_counter = 0; buffer_counter < NUMBER_OF_BUFFERS; buffer_counter++)
|
|
{
|
|
/* Test every combination of results to make sure they are consistant */
|
|
if((sw_slow_results[buffer_counter] != ci_results[buffer_counter]) |
|
|
(sw_fast_results[buffer_counter] != ci_results[buffer_counter]))
|
|
{
|
|
printf("FAILURE! Software CRC = 0x%lx, Optimized Software CRC = 0x%lx, Custom Instruction CRC = 0x%lx,\n",
|
|
sw_slow_results[buffer_counter], sw_fast_results[buffer_counter], ci_results[buffer_counter]);
|
|
exit(1);
|
|
}
|
|
}
|
|
printf("All CRC implementations produced the same results\n\n\n");
|
|
|
|
|
|
// Report processing times
|
|
printf("Processing time for each implementation\n");
|
|
printf("---------------------------------------\n");
|
|
printf("Software CRC = %.2lu ms\n", 1000*((unsigned long)(sw_slow_timeB-sw_slow_timeA))/((unsigned long)alt_timestamp_freq()));
|
|
printf("Optimized software CRC = %.2lu ms\n", 1000*((unsigned long)(sw_fast_timeB-sw_fast_timeA))/((unsigned long)alt_timestamp_freq()));
|
|
printf("Custom instruction CRC = %.2lu ms\n\n\n", 1000*((unsigned long)(ci_timeB-ci_timeA))/((unsigned long)alt_timestamp_freq()));
|
|
|
|
printf("Processing throughput for each implementation\n"); // throughput = total bits / (time(s) * 1000000)
|
|
printf("---------------------------------------------\n");
|
|
printf("Software CRC = %.2lu Mbps\n", (8 * NUMBER_OF_BUFFERS * BUFFER_SIZE)/(1000000*(unsigned long)(sw_slow_timeB-sw_slow_timeA)/((unsigned long)alt_timestamp_freq())));
|
|
printf("Optimized software CRC = %.2lu Mbps\n", (8 * NUMBER_OF_BUFFERS * BUFFER_SIZE)/(1000000*(unsigned long)(sw_fast_timeB-sw_fast_timeA)/((unsigned long)alt_timestamp_freq())));
|
|
printf("Custom instruction CRC = %.2lu Mbps\n\n\n", (8 * NUMBER_OF_BUFFERS * BUFFER_SIZE)/(1000000*(unsigned long)(ci_timeB-ci_timeA)/((unsigned long)alt_timestamp_freq())));
|
|
|
|
printf("Speedup ratio\n");
|
|
printf("-------------\n");
|
|
printf("Custom instruction CRC vs software CRC = %lu\n", ((unsigned long)(sw_slow_timeB-sw_slow_timeA))/((unsigned long)(ci_timeB-ci_timeA)));
|
|
printf("Custom instruction CRC vs optimized software CRC = %lu\n", ((unsigned long)(sw_fast_timeB-sw_fast_timeA))/((unsigned long)(ci_timeB-ci_timeA)));
|
|
printf("Optimized software CRC vs software CRC= %lu\n", ((unsigned long)(sw_slow_timeB-sw_slow_timeA))/((unsigned long)(sw_fast_timeB-sw_fast_timeA)));
|
|
return 0;
|
|
}
|