integrate zero-riscy

This commit is contained in:
marqs 2018-10-06 01:07:53 +03:00
parent e1d8446752
commit 4676cbd2f0
44 changed files with 11897 additions and 9998 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "ip/pulpino_qsys"]
path = ip/pulpino_qsys
url = https://github.com/marqs85/pulpino_qsys.git

View File

@ -1,56 +0,0 @@
// (C) 2001-2015 Altera Corporation. All rights reserved.
// Your use of Altera Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// files any of the foregoing (including device programming or simulation
// files), and any associated documentation or information are expressly subject
// to the terms and conditions of the Altera Program License Subscription
// Agreement, Altera MegaCore Function License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Altera and sold by
// Altera or its authorized distributors. Please refer to the applicable
// agreement for further details.
//Legal Notice: (C)2010 Altera Corporation. All rights reserved. Your
//use of Altera Corporation's design tools, logic functions and other
//software and tools, and its AMPP partner logic functions, and any
//output files any of the foregoing (including device programming or
//simulation files), and any associated documentation or information are
//expressly subject to the terms and conditions of the Altera Program
//License Subscription Agreement or other applicable license agreement,
//including, without limitation, that your use is for the sole purpose
//of programming logic devices manufactured by Altera and sold by Altera
//or its authorized distributors. Please refer to the applicable
//agreement for further details.
// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on
// turn off superfluous verilog processor warnings
// altera message_level Level1
// altera message_off 10034 10035 10036 10037 10230 10240 10030
module endianconverter_qsys (
// inputs:
dataa,
datab,
// outputs:
result
)
;
output [ 31: 0] result;
input [ 31: 0] dataa;
input [ 31: 0] datab;
wire [ 31: 0] result;
//s1, which is an e_custom_instruction_slave
assign result[7 : 0] = dataa[31 : 24];
assign result[15 : 8] = dataa[23 : 16];
assign result[23 : 16] = dataa[15 : 8];
assign result[31 : 24] = dataa[7 : 0];
endmodule

View File

@ -1,84 +0,0 @@
# (C) 2001-2015 Altera Corporation. All rights reserved.
# Your use of Altera Corporation's design tools, logic functions and other
# software and tools, and its AMPP partner logic functions, and any output
# files any of the foregoing (including device programming or simulation
# files), and any associated documentation or information are expressly subject
# to the terms and conditions of the Altera Program License Subscription
# Agreement, Altera MegaCore Function License Agreement, or other applicable
# license agreement, including, without limitation, that your use is for the
# sole purpose of programming logic devices manufactured by Altera and sold by
# Altera or its authorized distributors. Please refer to the applicable
# agreement for further details.
# TCL File Generated by Component Editor 10.1
# Tue Aug 17 15:04:48 MYT 2010
# DO NOT MODIFY
# +-----------------------------------
# |
# |
# | ./converter_0.v syn, sim
# |
# +-----------------------------------
# +-----------------------------------
# | request TCL package from ACDS 10.1
# |
package require -exact sopc 10.1
# |
# +-----------------------------------
# +-----------------------------------
# | module altera_nios_custom_instr_endian_converter
# |
set_module_property NAME altera_nios_custom_instr_endianconverter
set_module_property VERSION 17.1
set_module_property INTERNAL false
set_module_property GROUP "Custom Instruction Modules"
set_module_property AUTHOR "Altera Corporation"
set_module_property DISPLAY_NAME "Endian Converter"
set_module_property HIDE_FROM_SOPC true
set_module_property TOP_LEVEL_HDL_FILE endianconverter_qsys.v
set_module_property TOP_LEVEL_HDL_MODULE endianconverter_qsys
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
set_module_property SIMULATION_MODEL_IN_VHDL true
set_module_property EDITABLE false
set_module_property ANALYZE_HDL FALSE
# |
# +-----------------------------------
# +-----------------------------------
# | files
# |
add_file endianconverter_qsys.v {SYNTHESIS SIMULATION}
# |
# +-----------------------------------
# +-----------------------------------
# | parameters
# |
# |
# +-----------------------------------
# +-----------------------------------
# | display items
# |
# |
# +-----------------------------------
# +-----------------------------------
# | connection point s1
# |
add_interface s1 nios_custom_instruction end
set_interface_property s1 clockCycle 1
set_interface_property s1 operands 1
set_interface_property s1 ENABLED true
add_interface_port s1 dataa dataa Input 32
add_interface_port s1 datab datab Input 32
add_interface_port s1 result result Output 32
# |
# +-----------------------------------

