HDLRuby 3.3.3 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3fc400e683cbefc6a77e8e6c4394f67e88df74fccd3bcb4ba420f6babc2542c8
4
- data.tar.gz: e4619579f4ef6703c38cb1ee5cc95197b37b929eb630f93497a4b7bde0a4955f
3
+ metadata.gz: a22563a2a4dc9d6d53ba33618efa1c18d0cfb51336bb1308545b77f6673c7719
4
+ data.tar.gz: 4e3d7d9cf4fc513a42cdae82f51ef8e2dcc732f79076e23f14b50b8c1614191e
5
5
  SHA512:
6
- metadata.gz: 581b6f3029bc63108c0408495dcebaf6305f61697099985c7b2f043f3250d377e5640f0db7305f62ed2a4430f60f6dfc85495a382e84f89a1d595ac5519cebaa
7
- data.tar.gz: 1821cb1ee95bb0abfdfd8d99318b1a5a103baabc3c3d3c58e50cd965f54059d0636b3cd352f1c9e726c7c04d3282f06820896cc9cf74e92b6e7a721bcd254560
6
+ metadata.gz: 9087fea3e3d94a9d136482b27d017151e2e9593c4244ca7777cbc6cf63587163c6cec6c6d43b8721c4f1935f06ef9a28bd41c0bf271080b312d7f904fc4ef9ce
7
+ data.tar.gz: 47672356dba32493e1e3a9d7e38b9199c1bf44ea85f9e82d5e157daf2f3f4465c9cdc6cc78a079a1276d92672a9e6a4b08931ea5dbba85b33f57544a71f01825
data/README.md CHANGED
@@ -17,6 +17,19 @@ hdrcc --get-tuto
17
17
 
18
18
  __What's new__
19
19
 
