4.4.8 多码速卷积码硬件结构与实现
1.Convolution Encoder模块
卷积编码模块代码:
module conv_encoder(clk,aclr,data_in,nd,data_out_v,rdy);
input aclr;
input clk;
input data_in;
input nd;
output [1:0] data_out_v;
output rdy;
reg [6:1] shift_reg;
reg [1:0] data_out_v;
reg rdy;
always @ ( negedge aclr or posedge clk )
begin
if ( ! aclr )
begin
shift_reg <= 6'b000000;
data_out_v <= 0;
rdy <= 0 ;
end
else
if ( nd )
begin
data_out_v[0] <= shift_reg[6] + shift_reg[5] + shift_reg[3] + shift_reg[2] + data_in;
data_out_v[1] <= shift_reg[6] + shift_reg[3] + shift_reg[2] + shift_reg[1] + data_in;
rdy<=1;
shift_reg <= { shift_reg [5:1], data_in };
end
else
rdy <= 0;
end
endmodule
2.‘3/4’码率卷积的实现
(1)1/2卷积码放入缓存
(2)删余
(3)输出
代码:
module DATA_conv_encoder(DCONV_DIN,DCONV_ND,RATE_CON,DCONV_RST,DCONV_CLK_I,
DCONV_CLK_O,DCONV_DOUT,DCONV_INDEX,DCONV_RDY);
input DCONV_DIN;
input DCONV_ND;
input [3:0] RATE_CON;
input DCONV_RST;
input DCONV_CLK_I;
input DCONV_CLK_O;
output DCONV_DOUT;
output [8:0] DCONV_INDEX;
output DCONV_RDY;
wire RST;
wire [1:0] DATA_OUT_V;
wire RDY;
reg BUF_RDY;
reg [1:0] i;
reg [2:0] j;
reg [1:0] Puncture_BUF_12;
reg [5:0] Puncture_BUF_34;
reg [3:0] Puncture_BUF_23;
reg [9:0] INDEX_TEMP;
reg DCONV_DOUT;
reg [8:0] DCONV_INDEX;
reg DCONV_RDY;
//assign RST = ~DCONV_RST;
conv_encoder conv_encoder1(
.data_in(DCONV_DIN),
.nd(DCONV_ND),
.clk(DCONV_CLK_I),
.aclr(DCONV_RST),
.data_out_v(DATA_OUT_V),
.rdy(RDY));
always @ ( negedge DCONV_RST or posedge DCONV_CLK_I ) // Put data into puncture_buffer.
begin
if ( ! DCONV_RST )
begin
Puncture_BUF_12 <= 0;
Puncture_BUF_34 <= 0;
Puncture_BUF_23 <= 0;
i <= 0;
end
else
begin
if ( RDY )
case ( RATE_CON )
4'b1101,4'b0101,4'b1001: // Rate is 1/2 .
begin
Puncture_BUF_12 <= DATA_OUT_V;
BUF_RDY <= 1;
end
4'b1111,4'b0111,4'b1011,4'b0011: // Rate is 3/4 .
begin
case (i)
2'b00:
begin
Puncture_BUF_34 [1:0] <= DATA_OUT_V;
BUF_RDY <= 1;
i <= i + 1 ;
end
2'b01:
begin
Puncture_BUF_34 [3:2] <= DATA_OUT_V;
BUF_RDY <= 1;
i <= i + 1 ;
end
2'b10:
begin
Puncture_BUF_34 [5:4] <= DATA_OUT_V;
BUF_RDY <= 1;
i <= 2'b00 ;
end
default:
begin
Puncture_BUF_34 <= 0;
BUF_RDY <= 0;
i <= 0;
end
endcase
end
4'b0001: // Rate is 2/3 .
begin
case ( i )
2'b00:
begin
Puncture_BUF_23 [1:0] <= DATA_OUT_V;
BUF_RDY <= 1;
i <= i + 1 ;
end
2'b01:
begin
Puncture_BUF_23 [3:2] <= DATA_OUT_V;
BUF_RDY <= 1;
i <= 0 ;
end
default:
begin
Puncture_BUF_23 <= 0;
BUF_RDY <= 0;
i <= 0 ;
end
endcase
end
endcase
else
begin
BUF_RDY <= 0;
Puncture_BUF_12 <= 0;
Puncture_BUF_34 <= 0;
Puncture_BUF_23 <= 0;
i <= 0;
end
end
end
always @ ( negedge DCONV_RST or posedge DCONV_CLK_O ) // Puncture and output the data.
begin
if ( ! DCONV_RST )
begin
DCONV_DOUT <= 0 ;
DCONV_RDY <= 0;
j <= 3'b000;
end
else
if ( BUF_RDY )
case ( RATE_CON )
4'b1101,4'b0101,4'b1001: // Rate is 1/2 .
begin
case ( j )
3'b000:
begin
DCONV_DOUT <= Puncture_BUF_12 [j] ;
DCONV_RDY <= 1;
j <= j +1 ;
end
3'b001:
begin
DCONV_DOUT <= Puncture_BUF_12 [j] ;
DCONV_RDY <= 1;
j <= 3'b000 ;
end
default:
begin
DCONV_DOUT <= 0 ;
DCONV_RDY <= 0;
j <= 3'b000 ;
end
endcase
end
4'b1111,4'b0111,4'b1011,4'b0011: // Rate is 3/4 .
begin
case (j)
3'b000,3'b001,3'b010:
begin
DCONV_DOUT <= Puncture_BUF_34 [j] ;
DCONV_RDY <= 1;
j <= j + 1 ;
end
3'b011:
begin
DCONV_DOUT <= Puncture_BUF_34 [j+2] ;
DCONV_RDY <= 1;
j <= 3'b000 ;
end
default:
begin
DCONV_DOUT <= 0;
DCONV_RDY <= 0;
j <= 0;
end
endcase
end
4'b0001: // Rate is 2/3 .
begin
case ( j )
3'b000,3'b001:
begin
DCONV_DOUT <= Puncture_BUF_23 [j] ;
DCONV_RDY <= 1;
j <= j + 1 ;
end
3'b010:
begin
DCONV_DOUT <= Puncture_BUF_23 [j] ;
DCONV_RDY <= 1;
j <= 3'b000 ;
end
default:
begin
DCONV_DOUT <= 0 ;
DCONV_RDY <= 0 ;
j <= 0 ;
end
endcase
end
endcase
else
begin
DCONV_DOUT <= 0 ;
DCONV_RDY <= 0 ;
end
end
always @ ( negedge DCONV_RST or posedge DCONV_CLK_O ) // Index output.
begin
if ( ! DCONV_RST )
begin
DCONV_INDEX <= 0 ;
INDEX_TEMP <= 0;
end
else
begin
if ( BUF_RDY )
case ( RATE_CON )
4'b1101,4'b1111:
begin
if( INDEX_TEMP < 47 )
begin
INDEX_TEMP <= INDEX_TEMP + 1 ;
DCONV_INDEX <= INDEX_TEMP ;
end
else
begin
INDEX_TEMP <= 0 ;
DCONV_INDEX <= INDEX_TEMP ;
end
end
4'b0101,4'b0111:
begin
if( INDEX_TEMP < 95 )
begin
INDEX_TEMP <= INDEX_TEMP + 1 ;
DCONV_INDEX <= INDEX_TEMP ;
end
else
begin
INDEX_TEMP <= 0 ;
DCONV_INDEX <= INDEX_TEMP ;
end
end
4'b1001,4'b1011:
begin
if( INDEX_TEMP < 191 )
begin
INDEX_TEMP <= INDEX_TEMP + 1 ;
DCONV_INDEX <= INDEX_TEMP ;
end
else
begin
INDEX_TEMP <= 0 ;
DCONV_INDEX <= INDEX_TEMP ;
end
end
4'b0001,4'b0011:
begin
if( INDEX_TEMP < 287 )
begin
INDEX_TEMP <= INDEX_TEMP + 1 ;
DCONV_INDEX <= INDEX_TEMP ;
end
else
begin
INDEX_TEMP <= 0 ;
DCONV_INDEX <= INDEX_TEMP ;
end
end
endcase
else
DCONV_INDEX <= 0 ;
end
end
endmodule