Xilinx Reed-Solomon Tutorial 2


This is the second of two tutorials developed to introduce the Xilinx Reed-Solomon Encoder and Decoder LogiCOREs. Tutorial 1 concentrates on using the encoder core, while this tutorial concentrates on the decoder core.


Getting Started

If you have already completed Tutorial 1, then you can skip this section, as long as you:
  1. Make a hard copy of this tutorial for annotation
  2. Read the Reed-Solomon Decoder datasheet

The tutorials were developed and verified on a PC-based Windows platform. It should be possible to complete them on a unix-based system, although this has not been fully tested. Before commencing this tutorial, you must complete the following steps:

  1. Ensure your system has the following software tools (or appropriate alternatives):
    • WinZIP (7.0 or later)
      Any tool capable of extracting ZIP files should be suitable.
    • Netscape Communicator (4.5 or later)
      Any browser that supports the JDK1.1.5 version (or later) of Java, should be suitable. The latest version of Netscape Communicator may be downloaded from here. Note that Java must be enabled in the browser preferences. Also note that the cores are delivered to your email account, so you should also be able to access it.
    • Xilinx Foundation Series (2.1i or later)
      If you decide to do the implementation section of this tutorial, you will need this tool. The Xilinx or Alliance Series 2.1i is also suitable, but note that a 3rd-party synthesis tool capable of instantiating a "black-box" component will also be required.
    • Modelsim PE (5.2e or later)
      Any VHDL simulator that supports VHDL records should be suitable.
    • LViewPro (2.7 or later)
      The simulation testbench reads and writes images using the PGM (Portable Gray Map) file format. Any image viewer that supports the PGM format should be suitable. If you don't already have one, PC-based users should check out the latest version of LViewPro at http://www.lview.com. Unix-based users should check out John Bradley's All things XV webpage.
  2. Download xrs.zip. It contains:
    • copies of the tutorial worksheets (including this one)
    • VHDL testbenches and support files
    • command scripts for the implementations tools and modelsim
  3. Extract xrs.zip using WinZIP into a directory called C:\xrs. If you have to install it somewhere else, remember to modify all the pathnames of files and scripts referred to in the tutorial worksheets, as they all have "C:\xrs\" prepended.
  4. Read the Reed-Solomon Decoder datasheet
  5. Read through the Tutorial 1 worksheet which will help give context to this tutorial. It explains how to specify a Reed-Solomon code for a simple application. It also introduces the PGM file format used by the VHDL testbenches.
  6. Make a hard copy of this tutorial for annotation.


Generating the decoder core

Go to the Xilinx Reed-Solomon web page at www.xilinx.com/ipcenter/reed_solomon

Click on Generate a RS Decoder Core. The Username and Password Required window will appear:

Enter your username and password. Once they have been confirmed, the Xilinx LogiCORE Reed-Solomon Decoder, Configuration and Download page will be displayed. Fill in the fields in the decoder configuration GUI within this page so that they match the following:

The values in the Code-Block Parameters panel correspond to the values for the encoder generated in Tutorial 1 (except the Clock Periods per Symbol parameter which will be explained later). Check that the Latency and Processing Delay values displayed in the Information panel match the ones shown above. Once you have entered all the parameters click the Submit button. The Download Form window will appear. Enter your email address and ensure that the other fields match the following:

When you have completed the Download Form, click OK. The Request Successfully Submitted page will appear. Xilinx Webmaster will send you a confirmation email detailing the core parameters and options you selected. It will then generate your customized core. This should only take a few minutes (unless the web server is particularly busy). Xilinx Webmaster will then send you an email with an attached zip file. Unzip this file in:

C:\xrs\unzipped\rs_decoder

Within this directory, the following 7 files should now be accessible:

docs\readme.txt   - explains what each of the files is for
docs\dec_spec.pdf - current version of the RS decoder core data sheet
rs_decoder.v      - Verilog behavioral model for the core
rs_decoder.vhd    - VHDL behavioral model for the core
rsd.edn           - EDIF netlist for your required parameters
rsdec_wrap.v      - illustrates how to instantiate the core using Verilog
rsdec_wrap.vhd    - illustrates how to instantiate the core using VHDL

View these files using a text editor such as WordPad, starting with readme.txt.


Adding pads and global buffers

The steps for pushing the core through FPGAExpress and the Xilinx implementation tools are exactly the same as you did for the encoder core, so if you have already completed Tutorial 1, you may want to skip straight to the Simulation section.

