Как да заключим блок RAM във Verilog

Имам един много специфичен проблем с проект, който ме преследва от дни. Имам следния Verilog код за RAM модул:

module RAM_param(clk, addr, read_write, clear, data_in, data_out);
    parameter n = 4;
    parameter w = 8;

    input clk, read_write, clear;
    input [n-1:0] addr;
    input [w-1:0] data_in;
    output reg [w-1:0] data_out;

    reg [w-1:0] reg_array [2**n-1:0];

    integer i;
    initial begin
        for( i = 0; i < 2**n; i = i + 1 ) begin
            reg_array[i] <= 0;
        end
    end

    always @(negedge(clk)) begin
        if( read_write == 1 )
            reg_array[addr] <= data_in;
        if( clear == 1 ) begin
            for( i = 0; i < 2**n; i = i + 1 ) begin
                reg_array[i] <= 0;
            end
        end
        data_out = reg_array[addr];
    end
endmodule

Държи се точно както се очаква, но когато отида да синтезирам, получавам следното:

Synthesizing Unit <RAM_param_1>.
    Related source file is "C:\Users\stevendesu\---\RAM_param.v".
        n = 11
        w = 16
    Found 32768-bit register for signal <n2059[32767:0]>.
    Found 16-bit 2048-to-1 multiplexer for signal <data_out> created at line 19.
    Summary:
    inferred 32768 D-type flip-flop(s).
    inferred 2049 Multiplexer(s).
Unit <RAM_param_1> synthesized.

32768 джапанки! Защо просто не изведе блок RAM? Този RAM модул е ​​толкова огромен (и имам два от тях - един за памет за инструкции, един за памет за данни), че консумира цялата налична площ на FPGA... пъти 2,4

Опитвах всичко, за да го принудя да изведе блокова RAM вместо 33k джапанки, но освен ако не успея да го разбера скоро, може да се наложи значително да намаля размера на паметта си, само за да се побере в чип.


person stevendesu    schedule 18.12.2013    source източник
comment
Прегледахте ли таблиците с данни за вашия FPGA, за да видите какви овни предлага? Вероятно има и бележки за приложението за извеждане на овни от вашия доставчик на FPGA. На върха на главата си мисля, че повечето ram вероятно нямат "ясна" функционалност, която изтрива цялата ram, така че може би можете да опитате да премахнете това.   -  person Tim    schedule 18.12.2013
comment
Синтезаторът не може да изведе структура, която физически не съществува на вашия FPGA, а различните FPGA имат различни RAM. Това не е проблем на Verilog, трябва да прочетете ръководствата за вашия FPGA.   -  person    schedule 18.12.2013
comment
Съжалявам, че актуализирам нов отговор, това е BRAM, а не разпределена RAM. Наистина съжалявам за това.   -  person Khanh N. Dang    schedule 20.12.2013


Отговори (1)


Просто премахнах нещо от вашия код, резултатът е като този:

 module RAM_param(clk, addr, read_write, clear, data_in, data_out);
parameter n = 4;
parameter w = 8;

input clk, read_write, clear;
input [n-1:0] addr;
input [w-1:0] data_in;
output reg [w-1:0] data_out;

// Start module here!
reg [w-1:0] reg_array [2**n-1:0];

integer i;
initial begin
    for( i = 0; i < 2**n; i = i + 1 ) begin
        reg_array[i] <= 0;
    end
end

always @(negedge(clk)) begin
    if( read_write == 1 )
        reg_array[addr] <= data_in;
    //if( clear == 1 ) begin
        //for( i = 0; i < 2**n; i = i + 1 ) begin
            //reg_array[i] <= 0;
        //end
    //end
    data_out = reg_array[addr];
end
endmodule  

Инициирането на всички нули може да не се нуждае от код, ако искате да инициирате, просто го направете:

initial
begin
    $readmemb("data.dat", mem);
end

Тогава резултатът, който получих от ISE 13.1

