HDLRuby 2.11.12 → 3.1.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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/README.html +3274 -0
  3. data/README.md +660 -128
  4. data/ext/hruby_sim/hruby_sim_calc.c +2 -0
  5. data/lib/HDLRuby/backend/hruby_allocator.rb +2 -2
  6. data/lib/HDLRuby/backend/hruby_c_allocator.rb +7 -7
  7. data/lib/HDLRuby/hdr_samples/constant_in_function.rb +2 -1
  8. data/lib/HDLRuby/hdr_samples/mei8_bench.rb +1 -1
  9. data/lib/HDLRuby/hdr_samples/with_bram.rb +3 -3
  10. data/lib/HDLRuby/hdr_samples/with_bram_frame_stack.rb +105 -0
  11. data/lib/HDLRuby/hdr_samples/with_bram_stack.rb +69 -0
  12. data/lib/HDLRuby/hdr_samples/with_ref_expr.rb +30 -0
  13. data/lib/HDLRuby/hdr_samples/with_sequencer.rb +185 -0
  14. data/lib/HDLRuby/hdr_samples/with_sequencer_deep.rb +91 -0
  15. data/lib/HDLRuby/hdr_samples/with_sequencer_enumerable.rb +439 -0
  16. data/lib/HDLRuby/hdr_samples/with_sequencer_enumerator.rb +89 -0
  17. data/lib/HDLRuby/hdr_samples/with_sequencer_func.rb +63 -0
  18. data/lib/HDLRuby/hdr_samples/with_sequencer_sync.rb +120 -0
  19. data/lib/HDLRuby/hdrcc.rb +16 -3
  20. data/lib/HDLRuby/hdrlib.rb +1 -1
  21. data/lib/HDLRuby/hruby_db.rb +2 -2
  22. data/lib/HDLRuby/hruby_high.rb +61 -25
  23. data/lib/HDLRuby/hruby_high_fullname.rb +3 -1
  24. data/lib/HDLRuby/hruby_low.rb +2 -2
  25. data/lib/HDLRuby/hruby_low2c.rb +58 -43
  26. data/lib/HDLRuby/hruby_low2hdr.rb +66 -40
  27. data/lib/HDLRuby/hruby_low2high.rb +86 -44
  28. data/lib/HDLRuby/hruby_low2seq.rb +26 -18
  29. data/lib/HDLRuby/hruby_low2sym.rb +14 -13
  30. data/lib/HDLRuby/hruby_low2vhd.rb +78 -43
  31. data/lib/HDLRuby/hruby_low_bool2select.rb +61 -46
  32. data/lib/HDLRuby/hruby_low_casts_without_expression.rb +56 -44
  33. data/lib/HDLRuby/hruby_low_cleanup.rb +18 -16
  34. data/lib/HDLRuby/hruby_low_fix_types.rb +64 -32
  35. data/lib/HDLRuby/hruby_low_mutable.rb +53 -118
  36. data/lib/HDLRuby/hruby_low_resolve.rb +26 -31
  37. data/lib/HDLRuby/hruby_low_with_bool.rb +33 -16
  38. data/lib/HDLRuby/hruby_low_with_port.rb +3 -3
  39. data/lib/HDLRuby/hruby_low_with_var.rb +23 -9
  40. data/lib/HDLRuby/hruby_low_without_concat.rb +19 -13
  41. data/lib/HDLRuby/hruby_low_without_namespace.rb +47 -32
  42. data/lib/HDLRuby/hruby_low_without_parinseq.rb +18 -12
  43. data/lib/HDLRuby/hruby_low_without_select.rb +36 -23
  44. data/lib/HDLRuby/hruby_low_without_subsignals.rb +79 -39
  45. data/lib/HDLRuby/hruby_rcsim.rb +79 -64
  46. data/lib/HDLRuby/hruby_rsim.rb +64 -15
  47. data/lib/HDLRuby/hruby_rsim_mute.rb +2 -3
  48. data/lib/HDLRuby/hruby_rsim_vcd.rb +28 -25
  49. data/lib/HDLRuby/hruby_types.rb +5 -5
  50. data/lib/HDLRuby/hruby_values.rb +19 -8
  51. data/lib/HDLRuby/hruby_verilog.rb +191 -65
  52. data/lib/HDLRuby/hruby_verilog_name.rb +49 -42
  53. data/lib/HDLRuby/soft/stacks.rb +219 -0
  54. data/lib/HDLRuby/std/bram.rb +9 -5
  55. data/lib/HDLRuby/std/clocks.rb +1 -1
  56. data/lib/HDLRuby/std/fsm.rb +39 -10
  57. data/lib/HDLRuby/std/sequencer.rb +2085 -0
  58. data/lib/HDLRuby/std/sequencer_func.rb +533 -0
  59. data/lib/HDLRuby/std/sequencer_sync.rb +400 -0
  60. data/lib/HDLRuby/std/std.rb +13 -0
  61. data/lib/HDLRuby/version.rb +1 -1
  62. data/tuto/adder_sat_flags_vcd.png +0 -0
  63. data/tuto/addsub_vcd.png +0 -0
  64. data/tuto/alu_vcd.png +0 -0
  65. data/tuto/bit_pong_vcd.png +0 -0
  66. data/tuto/checksum_vcd.png +0 -0
  67. data/tuto/circuit_hdr.odg +0 -0
  68. data/tuto/circuit_hdr.png +0 -0
  69. data/tuto/circuit_hie.odg +0 -0
  70. data/tuto/circuit_hie.png +0 -0
  71. data/tuto/circuit_view.odg +0 -0
  72. data/tuto/circuit_view.png +0 -0
  73. data/tuto/clock_counter_vcd.png +0 -0
  74. data/tuto/counter_ext_vcd.png +0 -0
  75. data/tuto/fact_vcd.png +0 -0
  76. data/tuto/hw_flow.odg +0 -0
  77. data/tuto/hw_flow.png +0 -0
  78. data/tuto/maxxer_vcd.png +0 -0
  79. data/tuto/pingpong0_vcd.png +0 -0
  80. data/tuto/pingpong1_vcd.png +0 -0
  81. data/tuto/pingpong2_vcd.png +0 -0
  82. data/tuto/ram_vcd.png +0 -0
  83. data/tuto/serializer_vcd.png +0 -0
  84. data/tuto/sw_flow.odg +0 -0
  85. data/tuto/sw_flow.png +0 -0
  86. data/tuto/the_counter_vcd.png +0 -0
  87. data/tuto/tutorial_sw.html +2359 -0
  88. data/tuto/tutorial_sw.md +2890 -0
  89. data/tuto/tutorial_sw.pdf +0 -0
  90. data/tuto/tutorial_sw_jp.md +417 -0
  91. metadata +46 -2
