8b/10b encoder -- for review - Page 1
Forum section: electronics / general

author: blueskull
author_rank: Unknown
timestamp: September 07, 2015, 03:44:03 am
content: Hi all,Attached is a simple 8b/10b encoder I wrote to encode any data bytes into 8b/10b data stream.It also has the capability to transmit control symbols as well as a comma symbol, K28.1.If you need a serial communication IP core for personal projects, just take it.For those you have a lot of time, I will be very appreciate if you can test this module for me.I did some simple tests to cover some engineered input pattern for the module, and it seems to work properly.This module is fully synthesizable, and iceCube2 reports 200+ mbps on an ice40HX device.This module is FPGA verified. All tests are performed in a ice40HX8K device and a logic analyzer.-------------------Background: I am working on a DIY audio DAC, which is a 4 bit sigma delta based design.To get the best analog performance, I decided to build the DAC's 4 bit thermometer DAC stage out of acustomized ASIC (yes, I know, I am crazy). To isolate digital noise as well as ground loop noise,I decided to use isolated serial digital data link between DAC output stage and sigma delta modulator.Therefore, I wrote this 8b/10b encoder to run on the modulator FPGA. There will also be a decoder onthe ASIC soon, which also will be open source.Regards,Bo Gao

author: hamster_nz
author_rank: Super Contributor
timestamp: September 07, 2015, 04:57:22 am
content: There is an 8b/10b on OpenCores, which was written with logic that follows the original IBM patent. You might get a better verification by sending a lot of random data though your module, then through the Open Cores module to decode it, then check that you got what was sent. If you left that simulating for a while you should end up with total coverage - or you could be a little more structured and run every possible sequence of three input words through it for both possible initial disparity values, giving 266^3 * 2 = 37,642,192 test cases.It is a little bit unconventionally to me, but why are you using both edges of the clock? Was it just convenient for generating the serial stream with the clock out of phase? A more normal structure for an FPGA would be to use a DDR output hard wired to clock out zeros on the rising edge and ones on the falling edge. That minimises skew between the clock and data signal as they use the same structures within the FPGA. Maybe it is a Lattice thing?Also, do you have a way to reset the running disparity? You might not need it now, but it is sometimes need to be controlled during negotiation.

author: tszaboo
author_rank: Super Contributor
timestamp: September 07, 2015, 09:28:49 am
content: I'm going to put this here, this is the representation of the information the exact same way, as I learned it from professors at the university. They worked on the synthesizer at xilinx, quite knowledgeable people.always@(negedge clk)They also said, if they ever see this in our code, they make sure we never become an engineer.

author: danfo098
author_rank: Contributor
timestamp: September 07, 2015, 01:04:54 pm
content: Isn't it also bad practice to use flip flop outputs as clocks. Why not use datclk as a clock enable instead and clock the encode process with the "real" clock (bitclk) and also on the positive edge?

author: ale500
author_rank: Frequent Contributor
timestamp: September 07, 2015, 03:52:00 pm
content: You have a design with two clocks. Deriving one clock from the other one is not the best practice (for high speed signals). Recommended is to use a PLL/DCM or equivalent to derive one clock from the other one. There is a project posted here, a HDMI to DVI converter with serializers/deserializers, very nice. The x5 clock is done with a PLL and DDRegs embedded in the IO pins. For 1 channel it may not matter but when you have more channels that have to be synchronous one to another using slow routing for the clock adds jitter to your signals. YMMV, as always. You may want to read some app notes about cross clock domains where the topic of synchronism and jitter are discussed.

author: hamster_nz
author_rank: Super Contributor
timestamp: September 07, 2015, 09:53:41 pm
content: I'm currently working on an 'multiple words per cycle' 8b/10 encoder, for use in a DisplayPort implementation. It needs to encode 270M symbols per second as each DisplayPort channel is running at 2.7Gb/s. I also want to make it workable to encode 540M symbols per second - damn you 4k UHD! I would really like to use the transceivers 8b/10b encoder, but my low-end part doesn't seem to have them. Here's the rough design:Pipeline state 1:Use a 1-bit x 512 lookup table to look up if each of the output symbols will have an odd parity. The index to the table is the K flag and the Data word - approx resource usage 4 LUTs per symbol per cycle (8 shared as dual-port RAMs) + 9 registers to pipeline the inputs to the next stagePipeline stage 2:Use the results of stage 1 to calculate the running disparity for encoding each of the 'n' codewords, and to give the new running disparity for the next cycle. - approx resource usage one LUT per symbol per cycle, + 10 registers to pipeline the inputs to the next stagePipeline stage 3:Look up each symbol in a 10-bit x 1024 table, where the index is the negative disparity flag, K flag, and data word. By using multi-port memory it only needs one block RAM per pair of symbols being processed. approx resource usage 1/2 a BRAM block per symbol per cycle.Total resource usage should be about 10 LUTs, 38 registers and one BRAM per pair of symbols being encoded. If the design timing allows I most likely collapse pipeline stages 1 and 2 to halve the register usage.I wonder what the power usage will be compared to implementing 8b/10b in LUTs, especially since it can run at 1/2 the clock speed of encoding one symbol per cycle.

author: DocOptics
author_rank: Newbie
timestamp: September 18, 2015, 03:28:41 pm
content: Xilinx have an 8b/10b encoder/decoder with full code available. Have a look at xapp1014 and xapp1015. The example code contains both Verilog and VHDL versionsGavin