HDLRuby 3.3.2 → 3.3.4
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|