HDLRuby 2.11.12 → 3.0.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 (86) hide show
  1. checksums.yaml +4 -4
  2. data/README.html +3274 -0
  3. data/README.md +556 -84
  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/mei8_bench.rb +1 -1
  8. data/lib/HDLRuby/hdr_samples/with_bram.rb +3 -3
  9. data/lib/HDLRuby/hdr_samples/with_bram_frame_stack.rb +105 -0
  10. data/lib/HDLRuby/hdr_samples/with_bram_stack.rb +69 -0
  11. data/lib/HDLRuby/hdr_samples/with_register_stack.rb +150 -0
  12. data/lib/HDLRuby/hdr_samples/with_sequencer.rb +190 -0
  13. data/lib/HDLRuby/hdr_samples/with_sequencer_deep.rb +91 -0
  14. data/lib/HDLRuby/hdr_samples/with_sequencer_enumerable.rb +405 -0
  15. data/lib/HDLRuby/hdr_samples/with_sequencer_enumerator.rb +89 -0
  16. data/lib/HDLRuby/hdr_samples/with_sequencer_sync.rb +120 -0
  17. data/lib/HDLRuby/hdrcc.rb +15 -2
  18. data/lib/HDLRuby/hdrlib.rb +1 -1
  19. data/lib/HDLRuby/hruby_db.rb +2 -2
  20. data/lib/HDLRuby/hruby_high.rb +38 -20
  21. data/lib/HDLRuby/hruby_high_fullname.rb +3 -1
  22. data/lib/HDLRuby/hruby_low.rb +2 -2
  23. data/lib/HDLRuby/hruby_low2c.rb +58 -43
  24. data/lib/HDLRuby/hruby_low2hdr.rb +66 -40
  25. data/lib/HDLRuby/hruby_low2high.rb +86 -44
  26. data/lib/HDLRuby/hruby_low2seq.rb +26 -18
  27. data/lib/HDLRuby/hruby_low2sym.rb +14 -13
  28. data/lib/HDLRuby/hruby_low2vhd.rb +78 -43
  29. data/lib/HDLRuby/hruby_low_bool2select.rb +61 -46
  30. data/lib/HDLRuby/hruby_low_casts_without_expression.rb +56 -44
  31. data/lib/HDLRuby/hruby_low_cleanup.rb +18 -16
  32. data/lib/HDLRuby/hruby_low_fix_types.rb +64 -32
  33. data/lib/HDLRuby/hruby_low_mutable.rb +53 -118
  34. data/lib/HDLRuby/hruby_low_resolve.rb +26 -31
  35. data/lib/HDLRuby/hruby_low_with_bool.rb +33 -16
  36. data/lib/HDLRuby/hruby_low_with_port.rb +3 -3
  37. data/lib/HDLRuby/hruby_low_with_var.rb +23 -9
  38. data/lib/HDLRuby/hruby_low_without_concat.rb +19 -13
  39. data/lib/HDLRuby/hruby_low_without_namespace.rb +47 -32
  40. data/lib/HDLRuby/hruby_low_without_parinseq.rb +18 -12
  41. data/lib/HDLRuby/hruby_low_without_select.rb +36 -23
  42. data/lib/HDLRuby/hruby_low_without_subsignals.rb +29 -28
  43. data/lib/HDLRuby/hruby_rcsim.rb +79 -64
  44. data/lib/HDLRuby/hruby_rsim.rb +64 -15
  45. data/lib/HDLRuby/hruby_rsim_mute.rb +2 -3
  46. data/lib/HDLRuby/hruby_rsim_vcd.rb +28 -25
  47. data/lib/HDLRuby/hruby_values.rb +13 -2
  48. data/lib/HDLRuby/hruby_verilog.rb +90 -48
  49. data/lib/HDLRuby/soft/stacks.rb +219 -0
  50. data/lib/HDLRuby/std/bram.rb +9 -5
  51. data/lib/HDLRuby/std/clocks.rb +1 -1
  52. data/lib/HDLRuby/std/fsm.rb +29 -9
  53. data/lib/HDLRuby/std/sequencer.rb +1857 -0
  54. data/lib/HDLRuby/std/sequencer_sync.rb +400 -0
  55. data/lib/HDLRuby/std/std.rb +12 -0
  56. data/lib/HDLRuby/version.rb +1 -1
  57. data/tuto/adder_sat_flags_vcd.png +0 -0
  58. data/tuto/addsub_vcd.png +0 -0
  59. data/tuto/alu_vcd.png +0 -0
  60. data/tuto/bit_pong_vcd.png +0 -0
  61. data/tuto/checksum_vcd.png +0 -0
  62. data/tuto/circuit_hdr.odg +0 -0
  63. data/tuto/circuit_hdr.png +0 -0
  64. data/tuto/circuit_hie.odg +0 -0
  65. data/tuto/circuit_hie.png +0 -0
  66. data/tuto/circuit_view.odg +0 -0
  67. data/tuto/circuit_view.png +0 -0
  68. data/tuto/clock_counter_vcd.png +0 -0
  69. data/tuto/counter_ext_vcd.png +0 -0
  70. data/tuto/fact_vcd.png +0 -0
  71. data/tuto/hw_flow.odg +0 -0
  72. data/tuto/hw_flow.png +0 -0
  73. data/tuto/maxxer_vcd.png +0 -0
  74. data/tuto/pingpong0_vcd.png +0 -0
  75. data/tuto/pingpong1_vcd.png +0 -0
  76. data/tuto/pingpong2_vcd.png +0 -0
  77. data/tuto/ram_vcd.png +0 -0
  78. data/tuto/serializer_vcd.png +0 -0
  79. data/tuto/sw_flow.odg +0 -0
  80. data/tuto/sw_flow.png +0 -0
  81. data/tuto/the_counter_vcd.png +0 -0
  82. data/tuto/tutorial_sw.html +2359 -0
  83. data/tuto/tutorial_sw.md +2684 -0
  84. data/tuto/tutorial_sw.pdf +0 -0
  85. data/tuto/tutorial_sw_jp.md +417 -0
  86. metadata +44 -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,7 +212,8 @@ 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.
@@ -241,8 +260,6 @@ module HDLRuby::High::Std
241
260
  st.gotos.each(&:call)
242
261
  else
243
262
  # No gotos, by default the next step is
244
- # current + 1
245
- # this.next_state_sig <= this.cur_state_sig + 1
246
263
  if sequential then
247
264
  this.next_state_sig <= this.cur_state_sig + 1
248
265
  end
@@ -251,6 +268,7 @@ module HDLRuby::High::Std
251
268
  end
252
269
  # By default set the next state to 0.
253
270
  helse do
271
+ # hprint("Unknow state case: ",this.cur_state_sig,"\n")
254
272
  this.next_state_sig <= 0
255
273
  end
256
274
 
@@ -260,7 +278,8 @@ module HDLRuby::High::Std
260
278
  event = mk_ev.call
261
279
  event = event.invert if @dual
262
280
  # The extra code.
263
- par(*event) do
281
+ # par(*event) do
282
+ fsm_block(*event) do
264
283
  # Build the extra synchronous part.
265
284
  sync_code = proc do
266
285
  hcase(this.cur_state_sig)
@@ -289,7 +308,8 @@ module HDLRuby::High::Std
289
308
 
290
309
  # Extra asynchronous operative part.
291
310
  if extra_asyncs.any? then
292
- par do
311
+ # par do
312
+ fsm_block do
293
313
  # Build the extra synchronous part.
294
314
  async_code = proc do
295
315
  hcase(this.cur_state_sig)