@@ -0,0 +1,219 @@
1
+ require 'std/bram'
2
+
3
+ module HDLRuby::High::Soft
4
+
5
+
6
+ # Declare the possible commands for the stack.
7
+ PUSH = 0 # Pushes the value of input din into the stack.
8
+ POP = 1 # Pops din values for the stack. If din is negative, allocates din elements on the stack.
9
+ READ = 2 # Read the value address din and output it on dout.
10
+ WRITE = 3 # Write the value at the top of the stack at address din.
11
+
12
+
13
+
14
+
15
+
16
+ # Describe a stack based on a BRAM (compatible with FPGA's)
17
+ # - 'widthD': data bit width
18
+ # - 'size' : the size of the stack
19
+ system :bram_stack do |widthD, size|
20
+ # Compute the address width.
21
+ widthA = (size-1).width
22
+
23
+ # Compute the bit width of the stack pointer register.
24
+ widthS = (size+1).width
25
+
26
+ # Declare the inputs and outputs.
27
+ input :clk, :rst, :ce
28
+ input :cmd
29
+ [widthD].input :din
30
+ [widthD].output :dout
31
+ output :empty, :full
32
+
33
+ # Declare the BRAM containing the stack data.
34
+ inner rwb: 1
35
+ [widthA].inner :addr
36
+ [widthD].inner :brin, :brout
37
+ bram(widthA,widthD).(:bramI).(clk,rwb,addr,brin,brout)
38
+
39
+ # Declare the stack pointer register and the top of stack value.
40
+ [widthS].inner sp: size
41
+ [widthD].inner :top
42
+
43
+ # Tells if the stack is empty or full.
44
+ empty <= (sp == size)
45
+ full <= (sp == 0)
46
+
47
+ # The output bus is the top of the stack.
48
+ dout <= top
49
+
50
+ # The clock process handling the access.
51
+ seq(clk.posedge) do
52
+ # By default, read before the top of the memory.
53
+ rwb <= 1
54
+ hif(rst) do
55
+ # sp is set to size (stack empty).
56
+ sp <= size
57
+ top <= 0
58
+ end
59
+ helsif(ce) do
60
+ # Now depending on the command.
61
+ hcase(cmd)
62
+ hwhen(PUSH) do
63
+ # Is the stack full?
64
+ hif(~full) do
65
+ # No, can push onto the stack.
66
+ # Update the top register.
67
+ top <= din
68
+ # Update the bram.
69
+ brin <= din
70
+ rwb <= 0
71
+ # Finally, decrease sp.
72
+ sp <= sp - 1
73
+ # The address is the top of the stack
74
+ addr <= sp
75
+ end
76
+ end
77
+ hwhen(POP) do
78
+ # Is the stack empty?
79
+ hif(~empty) do
80
+ # No, can pop from the stack.
81
+ # Update the top register.
82
+ top <= brout
83
+ # Finally, increase sp.
84
+ sp <= sp + 1
85
+ end
86
+ end
87
+ end
88
+ hif(~ce | cmd != PUSH) do
89
+ # By default the address is the top of the stack + 1
90
+ addr <= sp + 1
91
+ end
92
+ end
93
+
94
+ end
95
+
96
+
97
+ # Describe a frame stack based on a BRAM (compatible with FPGA's)
98
+ # - 'widthD': data bit width
99
+ # - 'size' : the size of the stack
100
+ # - 'depth' : the maximum number of frames.
101
+ system :bram_frame_stack do |widthD, size, depth|
102
+ # Compute the address width.
103
+ widthA = (size-1).width
104
+
105
+ # Compute the bit width of the frame pointers.
106
+ widthF = (size+1).width
107
+
108
+ # compute the bit width of the frame stack pointer.
109
+ widthS = (depth+1).width
110
+
111
+ # Create the type used for accessing the frame stack.
112
+ typedef(:locT) { { frame: bit[widthS], offset: bit[widthF] } }
113
+
114
+ # Declare the inputs and outputs.
115
+ input :clk, :rst, :ce
116
+ [2].input :cmd
117
+ locT.input :loc
118
+ [widthD].input :din
119
+ [widthD].output :dout
120
+ output :empty, :full
121
+
122
+ # Declare the frame index stac pointer.
123
+ [widthS].inner :sp
124
+
125
+ # Declare the frame index table.
126
+ bit[widthF][-depth].inner :indexes
127
+
128
+ # Declare the BRAM containing the frames data.
129
+ inner rwb: 1
130
+ [widthA].inner :addr
131
+ [widthD].inner :brin, :brout
132
+ bram(widthA,widthD).(:bramI).(clk,rwb,addr,brin,brout)
133
+
134
+ # Tells if the stack is empty or full.
135
+ empty <= (sp == depth)
136
+ full <= (sp == 0)
137
+
138
+ # The input data is always the input of the bram.
139
+ brin <= din
140
+
141
+ # The output is always the output of the bram.
142
+ dout <= brout
143
+
144
+ # The clock process handling the access.
145
+ seq(clk.posedge) do
146
+ # By default, read before the top of the memory.
147
+ rwb <= 1
148
+ hif(rst) do
149
+ # sp is set to depth (stack empty).
150
+ sp <= depth
151
+ end
152
+ helsif(ce) do
153
+ # Now depending on the command.
154
+ hcase(cmd)
155
+ hwhen(PUSH) do
156
+ # Is the stack full or is the frame to push empty?
157
+ hif(~(full | loc.offset == 0)) do
158
+ # No, we can proceed.
159
+ # Decrease sp.
160
+ sp <= sp - 1
161
+ # Adds the frame.
162
+ hif(~empty) do
163
+ indexes[sp] <= loc.offset + indexes[sp+1]
164
+ end
165
+ helse do
166
+ indexes[sp] <= loc.offset
167
+ end
168
+ end
169
+ end
170
+ hwhen(POP) do
171
+ # Is the stack empty?
172
+ hif(~empty) do
173
+ # No, can pop a frame from the stack.
174
+ # Increase sp.
175
+ sp <= sp + 1
176
+ end
177
+ end
178
+ hwhen(READ) do
179
+ # Read access, is the frame valid?
180
+ cur_frame = sp+loc.frame
181
+ hif (~(empty | cur_frame >= depth)) do
182
+ # The frame is valid. Is the offset valid?
183
+ addr_calc = indexes[cur_frame] - loc.offset - 1
184
+ hif ((cur_frame < depth-1) &
185
+ (addr_calc > indexes[cur_frame+1])) do
186
+ # Not the first frame and the address is valid.
187
+ addr <= addr_calc
188
+ end
189
+ helsif ((cur_frame == depth-1) &
190
+ (addr_calc + 1 > 0)) do
191
+ # The first frame and the address is valid.
192
+ addr <= addr_calc
193
+ end
194
+ end
195
+ end
196
+ hwhen(WRITE) do
197
+ # Write access, is the frame valid?
198
+ cur_frame = sp+loc.frame
199
+ hif (~(empty | cur_frame >= depth)) do
200
+ # The frame is valid. Is the offset valid?
201
+ addr_calc = indexes[cur_frame] - loc.offset - 1
202
+ hif ((cur_frame < depth-1) &
203
+ (addr_calc > indexes[cur_frame+1])) do
204
+ # Not the first frame and the address is valid.
205
+ addr <= addr_calc
206
+ rwb <= 0
207
+ end
208
+ helsif ((cur_frame == depth-1) &
209
+ (addr_calc + 1 > 0)) do
210
+ # The first frame and the address is valid.
211
+ addr <= addr_calc
212
+ rwb <= 0
213
+ end
214
+ end
215
+ end
216
+ end
217
+ end
218
+ end
219
+ end
@@ -3,18 +3,22 @@ module HDLRuby::High::Std
3
3
  # Describe a RAM compatibile with BRAM of FPGAs.
