Delay a 32-bit signal with N clock cycle in verilog

464 Views Asked by At

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
1

There are 1 best solutions below

1
Serge On BEST ANSWER

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