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 +4 -4
- data/README.md +64 -1
- data/exe/v2hdr +3 -0
- data/ext/hruby_sim/hruby_rcsim_build.c +1 -0
- data/lib/HDLRuby/hdr_samples/adder8.v +6 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_bench.rb +2 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_cpu_bench.rb +2 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_cpusim_bench.rb +2 -0
- data/lib/HDLRuby/hdr_samples/verilog_parser_bench.rb +36 -0
- data/lib/HDLRuby/hdr_samples/with_handshake.rb +2 -0
- data/lib/HDLRuby/hdr_samples/with_memory.rb +2 -0
- data/lib/HDLRuby/hdr_samples/with_nand_board.rb +1 -1
- data/lib/HDLRuby/hdr_samples/with_reconf.rb +1 -0
- data/lib/HDLRuby/hdr_samples/with_verilog.rb +24 -0
- data/lib/HDLRuby/hruby_high.rb +40 -13
- data/lib/HDLRuby/hruby_tools.rb +0 -1
- data/lib/HDLRuby/ui/hruby_board.rb +53 -19
- data/lib/HDLRuby/v2hdr.rb +39 -0
- data/lib/HDLRuby/verilog_hruby.rb +1153 -0
- data/lib/HDLRuby/verilog_parser.rb +7293 -0
- data/lib/HDLRuby/version.rb +1 -1
- data/tuto/tutorial_sw.md +73 -2
- metadata +11 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a22563a2a4dc9d6d53ba33618efa1c18d0cfb51336bb1308545b77f6673c7719
|
4
|
+
data.tar.gz: 4e3d7d9cf4fc513a42cdae82f51ef8e2dcc732f79076e23f14b50b8c1614191e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
@@ -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,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
|
@@ -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
|
data/lib/HDLRuby/hruby_high.rb
CHANGED
@@ -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
|
1239
|
-
|
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
|
1252
|
-
|
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
|
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
|
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
|
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)
|
data/lib/HDLRuby/hruby_tools.rb
CHANGED
@@ -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
|
-
|
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
|
-
//
|
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+
|
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 +
|
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 (
|
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
|
-
//
|
828
|
-
|
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
|
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
|
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 (
|
1044
|
+
if (@first) then
|
1045
|
+
@first = false
|
1022
1046
|
# First or re-connection, generate the UI.
|
1023
|
-
return UI_header +
|
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 + @
|
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
|
1076
|
-
|
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) }
|