4
4
  # - 'widthA': address bit width
5
5
  # - 'widthD': data bit width
6
- system :bram do |widthA, widthD|
6
+ # - 'size': the size of the memory.
7
+ system :bram do |widthA, widthD, size = nil|
8
+ # Process size if required.
9
+ size = 2**widthA unless size
10
+ # puts "widthA=#{widthA} widthD=#{widthD} size=#{size}"
11
+
12
+ # Declares the io of the ram.
7
13
  input :clk, :rwb
8
14
  [widthA].input :addr
9
15
  [widthD].input :din
10
16
  [widthD].output :dout
11
17
 
12
- # puts "widthA=#{widthA} widthD=#{widthD}"
13
-
14
- bit[widthD][-2**widthA].inner mem: [ :"_b#{"0"*widthD}".to_value ] * 2**widthA
18
+ bit[widthD][-size].inner mem: [ :"_b#{"0"*widthD}".to_value ] * size
15
19
 
16
20
  par(clk.negedge) do
17
- hif(rwb == 1) { mem[addr] <= din }
21
+ hif(rwb == 0) { mem[addr] <= din }
18
22
  dout <= mem[addr]
19
23
  end
20
24
  end
@@ -135,8 +135,8 @@ module HDLRuby::High::Std
135
135
  end