20
+ For HDLRuby version 3.4.0:
21
+
22
+ * Improved synchronization of the browser-base graphical interface with the HDLRuby simulator.
23
+
24
+ * Added a Verilog HDL parsing library for Ruby. This library will be released separately once it is fully stabilized."
25
+
26
+ * Added a HDLRuby generating library from the a Verilog HDL AST provided by the above-mentioned library.
27
+
28
+ * Added a standalone tool for converting Verilog HDL files to HDLRuby called [v2hdr](#converting-verilog-hdl-to-hdlruby). This tool is still experimental though.
29
+
30
+ * Added a HDLRuby command for [loading a Verilog HDL file from a HDLRuby description](#loading-verilog-hdl-from-hdlruby).
31
+
32
+
20
33
  For HDLRuby version 3.3.0:
21
34
 
22
35
  * Remade the description of software components using the program construct.
@@ -3929,6 +3942,57 @@ The naming convention of the samples is the following:
3929
3942
  * `<name>_bench.rb`: sample including a simulation benchmark, these are the only samples that can be simulated using `hdrcc -S`. Please notice that such a sample cannot be converted to VHDL or Verilog HDL yet.
3930
3943
  * `with_<name>.rb`: sample illustrating a single aspect of HDLRuby or one of its libraries, usually includes a benchmark.
3931
3944
 
3945
+ # Converting Verilog HDL to HDLRuby
3946
+
3947
+ While the HDLRuby framwork does not support Verilog HDL files as input yet, a standalone tool is provided for converting those files to HDLRuby. For that please use the following command:
3948
+
3949
+ ```bash
3950
+ v2hdr <input Verilog HDL file> <output HDLRuby file>
3951
+ ```
3952
+
3953
+ For example, assuming that you have a Verilog ddHDL named 'adder.v' describing and adder circuit, you can convert it to HDLRuby as follows:
3954
+
3955
+ ```bash
3956
+ v2hdr adder.v adder.v.rb
3957
+ ```
3958
+
3959
+ Another possibility is to directly load the Verilog HDL file from a HDLRuby description using the command `require_verilog`.
3960
+ For example, assuming `adder.v` contains the following code:
3961
+
3962
+ ```verilog
3963
+ module adder(x,y,z);
3964
+ input[7:0] x,y;
3965
+ output[7:0] z;
3966
+
3967
+ assign z = x + y;
3968
+ endmodule
3969
+ ```
3970
+
3971
+ It can be loaded the be instantiated like any other module in HDLRuby as follows:
3972
+
3973
+ ```ruby
3974
+ require_verilog "adder.v"
3975
+
3976
+ system :my_IC do
3977
+ [8].inner :a, :b, :c
3978
+
3979
+ adder(:my_adder).(a,b,c)
3980
+
3981
+ ...
3982
+ end
3983
+ ```
3984
+
3985
+
3986
+ __Notes__:
3987
+
3988
+ * Verilog HDL accepts signal and module names in any letter case, while HDLRuby reserves identifiers starting with a capital letter for constants. To avoid conflicts, Verilog HDL names that begin with a capital letter are prefixed with an underscore (`_`) in HDLRuby. For example, if the Verilog HDL module name in the previous example were `ADDER`, it would be renamed to `_ADDER` in HDLRuby. Instantiating such a module would be done as follows:
3989
+
3990
+ ```ruby
3991
+ _ADDER(:my_add).(a,b,c)
3992
+ ```
3993
+
3994
+ * With the current version of HDLRuby, the Verilog HDL files are first converted to HDLRuby before being loaded using the standalone `v2hdr` tool.
3995
+
3932
3996
 
3933
3997
  # Contributing
3934
3998
 
@@ -3938,7 +4002,6 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/civol/
3938
4002
  # To do
3939
4003
 
3940
4004
  * Find and fix the (maybe) terrifying number of bugs.
3941
- * Add a GUI (any volunteer to do it?).
3942
4005
 
3943
4006
 
3944
4007
  # License
data/exe/v2hdr ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'HDLRuby/v2hdr.rb'
@@ -554,6 +554,7 @@ VALUE rcsim_make_timeWait(VALUE mod, VALUE unitV, VALUE delayV) {
554
554
  /* Adjust the delay depending on the unit. */
555
555
  const char* unit = rb_id2name(SYM2ID(unitV));
556
556
  switch(unit[0]) {
557
+ case 'f': delay /= 1000; break;
557
558
  case 'p': /* Ok as is. */ break;
558
559
  case 'n': delay *= 1000; break;
559
560
  case 'u': delay *= 1000000; break;
@@ -0,0 +1,6 @@
1
+ module adder8(x,y,z);
2
+ input[7:0] x,y;
3
+ output[7:0] z;
4
+
5
+ assign z = x + y;
6
+ endmodule
@@ -1,3 +1,5 @@
1
+ raise "Deprecated code."
2
+
1
3
  # require "../hruby_low2c.rb"
2
4
 
3
5
  # An 8-bit register with C encrypting.
@@ -1,3 +1,5 @@
1
+ raise "Deprecated code."
2
+
1
3
  require 'HDLRuby/backend/allocator'
2
4
  require 'HDLRuby/hdr_samples/mei8'
3
5
 
@@ -1,3 +1,5 @@
1
+ raise "Deprecated code."
2
+
1
3
  require 'HDLRuby/backend/allocator'
2
4
 
3
5
  ## A generic CPU description
@@ -0,0 +1,36 @@
1
+ $LOAD_PATH << "#{__dir__}/../../"
2
+
3
+ require "HDLRuby/verilog_hruby.rb"
4
+
5
+ parser = VerilogTools::Parser.new
6
+
7
+ ast = nil
8
+
9
+ begin
10
+ ast = parser.run(filename: ARGV[0], compress: ARGV[1] == "--compress" )
11
+ rescue => error
12
+ puts error
13
+ exit
14
+ end
15
+
16
+ puts "#################################"
17
+ puts "## AST ##"
18
+ puts "#################################"
19
+ puts "\n"
20
+
21
+ puts ast
22
+
23
+ hdlruby = ""
24
+ begin
25
+ hdlruby = ast.to_HDLRuby
26
+ rescue => error
27
+ puts error
28
+ exit
29
+ end
30
+
31
+ puts "\n"
32
+ puts "#################################"
33
+ puts "## HDLRuby ##"
34
+ puts "#################################"
35
+
36
+ puts hdlruby
@@ -1,3 +1,5 @@
1
+ raise "Deprecated code."
2
+
1
3
  require 'std/handshakes.rb'
2
4
 
3
5
  include HDLRuby::High::Std
@@ -1,3 +1,5 @@
1
+ raise "Deprecated code."
2
+
1
3
  require 'std/memory.rb'
2
4
 
3
5
  include HDLRuby::High::Std
@@ -11,7 +11,7 @@ system :nand_board do
11
11
  inner :clk
12
12
  # Description of the board.
13
13
  # It is updated at each rising edge of +clk+.
14
- board(:nand,8080) do
14
+ board(:nand,http_port: 8080) do
15
15
  actport clk.posedge
16
16
  sw din0: din0
17
17
  sw din1: din1
@@ -1,3 +1,4 @@
1
+ raise "Deprecated code."
1
2
 
2
3
  # Some system that can be used for reconfiguration.
3
4
  system :sys0 do
@@ -0,0 +1,24 @@
1
+ # Sample HDLRuby instantiating a Verilog HDL-described adder (adder.v)
2
+
3
+ require_verilog "adder8.v"
4
+
5
+ system :verilog_bench do
6
+ [8].inner :a, :b, :c
7
+
8
+ # Instantiate the adder.
9
+ adder8(:my_adder8).(a,b,c)
10
+
11
+ # Testing it.
12
+ timed do
13
+ a <= 0
14
+ b <= 0
15
+ repeat(100) do
16
+ repeat(100) do
17
+ !10.ns
18
+ b <= b + 1
19
+ end
20
+ a <= a + 1
21
+ end
22
+ !10.ns
23
+ end
24
+ end
@@ -1235,8 +1235,10 @@ module HDLRuby::High
1235
1235
  end
1236
1236
 
1237
1237
  # Declares a high-level sequential behavior activated on a list of
1238
- # +events+, and built by executing +ruby_block+.
1239
- def seq(*events, &ruby_block)
1238
+ # +events+, with possible name +name+ and built by executing
1239
+ # +ruby_block+.
1240
+ # def seq(*events, &ruby_block)
1241
+ def seq(*events, name: nil, &ruby_block)
1240
1242
  # Ensure there is a block.
1241
1243
  ruby_block = proc {} unless block_given?
1242
1244
  # Preprocess the events.
@@ -1244,12 +1246,16 @@ module HDLRuby::High
1244
1246
  event.respond_to?(:to_event) ? event.to_event : event
1245
1247
  end
1246
1248
  # Create and add the resulting behavior.
1247
- self.add_behavior(Behavior.new(:seq,*events,&ruby_block))
1249
+ # self.add_behavior(Behavior.new(:seq,*events,&ruby_block))
1250
+ self.add_behavior(Behavior.new(:seq,*events,name: name,
1251
+ &ruby_block))
1248
1252
  end
1249
1253
 
1250
1254
  # Declares a high-level parallel behavior activated on a list of
1251
- # +events+, and built by executing +ruby_block+.
1252
- def par(*events, &ruby_block)
1255
+ # +events+, with possible name +name+ and built by executing
1256
+ # +ruby_block+.
1257
+ # def par(*events, &ruby_block)
1258
+ def par(*events, name: nil, &ruby_block)
1253
1259
  # Ensure there is a block.
1254
1260
  ruby_block = proc {} unless block_given?
1255
1261
  # Preprocess the events.
@@ -1257,7 +1263,8 @@ module HDLRuby::High
1257
1263
  event.respond_to?(:to_event) ? event.to_event : event
1258
1264
  end
1259
1265
  # Create and add the resulting behavior.
1260
- self.add_behavior(Behavior.new(:par,*events,&ruby_block))
1266
+ self.add_behavior(Behavior.new(:par,*events,name: name,
1267
+ &ruby_block))
1261
1268
  end
1262
1269
 
1263
1270
  # Declares a high-level timed behavior built by executing +ruby_block+.
@@ -2271,6 +2278,22 @@ module HDLRuby::High
2271
2278
  end
2272
2279
 
2273
2280
 
2281
+ ## Methods for loading external files.
2282
+
2283
+ # Require a verilog file.
2284
+ def require_verilog(filename)
2285
+ # Converts the file to HDLRuby.
2286
+ if Kernel.system("v2hdr", "#{filename}", "#{filename}.rb") then
2287
+ # Success, require the resulting file.
2288
+ require "#{Dir.pwd}/#{filename}.rb"
2289
+ else
2290
+ # Failure.
2291
+ raise AnyError,
2292
+ "Could not load Verilog HDL file: #{filename}."
2293
+ end
2294
+ end
2295
+
2296
+
2274
2297
 
2275
2298
  # Classes describing harware instances.
2276
2299
 
@@ -4558,20 +4581,19 @@ module HDLRuby::High
4558
4581
  High = HDLRuby::High
4559
4582
 
4560
4583
  # Creates a new behavior executing +block+ activated on a list of
4561
- # +events+, and built by executing +ruby_block+.
4584
+ # +events+, possible name (of main block) +name+ and built by
4585
+ # executing +ruby_block+.
4562
4586
  # +mode+ can be either :seq or :par for respectively sequential or
4563
4587
  # parallel.
4564
- def initialize(mode,*events,&ruby_block)
4588
+ # def initialize(mode, *events, &ruby_block)
4589
+ def initialize(mode, *events, name: nil, &ruby_block)
4565
4590
  # Initialize the behavior with it.
4566
4591
  super(nil)
4567
- # # Save the Location for debugging information
4568
- # @location = caller_locations
4569
- # # Sets the current behavior
4570
- # @@cur_behavior = self
4571
4592
  # Add the events (they may be hierarchical to flatten)
4572
4593
  events.flatten.each { |event| self.add_event(event) }
4573
4594
  # Create and add the block.
4574
- self.block = High.make_block(mode,&ruby_block)
4595
+ # self.block = High.make_block(mode,&ruby_block)
4596
+ self.block = High.make_block(mode,*name,&ruby_block)
4575
4597
  # # Unset the current behavior
4576
4598
  # @@cur_behavior = nil
4577
4599
  end
@@ -4866,6 +4888,11 @@ module HDLRuby::High
4866
4888
  to_expr
4867
4889
  end
4868
4890
 
4891
+ # Converts to a new dealy in fentoseconds.
4892
+ def fs
4893
+ return Delay.new(self,:fs)
4894
+ end
4895
+
4869
4896
  # Converts to a new delay in picoseconds.
4870
4897
  def ps
4871
4898
  return Delay.new(self,:ps)
@@ -7,7 +7,6 @@ module HDLRuby
7
7
  # General tools for handling HDLRuby objects
8
8
  #######################################################
9
9
 
10
-
11
10
  # Method and attribute for generating an absolute uniq name.
12
11
  # Such names cannot be used in HDLRuby::High code, but can be used
13
12
  # to generate such code.
@@ -63,7 +63,8 @@ module HDLRuby::High::Std
63
63
  end
64
64
 
65
65
  ## Class describing a digit display.
66
- DIGIT = Struct.new(:id, :size, :hread) do
66
+ # Need to know the data type since signed is supported.
67
+ DIGIT = Struct.new(:id, :size, :type, :hread) do
67
68
  def to_html
68
69
  return '<div class="digitset" id=' + self.id.to_s +
69
70
  ' data-width="' + self.size.to_s + '" data-value="0" >' +
@@ -559,6 +560,9 @@ Content-Type: text/html
559
560
  const cartouche = document.getElementById("cartouche");
560
561
  const panel = document.getElementById("panel");
561
562
 
563
+ // The current time stamp.
564
+ var time_stamp = 0;
565
+
562
566
  // The input and output elements' ids.
563
567
  const input_ids = [];
564
568
  const output_ids = [];
@@ -689,7 +693,7 @@ Content-Type: text/html
689
693
  function digitset_update(digitset,value) {
690
694
  // Update the digiset value.
691
695
  digitset.dataset.value = value;
692
- // Unsigned case.
696
+ // Update its display.
693
697
  const num = digitset.dataset.width;
694
698
  digitset.lastElementChild.innerHTML = String(value).padStart(num,"\u00A0");
695
699
  }
@@ -704,7 +708,9 @@ Content-Type: text/html
704
708
  }
705
709
 
706
710
  // Update an oscilloscope.
707
- function scope_update(scope,value) {
711
+ function scope_update(scope,value,new_time_stamp) {
712
+ // Compute the advance in time.
713
+ let diff_time_stamp = new_time_stamp - time_stamp;
708
714
  // Get the canvas.
709
715
  const canvas = scope.lastElementChild;
710
716
  // Shall we set up its size?
@@ -775,21 +781,21 @@ Content-Type: text/html
775
781
  // Draw a line to the new position.
776
782
  cxt.beginPath();
777
783
  cxt.moveTo(toPx(pos), toPy(previous));
778
- cxt.lineTo(toPx(pos+1), toPy(value));
784
+ cxt.lineTo(toPx(pos+diff_time_stamp), toPy(value));
779
785
  cxt.stroke();
780
786
  /* Update the values. */
781
787
  scope.dataset.previous = value;
782
- scope.dataset.pos = pos + 1;
788
+ scope.dataset.pos = pos + diff_time_stamp;
783
789
  }
784
790
  }
785
791
 
786
792
  // Update a general display element.
787
- function element_update(element,value) {
793
+ function element_update(element,value,new_time_stamp) {
788
794
  if(element.classList.contains('ledset')) { ledset_update(element,value); }
789
795
  if(element.classList.contains('digitset')){ digitset_update(element,value); }
790
796
  if(element.classList.contains('signedset')){signedset_update(element,value);}
791
797
  if(element.classList.contains('hexaset')) { hexaset_update(element,value); }
792
- if(element.classList.contains('scope')) { scope_update(element,value); }
798
+ if(element.classList.contains('scope')) { scope_update(element,value,new_time_stamp); }
793
799
  }
794
800
 
795
801
 
@@ -799,19 +805,25 @@ Content-Type: text/html
799
805
  xhttp.onreadystatechange = function() {
800
806
  // console.log("response=" + this.responseText);
801
807
  if (this.readyState == 4 && this.status == 200) {
802
- if (/[0-9]+:[0-9]/.test(this.responseText)) {
808
+ if (/^[0-9]+;[0-9]+:-?[0-9]/.test(this.responseText)) {
803
809
  // There is a real response.
804
810
  // Update the interface with the answer.
805
811
  const commands = this.responseText.split(';');
812
+ // Get the new time stamp.
813
+ let new_time_stamp = commands.shift();
814
+ // console.log("new_time_stamp=" + new_time_stamp);
815
+ // Process the other commands.
806
816
  for(command of commands) {
807
817
  const toks = command.split(':');
808
- element_update(document.getElementById(toks[0]),toks[1]);
818
+ element_update(document.getElementById(toks[0]),toks[1],new_time_stamp);
809
819
  }
820
+ // Update the time stamp
821
+ time_stamp = new_time_stamp
810
822
  }
811
823
  }
812
824
  };
813
825
  // Builds the action from the state of the input elements.
814
- act = '';
826
+ let act = '';
815
827
  for(id of input_ids) {
816
828
  act += id + ':' + document.getElementById(id).dataset.value + ';';
817
829
  }
@@ -824,8 +836,9 @@ Content-Type: text/html
824
836
  // First call of synchronisation.
825
837
  hruby_sync();
826
838
 
827
- // Then periodic synchronize.
828
- setInterval(function() { hruby_sync(); }, 100);
839
+ // Moved to the Ruby constructor to allow setting the time intervals.
840
+ // // Then periodic synchronize.
841
+ // setInterval(function() { hruby_sync(); }, 100);
829
842
 
830
843
  </script>
831
844
 
@@ -850,9 +863,14 @@ HTMLRESPONSE
850
863
 
851
864
  # Create a new board named +name+ accessible on HTTP port +http_port+
852
865
  # and whose content is describe in +hdlruby_block+.
853
- def initialize(name, http_port = 8000, &hdlruby_block)
866
+ def initialize(name, http_port: 8000, refresh_rate: 100,
867
+ &hdlruby_block)
854
868
  # Set the name.
855
869
  @name = name.to_s
870
+ # Set the refresh rate.
871
+ @refresh_rate = refresh_rate.to_i
872
+ # Tell the interface is to be built.
873
+ @first = true
856
874
  # Check and set the port.
857
875
  http_port = http_port.to_i
858
876
  if (@@http_ports.include?(http_port)) then
@@ -869,13 +887,17 @@ HTMLRESPONSE
869
887
  # Initialize the list of board elements to empty.
870
888
  @elements = []
871
889
  @out_elements = []
890
+ # Initialize the time stamp.
891
+ @time_stamp = 0
872
892
  # And build the board.
873
893
  # Create the namespace for the program.
874
894
  @namespace = Namespace.new(self)
875
895
  # Build the program object.
876
896
  High.space_push(@namespace)
877
897
  pr = nil
878
- High.top_user.instance_eval { pr = program(:ruby, @name.to_sym) {} }
898
+ High.top_user.instance_eval do
899
+ pr = program(:ruby, @name.to_sym) { }
900
+ end
879
901
  @program = pr
880
902
  # Fill it.
881
903
  High.top_user.instance_eval(&hdlruby_block)
@@ -936,6 +958,7 @@ HTMLRESPONSE
936
958
  # Createthe ui component.
937
959
  @elements << DIGIT.new(@elements.size,
938
960
  Math.log10(2**hport[1].type.width - 1).to_i + (sign ? 2 : 1),
961
+ hport[1].type,
939
962
  hport[0])
940
963
  @out_elements << @elements[-1]
941
964
  end
@@ -1018,9 +1041,13 @@ HTMLRESPONSE
1018
1041
  # Generate a response to a request to the server.
1019
1042
  def make_response(request)
1020
1043
  # puts "request=#{request}"
1021
- if (request.empty?) then
1044
+ if (@first) then
1045
+ @first = false
1022
1046
  # First or re-connection, generate the UI.
1023
- return UI_header + "\n<script>\n" +
1047
+ return UI_header +
1048
+ "\n<script>\n" +
1049
+ "// Then periodic synchronize.\n" +
1050
+ "setInterval(function() { hruby_sync(); }, #{@refresh_rate});\n" +
1024
1051
  "set_cartouche('#{@name}');\n" +
1025
1052
  @elements.map do |elem|
1026
1053
  "add_element('#{elem.to_html}');"
@@ -1030,11 +1057,13 @@ HTMLRESPONSE
1030
1057
  # This should be an AJAX request, process it.
1031
1058
  commands = request.split(";")
1032
1059
  commands.each do |command|
1060
+ next unless command.include?(":")
1033
1061
  id, val = command.split(":").map {|t| t.to_i}
1034
1062
  self.update_port(id,val)
1035
1063
  end
1036
1064
  # And generate the response: an update of each board output element.
1037
- return UI_response + @out_elements.each.map do |e|
1065
+ return UI_response + "#{@time_stamp};" +
1066
+ @out_elements.each.map do |e|
1038
1067
  # puts "resp=" + "#{e.id}:#{RubyHDL.send(e.hread)}"
1039
1068
  "#{e.id}:#{RubyHDL.send(e.hread)}"
1040
1069
  end.join(";")
@@ -1057,6 +1086,8 @@ HTMLRESPONSE
1057
1086
  session.print self.make_response(path[1..-1])
1058
1087
  # And tell the ui has been connected.
1059
1088
  @connected = true
1089
+ # Then advance the time stamp.
1090
+ @time_stamp += 1
1060
1091
  else
1061
1092
  session.print 'Connection Refuse'
1062
1093
  end
@@ -1072,8 +1103,11 @@ HTMLRESPONSE
1072
1103
 
1073
1104
  # Create a new board named +name+ accessible on HTTP port +http_port+
1074
1105
  # and whose content is describe in +block+.
1075
- def board(name, http_port = 8000, &block)
1076
- return Board.new(name,http_port,&block)
1106
+ def board(name, http_port: 8000, refresh_rate: 100, &block)
1107
+ # puts "name=#{name} http_port=#{http_port} refresh_rate=#{refresh_rate} block=#{block}"
1108
+ return Board.new(name,
1109
+ http_port: http_port, refresh_rate: refresh_rate,
1110
+ &block)
1077
1111
  end
1078
1112
 
1079
1113
  end
@@ -0,0 +1,39 @@
1
+ require "HDLRuby/verilog_hruby.rb"
2
+
3
+ parser = VerilogTools::Parser.new
4
+
5
+ ast = nil
6
+
7
+ HELP = "Usage: v2hdr <input verilog file name> <output HDLRuby file name>"
8
+
9
+ if ARGV[0] == "--help" then
10
+ puts HELP
11
+ exit
12
+ end
13
+
14
+ unless ARGV.size == 2 then
15
+ puts HELP
16
+ exit(1)
17
+ end
18
+
19
+ if ARGV[0] == ARGV[1] then
20
+ puts "Error: input and output files are identical."
21
+ exit(1)
22
+ end
23
+
24
+ begin
25
+ ast = parser.run(filename: ARGV[0], compress: true)
26
+ rescue => error
27
+ puts error
28
+ exit(1)
29
+ end
30
+
31
+ hdlruby = ""
32
+ begin
33
+ hdlruby = ast.to_HDLRuby
34
+ rescue => error
35
+ puts error
36
+ exit(1)
37
+ end
38
+
39
+ File.open(ARGV[1],"w") { |f| f.write(hdlruby) }