2013-12-14 51 views
1

当调用vsim命令时,如何让ModelSim自动使用顶级VHDL实体(或多个实体)?我正在编写运行VHDL仿真的通用脚本。如何使用ModelSim自动模拟顶级VHDL实体?

目前我做以下进行编译和仿真:

vcom design.vhd testbench.vhd 
vsim -c -do "onElabError resume; run -all; exit" MY_TB 

我怎样才能让这个自动的ModelSim仿真MY_TB没有明确指定它。

自动使用顶层模块(S)可以使用Verilog:

vlog -writetoplevels my.tops design.v testbench.v 
vsim -c -do "onElabError resume; run -all; exit" -f my.tops 

回答

1

我的方法是在Ruby中创建一个脚本。很容易找到实体/体系结构名称,然后调用Modelsim。该解决方案的要点是:

  1. 打开VHDL文件:
    file_contents = File.read(file_name)

  2. 使用正则表达式来查找实体和架构名称:
    match = file_contents.match(/entity (.*) is/)
    entity = match && match[1]
    match = file_contents.match(/architecture (.*) of/)
    architecture = match && match[1]

  3. 调用的ModelSim在命令行模式下:
    vsim -do {run -all; quit} -lib /temp/work -c entity_name(architecture_name)

以下附上参考我的整个脚本。我认为它的亮点在于:

  • vhdl -m→ “使” 项目通过编译目录中的所有VHDL文件
  • vhdl -f text→找到text在VHDL文件
  • vhdl -s filename→模拟filename

    # vhdl.rb: Swiss army knife for VHDL-related tasks. 
    # vhdl --compile file_name  # Compile file with ModelSim 
    # vhdl --simulate file_name # Simulate file with ModelSim 
    # vhdl --find text    # Find text in VHDL source files 
    # vhdl --make dir    # Compile all files in dir 
    
    require 'optparse' 
    require 'pathname' 
    
    begin 
        gem 'colorize' # gem install colorize 
        require 'colorize' 
    rescue Gem::LoadError 
        puts "Gem 'colorize' is not installed. You can install it by typing:\ngem install colorize" 
    end 
    
    WORK = Pathname.new("/temp/work") 
    
    def ensure_library_work_exists 
        if WORK.exist? 
        puts "Found library work at #{WORK.expand_path}" 
        else 
        puts "Creating library work at #{WORK.expand_path}..." 
        system('mkdir \temp\work') 
        system('vlib /temp/work') 
        end 
    end 
    
    def compile(file_name) 
        ensure_library_work_exists 
        puts "Compiling #{file_name}..." 
        puts cmd_line = "vcom -2008 -work #{WORK} #{file_name}" 
        system(cmd_line) 
    end 
    
    def simulate(file_name) 
        ensure_library_work_exists 
        puts "Simulating #{file_name}..." 
        compile(file_name) 
        entity, architecture = find_entity_architecture(file_name) 
        if entity && architecture 
        cmd_line = "vsim -lib #{WORK} -C#{$entity || entity}(#{$architecture || architecture}) -do \"run -all; quit\"" 
        system(cmd_line) 
        end 
    end 
    
    def find_entity_architecture(file_name) 
        file_contents = File.read(file_name) 
    
        match = file_contents.match(/entity (.*) is/) 
        entity = match && match[1] 
    
        match = file_contents.match(/architecture (.*) of/) 
        architecture = match && match[1] 
    
        [ entity, architecture ] 
    end 
    
    def find_text(text) 
        puts cmd_line = "findstr /sni /C:\"#{text}\" *.vhd *.vhdl" 
        system(cmd_line) 
    end 
    
    $before_context = 1 
    $after_context = 3 
    
    def find_filenames(path) 
        filenames = Dir["#{path}/**/*.vhd"] 
        puts "Found #{filenames.count} VHDL files" 
        filenames 
    end 
    
    def grep_text(text) 
        filenames = find_filenames(".") 
        filenames.each do |filename| 
        output = `grep #{text} #{filename} --recursive --line-number --before-context=#{$before_context} --after-context=#{$after_context}` 
        last_output_was_blank = true 
        if output.empty? 
         print ".".green 
         last_output_was_blank = true 
        else 
         puts() if last_output_was_blank 
         puts filename.green, output 
         last_output_was_blank = false 
        end 
        end 
    end 
    
    def compile_vhdl_file(file_name) 
        vcom_output = `vcom -2008 -work #{WORK} #{file_name}` 
        if vcom_output.match(/\*\* Error/) 
        error_message = vcom_output[/(\*\* Error.*$)/m] 
        raise error_message 
        end 
        puts vcom_output 
    end 
    
    def make(path) 
        ensure_library_work_exists 
        filenames = Dir["#{path}/**/*.vhd"] 
        puts "Found #{filenames.count} VHDL files:" 
        puts filenames.join(" ").green 
    
        pass_number = 0 
        failed_filenames = [] 
        begin 
        pending_files_count = filenames.count - failed_filenames.count 
        puts ">>> Starting pass #{pass_number} -- pending #{pending_files_count}, failed #{failed_filenames.count}".yellow 
        previously_failed_filenames = failed_filenames.dup 
        failed_filenames.clear 
        filenames.each do |filename| 
         begin 
         compile_vhdl_file(filename) 
         rescue 
         puts "#{$!}".red 
         failed_filenames << filename 
         end 
        end 
        pass_number += 1 
        end while failed_filenames.any? and (failed_filenames != previously_failed_filenames) 
    
        if failed_filenames.any? 
        puts "*** Error: Failed to compile:".red 
        puts failed_filenames.join("\n").red 
        exit 
        end 
    end 
    
    OptionParser.new do |o| 
        o.on('-e', '--ent entity_name') { |entity| $entity = entity } 
        o.on('-a', '--arch architecture_name') { |architecture| $architecture = architecture } 
        o.on('-c', '--compile file') { |file| compile(file) } 
        o.on('-s', '--simulate file') { |file| simulate(file) } 
        o.on('-f', '--find text') { |text| find_text(text) } 
        o.on('-b', '--before-context before_context') { |lines_count| $before_context = lines_count } 
        o.on('-t', '--after-context after_context') { |lines_count| $after_context = lines_count } 
        o.on('-g', '--grep text') { |text| grep_text(text) } 
        o.on('-m', '--make [dir]') { |dir| make(dir || '.') } 
        o.parse! 
    end 
    
+0

为一个文件或多个文件提供脚本吗? –

+0

如果您使用'vhdl -s filename.vhd'调用脚本,该脚本会模拟一个文件。它编译目录中的所有文件,如果你用'vhdl -m'调用它的话。海事组织,除非你想运行一组测试平台,否则一次模拟许多文件没什么意义。在这种情况下,我有另一个脚本来模拟所有名称以'_tb.vhd'结尾的VHDL文件。 – rick