136
136
 
137
137
 
138
- # Enhnace the events with multiply operator.
139
138
  class HDLRuby::High::Event
139
+ # Enhance the events with multiply operator.
140
140
 
141
141
  # Creates a new event activated every +times+ occurences of the
142
142
  # current event.
@@ -31,8 +31,10 @@ module HDLRuby::High::Std
31
31
 
32
32
  # Creates a new fsm type with +name+.
33
33
  # +options+ allows to specify the type of fsm:
34
- # synchronous (default) / asynchronous and
35
- # mono-front(default) / dual front
34
+ # - :sync, :synchronous : synchronous (default)
35
+ # - :async, :asynchronous : asynchronous
36
+ # - :dual : dual front
37
+ # - :seq, :blocking : use blocking assignments
36
38
  def initialize(name,*options)
37
39
  # Check and set the name
38
40
  @name = name.to_sym
@@ -40,6 +42,7 @@ module HDLRuby::High::Std
40
42
  @dual = false
41
43
  @type = :sync # By default, the FSM is synchronous.
42
44
  @sequential = true # By default, the default next state is the next one in the list.
45
+ @blocking = false # By default, use non-blocking assignments (par)
43
46
  options.each do |opt|
44
47
  case opt
45
48
  when :sync,:synchronous then
@@ -50,10 +53,23 @@ module HDLRuby::High::Std
50
53
  @dual = true
