Module: Rvvm

Defined in:
lib/rvvm.rb,
lib/rvvm/version.rb

Overview

Module holding current rvvm version.

Defined Under Namespace

Classes: Error

Constant Summary collapse

VERSION =

Current rvvm module version.

"1.2.2"

Class Method Summary collapse

Class Method Details

.check_argsvoid

This method returns an undefined value.

Simple argument check.

Since:

  • 0.8.0



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/rvvm.rb', line 123

def self.check_args
  if @args[:all]
    @args[:comp] = 1
    @args[:elab] = 1
    @args[:run] = 1
  end

  # Check if a required arg is provided
  return unless Utils.all_nil?(@args, @required_args)

  puts ""
  Crayons.log_error("No required options provided!")
  puts "For more info use -h or --help\n\n"
  exit(1)
end

.compilevoid

This method returns an undefined value.

Compiles project SystemVerilog sources using xvlog.

Since:

  • 0.8.0



319
320
321
322
323
324
325
326
# File 'lib/rvvm.rb', line 319

def self.compile
  cmd_args = @config[:compilation][:args].strip
  logname = @args[:complog] || File.join([@config[:project][:logDir], @config[:compilation][:logDir], @config[:compilation][:log]])
  complist = @args[:compilelist] || @config[:compilation][:list]

  cmd = "xvlog -sv -f #{complist} -log #{logname} #{cmd_args}"
  execute("Compiling HDL sources...", cmd)
end

.cov_reportvoid

This method returns an undefined value.

Opens last generated functional coverage report in a HTML dashboard.

Since:

  • 0.9.0



443
444
445
446
447
448
# File 'lib/rvvm.rb', line 443

def self.cov_report
  Dir.chdir("xcrg_func_cov_report")
  execute("Opening coverage dashboard...", "./dashboard.html")

  exit(0)
end

.coveragevoid

This method returns an undefined value.

Generates UVM test functional coverage report using xcrg.

Since:

  • 0.9.0



433
434
435
436
# File 'lib/rvvm.rb', line 433

def self.coverage
  cmd = "xcrg -report_format html -dir xsim.covdb"
  execute("Generating UVM test functional coverage report...", cmd)
end

.create_module(name, type) ⇒ void

This method returns an undefined value.

Generates a SystemVerilog module/interface template.

Parameters:

  • type (String)

    specifies modudle/itf

  • name (String)

    specifies module/itf name

Since:

  • 0.9.0



458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
# File 'lib/rvvm.rb', line 458

def self.create_module(name, type)
  conf = @templates[:module][:conf]
  conf[:module] = name
  conf[:date] = @formatted_time
  unless @args[:here]
    conf[:prjname] = @config[:project][:name]
    conf[:company] = @config[:project][:company]
  end

  conf[:type] = type
  @templates[:module][:file][:path] = "design/itf" if type == "itf"

  if @args[:here]
    path = "."
  else
    path = File.join([@config[:project][:path], @args[:path] || @templates[:module][:file][:path]])
  end
  conf[:username] = Utils.git_userame || " "

  Crayons.spinner_start("Generating SV #{type} template...")
  Utils.gen_template(@templates[:module], "#{name}.sv", conf, path)
  Crayons.spinner_stop(nil, true)
  puts ""

  exit(0)
end

.create_new_project(name) ⇒ void

This method returns an undefined value.

Creates a new RVvM project template in pwd with a given name.

Parameters:

  • name (String)

    project name

Since:

  • 0.8.0



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/rvvm.rb', line 189

