I've built a website - http://OutputLogic.com - with online tools that generate a Verilog code for parallel CRC and Scrambler given data width and polynomial coefficients. Also, there are short posts that describe an efficient parallel CRC/ Scrambler generation algorithm for Verilog or VHDL that I've used. -evgeni
Online tool that generates parallel CRC and Scrambler
A developer introduced an online tool for generating Verilog code for parallel CRC and Scrambler modules based on user-defined polynomial coefficients and data widths. The discussion evolved into a technical debate over the merits of using external code generators versus writing native HDL code with "for" loops that rely on synthesis tools to optimize the logic.
While some participants argued that native HDL is more readable and manageable, others highlighted that dedicated generators historically provided better XOR-based optimizations for complex designs and wider data paths.
- Native HDL implementations using 'for' loops can achieve parallel CRC logic if the synthesis tool is capable of unrolling iterations into XOR trees.
- Generated code from external tools can be more difficult to maintain and read compared to parameterized HDL modules.
- External generators were historically preferred because early synthesis tools struggled with large CRC loops and optimization run-times.
- Xilinx FPGAs can implement LFSRs efficiently using SRL16 primitives, provided the registers do not use a reset.
- The tool author chose a Perl-based backend to ensure the generator remained platform-independent and accessible via the web.
On May 18, 10:14=A0am, Jake7 <evgen...@gmail.com> wrote:> I've built a website -http://OutputLogic.com- =A0with online tools > that generate a Verilog code for parallel CRC and Scrambler given data > width and polynomial coefficients. > > Also, there are short posts that describe an efficient parallel CRC/ > Scrambler generation algorithm for Verilog or VHDL that I've used. > > -evgeniThatks for these tools ! How about making it a bit more interesting and adding byte enables ?! Cheers, rudi
Evgeni, Ok neat. But why not just code the algorithm in straight verilog or VHDL, instead of C generates verilog? The C generated verilog code is unmanageable. CRC, and LFSR algorithms are the top of the list for implenting in hardware (i.e. HDLs) rather than C. C implementations are messy. You don't need to calculate "one-bit per clock" - rather one-bit per ITERATION. Who says each iteration must be a clock tick? Just implement the procedural code for the logic update of one bit and stick a 'for' loop around it for 'n' bits. Boom, done. Let the synthesis tool optimize, and produce the big XOR trees. The core of the verilog code that supports any polynomial (width, taps), and any data size could consist of less than 10 lines of code. --Mark
In comp.arch.fpga Mark <mark@cacurry.net> wrote: (snip) < CRC, and LFSR algorithms are the top of the list for implenting in < hardware (i.e. HDLs) rather than C. C implementations are messy. (snip) < The core of the verilog code that supports any polynomial < (width, taps), and any data size could consist of less than < 10 lines of code. Note that Xilinx FPGAs can do 16 bits of LFSR in one SRL16, which takes up very little space. You could easily generate many of them, also wider than 16 bits. -- glen
Mark wrote:> Ok neat. But why not just code the algorithm in straight verilog or > VHDL, instead of C generates verilog?...> You don't need to calculate "one-bit per clock" - rather one-bit per > ITERATION. Who says each iteration must be a clock tick? Just > implement the procedural code for the logic update of one bit and > stick a 'for' loop around it for 'n' bits. Boom, done. Let > the synthesis tool optimize, and produce the big XOR trees.I agree, but not everyone is a language wonk. This is straightforward in vhdl, and has been covered repeatedly in the vhdl newsgroup. If you have done it in verilog, let's see the code.> The C generated verilog code > is unmanageable.http://www.easics.be/webtools/crctool Is a similar generator that has been around for years. It produces the same "unmanageable" code that many have nonetheless managed to paste in and use successfully -- Mike Treseler
On 2009-05-21, Mike Treseler <mtreseler@gmail.com> wrote:> I agree, but not everyone is a language wonk. > This is straightforward in vhdl, and has been > covered repeatedly in the vhdl newsgroup. > If you have done it in verilog, > let's see the code.It is straight forward in Verilog as well. This is taken from an Ethernet CRC32 module I wrote a long time ago: // Ethernet's CRC32 always @(posedge clk125_i) begin if(crc_enable) begin crc_tmp = crc; // Implement it as a for loop of the bit serial version // and hope that the synthesizer optimize it well (at least ISE does) for(i = 0; i < 8; i = i + 1) begin fb = crc_tmp[31]; crc_tmp[31] = crc_tmp[30]; crc_tmp[30] = crc_tmp[29]; crc_tmp[29] = crc_tmp[28]; // ... and so on... crc_tmp[2] = next_txd_o[i] ^ fb ^ crc_tmp[1]; // x^2 crc_tmp[1] = next_txd_o[i] ^ fb ^ crc_tmp[0]; // x^1 crc_tmp[0] = next_txd_o[i] ^ fb; // 1 end // for (i = 0; i < 8; i = i + 1) crc <= crc_tmp; end else if(crc_clear) begin crc <= 32'hffffffff; end end /Andreas
Andreas Ehliar wrote:> It is straight forward in Verilog as well.I agree, other than filling in that ... and so on... part. Thanks for the posting. You have cracked the code and discovered verilog variables. I won't tell anyone ;)> This is taken from an Ethernet > CRC32 module I wrote a long time ago:I did it in vhdl with a compile time constant table and a serial crc_shift function overloaded for the parallel case something like: begin crc_v := crc; -- starting value for i in data'range loop -- call serial shift below for each bit -- left to right crc_v := crc_shift(data(i), crc_v, crc_type); end loop; return crc_v; end function crc_shift; -- Mike Treseler __________________________________________________ constant crc_table : crc_table_t := ( ppp32 => -- ethernet, hdlc, ppp, AAL5, fddi, ( crc_len => 32, poly_vec => (26|23|22|16|12|11|10|8|7|5|4|2|1|0 => '1', others => '0'), crc_init => (others => '1'), remainder => x"c704_dd7b" ), ... _____________________________________________________ -- Base serial shifter, all of the other crc_shifts end up here -- This gets called n times for the parallel versions above function crc_shift -- Serial in, unsigned return ( data : in std_ulogic; -- input bit crc : in unsigned; -- crc starting value crc_type : in crc_t ) return unsigned is variable crc_v : unsigned(crc'range); -- CRC register constant reg_len : natural := crc_table(crc_type).crc_len; -- look up length subtype crc_vec is unsigned(reg_len-1 downto 0); -- chop table poly to length constant mask : crc_vec := crc_table(crc_type).poly_vec(crc_vec'range); begin crc_v := crc sll 1; -- shift it if (crc(crc'left) xor data) = '1' then -- maybe invert mask bits crc_v := crc_v xor mask; end if; return unsigned(crc_v); -- returns whole register each shift end function crc_shift;
Mark <mark@cacurry.net> writes:> Ok neat. But why not just code the algorithm in straight verilog or > VHDL, instead of C generates verilog? The C generated verilog code > is unmanageable.I think this historically from the time when synthesis tools did not handle loops very well. It was very easy to do the expansion symbolically in a language like Common Lisp and generate HDL code. I've done this many times in the past and I disagree that the generated code is unmanageable. You simply stick it in a module and instantiate it. Petter -- A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing on usenet and in e-mail?
Andreas Ehliar <ehliar-nospam@isy.liu.se> writes:> It is straight forward in Verilog as well. This is taken from an Ethernet > CRC32 module I wrote a long time ago:<snipped code> But that's not any poly at any length... Petter -- A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing on usenet and in e-mail?
Andreas Ehliar wrote:> On 2009-05-21, Mike Treseler <mtreseler@gmail.com> wrote: >> I agree, but not everyone is a language wonk. >> This is straightforward in vhdl, and has been >> covered repeatedly in the vhdl newsgroup. >> If you have done it in verilog, >> let's see the code. > > It is straight forward in Verilog as well.I agree. But consider what many Verilog designers have learned: * Think Hardware. * Don't mix blocking and non-blocking assignments. If I "think hardware" on an example such as yours, I easily get confused. To find such an elegant solution, I need to understand what HDLs and synthesis tools can do. Likewise, if I can't mix blocking and non-blocking assignments in a clocked always block, I can't write code like yours. In summary, unless Verilog RTL designers are prepared to discard what they are learning from all kinds of papers and trainers, they won't come up with such elegant solutions. No matter how straightforward we might find them. Jan -- Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com Python as a HDL: http://www.myhdl.org VHDL development, the modern way: http://www.sigasi.com Analog design automation: http://www.mephisto-da.com World-class digital design: http://www.easics.com





