Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Variable Width CRC generator based on parameter "crc_poly"

Status
Not open for further replies.

rrucha

Member level 3
Joined
Jul 17, 2019
Messages
66
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
675
I wish to make a parameterized CRC generator that takes different widths of data in and gives 2 different types of CRC at the output. This depends on the parameter "crc_poly" which will decide whether the output CRC will be 32 bit or 64 bit.
My code will have all the different combinations of the CRC generators as a function.
Based on the select signal, I will pick which CRC to choose for my output. This is pretty straight forward.
I need help in understanding how I can have one parameterized module that can have two different output crc widths. I will attach a picture to explain better.
My question is, will i need two completely different CRC modules if the output width is not fixed? I know its possible to use the same module if only the polynomial differs but the widths stay the same. But in my case my output width is changing.

Capture.PNG
 

The block symbol looks confusing, what's the purpose of the "input data" ports with different width?

Supporting different a CRC lengths in a single module isn't impossible, but not neccessarily saving resources. It also depends on the topology. Width switching is probably simple in a bit serial (slow) implementation, less useful in a parallel topology.
 

Verilog parameters to select different output width for the CRC output.


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
module crc_generator  #(
  // width selection parameter
  parameter   crc_poly = 0    // 0: 32-bit, 1: 64-bit
 
  // do not modify! calculated parameter
  parameter   width = 32*(1+crc_poly);
) (
  output  [width-1:0]   crc_out
);
 
endmodule



Something similar can be done in VHDL using generics.
 
  • Like
Reactions: rrucha

    rrucha

    Points: 2
    Helpful Answer Positive Rating
The block symbol looks confusing, what's the purpose of the "input data" ports with different width?

Supporting different a CRC lengths in a single module isn't impossible, but not neccessarily saving resources. It also depends on the topology. Width switching is probably simple in a bit serial (slow) implementation, less useful in a parallel topology.

Hi! I want to make a general module for CRC generation for different widths of data input and also using 2 different polynomials that happen to be of two different widths.
For choosing the input width, there is a select signal as well.
I tried implementing this by making use of case and assigning crc_out to the individual functions of different widths. It doesnt seem to work though.
Are there any better ways ?

I wanted to use `ifdef to choose from the different modules based on select. But if I am not wrong, `ifdef used `define which is something like a parameter. Does it work when an input is coming to the module that uses `ifdef and this input is the condition for executing `ifdef? Some example could really help as there arent many online with more than 2 statemnets like `ifdef `else
I have 5 conditions under consideration here.
 
Last edited:

Re: Variable Width CRC generator based on parameter "crc_poly"

IMO `ifdef should be avoided and parameterized modules should be implemented. The times I've used `ifdef was when the actual number of ports on the module were different and only because I didn't want to end up with a bunch of warnings about unconnected ports.

- - - Updated - - -

For choosing the input width, there is a select signal as well.
I tried implementing this by making use of case and assigning crc_out to the individual functions of different widths. It doesnt seem to work though.
Are there any better ways ?

