Verilog – How to Implement a Linear Feedback Shift Register Using For Loops

digital-logicfpgaverilog

I tried implementing LFSR using Verilog , but I am unable to get the output properly, please check the verilog code for both module and test bench below:-

    //LFSR.v
    `timescale 1ns / 1ps
module AUTO_LFSR #(parameter Length=8, initial_state=8'b1000_0001, parameter[1:Length]tp_coeff=8'b1111_0011)
( 
input clk,rst,
output reg [1:Length]Y
);
integer cell_ptr;

always @(posedge clk)

if(rst==1'b1)
Y<=initial_state;
else
    begin

        for(cell_ptr=2;cell_ptr<=Length;cell_ptr=cell_ptr+1)
            begin
                if(tp_coeff[cell_ptr+1]==1)
                    Y[cell_ptr]=Y[cell_ptr-1]^Y[Length];
                else

                    Y[cell_ptr]<=Y[cell_ptr-1];
                    Y[1]<=Y[Length];

            end
    end

endmodule


//LFSR_tb.v
`timescale 1ns / 1ps
`include"LFSR.v"
module LFSR_tb();
parameter Length=8;
parameter initial_state=8'b1000_0001;
parameter[1:Length]tp_coeff=8'b1111_0011;
reg clk,rst;
wire [1:Length]Y;
AUTO_LFSR dut(.clk(clk),.rst(rst),.Y(Y));

initial
begin
    clk=0;
    rst=1;
end

always
#1 clk=~clk;
initial
begin

rst=0;
#100 $monitor("This is the cllk %b %b %b",tp_coeff,Y,clk);
#200 $finish;

end
endmodule

This is my output:
output

I implemented it exactly how it was mentioned in Ciletti book:M . D. Ciletti Advanced Digital Design

Best Answer

The following code simulates just fine in iverilog:

/* lfsr.v */

`timescale 1ns / 1ps

module AUTO_LFSR #(
  parameter Length=8,
            initial_state = 8'b1000_0001,
  parameter[1:Length]tp_coeff=8'b1111_0011
) ( 
  input clk, rst,
  output reg [1:Length] Y
);

  integer cell_ptr;

  always @(posedge clk)
    if (rst==1'b1)
      Y <= initial_state;
    else begin
      for (cell_ptr = 2; cell_ptr <= Length; cell_ptr = cell_ptr + 1) begin
        if (tp_coeff[cell_ptr+1]==1)
          Y[cell_ptr] = Y[cell_ptr-1] ^ Y[Length];
        else 
          Y[cell_ptr] <= Y[cell_ptr-1];
        Y[1] <= Y[Length];
      end
    end
endmodule

//LFSR_tb.v
`timescale 1ns / 1ps
//`include"LFSR.v"
module LFSR_tb();
  parameter Length=8;
  parameter initial_state=8'b1000_0001;
  parameter[1:Length]tp_coeff=8'b1111_0011;

  reg clk,rst;
  wire [1:Length]Y;

  AUTO_LFSR dut(
    .clk        (clk),
    .rst        (rst),
    .Y          (Y)
  );

  /* Generate periodic clock
   */
  initial clk=0;
  always #1 clk=~clk;

  /* Assert reset for several clock cycles
   */
  initial begin
    rst=1;
     #10 rst=0;
    #100 $monitor("This is the cllk %b %b %b", tp_coeff, Y, clk);
    #200 $finish;
  end
endmodule