ecic 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5fe4c1aca4adfa0193f736c1ad55a32addf62978adf94d658b677805fa5efe2a
4
- data.tar.gz: 7f01b0281fda482bb7007e8fbdcd592cb03cefb1c198dae0687f4ddb61b98956
3
+ metadata.gz: a1529013358fa74fc927995546738340500b80fcc80aaf96155a761a6696dbf4
4
+ data.tar.gz: 75a1426a8775b5d267ea9df4f3d32af6ab7f7f87dbbc37ae062f47d8a048ef4c
5
5
  SHA512:
6
- metadata.gz: 9791e87cbb17451e0c5b45802a958b7ac0c4e06ce4eea40b9c6fdc850486b5c1310543afbc1ff31fba98e539bf5e09e073ed9aa40b0a054d48dd68cccf655b6f
7
- data.tar.gz: 98bc6a7a59f5ab7267095dd6681eb240ccf5672ddf883ea0b23d331fe43945ce648c619dcce2d80c622957c0937cf0603729887a24c5b951fe660413e2001f90
6
+ metadata.gz: 9723f99531c5ef0d17d79360f647ca2f8c24329041c44adf7e769f8b0e09f9b3315694421eb736ba9355f7a2af530c9b23f445ce97e9dc9149eef5ab52597e4b
7
+ data.tar.gz: 5afaeb4239982741957301afcc184386d1db04701c6fce5f026b8389bc332b8b18c12a760c1364811ad9d38d7c88ee7cf8488be389756ecb3e7032186d540749
data/README.md CHANGED
@@ -161,21 +161,32 @@ If the folder contains files that will normally be overwritten by the framework,
161
161
 
162
162
  ### Add existing RTL files
163
163
 
164
- To add an existing RTL file to the project, go to the project folder and use the `ecic add design` commmand. This will add all the listed files to the given design library. If the library does not already exist, you will be asked to confirm the creation of it.
164
+ To add an existing RTL file to the project, go to the project folder and use the `ecic addfile` commmand. This will add all the listed files to your project.
165
165
 
166
- For example, to add two existing files named `./foo/bar/some_design.sv` and `../toto/kuku.vhd` to a library called `my_lib`, run:
166
+ You can specify the library name with the `--lib` option or rely on an implicit library name that is extracted from the full paths of the added files. In the latter case the extracted library name will be equal to the name of the directory just under `src/design` or `src/testbench`. In either case, if the library does not already exist, you will be asked to confirm the creation of it.
167
167
 
168
- $ ecic add design my_lib ./foo/bar/some_design.sv ../toto/kuku.vhd
168
+ For example, given that:
169
169
 
170
- Although all files that belong to a given library should be placed in the folder for that library, you can specify files that are placed anywhere in your file system.
170
+ * you have a Unix like terminal
171
+ * you want to eg. add all design files that have a `.vhd` or `.sv` extention
172
+ * all design files are placed in subfolders under a `./src/design`
173
+ * all files for a given RTL library are placed under a folder (of the same name) in the `./src/design`
171
174
 
172
- If you have a Unix like terminal and want to eg. add all files in a `./foo` folder that has the extension `.vhd`, you can use the standard Unix `find` command:
175
+ ... then you can use the standard Unix `find` command and leave out the `--lib` option:
173
176
 
174
- $ ecic add design my_lib `find ./foo -name "*.vhd"`
177
+ $ ecic addfile `find ./src/design -name "*.vhd"` `find ./src/design -name "*.sv"`
175
178
 
176
- When adding files to the project, the file extension (eg. vhd) is used to determine the file type. VHDL files are expected to have a .vhd or .vhdl extension and Verilog/SystemVerilog files are expected to have a .sv og .v extension. You can also specify the file type with a `type=vhdl|sv` option, eg.:
179
+ Although all files that belong to a given library should be placed in the folder for that library, you can specify files that are placed anywhere in your file system, but this requires using the `--lib` option. For example, to add two existing files named `./foo/bar/some_design.sv` and `../../some/path/outside/the/library/folder/kuku.vhd` to a library called `my_lib`, run:
177
180
 
178
- $ ecic add design --type=vhdl my_lib `find ./foo -name "*.*"`
181
+ $ ecic addfile --lib=my_lib ./foo/bar/some_design.sv ../../some/path/outside/the/library/folder/kuku.vhd
182
+
183
+ If all your VHDL designs assume to be compiled into one library called `work`, you can just set `--lib=work`, eg.:
184
+
185
+ $ ecic addfile --lib=work `find . -name "*.vhd"`
186
+
187
+ When adding files to the project, the file extension (eg. .vhd) is used to determine the file type. VHDL files are expected to have a .vhd or .vhdl extension and Verilog/SystemVerilog files are expected to have a .sv og .v extension. You can also specify the file type with a `type=vhdl|sv` option, eg.:
188
+
189
+ $ ecic addfile --type=vhdl --lib=my_lib `find ./foo -name "*.*"`
179
190
 
180
191
  ## Compiling and elaborating RTL files
181
192
 
@@ -55,14 +55,16 @@ help:
55
55
  long: |
56
56
  Add one or more existing design files to a given library in the project!
57
57
 
58
- Example: ecic addfile my_lib ./foo/bar/some_design.sv ../toto/kuku.vhd
58
+ Example: ecic addfile --lib=my_lib ./foo/bar/some_design.sv ../toto/kuku.vhd
59
59
 
60
60
  This adds the ./foo/bar/some_design.sv ../toto/kuku.vhd files to the library
