Buy latest IEEE projects of 2018 online with base paper abstract Schematic Diagram and the main thing is code. All the things you will be found here with less cost. Price ranges from Rs.50-2000 depending on the project. We Mainly focus on Embedded VLSI and Matlab Projects. CSE and IT Projects are also Focused.

Sunday, May 7, 2017

Verilog HDL Implementation of the Viterbi decoder Algorithm



A Viterbi decoder uses the Viterbi algorithm for decoding a bitstream that has been encoded using convolutional code or trellis code.There are other algorithms for decoding a convolutionally encoded stream (for example, the Fano algorithm). The Viterbi algorithm is the most resource-consuming, but it does the maximum likelihood decoding. It is most often used for decoding convolutional codes with constraint lengths k<=10, but values up to k=15 are used in practice.Viterbi decoding was developed by Andrew J. Viterbi and published in the paper "Error Bounds for Convolutional Codes and an Asymptotically Optimum Decoding Algorithm", IEEE Transactions on Information Theory, Volume IT-13, pages 260-269, in April, 1967.There are both hardware (in modems) and software implementations of a Viterbi decoder.
Verilog implementation of Viterbi decoder

Verilog code for Viterbi Decoder

module decoder
(


   clk,
   rst,
   enable,
   d_in,
   d_out
);

   input             clk;
   input             rst;
   input             enable;
   input [1:0]       d_in;
   output            d_out;

   reg               decoder_o_reg;


//bmc module signals
   wire  [1:0]       bmc000_path_0_bmc;
   wire  [1:0]       bmc001_path_0_bmc;
   wire  [1:0]       bmc010_path_0_bmc;
   wire  [1:0]       bmc011_path_0_bmc;
   wire  [1:0]       bmc100_path_0_bmc;
   wire  [1:0]       bmc101_path_0_bmc;
   wire  [1:0]       bmc110_path_0_bmc;
   wire  [1:0]       bmc111_path_0_bmc;

   wire  [1:0]       bmc000_path_1_bmc;
   wire  [1:0]       bmc001_path_1_bmc;
   wire  [1:0]       bmc010_path_1_bmc;
   wire  [1:0]       bmc011_path_1_bmc;
   wire  [1:0]       bmc100_path_1_bmc;
   wire  [1:0]       bmc101_path_1_bmc;
   wire  [1:0]       bmc110_path_1_bmc;
   wire  [1:0]       bmc111_path_1_bmc;

//ACS modules signals
   reg   [7:0]       validity;
   reg   [7:0]       selection;
   reg   [7:0]       path_cost   [7:0];
   wire  [7:0]       validity_nets;
   wire  [7:0]       selection_nets;

   wire              ACS000_selection;
   wire              ACS001_selection;
   wire              ACS010_selection;
   wire              ACS011_selection;
   wire              ACS100_selection;
   wire              ACS101_selection;
   wire              ACS110_selection;
   wire              ACS111_selection;

   wire              ACS000_valid_o;
   wire              ACS001_valid_o;
   wire              ACS010_valid_o;
   wire              ACS011_valid_o;
   wire              ACS100_valid_o;
   wire              ACS101_valid_o;
   wire              ACS110_valid_o;
   wire              ACS111_valid_o;

   wire  [7:0]       ACS000_path_cost;
   wire  [7:0]       ACS001_path_cost;
   wire  [7:0]       ACS010_path_cost;
   wire  [7:0]       ACS011_path_cost;
   wire  [7:0]       ACS100_path_cost;
   wire  [7:0]       ACS101_path_cost;
   wire  [7:0]       ACS110_path_cost;
   wire  [7:0]       ACS111_path_cost;

//Trelis memory write operation
   reg   [1:0]       mem_bank;
   reg   [1:0]       mem_bank_buf;
   reg   [1:0]       mem_bank_buf_buf;
   reg               mem_bank_buf_buf_buf;
   reg               mem_bank_buf_buf_buf_buf;
   reg               mem_bank_buf_buf_buf_buf_buf;
   reg   [9:0]       wr_mem_counter;
   reg   [9:0]       rd_mem_counter;

   reg   [9:0]       addr_mem_A;
   reg   [9:0]       addr_mem_B;
   reg   [9:0]       addr_mem_C;
   reg   [9:0]       addr_mem_D;

   reg               wr_mem_A;
   reg               wr_mem_B;
   reg               wr_mem_C;
   reg               wr_mem_D;

   reg   [7:0]       d_in_mem_A;
   reg   [7:0]       d_in_mem_B;
   reg   [7:0]       d_in_mem_C;
   reg   [7:0]       d_in_mem_D;

   wire  [7:0]       d_o_mem_A;
   wire  [7:0]       d_o_mem_B;
   wire  [7:0]       d_o_mem_C;
   wire  [7:0]       d_o_mem_D;