Before the core can be pushed through the Xilinx implementation tools, pads and buffers must be added. In this tutorial we will use FPGAExpress to accomplish this (if you use another sythesis tool, you should still be able to follow this part of the tutorial - just substitute the appropriate commands for your tool). You could just use the rsdec_wrap.vhd included in the emailed zip file. However, you should use an enhanced version called C:\xrs\fpgaexpress\rsdec_wrap.vhd. This version has:

  • the core's reset pin connected to the dedicated global set/reset resource (using a STARTUP_VIRTEX instantiation)
  • the core's clk pin driven by a global low-skew clock buffer (a BUFG instantiation)

Complete the following steps to create an EDIF wrapper from rsdec_wrap.vhd:

  1. Launch FPGAExpress.
  2. Create a new project by clicking the New Project button in the toolbar or by selecting File->New Project...
  3. In the Create New FPGA Express Project dialog box, you can choose a location for the project.  Use the drop-down list in the Save In field to navigate your directory tree to: C:\xrs\fpgaexpress
  4. Enter rs_decoder in the Name: field. The rs_decoder directory is where project files will be stored.
  5. Click on the Create button to create the new project.
  6. After the program creates the rs_decoder project, the Add sources dialog box is displayed. Select C:\xrs\fpgaexpress\rsdec_wrap.vhd. Click Open.
  7. The rs_decoder.exp window should pop up and rsdec_wrap.vhd should have a green tick next to it in the Design Sources section.
  8. Expand rsdec_wrap.vhd by double-clicking on it.
  9. Right-click on rsdec_wrap and select Create Implementation...
  10. In the Create Implementation window, complete the fields so that they match the following:
  11. Click OK.
  12. In the Chips section of the rs_decoder.exp window, there should be a red exclamation mark over rsdec_wrap. The associated warnings can be safely ignored as they are caused by the core being a black box component within rsdec_wrap.vhd.
  13. Right-click on rsdec_wrap-Optimized and select Export netlist...
  14. In the Export Netlist window, complete the fields so that they match the following:
  15. Click OK, then exit FPGAExpress.
  16. The EDIF wrapper rsdec_wrap.edf and the constraints file rsdec_wrap.ncf should be in the C:\xrs\fpgaexpress\rs_decoder directory.


Implementation

We're now ready to push the design through the Xilinx implementation tools. To save time, you will use the command-line approach rather than the Design Manager. First of all open a DOS command prompt window and, move to the appropriate directory:

cd C:\xrs\implementation\rs_decoder

The EDIF netlists for the core and wrapper should be copied to this directory:

copy C:\xrs\unzipped\rs_decoder\rsd.edn .
copy C:\xrs\fpgaexpress\rs_decoder\rsdec_wrap.edf .

The user constraints file generated by FPGAExpress should also be copied to this directory. However, it's extension must be changed to .ucf using the following command:

copy C:\xrs\fpgaexpress\rs_decoder\rsdec_wrap.ncf rsdec_wrap.ucf

FPGAExpress did not add a register-to-register timespec to rsdec_wrap.ucf because there are no registers within rsdec_wrap.vhd. Therefore you have to manually add the following timespec to rsdec_wrap.ucf:

TIMESPEC TS_F2F = FROM FFS TO FFS 20 ns;

Note that the TS_P2P timespec will be ignored by the implementation tools as there are no direct pad-to-pad boolean paths.

This directory should have the following files:

go_map.bat
go_par.bat
go_trace.bat
go_hdl.bat
go_map
go_par
go_trace
go_hdl
rsd.edn
rsdec_wrap.edf
rsdec_wrap.ucf

At the DOS prompt, run the script files in the following order:

go_map.bat
go_par.bat
go_trace.bat
go_hdl.bat

(Unix users should use the go_* scripts without the ".bat" extensions.)

Check the rsdec_routed.twr file. Did the place-and-route tools meet the timing constraints you set? View the core with FPGAEditor using the following command at the DOS prompt:

fpga_editor rsdec_routed

Notice that the core is made up of several relationally placed macros (RPMs).


Simulation

Launch a DOS-prompt, and go to the modelsim directory:

cd C:\xrs\modelsim

Copy the decoder VHDL behavioral model that was extracted from the zip file you received via email:

copy C:\xrs\unzipped\rs_decoder\rs_decoder.vhd .

In Tutorial 1 an instantiation of the encoder core was used to encode the image in input.pgm. The encoder testbench created three pgm files in the modelsim directory:

  • encoded.pgm
  • noise.pgm
  • received.pgm

If you have not completed Tutorial 1, use the following command to copy canned versions of the pgm files into the modelsim directory:

copy C:\xrs\canned\*.pgm .

The pgm files can be viewed with LViewPro. Note that the check symbols are appended to the end of each row in encoded.pgm. The received.pgm file is the result of XOR-ing the bits of each pixel in encoded.pgm with the bits of the corresponding pixel in noise.pgm. In this tutorial, you will use the VHDL behavioral model of the Reed-Solomon decoder to detect and correct the errors in received.pgm (you could use the back-annotated netlist model if you wanted, but the simulation time will be very long).

Launch Modelsim. At the Modelsim command prompt, type the following commands:

cd C:/xrs/modelsim
vcom -87 -work work rs_decoder.vhd
vcom -87 -work work tb_rs_decoder.vhd

The source files should have compiled without any errors, although expect to see the following warning which can be ignored:

# WARNING[1]: tb_rs_decoder.vhd(463): No default binding for component: "rsd". (No entity named "rsd" was found)

Use the following command to run the simulation:

vsim tb_rs_decoder_config -Grfile=received.pgm

The testbench calculates the Processing Delay and Latency using the equations given in the datasheet, and displays them in the Modelsim command prompt window. These should be exactly the same as the values that were displayed on the configuration GUI.

Use the following steps to set the radix for bus signals:

  1. In the Modelsim command prompt window, select Options->Simulation...
  2. In the Defaults tab, select Unsigned as the Default Radix.
  3. Click OK.

Add the core signals to the Wave window using the following commands:

add wave reset clk ce sr sync data_in
add wave data_out err_cnt err_found fail blk_strt blk_end ready

As with the encoder testbench, the decoder testbench toggles the clk signal at 50 MHz. For this part of the tutorial, Clock Periods Per Symbol = 1, so one symbol period is equal to one clock cycle (period). However, remember that the decoder core can be configured to use multiple clocks cycles per symbol, in which case there may be several clock cycles for each symbol period.

Run the simulation for 750 symbol periods, i.e.(750 x 20 ns):

run 15000 ns

Go to the Modelsim Wave window and click on Zoom->Zoom Full. You will be able to see the first few code word blocks on data_in.
 

Processing Delay

The testbench has been configured so that it only puts new data onto data_in if the decoder ready signal is asserted high.
Q1. Using the Processing Delay figure you noted from the configuration GUI, how many symbol periods would you expect ready to stay low for after a complete code word (n = 207) has been sampled?
Answer : ___________________(predicted)
In the Wave window, add two cursors using Cursor->Add Cursor. Then measure how long ready goes low for between the first and second code word blocks.
Q2. For how many symbol periods is ready low?
Answer : ___________________(measured)
Does your predicted value match your measured value?

Latency

The testbench assumes that the core uses the Start Pulse Synchronization mode, so the sync signal is asserted for one symbol period at the start of each code word block.
Q3. Use cursors to measure the time between the first symbol of the first code word being sampled on data_in, and when the corrected version of the first symbol appears on data_out.
Answer : ___________________(in symbol periods)
Does your measured value agree with the value that was displayed on the configuration GUI?

Status signals

Check that the blk_strt and blk_end signals encapsulate the first code word block. Note that both err_found and err_cnt are updated each time blk_end is asserted.
Q4. Does the value on err_cnt agree with the number of errors added to each code word in tutorial 1?
Answer : ___________

Run the simulation to completion using:

run -all

The testbench should have created a new pgm file called decoded.pgm. Use LViewPro to verify (qualitively) that the errors have been corrected.


Going beyond the error correcting capability of the Reed-Solomon code

Edit received.pgm, the beginning of which should look like:

P2
207
200
255

# row 0
 124 151 119 163 131  34 129 154 160 160 163 154 141 147 171 124 147
 147 147 141 113 131 230 140 145 121 121 141 141 154 120 135 113 128
.
.
.

Change the first pixel value in row 0 from 124 to 255. Save received.pgm. There should now be 11 errors in the first code word. Re-start the simulation using:

restart -f
run 15000 ns

Q5. Scroll along to the first blk_strt pulse - did the decoder manage to correct the symbol you added an error to?

Answer : _______
Q6. Scroll along to the first blk_end pulse - did the decoder calculate the correct number of errors in the code block?
Answer : _______
Q7. Which signal should you use to check whether the decoder has successfully decoded a code word?
Answer : _______
If you have time, run the simulation to completion and view decoded.pgm, paying particular attention to the first row of pixels. It should be quite obvious that this row was not decoded successfully.

Multiple clock periods per symbol