View File

@ -1,224 +0,0 @@
/******************************************************************************
* *
* 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;
}

View File

@ -1,97 +0,0 @@
/******************************************************************************
* *
* 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. *
******************************************************************************/
/**********************************************************************
*
* Filename: ci_crc.c
*
* Description: Custom instruction implementations of the CRC.
*
* Notes: A macro is defined that is used to access the CRC custom
* instruction.
*********************************************************************/
#include "system.h"
/*The n values and their corresponding operation are as follow:
* n = 0, Initialize the custom instruction to the initial remainder value
* n = 1, Write 8 bits data to custom instruction
* n = 2, Write 16 bits data to custom instruction
* n = 3, Write 32 bits data to custom instruction
* n = 4, Read 32 bits data from the custom instruction
* n = 5, Read 64 bits data from the custom instruction
* n = 6, Read 96 bits data from the custom instruction
* n = 7, Read 128 bits data from the custom instruction*/
#define CRC_CI_MACRO(n, A) __builtin_custom_ini(ALT_CI_NIOS2_HW_CRC32_0_N + (n & 0x7), (A))
unsigned long crcCI(unsigned char * input_data, unsigned long input_data_length, int do_initialize)
{
unsigned long index;
/* copy of the data buffer pointer so that it can advance by different widths */
void * input_data_copy = (void *)input_data;
/* The custom instruction CRC will initialize to the inital remainder value */
if (do_initialize)
CRC_CI_MACRO(0,0);
/* Write 32 bit data to the custom instruction. If the buffer does not end
* on a 32 bit boundary then the remaining data will be sent to the custom
* instruction in the 'if' statement below.
*/
for(index = 0; index < (input_data_length & 0xFFFFFFFC); index+=4)
{
CRC_CI_MACRO(3, *(unsigned long *)input_data_copy);
input_data_copy += 4; /* void pointer, must move by 4 for each word */
}
/* Write the remainder of the buffer if it does not end on a word boundary */
if((input_data_length & 0x3) == 0x3) /* 3 bytes left */
{
CRC_CI_MACRO(2, *(unsigned short *)input_data_copy);
input_data_copy += 2;
CRC_CI_MACRO(1, *(unsigned char *)input_data_copy);
}
else if((input_data_length & 0x3) == 0x2) /* 2 bytes left */
{
CRC_CI_MACRO(2, *(unsigned short *)input_data_copy);
}
else if((input_data_length & 0x3) == 0x1) /* 1 byte left */
{
CRC_CI_MACRO(1, *(unsigned char *)input_data_copy);
}
/* There are 4 registers in the CRC custom instruction. Since
* this example uses CRC-32 only the first register must be read
* in order to receive the full result.
*/
return CRC_CI_MACRO(4, 0);
}

View File

