HDLRuby 3.6.0 → 3.6.2
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 +7 -3
- data/lib/HDLRuby/hdr_samples/with_board.rb +11 -1
- data/lib/HDLRuby/ui/hruby_board.rb +122 -9
- data/lib/HDLRuby/version.rb +1 -1
- data/tuto/tutorial_sw.html +4 -2
- data/tuto/tutorial_sw.md +4 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 70c4b4aec90e44d8229a4f13990112c3599b7104e3a867cf87741b2d1e4ff246
|
4
|
+
data.tar.gz: 10c6957977c1df45cae0f270dd27db75824a92e51dc508b5ffa600ce4654f1a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56b18d61f3945edaaff50244ecb8ae69fa5c29058942c456ca377eb54da83bb64677004dae4047a8f2aae9b4dd2fa57972c8cf6f0fc497bfe9785c447466cfaa
|
7
|
+
data.tar.gz: 81e58ca1a9ae1b6ba038c5a43c857ebff9e93dd2627befe89706c0200389a5ee18e1d77261e21d13f291b547dc4cf5be2e9024d75d524e2d54d26c37f7943679
|
data/README.md
CHANGED
@@ -17,10 +17,12 @@ hdrcc --get-tuto
|
|
17
17
|
|
18
18
|
__What's new__
|
19
19
|
|
20
|
-
For HDLRuby version 3.6.
|
20
|
+
For HDLRuby version 3.6.x:
|
21
21
|
|
22
22
|
* Added a new element for the GUI board that allows to assign an expression to a signal on the fly while simulating.
|
23
23
|
|
24
|
+
* Added a new slider element for the GUI board (from 3.6.1).
|
25
|
+
|
24
26
|
For HDLRuby version 3.5.0:
|
25
27
|
|
26
28
|
* Added direct support for Verilog HDL files as input to 'hdrcc'.
|
@@ -2224,9 +2226,11 @@ The list of possible elements is as follows:
|
|
2224
2226
|
|
2225
2227
|
* `bt`: represents a set of push buttons, their number is set to match the bit-width of the attached signal.
|
2226
2228
|
|
2227
|
-
* `
|
2229
|
+
* `slider`: represents an horizontal slider.
|
2230
|
+
|
2231
|
+
* `text`: represents a text input box whose content is interpreted as an expression. The syntax of the expression follows Ruby, and the available variables include the board's display objects. For example, if a set of LEDs is named `leds`, it will be accessible as a variable.
|
2228
2232
|
|
2229
|
-
* `hook`:
|
2233
|
+
* `hook`: attaches a signal to the board without displaying. It can be used as a variable in `text` expressions, similar to display objects.
|
2230
2234
|
|
2231
2235
|
* `led`: represents a set of LEDs, their number is set to match the bit-width of the attached signal.
|
2232
2236
|
|
@@ -15,6 +15,12 @@ system :with_board do
|
|
15
15
|
[8].inner :counter8
|
16
16
|
signed[8].inner :scounter8
|
17
17
|
|
18
|
+
bit[8][-256].inner :mem
|
19
|
+
[8].inner :addr, :din, :dout
|
20
|
+
|
21
|
+
mem[addr] <= din
|
22
|
+
dout <= mem[addr]
|
23
|
+
|
18
24
|
# Description of the board.
|
19
25
|
# It is updated at each rising edge of +clk2+.
|
20
26
|
board(:some_board) do
|
@@ -24,12 +30,16 @@ system :with_board do
|
|
24
30
|
hook sw_bi: sw_b
|
25
31
|
row
|
26
32
|
sw sw_a: sw_a
|
27
|
-
|
33
|
+
slider sw_b: sw_b
|
28
34
|
led led_z: led_z
|
29
35
|
row
|
30
36
|
text expr: expr
|
31
37
|
digit show: show
|
32
38
|
row
|
39
|
+
text addr: addr
|
40
|
+
hexa dout: dout
|
41
|
+
text din: din
|
42
|
+
row
|
33
43
|
digit cnt_d: counter
|
34
44
|
hexa cnt_h: counter
|
35
45
|
digit cnt_s: scounter8
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'socket'
|
2
|
+
require 'io/console'
|
2
3
|
|
3
4
|
require 'rubyHDL'
|
4
5
|
|
@@ -34,7 +35,7 @@ module HDLRuby::High::Std
|
|
34
35
|
'<label class="sw"><input type="checkbox" data-bit="' +
|
35
36
|
(self.size-i-1).to_s + '" ' +
|
36
37
|
'onchange="sw_change(this)">' +
|
37
|
-
'<span class="
|
38
|
+
'<span class="sw_slider"></span></label>\n'
|
38
39
|
end.join + "</div>\\n"
|
39
40
|
end
|
40
41
|
end
|
@@ -52,6 +53,22 @@ module HDLRuby::High::Std
|
|
52
53
|
end.join + "</div>\\n"
|
53
54
|
end
|
54
55
|
end
|
56
|
+
|
57
|
+
## Class describing an "analog" slide switch.
|
58
|
+
SLIDER = Struct.new(:id, :min, :max, :hwrite) do
|
59
|
+
def to_html
|
60
|
+
# Prepare the min, max and blank strings.
|
61
|
+
min = self.min.to_s
|
62
|
+
max = self.max.to_s
|
63
|
+
return "<div class=\"sliderset\" id=\"#{self.id}\" data-value=\"0\">\\n" +
|
64
|
+
'<span class="name">' + self.hwrite.to_s.chop + '</span>' +
|
65
|
+
'<span> </span>' +
|
66
|
+
'<input type="range" min="' + min + '" max="' + max +
|
67
|
+
'" value="' + min + '" ' +
|
68
|
+
'class="slider" oninput="slider_change(this)">' +
|
69
|
+
"</div>\\n"
|
70
|
+
end
|
71
|
+
end
|
55
72
|
|
56
73
|
## Class describing a text-based input.
|
57
74
|
TEXT = Struct.new(:id, :size, :hwrite) do
|
@@ -272,6 +289,16 @@ Content-Type: text/html
|
|
272
289
|
height: 40px;
|
273
290
|
}
|
274
291
|
|
292
|
+
.sliderset {
|
293
|
+
display: flex;
|
294
|
+
flex-direction: row;
|
295
|
+
justify-content: center;
|
296
|
+
align-items: center;
|
297
|
+
margin-left: 8px;
|
298
|
+
margin-right: 8px;
|
299
|
+
height: 40px;
|
300
|
+
}
|
301
|
+
|
275
302
|
.ledset {
|
276
303
|
display: flex;
|
277
304
|
flex-direction: row;
|
@@ -454,7 +481,7 @@ Content-Type: text/html
|
|
454
481
|
height: 0;
|
455
482
|
}
|
456
483
|
|
457
|
-
.
|
484
|
+
.sw_slider {
|
458
485
|
position: absolute;
|
459
486
|
cursor: pointer;
|
460
487
|
top: 0;
|
@@ -467,7 +494,7 @@ Content-Type: text/html
|
|
467
494
|
border: solid 2px #505050;
|
468
495
|
}
|
469
496
|
|
470
|
-
.
|
497
|
+
.sw_slider:before {
|
471
498
|
position: absolute;
|
472
499
|
content: "";
|
473
500
|
height: 16px;
|
@@ -479,16 +506,48 @@ Content-Type: text/html
|
|
479
506
|
transition: .2s;
|
480
507
|
}
|
481
508
|
|
482
|
-
input:checked + .
|
509
|
+
input:checked + .sw_slider {
|
483
510
|
background-color: yellow;
|
484
511
|
}
|
485
512
|
|
486
|
-
input:checked + .
|
513
|
+
input:checked + .sw_slider:before {
|
487
514
|
-webkit-transform: translateY(-16px);
|
488
515
|
-ms-transform: translateY(-16px);
|
489
516
|
transform: translateY(-16px);
|
490
517
|
}
|
491
518
|
|
519
|
+
.slider {
|
520
|
+
-webkit-appearance: none;
|
521
|
+
width: 100%;
|
522
|
+
height: 25px;
|
523
|
+
background-color: #ccc;
|
524
|
+
-webkit-transition: .2s;
|
525
|
+
transition: .2s;
|
526
|
+
border: solid 2px #505050;
|
527
|
+
margin: 2px;
|
528
|
+
box-shadow: -1px -1px 1px white, 1px 1px 1px #101010;
|
529
|
+
-moz-box-shadow: -1px -1px 1px white, 1px 1px 1px #101010;
|
530
|
+
-webkit-shadow: -1px -1px 1px white, 1px 1px 1px #101010;
|
531
|
+
}
|
532
|
+
|
533
|
+
.slider::-webkit-slider-thumb {
|
534
|
+
-webkit-appearance: none;
|
535
|
+
appearance: none;
|
536
|
+
width: 25px;
|
537
|
+
height: 25px;
|
538
|
+
background: black;
|
539
|
+
border: solid 2px #505050;
|
540
|
+
cursor: pointer;
|
541
|
+
}
|
542
|
+
|
543
|
+
.slider::-moz-range-thumb {
|
544
|
+
width: 25px;
|
545
|
+
height: 25px;
|
546
|
+
background: black;
|
547
|
+
border: solid 2px #505050;
|
548
|
+
cursor: pointer;
|
549
|
+
}
|
550
|
+
|
492
551
|
.matrix {
|
493
552
|
font-size: 26px;
|
494
553
|
font-family: "Lucida Console", "Courier New", monospace;
|
@@ -622,6 +681,7 @@ Content-Type: text/html
|
|
622
681
|
// Depending of the kind of element.
|
623
682
|
if (element.classList.contains('swset') ||
|
624
683
|
element.classList.contains('btset') ||
|
684
|
+
element.classList.contains('sliderset') ||
|
625
685
|
element.classList.contains('textset') ) {
|
626
686
|
// Input element.
|
627
687
|
input_ids.push(element.id);
|
@@ -664,6 +724,14 @@ Content-Type: text/html
|
|
664
724
|
// console.log("sw value=" + swset.dataset.value);
|
665
725
|
}
|
666
726
|
|
727
|
+
// Handler of slider change.
|
728
|
+
function slider_change(slider) {
|
729
|
+
// Get the set holding slider.
|
730
|
+
const sliderset = slider.parentElement;
|
731
|
+
sliderset.dataset.value = slider.value;
|
732
|
+
// console.log("slider value=" + sliderset.dataset.value);
|
733
|
+
}
|
734
|
+
|
667
735
|
// Set the aspect of a button to clicked.
|
668
736
|
function bt_on(bt) {
|
669
737
|
bt.innerHTML = '<i class="bt_on"></i>';
|
@@ -927,6 +995,31 @@ HTMLRESPONSE
|
|
927
995
|
@@http_ports << @http_port
|
928
996
|
# Create the server
|
929
997
|
@server = TCPServer.new(@http_port)
|
998
|
+
|
999
|
+
browse = Thread.new do
|
1000
|
+
url = "http://localhost:#{@http_port}"
|
1001
|
+
# Shall we try to open a page automatically:
|
1002
|
+
puts "Shall I open a new page on your browser for the GUI? [y/n]"
|
1003
|
+
ch = ""
|
1004
|
+
ch = STDIN.getch while !(ch =~ /[YyNn]/)
|
1005
|
+
unless ch =~ /[Yy]/ then
|
1006
|
+
puts "Please open the following url manually: #{url}"
|
1007
|
+
browse.kill
|
1008
|
+
end
|
1009
|
+
# Open the page if possible.
|
1010
|
+
sleep(0.2)
|
1011
|
+
case RUBY_PLATFORM
|
1012
|
+
when /darwin/
|
1013
|
+
Kernel.system("open",url)
|
1014
|
+
when /linux/
|
1015
|
+
Kernel.system("xdg",url)
|
1016
|
+
when /mingw|mswin/
|
1017
|
+
Kernel.system("start",url)
|
1018
|
+
else
|
1019
|
+
puts "Please open the following url on your browser: #{url}"
|
1020
|
+
end
|
1021
|
+
end
|
1022
|
+
|
930
1023
|
# Create the running function.
|
931
1024
|
this = self
|
932
1025
|
Kernel.define_method(@name.to_sym) { this.run }
|
@@ -979,6 +1072,27 @@ HTMLRESPONSE
|
|
979
1072
|
@elements << BT.new(@elements.size,hport[1].type.width,:"#{hport[0]}=")
|
980
1073
|
end
|
981
1074
|
|
1075
|
+
# Add a new slider element attached to HDLRuby port +hport+
|
1076
|
+
def slider(hport)
|
1077
|
+
if !hport.is_a?(Hash) or hport.size != 1 then
|
1078
|
+
raise UIError.new("Malformed HDLRuby port declaration: #{hport}")
|
1079
|
+
end
|
1080
|
+
# Create the HDLRuby program port.
|
1081
|
+
@program.outport(hport)
|
1082
|
+
hport = hport.first
|
1083
|
+
# Compute the min and max values.
|
1084
|
+
width = hport[1].type.width
|
1085
|
+
if hport[1].type.signed? then
|
1086
|
+
min = -2**(width-1)
|
1087
|
+
max = 2**(width-1) - 1
|
1088
|
+
else
|
1089
|
+
min = 0
|
1090
|
+
max = 2**width - 1
|
1091
|
+
end
|
1092
|
+
# Create the UI component.
|
1093
|
+
@elements << SLIDER.new(@elements.size,min,max,:"#{hport[0]}=")
|
1094
|
+
end
|
1095
|
+
|
982
1096
|
# Add a new text input element attached to HDLRuby port +hport+
|
983
1097
|
def text(hport)
|
984
1098
|
if !hport.is_a?(Hash) or hport.size != 1 then
|
@@ -1111,9 +1225,6 @@ HTMLRESPONSE
|
|
1111
1225
|
val = "0" unless val
|
1112
1226
|
val = val.gsub("%20"," ")
|
1113
1227
|
# Replace the names by the corresponding ports read result.
|
1114
|
-
# val = val.gsub(/([^0-9\.A-Z][_a-z][_a-zA-Z0-9]*)/) do |str|
|
1115
|
-
# RubyHDL.send(Regexp.last_match[1]).to_s rescue 0
|
1116
|
-
# end
|
1117
1228
|
val = val.gsub(/([\._a-zA-Z0-9]+)/) do |str|
|
1118
1229
|
if str[0] >= "a" && str[0] <= "z" then
|
1119
1230
|
# Variable identifier, process it if recognized.
|
@@ -1130,6 +1241,7 @@ HTMLRESPONSE
|
|
1130
1241
|
$SAFE = 2
|
1131
1242
|
res = eval(val).to_i
|
1132
1243
|
rescue SyntaxError => se
|
1244
|
+
rescue StandardError => se
|
1133
1245
|
end
|
1134
1246
|
$SAFE = safe
|
1135
1247
|
return res
|
@@ -1183,7 +1295,7 @@ HTMLRESPONSE
|
|
1183
1295
|
|
1184
1296
|
# Start the ui.
|
1185
1297
|
def run
|
1186
|
-
# At first the
|
1298
|
+
# At first the ui is not running.
|
1187
1299
|
@connected = false
|
1188
1300
|
# Create the ui thread.
|
1189
1301
|
@thread = Thread.new do
|
@@ -1209,6 +1321,7 @@ HTMLRESPONSE
|
|
1209
1321
|
# Wait for a first connection.
|
1210
1322
|
sleep(0.1) while(!@connected)
|
1211
1323
|
end
|
1324
|
+
|
1212
1325
|
end
|
1213
1326
|
|
1214
1327
|
|
data/lib/HDLRuby/version.rb
CHANGED
data/tuto/tutorial_sw.html
CHANGED
@@ -3047,9 +3047,11 @@ end
|
|
3047
3047
|
</li>
|
3048
3048
|
<li><p><code>led</code>: represents a set of LEDs, their number is set to match the bit-width of the attached signal.</p>
|
3049
3049
|
</li>
|
3050
|
-
<li><p><code>
|
3050
|
+
<li><p><code>slider</code>: represents an horizontal slider.</p>
|
3051
3051
|
</li>
|
3052
|
-
<li><p><code>
|
3052
|
+
<li><p><code>text</code>: represents a text input box whose content is interpreted as an expression. The syntax of the expression follows Ruby, and the available variables include the board's display objects. For example, if a set of LEDs is named <code>leds</code>, it will be accessible as a variable.</p>
|
3053
|
+
</li>
|
3054
|
+
<li><p><code>hook</code>: attaches a signal to the board without displaying. It can be used as a variable in <code>text</code> expressions, similar to display objects.</p>
|
3053
3055
|
</li>
|
3054
3056
|
<li><p><code>hexa</code>: represents a hexadecimal number display, its character width is set to match the width of the largest possible value of the attached signal.</p>
|
3055
3057
|
</li>
|
data/tuto/tutorial_sw.md
CHANGED
@@ -3750,9 +3750,11 @@ And the comprise the following:
|
|
3750
3750
|
|
3751
3751
|
* `led`: represents a set of LEDs, their number is set to match the bit-width of the attached signal.
|
3752
3752
|
|
3753
|
-
* `
|
3753
|
+
* `slider`: represents an horizontal slider.
|
3754
3754
|
|
3755
|
-
* `
|
3755
|
+
* `text`: represents a text input box whose content is interpreted as an expression. The syntax of the expression follows Ruby, and the available variables include the board's display objects. For example, if a set of LEDs is named `leds`, it will be accessible as a variable.
|
3756
|
+
|
3757
|
+
* `hook`: attaches a signal to the board without displaying. It can be used as a variable in `text` expressions, similar to display objects.
|
3756
3758
|
|
3757
3759
|
* `hexa`: represents a hexadecimal number display, its character width is set to match the width of the largest possible value of the attached signal.
|
3758
3760
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: HDLRuby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.6.
|
4
|
+
version: 3.6.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lovic Gauthier
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-01-
|
10
|
+
date: 2025-01-14 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: bundler
|