logo资料库

Verilog实现viterbi 译码.doc

第1页 / 共8页
第2页 / 共8页
第3页 / 共8页
第4页 / 共8页
第5页 / 共8页
第6页 / 共8页
第7页 / 共8页
第8页 / 共8页
资料共8页,全文预览结束
测试代码: `timescale 1ns / 1ps module VB_test( ); reg clk_all = 0; reg rst_all = 0; wire [2:0] BUM_dasin0; wire [2:0] BUM_dasin1; wire [2:0] BUM_dasin2; wire outbit; wire ready; wire start; wire = 60'b1110101001_1011010100_1010001010_1010111101_0100010101_1011001011;// 定 义 传 输序列 [59:0] inbit rst_all <= 1; rst_all <= 0; always #10 clk_all <= ~clk_all; initial begin #50 #50 end VB_top VB_top_test( .BUM_dasin0(BUM_dasin0), .BUM_dasin1(BUM_dasin1), .BUM_dasin2(BUM_dasin2), .outbit(outbit), //l-bit-output .ready(ready), .clk(clk_all), .reset(rst_all), .start(start) //decode output ready ); vbencoder vbencoder_test( .inbit(inbit), .BUM_dasin0(BUM_dasin0), .BUM_dasin1(BUM_dasin1), .BUM_dasin2(BUM_dasin2), .clk(clk_all), .reset(rst_all), .ready_en(start) );
endmodule module vbencoder(inbit,BUM_dasin0,BUM_dasin1,BUM_dasin2,clk,reset,ready_en); //for 2-1-6 code input [59:0] inbit;//input bit=一 0 or 1 output [2:0]BUM_dasin0; output [2:0]BUM_dasin1; output [2:0]BUM_dasin2; input clk; input reset;//if==1,reset the module output ready_en; reg [2:0]BUM_dasin0; reg [2:0]BUM_dasin1; reg [2:0]BUM_dasin2; reg [5:0] count =0; reg [2:0] outG3G2G1; reg [6-1:0] curstt; //current state 一 0 一('STTNUM-I) reg ready_en = 0; always @ (posedge clk) begin if(reset) begin curstt=0; outG3G2G1='bzzz; ready_en = 0; count = 0; end else begin 最右边为 curstt[5] 1 1 0 1 0 1 1 1 1 0 0 1 0 1 1 0 1 1 1--7 0---0, //(3,1,7)卷积编码,每次输入比特从左到右输入,最左边为 inbit[count], outG3G2G1[2] = curstt[5]^curstt[3]^curstt[1]^curstt[0]^inbit[count];//1 outG3G2G1[1] = curstt[5]^curstt[2]^curstt[1]^curstt[0]^inbit[count];//1 outG3G2G1[0] = curstt[5]^curstt[4]^curstt[2]^curstt[1]^inbit[count];//1 //由于本方案是进行软判决,所以模拟对卷积编码后的比特进行量化 if(outG3G2G1[2]) BUM_dasin0 = 3'b111; else BUM_dasin0 = 3'b000;
if(outG3G2G1[1]) BUM_dasin1 = 3'b111; else BUM_dasin1 = 3'b000; if(outG3G2G1[0]) BUM_dasin2 = 3'b111; else BUM_dasin2 = 3'b000; curstt = (curstt << 1) | inbit[count]; count = count + 1; ready_en =1; if((count<1) | (count>=60)) begin count =0; curstt=0; end end end endmodule 顶层模块: `timescale 1ns / 1ps `define STATE_BIT_NUM 6 `define STATE_NUM 64 `define CODE_LENGTH 60 //截断深度 译码长度 (`STATE_BIT_NUM * 6) `define METRICW 8 `define CODE_LENGTH_BIT_NUM 6 //number of states of these registers, //number of regi sters in encoder //bit-Width of a metric value // bit-width of user-defined code-sequence-lengh. //must be wide enough to accomodate"MAX_USERML //bit-width for counter,i,… //decode output ready `define COUNTER_WIDTH 8 module VB_top( BUM_dasin0, BUM_dasin1, BUM_dasin2, outbit, //l-bit-output ready, clk, reset, start ); input [2:0] BUM_dasin0; input [2:0] BUM_dasin1; input [2:0] BUM_dasin2; input clk;
input reset; input start; output outbit; output ready; reg outbit; reg ready; reg [`COUNTER_WIDTH-1:0] reg [`COUNTER_WIDTH-1:0] counter; i; reg [`CODE_LENGTH_BIT_NUM-1:0] decodedepth; //store each state's current metric reg [`METRICW-1:0] metric[`STATE_NUM-1:0]; reg [`METRICW-1:0] metric_tmp[`STATE_NUM-1:0]; reg [`METRICW-1:0] min_metric; reg [`STATE_BIT_NUM - 1:0] minpos; //store each state's current path reg [`CODE_LENGTH-1:0] path[`STATE_NUM-1:0]; reg [`CODE_LENGTH-1:0] path_tmp[`STATE_NUM-1:0]; reg [`CODE_LENGTH-1:0] outbits; reg ok; //================================================ always @ (posedge clk)begin if(start) begin if(reset) begin decodedepth = `CODE_LENGTH; counter = 0; ok = 0; ready = 0; outbits = 0; for(i=0;i<`STATE_NUM;i=i + 1) begin metric[i] = 0; metric_tmp[i] = 0; path[i] = 0; path_tmp[i] = 0; end end else
begin counter = counter + 1; if((counter<1) || (counter>decodedepth)) begin counter = 1; ready = 1; min_metric = metric[0]; minpos = 0; for(i=0;i<`STATE_NUM;i=i+1) begin if(metric[i]
outbit=outbits[decodedepth-counter]; end endtask //=========================================== //=========================================== task DoRcvBBCodeSeqTrunc; begin if((counter>=1)&&(counter<=decodedepth)) do_part2_ACS; end endtask //============================================== //============================================== task do_part2_ACS; reg[`STATE_BIT_NUM:0] i; //don't use[`M-1: O],that's too small! begin for(i=0;i<`STATE_NUM;i=i+1) begin do_1_ACS(i,BUM_dasin0,BUM_dasin1,BUM_dasin2); end end endtask //============================================== //============================================== task do_1_ACS; input[`STATE_BIT_NUM-1:0] curstt;//current state input[2:0] inbb0; input[2:0] inbb1; input[2:0] inbb2; //use in do_1_ACS reg[`STATE_BIT_NUM-1:0] tmp; reg[`STATE_BIT_NUM-1:0] s1; reg[`STATE_BIT_NUM-1:0] s2; reg ib; //these 2 width must equal above metric's width。 reg[`METRICW-1:0] m1; reg[`METRICW-1:0] m2;
reg[4:0] d1; //0`2 reg[4:0] d2; //0`2 reg[2:0] obbl; reg[2:0] obb2; begin s1=(curstt>>1); s2=(curstt>>1)|(1<<(`STATE_BIT_NUM-1)); ib=curstt[0]; doFSM(s1,ib,tmp,obbl); //compute obbl doFSM(s2,ib,tmp,obb2); //compute obb2 d1=distance(obbl,inbb0,inbb1,inbb2); d2=distance(obb2,inbb0,inbb1,inbb2); m1=metric[s1]+d1; m2=metric[s2]+d2; if(m1
endtask //============================================== //============================================== function [4:0] distance; //Hamming Distance=0 or 1 or 2 input[2:0] G123; input[2:0] G123_0; input[2:0] G123_1; input[2:0] G123_2; begin case(G123) 3'b000: distance = G123_0 + G123_1 + G123_2; 3'b001: distance = G123_0 + G123_1 + (~G123_2 & 5'b00111); 3'b010: distance = G123_0 + (~G123_1 & 5'b00111) + G123_2; 3'b011: distance = G123_0 + (~G123_1 & 5'b00111) + (~G123_2 & 5'b00111); 3'b100: distance = (~G123_0 & 5'b00111) + G123_1 + G123_2; 3'b101: distance = (~G123_0 & 5'b00111) + G123_1 + (~G123_2 & 5'b00111); 3'b110: distance = (~G123_0 & 5'b00111) + (~G123_1 & 5'b00111) + G123_2; 3'b111: distance = (~G123_0 & 5'b00111) + (~G123_1 & 5'b00111) + (~G123_2 & 5'b00111); default: distance = 0; endcase end endfunction //============================================== endmodule
分享到:
收藏