def self.create_new_project(name)
  if File.exist?(name)
    print "\nDirectory #{name} already exists. Do you want to overwrite it? [y/n] "
    input = gets.chomp
    puts ""

    exit(0) unless input == "y"
    FileUtils.rm_rf(name)
  else
    puts ""
  end

  Crayons.spinner_start("Generating new project: #{name}...")

  FileUtils.mkdir(name)
  Dir.chdir(name)

  FileUtils.mkdir("rvvm")
  FileUtils.chdir("rvvm")
  FileUtils.mkdir("logs")
  Dir.chdir("logs")
  FileUtils.mkdir("comp")
  FileUtils.mkdir("elab")
  FileUtils.mkdir("sim")
  FileUtils.mkdir("dpi")
  Dir.chdir("../..")

  temp_conf = @templates[:rvvmconf][:conf]
  temp_conf[:prjname] = name
  temp_conf[:prjpath] = Dir.pwd
  Utils.gen_template(@templates[:rvvmconf], nil, temp_conf)

  temp_conf = @templates[:compilelist][:conf]
  temp_conf[:prjname] = name
  Utils.gen_template(@templates[:compilelist], "#{name}_compile_list.f", temp_conf)

  Utils.gen_template(@templates[:wfcfg])
  Utils.gen_template(@templates[:dpilist])

  FileUtils.mkdir("design")
  Dir.chdir("design")
  FileUtils.mkdir("pkg")
  FileUtils.mkdir("itf")
  FileUtils.mkdir("src")
  Dir.chdir("..")

  FileUtils.mkdir("verif")
  Dir.chdir("verif")
  FileUtils.mkdir("env")
  FileUtils.mkdir("env/agents")
  FileUtils.mkdir("env/top")
  FileUtils.mkdir("tb")
  FileUtils.mkdir("tb/src")
  FileUtils.mkdir("test")
  FileUtils.mkdir("test/seq")
  FileUtils.mkdir("test/src")
  Dir.chdir("..")

  temp_conf = @templates[:tbtop][:conf]
  temp_conf[:prjname] = name
  temp_conf[:PRJNAME] = name.upcase
  Utils.gen_template(@templates[:tbtop], "#{name}_tb_top.sv", temp_conf)

  Crayons.spinner_log(" ")
  Crayons.spinner_pause
  system("git init")
  system("git add .")
  system('git commit -am "Initial commit"')
  Crayons.spinner_resume

  Crayons.spinner_log("")
  Crayons.spinner_stop("Done!", true)
  Crayons.log_pass("\nRVvM: New project generated. ^^\n\n")

  exit(0)
rescue StandardError => e
  Crayons.spinner_stop("Error!", false) if Crayons.spinner_running?
  Crayons.log_error("RVvM failed to create project...\n\n#{e.message}\n")
  exit(1)
end

.create_pkg(name) ⇒ void

This method returns an undefined value.

Generates a SystemVerilog package template.

Parameters:

  • name (String)

    specifies package name

Since:

  • 0.9.0



492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
# File 'lib/rvvm.rb', line 492

def self.create_pkg(name)
  conf = @templates[:package][:conf]
  conf[:package] = name
  conf[:PACKAGE] = name.upcase
  conf[:date] = @formatted_time
  unless @args[:here]
    conf[:prjname] = @config[:project][:name]
    conf[:company] = @config[:project][:company]
  end
  conf[:username] = Utils.git_userame || " "

  if @args[:here]
    path = "."
  else
    path = File.join([@config[:project][:path], @args[:path] || @templates[:package][:file][:path]])
  end

  Crayons.spinner_start("Generating SV pkg template...")
  Utils.gen_template(@templates[:package], "#{name}.sv", conf, path)
  Crayons.spinner_stop(nil, true)
  puts ""

  exit(0)
end

.create_svfile(name) ⇒ void

This method returns an undefined value.

Generates a generic SystemVerilog template file.

Parameters:

  • name (String)

    specifies template name

Since:

  • 0.9.0



524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
# File 'lib/rvvm.rb', line 524

def self.create_svfile(name)
  conf = @templates[:svfile][:conf]
  conf[:NAME] = name.upcase
  conf[:date] = @formatted_time
  unless @args[:here]
    conf[:prjname] = @config[:project][:name] || " "
    conf[:company] = @config[:project][:company] || " "
  end
  conf[:username] = Utils.git_userame || ""

  if @args[:here]
    path = "."
  else
    path = File.join([@config[:project][:path], @args[:path] || @templates[:module][:file][:path]])
  end

  Crayons.spinner_start("Generating generic SV file template...")
  Utils.gen_template(@templates[:svfile], "#{name}.sv", conf, path)
  Crayons.spinner_stop(nil, true)
  puts ""

  exit(0)
