HDLRuby 3.5.0 → 3.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d4aecd7d8db226fd84031bd58762b442e4882a405a0898b8e87e3118c1ade8be
4
- data.tar.gz: 9808966d1decc2aae4c9c9b0423b0ab2fbb0543d44dd635b98789f1f07aaabcf
3
+ metadata.gz: 705f4b6e4835c910f62b0bced03175761ce62766d976c71123fa8756d7103714
4
+ data.tar.gz: e72f192e90d3aad1fa9819988251223108011b3bd9e931d3349ed1dd6d7413f7
5
5
  SHA512:
6
- metadata.gz: bebd8de17a2e35c7c926fe44feb6ad04cce0fa4558d7a96376125da7a2ec55bc0815a24b6f26936e6dc6ca99781867fd8737a2cf8a3a6c6430c8fdef53bd38fc
7
- data.tar.gz: 6ca378209e06714804526c8bff40845ccd7663ee4cff033044727035e16ff1ef86bc021342944b633d10cf7a599da4faff739b14b90b0ac5efdb329303e5c4f9
6
+ metadata.gz: d92f346ae79abb3a701784861d16c162a134a2f07477657e6976d569d591cbbb38f0bff20da5b2eeff6b32efdc170b539e34f807bba1d58ac770611b1582810f
7
+ data.tar.gz: d84037e56a7dacfc3e43a96a8885f1813b2a708be069a128878e3cf8a54602d3a28dd0db7d04fdde976bdde6880afd7b239bd356addd37bc0bcd05abab7a45ee
data/README.md CHANGED
@@ -17,6 +17,10 @@ hdrcc --get-tuto
17
17
 
18
18
  __What's new__
19
19
 
20
+ For HDLRuby version 3.6.0:
21
+
22
+ * Added a new element for the GUI board that allows to assign an expression to a signal on the fly while simulating.
23
+
20
24
  For HDLRuby version 3.5.0:
21
25
 
22
26
  * Added direct support for Verilog HDL files as input to 'hdrcc'.
@@ -2220,6 +2224,10 @@ The list of possible elements is as follows:
2220
2224
 
2221
2225
  * `bt`: represents a set of push buttons, their number is set to match the bit-width of the attached signal.
2222
2226
 
