03-08-2018 06:40 AM
I made a Hardware Implementation of Convolutional Coding with Viterbi Decoding in VERILOG for a Zynq-7000 Application.
My Decoder is working very well with non-punctured Codes (R=1/2).
I have read some other posts about Viterbi Decoding of punctured convolutional codes but I still have some trouble with it. My Decoder is producing Bit Errors in case of punctured decoding (R=2/3 or 5/6). The interval between the Bit Errors at the output are not equidistant.
A logical "0" is internal mapped to +1 and a logical "1" is mapped to -1. My Branch Metric Unit is calculating the distances with Manhattan-Metric for all kind of Code-Rates. In Case of puncturing the erased bit is set to 0.
The only modifiaction for punctured decoding is inside the BMU, all other modules like ACS or Traceback are identical to non-punctured decoding.
I am sure, that the Input of my Branch Metric Calculation is identical to the punctured data at the Encoder.
That`s myy Manhattan-Distance calculation:
It is all sequential logic inside an always@(posedge clk) block. Is this the correct way to handle punctured data or is something wrong or missing. May I need addional changes in other modules?
input wire signed [1:0] in; output reg [7:0] bm00; output reg [7:0] bm01; output reg [7:0] bm10; output reg [7:0] bm11; reg signed [7:0] X; reg signed [7:0] Y; reg signed [7:0] md00_x; reg signed [7:0] md00_y; reg signed [7:0] md01_x; reg signed [7:0] md01_y; reg signed [7:0] md10_x; reg signed [7:0] md10_y; reg signed [7:0] md11_x; reg signed [7:0] md11_y; reg [7:0] abs_00; reg [7:0] abs_01; reg [7:0] abs_10; reg [7:0] abs_11; always @(posedge clk or negedge rst_n) begin if(!rst_n) begin /* some rst_n logic */ end else if(clk_en) begin X <= (punc_flag_x) ? 0 : in; Y <= (punc_flag_y) ? 0 : in; md00_x <= (+1-X); md00_y <= (+1-Y); md01_x <= (+1-X); md01_y <= (-1-Y); md10_x <= (-1-X); md10_y <= (+1-Y); md11_x <= (-1-X); md11_y <= (-1-Y); abs_00 <= ((md00_x) ? (~md00_x+1):md00_x) + ((md00_y) ? (~md00_y+1):md00_y); abs_01 <= ((md01_x) ? (~md01_x+1):md01_x) + ((md01_y) ? (~md01_y+1):md01_y); abs_10 <= ((md10_x) ? (~md10_x+1):md10_x) + ((md10_y) ? (~md10_y+1):md10_y); abs_11 <= ((md11_x) ? (~md11_x+1):md11_x) + ((md11_y) ? (~md11_y+1):md11_y); bm00 <= abs_00; bm01 <= abs_01; bm10 <= abs_10; bm11 <= abs_11; end end
Thank you for your help!
03-08-2018 10:42 AM
The only thing that comes to mind is that your puncturing flags may not be lined up with the actual punctured symbols.. In order for your code to work, you have to insert dummy symbols (like zeros) into the input stream, which is presumably done in an upstream module. You'll have to simulate the whole flow, and try to figure out where it's going wrong.
03-09-2018 02:02 AM
In my opinion, the puncturing flags are not the problem.
What I can see in my testbench is, that all flags are lined up with punctured bits.