61
- called 'my_lib' by adding these to the <PROJECT_ROOT>/src/design/my_lib/sources.rb file.
61
+ called 'my_lib' by adding these to the sources.rb file of the libray.
62
62
 
63
63
  Although all files that belong to a given library should be placed in the
64
64
  folder for that library, you can specify files that are placed anywhere
65
65
  in your file system.
66
+
67
+ If an added file is located outside the project folder, an absolute path will be used by default.
66
68
 
67
69
  generate:
68
70
  short: Generate new testbenches, RTL modules, tests etc.!
data/ecic.gemspec CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
20
  spec.require_paths = ["lib"]
21
-
21
+ spec.required_ruby_version = '>= 2.4.4'
22
22
  spec.add_dependency "thor", '~> 0.20'
23
23
  spec.add_dependency "colorize", '~> 0.8'
24
24
  spec.add_dependency "rake", '~> 12.3'
data/lib/ecic/cli.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Ecic
2
2
  class CLI < Command
3
3
 
4
- include Ecic::SourceFileAdder
4
+ include Ecic::SourceListUpdater
5
5
 
6
6
  class << self
7
7
  def help(shell, subcommand = false)
@@ -11,10 +11,6 @@ module Ecic
11
11
  shell.say "To get more help on a specific command, try 'ecic help [COMMAND]'"
12
12
  end
13
13
 
14
- #TBA: Make a function that returns the root folder for the project
15
- def root
16
- File.expand_path("./tfj2")
17
- end
18
14
  end
19
15
 
20
16
  check_unknown_options!
@@ -56,37 +52,32 @@ module Ecic
56
52
  #--------------------------------------------------------------------------
57
53
  # design generator:
58
54
  #--------------------------------------------------------------------------
59
- desc "addfile LIBRARY_NAME FILENAME...", Help.text('addfile')['short']
55
+ desc "addfile FILENAME...", Help.text('addfile')['short']
60
56
  long_desc Help.text('addfile')['long']
57
+ option :lib, :type => :string, :banner => 'LIBRARY_NAME', :desc => 'Specify the name of the design library'
61
58
 
62
- def addfile(lib_name, *file_names)
59
+ def addfile(*file_names)
63
60
  begin
64
61
  root_dir = Project::root
65
62
  if root_dir.nil?
66
- shell.error "You must be within an ECIC project before calling this command"
63
+ shell.error set_color("You must be within an ECIC project before calling this command",Thor::Shell::Color::RED)
67
64
  exit(1)
68
65
  end
66
+
67
+ opt = {"lib" => nil}.merge(options)
68
+
69
69
  project = Project.new(root_dir)
70
70
  project.load_libraries
71
-
72
- unless project.has_library?(lib_name)
73
- if yes?("Library '#{lib_name}' does not exist. Create it? [y/n]:")
74
- generator = LibraryGenerator.new
75
- generator.destination_root = root_dir
76
- generator.library_name = lib_name
77
- generator.invoke_all
78
- else
79
- shell.error "Operation aborted!"
80
- exit(2)
81
- end
82
- end
71
+ lib_name = opt['lib']
83
72
  file_adder = FileAdder.new
73
+ file_adder.destination_root = root_dir
84
74
  file_adder.library_name = lib_name
85
- file_adder.file_names = file_names
75
+ file_adder.project = project
76
+ file_adder.file_names = file_names
86
77
  file_adder.invoke_all
87
78
 
88
79
  rescue Exception => exc
89
- shell.error exc.message
80
+ shell.error set_color(exc.message, Thor::Shell::Color::RED)
90
81
  exit(3)
91
82
  end
92
83
 
@@ -127,7 +118,6 @@ module Ecic
127
118
  option :format, :type => :string, :banner => 'text|json', :desc => 'Specify the output format'
128
119
  option :include_source_files, :type => :boolean, :aliases => '-s', :desc => "Include source files for each library"
129
120
  def libraries