@ -1,265 +0,0 @@
/******************************************************************************
* *
* 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. *
******************************************************************************/
/**********************************************************************
*
* Filename: crc.c
*
* Description: Slow and fast implementations of the CRC standards.
*
* Notes: The parameters for each supported CRC standard are
* defined in the header file crc.h. The implementations
* here should stand up to further additions to that list.
*
*
* Copyright (c) 2000 by Michael Barr. This software is placed into
* the public domain and may be used for any purpose. However, this
* notice must not be changed or removed and no warranty is either
* expressed or implied by its publication or distribution.
**********************************************************************/
#include "crc.h"
/*
* Derive parameters from the standard-specific parameters in crc.h.
*/
#define WIDTH (8 * sizeof(crc))
#define TOPBIT (1 << (WIDTH - 1))
#if (REFLECT_DATA == TRUE)
#undef REFLECT_DATA
#define REFLECT_DATA(X) ((unsigned char) reflect((X), 8))
#else
#undef REFLECT_DATA
#define REFLECT_DATA(X) (X)
#endif
#if (REFLECT_REMAINDER == TRUE)
#undef REFLECT_REMAINDER
#define REFLECT_REMAINDER(X) ((crc) reflect((X), WIDTH))
#else
#undef REFLECT_REMAINDER
#define REFLECT_REMAINDER(X) (X)
#endif
/*********************************************************************
*
* Function: reflect()
*
* Description: Reorder the bits of a binary sequence, by reflecting
* them about the middle position.
*
* Notes: No checking is done that nBits <= 32.
*
* Returns: The reflection of the original data.
*
*********************************************************************/
static unsigned long
reflect(unsigned long data, unsigned char nBits)
{
unsigned long reflection = 0x00000000;
unsigned char bit;
/*
* Reflect the data about the center bit.
*/
for (bit = 0; bit < nBits; ++bit)
{
/*
* If the LSB bit is set, set the reflection of it.
*/
if (data & 0x01)
{
reflection |= (1 << ((nBits - 1) - bit));
}
data = (data >> 1);
}
return (reflection);
} /* reflect() */
/*********************************************************************
*
* Function: crcSlow()
*
* Description: Compute the CRC of a given message.
*
* Notes:
*
* Returns: The CRC of the message.
*
*********************************************************************/
crc
crcSlow(unsigned char const message[], int nBytes)
{
crc remainder = INITIAL_REMAINDER;
int byte;
unsigned char bit;
/*
* Perform modulo-2 division, a byte at a time.
*/
for (byte = 0; byte < nBytes; ++byte)
{
/*
* Bring the next byte into the remainder.
*/
remainder ^= (REFLECT_DATA(message[byte]) << (WIDTH - 8));
/*
* Perform modulo-2 division, a bit at a time.
*/
for (bit = 8; bit > 0; --bit)
{
/*
* Try to divide the current data bit.
*/
if (remainder & TOPBIT)
{
remainder = (remainder << 1) ^ POLYNOMIAL;
}
else
{
remainder = (remainder << 1);
}
}
}
/*
* The final remainder is the CRC result.
*/
return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE);
} /* crcSlow() */
crc crcTable[256];
/*********************************************************************
*
* Function: crcInit()
*
* Description: Populate the partial CRC lookup table.
*
* Notes: This function must be rerun any time the CRC standard
* is changed. If desired, it can be run "offline" and
* the table results stored in an embedded system's ROM.
*
* Returns: None defined.
*
*********************************************************************/
void
crcInit(void)
{
crc remainder;
int dividend;
unsigned char bit;
/*
* Compute the remainder of each possible dividend.
*/
for (dividend = 0; dividend < 256; ++dividend)
{
/*
* Start with the dividend followed by zeros.
*/
remainder = dividend << (WIDTH - 8);
/*
* Perform modulo-2 division, a bit at a time.
*/
for (bit = 8; bit > 0; --bit)
{
/*
* Try to divide the current data bit.
*/
if (remainder & TOPBIT)
{
remainder = (remainder << 1) ^ POLYNOMIAL;
}
else
{
remainder = (remainder << 1);
}
}
/*
* Store the result into the table.
*/
crcTable[dividend] = remainder;
}
} /* crcInit() */
/*********************************************************************
*
* Function: crcFast()
*
* Description: Compute the CRC of a given message.
*
* Notes: crcInit() must be called first.
*
* Returns: The CRC of the message.
*
*********************************************************************/
crc
crcFast(unsigned char const message[], int nBytes)
{
crc remainder = INITIAL_REMAINDER;
unsigned char data;
int byte;
/*
* Divide the message by the polynomial, a byte at a time.
*/
for (byte = 0; byte < nBytes; ++byte)
{
data = REFLECT_DATA(message[byte]) ^ (remainder >> (WIDTH - 8));
remainder = crcTable[data] ^ (remainder << 8);
}
/*
* The final remainder is the CRC.
*/
return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE);
} /* crcFast() */

