【问题标题】:How do you write a parameterized delay register?如何编写参数化延迟寄存器?
【发布时间】:2021-10-04 20:35:04
【问题描述】:

我正在尝试编写具有宽度和延迟参数(用于同步/CDC 目的的延迟)的通用 Verilog 锁存器模块。起初我想根据延迟参数生成一些延迟寄存器,但我决定只使用一个移位寄存器,根据延迟来调整大小,因为我相信它更干净。代码如下:

module latch # (
    parameter WIDTH = 32,
    parameter DELAY = 0
  )
  (
    input                  clk,
    input                  resetn,
    input [WIDTH-1:0]      din,
    output reg [WIDTH-1:0] dout
  );

  reg [(WIDTH*(DELAY))-1:0] dly;

  always @ (posedge clk)
  begin
    if (!resetn)
    begin
      dly  <= 0;
      dout <= 0;
    end
    else
    begin
      if (DELAY == 0)
      begin
        dout <= din;
      end
      else
      begin
        dly  <= {dly[(WIDTH*(DELAY-1))-1:0], din};
        dout <= dly[(WIDTH*(DELAY))-1 -: WIDTH];
      end
    end
  end

endmodule

xvlog 对此没有任何问题,即使使用DELAY = 0 实例化也是如此。但是,Vivado 综合返回:

ERROR: [Synth 8-524] part-select [-1:0] out of range of prefix 'dly'

当这个模块用DELAY = 0 实例化时。你将如何解决这个问题?我想我可以通过定义一个最大宏并将寄存器的顶部索引设置为max(0, (WIDTH*(DELAY-1))-1) 来逃避,但当然这会被拒绝为可变宽度寄存器。是否可以根据参数有条件地声明寄存器?

【问题讨论】:

    标签: verilog hdl vivado synthesis


    【解决方案1】:

    您可以尝试使用generate if 语句来有条件地声明寄存器:

    module latch # (
        parameter WIDTH = 32,
        parameter DELAY = 0
      )
      (
        input                  clk,
        input                  resetn,
        input [WIDTH-1:0]      din,
        output reg [WIDTH-1:0] dout
      );
    
      if (DELAY == 0)
      begin
    
        always @ (posedge clk)
        begin
          if (!resetn)
          begin
            dout <= 0;
          end
          else
          begin
            dout <= din;
          end
        end
    
      end
      else if (DELAY == 1)
      begin
    
        reg [WIDTH-1:0] dly;
    
        always @ (posedge clk)
        begin
          if (!resetn)
          begin
            dly  <= 0;
            dout <= 0;
          end
          else
          begin
            dly  <= din;
            dout <= dly;
          end
        end
    
      end
      else
      begin
    
        reg [(WIDTH*(DELAY))-1:0] dly;
    
        always @ (posedge clk)
        begin
          if (!resetn)
          begin
            dly  <= 0;
            dout <= 0;
          end
          else
          begin
            dly  <= {dly[(WIDTH*(DELAY-1))-1:0], din};
            dout <= dly[(WIDTH*DELAY)-1 -: WIDTH];
          end
        end
      end
    
    endmodule
    

    generate 关键字是可选的。请参阅 IEEE Std 1800-2017,第 27 节。生成构造

    【讨论】:

      【解决方案2】:

      是的,您可以使用 generate if 构造有条件地声明寄存器。

      module latch # (
          parameter WIDTH = 32,
          parameter DELAY = 0
        )
        (
          input                  clk,
          input                  resetn,
          input [WIDTH-1:0]      din,
          output reg [WIDTH-1:0] dout
        );
      
      if (DELAY==0) begin
         dout <= din;
      end else begin 
        reg [(WIDTH*(DELAY))-1:0] dly;
      
        always @ (posedge clk)
        begin
          if (!resetn)
          begin
            dly  <= 0;
            dout <= 0;
          end
          else
          begin
            if (DELAY == 0)
            begin
              dout <= din;
            end
            else
            begin
              dly  <= {dly[(WIDTH*(DELAY-1))-1:0], din};
              dout <= dly[(WIDTH*(DELAY))-1 -: WIDTH];
            end
          end
        end
      end
      
      endmodule
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-26
        • 2017-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多