end

.dpi_cvoid

This method returns an undefined value.

Compiles C/C++ sources into a shared library to use during elaboration and simulation using DPI-C.

Since:

  • 0.9.0



334
335
336
337
338
339
340
# File 'lib/rvvm.rb', line 334

def self.dpi_c
  cmd_args = @config[:dpi][:args].strip
  dpilist = @args[:dpilist] || @config[:dpi][:list]

  cmd = "xsc -f #{dpilist} #{cmd_args}"
  execute("Building DPI-C library...", cmd)
end

.elaboratevoid

This method returns an undefined value.

Elaborates project into a testbench snapshot using xelab.

Since:

  • 0.8.0



347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
# File 'lib/rvvm.rb', line 347

def self.elaborate
  cmd_args = @config[:elaboration][:args]
  cmd_args << " -sv_lib #{@config[:elaboration][:customdpilib]}" if @config[:elaboration][:customdpilib] != ""
  unless @config[:elaboration][:customdpilib] != ""
    cmd_args << " -sv_lib dpi" if @args[:dpi] || @args[:dpilib] || @config[:dpi][:dpilib] == 1
  end
  cmd_args << " -debug wave" if @args[:wave]
  cmd_args.strip!
  logname = @args[:elablog] || File.join([@config[:project][:logDir], @config[:elaboration][:logDir], @config[:elaboration][:log]])
  tb_top = @args[:tbtop] || @config[:elaboration][:tbTop]
  tb = @args[:tb] || @config[:elaboration][:tb]
  timescale = @args[:timescale] || @config[:elaboration][:timescale]

  cmd = "xelab #{tb_top} -relax -s #{tb} -timescale #{timescale} -log #{logname} #{cmd_args}"
  execute("Elaborating testbench #{tb}...", cmd)
end

.execute(tag, command) ⇒ void

This method returns an undefined value.

Shell command with debug printout.

If --debug arg provided instead of calling system prints the input command.

Parameters:

  • command (String)

    command to be called/printed

Since:

  • 0.8.0



171
172
173
174
175
176
177
178
179
180
# File 'lib/rvvm.rb', line 171

def self.execute(tag, command)
  if @args[:debug]
    Crayons.spinner_start(tag)
    sleep(1)
    Crayons.spinner_log(command)
    Crayons.spinner_stop(nil, true)
  else
    Crayons.command(tag, command, ignore_errors: @args[:ignore_errors])
  end
end

.guivoid

This method returns an undefined value.

Opens last generated waveform trace dump to inspect in Vivado GUI.

Since:

  • 0.9.0



419
420
421
422
423
424
425
426
# File 'lib/rvvm.rb', line 419

def self.gui
  dump = @args[:wavefile] || "#{@config[:elaboration][:tb]}.wdb"

  cmd = "xsim --gui #{dump}"
  execute("Running Vivado GUI...", cmd)

  exit(0)
end

.handle_argsvoid

This method returns an undefined value.

Argument collision handling and additional settings for batch simulation and dpi compilation.

Since:

  • 0.8.0



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/rvvm.rb', line 145

def self.handle_args
  @args[:dpi] = 1 if @args[:all] && @config[:dpi][:dpilib] == 1

  if @args[:batch] || @config[:simulation][:batch] == 1
    if @args[:test]
      puts "UVM test provided even though running in batch mode - option will be ignored..."
      @args[:test] = nil
    end
  elsif @args[:testList]
    puts "UVM test list provided without running in batch mode - option will be ignored..."
    @args[:testlist] = nil
  end

  @config[:elaboration][:customdpilib] = @args[:customdpilib] if @args[:customdpilib]
end

.load_configvoid

This method returns an undefined value.

Loads and parses rvvmconf.json config file from an RVvM project rvvm directory.

Since:

  • 0.8.0



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
# File 'lib/rvvm.rb', line 276