View File

@ -1,314 +0,0 @@
/*
Legal Notice: (C)2006 Altera Corporation. All rights reserved. Your
use of Altera Corporation's design tools, logic functions and other
software and tools, and its AMPP partner logic functions, and any
output files any of the foregoing (including device programming or
simulation files), and any associated documentation or information are
expressly subject to the terms and conditions of the Altera Program
License Subscription Agreement or other applicable license agreement,
including, without limitation, that your use is for the sole purpose
of programming logic devices manufactured by Altera and sold by Altera
or its authorized distributors. Please refer to the applicable
agreement for further details.
*/
/*
This component supports 8, 16, 24, and 32 bit little endian data
and any CRC standard between 1 to 128 bits. Through parameterization
you can change the CRC standard which will take effect after you
regenerate your system in SOPC Builder.
Register Map:
000 -> reset the CRC peripheral to the inital value (data and byte enables ignored)
001 -> data write between 1-32 bits
010 -> reserved
011 -> reserved
100 -> read bits 1-32 of the crc result
101 -> read bits 33-64 of the crc result (where applicable)
110 -> read bits 65-96 of the crc result (where applicable)
111 -> read bits 97-128 of the crc result (where applicable)
Write latency = 0
Read latency = 1
Note: This component uses four blocks of eight bits of data in cascade.
To improve the timing of logic you can create seperate cascades
for 8, 16, 24, and 32 bit data which will allow for smaller area
and a shorter combinational depth. Since CRC logic consumes power
even when not in use you can also add a logic disable feature using
the chipselect signal. Even though the registered CRC value is
held constant when the circuit is not in use the input data will
change during this time and cause the CRC cascade logic to react.
*/
module CRC_Component (clk,
reset,
address,
writedata,
byteenable,
write,
read,
chipselect,
readdata);
/*
Using these parameters you can create any CRC ranging from one bit (parity checker)
up to 128 bits. The following list describes the function of each parameter:
crc_width:
The width of the registered CRC result, this value is typically apart of
the name of the standard (CRC32 is 32 bits wide). Adjusting this value
will impact the logic resource usage.
polynomial_initial:
The initial value set for the CRC result register. By writing any data to address 0
this value will be stored in the result register thereby clearing any previously existing
value. This value must be the same width as 'crc_width'
polynomial:
This is the divisor value used on the input data. Typically shown in polynomial format
the value symbolizes the placement of xor operation on the input data. In synthesis, the
polynomial bits that are '1' will create a not gate, whereas the bits that are '0' will
simply create a wire. Even with 32 stages of these operations cascaded, the simple logic
will not become a significant factor on logic utilization or fmax. This value must be the
same width as 'crc_width'
reflected_input:
Some CRC standards require that all the input bits be reflected around the center point.
This option is enabled with '1' and disabled with '0'. Typically this option is enabled
or disabled with 'reflected_output'.
reflected_output:
Some CRC standards require that all the output bits be reflected around the center point.
This operation occurs before the final optional xor output step. This option is enabled
with '1' and disabled with '0'. Typically this option is enabled or disabled with
'reflected_input' (to undo the input reversal typically).
xor_output:
This is the value used to bitwise xor the CRC result. Most standards use either all zeros
or all ones for this value. When zeros are used the CRC result is passed directly and when
ones are used the CRC result is inverted. Since it's no mandatory that this value be all
ones or zeros, this operation occurs before the output reflection when applicable.
*/
parameter crc_width = 32;
parameter polynomial_inital = 32'hFFFFFFFF;
parameter polynomial = 32'h04C11DB7;
parameter reflected_input = 1;
parameter reflected_output = 1;
parameter xor_output = 32'hFFFFFFFF;
input clk;
input reset;
input [2:0] address;
input [31:0] writedata;
input [3:0] byteenable;
input write;
input read;
input chipselect;
output [31:0] readdata;
reg [crc_width-1:0] crc_value;
wire [crc_width-1:0] poly = polynomial;
wire [crc_width-1:0] cascade [3:0];
wire [7:0] block0_data, block1_data, block2_data, block3_data;
wire [crc_width-1:0] result, result_xored;
wire [31:0] mux_result;
reg [31:0] readdata;
/*
Some standards like CRC16 and CRC32 require this bitreversal for serial
devices like ethernet, uarts, usb, etc...
*/
genvar index;
generate if (reflected_input == 1)
begin
for(index = 0; index < 8; index = index + 1)
begin: input_reflection
assign block0_data[index] = writedata[7-index];
assign block1_data[index] = writedata[15-index];
assign block2_data[index] = writedata[23-index];
assign block3_data[index] = writedata[31-index];
end
end
else
begin
assign block0_data = writedata[7:0];
assign block1_data = writedata[15:8];
assign block2_data = writedata[23:16];
assign block3_data = writedata[31:24];
end
endgenerate
/*
Control for the registered events. It assumes that either 8, 16, 24, or 32
bit data is being written using byte enables. It is important that the data
be in little endian format and no gaps of byte enables be present (like
1011 or 1101 for example)
*/
always @ (posedge clk or posedge reset)
begin
if(reset == 1)
begin
crc_value <= 0;
end
else
begin
if(write && chipselect && (address == 3'b000))
begin
crc_value <= polynomial_inital; // reset the crc to the initial value
end
else if(write && chipselect && (address == 3'b001))
begin
if(byteenable == 4'b0001) // 8 bit data input
begin
crc_value <= cascade[0];
end
else if(byteenable == 4'b0011) // 16 bit data input
begin
crc_value <= cascade[1];
end
else if(byteenable == 4'b0111) // 24 bit data input
begin
crc_value <= cascade[2];
end
else if(byteenable == 4'b1111) // 32 bit data input
begin
crc_value <= cascade[3];
end
end
end
end
/* four stages of cascade blocks (each block is crc_width x 8 bits) */
XOR_Shift_Block cascade_block0(.block_input(crc_value), .poly(poly), .data_input(block0_data), .block_output(cascade[0]));
defparam cascade_block0.crc_width = crc_width;
XOR_Shift_Block cascade_block1(.block_input(cascade[0]), .poly(poly), .data_input(block1_data), .block_output(cascade[1]));
defparam cascade_block1.crc_width = crc_width;
XOR_Shift_Block cascade_block2(.block_input(cascade[1]), .poly(poly), .data_input(block2_data), .block_output(cascade[2]));
defparam cascade_block2.crc_width = crc_width;
XOR_Shift_Block cascade_block3(.block_input(cascade[2]), .poly(poly), .data_input(block3_data), .block_output(cascade[3]));
defparam cascade_block3.crc_width = crc_width;
/*
Some standards like CRC16 and CRC32 require this bitreversal.
This is to better support serial devices like uarts, ethernet, usb, etc...)
*/
generate if (reflected_output == 1)
begin
for(index = 0; index < crc_width; index = index + 1)
begin: output_reflection32
assign result[index] = crc_value[(crc_width-1)-index];
end
end
else
begin
assign result = crc_value;
end
endgenerate
/* This final xor operation occurs after the bit swap */
assign result_xored = result ^ xor_output;
/* Generates the appropriate MUX logic depending on the CRC width */
generate if((crc_width > 32) && (crc_width < 65))
begin
assign mux_result = (address == 3'b100)? result_xored[31:0] : result_xored[crc_width-1:32];
end
else if((crc_width > 64) && (crc_width < 97))
begin
assign mux_result = (address == 3'b100)? result_xored[31:0] :
((address == 3'b101)? result_xored[63:32] : result_xored[crc_width-1:64]);
end
else if((crc_width > 96) && (crc_width < 129))
begin
assign mux_result = (address == 3'b100)? result_xored[31:0] :
((address == 3'b101)? result_xored[63:32] :
((address == 3'b110)? result_xored[95:64] : result_xored[crc_width-1:96]));
end
else
begin
assign mux_result = result_xored;
end
endgenerate
/* Registering the return path of the CRC data (32 bits of it) */
always @ (posedge clk or posedge reset)
begin
if(reset == 1)
begin
readdata <= 0;
end
else if((read == 1) && (chipselect == 1))
begin
readdata <= mux_result;
end
end
endmodule
/* a single cascade block of width: crc_width and a length of eight input bits */
module XOR_Shift_Block(block_input,
poly,
data_input,
block_output);
parameter crc_width = 32;
input [(crc_width-1):0] block_input;
input [(crc_width-1):0] poly;
input [7:0] data_input;
output [(crc_width-1):0] block_output;
wire [(crc_width-1):0] cascade [7:0];
XOR_Shift bit_0(.stage_input(block_input), .poly(poly), .new_bit(data_input[7]), .stage_output(cascade[0]));
defparam bit_0.crc_width = crc_width;
XOR_Shift bit_1(.stage_input(cascade[0]), .poly(poly), .new_bit(data_input[6]), .stage_output(cascade[1]));
defparam bit_1.crc_width = crc_width;
XOR_Shift bit_2(.stage_input(cascade[1]), .poly(poly), .new_bit(data_input[5]), .stage_output(cascade[2]));
defparam bit_2.crc_width = crc_width;
XOR_Shift bit_3(.stage_input(cascade[2]), .poly(poly), .new_bit(data_input[4]), .stage_output(cascade[3]));
defparam bit_3.crc_width = crc_width;
XOR_Shift bit_4(.stage_input(cascade[3]), .poly(poly), .new_bit(data_input[3]), .stage_output(cascade[4]));
defparam bit_4.crc_width = crc_width;
XOR_Shift bit_5(.stage_input(cascade[4]), .poly(poly), .new_bit(data_input[2]), .stage_output(cascade[5]));
defparam bit_5.crc_width = crc_width;
XOR_Shift bit_6(.stage_input(cascade[5]), .poly(poly), .new_bit(data_input[1]), .stage_output(cascade[6]));
defparam bit_6.crc_width = crc_width;
XOR_Shift bit_7(.stage_input(cascade[6]), .poly(poly), .new_bit(data_input[0]), .stage_output(cascade[7]));
defparam bit_7.crc_width = crc_width;
assign block_output = cascade[7];
endmodule
/* performs the 'new_bit' stuffing, shifting, and XOR operations for a single input bit */
module XOR_Shift (stage_input,
poly,
new_bit,
stage_output);
parameter crc_width = 32;
input [crc_width-1:0] stage_input;
input [crc_width-1:0] poly;
input new_bit;
output [crc_width-1:0] stage_output;
assign stage_output[0] = new_bit ^ stage_input[crc_width-1];
assign stage_output[crc_width-1:1] = stage_input[crc_width-2:0] ^ ({crc_width-1{stage_output[0]}} & poly[crc_width-1:1]);
endmodule

View File

@ -1,101 +0,0 @@
/*
Legal Notice: (C)2006 Altera Corporation. All rights reserved. Your
use of Altera Corporation's design tools, logic functions and other
software and tools, and its AMPP partner logic functions, and any
output files any of the foregoing (including device programming or
simulation files), and any associated documentation or information are
expressly subject to the terms and conditions of the Altera Program
License Subscription Agreement or other applicable license agreement,
including, without limitation, that your use is for the sole purpose
of programming logic devices manufactured by Altera and sold by Altera
or its authorized distributors. Please refer to the applicable
agreement for further details.
*/
/*
This thin wrapper re-uses the CRC Avalon component as a Nios II
custom instruction. The n port of custom instruction is used as
control to the CRC Avalon component. Below are the values of n and
the corresponding operations perform by the custom instruction:
n = 0, Initialize the custom instruction to the initial remainder value
n = 1, Write 8 bits data to custom instruction
n = 2, Write 16 bits data to custom instruction
n = 3, Write 32 bits data to custom instruction
n = 4, Read 32 bits data from the custom instruction
n = 5, Read 64 bits data from the custom instruction
n = 6, Read 96 bits data from the custom instruction
n = 7, Read 128 bits data from the custom instruction
*/
module CRC_Custom_Instruction(clk,
reset,
dataa,
n,
clk_en,
start,
done,
result);
/*
See the Avalon CRC component for details on the meaning of each
parameter listed below.
*/
parameter crc_width = 32;
parameter polynomial_inital = 32'hFFFFFFFF;
parameter polynomial = 32'h04C11DB7;
parameter reflected_input = 1;
parameter reflected_output = 1;
parameter xor_output = 32'hFFFFFFFF;
input clk;
input reset;
input [31:0] dataa;
input [2:0] n;
input clk_en;
input start;
output done;
output [31:0] result;
wire [2:0] address;
wire [3:0] byteenable;
wire write;
wire read;
reg done_delay;
assign write = (n<4);
assign read = (n>3);
assign byteenable = (n==1)?4'b0001 : (n==2)?4'b0011 : (n==3)?4'b1111 : 4'b0000;
assign address = (n==0)?3'b000 : ((n==1)|(n==2)|(n==3))?3'b001 : (n==4)?3'b100 : (n==5)?3'b101 : (n==6)?3'b110 : 3'b111;
assign done = (n>3)? done_delay : start;
always @ (posedge clk or posedge reset)
begin
if (reset)
done_delay <= 0;
else
done_delay <= start;
end
/*
Instantiating the Avalon CRC component and wiring it to be
custom instruction compilant
*/
CRC_Component wrapper_wiring(.clk(clk),
.reset(reset),
.address(address),
.writedata(dataa),
.byteenable(byteenable),
.write(write & start),
.read(read),
.chipselect(clk_en),
.readdata(result));
defparam wrapper_wiring.crc_width = crc_width;
defparam wrapper_wiring.polynomial_inital = polynomial_inital;
defparam wrapper_wiring.polynomial = polynomial;
defparam wrapper_wiring.reflected_input = reflected_input;
defparam wrapper_wiring.reflected_output = reflected_output;
defparam wrapper_wiring.xor_output = xor_output;
endmodule

View File

@ -1,116 +0,0 @@
# TCL File Generated by Component Editor 15.1
# Tue Dec 22 18:46:40 EET 2015
# DO NOT MODIFY
#
# nios2_hw_crc32 "nios2_hw_crc32" v1.0
# 2015.12.22.18:46:40
#
#
#
# request TCL package from ACDS 15.1
#
package require -exact qsys 15.1
#
# module nios2_hw_crc32
#
set_module_property DESCRIPTION ""
set_module_property NAME nios2_hw_crc32
set_module_property VERSION 17.1
set_module_property INTERNAL false
set_module_property OPAQUE_ADDRESS_MAP true
set_module_property GROUP "Custom Instruction Modules"
set_module_property AUTHOR ""
set_module_property DISPLAY_NAME nios2_hw_crc32
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
set_module_property EDITABLE true
set_module_property REPORT_TO_TALKBACK false
set_module_property ALLOW_GREYBOX_GENERATION false
set_module_property REPORT_HIERARCHY false
#
# file sets
#
add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" ""
set_fileset_property QUARTUS_SYNTH TOP_LEVEL CRC_Custom_Instruction
set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false
set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE false
add_fileset_file CRC_Component.v VERILOG PATH hdl/CRC_Component.v
add_fileset_file CRC_Custom_Instruction.v VERILOG PATH hdl/CRC_Custom_Instruction.v TOP_LEVEL_FILE
#
# parameters
#
add_parameter crc_width INTEGER 32
set_parameter_property crc_width DEFAULT_VALUE 32
set_parameter_property crc_width DISPLAY_NAME crc_width
set_parameter_property crc_width TYPE INTEGER
set_parameter_property crc_width UNITS None
set_parameter_property crc_width HDL_PARAMETER true
add_parameter polynomial_inital STD_LOGIC_VECTOR 4294967295
set_parameter_property polynomial_inital DEFAULT_VALUE 4294967295
set_parameter_property polynomial_inital DISPLAY_NAME polynomial_inital
set_parameter_property polynomial_inital TYPE STD_LOGIC_VECTOR
set_parameter_property polynomial_inital UNITS None
set_parameter_property polynomial_inital ALLOWED_RANGES 0:17179869183
set_parameter_property polynomial_inital HDL_PARAMETER true
add_parameter polynomial STD_LOGIC_VECTOR 79764919
set_parameter_property polynomial DEFAULT_VALUE 79764919
set_parameter_property polynomial DISPLAY_NAME polynomial
set_parameter_property polynomial TYPE STD_LOGIC_VECTOR
set_parameter_property polynomial UNITS None
set_parameter_property polynomial ALLOWED_RANGES 0:17179869183
set_parameter_property polynomial HDL_PARAMETER true
add_parameter reflected_input INTEGER 1
set_parameter_property reflected_input DEFAULT_VALUE 1
set_parameter_property reflected_input DISPLAY_NAME reflected_input
set_parameter_property reflected_input TYPE INTEGER
set_parameter_property reflected_input UNITS None
set_parameter_property reflected_input HDL_PARAMETER true
add_parameter reflected_output INTEGER 1
set_parameter_property reflected_output DEFAULT_VALUE 1
set_parameter_property reflected_output DISPLAY_NAME reflected_output
set_parameter_property reflected_output TYPE INTEGER
set_parameter_property reflected_output UNITS None
set_parameter_property reflected_output HDL_PARAMETER true
add_parameter xor_output STD_LOGIC_VECTOR 4294967295
set_parameter_property xor_output DEFAULT_VALUE 4294967295
set_parameter_property xor_output DISPLAY_NAME xor_output
set_parameter_property xor_output TYPE STD_LOGIC_VECTOR
set_parameter_property xor_output UNITS None
set_parameter_property xor_output ALLOWED_RANGES 0:17179869183
set_parameter_property xor_output HDL_PARAMETER true
#
# display items
#
#
# connection point nios_custom_instruction_slave
#
add_interface nios_custom_instruction_slave nios_custom_instruction end
set_interface_property nios_custom_instruction_slave clockCycle 0
set_interface_property nios_custom_instruction_slave operands 1
set_interface_property nios_custom_instruction_slave ENABLED true
set_interface_property nios_custom_instruction_slave EXPORT_OF ""
set_interface_property nios_custom_instruction_slave PORT_NAME_MAP ""
set_interface_property nios_custom_instruction_slave CMSIS_SVD_VARIABLES ""
set_interface_property nios_custom_instruction_slave SVD_ADDRESS_GROUP ""
add_interface_port nios_custom_instruction_slave clk clk Input 1
add_interface_port nios_custom_instruction_slave clk_en clk_en Input 1
add_interface_port nios_custom_instruction_slave dataa dataa Input 32
add_interface_port nios_custom_instruction_slave done done Output 1
add_interface_port nios_custom_instruction_slave n n Input 3
add_interface_port nios_custom_instruction_slave reset reset Input 1
add_interface_port nios_custom_instruction_slave result result Output 32
add_interface_port nios_custom_instruction_slave start start Input 1

View File

@ -1,58 +0,0 @@
# (C) 2001-2015 Altera Corporation. All rights reserved.
# Your use of Altera Corporation's design tools, logic functions and other
# software and tools, and its AMPP partner logic functions, and any output
# files any of the foregoing (including device programming or simulation
# files), and any associated documentation or information are expressly subject
# to the terms and conditions of the Altera Program License Subscription
# Agreement, Altera MegaCore Function License Agreement, or other applicable
# license agreement, including, without limitation, that your use is for the
# sole purpose of programming logic devices manufactured by Altera and sold by
# Altera or its authorized distributors. Please refer to the applicable
# agreement for further details.
# TCL File Generated by Altera University Program
# DO NOT MODIFY
set aup_version 15.1
# Create a new driver - this name must be different than the
# hardware component name
create_driver nios2_hw_crc32_driver
# Associate it with some hardware
set_sw_property hw_class_name nios2_hw_crc32
# The version of this driver
set_sw_property version $aup_version
# This driver is proclaimed to be compatible with 'component'
# as old as version "1.0". The component hardware version is set in the