Memory elements of a RamNet

From Verific Design Automation FAQ
Revision as of 17:06, 22 January 2020 by Hoa (Talk | contribs) (Created page with "In Verific Netlist Database, a RamNet is created for every identifier in the parsetree that is inferred as multi-port memory. This example checks what memory elements are con...")

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

In Verific Netlist Database, a RamNet is created for every identifier in the parsetree that is inferred as multi-port memory.

This example checks what memory elements are connected to the RamNets.

C++:

#include "veri_file.h"
#include "Netlist.h"
#include "Net.h"
#include "Instance.h"
#include "PortRef.h"
#include "Set.h"

#ifdef VERIFIC_NAMESPACE
using namespace Verific ;
#endif

void AnalyzeMultiPortRAM(Netlist* top)
{
    // Traverse all the multiport memory nets of the netlist to check the portrefs.
    Net *net ;
    MapIter mi ;
    FOREACH_NET_OF_NETLIST(top, mi, net) {
        // Only interested in RamNet
        if (!net || !net->IsRamNet()) continue ;

        unsigned hasReadPort = 0 ;
        unsigned hasWritePort = 0 ;
        unsigned hasClockedWritePort = 0;

        // Traverse all the portrefs of the net to check if the portref is connected to any ram ports.
        SetIter si ;
        PortRef *pr ;
        FOREACH_PORTREF_OF_NET(net,si, pr) {
            Instance *inst = pr ? pr->GetInst() : 0 ;
            if (!inst) continue ;

            if (inst->Type() == OPER_READ_PORT) {
                // This net is connected to a memory read port
                hasReadPort = 1 ;
            }
            if (inst->Type() == OPER_WRITE_PORT) {
                // This net is connected to a memory write port
                hasWritePort = 1;
            }
            if (inst->Type() == OPER_CLOCKED_WRITE_PORT) {
                // This net is connected to a memory clocked write port
                hasClockedWritePort = 1;
            }
        }

        if (hasReadPort) Message::Msg(VERIFIC_INFO, 0, 0, "RamNet '%s' has read port", net->Name()) ;
        if (hasWritePort) Message::Msg(VERIFIC_INFO, 0, 0, "RamNet '%s' has write port", net->Name()) ;
        if (hasClockedWritePort) Message::Msg(VERIFIC_INFO, 0, 0, "RamNet '%s' has clocked write port", net->Name()) ;
    }
}

int main (int argc, char **argv)
{
    RuntimeFlags::SetVar("veri_extract_dualport_rams", 0) ;
    RuntimeFlags::SetVar("veri_extract_multiport_rams", 1) ;

    // Now analyze the Verilog file (into the work library). In case of any error do not process further.
    if (!veri_file::Analyze("test.sv", veri_file::SYSTEM_VERILOG)) return 1 ;

    // RTL elaborate the module.
    if (!veri_file::Elaborate("test", "work")) return 1 ;

    // Get the top netlist
    Netlist *top = Netlist::PresentDesign() ;

    if (!top) {
        Message::Msg(VERIFIC_ERROR, 0, 0, "an error occurred with this example") ;
        return 1 ;
    }

    AnalyzeMultiPortRAM(top) ;

    return 0 ;
}
 

test.sv:

module test (input clk, write, input [6:0]addr, input [7:0]in, output reg [7:0]out, output reg [7:0]out1) ;
    reg [7:0]RAM[127:0] ;
    reg [7:0]RAM1[127:0] ;
    reg [7:0]RAM2[127:0] ;

    always @(posedge clk) begin
        if (write) begin
            RAM[addr] = in ;
            RAM1[addr] = in ;
        end
        out = RAM[addr] ;
        out1 = RAM2[addr] ;
    end
endmodule
 

Run:

$ test-linux 
-- Analyzing Verilog file 'test.sv' (VERI-1482)
test.sv(1): INFO: compiling module 'test' (VERI-1018)
test.sv(4): WARNING: net 'RAM2' does not have a driver (VDB-1002)
INFO: RamNet 'RAM' has read port
INFO: RamNet 'RAM' has clocked write port
INFO: RamNet 'RAM1' has clocked write port
INFO: RamNet 'RAM2' has read port
$