I posted (#3) a way to adjust the instantiated width of an output port based on a parameter. It's definitely a better way than putting all the possible options of width on the module, as that method results in a bunch of tool warnings about the unused/unconnected ports.
 

Re: Variable Width CRC generator based on parameter "crc_poly"

IMO `ifdef should be avoided and parameterized modules should be implemented. The times I've used `ifdef was when the actual number of ports on the module were different and only because I didn't want to end up with a bunch of warnings about unconnected ports.

- - - Updated - - -



I posted (#3) a way to adjust the instantiated width of an output port based on a parameter. It's definitely a better way than putting all the possible options of width on the module, as that method results in a bunch of tool warnings about the unused/unconnected ports.

Hi!
That works for the output when I am choosing which polynomial width I will be using. It can be parameterized then. But when I am thinking about the inputs coming in (which are of different widths), these inputs depend on the select signal that comes along with them . In this case i will have the hardware for all the different CRC implementation but I am having trouble deciding how to choose the correct hardware based on the select input.
 

Re: Variable Width CRC generator based on parameter "crc_poly"

Hi!
That works for the output when I am choosing which polynomial width I will be using. It can be parameterized then. But when I am thinking about the inputs coming in (which are of different widths), these inputs depend on the select signal that comes along with them . In this case i will have the hardware for all the different CRC implementation but I am having trouble deciding how to choose the correct hardware based on the select input.
Do you need all the possible hardware available at all times, so you can switch on the fly in the hardware based on the select signal? I was under the impression from your first post that you just wanted a parameterizable CRC module, which you would set to a specific CRC and instantiate it in a design.

So do you need to change the CRC poly during run time? If you don't you should parameterized the input width and change the polynomial select input into a select parameter. You would then use the input width to set the input data width and use a generate to select the CRC polynomial hardware for that instance.
 

I believe I answered about runtime selectable poly in post #2. You didn't yet tell about implementation details and which problems you experience.
 

Re: Variable Width CRC generator based on parameter "crc_poly"

Do you need all the possible hardware available at all times, so you can switch on the fly in the hardware based on the select signal? I was under the impression from your first post that you just wanted a parameterizable CRC module, which you would set to a specific CRC and instantiate it in a design.

So do you need to change the CRC poly during run time? If you don't you should parameterized the input width and change the polynomial select input into a select parameter. You would then use the input width to set the input data width and use a generate to select the CRC polynomial hardware for that instance.

The polynomial can be parameterized because I can choose which CRC I wish to implement. But the input data width cannot be parameterized because it comes in along with the select signal and based on the select signal I will pick the particular CRC function. So all of the hardware for the different data widths will have to be present.

- - - Updated - - -

I believe I answered about runtime selectable poly in post #2. You didn't yet tell about implementation details and which problems you experience.

As of now, I am still dealing with selecting input data widths. I tried implementing a single function without a clock; it works. The moment I introduce a clock ; the output is all 0's.
Code:
always @(posedge clock or negedge reset) begin 
if (!reset) crc_out <= 'd0;
else begin 
   if (sel == 1'b0)
   crc_out <= functCRC8(.data(data8), .crc(crc));
   else crc_out <= functCRC16(.data(data16), .crc(crc));
end

function [15:0] functCRC8;
input [7:0] data8;
input [15:0] crc;
......
endfunction 

function [15:0] functCRC16;
input [15:0] data16;
input [15:0] crc;
......
endfunction

I dont get why the output crc wont take the value from the function as soon as i put it inside the clock.
 

Re: Variable Width CRC generator based on parameter &amp;quot;crc_poly&amp;quot;

The polynomial can be parameterized because I can choose which CRC I wish to implement. But the input data width cannot be parameterized because it comes in along with the select signal and based on the select signal I will pick the particular CRC function. So all of the hardware for the different data widths will have to be present.
You are saying that while it is in operation, you will switch between CRCs?

If so then this design is overly convoluted it would be better to create generic CRC code with the poly, widths, etc all parameterized and then just instantiate all the various CRCs you require in the top level of code and use muxes and demuxes for deciding which CRC you are using at any given time. The amount of logic isn't going to change from your current design and the CRC code itself will be more useful overall.
 
  • Like
Reactions: rrucha

    rrucha

    Points: 2
    Helpful Answer Positive Rating
Re: Variable Width CRC generator based on parameter &amp;quot;crc_poly&amp;quot;

You are saying that while it is in operation, you will switch between CRCs?

If so then this design is overly convoluted it would be better to create generic CRC code with the poly, widths, etc all parameterized and then just instantiate all the various CRCs you require in the top level of code and use muxes and demuxes for deciding which CRC you are using at any given time. The amount of logic isn't going to change from your current design and the CRC code itself will be more useful overall.

Yes you are right. I thought there was some way for me to avoid the amount of logic that is needed but I guess I will any way need those many MUXs and DEMUXs.

Thanks for your help!
 

Now that it is clear that you want any CRC available (or certain set of CRCs available) it is possible to build a generic CRC engine that accepts a CRC polynomial and computes CRCs for that polynomial input.

The poly input would be what taps are used and the logic would be capable of creating any set of taps. The width of the input and output would be set to the absolute largest input output bits and you would slice the output depending on what CRC you are running (the only mux/demux required). The CRC would not be replicated in this case, like you have been doing previously.

The whole "I want to parameterize" (i.e. make it compile time) was throwing me off and making me think you only needed a single CRC built for any given instantiation of the CRC core and all the muxing/demuxing was to select the proper CRC for that design.

This should be a lesson for you, to explain what you are trying to accomplish and then explain what your implementation is to accomplish it. If you had done that originally I would have suggested to use a generic programmable CRC so you would have the most optimal solution for what you want. Replicating a bunch of CRCs is not the way to go.

FYI, replicating and muxing is easier as the programmable version will require much more thought and effort to implement (you will also need to test it more thoroughly as there are more chances for something to be wrong).
 

So what I am dealing with is a lot more convoluted. What you said is working for me when I am choosing between different widths and polynomials. I just use case. So all the hardware is present.

But I have this additional action where a few number of bits are getting added to my data and coming to my crc module. For instance, as i have drawn the figure, the 256 bit data can come as 256+n ; where n is a parameter in the previous module and it will be a parameter in my module as well.
And this 256+n data has a fixed CRC polynomial. So between the 2 cases we know that this data will only be going to the second case.
Now I am being recommended to use `ifdef because apparently it reduces hardware. As the extra data is a parameter it will always be fixed.
How can I make use of `ifdef inside one particular case to choose between the different CRC engines? Just to make it clear; the different widths of data going to this particular CRC polynomial engine will be in my code; I just need to make use of `ifdef to choose from these. Any help will be appreciated.
 

So what I am dealing with is a lot more convoluted. What you said is working for me when I am choosing between different widths and polynomials. I just use case. So all the hardware is present.

But I have this additional action where a few number of bits are getting added to my data and coming to my crc module. For instance, as i have drawn the figure, the 256 bit data can come as 256+n ; where n is a parameter in the previous module and it will be a parameter in my module as well.
And this 256+n data has a fixed CRC polynomial. So between the 2 cases we know that this data will only be going to the second case.
Now I am being recommended to use `ifdef because apparently it reduces hardware. As the extra data is a parameter it will always be fixed.
How can I make use of `ifdef inside one particular case to choose between the different CRC engines? Just to make it clear; the different widths of data going to this particular CRC polynomial engine will be in my code; I just need to make use of `ifdef to choose from these. Any help will be appreciated.

You keep changing the requirements...do you even know what you are supposed to design?
* First you tell us you want to use a parameter (i.e. the parameter is set at compile time and can't be changed without creating a new bit file).
* Then you tell us you have to select the CRC and the port widths based on an input (the +n bits), which means you have to support ALL of the CRCs in system after the design is compiled (i.e. All CRCs must exist otherwise you can't select based on the +n input).
* Now you are saying that someone is telling you to use `ifdefs to reduce the logic because you have all the CRCs in the design and you only need the one parameterized. (but it is a parameter that is coming in as part of the data 256+n, what the heck is up with that!? FYI an input to a module is not a parameter and neither an actual parameter or an input "parameter" can be used in an ifdef).

So what are you supposed to design?

I give up...just do what I told you in post #12 and create a generic module with a programmable CRC polynomial. That is the most optimal solution and doesn't require a bunch of novice engineer ifdefs.
 

There was no confusion actually. there are a lot of things that have to be taken care of in this one module. I am sorry about that. This thread helped me resolve the two main scenarios of variable width input as well as 2 different CRC polynomial.
The `ifdef is for a completely different scenario where , even in the different widths coming into my module, i have one particular width that could have another variable width information attached to it. But I will figure that out. Another thread will be needed for `ifdef implementation.
I am sorry for all the trouble. Thanks for all your help.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top