测试代码:
`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