//Trace back module signals
   reg               selection_tbu_0;
   reg               selection_tbu_1;

   reg   [7:0]       d_in_0_tbu_0;
   reg   [7:0]       d_in_1_tbu_0;
   reg   [7:0]       d_in_0_tbu_1;
   reg   [7:0]       d_in_1_tbu_1;

   wire              d_o_tbu_0;
   wire              d_o_tbu_1;

   reg               enable_tbu_0;
   reg               enable_tbu_1;

//Display memory operations 
   wire              wr_disp_mem_0;
   wire              wr_disp_mem_1;

   wire              d_in_disp_mem_0;
   wire              d_in_disp_mem_1;

   reg   [9:0]       wr_mem_counter_disp;
   reg   [9:0]       rd_mem_counter_disp;

   reg   [9:0]       addr_disp_mem_0;
   reg   [9:0]       addr_disp_mem_1;


   assign   d_out =  decoder_o_reg;


//Branch matrc calculation modules

   bmc000   bmc000_inst(d_in,bmc000_path_0_bmc,bmc000_path_1_bmc);
   bmc001   bmc001_inst(d_in,bmc001_path_0_bmc,bmc001_path_1_bmc);
   bmc010   bmc010_inst(d_in,bmc010_path_0_bmc,bmc010_path_1_bmc);
   bmc011   bmc011_inst(d_in,bmc011_path_0_bmc,bmc011_path_1_bmc);
   bmc100   bmc100_inst(d_in,bmc100_path_0_bmc,bmc100_path_1_bmc);
   bmc101   bmc101_inst(d_in,bmc101_path_0_bmc,bmc101_path_1_bmc);
   bmc110   bmc110_inst(d_in,bmc110_path_0_bmc,bmc110_path_1_bmc);
   bmc111   bmc111_inst(d_in,bmc111_path_0_bmc,bmc111_path_1_bmc);


