HDLRuby 3.3.2 → 3.3.4
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/lib/HDLRuby/hdr_samples/with_board_sequencer.rb +69 -0
- data/lib/HDLRuby/hdr_samples/with_nand_board.rb +1 -1
- data/lib/HDLRuby/hruby_high.rb +56 -20
- data/lib/HDLRuby/hruby_low.rb +8 -2
- data/lib/HDLRuby/hruby_low_without_namespace.rb +11 -4
- data/lib/HDLRuby/hruby_low_without_subsignals.rb +1 -0
- data/lib/HDLRuby/ui/hruby_board.rb +53 -19
- data/lib/HDLRuby/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 160a8c6607e6dd20282a50fa26e0d472e055992ebce5f7cdf62d39e8c6bf7db5
|
4
|
+
data.tar.gz: 2c44f4edc3e4fdd76d64c2cb349f7083a255b68b1a18c6f41bef77c6d82138ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 234d4901bc7ae389c1e0893ad19a7a2aff93c2bc2851066a80ce07b778787a1fa25950af60dd30d32d7e77a8804f0ef4dbc2c43bdf2f026f7b725cd15a943c84
|
7
|
+
data.tar.gz: 774369895db9a9f30b7a85061aba5190d3e45f962f6ca28e2cee7fe77d7c02c049570dd6e2a0f730640f687bc8069f19e433ea6d4bb2f79b6cb7875a6ef423a4
|
@@ -0,0 +1,69 @@
|
|
1
|
+
|
2
|
+
# A benchmark for testing the use of a board model in conjuction
|
3
|
+
# with a sequencer implementing:
|
4
|
+
# * a simple adder whose input are set using slide switches, and
|
5
|
+
# whose output bits are showns on LEDs.
|
6
|
+
# * simple unsigned and signed counters whose values are shown using
|
7
|
+
# decimal or hexadecimal displays, and oscilloscopes.
|
8
|
+
system :with_board_sequencer do
|
9
|
+
inner :clk, :clk2
|
10
|
+
[8].inner clk_cnt: 0
|
11
|
+
inner rst: 0
|
12
|
+
[8].inner :sw_a, :sw_b
|
13
|
+
[9].inner :led_z
|
14
|
+
[16].inner counter: 0
|
15
|
+
[8].inner :counter8
|
16
|
+
signed[8].inner :scounter8
|
17
|
+
|
18
|
+
# Description of the board.
|
19
|
+
# It is updated at each rising edge of +clk2+.
|
20
|
+
board(:some_board) do
|
21
|
+
actport clk2.posedge
|
22
|
+
bt reset: rst
|
23
|
+
row
|
24
|
+
sw sw_a: sw_a
|
25
|
+
sw sw_b: sw_b
|
26
|
+
led led_z: led_z
|
27
|
+
row
|
28
|
+
digit cnt_d: counter
|
29
|
+
hexa cnt_h: counter
|
30
|
+
digit cnt_s: scounter8
|
31
|
+
row
|
32
|
+
scope scope: counter8
|
33
|
+
scope scope_s:scounter8
|
34
|
+
end
|
35
|
+
|
36
|
+
# The adder.
|
37
|
+
led_z <= sw_a.as(bit[9]) + sw_b
|
38
|
+
|
39
|
+
# The counters and the generation of +clk2+.
|
40
|
+
counter8 <= counter[7..0]
|
41
|
+
scounter8 <= counter[7..0]
|
42
|
+
|
43
|
+
seq(clk.posedge) do
|
44
|
+
clk_cnt <= clk_cnt + 1
|
45
|
+
hif(clk_cnt & 3 == 0) { clk2 <= ~clk2 }
|
46
|
+
end
|
47
|
+
|
48
|
+
sequencer(clk.posedge,rst) do
|
49
|
+
counter <= 0
|
50
|
+
sloop do
|
51
|
+
counter <= counter + 1
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
timed do
|
58
|
+
clk <= 0
|
59
|
+
clk2 <= 0
|
60
|
+
!10.ns
|
61
|
+
repeat(1000) do
|
62
|
+
clk <= 1
|
63
|
+
!10.ns
|
64
|
+
clk <= 0
|
65
|
+
!10.ns
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
data/lib/HDLRuby/hruby_high.rb
CHANGED
@@ -1529,15 +1529,19 @@ module HDLRuby::High
|
|
1529
1529
|
self.each_program { |prog| scopeL.add_program(prog.to_low) }
|
1530
1530
|
# Adds the code chunks.
|
1531
1531
|
self.each_code { |code| scopeL.add_code(code.to_low) }
|
1532
|
+
# Adds the behaviors.
|
1533
|
+
self.each_behavior { |behavior|
|
1534
|
+
scopeL.add_behavior(behavior.to_low)
|
1535
|
+
}
|
1532
1536
|
# Adds the connections.
|
1533
1537
|
self.each_connection { |connection|
|
1534
1538
|
# puts "connection=#{connection}"
|
1535
1539
|
scopeL.add_connection(connection.to_low)
|
1536
1540
|
}
|
1537
|
-
# Adds the behaviors.
|
1538
|
-
self.each_behavior { |behavior|
|
1539
|
-
|
1540
|
-
}
|
1541
|
+
# # Adds the behaviors.
|
1542
|
+
# self.each_behavior { |behavior|
|
1543
|
+
# scopeL.add_behavior(behavior.to_low)
|
1544
|
+
# }
|
1541
1545
|
end
|
1542
1546
|
|
1543
1547
|
# Converts the scope to HDLRuby::Low.
|
@@ -2247,17 +2251,21 @@ module HDLRuby::High
|
|
2247
2251
|
ruby_block = proc {} unless block_given?
|
2248
2252
|
if HDLRuby::High.in_system? then
|
2249
2253
|
define_singleton_method(name.to_sym) do |*args,&other_block|
|
2254
|
+
res = nil
|
2250
2255
|
sub(HDLRuby.uniq_name(name)) do
|
2251
|
-
HDLRuby::High.top_user.instance_exec(*args
|
2252
|
-
|
2256
|
+
res = HDLRuby::High.top_user.instance_exec(*args,
|
2257
|
+
*other_block, &ruby_block)
|
2253
2258
|
end
|
2259
|
+
res
|
2254
2260
|
end
|
2255
2261
|
else
|
2256
2262
|
define_method(name.to_sym) do |*args,&other_block|
|
2263
|
+
res = nil
|
2257
2264
|
sub(HDLRuby.uniq_name(name)) do
|
2258
|
-
HDLRuby::High.top_user.instance_exec(*args
|
2259
|
-
|
2265
|
+
res = HDLRuby::High.top_user.instance_exec(*args,
|
2266
|
+
*other_block, &ruby_block)
|
2260
2267
|
end
|
2268
|
+
res
|
2261
2269
|
end
|
2262
2270
|
end
|
2263
2271
|
end
|
@@ -3089,10 +3097,14 @@ module HDLRuby::High
|
|
3089
3097
|
end
|
3090
3098
|
|
3091
3099
|
|
3092
|
-
# Creates an access to elements of range +rng+ of the signal
|
3100
|
+
# Creates an access to elements of range +rng+ of the signal,
|
3101
|
+
# and set the type of elements as +typ+ if given.
|
3093
3102
|
#
|
3094
3103
|
# NOTE: +rng+ can be a single expression in which case it is an index.
|
3095
|
-
def [](rng)
|
3104
|
+
def [](typ,rng=nil)
|
3105
|
+
# Treat the number of arguments
|
3106
|
+
rng, typ = typ, nil unless rng
|
3107
|
+
# Process the range.
|
3096
3108
|
if rng.is_a?(::Range) then
|
3097
3109
|
first = rng.first
|
3098
3110
|
if (first.is_a?(::Integer)) then
|
@@ -3113,14 +3125,23 @@ module HDLRuby::High
|
|
3113
3125
|
end
|
3114
3126
|
if rng.is_a?(HDLRuby::Low::Expression) then
|
3115
3127
|
# Index case
|
3116
|
-
|
3128
|
+
if typ then
|
3129
|
+
return RefIndex.new(typ,self.to_expr,rng)
|
3130
|
+
else
|
3131
|
+
return RefIndex.new(self.type.base,self.to_expr,rng)
|
3132
|
+
end
|
3117
3133
|
else
|
3118
3134
|
# Range case, ensure it is made among expression.
|
3119
3135
|
first = rng.first.to_expr
|
3120
3136
|
last = rng.last.to_expr
|
3121
|
-
#
|
3122
|
-
|
3123
|
-
|
3137
|
+
# And create the reference.
|
3138
|
+
if typ then
|
3139
|
+
return RefRange.new(typ,
|
3140
|
+
self.to_expr,first..last)
|
3141
|
+
else
|
3142
|
+
return RefRange.new(self.type.slice(first..last),
|
3143
|
+
self.to_expr,first..last)
|
3144
|
+
end
|
3124
3145
|
end
|
3125
3146
|
end
|
3126
3147
|
|
@@ -3524,8 +3545,8 @@ module HDLRuby::High
|
|
3524
3545
|
if @base.is_a?(RefThis) &&
|
3525
3546
|
(@object.parent != High.top_user) &&
|
3526
3547
|
(@object.parent != High.cur_system) &&
|
3527
|
-
(@object.parent != High.cur_system.scope) &&
|
3528
|
-
(!@object.parent.name.empty?) then
|
3548
|
+
(@object.parent != High.cur_system.scope) then # &&
|
3549
|
+
# (!@object.parent.name.empty?) then
|
3529
3550
|
# Need to have a hierachical access.
|
3530
3551
|
if @object.respond_to?(:low_object) && @object.low_object then
|
3531
3552
|
# There where already a low object, create the ref from it.
|
@@ -4387,9 +4408,15 @@ module HDLRuby::High
|
|
4387
4408
|
end
|
4388
4409
|
|
4389
4410
|
# Converts the block to HDLRuby::Low.
|
4390
|
-
def to_low
|
4411
|
+
# def to_low
|
4412
|
+
def to_low(low_parent = nil)
|
4391
4413
|
# Create the resulting block
|
4392
4414
|
blockL = HDLRuby::Low::Block.new(self.mode,self.name)
|
4415
|
+
# Is there a low parent?
|
4416
|
+
if low_parent then
|
4417
|
+
# Set it straight away to have correct references.
|
4418
|
+
low_parent.block = blockL
|
4419
|
+
end
|
4393
4420
|
# # For debugging: set the source high object
|
4394
4421
|
# blockL.properties[:low2high] = self.hdr_id
|
4395
4422
|
# self.properties[:high2low] = blockL
|
@@ -4555,12 +4582,16 @@ module HDLRuby::High
|
|
4555
4582
|
|
4556
4583
|
# Converts the time behavior to HDLRuby::Low.
|
4557
4584
|
def to_low
|
4585
|
+
# Create an empty low behavior for the result.
|
4586
|
+
behaviorL = HDLRuby::Low::Behavior.new
|
4587
|
+
# Then fill it.
|
4558
4588
|
# Create the low level block.
|
4559
|
-
blockL = self.block.to_low
|
4589
|
+
# blockL = self.block.to_low
|
4590
|
+
blockL = self.block.to_low(behaviorL)
|
4560
4591
|
# Create the low level events.
|
4561
4592
|
eventLs = self.each_event.map { |event| event.to_low }
|
4562
|
-
# Create and return the resulting low level behavior.
|
4563
|
-
behaviorL = HDLRuby::Low::Behavior.new(blockL)
|
4593
|
+
# # Create and return the resulting low level behavior.
|
4594
|
+
# behaviorL = HDLRuby::Low::Behavior.new(blockL)
|
4564
4595
|
# # For debugging: set the source high object
|
4565
4596
|
# behaviorL.properties[:low2high] = self.hdr_id
|
4566
4597
|
# self.properties[:high2low] = behaviorL
|
@@ -4908,6 +4939,11 @@ module HDLRuby::High
|
|
4908
4939
|
def width
|
4909
4940
|
return self.bit_length
|
4910
4941
|
end
|
4942
|
+
|
4943
|
+
# Cast.
|
4944
|
+
def as(typ)
|
4945
|
+
return self.to_expr.as(typ)
|
4946
|
+
end
|
4911
4947
|
end
|
4912
4948
|
|
4913
4949
|
# Extends the Float class for computing the bit width and conversion
|
data/lib/HDLRuby/hruby_low.rb
CHANGED
@@ -74,6 +74,7 @@ module HDLRuby::Low
|
|
74
74
|
res = []
|
75
75
|
cur = self
|
76
76
|
while(cur) do
|
77
|
+
# puts "cur=#{cur} cur.parent=#{cur.parent}"
|
77
78
|
res << cur
|
78
79
|
cur = cur.parent
|
79
80
|
end
|
@@ -82,6 +83,7 @@ module HDLRuby::Low
|
|
82
83
|
|
83
84
|
# Get an absolute reference to the object.
|
84
85
|
def absolute_ref
|
86
|
+
# puts "absolute_ref for self=#{self}"
|
85
87
|
# Get the full hierarchy up to the object.
|
86
88
|
path = self.hierarchy
|
87
89
|
# Create the reference.
|
@@ -2379,7 +2381,7 @@ module HDLRuby::Low
|
|
2379
2381
|
attr_reader :block
|
2380
2382
|
|
2381
2383
|
# Creates a new behavior executing +block+.
|
2382
|
-
def initialize(block)
|
2384
|
+
def initialize(block = nil)
|
2383
2385
|
# Initialize the sensitivity list.
|
2384
2386
|
@events = []
|
2385
2387
|
# Check and set the block.
|
@@ -2417,7 +2419,7 @@ module HDLRuby::Low
|
|
2417
2419
|
# And set the block
|
2418
2420
|
@block = block
|
2419
2421
|
end
|
2420
|
-
private :block=
|
2422
|
+
# private :block=
|
2421
2423
|
|
2422
2424
|
# Comparison for hash: structural comparison.
|
2423
2425
|
def eql?(obj)
|
@@ -6078,6 +6080,10 @@ module HDLRuby::Low
|
|
6078
6080
|
raise AnyError, "Invalid class for a range last: #{last.class}."
|
6079
6081
|
end
|
6080
6082
|
@range = first..last
|
6083
|
+
# Clears the parent of first and last that is automatically added
|
6084
|
+
# by Ruby when creating a range.
|
6085
|
+
first.no_parent! if first.is_a?(Hparent)
|
6086
|
+
last.no_parent! if last.is_a?(Hparent)
|
6081
6087
|
# And set their parents.
|
6082
6088
|
first.parent = last.parent = self
|
6083
6089
|
end
|
@@ -88,6 +88,7 @@ module HDLRuby::Low
|
|
88
88
|
|
89
89
|
# Moves the declarations to the upper namespace.
|
90
90
|
def to_upper_space!
|
91
|
+
# puts "to_upper_space for scope=#{self}"
|
91
92
|
# First recurse.
|
92
93
|
# On the sub scopes.
|
93
94
|
self.each_scope(&:to_upper_space!)
|
@@ -472,6 +473,7 @@ module HDLRuby::Low
|
|
472
473
|
# Fix the references names using scopes given in +scopes + list (they
|
473
474
|
# are marked to be deleted).
|
474
475
|
def fix_scope_refnames!(scopes)
|
476
|
+
# puts "fix_scope_refnames for self=#{self}"
|
475
477
|
self.block.fix_scope_refnames!(scopes)
|
476
478
|
return self
|
477
479
|
end
|
@@ -834,10 +836,13 @@ module HDLRuby::Low
|
|
834
836
|
|
835
837
|
# Replaces recursively +former+ name by +nname+ until it is redeclared.
|
836
838
|
def replace_names!(former,nname)
|
839
|
+
# Already processed with fix_scope_refnames, so nothing to do
|
840
|
+
# here.
|
841
|
+
return
|
837
842
|
# Stop here if the name is redeclared.
|
838
|
-
return if self.each_inner.find {|inner| inner.name == former }
|
843
|
+
# return if self.each_inner.find {|inner| inner.name == former }
|
839
844
|
# Recurse on the sub scopes and behaviors.
|
840
|
-
replace_names_subs!(former,nname)
|
845
|
+
# replace_names_subs!(former,nname)
|
841
846
|
end
|
842
847
|
|
843
848
|
# Fix the references names using scopes given in +scopes + list (they
|
@@ -856,14 +861,16 @@ module HDLRuby::Low
|
|
856
861
|
# are marked to be deleted).
|
857
862
|
def fix_scope_refnames!(scopes)
|
858
863
|
return self unless self.ref.is_a?(RefName)
|
859
|
-
# puts "fix_scope_refnames! with self.name=#{name} and self.ref=#{self.ref}"
|
864
|
+
# puts "fix_scope_refnames! with self=#{self} self.name=#{name} and self.ref=#{self.ref}"
|
860
865
|
# Recurse on the ref.
|
861
|
-
self.set_ref!(self.ref.fix_scope_refnames!(scopes))
|
866
|
+
# self.set_ref!(self.ref.fix_scope_refnames!(scopes))
|
862
867
|
# Rename and curt the subref if referening to one of the scopes.
|
863
868
|
if scopes.find {|scope| scope.name == self.ref.name } then
|
864
869
|
self.ref.extend_name!(self)
|
870
|
+
# But need to remove the scope reference.
|
865
871
|
self.set_ref!(RefThis.new)
|
866
872
|
end
|
873
|
+
# puts "Now self=#{self} self.name=#{self.name} self.ref=#{self.ref}"
|
867
874
|
return self
|
868
875
|
end
|
869
876
|
end
|
@@ -243,6 +243,7 @@ module HDLRuby::Low
|
|
243
243
|
# Flatten a reference to a list of reference to leaf signals
|
244
244
|
# from signal +sig+ and add to result to +subrefs+
|
245
245
|
def flatten_to(sig,subrefs)
|
246
|
+
# puts "flatten_to with sig=#{sig}"
|
246
247
|
# Shall we decompose 2d vectors, and is the current signal
|
247
248
|
# for one of them?
|
248
249
|
if SystemT.decompose_vec2d? and sig.type.is_a?(TypeVector) and
|
@@ -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
|
data/lib/HDLRuby/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: HDLRuby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.3.
|
4
|
+
version: 3.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lovic Gauthier
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -186,6 +186,7 @@ files:
|
|
186
186
|
- lib/HDLRuby/hdr_samples/tuple.rb
|
187
187
|
- lib/HDLRuby/hdr_samples/type_minmax_bench.rb
|
188
188
|
- lib/HDLRuby/hdr_samples/with_board.rb
|
189
|
+
- lib/HDLRuby/hdr_samples/with_board_sequencer.rb
|
189
190
|
- lib/HDLRuby/hdr_samples/with_bram.rb
|
190
191
|
- lib/HDLRuby/hdr_samples/with_bram_frame_stack.rb
|
191
192
|
- lib/HDLRuby/hdr_samples/with_bram_stack.rb
|
@@ -475,7 +476,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
475
476
|
- !ruby/object:Gem::Version
|
476
477
|
version: '0'
|
477
478
|
requirements: []
|
478
|
-
rubygems_version: 3.5.
|
479
|
+
rubygems_version: 3.5.17
|
479
480
|
signing_key:
|
480
481
|
specification_version: 4
|
481
482
|
summary: HDLRuby is a library for describing and simulating digital electronic systems.
|