130
-
131
121
  defaults = {
132
122
  "format" => "text",
133
123
  "include_source_files" => false
@@ -136,22 +126,21 @@ module Ecic
136
126
 
137
127
  root_dir = Project::root
138
128
  if root_dir.nil?
139
- shell.error "You must be within an ECIC project before calling this command"
129
+ shell.error set_color("You must be within an ECIC project before calling this command",Thor::Shell::Color::RED)
140
130
  exit(3)
141
131
  end
142
132
  project = Project.new(root_dir)
143
133
  project.load_libraries
144
- project.load_sources if opt['include_source_files']
134
+ if opt['include_source_files']
135
+ # puts "reading source files..."
136
+ project.load_sources
137
+ end
145
138
  if opt['format'] == 'json'
146
139
  require 'json'
147
140
  say project.libraries.map{ |lib| lib.to_json(:include_source_files => opt['include_source_files']) }.join(",")
148
141
  else
149
- say project.libraries.map{ |lib| lib.to_str(:include_source_files => opt['include_source_files']) }.join("\n")
142
+ say project.libraries.map{ |lib| lib.to_s(:include_source_files => opt['include_source_files']) }.join("\n")
150
143
  end
151
144
  end
152
145
  end
153
- end
154
-
155
-
156
-
157
-
146
+ end
@@ -3,9 +3,9 @@ module Ecic
3
3
  class DesignGenerator < Thor::Group
4
4
  # require source_file_adder
5
5
  include Thor::Actions
6
- include Ecic::SourceFileAdder
6
+ include Ecic::SourceListUpdater
7
7
 
8
- attr_writer :library_name, :design_name, :include_types_pkg
8
+ attr_writer :library, :design_name, :include_types_pkg
9
9
 
10
10
  def self.source_root
11
11
  File.dirname(__FILE__) + '/../../templates/project'
@@ -21,7 +21,7 @@ module Ecic
21
21
  # end
22
22
 
23
23
  def copy_rtl_templates
24
- base_name = "src/design/#{@library_name}/#{@design_name}"
24
+ base_name = "#{@library.path}/#{@design_name}"
25
25
  @include_types_pkg ||= false
26
26
  if @include_types_pkg
27
27
  template("src/design/lib/pkg_types.vhd.tt", "#{base_name}-pkg_types.vhd")
@@ -32,15 +32,16 @@ module Ecic
32
32
  end
33
33
 
34
34
  def update_src_list
35
- src_file = "src/design/#{@library_name}/sources.rb"
35
+ src_file = "#{@library.path}/sources.rb"
36
36
  create_file src_file unless File.exists?(src_file)
37
37
  @include_types_pkg ||= false
38
+ #TBA: update these cals to 'Pathname'
38
39
  if @include_types_pkg
39
- add_src_file("#{@design_name}-pkg_types.vhd")
40
+ append_to_file(src_file, "source_file('#{@design_name}-pkg_types.vhd')\n"
40
41
  end
41
- add_src_file("#{@design_name}-pkg_comp.vhd")
42
- add_src_file("#{@design_name}-ent.vhd")
43
- add_src_file("#{@design_name}-arc_rtl.vhd")
42
+ append_to_file(src_file, "source_file('#{@design_name}-pkg_comp.vhd')\n"
43
+ append_to_file(src_file, "source_file('#{@design_name}-ent.vhd')\n"
44
+ append_to_file(src_file, "source_file('#{@design_name}-arc_rtl.vhd')\n"
44
45
  end
45
46
 
46
47
  end
@@ -1,21 +1,31 @@
1
1
  module Ecic
2
-
3
2
  class FileAdder < Thor::Group
4
3
  include Thor::Actions
5
- include Ecic::SourceFileAdder
4
+ include Ecic::SourceListUpdater
5
+ include Ecic::LibraryCreationHelper
6
+ require 'pathname'
6
7
 
7
- attr_writer :library_name, :file_names
8
-
9
- # def self.source_root
10
- # File.dirname(__FILE__) + '/../../templates/project'
11
- # end
8
+ attr_accessor :library_name, :file_names, :project
12
9
 
13
10
  def add_files_to_source_list
14
- @file_names.each { |file_name|
15
- add_src_file(file_name)
11
+ #If a library name is given, then the project must already contain a library with that
12
+ #name. Otherwise an error message must be returned, because we do not know if it is a
13
+ #design or testbench library.
14
+ unless library_name.nil?
15
+ library = project.get_library(library_name)
16
+ raise "Unknown library called '#{library_name}'. Please create the library before adding files to it. " if library.nil?
17
+ end
18
+ destination_path = Pathname.new(destination_root)
19
+ file_names.each { |file_name|
20
+ src_file_info = SourceFileInfo.new(project, file_name, library)
21
+ raise "Library name could not be determined from the path of '#{file_name}'. Make sure the appropriate library has been created and specify it with the --lib option." if src_file_info.library.nil?
22
+ # puts "lib name=#{src_file_info.library.name}, lib_path = #{src_file_info.library.path}"
23
+ if create_library_if_missing(src_file_info.library)
24
+ add_src_file(src_file_info, destination_path)
25
+ else
26
+ say set_color("Skipping #{file_name}",Thor::Shell::Color::BLUE)
27
+ end
16
28
  }
17
29
  end
18
-
19
30
  end
20
-
21
31
  end
data/lib/ecic/generate.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  module Ecic
2
2
  class Generate < Command
3
+ include Ecic::LibraryCreationHelper
3
4
 
4
5
  #--------------------------------------------------------------------------
5
6
  # TESTBENCH generator:
@@ -21,20 +22,30 @@ module Ecic
21
22
 
22
23
  option :just_print, :type => :boolean, :aliases => '-n', :desc => "Don't actually run any commands; just print them."
23
24
  def library(*names)
24
- project_root_path = Ecic::Project::root
25
- #project_root_path = Dir.pwd
26
- #if false
27
- if project_root_path.nil?
28
- shell.error "You must be within an ECIC project before calling this command"
29
- exit(1)
30
- else
31
- # shell.say "Generating library in #{project_root_path}"
32
- names.each { |lib_name|
33
- generator = LibraryGenerator.new
34
- generator.destination_root = project_root_path
35
- generator.library_name = lib_name
36
- generator.invoke_all
37
- }
25
+ begin
26
+ project_root_path = Ecic::Project::root
27
+ #project_root_path = Dir.pwd
28
+ #if false
29
+ if project_root_path.nil?
30
+ shell.error set_color("You must be within an ECIC project before calling this command",Thor::Shell::Color::RED)
31
+ exit(1)
32
+ else
33
+ # shell.say "Generating library in #{project_root_path}"
34
+ project = Project.new(project_root_path)
35
+ project.load_libraries
36
+ names.each { |lib_name|
37
+ #TBA: Add option to generate a testbench library as well
38
+ new_lib = project.design_library(lib_name)
39
+ if new_lib.already_exists?
40
+ say set_color("Library called '#{lib_name}' already exists",Thor::Shell::Color::GREEN)
41
+ else
42
+ shell.error set_color("Library called '#{lib_name}' could not be generated",Thor::Shell::Color::RED) unless generate_library new_lib
43
+ end
44
+ }
45
+ end
46
+ rescue Exception => exc
47
+ shell.error set_color(exc.message,Thor::Shell::Color::RED)
48
+ exit(3)
38
49
  end
39
50
  end
40
51
 
@@ -51,26 +62,21 @@ module Ecic
51
62
 
52
63
  def design(*names)
53
64
  begin
54
- lib_name = options[:lib]
55
65
  type = options[:type]
56
66
  root_dir = Project::root
57
67
  if root_dir.nil?
58
- shell.error "You must be within an ECIC project before calling this command"
68
+ shell.error set_color("You must be within an ECIC project before calling this command",Thor::Shell::Color::RED)
59
69
  exit(1)
60
70
  end
61
71
  project = Project.new(root_dir)
62
72
  project.load_libraries
63
73
  # p project.libraries
64
74
 
65
- unless project.has_library?(lib_name)
66
- if yes?("Library '#{lib_name}' does not exist. Create it? [y/n]:")
67
- generator = LibraryGenerator.new
68
- generator.destination_root = root_dir
69
- generator.library_name = lib_name
70
- generator.invoke_all
71
- else
72
- shell.error "Operation aborted!"
73
- exit(2)
75
+ lib = project.design_library(options[:lib])
76
+ unless lib.already_exists?
77
+ unless ok_to_create_library? lib
78
+ say "Operation aborted!"
79
+ raise SystemExit
74
80
  end
75
81
  end
76
82
 
@@ -81,7 +87,7 @@ module Ecic
81
87
  else
82
88
  incl_types_pkg ||= false
83
89
  if incl_types_pkg
84
- shell.error "--types_package option does not apply for Verilog/SystemVerilog generation!"
90
+ shell.error set_color("--types_package option does not apply for Verilog/SystemVerilog generation!",Thor::Shell::Color::RED)
85
91
  exit(3)
86
92
  end
87
93
  end
@@ -92,16 +98,16 @@ module Ecic
92
98
  elsif type == 'sv'
93
99
  generator = SvDesignGenerator.new
94
100
  else
95
- shell.error "--type option must be set to either 'vhdl' or 'sv'"
101
+ shell.error set_color("--type option must be set to either 'vhdl' or 'sv'",Thor::Shell::Color::RED)
96
102
  exit(3)
97
103
  end
98
104
  generator.destination_root = root_dir
99
- generator.library_name = lib_name
105
+ generator.library = lib
100
106
  generator.design_name = design_name
101
107
  generator.invoke_all
102
108
  }
103
109
  rescue Exception => exc
104
- shell.error exc.message
110
+ shell.error set_color(exc.message,Thor::Shell::Color::RED)
105
111
  exit(3)
106
112
  end
107
113
 
@@ -0,0 +1,77 @@
1
+ module Ecic::LibraryCreationHelper
2
+
3
+ def create_library_if_missing(library)
4
+ unless library.already_exists?
5
+ return ok_to_create_library? library
6
+ end
7
+ return true
8
+ end
9
+
10
+ def ok_to_create_library?(library)
11
+ if must_create_new_library? library
12
+ return generate_library library
13
+ end
14
+ # shell.error set_color("Operation aborted!",Thor::Shell::Color::RED)
15
+ # exit(2)
16
+ return false
17
+ end
18
+
19
+ def generate_library(library)
20
+ if library.is_valid?
21
+ generator = Ecic::LibraryGenerator.new
22
+ generator.destination_root = library.project.root
23
+ generator.library = library
24
+ generator.invoke_all
25
+ library.save
26
+ else
27
+ return false
28
+ end
29
+ end
30
+
31
+ protected
32
+
33
+ def must_create_new_library?(library)
34
+ return true if @always_create_library
35
+ options = "[Ynaq]"
36
+ loop do
37
+ answer = ask(
38
+ %[#{library.type.to_s.capitalize} library '#{library.name}' does not exist. Create it? (enter "h" for help) #{options}],
39
+ :add_to_history => false
40
+ )
41
+ case answer
42
+ when nil
43
+ say ""
44
+ return true
45
+ when is?(:yes), is?(:all), ""
46
+ return true
47
+ when is?(:no), is?(:skip)
48
+ return false
49
+ when is?(:always)
50
+ return @always_create_library = true
51
+ when is?(:quit)
52
+ say "Aborting..."
53
+ raise SystemExit
54
+ else
55
+ say library_creation_help
56
+ end
57
+ end
58
+ end
59
+
60
+ def library_creation_help
61
+ puts "Options:"
62
+ puts " Yes : Create the library (default)"
63
+ puts " No : Continue without creating the library"
64
+ puts " All : Create the library (and any additional libraries)"
65
+ puts " Quit : Abort operation"
66
+ end
67
+
68
+ def is?(value) #:nodoc:
69
+ value = value.to_s
70
+ if value.size == 1
71
+ /\A#{value}\z/i
72
+ else
73
+ /\A(#{value}|#{value[0, 1]})\z/i
74
+ end
75
+ end
76
+
77
+ end
@@ -0,0 +1,21 @@
1
+ module Ecic::SourceListUpdater
2
+ def add_src_file(src_file_info, dest_root)
3
+ #TBA: IF THE absolute_file_path IS OUTSIDE THE PROJECT FOLDER, THEN THE ABSOLUTE FILE PATH MUST BE USED INSTEAD OF 'relative_file_path'
4
+ src_list_filepath = src_file_info.sources_file_path
5
+ absolute_file_path = src_file_info.absolute_path
6
+ # puts "src_list_filepath=#{src_list_filepath}"
7
+ # puts "absolute_file_path=#{absolute_file_path}"
8
+ # puts "dest_root=#{dest_root}"
9
+ if src_file_info.is_outside_project?
10
+ used_file_ref = absolute_file_path.to_s
11
+ else
12
+ used_file_ref = absolute_file_path.relative_path_from(dest_root.join(src_list_filepath.dirname)).to_s
13
+ end
14
+ # puts "relative_file_path = #{relative_file_path}"
15
+ # relative_src_list_filepath = src_list_filepath.relative_path_from(dest_root).to_s
16
+ # puts "relative_src_list_filepath = relative_src_list_filepath"
17
+ # src_file = "src/design/#{library_name}/sources.rb.tfj"
18
+ create_file src_list_filepath unless File.exists?(File.join(dest_root,src_list_filepath))
19
+ append_to_file src_list_filepath, "source_file('#{used_file_ref}')\n"
20
+ end
21
+ end
data/lib/ecic/library.rb CHANGED
@@ -2,56 +2,99 @@ module Ecic
2
2
 
3
3
  class Library
4
4
 
5
- attr_accessor :name
5
+ attr_accessor :name, :path, :project
6
6
  attr_accessor :source_files
7
+ attr_reader :type
7
8
 
8
- def initialize(project, name=nil)
9
+
10
+ def initialize(project, name, type, options={})
11
+ opt = {:path => nil}.merge(options)
9
12
  @project = project
13
+ @type = type
10
14
  @name = name
15
+ default_path = {:testbench => "src/testbench/#{@name}",
16
+ :design => "src/design/#{@name}"}
17
+ @path = opt[:path] || default_path[@type]
11
18
  @source_files = []
12
19
  end
13
-
14
- def create(name)
15
- @name = name
20
+
21
+ def is_valid?
22
+ begin
23
+ validate_name
24
+ return false if already_exists?
25
+ #TBA: validate unique name as well
26
+ return true
27
+ #TBA: 'validate_name' should raise a specific naming exception and only this specific exception should be caught.
28
+ rescue Exception => exc
29
+ return false
30
+ end
16
31
  end
17
32
 
33
+ def save
34
+ validate_name
35
+ @project.add_library self
36
+ end
37
+
38
+ def already_exists?
39
+ @project.has_library?(self)
40
+ end
41
+
18
42
  def to_str(options={})
43
+ to_s(options)
44
+ end
45
+
46
+ def to_s(options={})
19
47
  str = name
20
48
  incl_src_files = options[:include_source_files] || false
21
49
  if incl_src_files
22
- str += "\n" + source_files.join("\n")
50
+ str += ":"
51
+ str += "\n " + source_files.join("\n ") unless source_files.length == 0
23
52
  end
24
53
  str
25
54
  end
26
55
 
27
56
  def to_json(options = {})
28
57
  incl_src_files = options[:include_source_files] || false
29
- if incl_src_files
30
- str = {:name => name, :source_files => source_files}.to_json
31
- else
32
- str = {:name => name}.to_json
33
- end
58
+ hash = {:name => name, :path => path}
59
+ hash[:source_files] = source_files if incl_src_files
60
+ hash.to_json
34
61
  end
35
62
 
36
63
  def load_sources
37
- src_file = File.join(@project.root, 'src', 'design', @name, 'sources.rb')
64
+ src_file = File.join(@project.root, @path, 'sources.rb')
38
65
  if File.exists?(src_file)
39
66
  begin
67
+ puts "reading #{src_file} ..."
40
68
  eval File.read(src_file)
41
69
  rescue Exception => exc
42
70
  raise "Syntax error occurred while reading #{src_file}: #{exc.message}"
43
71
  end
44
72
  else
45
- raise "Could not read sources for #{name} library"
73
+ # p @path
74
+ # p @type
75
+ raise "Could not read sources for #{name} library. #{src_file} file does not exist"
46
76
  end
47
77
  end
48
78
 
49
- #Function used by 'source.create' method used in src/confic/libraries.rb
50
- def source_file
51
- new_src = SourceFile.new(self)
79
+ def is_a_testbench?
80
+ @type == :testbench
81
+ end
82
+
83
+ #Function used in sources.rb file of each library
84
+ def source_file(path)
85
+ # puts "Creating new source file"
86
+ new_src = SourceFile.new(self, path)
52
87
  source_files << new_src
53
88
  new_src
54
89
  end
55
90
 
91
+ ###########################################################################
92
+ protected
93
+ ###########################################################################
94
+
95
+ def validate_name
96
+ raise "#{@name} is not a valid library name. Library names must start with a letter, followed by one or more numbers, letters or underscores" unless /\A[a-zA-Z]\w*\Z/.match(@name)
97
+ end
98
+
56
99
  end
57
100
  end
@@ -4,21 +4,34 @@ module Ecic
4
4
  include Thor::Actions
5
5
  desc 'Generate a new RTL library'
6
6
 
7
- attr_writer :library_name
7
+ attr_writer :library
8
8
 
9
9
  def self.source_root
10
10
  File.dirname(__FILE__) + '/../../templates/project'
11
11
  end
12
12
 
13
13
  def create_library_directory
14
- template("src/design/lib/sources.rb.tt", "src/design/#{@library_name}/sources.rb")
14
+ src_list_file = File.expand_path("#{destination_root}/#{@library.path}/sources.rb")
15
+ template("src/design/lib/sources.rb.tt", src_list_file) unless File.exist?(src_list_file)
15
16
  end
16
17
 
17
18
  def update_library_list
18
19
  libraries_file = File.expand_path("#{destination_root}/src/config/libraries.rb")
19
- empty_directory 'src/config' unless File.exist?(File.dirname(libraries_file))
20
- create_file libraries_file unless File.exist?(libraries_file)
21
- append_to_file 'src/config/libraries.rb', "library.create('#{@library_name}')\n"
20
+ empty_directory 'src/config' unless File.exist?(File.dirname(libraries_file))
21
+ create_file libraries_file unless File.exist?(libraries_file)
22
+ case @library.path.to_s
23
+ when "src/design/#{@library.name}"
24
+ cmd = "design_library('#{@library.name}')"
25
+ when "src/testbench/#{@library.name}"
26
+ cmd = "testbench_library('#{@library.name}')"
27
+ else
28
+ if @library.is_a_testbench?
29
+ cmd = "testbench_library('#{@library.name}', :path => '#{@library.path}')"
30
+ else
31
+ cmd = "design_library('#{@library.name}', :path => '#{@library.path}')"
32
+ end
33
+ end
34
+ append_to_file 'src/config/libraries.rb', "#{cmd}\n"
22
35
  end
23
36
 
24
37
  end
data/lib/ecic/project.rb CHANGED
@@ -20,13 +20,13 @@ module Ecic
20
20
  #from within an ECIC project folder
21
21
  def self.root(path = Pathname.new(Dir.pwd))
22
22
  if File.exists?(File.join(path, SCRIPT_ECIC))
23
- return path
23
+ return File.expand_path(path)
24
24
  elsif path.root?
25
25
  return nil
26
26
  end
27
27
  return root(path.parent)
28
28
  end
29
-
29
+
30
30
  def load_libraries
31
31
  lib_file = File.join(@root, LIBRARIES_CFG_SCRIPT)
32
32
  if File.exists?(lib_file)
@@ -34,26 +34,47 @@ module Ecic
34
34
  eval File.read(lib_file)
35
35
  rescue Exception => exc
36
36
  raise "Syntax error occurred while reading #{lib_file}: #{exc.message}"
37
- end
37
+ end
38
38
  # else
39
39
  # raise "Could not read library definitions from #{lib_file}"
40
40
  end
41
41
  end
42
42
 
43
+ def has_library?(library)
44
+ libraries.any? {|l| l.name.eql? library.name}
45
+ end
43
46
 
44
- def has_library?(lib_name)
45
- libraries.any? {|l| l.name == lib_name }
47
+ def library_mapped_to(path)
48
+ matching_libraries = libraries.select {|l| l.path.eql? path }
49
+ raise "Found multiple libraries mapped to '#{path}'" if matching_libraries.length > 1
50
+ matching_libraries.first
51
+ end
52
+
53
+ def get_library(lib_name)
54
+ matching_libraries = libraries.select {|l| l.name.eql? lib_name }
55
+ raise "Found multiple libraries called '#{lib_name}'" if matching_libraries.length > 1
56
+ matching_libraries.first
46
57
  end
47
58
 
48
- # def add_libray(name)
49
- # @libraries << Library.new(self, name)
50
- # end
59
+ def add_library(lib)
60
+ raise "A library called '#{lib.name}' already exists" if has_library?(lib)
61
+ raise "A library is already mapped to '#{lib.path}'" if library_mapped_to(lib.path)
62
+ @libraries << lib
63
+ return true
64
+ end
65
+
66
+ #Function used in src/confic/libraries.rb
67
+ def design_library(name, options={})
68
+ lib = Library.new(self, name, :design, options)
69
+ lib.save
70
+ lib
71
+ end
51
72
 
52
- #Function used by 'library.create' method used in src/confic/libraries.rb
53
- def library
54
- new_lib = Library.new(self)
55
- libraries << new_lib
56
- new_lib
73
+ #Function used in src/confic/libraries.rb
74
+ def testbench_library(name, options={})
75
+ lib = Library.new(self, name, :testbench, options)
76
+ lib.save
77
+ lib
57
78
  end
58
79
 
59
80
  def load_sources
@@ -4,12 +4,9 @@ module Ecic
4
4
 
5
5
  attr_accessor :path #, :library
6
6
 
7
- def initialize(library)
7
+ def initialize(library, path)
8
8
  @library = library
9
- end
10
-
11
- def create(path)
12
- @path = path
9
+ @path = path
13
10
  end
14
11
 
15
12
  def to_s
@@ -0,0 +1,98 @@
1
+ module Ecic
2
+ #Class that can provide various info about what do to with a source file.
3
+ class SourceFileInfo
4
+
5
+ require 'pathname'
6
+
7
+ attr_reader :absolute_path, :library
8
+
9
+ STANDARD_LIBRARY_FOLDERS_LIST = ["src/design", "src/testbench"]
10
+
11
+ def initialize(project, file_name, library=nil)
12
+ @project = project
13
+ @absolute_path = Pathname.new(File.expand_path(file_name))
14
+ @relative_path_from_project = @absolute_path.relative_path_from(Pathname.new("#{@project.root}"))
15
+ @library = library || get_library_from_file_path
16
+ end
17
+
18
+ #TBA: Make sure this function works for libraries under src/testbench as
19
+ #well and make sure it returns nil, if the library name cannot be determined.
20
+ #TBA: Update this function to first look for any sources.rb files within the
21
+ #project folder structure.
22
+ def get_library_from_file_path
23
+ return nil if is_outside_project?
24
+ sources_file_dir = find_sources_file_dir
25
+ if sources_file_dir
26
+ #A sources.rb file was found."
27
+ #Check if an existing library is already mapped to that folder. If so, return that library
28
+ #and otherwise return a new library that is named according to the folder
29
+ already_mapped_lib = @project.library_mapped_to(sources_file_dir.to_s)
30
+ return already_mapped_lib if already_mapped_lib
31
+ #Use the name of the folder as the library name:"
32
+ lib_dir = sources_file_dir
33
+ else
34
+ # puts " #Could not find an existing sources.rb file for the given source file"
35
+ lib_dir = get_default_library_dir_from_file_path
36
+ end
37
+ unless lib_dir.nil?
38
+ lib_name = lib_dir.basename.to_s
39
+ Ecic::Library.new(@project, lib_name, get_library_type_from_file_path, :path => lib_dir)
40
+ end
41
+ end
42
+
43
+ def is_outside_project?
44
+ # @relative_path_from_project.to_s.split('/')[0] == ".."
45
+ /\A\.\./.match(@relative_path_from_project.to_s)
46
+ end
47
+
48
+ # def within_expected_folder?
49
+ # rel_design_path_list = @relative_path_from_project.to_s.split('/')
50
+ # return nil if rel_design_path_list.length < 3
51
+ # str = [rel_design_path_list.first(2)].join('/')
52
+ # STANDARD_LIBRARY_FOLDERS_LIST.include? str
53
+ # end
54
+
55
+ #Function that looks for a sources.rb file within the project
56
+ def find_sources_file_dir(dir = @relative_path_from_project.dirname)
57
+ return nil if is_outside_project?
58
+ file = File.join(@project.root, dir, "sources.rb")
59
+ if dir.root? or dir.to_s == "."
60
+ return nil
61
+ elsif File.exists?(file)
62
+ return dir
63
+ else
64
+ return find_sources_file_dir(dir.parent)
65
+ end
66
+ end
67
+
68
+ #Function that returns the name of the directory that is placed just under src/design or src/testbench:
69
+ def get_default_library_dir_from_file_path
70
+ #Get the first directory name after src/design or src/testbench:
71
+ rel_design_path_list = @relative_path_from_project.to_s.split('/')
72
+ return nil if rel_design_path_list.length < 3
73
+ return nil unless STANDARD_LIBRARY_FOLDERS_LIST.include? [rel_design_path_list.first(2)].join('/')
74
+ Pathname.new([rel_design_path_list.first(3)].join('/'))
75
+ end
76
+
77
+ #Function that returns the type of library that
78
+ def get_library_type_from_file_path
79
+ #Get the first directory name after src/design or src/testbench:
80
+ rel_design_path_list = @relative_path_from_project.to_s.split('/')
81
+ return nil if rel_design_path_list.length < 2
82
+ case [rel_design_path_list.first(2)].join('/')
83
+ when "src/testbench"
84
+ return :testbench
85
+ when "src/design"
86
+ return :design
87
+ else
88
+ return nil
89
+ end
90
+ end
91
+
92
+ def sources_file_path
93
+ return nil if @library.nil?
94
+ # puts "#{@library.path}/sources.rb"
95
+ Pathname.new("#{@library.path}/sources.rb")
96
+ end
97
+ end
98
+ end
@@ -4,21 +4,21 @@ module Ecic
4
4
  include Thor::Actions
5
5
  desc 'Generate a new SystemVerilog design'
6
6
 
7
- attr_writer :library_name, :design_name
7
+ attr_writer :library, :design_name
8
8
 
9
9
  def self.source_root
10
10
  File.dirname(__FILE__) + '/../../templates/project'
11
11
  end
12
12
 
13
13
  def copy_rtl_templates
14
- base_name = "src/design/#{@library_name}/#{@design_name}"
14
+ base_name = "#{@library.path}/#{@design_name}"
15
15
  template("src/design/lib/design.sv.tt", "#{base_name}.sv")
16
16
  end
17
17
 
18
18
  def update_src_list
19
- src_file = "src/design/#{@library_name}/sources.rb"
19
+ src_file = "#{@library.path}/sources.rb"
20
20
  create_file src_file unless File.exists?(src_file)
21
- append_to_file src_file, "source_file.create('#{@design_name}.sv')\n"
21
+ append_to_file src_file, "source_file('#{@design_name}.sv')\n"
22
22
  end
23
23
  end
24
24
 
data/lib/ecic/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ecic
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
data/lib/ecic.rb CHANGED
@@ -28,8 +28,10 @@ module Ecic
28
28
  autoload :SvDesignGenerator, "ecic/sv_design_generator"
29
29
  autoload :ProjectGenerator, "ecic/project_generator"
30
30
  autoload :LibraryGenerator, "ecic/library_generator"
31
- autoload :SourceFileAdder, "ecic/helpers/source_file_adder"
31
+ autoload :SourceListUpdater, "ecic/helpers/source_list_updater"
32
+ autoload :LibraryCreationHelper, "ecic/helpers/library_creation_helper"
32
33
  autoload :SourceFile, "ecic/source_file"
33
34
  autoload :Library, "ecic/library"
34
35
  autoload :Project, "ecic/project"
35
- end
36
+ autoload :SourceFileInfo, "ecic/source_file_info"
37
+ end
data/notes.txt CHANGED
@@ -1,3 +1,30 @@
1
+ #Make sure to check if a library already is mapped to a given folder - before asking to create a new one (in case a library with different name than the folder name is already mapped to that folder)
2
+
3
+ #The 'all' option for creating a new library (when adding files) does not work
4
+
5
+ #When sources files are listed, they must be displayed in alphabetical order.
6
+
7
+ #Use "raise SystemExit" instead of the various "exit" calls
8
+
9
+ * Make sure the design_generator still works, now that the 'add_src_file' method has been changed.
10
+
11
+ * make sure "/Users/torbenj/projects/github/ecic/exe/ecic generate library dsp_core" command works
12
+
13
+ * When generating a library, the libraries.rb file must include a path as a 2nd optional option, if the design library is not placed in src/design or if a testbench library is not placed in src/testbench.
14
+
15
+ * Update the 'add_src_file' method so this method ensures that file paths are always relative to the sources.rb file.
16
+
17
+ * Consider adding support for having libraries within subfolders, ie. a
18
+ "--lib=blk1/subblock" should expect a sources.rb file in eg "src/design/blk1/subblock" and the library name should be
19
+ converted eg. "blk1-subblock" when compiling and when using it in a VHDL design.
20
+
21
+
22
+ * bug: 'addfile' command assumes that files are placed inder src/design - and never under src/testbench!! (given the fact that the --lib option is used, how can be specify a library under src/testbench ?? One option could be to require that the addfile command is called from within a library/testbench folder if adding a file not placed in either src/Design or src/testbench - and then remove the --lib option completely?) .
23
+
24
+ Same issue with 'add_src_file' which also assumes src/design folder
25
+
26
+ * ls -d */ -> returns list of directorys (but include a trailing / character)
27
+
1
28
  * Remove any '/' prefix and postfix from library names when generating a new library (to allow use of "find" command to generate a number of libraries)
2
29
  * 'addfile' command must check that each add file actually exists.
3
30
 
@@ -6,7 +33,4 @@
6
33
  add design chip, :env => ['asic_rtl', 'asic_gate', 'fpga_rtl']
7
34
  add design [basic_vhdl, chip], :except => {:env => ['asic']}
8
35
  #add design chip_tb, :path => '/some/absolute/path'
9
- #add testbench chip_tb, :path => '/some/absolute/path'
10
-
11
- #Libraries can be added in libraries.rb with the syntax:
12
- library.create('lib_x')
36
+ #add testbench chip_tb, :path => '/some/absolute/path'
@@ -2,12 +2,10 @@
2
2
 
3
3
  #Syntax:
4
4
  #
5
- # library.create('LIBRARY')
5
+ # design_library('library_name')
6
6
  #
7
- # where LIBRARY is the name of a VHDL/Verilog library that must be placed in a folder of the same name under src/design
8
-
9
- #Syntax:
7
+ # where library_name is the name of a VHDL/Verilog library, which is normally placed in a folder of the same name under src/design
10
8
  #
11
- # testbench.create('TESTBENCH')
9
+ # testbench_library('testbench_name')
12
10
  #
13
- # where TESTBENCH is the name of a testbench that must be placed in a folder of the same name under src/testbench
11
+ # where testbench_name is the name of a testbench library, which is normally placed in a folder of the same name under src/testbench
@@ -2,6 +2,6 @@
2
2
  #
3
3
  # Syntax:
4
4
  #
5
- # source_file.create('DESIGN_FILE')
5
+ # source_file('design_file')
6
6
  #
7
- # where DESIGN_FILE is the name of a VHDL/Verilog/SystemVerilog file.
7
+ # where design_file is the name of a VHDL/Verilog/SystemVerilog file.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ecic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Torben Fox Jacobsen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-10-18 00:00:00.000000000 Z
11
+ date: 2018-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -144,12 +144,14 @@ files:
144
144
  - lib/ecic/file_adder.rb
145
145
  - lib/ecic/generate.rb
146
146
  - lib/ecic/help.rb
147
- - lib/ecic/helpers/source_file_adder.rb
147
+ - lib/ecic/helpers/library_creation_helper.rb
148
+ - lib/ecic/helpers/source_list_updater.rb
148
149
  - lib/ecic/library.rb
149
150
  - lib/ecic/library_generator.rb
150
151
  - lib/ecic/project.rb
151
152
  - lib/ecic/project_generator.rb
152
153
  - lib/ecic/source_file.rb
154
+ - lib/ecic/source_file_info.rb
153
155
  - lib/ecic/sv_design_generator.rb
154
156
  - lib/ecic/version.rb
155
157
  - notes.txt
@@ -178,7 +180,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
178
180
  requirements:
179
181
  - - ">="
180
182
  - !ruby/object:Gem::Version
181
- version: '0'
183
+ version: 2.4.4
182
184
  required_rubygems_version: !ruby/object:Gem::Requirement
183
185
  requirements:
184
186
  - - ">="
@@ -1,7 +0,0 @@
1
- module Ecic::SourceFileAdder
2
- def add_src_file(file_name)
3
- src_file = "src/design/#{@library_name}/sources.rb"
4
- create_file src_file unless File.exists?(src_file)
5
- append_to_file src_file, "source_file.create('#{file_name}')\n"
6
- end
7
- end