The decoder can be configured to use multiple clock periods per symbol. This helps reduce the Processing Delay (with respect to symbol periods), so that the core can accept continuous input data i.e. no gaps between code words, which is required by some applications.  As you are using the (parameterizable) behavioral model of the core, you can increase the number of clock periods per symbol simply by editing the appropriate parameter that is passed to the core instantiation within the testbench. The tb_rs_decoder.vhd testbench currently has Clock Periods Per Symbol = 1. Complete the following steps to change it to 2:

  1. Edit tb_rs_decoder.vhd.
  2. Search for CHECKPOINT 2. This is where the constants that are passed to the decoder behavioral model are defined.
  3. Find the constant clks_per_sym and change its value from 1 to 2. This constant is passed into the decoder instance.

Re-compile using the following command:

vcom -87 -work work tb_rs_decoder.vhd

Use the following command to run the simulation:

vsim tb_rs_decoder_config -Grfile=tutorial2.pgm

Note that tutorial2.pgm is almost identical to received.pgm except that:

  1. Every code word has ten error symbols (earlier you added an eleventh to the first code word).
  2. An error symbol (255) has been placed at the first pixel (originally 124) of the first code word. This will help illustrate the behavior of the core when it has to re-synchronize for the first code word.

Take a note of the Processing Delay and Latency values now displayed in the Modelsim command prompt window:

Processing Delay: ________________(symbol_periods)
Latency:________________(symbol_periods)
Q8. Will the core be able to accept continuous input data?
Answer : ___________________

Add the core signals to the Wave window using the following commands:

add wave reset clk ce sr sync data_in
add wave data_out err_cnt err_found fail blk_strt blk_end ready

The clock period is still 20 ns, so run the simulation for 750 symbol periods:

run _______ ns

Q9. What do you notice about the ready signal?

Answer : __________________________________________

Latency (for multiple clock periods per symbol)

The symbol on data_in is sampled on the last rising edge of clk when sync is asserted.
Q10. Use cursors to measure the time between the last rising edge of clk when sync is asserted and the rising edge of blk_strt.
Answer : ___________________(in symbol periods)
Does your measured value agree with the value you noted earlier?

Re-synchronization

When multiple clock periods per symbol are used, the decoder initially doesn't know where the symbol period is relative to the clock. The decoder uses the rising edge of sync to synchronize itself with respect to the incoming symbols on data_in. It may be helpful to imagine that the decoder has an internal clock that has a rising edge at the end of each symbol period. Initially this imaginary clock is likely to be out of phase with the symbols on data_in. The decoder will always be able to synchronize itself to the incoming symbols. However, if the rising edge of sync occurs less than two clock periods before the rising edge of the imaginary clock, the decoder samples the first symbol twice. Note that the decoder still operates correctly, but an interesting thing happens on the data_out bus. The testbench has been configured to illustrate this case.
Zoom in on the first rising edge of blk_strt until the individual symbols on the data buses are visible. Notice that the uncorrected version (255) of the first symbol appears on data_out for one symbol period before blk_strt is asserted. Therefore in a user's design, circuits downstream should use  blk_strt and blk_end to define when data_out is valid, so that the uncorrected version of the first symbol is ignored.
IMPORTANT - If a new code word block is started on data_in  prior to the first corrected symbols from the previous block appearing on data_out, there must be a whole number of symbol periods between the last symbol of the previous block and the first symbol of the new block. Otherwise the decoder may lose track of processing the previous block.


End of Tutorial 2!

By now you should know how to:

  • generate a Reed-Solomon decoder core using the web-based configuration and download pages
  • push the core through the Xilinx implementation tools (exactly the same flow as for the encoder core, except it takes longer!)
  • simulate the core

and understand:

  • the difference between Processing Delay and Latency
  • the issues involved in using multiple clocks per symbol
  • how a Reed-Solomon codec can protect data !


Further reading

[1] P. J. Ashenden. "The designer's guide to VHDL". Section 18.2. Morgan Kaufmann Publishers, Inc., 1995. (ISBN 1-55860-270-4)
[2] S. Lin and D. J. Costello. "Error control coding: fundamentals and applications". Prentice-Hall, 1983. (ISBN 0-13-283796-X)
[3] S. B. Wicker and V. K. Bhargava (editors). "Reed-Solomon codes and their applications". IEEE Communications Society and IEEE Information Theory Society, 1994. (ISBN 0-7803-1025-X)
Back to Xilinx Reed-Solomon Solution page


 
  Trademarks and Patents
Legal Information

Privacy Policy
| Home | Products | Support | Education | Purchase | Contact | Search |