2227
+ * `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
+
2229
+ * `hook`: Attaches a signal to the board without displaying. It can be used as a variable in `text` expressions, similar to display objects.
2230
+
2223
2231
  * `led`: represents a set of LEDs, their number is set to match the bit-width of the attached signal.
2224
2232
 
2225
2233
  * `hexa`: represents a hexadecimal number display, its character width is set to match the width of the largest possible value of the attached signal.
@@ -10,6 +10,7 @@ system :with_board do
10
10
  inner rst: 0
11
11
  [8].inner :sw_a, :sw_b
12
12
  [9].inner :led_z
13
+ [8].inner :expr, :show
13
14
  [16].inner counter: 0
14
15
  [8].inner :counter8
15
16
  signed[8].inner :scounter8
@@ -19,11 +20,16 @@ system :with_board do
19
20
  board(:some_board) do
20
21
  actport clk2.posedge
21
22
  bt reset: rst
23
+ hook sw_ai: sw_a
24
+ hook sw_bi: sw_b
22
25
  row
23
26
  sw sw_a: sw_a
24
27
  sw sw_b: sw_b
25
28
  led led_z: led_z
26
29
  row
30
+ text expr: expr
31
+ digit show: show
32
+ row
27
33
  digit cnt_d: counter
28
34
  hexa cnt_h: counter
29
35
  digit cnt_s: scounter8
@@ -35,6 +41,9 @@ system :with_board do
35
41
  # The adder.
36
42
  led_z <= sw_a.as(bit[9]) + sw_b
37
43
 
44
+ # The text input and result.
45
+ show <= expr
46
+
38
47
  # The counters and the generation of +clk2+.
39
48
  counter8 <= counter[7..0]
40
49
  scounter8 <= counter[7..0]
@@ -52,7 +61,7 @@ system :with_board do
52
61
  clk <= 0
53
62
  clk2 <= 0
54
63
  !10.ns
55
- repeat(1000) do
64
+ repeat(10000) do
56
65
  clk <= 1
57
66
  !10.ns
58
67
  clk <= 0
@@ -1,6 +1,6 @@
1
1
  # An IC netlist mrdel and SVG-based vizualizer for HDLRuby
2
2
 
3
- require 'stackprof'
3
+ # require 'stackprof'
4
4
 
5
5
 
6
6
  module HDLRuby::Viz
@@ -20,6 +20,9 @@ module HDLRuby::High::Std
20
20
  include Hmissing
21
21
 
22
22
  attr_reader :namespace
23
+
24
+ ## Suffix telling a text is an expression to compute.
25
+ TO_COMPUTE = "="
23
26
 
24
27
  ## Class describing a row of slide switches.
25
28
  SW = Struct.new(:id, :size, :hwrite) do
@@ -50,6 +53,27 @@ module HDLRuby::High::Std
50
53
  end
51
54
  end
52
55
 
56
+ ## Class describing a text-based input.
57
+ TEXT = Struct.new(:id, :size, :hwrite) do
58
+ def to_html
59
+ return "<div class=\"textset\" id=\"#{self.id}\" data-value=\"0\">\\n" +
60
+ '<form onSubmit="text_submit(this); return false">\\n' +
61
+ '<span class="name">' + self.hwrite.to_s.chop + '</span>' +
62
+ '<span>&nbsp;&nbsp;</span>' +
63
+ '<input class="matrix_in" type="text" name="text" ' +
64
+ 'placeholder="Enter an expression">' +
65
+ "</form>\\n" +
66
+ "</div>\\n"
67
+ end
68
+ end
69
+
70
+ ## Class describing a hook (invisible display element).
71
+ HOOK = Struct.new(:id, :size, :hread) do
72
+ def to_html
73
+ return "<div id=\"#{self.id}\" data-value=\"0\"/>\\n"
74
+ end
75
+ end
76
+
53
77
  ## Class describing a row of LEDs.
54
78
  LED = Struct.new(:id, :size, :hread) do
55
79
  def to_html
@@ -476,6 +500,17 @@ Content-Type: text/html
476
500
  -webkit-shadow: -1px -1px 1px white, 1px 1px 1px #101010;
477
501
  }
478
502
 
503
+ .matrix_in {
504
+ font-size: 26px;
505
+ font-family: "Lucida Console", "Courier New", monospace;
506
+ color: #0B190B;
507
+ background-color: #9BBC0F;
508
+ border: solid 2px #505050;
509
+ box-shadow: -1px -1px 1px white, 1px 1px 1px #101010;
510
+ -moz-box-shadow: -1px -1px 1px white, 1px 1px 1px #101010;
511
+ -webkit-shadow: -1px -1px 1px white, 1px 1px 1px #101010;
512
+ }
513
+
479
514
  .bt {
480
515
  background-color: #ccc;
481
516
  border: solid 2px #505050;
@@ -586,7 +621,8 @@ Content-Type: text/html
586
621
  const element = prow.lastElementChild;
587
622
  // Depending of the kind of element.
588
623
  if (element.classList.contains('swset') ||
589
- element.classList.contains('btset')) {
624
+ element.classList.contains('btset') ||
625
+ element.classList.contains('textset') ) {
590
626
  // Input element.
591
627
  input_ids.push(element.id);
592
628
  } else {
@@ -660,6 +696,16 @@ Content-Type: text/html
660
696
  btset.dataset.value = btset.dataset.value & ~(1 << bit);
661
697
  }
662
698
 
699
+
700
+ // Handler of the text submit
701
+ function text_submit(form) {
702
+ // Get the et holding the form.
703
+ const textset = form.parentElement;
704
+ // Update the value, suffixed with #{TO_COMPUTE} for telling it is a
705
+ // text expression to compute.
706
+ textset.dataset.value = form.elements.text.value + "#{TO_COMPUTE}"
707
+ }
708
+
663
709
 
664
710
  // Switch a led on.
665
711
  function led_on(led) {
@@ -916,7 +962,7 @@ HTMLRESPONSE
916
962
  end
917
963
  # Create the HDLRuby program port.
918
964
  @program.outport(hport)
919
- # Create the ui component.
965
+ # Create the UI component.
920
966
  hport = hport.first
921
967
  @elements << SW.new(@elements.size,hport[1].type.width,:"#{hport[0]}=")
922
968
  end
@@ -929,10 +975,37 @@ HTMLRESPONSE
929
975
  # Create the HDLRuby program port.
930
976
  @program.outport(hport)
931
977
  hport = hport.first
932
- # Create the ui component.
978
+ # Create the UI component.
933
979
  @elements << BT.new(@elements.size,hport[1].type.width,:"#{hport[0]}=")
934
980
  end
935
981
 
982
+ # Add a new text input element attached to HDLRuby port +hport+
983
+ def text(hport)
984
+ if !hport.is_a?(Hash) or hport.size != 1 then
985
+ raise UIError.new("Malformed HDLRuby port declaration: #{hport}")
986
+ end
987
+ # Create the HDLRuby program port.
988
+ @program.outport(hport)
989
+ hport = hport.first
990
+ # Create the UI component.
991
+ @elements << TEXT.new(@elements.size,hport[1].type.width,:"#{hport[0]}=")
992
+ end
993
+
994
+ # Add a new hook element attached to HDLRuby port +hport+.
995
+ # NOTE: a hook element is not displayed on the board but can be used
996
+ # in the `text` expression.
997
+ def hook(hport)
998
+ if !hport.is_a?(Hash) or hport.size != 1 then
999
+ raise UIError.new("Malformed HDLRuby port declaration: #{hport}")
1000
+ end
1001
+ # Create the HDLRuby program port.
1002
+ @program.inport(hport)
1003
+ hport = hport.first
1004
+ # Createthe UI component (invisible)
1005
+ @elements << HOOK.new(@elements.size,hport[1].type.width,hport[0])
1006
+ @out_elements << @elements[-1]
1007
+ end
1008
+
936
1009
  # Add a new LED element attached to HDLRuby port +hport+.
937
1010
  def led(hport)
938
1011
  if !hport.is_a?(Hash) or hport.size != 1 then
@@ -941,7 +1014,7 @@ HTMLRESPONSE
941
1014
  # Create the HDLRuby program port.
942
1015
  @program.inport(hport)
943
1016
  hport = hport.first
944
- # Createthe ui component.
1017
+ # Createthe UI component.
945
1018
  @elements << LED.new(@elements.size,hport[1].type.width,hport[0])
946
1019
  @out_elements << @elements[-1]
947
1020
  end
@@ -1032,6 +1105,35 @@ HTMLRESPONSE
1032
1105
  end
1033
1106
 
1034
1107
 
1108
+ # Compute a value.
1109
+ def compute(val)
1110
+ # Preprocess val to match Ruby syntax.
1111
+ val = "0" unless val
1112
+ val = val.gsub("%20"," ")
1113
+ # 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
+ val = val.gsub(/([\._a-zA-Z0-9]+)/) do |str|
1118
+ if str[0] >= "a" && str[0] <= "z" then
1119
+ # Variable identifier, process it if recognized.
1120
+ RubyHDL.send(Regexp.last_match[1]).to_s rescue str
1121
+ else
1122
+ # Other token leave it as is.
1123
+ str
1124
+ end
1125
+ end
1126
+ # Compute.
1127
+ res = 0
1128
+ safe = $SAFE
1129
+ begin
1130
+ $SAFE = 2
1131
+ res = eval(val).to_i
1132
+ rescue SyntaxError => se
1133
+ end
1134
+ $SAFE = safe
1135
+ return res
1136
+ end
1035
1137
 
1036
1138
  # Update port number +id+ with value +val+.
1037
1139
  def update_port(id,val)
@@ -1057,8 +1159,17 @@ HTMLRESPONSE
1057
1159
  # This should be an AJAX request, process it.
1058
1160
  commands = request.split(";")
1059
1161
  commands.each do |command|
1060
- next unless command.include?(":")
1061
- id, val = command.split(":").map {|t| t.to_i}
1162
+ # next unless command.include?(":")
1163
+ # id, val = command.split(":").map {|t| t.to_i}
1164
+ id, val = command.split(":",2)
1165
+ next unless val
1166
+ id = id.to_i
1167
+ if val[-1] == "=" then
1168
+ # This is an expression to compute.
1169
+ val = self.compute(val.chop)
1170
+ else
1171
+ val = val.to_i
1172
+ end
1062
1173
  self.update_port(id,val)
1063
1174
  end
1064
1175
  # And generate the response: an update of each board output element.
@@ -1,3 +1,3 @@
1
1
  module HDLRuby
2
- VERSION = "3.5.0"
2
+ VERSION = "3.6.0"
3
3
  end
@@ -3047,6 +3047,10 @@ 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>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>
3051
+ </li>
3052
+ <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
+ </li>
3050
3054
  <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>
3051
3055
  </li>
3052
3056
  <li><p><code>digit</code>: represents a decimal number display, its character width is set to match the width of the largest possible positive or the smallest possible negative value of the attached signal.</p>
data/tuto/tutorial_sw.md CHANGED
@@ -3750,6 +3750,10 @@ 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
+ * `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.
3754
+
3755
+ * `hook`: Attaches a signal to the board without displaying. It can be used as a variable in `text` expressions, similar to display objects.
3756
+
3753
3757
  * `hexa`: represents a hexadecimal number display, its character width is set to match the width of the largest possible value of the attached signal.
3754
3758
 
3755
3759
  * `digit`: represents a decimal number display, its character width is set to match the width of the largest possible positive or the smallest possible negative value of the attached signal.
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.5.0
4
+ version: 3.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lovic Gauthier
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2024-12-23 00:00:00.000000000 Z
10
+ date: 2025-01-05 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: bundler
@@ -488,7 +488,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
488
488
  - !ruby/object:Gem::Version
489
489
  version: '0'
490
490
  requirements: []
491
- rubygems_version: 3.6.0
491
+ rubygems_version: 3.6.2
492
492
  specification_version: 4
493
493
  summary: HDLRuby is a library for describing and simulating digital electronic systems.
494
494
  test_files: []