Back-trace unit restores an (almost) maximum-likelihood path from the decisions made by PMU. Since it does it in inverse direction, a viterbi decoder comprises a FILO (first-in-last-out) buffer to reconstruct a correct order.Note that the implementation shown on the image requires double frequency. There are some tricks that eliminate this requirement.
The general approach to traceback is to accumulate path metrics for up to five times the constraint length (5 (K - 1)), find the node with the largest accumulated cost, and begin traceback from this node.However, computing the node which has accumulated the largest cost (either the largest or smallest integral path metric) involves finding the maxima or minima of several (usually 2K-1) numbers, which may be time consuming when implemented on embedded hardware systems.Most communication systems employ Viterbi decoding involving data packets of fixed sizes, with a fixed bit/byte pattern either at the beginning or/and at the end of the data packet. By using the known bit/byte pattern as reference, the start node may be set to a fixed value, thereby obtaining a perfect Maximum Likelihood Path during traceback.
The general approach to traceback is to accumulate path metrics for up to five times the constraint length (5 (K - 1)), find the node with the largest accumulated cost, and begin traceback from this node.However, computing the node which has accumulated the largest cost (either the largest or smallest integral path metric) involves finding the maxima or minima of several (usually 2K-1) numbers, which may be time consuming when implemented on embedded hardware systems.Most communication systems employ Viterbi decoding involving data packets of fixed sizes, with a fixed bit/byte pattern either at the beginning or/and at the end of the data packet. By using the known bit/byte pattern as reference, the start node may be set to a fixed value, thereby obtaining a perfect Maximum Likelihood Path during traceback.
Verilog code for Traceback unit (TBU)
module tbu
(
clk,
rst,
enable,
selection,
d_in_0,
d_in_1,
d_o,
wr_en
);
input clk;
input rst;
input enable;
input selection;
input [7:0] d_in_0;
input [7:0] d_in_1;
output reg d_o;
output reg wr_en;
reg d_o_reg;
reg wr_en_reg;
reg [2:0] pstate;
reg [2:0] nstate;
reg selection_buf;
always @(posedge clk)
begin
selection_buf <= selection;
wr_en <= wr_en_reg;
d_o <= d_o_reg;
end
always @(posedge clk or negedge rst)
begin
if(rst==1'b0)
pstate <= 3'b000;
else if(enable==1'b0)
pstate <= 3'b000;
else if(selection_buf==1'b1 && selection==1'b0)
pstate <= 3'b000;
else
pstate <= nstate;
end
always @(*)
begin
case (pstate)
3'b000:
begin
if(selection==1'b0)
begin
wr_en_reg = 1'b0;
case(d_in_0[0])
1'b0: nstate = 3'b000;
1'b1: nstate = 3'b001;
endcase
end
else
begin
d_o_reg = d_in_1[0];
wr_en_reg = 1'b1;
case(d_in_1[0])
1'b0: nstate = 3'b000;
1'b1: nstate = 3'b001;
endcase
end
end
3'b001:
begin
if(selection==1'b0)
begin
wr_en_reg = 1'b0;
case(d_in_0[1])
1'b0: nstate = 3'b011;
1'b1: nstate = 3'b010;
endcase
end
else
begin
d_o_reg = d_in_1[1];
wr_en_reg = 1'b1;
case(d_in_1[1])
1'b0: nstate = 3'b011;
1'b1: nstate = 3'b010;
endcase
end
end
3'b010:
begin
if(selection==1'b0)
begin
wr_en_reg = 1'b0;
case(d_in_0[2])
1'b0: nstate = 3'b100;
1'b1: nstate = 3'b101;
endcase
end
else
begin
d_o_reg = d_in_1[2];
wr_en_reg = 1'b1;
case(d_in_1[2])
1'b0: nstate = 3'b100;
1'b1: nstate = 3'b101;
endcase
end
end
3'b011:
begin
if(selection==1'b0)
begin
wr_en_reg = 1'b0;
case(d_in_0[3])
1'b0: nstate = 3'b111;
1'b1: nstate = 3'b110;
endcase
end
else
begin
d_o_reg = d_in_1[3];
wr_en_reg = 1'b1;
case(d_in_1[3])
1'b0: nstate = 3'b111;
1'b1: nstate = 3'b110;
endcase
end
end
3'b100:
begin
if(selection==1'b0)
begin
wr_en_reg = 1'b0;
case(d_in_0[4])
1'b0: nstate = 3'b001;
1'b1: nstate = 3'b000;
endcase
end
else
begin
d_o_reg = d_in_1[4];
wr_en_reg = 1'b1;
case(d_in_1[4])
1'b0: nstate = 3'b001;
1'b1: nstate = 3'b000;
endcase
end
end
3'b101:
begin
if(selection==1'b0)
begin
wr_en_reg = 1'b0;
case(d_in_0[5])
1'b0: nstate = 3'b010;
1'b1: nstate = 3'b011;
endcase
end
else
begin
d_o_reg = d_in_1[5];
wr_en_reg = 1'b1;
case(d_in_1[5])
1'b0: nstate = 3'b010;
1'b1: nstate = 3'b011;
endcase
end
end
3'b110:
begin
if(selection==1'b0)
begin
wr_en_reg = 1'b0;
case(d_in_0[6])
1'b0: nstate = 3'b101;
1'b1: nstate = 3'b100;
endcase
end
else
begin
d_o_reg = d_in_1[6];
wr_en_reg = 1'b1;
case(d_in_1[6])
1'b0: nstate = 3'b101;
1'b1: nstate = 3'b100;
endcase
end
end
3'b111:
begin
if(selection==1'b0)
begin
wr_en_reg = 1'b0;
case(d_in_0[7])
1'b0: nstate = 3'b110;
1'b1: nstate = 3'b111;
endcase
end
else
begin
d_o_reg = d_in_1[7];
wr_en_reg = 1'b1;
case(d_in_1[7])
1'b0: nstate = 3'b110;
1'b1: nstate = 3'b111;
endcase
end
end
endcase
end
endmodule
No comments:
Post a Comment