51
54
  when :static then
52
55
  @sequential = false
56
+ when :seq then
57
+ @blocking = true
58
+ when :blocking then
59
+ @blocking = true
53
60
  else
54
61
  raise AnyError, "Invalid option for a fsm: :#{type}"
55
62
  end
56
63
  end
64
+ if @blocking then
65
+ define_singleton_method(:fsm_block) do |*args,&ruby_block|
66
+ send(:seq,*args,&ruby_block)
67
+ end
68
+ else
69
+ define_singleton_method(:fsm_block) do |*args,&ruby_block|
70
+ send(:par,*args,&ruby_block)
71
+ end
72
+ end
57
73
 
58
74
  # Initialize the internals of the FSM.
59
75
 
@@ -127,7 +143,8 @@ module HDLRuby::High::Std
127
143
  # sub do
128
144
  HDLRuby::High.space_push(namespace)
129
145
  # Execute the instantiation block
130
- return_value = HDLRuby::High.top_user.instance_exec(&ruby_block)
146
+ # return_value = HDLRuby::High.top_user.instance_exec(&ruby_block)
147
+ return_value = HDLRuby::High.top_user.instance_exec(&ruby_block) if ruby_block
131
148
 
132
149
  # Expands the extra state processing so that al all the
133
150
  # parts of the state machine are in par (clear synthesis).
@@ -171,7 +188,8 @@ module HDLRuby::High::Std
171
188
  # Create the fsm code
172
189
 
173
190
  # Control part: update of the state.
174
- par(mk_ev.call) do
191
+ # par(mk_ev.call) do
192
+ fsm_block(mk_ev.call) do
175
193
  hif(mk_rst.call) do
176
194
  # Reset: current state is to put to 0.
177
195
  this.cur_state_sig <= 0
@@ -194,13 +212,18 @@ module HDLRuby::High::Std
194
212
  event = []
195
213
  end
196
214
  # The process
197
- par(*event) do
215
+ # par(*event) do
216
+ fsm_block(*event) do
198
217
  # The operative code.
199
218
  oper_code = proc do
200
219
  # The default code.
201
220
  default_codes.each(&:call)
202
221
  # Depending on the state.
203
- hcase(this.cur_state_sig)
222
+ if (type == :sync) then
223
+ hcase(this.next_state_sig)
224
+ else
225
+ hcase(this.cur_state_sig)
226
+ end
204
227
  states.each do |st|
205
228
  # Register the working state (for the gotos)
206
229
  this.work_state = st
@@ -241,8 +264,6 @@ module HDLRuby::High::Std
241
264
  st.gotos.each(&:call)
242
265
  else
243
266
  # No gotos, by default the next step is
244
- # current + 1
245
- # this.next_state_sig <= this.cur_state_sig + 1
246
267
  if sequential then
247
268
  this.next_state_sig <= this.cur_state_sig + 1
248
269
  end
@@ -251,6 +272,7 @@ module HDLRuby::High::Std
251
272
  end
252
273
  # By default set the next state to 0.
253
274
  helse do
275
+ # hprint("Unknow state case: ",this.cur_state_sig,"\n")
254
276
  this.next_state_sig <= 0
255
277
  end
256
278
 
@@ -260,7 +282,8 @@ module HDLRuby::High::Std
260
282
  event = mk_ev.call
261
283
  event = event.invert if @dual
262
284
  # The extra code.
263
- par(*event) do
285
+ # par(*event) do
286
+ fsm_block(*event) do
264
287
  # Build the extra synchronous part.
265
288
  sync_code = proc do
266
289
  hcase(this.cur_state_sig)
@@ -289,7 +312,8 @@ module HDLRuby::High::Std
289
312
 
290
313
  # Extra asynchronous operative part.
291
314
  if extra_asyncs.any? then
292
- par do
315
+ # par do
316
+ fsm_block do
293
317
  # Build the extra synchronous part.
294
318
  async_code = proc do
295
319
  hcase(this.cur_state_sig)
@@ -325,6 +349,11 @@ module HDLRuby::High::Std
325
349
 
326
350
 
327
351
  ## The interface for building the fsm
352
+
353
+ # Gets the current number of states.
354
+ def size
355
+ @states.size
356
+ end
328
357
 
329
358
  # Sets the event synchronizing the fsm.
330
359
  def for_event(event = nil,&ruby_block)