首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Icarus Verilog在编译动态内存模块时崩溃

Icarus Verilog在编译动态内存模块时崩溃
EN

Stack Overflow用户
提问于 2016-10-17 21:15:53
回答 1查看 255关注 0票数 1

这是我在StackOverflow上的第一篇文章。

我是Verilog新手,尽管我对Python、C和C++有丰富的经验。我正在Windows 10上使用Icarus版本10.1.1,并试图编写一个动态内存分配器。由于某些原因,在运行此命令时:

代码语言:javascript
复制
iverilog dynmem.v dynmem_test.v -o dynmem_test.out

输出如下:

代码语言:javascript
复制
Assertion failed!

Program: c:\iverilog\lib\ivl\ivl.exe
File: ../verilog-10.1.1/pform.cc, Line 333

Expression: lexical_scope

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

我的代码有什么问题,我应该为此提交一个错误报告吗?

五、

代码语言:javascript
复制
`define WORD_SIZE 32

`ifndef DYNMEM_SIZE // size of dynamic memory in words
  `define DYNMEM_SIZE 16384*8/WORD_SIZE // 16 KB
`endif

`define __DYNMEM_BIT_SIZE WORD_SIZE*DYNMEM_SIZE-1 // size of dynamic memory in bits

reg [__DYNMEM_BIT_SIZE:0] dynmem; // dynamic memory
reg [DYNMEM_SIZE:0] allocated; // bitvector telling which words are allocated
reg mutex = 0;

module dynreg(address,
              ioreg,
              read_en,
              write_en,
              realloc_en);
    output reg [WORD_SIZE-1:0] address;
    output reg [WORD_SIZE-1:0] ioreg;
    output reg read_en; // rising edge: put word stored at location address into ioreg
    output reg write_en; // rising edge: put word stored in ioreg into location address
    output reg realloc_en; // rising edge: if ioreg=0, free memory, otherwise reallocate memory into buffer of size ioreg.

    task malloc; // allocate dynamic memory
        output reg [WORD_SIZE-1:0] size;
        output reg [WORD_SIZE-1:0] start;

        unsigned integer size_int = size; // convert size to integer

        reg flag1 = 1;

        while (mutex) begin end // wait on mutex
        mutex = 1; // acquire mutex

        // loop through possible starting locations
        for (index=size_int-1; (index < DYNMEM_SIZE) && flag1; index=index+1) begin
            // check if unallocated
            reg flag2 = 1;
            for (offset=0; (offset < size_int) && flag2; offset=offset+1)
                 if (allocated[index-offset])
                     flag2 = 0;
            if (flag2) begin // if memory block is free
                start = index;
                flag1 = 0; // exit loop
            end
        end

        // mark as allocated
        for (i=0; i<size; i=i+1)
            allocated[start-offset] = 1;

        mutex = 0; // release mutex
    endtask

    task freealloc;
        output reg [WORD_SIZE-1:0] size;
        output reg [WORD_SIZE-1:0] start;

        while (mutex) begin end // wait on mutex
        mutex = 1; // acquire mutex

        // deallocate locations
        for (index=start; index > 0; index=index-1)
            allocated[index] = 0;

        mutex = 0; // release mutex
    endtask

    // internal registers
    unsigned integer start; // start address
    unsigned integer size; // block size
    unsigned integer address_int; // address register converted to int

    initial begin
        // allocate memory
        size = ioreg;
        malloc(size, start);
    end

    always @(posedge(read_en)) begin
        // read memory into ioreg
        address_int = address;
        ioreg[WORD_SIZE-1:0] = dynmem[8*(start+address_int)-1 -:WORD_SIZE-1];
    end

    always @(posedge(write_en)) begin
        // write memory from ioreg
        address_int = address;
        dynmem[8*(start+address_int)-1 -:WORD_SIZE-1] = ioreg[WORD_SIZE-1:0];
    end

    always @(posedge(realloc_en)) begin
        unsigned integer ioreg_int = ioreg; // convert ioreg to integer
        reg [WORD_SIZE-1:0] new_start; // new start address

        if (ioreg_int != 0) begin // if memory is to be reallocated, not freed
            malloc(ioreg, new_start); // allocated new memory
            // copy memory
            for (i=0; i<size; i=i+1)
                dynmem[8*(new_start+i)-1 -:WORD_SIZE-1] = dynmem[8*(start+i)-1 -:WORD_SIZE-1];
        end

        freealloc(size, start); // free previous memory
        // update registers
        size = ioreg_int;
        start = new_start;
    end
endmodule

dynmem_test.v:

代码语言:javascript
复制
module testmodule();
    $monitor ("%g ioreg1=%b ioreg2=%b",
      $time, ioreg1, ioreg2);
    reg [WORD_SIZE-1:0] address1, address2;
    reg [WORD_SIZE-1:0] ioreg1=5, ioreg2=10;
    reg read_en1, read_en2;
    reg write_en1, write_en2;
    reg realloc_en1, realloc_en2;
 #1 dynreg dr1(address1, ioreg1, read_en1, write_en1, realloc_en1);
 #1 dynreg dr2(address2, ioreg2, read_en2, write_en2, realloc_en2);
    address1 = 0;
    ioreg1 = 23;
 #1 write_en1 = 1;
    write_en1 = 0;
    address1 = 2;
    ioreg1 = 53;
 #1 write_en1 = 1;
    write_en1 = 0;
    address1 = 0;
 #1 read_en1 = 1;
    read_en1 = 0;
    address1 = 2;
 #1 read_en1 = 1;
    read_en1 = 0;
 #1 $finish;    
endmodule

更新: C:\iverilog\lib\verilog-10.1.1不存在,实际上,我在C:\iverilog中搜索pform.cc,没有发现结果。真奇怪。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-18 00:48:00

代码语言:javascript
复制
#1 dynreg dr1(address1, ioreg1, read_en1, write_en1, realloc_en1);

在实例声明中使用延迟(#1)可能会使Icarus感到困惑,就像它使我感到困惑一样。(确切地说,什么东西会被延迟?实例是否不存在于一个模拟步骤?)

删除这些延迟,并将这两个实例声明之后的所有代码放到一个initial块中。

无论它的价值是什么,dynreg可能无法像所写的那样进行综合。它没有时钟输入,它包含几个不能在硬件中展开的循环。

更新: C:\iverilog\lib\verilog-10.1.1不存在,实际上,我在C:\iverilog中搜索pform.cc,没有发现结果。真奇怪。

这个路径可能是指在开发人员的计算机上编译Icarus副本的代码的位置。除非您计划自己修复导致此崩溃的错误,否则您可以安全地忽略这一点。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40095779

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档