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 +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) }
|