HDLRuby 2.11.12 → 3.1.0

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