【问题标题】:Way to initialize synthesizable 2D array with constant values in Verilog在 Verilog 中用常量值初始化可合成二维数组的方法
【发布时间】:2012-12-17 07:12:11
【问题描述】:

在 VHDL 中,我可以轻松做到这一点:

constant    cmdbytes       : bytearray(0 to Total) := (x"05", x"00", x...};

我想要可综合的常量,这样当 FPGA 启动时,这个数组就有我提供的数据。这些寄存器连接到 VCC 或接地以表示 1 或 0。然后我可以使用它们来生成波形。我也想有 2D 字节数组,它在 verilog 世界中是 3D。

【问题讨论】:

    标签: arrays initialization constants vhdl verilog


    【解决方案1】:

    如果您只是使用数组一次提取一个值,那么使用case 语句怎么样?当然,这是一种冗长的方法,但您始终可以编写一个脚本来为您编写 RTL。

    reg [7:0] value;
    reg [7:0] i;
    
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n)
            i <= 8'd0;
        else
            i <= i + 1;
    end
    
    always @(*) begin
        case(i) 
            8'h00: value = 8'd0;
            8'h01: value = 8'd34;
            ...
        endcase
    endcase
    

    另一种方法是使用initial 语句。据我所知,FPGA 综合工具将允许您以下列方式设置数组的初始值。同样,编写这个的脚本可能是要走的路。

    reg [0:35][7:0] my_array;
    
    initial begin
        my_array[0] = 8'd45;
        my_array[1] = 8'd26;
        ...
    end
    

    如果您的 FGPA 综合工具支持某些 SystemVerilog,您将能够像这样初始化数组:

    reg [0:34][7:0] my_array = '{ 8'd90, 8'd34, ... }; // note the '{
    

    【讨论】:

      【解决方案2】:
      module test (
      
         input [7:0]   p1_sa,            // i
         input [7:0]   p1_sb,            // i
         output [7:0]   p3,            // o
         output [7:0]   p3b            // o
      );
      
      logic [7:0] array2d [7:0] = {99,124,119,123,242,107,111,197};
      
         assign p3    = array2d[p1_sa];
         assign p3b   = array2d[p1_sb];
      
      endmodule
      

      我尝试了上面的系统verilog代码,它在modelsim和Vivado中运行良好。

      【讨论】:

        【解决方案3】:

        case 语句方法的替代方法是使用 function 来访问值。

        包含 8 位常量的大小为 4 的“数组”示例:

        function [7:0] cmdbytes;
                input    [1:0] index;
                reg      [7:0] t[0:3];
            begin
                {   
                     t[0],t[1],t[2],t[3]
                } = {   
                     8'h05, 8'h00, 8'h5b, 8'h45
                };
        
                cmdbytes = t[index];
            end
        endfunction
        

        可以像这样访问常量:

        wire [7:0] value0;
        wire [7:0] value1;
        wire [7:0] value2;
        wire [7:0] value3;
        
        assign value0 = cmdbytes(2'd0);
        assign value1 = cmdbytes(2'd1);
        assign value2 = cmdbytes(2'd2);
        assign value3 = cmdbytes(2'd3);
        

        【讨论】:

          【解决方案4】:

          Verilog 2005 不允许数组初始化。虽然您的 FPGA 供应商应该有办法生成 ROM。

          【讨论】:

            猜你喜欢
            • 2021-10-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-11-29
            相关资源
            最近更新 更多