def self.load_config
  puts ""
  Crayons.spinner_start("Loading RVvM project config...")

  @config_path = Utils.find_file_dir("rvvmconf.json", ".")
  json_file = File.read("#{@config_path}/rvvmconf.json") if @config_path

  unless json_file
    Crayons.log_error("     Failed to load config file!\n")
    Crayons.log_error("     Make sure you are inside an RVvM project.\n\n")
    exit(1)
  end

  @config = JSON.parse(json_file) if json_file

  if @config.instance_of?(Hash)
    @config = @config.transform_values do |v|
      v.transform_keys(&:to_sym) if v.instance_of?(Hash)
    end.transform_keys(&:to_sym)
  end

  Crayons.spinner_stop(nil, true)
  puts ""
rescue JSON::ParserError => e
  Crayons.log_error("     Invalid config json!\n\n#{e.message}")
  puts""
  exit(1)
end

.prj_topvoid

This method returns an undefined value.

Navigates to project top (rvvm directory of the RVvM project).

Since:

  • 0.8.0



310
311
312
# File 'lib/rvvm.rb', line 310

def self.prj_top
  Dir.chdir(@config_path)
end

.runvoid

This method returns an undefined value.

Runs rvvm calling its methods based on provided script args.

Since:

  • 0.8.0



553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
# File 'lib/rvvm.rb', line 553

def self.run
  create_new_project(@args[:new]) if @args[:new]

  check_args
  unless @args[:here]
    load_config
    handle_args
  end

  create_module(@args[:module], "module") if @args[:module]
  create_module(@args[:itf], "itf")       if @args[:itf]
  create_pkg(@args[:pkg])                 if @args[:pkg]
  create_svfile(@args[:svfile])           if @args[:svfile]

  prj_top

  compile     if @args[:comp]
  dpi_c       if @args[:dpi]
  elaborate   if @args[:elab]
  run_sim     if @args[:run]
  run_sv      if @args[:runsv]
  gui         if @args[:gui]
  coverage    if @args[:gencov]
  cov_report  if @args[:covreport]

  exit(0)
end

.run_simvoid

This method returns an undefined value.

Runs UVM test simulation on an elaborated testbench snapshot using xrun.

Since:

  • 0.8.0



369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
# File 'lib/rvvm.rb', line 369

def self.run_sim
  cmd_args = @config[:simulation][:args]
  if @args[:wave]
    cmd_args << " --tclbatch wfcfg.tcl"
  else
    cmd_args << " -R"
  end
  cmd_args.strip!

  # Run simulaton on an array of tests.
  # If in not running in batch mode testlist is an array with a single test
  test = @args[:test] || @config[:simulation][:defTest]
  testlist = [test]
  testlist = @args[:testlist] || @config[:simulation][:testlist] if @args[:batch] || @config[:simulation][:batch] == 1

  tb = @args[:simtb] || @args[:tb] || @config[:elaboration][:tb]

  testlist.each_with_index do |simtest, i|
    simtest.strip!

    logname = File.join([@config[:project][:logDir], @config[:simulation][:logDir], @config[:simulation][:log]])
    logname = Utils.interpolate(logname, { testname: simtest })

    verb = "UVM_#{@args[:verb] || @config[:simulation][:verbosity]}"

    cmd = "xsim #{tb} -log #{logname} -testplusarg \"UVM_VERBOSITY=#{verb}\" -testplusarg \"UVM_TESTNAME=#{simtest}\" #{cmd_args}"
    execute("Running UVM test #{i + 1}/#{testlist.size}: #{simtest}...", cmd)
  end
end

.run_svvoid

This method returns an undefined value.

Runs a pure SystemVerilog/Verilog simulation using xrun.

Since:

  • 0.9.0



404
405
406
407
408
409
410
411
412
# File 'lib/rvvm.rb', line 404

def self.run_sv
  cmd_args = @config[:simulation][:args].strip!
  tb = @args[:simtb] || @args[:tb] || @config[:elaboration][:tb]

  logname = @args[:simlog] || File.join([@config[:project][:logDir], @config[:simulation][:logDir], "svsim.log"])

  cmd = "xsim #{tb} -log #{logname} #{cmd_args}"
  execute("Running pure SV/V simulation...", cmd)
end