Synthesizing (advanced) Unit <RAM_param>.
INFO:Xst:3231 - The small RAM <Mram_reg_array> will be implemented on LUTs in order to maximize performance and save block RAM resources. If you want to force its implementation on block, use option/constraint ram_style.

    -----------------------------------------------------------------------
    | ram_type           | Distributed                         |          |
    -----------------------------------------------------------------------
    | Port A                                                              |
    |     aspect ratio   | 16-word x 8-bit                     |          |
    |     clkA           | connected to signal <clk>           | fall     |
    |     weA            | connected to signal <read_write>    | high     |
    |     addrA          | connected to signal <addr>          |          |
    |     diA            | connected to signal <data_in>       |          |
    |     doA            | connected to internal node          |         

Актуализирайте тук!: Силно благодаря на mcleod_ideafix Съжалявам, че забравих въпроса си: това е блокова RAM, а не разпределена. За блок RAM, трябва да го принудите: Синтез - XST -> Свойства на процеса -> HDL опция -> RAM стил -> Промяна от автоматично на Блокиране. Резултатът ще бъде следният:

Synthesizing (advanced) Unit <RAM_param>.
INFO:Xst:3226 - The RAM <Mram_reg_array> will be implemented as a BLOCK RAM, absorbing the following register(s): <data_out>
    -----------------------------------------------------------------------
    | ram_type           | Block                               |          |
    -----------------------------------------------------------------------
    | Port A                                                              |
    |     aspect ratio   | 16-word x 8-bit                     |          |
    |     mode           | read-first                          |          |
    |     clkA           | connected to signal <clk>           | fall     |
    |     weA            | connected to signal <read_write>    | high     |
    |     addrA          | connected to signal <addr>          |          |
    |     diA            | connected to signal <data_in>       |          |
    |     doA            | connected to signal <data_out>      |          |
    -----------------------------------------------------------------------
    | optimization       | speed                               |          |
    -----------------------------------------------------------------------
Unit <RAM_param> synthesized (advanced).

Край на актуализацията

Препоръчвам ви да прочетете ръководството за потребителя на xst за примерен код на RAM и листа с данни на устройството. Например, в някои FPGA LUT RAM: сигналът за нулиране не е валиден. Ако сте се опитали да го нулирате, логическият модул за нулиране трябва да бъде интегриран. Води до D-FF вместо RAM. Сигналът за нулиране ще се присвои автоматично за нулиране на системата.

В случай на Block RAM (не LUT RAM), предпочитам конкретна дълбочина/ширина на данни или генериране на ядро ​​или го извиквам директно от библиотеката. Повече изходен код за обща употреба (ASIC/FPGA) можете да намерите тук: http://asic-world.com/examples/verilog/ram_dp_sr_sw.html

person Khanh N. Dang    schedule 18.12.2013
comment
Просто исках да отбележа, че сте заменили нулирането на хардуера с натоварване на RAM по време на изпълнение. Мисля, че това е точно правилното нещо, тъй като общата RAM обикновено няма да позволи асинхронно нулиране на всички клетки и initial блоковете обикновено не могат да се синтезират. - person ; 18.12.2013
comment
Това оправи всичко! Ясният бит всъщност беше нещо в примерния код на нашия професор. Ще трябва да го уведомя, че счупи всичко. - person stevendesu; 18.12.2013
comment
Ако има ясно, то обикновено се изпълнява като if (clear==1'b1) begin ... end else if (read_write==1'b1) begin ... end else begin ... end. Освен това negedge(clk) обикновено се записва като negedge clk - person Greg; 18.12.2013
comment
@JoeHass: Знам, че инициалът не може да се синтезира, но инициалът с нула не е нещо повече в дизайна на RAM, а само за ROM init. Просто искам да го направя по-кратък :D. Опитвам се да направя нулиране, но не беше синтезирано като RAM (само масив от FF). Доколкото разбирам, RAM използва нулиране на системата, а не дефинирано от потребителя, защото не е необходимо да изчистваме RAM по време на изпълнение. Ако системата направи това, ще го определя като регистри. - person Khanh N. Dang; 19.12.2013
comment
Вашият резултат от ISE показва, че е използвана разпределена RAM, а не блокова RAM! - person mcleod_ideafix; 20.12.2013
comment
@mcleod_ideafix: Благодаря ви за коментара, наистина го забравих. Сега актуализирах отговора си!. - person Khanh N. Dang; 20.12.2013