HDLRuby 3.3.3 → 3.4.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: 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) }