//Add Compare Select Modules

   ACS      ACS000(validity[0],validity[1],bmc000_path_0_bmc,bmc000_path_1_bmc,path_cost[0],path_cost[1],ACS000_selection,ACS000_valid_o,ACS000_path_cost);
   ACS      ACS001(validity[3],validity[2],bmc001_path_0_bmc,bmc001_path_1_bmc,path_cost[3],path_cost[2],ACS001_selection,ACS001_valid_o,ACS001_path_cost);
   ACS      ACS010(validity[4],validity[5],bmc010_path_0_bmc,bmc010_path_1_bmc,path_cost[4],path_cost[5],ACS010_selection,ACS010_valid_o,ACS010_path_cost);
   ACS      ACS011(validity[7],validity[6],bmc011_path_0_bmc,bmc011_path_1_bmc,path_cost[7],path_cost[6],ACS011_selection,ACS011_valid_o,ACS011_path_cost);
   ACS      ACS100(validity[1],validity[0],bmc100_path_0_bmc,bmc100_path_1_bmc,path_cost[1],path_cost[0],ACS100_selection,ACS100_valid_o,ACS100_path_cost);
   ACS      ACS101(validity[2],validity[3],bmc101_path_0_bmc,bmc101_path_1_bmc,path_cost[2],path_cost[3],ACS101_selection,ACS101_valid_o,ACS101_path_cost);
   ACS      ACS110(validity[5],validity[4],bmc110_path_0_bmc,bmc110_path_1_bmc,path_cost[5],path_cost[4],ACS110_selection,ACS110_valid_o,ACS110_path_cost);
   ACS      ACS111(validity[6],validity[7],bmc111_path_0_bmc,bmc111_path_1_bmc,path_cost[6],path_cost[7],ACS111_selection,ACS111_valid_o,ACS111_path_cost);

   
   assign selection_nets  =  {ACS111_selection,ACS110_selection,ACS101_selection,ACS100_selection,
                              ACS011_selection,ACS010_selection,ACS001_selection,ACS000_selection};
   assign validity_nets    =  {ACS111_valid_o,ACS110_valid_o,ACS101_valid_o,ACS100_valid_o,
                              ACS011_valid_o,ACS010_valid_o,ACS001_valid_o,ACS000_valid_o};


   always @ (posedge clk or negedge rst)
   begin
      if(rst==1'b0)
      begin
         validity          <= 8'b00000001;
         selection         <= 8'b00000000;

         path_cost[0]      <= 8'd0;
         path_cost[1]      <= 8'd0;
         path_cost[2]      <= 8'd0;
         path_cost[3]      <= 8'd0;
         path_cost[4]      <= 8'd0;
         path_cost[5]      <= 8'd0;
         path_cost[6]      <= 8'd0;
         path_cost[7]      <= 8'd0;

      end
      else if(enable==1'b0)
      begin
         validity          <= 8'b00000001;
         selection         <= 8'b00000000;

         path_cost[0]      <= 8'd0;
         path_cost[1]      <= 8'd0;
         path_cost[2]      <= 8'd0;
         path_cost[3]      <= 8'd0;
         path_cost[4]      <= 8'd0;
         path_cost[5]      <= 8'd0;
         path_cost[6]      <= 8'd0;
         path_cost[7]      <= 8'd0;

      end
      else if( path_cost[0][7] && path_cost[1][7] && path_cost[2][7] && path_cost[3][7] &&
             path_cost[4][7] && path_cost[5][7] && path_cost[6][7] && path_cost[7][7] )
      begin

         validity          <= validity_nets;
         selection         <= selection_nets;
         
         path_cost[0]      <= 8'b01111111 & ACS000_path_cost;
         path_cost[1]      <= 8'b01111111 & ACS001_path_cost;
         path_cost[2]      <= 8'b01111111 & ACS010_path_cost;
         path_cost[3]      <= 8'b01111111 & ACS011_path_cost;
         path_cost[4]      <= 8'b01111111 & ACS100_path_cost;
         path_cost[5]      <= 8'b01111111 & ACS101_path_cost;
         path_cost[6]      <= 8'b01111111 & ACS110_path_cost;
         path_cost[7]      <= 8'b01111111 & ACS111_path_cost;
      end
      else 
      begin
         validity          <= validity_nets;
         selection         <= selection_nets;

         path_cost[0]      <= ACS000_path_cost;
         path_cost[1]      <= ACS001_path_cost;
         path_cost[2]      <= ACS010_path_cost;
         path_cost[3]      <= ACS011_path_cost;
         path_cost[4]      <= ACS100_path_cost;
         path_cost[5]      <= ACS101_path_cost;
         path_cost[6]      <= ACS110_path_cost;
         path_cost[7]      <= ACS111_path_cost;
      end
   end



   always @ (posedge clk or negedge rst)
   begin
      if(rst==1'b0)
         wr_mem_counter <= 10'd0;
      else if(enable==1'b0)
         wr_mem_counter <= 10'd0;
      else
         wr_mem_counter <= wr_mem_counter + 10'd1;
   end

   always @ (posedge clk or negedge rst)
   begin
      if(rst==1'b0)
         rd_mem_counter <= 10'b1111111111;
      else if(enable==1'b0)
         rd_mem_counter <= 10'd0;
      else
         rd_mem_counter <= rd_mem_counter - 10'd1;
   end

   
   always @ (posedge clk or negedge rst)
   begin
      if(rst==1'b0)
         mem_bank <= 2'b00;
      else begin
         if(wr_mem_counter==10'b1111111111)
               mem_bank <= mem_bank + 2'b01;
      end
   end

   
   always @ (posedge clk)
   begin
      d_in_mem_A  <= selection;
      d_in_mem_B  <= selection;
      d_in_mem_C  <= selection;
      d_in_mem_D  <= selection;

   end


   always @ (posedge clk)
   begin
if(!rst)
begin
wr_mem_A <= 0;
wr_mem_B <= 0;
wr_mem_C <= 0;
wr_mem_D <= 0;
end
else
begin
      case(mem_bank)
         2'b00:
         begin
            addr_mem_A        <= wr_mem_counter;
            addr_mem_B        <= rd_mem_counter;
            addr_mem_C        <= 10'd0;
            addr_mem_D        <= rd_mem_counter;

            wr_mem_A          <= 1'b1;
            wr_mem_B          <= 1'b0;
            wr_mem_C          <= 1'b0;
            wr_mem_D          <= 1'b0;
         end
         2'b01:
         begin
            addr_mem_A        <= rd_mem_counter;
            addr_mem_B        <= wr_mem_counter;
            addr_mem_C        <= rd_mem_counter;
            addr_mem_D        <= 10'd0;

            wr_mem_A          <= 1'b0;
            wr_mem_B          <= 1'b1;
            wr_mem_C          <= 1'b0;
            wr_mem_D          <= 1'b0;

         end
         2'b10:
         begin
            addr_mem_A        <= 10'd0;
            addr_mem_B        <= rd_mem_counter;
            addr_mem_C        <= wr_mem_counter;
            addr_mem_D        <= rd_mem_counter;

            wr_mem_A          <= 1'b0;
            wr_mem_B          <= 1'b0;
            wr_mem_C          <= 1'b1;
            wr_mem_D          <= 1'b0;
         end
         2'b11:
         begin
            addr_mem_A        <= rd_mem_counter;
            addr_mem_B        <= 10'd0;
            addr_mem_C        <= rd_mem_counter;
            addr_mem_D        <= wr_mem_counter;

            wr_mem_A          <= 1'b0;
            wr_mem_B          <= 1'b0;
            wr_mem_C          <= 1'b0;
            wr_mem_D          <= 1'b1;
         end
      endcase
end
  end

//Trelis memory module instantiation

   mem   trelis_mem_A
   (
      //.rst(rst),
.clk(clk),
      .wr(wr_mem_A),
      .addr(addr_mem_A),
      .d_i(d_in_mem_A),
      .d_o(d_o_mem_A)
   );

  mem   trelis_mem_B
   (
     // .rst(rst),
.clk(clk),
      .wr(wr_mem_B),
      .addr(addr_mem_B),
      .d_i(d_in_mem_B),
      .d_o(d_o_mem_B)
   );

  mem   trelis_mem_C
   (
     // .rst(rst),
.clk(clk),
      .wr(wr_mem_C),
      .addr(addr_mem_C),
      .d_i(d_in_mem_C),
      .d_o(d_o_mem_C)
   );

  mem   trelis_mem_D
   (
     // .rst(rst),
.clk(clk),
      .wr(wr_mem_D),
      .addr(addr_mem_D),
      .d_i(d_in_mem_D),
      .d_o(d_o_mem_D)
   );

//Trace back module operation

   always @(posedge clk)
      mem_bank_buf   <= mem_bank;
   
   always @(posedge clk)
      mem_bank_buf_buf   <= mem_bank_buf;


   always @ (posedge clk or negedge rst)
   begin
      if(rst==1'b0)
            enable_tbu_0   <= 1'b0;
      else begin
         if(mem_bank_buf_buf==2'b10)
            enable_tbu_0   <= 1'b1;
         else
            enable_tbu_0   <= enable_tbu_0;
      end   
   end

   always @ (posedge clk or negedge rst)
   begin
      if(rst==1'b0)
            enable_tbu_1   <= 1'b0;
      else begin
         if(mem_bank_buf_buf==2'b11)
            enable_tbu_1   <= 1'b1;
         else
            enable_tbu_1   <= enable_tbu_1;
      end   
   end
   
   always @ (posedge clk)
   begin
      case(mem_bank_buf_buf)
         2'b00:
         begin
            d_in_0_tbu_0   <= d_o_mem_D;
            d_in_1_tbu_0   <= d_o_mem_C;
            
            d_in_0_tbu_1   <= d_o_mem_C;
            d_in_1_tbu_1   <= d_o_mem_B;

            selection_tbu_0<= 1'b0;
            selection_tbu_1<= 1'b1;

         end
         2'b01:
         begin
            d_in_0_tbu_0   <= d_o_mem_D;
            d_in_1_tbu_0   <= d_o_mem_C;
            
            d_in_0_tbu_1   <= d_o_mem_A;
            d_in_1_tbu_1   <= d_o_mem_D;
            
            selection_tbu_0<= 1'b1;
            selection_tbu_1<= 1'b0;
         end
         2'b10:
         begin
            d_in_0_tbu_0   <= d_o_mem_B;
            d_in_1_tbu_0   <= d_o_mem_A;
            
            d_in_0_tbu_1   <= d_o_mem_A;
            d_in_1_tbu_1   <= d_o_mem_D;

            selection_tbu_0<= 1'b0;
            selection_tbu_1<= 1'b1;
         end
         2'b11:
         begin
            d_in_0_tbu_0   <= d_o_mem_B;
            d_in_1_tbu_0   <= d_o_mem_A;
            
            d_in_0_tbu_1   <= d_o_mem_C;
            d_in_1_tbu_1   <= d_o_mem_B;

            selection_tbu_0<= 1'b1;
            selection_tbu_1<= 1'b0;
         end
      endcase
   end

//Trace-Back modules instantiation

   tbu tbu_0
   (
      .clk(clk),
      .rst(rst),
      .enable(enable_tbu_0),
      .selection(selection_tbu_0),
      .d_in_0(d_in_0_tbu_0),
      .d_in_1(d_in_1_tbu_0),
      .d_o(d_o_tbu_0),
      .wr_en(wr_disp_mem_0)
   );

   tbu tbu_1
   (
      .clk(clk),
      .rst(rst),
      .enable(enable_tbu_1),
      .selection(selection_tbu_1),
      .d_in_0(d_in_0_tbu_1),
      .d_in_1(d_in_1_tbu_1),
      .d_o(d_o_tbu_1),
      .wr_en(wr_disp_mem_1)
   );

//Display Memory modules Instantioation

   assign   d_in_disp_mem_0   =  d_o_tbu_0;
   assign   d_in_disp_mem_1   =  d_o_tbu_1;
   

  mem_disp   disp_mem_0
  (
      .clk(clk),
      .wr(wr_disp_mem_0),
      .addr(addr_disp_mem_0),
      .d_i(d_in_disp_mem_0),
      .d_o(d_o_disp_mem_0)
   );

  mem_disp   disp_mem_1
  (
      .clk(clk),
      .wr(wr_disp_mem_1),
      .addr(addr_disp_mem_1),
      .d_i(d_in_disp_mem_1),
      .d_o(d_o_disp_mem_1)
   );

// Display memory module operation
   always @ (posedge clk)
      mem_bank_buf_buf_buf <= mem_bank_buf_buf[0];

   always @ (posedge clk)
   begin
      if(rst==1'b0)
         wr_mem_counter_disp  <= 10'b0000000010;
      if(enable==1'b0)
         wr_mem_counter_disp  <= 10'b0000000010;
      else
         wr_mem_counter_disp  <= wr_mem_counter_disp - 10'd1;   
   end

   always @ (posedge clk)
   begin
      if(rst==1'b0)
         rd_mem_counter_disp  <= 10'b1111111101;
      if(enable==1'b0)
         rd_mem_counter_disp  <= 10'b1111111101;
      else
         rd_mem_counter_disp  <= rd_mem_counter_disp + 10'd1;   
   end

   
   always @ (posedge clk)
   begin
      case(mem_bank_buf_buf_buf)
         1'b0:
         begin
            addr_disp_mem_0   <= rd_mem_counter_disp; 
            addr_disp_mem_1   <= wr_mem_counter_disp;
         end
         1'b1:
         begin
            addr_disp_mem_0   <= wr_mem_counter_disp; 
            addr_disp_mem_1   <= rd_mem_counter_disp; 
         end
      endcase
   end


   always @ (posedge clk)
      mem_bank_buf_buf_buf_buf   <= mem_bank_buf_buf_buf;

   always @ (posedge clk)
      mem_bank_buf_buf_buf_buf_buf <= mem_bank_buf_buf_buf_buf;



   always @ (posedge clk)
   begin
      case(mem_bank_buf_buf_buf_buf_buf)
         1'b0:
         begin
            decoder_o_reg  <= d_o_disp_mem_0;
         end
         1'b1:
         begin
            decoder_o_reg  <= d_o_disp_mem_1;
         end
      endcase
   end

endmodule

You can Find the BMU Code in the Next page or Click Here

 You can Find the ACS Code in the Next page or Click Here

 You can Find the TBU Code in the Next page or Click Here

No comments:

Post a Comment

Blog Views