(2,1,2)卷积码的维特比译码Verilog实现

Verilog代码块

`timescale 1ns / 1ps
module viterbi(
  input  clk,
  input  clk_div2,
  input  rst_n,  //
  input  x,
  output y,
  output c,
  output reg rd,
  output reg ready);  
  reg[13:0]     x_t,x_t1;
  reg[3:0]      cnt;
  reg[2:0]      cnt2;
  reg[13:0]     a_out,a_out1,a1,a2,a3,a4;
  reg[3:0]      c1,c2,c3,c4; 
  reg[6:0]      c_t,c_t1,c_t2,c_t3,c_t4;
  reg[6:0]      c_t5;
   always@(posedge clk)begin
   if(!rst_n)begin
        x_t   <=  0;
    x_t1  <=  0;
    cnt   <=  0;
  end
   else begin
   if(cnt == 4'b1101)
        cnt   <= 4'b0000;        
   else
        cnt  <= cnt + 1;
    x_t1 <= {x,x_t1[13:1]};
         if(cnt == 4'b0000)begin
              x_t <= x_t1;
             end
          else
              x_t <= x_t;
   end 
  end
   always@(posedge clk_div2)begin
  if(!rst_n)begin
       cnt2 <= 0;
   a1   <= 0;
   a2   <= 0;
   a3   <= 0;
   a4   <= 0; 
   c1   <= 0;
   c2   <= 0;
   c3   <= 0;
   c4   <= 0;
   c_t1 <= 0;
   c_t2 <= 0;
   c_t3 <= 0;
   c_t4 <= 0;
  end
 else begin
   cnt2 <= cnt2  + 1;
     case(cnt2)
       3'b000: begin
         a1[1:0]  <= 2'b00;
         a2[1:0]  <= 2'b00;
         a3[1:0]  <= 2'b11;
         a4[1:0]  <= 2'b11;
         a1[13:2] <= 0;
         a2[13:2] <= 0;
         a3[13:2] <= 0;
         a4[13:2] <= 0;
         c1  <= 0;
         c2  <= 0;
         c3  <= 0;
         c4  <= 0;    
         c_t1[6]  <= 0;
         c_t2[6]  <= 0;
         c_t3[6]  <= 1;
         c_t4[6]  <= 1;
      end
     3'b001 : begin
          a1[3:2]  <= 2'b00;
          a2[3:2]  <= 2'b11;
          a3[3:2]  <= 2'b01;
          a4[3:2]  <= 2'b10;     
       c1  <= {3'b000,0^x_t[0]} + {3'b000,0^x_t[1]} +
                   {3'b000,0^x_t[2]} + {3'b000,0^x_t[3]};
       c2  <= {3'b000,0^x_t[0]} + {3'b000,0^x_t[1]} +
                   {3'b000,1^x_t[2]} + {3'b000,1^x_t[3]};
       c3  <= {3'b000,1^x_t[0]} + {3'b000,1^x_t[1]} +
                   {3'b000,1^x_t[2]} + {3'b000,0^x_t[3]};
       c4  <= {3'b000,1^x_t[0]} + {3'b000,1^x_t[1]} +
                   {3'b000,0^x_t[2]} + {3'b000,1^x_t[3]};   
       c_t1[5] <= 0;
       c_t2[5] <= 1;
       c_t3[5] <= 0;
       c_t4[5] <= 1;
    end    
     3'b010 : begin
         //  a = 2'b00
     if(c1 + {3'b000,0^x_t[5]} + {3'b000,0^x_t[4]} >
         c3 + {3'b000,1^x_t[5]} + {3'b000,1^x_t[4]})
      begin
       c1 <= c3 + {3'b000,1^x_t[5]} + {3'b000,1^x_t[4]};
       a1[3:0]    <= a3[3:0];
       a1[5:4]    <= 2'b11;
       c_t1[4]     <= 1'b0;
       c_t1[6:5]  <= c_t3[6:5];
      end
     else begin 
       c1 <= c1 + {3'b000,0^x_t[5]} + {3'b000,0^x_t[4]};
       a1[3:0]  <= a1[3:0];
       a1[5:4]  <= 2'b00;
       c_t1[4]  <= 1'b0;
       c_t1[6:5] <= c_t1[6:5];
      end
     // b = 2'b10
     if(c1 + {3'b000,1^x_t[5]} + {3'b000,1^x_t[4]} >
         c3 + {3'b000,0^x_t[5]} + {3'b000,0^x_t[5]})
      begin
        c2  <= c3 + {3'b000,0^x_t[5]} + {3'b000,0^x_t[5]};
      a2[3:0] <= a3[3:0];
      a2[5:4] <= 2'b00;
      c_t2[4] <= 1;
      c_t2[6:5] <= c_t3[6:5];
     end
     else begin 
      c2 <= c1 + {3'b000,1^x_t[5]} + {3'b000,1^x_t[4]};
      a2[3:0] <= a1[3:0];
      a2[5:4] <= 2'b11;
      c_t2[4]  <= 1;
      c_t2[6:5] <= c_t1[6:5];
      end
     //c = 2'b01
     if(c2 + {3'b000,0^x_t[5]} + {3'b000,1^x_t[4]} >
         c4 + {3'b000,1 ^x_t[5]} + {3'b000,0^x_t[4]})
      begin
        c3  <=c4 + {3'b000,1 ^x_t[5]} + {3'b000,0^x_t[4]};
        a3[3:0] <= a4[3:0];
        a3[5:4] <= 2'b10;
        c_t3[4]  <= 0;
        c_t3[6:5] <= c_t4[6:5];
      end
     else begin
        c3  <= c2 + {3'b000,0^x_t[5]} + {3'b000,1^x_t[4]};
        a3[3:0] <= a2[3:0];
        a3[5:4] <= 2'b01;
        c_t3[4] <= 0;
        c_t3[6:5] <= c_t2[6:5];
      end     
     // c = 2'b11
     if(c2 + {3'b000,1^x_t[5]} + {3'b000,0^x_t[4]} >
          c4 + {3'b000,0^x_t[5]} + {3'b000,1^x_t[4]})
      begin
       c4 <= c4 + {3'b000,0^x_t[5]} + {3'b000,1^x_t[4]};
       a4[3:0] <= a4[3:0];
       a4[5:4] <= 2'b01;
       c_t4[4] <= 1;
       c_t4[6:5] <= c_t4[6:5];
      end
     else begin
       c4 <= c2 + {3'b000,1^x_t[5]} + {3'b000,0^x_t[4]};
       a4[3:0] <= a2[3:0];
       a4[5:4] <= 2'b10;
       c_t4[4] <= 1;
       c_t4[6:5] <= c_t2[6:5];
      end
    end
   3'b011 :begin  
         //a = 2'b00
         if(c1 + {3'b000,0^x_t[7]} + {3'b000,0^x_t[6]} >
          c3 + {3'b000,1^x_t[7]} + {3'b000,1^x_t[6]})
      begin
       c1  <= c3 + {3'b000,1^x_t[7]} + {3'b000,1^x_t[6]};
       a1[5:0] <= a3[5:0];
       a1[7:6] <= 2'b11;
       c_t1[3] <= 0;
       c_t1[6:4] <= c_t3[6:4];
      end
     else begin
       c1  <= c1 + {3'b000,0^x_t[7]} + {3'b000,0^x_t[6]};
       a1[5:0] <= a1[5:0];
       a1[7:6] <= 2'b00;
       c_t1[3] <= 0;
       c_t1[6:4] <= c_t1[6:4];
      end
     // b = 2'b10
     if(c1 + {3'b000,1^x_t[7]} + {3'b000, 1^x_t[6]} >
          c3+ {3'b000,0^x_t[7]} + {3'b000,0^x_t[6]})
      begin
       c2  <= c3 + {3'b000,0^x_t[7]} + {3'b000,0^x_t[6]};
       a2[5:0] <= a3[5:0];
       a2[7:6] <= 2'b00;
       c_t2[3] <= 1;
       c_t2[6:4] <= c_t3[6:4];
      end
     else begin
       c2 <= c1 + {3'b000,1^x_t[7]} + {3'b000, 1^x_t[6]};
       a2[5:0]  <= a1[5:0];
       a2[7:6]  <= 2'b11;
       c_t2[3]  <= 1;
       c_t2[6:4] <= c_t1[6:4];
      end
     //2'b01
     if(c2 + {3'b000,0^x_t[7]} + {3'b000,1^x_t[6]} >
         c4 + {3'b000,1^x_t[7]} + {3'b000,0^x_t[6]})
      begin
       c3  <= c4 + {3'b000,1^x_t[7]} + {3'b000,0^x_t[6]};
       a3[5:0] <= a4[5:0];
       a3[7:6] <= 2'b10;
       c_t3[3] <= 0;
       c_t3[6:4] <= c_t4[6:4];
      end
     else begin
                 c3  <= c2 + {3'b000,0^x_t[7]} + {3'b000,1^x_t[6]};
       a3[5:0] <= a2[5:0];
       a3[7:6] <= 2'b01;
       c_t3[3] <= 0;
       c_t3[6:4] <= c_t2[6:4];
      end
     // 2'b11
     if(c2 + {3'b000,1^x_t[7]} + {3'b000,0^x_t[6]} >
         c4 + {3'b000,0^x_t[7]} + {3'b000,1^x_t[6]})
      begin
                 c4  <= c4 + {3'b000,1^x_t[7]} + {3'b000,0^x_t[6]};
       a4[5:0] <= a4[5:0];
       a4[7:6] <= 2'b01;
       c_t4[3] <= 1;
       c_t4[6:4] <= c_t4[6:4];
      end
     else begin
       c4  <= c2 + {3'b000,0^x_t[7]} + {3'b000,1^x_t[6]};
       a4[5:0] <= a2[5:0];
       a4[7:6] <= 2'b10;
       c_t4[3] <= 1;
       c_t4[6:4] <= c_t2[6:4];
      end
      end
     3'b100 : begin
         // 2'b00
     if(c1 + {3'b000,0^x_t[9]} + {3'b000,0^x_t[8]} >
         c3 + {3'b000,1^x_t[9]} + {3'b000,1^x_t[8]})
      begin
       c1  <= c3 + {3'b000,1^x_t[9]} + {3'b000,1^x_t[8]};
       a1[7:0] <= a3[7:0];
       a1[9:8] <= 2'b11;
       c_t1[2] <= 0;
       c_t1[6:3] <= c_t3[6:3];
      end
       else begin
       c1 <= c1 + {3'b000,0^x_t[9]} + {3'b000,0^x_t[8]};
       a1[7:0] <= a1[7:0];
       a1[9:8] <= 2'b00;
       c_t1[2] <= 0;
       c_t1[6:3] <= c_t1[6:3];
      end
     //2'b10
     if(c1 + {3'b000,1^x_t[9]} + {3'b000,1^x_t[8]} >
         c3 + {3'b000,0^x_t[9]} + {3'b000,0^x_t[8]})
      begin
       c2 <= c3 + {3'b000,0^x_t[9]} + {3'b000,0^x_t[8]};
       a2[7:0] <= a3[7:0];
       a2[9:8] <= 2'b00;
       c_t2[2] <= 1;
       c_t2[6:3] <= c_t3[6:3];
      end
     else begin
       c2 <= c1 + {3'b000,1^x_t[9]} + {3'b000,1^x_t[8]};
       a2[7:0] <= a1[7:0];
       a2[9:8] <= 2'b11;
       c_t2[2] <= 1;
       c_t2[6:3] <= c_t1[6:3];
      end
     // 2'b01
     if(c2 +{3'b000,0^x_t[9]} + {3'b000,1^x_t[8]} >
         c4 + {3'b000,1^x_t[9]} + {3'b000,0^x_t[8]})
      begin
       c3      <= c4 + {3'b000,1^x_t[9]} + {3'b000,0^x_t[8]};
      a3[7:0] <= a4[7:0];
       a3[9:8] <= 2'b10;
       c_t3[2] <= 0;
       c_t3[6:3] <= c_t4[6:3];
      end
     else begin
       c3  <= c2 + {3'b000,0^x_t[9]} + {3'b000,1^x_t[8]};
       a3[7:0] <= a2[7:0];
       a3[9:8] <= 2'b01;
       c_t3[2] <= 0;
       c_t3[6:3] <= c_t2[6:3];
      end
     // 2'b11
     if(c2 + {3'b000,1^x_t[9]} + {3'b000,0^x_t[8]} >
         c4 + {3'b000,0^x_t[9]} + {3'b000,1^x_t[8]})
      begin
       c4 <= c4 + {3'b000,0^x_t[9]} + {3'b000,1^x_t[8]};
       a4[7:0] <= a4[7:0];
       a4[9:8] <= 2'b01;
       c_t4[2] <= 1;
       c_t4[6:3] <= c_t4[6:3];
      end
     else begin
       c4 <= c2 + {3'b000,1^x_t[9]} + {3'b000,0^x_t[8]};
       a4[7:0] <= a2[7:0];
       a4[9:8] <= 2'b10;
       c_t4[2] <= 1;
       c_t4[6:3] <= c_t2[6:3];
      end
    end
   3'b101: begin
         //2'b00
     if(c1 + {3'b000,0^x_t[11]} + {3'b000,0^x_t[10]} >
         c3 + {3'b000,1^x_t[11]} + {3'b000,1^x_t[10]})
      begin
        c1 <= c3 + {3'b000,1^x_t[11]} + {3'b000,1^x_t[10]};
      a1[9:0] <= a3[9:0];
      a1[11:10] <= 2'b11;
      c_t1[1]   <= 0;
      c_t1[6:2] <= c_t3[6:2];
      end
     else begin
        c1 <= c1 + {3'b000,0^x_t[11]} + {3'b000,0^x_t[10]};
      a1[9:0]   <= a1[9:0];
      a1[11:10] <= 2'b00;
      c_t1[1]   <= 0;
      c_t1[6:2] <= c_t1[6:2];
      end
     //2'b01
     if(c2 + {3'b000,0^x_t[11]} + {3'b000,1^x_t[10]} >
         c4 + {3'b000,1^x_t[11]} + {3'b000,0^x_t[10]})
                begin
       c3 <= c4 + {3'b000,1^x_t[11]} + {3'b000,0^x_t[10]};
       a3[9:0]   <= a4[9:0];
       a3[11:10] <= 2'b10;
       c_t3[1]   <= 0;
       c_t3[6:2] <= c_t4[6:2];
      end
     else begin
       c3 <= c2 + {3'b000,0^x_t[11]} + {3'b000,1^x_t[10]};
       a3[9:0]   <= a2[9:0];
       a3[11:10] <= 2'b01;
       c_t3[1]   <= 0;
       c_t3[6:2] <= c_t2[6:2];
      end
    end
   3'b110 : begin
               // 2'b00
      if(c1 + {3'b000,0^x_t[13]} + {3'b000,0^x_t[12]} >
          c3 + {3'b000,1^x_t[13]} + {3'b000,1^x_t[12]})
      begin
       c1 <= c3 + {3'b000,1^x_t[13]} + {3'b000,1^x_t[12]};
       a1[11:0]    <= a3[11:0];
       a1[13:12]   <= 2'b11;
       a_out[11:0] <= a3[11:0];
       a_out[13:12]<= 2'b11;
       c_t1[0]     <= 0;
       c_t1[6:1]   <= c_t3[6:1];
      end
      else begin
       c1 <= c1 + {3'b000,0^x_t[13]} + {3'b000,0^x_t[12]};
       a1[11:0]    <= a1[11:0];
       a1[13:12]   <= 2'b00;
       a_out[11:0] <= a1[11:0];
       a_out[13:12]<= 2'b00;
       c_t1[0]     <= 0;
       c_t1[6:1]   <= c_t1[6:1];
      end
     end    
 3'b111 :  c_t5[6:0] <= c_t1[6:0];   
   default :begin
         a1[1:0] <= 2'b00;
         a2[1:0] <= 2'b00;
         a3[1:0] <= 2'b11;
         a4[1:0] <= 2'b11;     
         c1  <= 0;
         c2  <= 0;
         c3  <= 0;
         c4  <= 0;     
         c_t1 <= 0;
         c_t2 <= 0;
         c_t3 <= 0;
         c_t4 <= 0;
    end
  endcase
  end
 end
  always@(posedge clk)begin
    if(!rst_n)begin
     ready   <= 0;
   a_out1  <= 0;
   c_t     <= 0;
   rd      <= 0;
   end
  else begin
     if(cnt == 0)
       rd   <= 1;
   else
           rd  <= 0 ;
   if(cnt == 1)begin
      c_t    <= c_t5;
      a_out1 <= a_out;
    ready  <= 1;
      end
     else begin 
      ready  <= 0;
    a_out1[13:0] <= {a_out1[0],a_out1[13:1]};
    if(cnt[0]==1)
       c_t[6:0]  <= {c_t[5:0],c_t[6]};
   end
    end    
  end
    assign y = a_out1[0];
  assign c = c_t[6];
endmodule

以下是简单的测试模块(testbench)
输入待译码信息10010100101100
对应的路径译码11010100101100
输出的译码为1101000

“`

module viterbi_tb(
);
reg clk;
reg clk_div2;
reg reset;
reg x;

wire y;
wire c;
wire rd;
wire ready;

viterbi dut(clk,clk_div2,reset,x,y,c,rd,ready);

initial begin

clk      = 0;

clk_div2 = 0;
reset = 0;
#10;
x = 1;
#15;
reset = 1;
end

always #5 clk = ~clk;
always@(posedge clk)begin
clk_div2 <= ~clk_div2;
end
initial
begin
#25;
x = 1;
#10;
x = 0;
#10;
x = 0;
#10;
x = 1;
#10;
x = 0;
#10;
x = 1;
#10;
x = 0;
#10;
x = 0;
#10;
x = 1;
#10;
x = 0;
#10;
x = 1;
#10;
x = 1;
#10;
x = 0;
#10;
x = 0;
end
endmodule

附上modelsim仿真图

“`(2,1,2)卷积码的维特比译码Verilog实现_第1张图片

你可能感兴趣的:(verilog)