如何使用ModelSim自动模拟顶级VHDL实体?

时间:2013-12-14 23:32:52

标签: vhdl modelsim

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

目前我正在进行以下编译和模拟:

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

如何制作它以便ModelSim自动模拟MY_TB而不明确指定它。

使用Verilog:

可以自动使用顶级模块
vlog -writetoplevels my.tops design.v testbench.v
vsim -c -do "onElabError resume; run -all; exit" -f my.tops

1 个答案:

答案 0 :(得分: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)
  4. 我已将我的整个脚本包含在下面以供参考。我认为它的亮点是:

    • vhdl -m→通过编译目录中的所有VHDL文件来“制作”项目
    • vhdl -f text→在VHDL文件中找到text
    • 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