0

I am trying to delay a 32-bit signal using shift register. My logic is a single flip flop delay a signal by 1 clk so I use shift register as it is combination of flip flop can someone guide me what is wrong with this code.

module delay_n_cycles (
  input wire [31:0] data_in,
  input wire clk,
  output reg [31:0] data_out,
  parameter N = 5
);

reg [31:0] shift_reg;

always @(posedge clk) begin
  shift_reg <= {shift_reg[30:0], data_in};
  if (N == 0) begin
    data_out <= shift_reg[31];
 end else begin
    data_out <= shift_reg[N-1];
  end
end

endmodule
hope_99
  • 27
  • 5

1 Answers1

0

First of all, your code is syntactically wrong. parameter cannot be declared in a way you provided.

Your shift register is only 32 bit wide. Usually, to delay multi-bit data this way, you need to keep N copies of data in the register, shift them at one end and read at the other. I guess the following should help:

module delay_n_cycles #(parameter N = 5)(
  input wire [31:0] data_in,
  input wire clk,
  output reg [31:0] data_out
);

  reg [N-1:0][31:0] shift_reg;

always @(posedge clk) begin
  shift_reg <= (shift_reg << 32) | data_in;
  data_out <= shift_reg[N-1];
end
endmodule

This code will work with system verilog because it used packed multi-dimensional arrays.

You need to shift the reg by 32 (width of the data) in packed version.

Here is an example of a testbench:

module tb();
  bit clk;
  int clkCount;
  initial 
    forever begin 
      #5 clk = ~clk;
      clkCount++;
    end
  
  logic [31:0] data_in, data_out;
  
  initial begin
    $monitor("%0t (%0d) [%h]: %0d --> %0d", $time, clkCount, ds.shift_reg[4], data_in, ds.data_out);
    
    for(int i = 0; i < 20; i++) begin
      #10 data_in = i;
    end
    $finish;
  end
  
  delay_n_cycles ds(data_in, clk, data_out);
endmodule
Serge
  • 11,616
  • 3
  • 18
  • 28
  • shift_reg is 160 bit wide, containt 5 x 32-bit data chunks. Every clock tick it get shifted by 32 bit, shifting old 4 chunks and putting 0 in the lowest 32 bits. In this case binary '|' maps data_in into those zeroed lowest bits. It is identical to say 'shift_reg[0] = data_in' in a separate statement: `shift_reg <= shift_reg<<32; shift_reg[0]<=data_in;` – Serge Dec 22 '22 at 21:00