HDLRuby 2.0.8

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 (224) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +5 -0
  4. data/.yardopts +1 -0
  5. data/Gemfile +4 -0
  6. data/HDLRuby.gemspec +36 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +2774 -0
  9. data/README.pdf +0 -0
  10. data/Rakefile +10 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/exe/hdrcc +3 -0
  14. data/lib/HDLRuby/alcc.rb +137 -0
  15. data/lib/HDLRuby/backend/hruby_allocator.rb +69 -0
  16. data/lib/HDLRuby/backend/hruby_c_allocator.rb +76 -0
  17. data/lib/HDLRuby/hdr_samples/adder.rb +7 -0
  18. data/lib/HDLRuby/hdr_samples/adder_assign_error.rb +11 -0
  19. data/lib/HDLRuby/hdr_samples/adder_bench.rb +27 -0
  20. data/lib/HDLRuby/hdr_samples/adder_gen.rb +7 -0
  21. data/lib/HDLRuby/hdr_samples/adder_nodef_error.rb +7 -0
  22. data/lib/HDLRuby/hdr_samples/addsub.rb +19 -0
  23. data/lib/HDLRuby/hdr_samples/addsubz.rb +22 -0
  24. data/lib/HDLRuby/hdr_samples/alu.rb +47 -0
  25. data/lib/HDLRuby/hdr_samples/calculator.rb +48 -0
  26. data/lib/HDLRuby/hdr_samples/counter_bench.rb +83 -0
  27. data/lib/HDLRuby/hdr_samples/dff.rb +9 -0
  28. data/lib/HDLRuby/hdr_samples/dff_bench.rb +66 -0
  29. data/lib/HDLRuby/hdr_samples/dff_counter.rb +20 -0
  30. data/lib/HDLRuby/hdr_samples/include.rb +14 -0
  31. data/lib/HDLRuby/hdr_samples/instance_open.rb +23 -0
  32. data/lib/HDLRuby/hdr_samples/mei8.rb +256 -0
  33. data/lib/HDLRuby/hdr_samples/mei8_bench.rb +309 -0
  34. data/lib/HDLRuby/hdr_samples/multer_gen.rb +8 -0
  35. data/lib/HDLRuby/hdr_samples/multer_seq.rb +29 -0
  36. data/lib/HDLRuby/hdr_samples/neural/a.rb +9 -0
  37. data/lib/HDLRuby/hdr_samples/neural/a_sub.rb +5 -0
  38. data/lib/HDLRuby/hdr_samples/neural/bw.rb +23 -0
  39. data/lib/HDLRuby/hdr_samples/neural/counter.rb +16 -0
  40. data/lib/HDLRuby/hdr_samples/neural/dadz.rb +9 -0
  41. data/lib/HDLRuby/hdr_samples/neural/dadz_sub.rb +4 -0
  42. data/lib/HDLRuby/hdr_samples/neural/forward.rb +153 -0
  43. data/lib/HDLRuby/hdr_samples/neural/forward_sub.rb +62 -0
  44. data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand.rb +41 -0
  45. data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand_typedef.rb +47 -0
  46. data/lib/HDLRuby/hdr_samples/neural/mem.rb +30 -0
  47. data/lib/HDLRuby/hdr_samples/neural/random.rb +23 -0
  48. data/lib/HDLRuby/hdr_samples/neural/selector.rb +29 -0
  49. data/lib/HDLRuby/hdr_samples/neural/sigmoid.rb +20 -0
  50. data/lib/HDLRuby/hdr_samples/neural/z.rb +33 -0
  51. data/lib/HDLRuby/hdr_samples/prog.obj +256 -0
  52. data/lib/HDLRuby/hdr_samples/ram.rb +18 -0
  53. data/lib/HDLRuby/hdr_samples/register_with_code_bench.rb +98 -0
  54. data/lib/HDLRuby/hdr_samples/rom.rb +10 -0
  55. data/lib/HDLRuby/hdr_samples/struct.rb +14 -0
  56. data/lib/HDLRuby/hdr_samples/sumprod.rb +29 -0
  57. data/lib/HDLRuby/hdr_samples/sw_encrypt_bench.rb +103 -0
  58. data/lib/HDLRuby/hdr_samples/sw_encrypt_cpu_bench.rb +261 -0
  59. data/lib/HDLRuby/hdr_samples/sw_encrypt_cpusim_bench.rb +302 -0
  60. data/lib/HDLRuby/hdr_samples/system_open.rb +11 -0
  61. data/lib/HDLRuby/hdr_samples/tuple.rb +16 -0
  62. data/lib/HDLRuby/hdr_samples/with_channel.rb +118 -0
  63. data/lib/HDLRuby/hdr_samples/with_class.rb +199 -0
  64. data/lib/HDLRuby/hdr_samples/with_decoder.rb +17 -0
  65. data/lib/HDLRuby/hdr_samples/with_fsm.rb +34 -0
  66. data/lib/HDLRuby/hdr_samples/with_reconf.rb +103 -0
  67. data/lib/HDLRuby/hdrcc.rb +623 -0
  68. data/lib/HDLRuby/high_samples/_adder_fault.rb +23 -0
  69. data/lib/HDLRuby/high_samples/_generic_transmission2.rb +146 -0
  70. data/lib/HDLRuby/high_samples/adder.rb +21 -0
  71. data/lib/HDLRuby/high_samples/adder_common_errors.rb +25 -0
  72. data/lib/HDLRuby/high_samples/addsub.rb +33 -0
  73. data/lib/HDLRuby/high_samples/addsubz.rb +37 -0
  74. data/lib/HDLRuby/high_samples/after.rb +28 -0
  75. data/lib/HDLRuby/high_samples/all_signals.rb +29 -0
  76. data/lib/HDLRuby/high_samples/alu.rb +61 -0
  77. data/lib/HDLRuby/high_samples/anonymous.rb +41 -0
  78. data/lib/HDLRuby/high_samples/before.rb +28 -0
  79. data/lib/HDLRuby/high_samples/blockblock.rb +26 -0
  80. data/lib/HDLRuby/high_samples/bugs/dadz.rb +22 -0
  81. data/lib/HDLRuby/high_samples/bugs/misample_instan.rb +20 -0
  82. data/lib/HDLRuby/high_samples/bugs/misample_updown.rb +22 -0
  83. data/lib/HDLRuby/high_samples/bugs/sample_add.rb +16 -0
  84. data/lib/HDLRuby/high_samples/bugs/sample_barrel.rb +13 -0
  85. data/lib/HDLRuby/high_samples/bugs/sample_daice.rb +57 -0
  86. data/lib/HDLRuby/high_samples/bugs/sample_kumiawase.rb +52 -0
  87. data/lib/HDLRuby/high_samples/bugs/sample_multi.rb +18 -0
  88. data/lib/HDLRuby/high_samples/bugs/sample_sub.rb +14 -0
  89. data/lib/HDLRuby/high_samples/bugs/z2.rb +32 -0
  90. data/lib/HDLRuby/high_samples/case.rb +32 -0
  91. data/lib/HDLRuby/high_samples/case2.rb +30 -0
  92. data/lib/HDLRuby/high_samples/change.rb +23 -0
  93. data/lib/HDLRuby/high_samples/clocks.rb +35 -0
  94. data/lib/HDLRuby/high_samples/comparer.rb +21 -0
  95. data/lib/HDLRuby/high_samples/conditionals.rb +29 -0
  96. data/lib/HDLRuby/high_samples/dff.rb +23 -0
  97. data/lib/HDLRuby/high_samples/each.rb +28 -0
  98. data/lib/HDLRuby/high_samples/exporter.rb +42 -0
  99. data/lib/HDLRuby/high_samples/functions.rb +60 -0
  100. data/lib/HDLRuby/high_samples/if_seq.rb +26 -0
  101. data/lib/HDLRuby/high_samples/inherit_as_dff.rb +32 -0
  102. data/lib/HDLRuby/high_samples/inherit_dff.rb +36 -0
  103. data/lib/HDLRuby/high_samples/instance.rb +37 -0
  104. data/lib/HDLRuby/high_samples/memory.rb +64 -0
  105. data/lib/HDLRuby/high_samples/multi_file.rb +27 -0
  106. data/lib/HDLRuby/high_samples/overload.rb +32 -0
  107. data/lib/HDLRuby/high_samples/paper_after.rb +49 -0
  108. data/lib/HDLRuby/high_samples/ram.rb +27 -0
  109. data/lib/HDLRuby/high_samples/registers.rb +139 -0
  110. data/lib/HDLRuby/high_samples/rom.rb +23 -0
  111. data/lib/HDLRuby/high_samples/scopeblockname.rb +37 -0
  112. data/lib/HDLRuby/high_samples/scopescope.rb +26 -0
  113. data/lib/HDLRuby/high_samples/shift.rb +31 -0
  114. data/lib/HDLRuby/high_samples/shift2.rb +40 -0
  115. data/lib/HDLRuby/high_samples/simple_instance.rb +31 -0
  116. data/lib/HDLRuby/high_samples/test_all.sh +10 -0
  117. data/lib/HDLRuby/high_samples/typedef.rb +24 -0
  118. data/lib/HDLRuby/high_samples/values.rb +70 -0
  119. data/lib/HDLRuby/high_samples/vector.rb +22 -0
  120. data/lib/HDLRuby/high_samples/with_decoder.rb +30 -0
  121. data/lib/HDLRuby/high_samples/with_fsm.rb +46 -0
  122. data/lib/HDLRuby/high_samples/with_pipe.rb +43 -0
  123. data/lib/HDLRuby/high_samples/with_seq.rb +25 -0
  124. data/lib/HDLRuby/hruby_bstr.rb +1085 -0
  125. data/lib/HDLRuby/hruby_check.rb +317 -0
  126. data/lib/HDLRuby/hruby_db.rb +432 -0
  127. data/lib/HDLRuby/hruby_error.rb +44 -0
  128. data/lib/HDLRuby/hruby_high.rb +4103 -0
  129. data/lib/HDLRuby/hruby_low.rb +4735 -0
  130. data/lib/HDLRuby/hruby_low2c.rb +1986 -0
  131. data/lib/HDLRuby/hruby_low2high.rb +738 -0
  132. data/lib/HDLRuby/hruby_low2seq.rb +248 -0
  133. data/lib/HDLRuby/hruby_low2sym.rb +126 -0
  134. data/lib/HDLRuby/hruby_low2vhd.rb +1437 -0
  135. data/lib/HDLRuby/hruby_low_bool2select.rb +295 -0
  136. data/lib/HDLRuby/hruby_low_cleanup.rb +193 -0
  137. data/lib/HDLRuby/hruby_low_fix_types.rb +437 -0
  138. data/lib/HDLRuby/hruby_low_mutable.rb +1803 -0
  139. data/lib/HDLRuby/hruby_low_resolve.rb +165 -0
  140. data/lib/HDLRuby/hruby_low_skeleton.rb +129 -0
  141. data/lib/HDLRuby/hruby_low_with_bool.rb +141 -0
  142. data/lib/HDLRuby/hruby_low_with_port.rb +167 -0
  143. data/lib/HDLRuby/hruby_low_with_var.rb +302 -0
  144. data/lib/HDLRuby/hruby_low_without_bit2vector.rb +88 -0
  145. data/lib/HDLRuby/hruby_low_without_concat.rb +162 -0
  146. data/lib/HDLRuby/hruby_low_without_connection.rb +113 -0
  147. data/lib/HDLRuby/hruby_low_without_namespace.rb +718 -0
  148. data/lib/HDLRuby/hruby_low_without_outread.rb +107 -0
  149. data/lib/HDLRuby/hruby_low_without_select.rb +206 -0
  150. data/lib/HDLRuby/hruby_serializer.rb +398 -0
  151. data/lib/HDLRuby/hruby_tools.rb +37 -0
  152. data/lib/HDLRuby/hruby_types.rb +239 -0
  153. data/lib/HDLRuby/hruby_values.rb +64 -0
  154. data/lib/HDLRuby/hruby_verilog.rb +1888 -0
  155. data/lib/HDLRuby/hruby_verilog_name.rb +52 -0
  156. data/lib/HDLRuby/low_samples/adder.yaml +97 -0
  157. data/lib/HDLRuby/low_samples/after.yaml +228 -0
  158. data/lib/HDLRuby/low_samples/before.yaml +223 -0
  159. data/lib/HDLRuby/low_samples/blockblock.yaml +48 -0
  160. data/lib/HDLRuby/low_samples/bugs/sample_add.yaml +97 -0
  161. data/lib/HDLRuby/low_samples/bugs/sample_daice.yaml +444 -0
  162. data/lib/HDLRuby/low_samples/bugs/sample_kumiawase.yaml +332 -0
  163. data/lib/HDLRuby/low_samples/bugs/sample_sub.yaml +97 -0
  164. data/lib/HDLRuby/low_samples/bugs/seqpar.yaml +184 -0
  165. data/lib/HDLRuby/low_samples/case.yaml +327 -0
  166. data/lib/HDLRuby/low_samples/change.yaml +135 -0
  167. data/lib/HDLRuby/low_samples/clocks.yaml +674 -0
  168. data/lib/HDLRuby/low_samples/cloner.rb +22 -0
  169. data/lib/HDLRuby/low_samples/comparer.yaml +85 -0
  170. data/lib/HDLRuby/low_samples/conditionals.yaml +133 -0
  171. data/lib/HDLRuby/low_samples/dff.yaml +107 -0
  172. data/lib/HDLRuby/low_samples/each.yaml +1328 -0
  173. data/lib/HDLRuby/low_samples/exporter.yaml +226 -0
  174. data/lib/HDLRuby/low_samples/functions.yaml +298 -0
  175. data/lib/HDLRuby/low_samples/generic_transmission.yaml +597 -0
  176. data/lib/HDLRuby/low_samples/inherit_as_dff.yaml +125 -0
  177. data/lib/HDLRuby/low_samples/inherit_dff.yaml +107 -0
  178. data/lib/HDLRuby/low_samples/load_yaml.rb +11 -0
  179. data/lib/HDLRuby/low_samples/memory.yaml +678 -0
  180. data/lib/HDLRuby/low_samples/namespace_extractor.rb +23 -0
  181. data/lib/HDLRuby/low_samples/overload.yaml +226 -0
  182. data/lib/HDLRuby/low_samples/paper_after.yaml +431 -0
  183. data/lib/HDLRuby/low_samples/port_maker.rb +14 -0
  184. data/lib/HDLRuby/low_samples/ram.yaml +207 -0
  185. data/lib/HDLRuby/low_samples/registers.yaml +228 -0
  186. data/lib/HDLRuby/low_samples/rom.yaml +2950 -0
  187. data/lib/HDLRuby/low_samples/shift.yaml +230 -0
  188. data/lib/HDLRuby/low_samples/shift2.yaml +2095 -0
  189. data/lib/HDLRuby/low_samples/simple_instance.yaml +102 -0
  190. data/lib/HDLRuby/low_samples/test_all.sh +43 -0
  191. data/lib/HDLRuby/low_samples/typedef.yaml +115 -0
  192. data/lib/HDLRuby/low_samples/values.yaml +577 -0
  193. data/lib/HDLRuby/low_samples/variable_maker.rb +14 -0
  194. data/lib/HDLRuby/low_samples/vector.yaml +56 -0
  195. data/lib/HDLRuby/low_samples/with_seq.yaml +188 -0
  196. data/lib/HDLRuby/low_samples/yaml2hdr.rb +10 -0
  197. data/lib/HDLRuby/low_samples/yaml2vhd.rb +19 -0
  198. data/lib/HDLRuby/sim/Makefile +19 -0
  199. data/lib/HDLRuby/sim/hruby_sim.h +590 -0
  200. data/lib/HDLRuby/sim/hruby_sim_calc.c +2362 -0
  201. data/lib/HDLRuby/sim/hruby_sim_core.c +589 -0
  202. data/lib/HDLRuby/sim/hruby_sim_list.c +93 -0
  203. data/lib/HDLRuby/sim/hruby_sim_vizualize.c +91 -0
  204. data/lib/HDLRuby/sim/hruby_value_pool.c +64 -0
  205. data/lib/HDLRuby/std/channel.rb +354 -0
  206. data/lib/HDLRuby/std/clocks.rb +165 -0
  207. data/lib/HDLRuby/std/counters.rb +82 -0
  208. data/lib/HDLRuby/std/decoder.rb +214 -0
  209. data/lib/HDLRuby/std/fsm.rb +516 -0
  210. data/lib/HDLRuby/std/pipeline.rb +220 -0
  211. data/lib/HDLRuby/std/reconf.rb +309 -0
  212. data/lib/HDLRuby/test_hruby_bstr.rb +2259 -0
  213. data/lib/HDLRuby/test_hruby_high.rb +594 -0
  214. data/lib/HDLRuby/test_hruby_high_low.rb +99 -0
  215. data/lib/HDLRuby/test_hruby_low.rb +934 -0
  216. data/lib/HDLRuby/v_samples/adder.v +10 -0
  217. data/lib/HDLRuby/v_samples/dff.v +12 -0
  218. data/lib/HDLRuby/v_samples/ram.v +20 -0
  219. data/lib/HDLRuby/v_samples/rom.v +270 -0
  220. data/lib/HDLRuby/version.rb +3 -0
  221. data/lib/HDLRuby.rb +11 -0
  222. data/makedoc +1 -0
  223. data/metadata.yaml +4 -0
  224. metadata +299 -0
@@ -0,0 +1,20 @@
1
+ # Describes a simple D-FF
2
+ system :dff do
3
+ input :clk,:rst
4
+ input :d
5
+ output :q
6
+
7
+ (q <= d & ~rst ).at(clk.posedge)
8
+ end
9
+
10
+
11
+ # Describes a 2-bit counter using dff
12
+ system :counter2 do
13
+ input :clk,:rst
14
+ output :q
15
+
16
+ dff [:dff0, :dff1]
17
+
18
+ dff0.(clk,rst,~dff0.q)
19
+ dff1.(dff0.q,rst,~dff1.q,q)
20
+ end
@@ -0,0 +1,14 @@
1
+ system :dff do
2
+ input :clk, :rst, :d
3
+ output :q
4
+
5
+ par(clk.posedge) { q <= d & ~rst }
6
+ end
7
+
8
+ system :dff_full do
9
+ output :qb
10
+
11
+ include dff
12
+
13
+ qb <= ~q
14
+ end
@@ -0,0 +1,23 @@
1
+ system :dff do
2
+ input :clk, :rst, :d
3
+ output :q
4
+
5
+ (q <= d & ~rst).at(clk.posedge)
6
+ end
7
+
8
+ system :in_dff do
9
+ input :clk, :rst, :d
10
+ output :q, :qb
11
+
12
+ dff :dff0
13
+ dff0.open do
14
+ output :qb
15
+ qb <= ~q
16
+ end
17
+
18
+ dff0.clk <= clk
19
+ dff0.rst <= rst
20
+ dff0.d <= d
21
+ q <= dff0.q
22
+ qb <= dff0.qb
23
+ end
@@ -0,0 +1,256 @@
1
+ require '../std/fsm.rb'
2
+ require '../std/decoder.rb'
3
+ include HDLRuby::High::Std
4
+
5
+ # A simple implementation of the MEI8 processor.
6
+ #
7
+ # In this implementation, the program is hard-coded in an internal ROM
8
+ system :mei8 do |prog_file = "./prog.obj"|
9
+ # Clock and reset.
10
+ input :clk, :rst
11
+ # Bus.
12
+ output :req, :rwb
13
+ [8].output :addr
14
+ [8].inout :dbus
15
+ input :ack
16
+ # Interrupts.
17
+ input :iq0, :iq1
18
+ # The signals for controlling the io unit.
19
+ inner :io_req, :io_rwb, :io_done # Request, read/not write, done.
20
+ inner :io_r_done # Read done.
21
+ [8].inner :io_out,:io_in # The write and read inner buses.
22
+ [8].inner :data # The read buffer.
23
+
24
+ # The rom containing the program.
25
+ instance :prog do
26
+ [7..0].input :addr # The address bus
27
+ [7..0].output :instr # The instruction bus
28
+ bit[7..0][-256].constant content: # The content of the memory
29
+ File.readlines(prog_file).map {|l| l.split[0].to_i(2)}
30
+ instr <= content[addr] # The access procedure
31
+ end
32
+
33
+ # The registers.
34
+ [8].inner :a, :b, :c, :d, :e, :f, :g, :h # General purpose registers
35
+ inner :zf, :cf, :sf, :vf # Flags
36
+ [8].inner :ir # Instruction register
37
+ [8].inner :pc # Program counter
38
+ [8].inner :s # Status register
39
+
40
+ # The ALU
41
+ instance :alu do
42
+ [4].input :opr # The operator bus
43
+ [8].input :x,:y # The input buses
44
+ [8].output :z # The output bus
45
+ output :zf, :cf, :sf, :vf # The flag signals
46
+
47
+ # The only adder instance.
48
+ instance :add do
49
+ [8].input :x,:y # The input buses
50
+ input :cin # The input carry
51
+ [9].output :z # The output bus (including
52
+ # the output carry)
53
+ z <= x.as([9])+y+cin
54
+ end
55
+
56
+ # The control part for choosing between 0, add, sub and neg.
57
+ par do
58
+ # Default computations
59
+ cf <= 0; vf <= 0; zf <= (z == 0); sf <= z[7]
60
+ add.(0,0,0)
61
+ # Depending on the operator
62
+ hcase(opr)
63
+ hwhen(0) { add.(x ,y ,0,[cf,z]) # add
64
+ vf <= (~x[7] & ~y[7] & z[7]) | (x[7] & y[7] & ~z[7]) }
65
+ hwhen(1) { add.(x ,~y,1,[cf,z]) # sub
66
+ vf <= (~x[7] & y[7] & z[7]) | (x[7] & ~y[7] & ~z[7]) }
67
+ hwhen(2) { add.(x ,0 ,1,[cf,z]) # inc
68
+ vf <= (~x[7] & ~y[7] & z[7]) | (x[7] & y[7] & ~z[7]) }
69
+ hwhen(3) { add.(x ,0xFF ,0,[cf,z]) # dec
70
+ vf <= (~x[7] & ~y[7] & z[7]) | (x[7] & y[7] & ~z[7]) }
71
+ hwhen(4) { z <= x & y } # and
72
+ hwhen(5) { z <= x | y } # or
73
+ hwhen(6) { z <= x ^ y } # xor
74
+ hwhen(7) { z <= x } # mov
75
+ hwhen(8) { add.(~x,0 ,1,[cf,z]) # neg
76
+ vf <= (x[7] & ~z[7]) }
77
+ hwhen(9) { z <= ~x } # not
78
+ hwhen(10) { z <= x << 1 ; cf <= x[7] } # shl
79
+ hwhen(11) { z <= x >> 1 ; cf <= x[0] } # shr
80
+ hwhen(12) { z <= [x[7], x[7..1] ] ; cf <= x[0] } # sar
81
+ helse { z <= 0 } # zero
82
+ end
83
+ end
84
+
85
+ # Signals relative to the decoder
86
+ [3].inner :dst # Index of the destination register.
87
+ [8].inner :src0, :src1 # Values of the source registers.
88
+ inner :branch # Tells if the instruction is a branch.
89
+ inner :cc # Tells if a branch condition is met.
90
+ inner :wr, :wf # Tells the computation result is to write to a gpr/flag.
91
+ inner :ld, :st # Tells if the instruction is a load/store.
92
+ inner :iq_calc # Tells if the interrupt unit is preempting calculation.
93
+
94
+ # The decoder.
95
+ par do
96
+ # By default, no branch, no load, no store, write to gpr but not to
97
+ # flags and destination is a and output value is a
98
+ branch <= 0; ld <= 0; st <= 0; wr <= 1; wf <= 0; dst <= 0; io_out <= a
99
+ # And transfer 0.
100
+ alu.(15,0,0)
101
+ # Compute the possible sources
102
+ src0 <= mux(ir[5..3],a,b,c,d,e,f,g,h)
103
+ src1 <= mux(ir[2..0],a,b,c,d,e,f,g,h)
104
+ # Compute the branch condition.
105
+ cc <= mux(ir[5..3],1,zf,cf,sf,vf,~zf,0)
106
+ # Is it an interrupt?
107
+ hif (iq_calc) { alu.(2,h,0) }
108
+ # No, do a normal decoding of the instruction in ir.
109
+ helse do
110
+ decoder(ir) do
111
+ # Format 0
112
+ entry("00000000") { wr <= 0 } # nop
113
+ entry("00xxxyyy") {
114
+ hif (x == y) { alu.(15,0,0) } # mov 0,y
115
+ helse { alu.(7,src0) } # mov x,y
116
+ dst <= y }
117
+ # Format 1
118
+ entry("01oooyyy") { wf <= 1
119
+ # Destination is also y in case of inc/dec
120
+ hif (ir[6..4] == _101) { dst <= y }
121
+ alu.(o,a,src1) } # binary alu
122
+ # Format 1 extended.
123
+ entry("10000yyy") { wr <= 0; wf <= 1
124
+ alu.(1,a,src1) } # cp y
125
+ entry("10001yyy") { ld <= 1; dst <= y } # ld y
126
+ entry("10010yyy") { st <= 1; wr <= 0 # st y
127
+ [a,b,c,d,e,f,g,h].hcase(y) {|r| io_out <= r } }
128
+ entry("10011yyy") { branch <= 1 # jr y, must inc y
129
+ alu.(2,src1) } # since pc-1 is used
130
+ # Format 2
131
+ entry("1010iiii") { alu.(7,[_0000,i]) } # movl i
132
+ entry("1011iiii") { alu.(7,[i,a[3..0]]) } # movh i
133
+ # Format 4
134
+ entry("11110110") { branch <= 1 # trap
135
+ alu.(7,0xFC) }
136
+ entry("11110ooo") { wf <= 1; alu.([_1,o],a) } # unary alu
137
+ entry("111110os") { st <= s; ld <= ~s # ++--ld / ++--st
138
+ alu.([_001,o],g); dst <= 6 }
139
+ entry("1111110i") { branch <= i
140
+ st <= ~i; ld <= i
141
+ alu.([_001,~i],h)
142
+ dst <= 7; io_out <= pc } # push / pop pc
143
+ # Format 3
144
+ entry("11cccsii") { branch <= cc; wr <= 0
145
+ alu.(0,pc,[s]*6+[i]) }# br c i
146
+ # xs / halt / reset: treated without decoding
147
+ end
148
+ end
149
+ end
150
+
151
+ # The io unit.
152
+ fsm(clk.posedge,rst,:async) do
153
+ default { io_done <= 0; req <= 0; rwb <= 0; addr <= 0
154
+ io_r_done <= 0
155
+ # Default handling of the 3-state data bus
156
+ hif(io_rwb) { dbus <= _zzzzzzzz }
157
+ helse { dbus <= io_out }
158
+ io_in <= dbus }
159
+ reset(:sync) { data <= 0; }
160
+ state(:wait) { goto(io_req,:start,:wait) } # Waiting for an IO
161
+ state(:start) { req <= 1; rwb <= io_rwb; addr <= g # Start an IO
162
+ goto(ack,:end,:start) } # Wait exteral ack to end IO
163
+ sync(:start) { data <= io_in }
164
+ state(:end) { io_done <= 1; io_r_done <= io_rwb # End IO
165
+ goto(:wait) }
166
+ end
167
+
168
+ inner :calc # Tell if calculation is to be writen back to a register.
169
+ inner :init # Tell CPU is in initialization mode (soft reset).
170
+
171
+ [8].inner :npc # Next pc
172
+ inner :nbr # Tell if must branch next.
173
+
174
+ # Write back unit: handles the writing to registers.
175
+ par(clk.posedge) do
176
+ nbr <= 0; npc <= 0 # By default no branch to schedule.
177
+ hif(rst) do
178
+ # In case of hard reset all the registers of the operative part
179
+ # are to put to 0.
180
+ [a,b,c,d,e,f,g,h,zf,cf,sf,vf,nbr,npc,s].each { |r| r <= 0 }
181
+ end
182
+ # Ensures a is 0 and enable interrupts when starting.
183
+ helsif(init) { a<= 0; s <= _00000011; }
184
+ helsif(iq_calc) do
185
+ s[7] <= 1
186
+ hif(iq1) { s[1] <= 0 }
187
+ helse { s[0] <= 0 }
188
+ h <= alu.z
189
+ end
190
+ helsif(calc) do
191
+ hif wr do # Write to the destination gpr.
192
+ [a,b,c,d,e,f,g,h].hcase(dst) { |r| r <= alu.z }
193
+ end
194
+ hif wf do # Write the the flags.
195
+ zf <= alu.zf; cf <= alu.cf; sf <= alu.sf; vf <= alu.vf
196
+ end
197
+ # Specific cases
198
+ hif(ir == _11110111) { s <= a; a <= s } # xs
199
+ hif(ir == _11110110) { s[7] <= 1 } # trap
200
+ hif(branch) { npc <= alu.z; nbr <= 1 } # Branch
201
+ end
202
+ # Write memory read result to a register if any.
203
+ helsif (io_r_done) do
204
+ hif(branch) { npc <= data; nbr <= 1 } # pop case
205
+ helsif(ir[7..3] == _10001) do # ld case
206
+ [a,b,c,d,e,f,g,h].hcase(dst) {|r| r <= data }
207
+ end
208
+ helse { a <= data } # ld++-- case
209
+ end
210
+ end
211
+
212
+ prog.addr <= pc # Buses permanent connections.
213
+
214
+ inner :iq_chk # Interrupt check buffer.
215
+
216
+ # The main FSM
217
+ fsm(clk.posedge,rst,:async) do
218
+ default { init <= 0; calc <= 0; io_req <= 0; io_rwb <= 1
219
+ iq_calc <= 0 }
220
+ reset(:sync) { pc <= 0; ir <= 0; iq_chk <= 0 } # Hard reset
221
+ # Soft reset state.
222
+ state(:re) { init <= 1 }
223
+ sync(:re) { pc <= 0; ir <= 0; iq_chk <= 0 }
224
+ # Standard execution states.
225
+ state(:fe) { }
226
+ sync(:fe) { ir <= prog.instr; pc <= pc + 1 # Standard fetch
227
+ iq_chk <= (iq0 & s[0]) | (iq1 & s[1]) } # Check interrupt
228
+ state(:ex) { calc <= 1 # Activate the write back unit
229
+ hif(ld|st) { io_req <= 1; io_rwb <= ld } # Prepare IO unit if ld or st
230
+ goto(:fe) # By default execution is over
231
+ goto(iq_chk,:iq_s) # Interrupt / No interrupt
232
+ goto(branch,:br) # Branch instruction
233
+ goto((ld|st) & ~io_done,:ld_st) # ld/st instruction
234
+ goto(ir == _11111110,:ht) # Halt instruction
235
+ goto(ir == _11111111,:re) } # Reset instruction
236
+ # Branch state.
237
+ state(:br) { goto(iq_chk,:iq_s,:fe) } # Interrupt / No interrupt
238
+ sync(:br) { hif(nbr) { pc <= npc-1 } } # Next pc is the branch target
239
+ # State waiting the end of a load/store.
240
+ state(:ld_st){ io_rwb <= ld # Tell IO unit if read or write
241
+ goto(branch,:br,:fe) # In case of pop, branch after ld
242
+ goto(~io_done,:ld_st) # ld/et not finished yet
243
+ goto(io_done & iq_chk,:iq_s)}# Interrupt / No interrupt
244
+ # States handling the interrupts.
245
+ # Push PC
246
+ state(:iq_s) { iq_calc <= 1;
247
+ io_req <= 1; io_rwb <= 0; # io_out <= pc
248
+ goto(io_done, :iq_d, :iq_s) }
249
+ # Jump to interrupt handler.
250
+ state(:iq_d) { goto(:fe) }
251
+ sync(:iq_d) { pc <= 0xF8 }
252
+ # State handling the halt (until a reset or an interrupt).
253
+ state(:ht) { goto(iq_chk,:iq_s,:ht) } # Interrupt / No interrupt
254
+ sync(:ht) { iq_chk <= (iq0 & s[0]) | (iq1 & s[1]) }
255
+ end
256
+ end
@@ -0,0 +1,309 @@
1
+ require '../std/fsm.rb'
2
+ require '../std/decoder.rb'
3
+ include HDLRuby::High::Std
4
+
5
+ # A simple implementation of the MEI8 processor.
6
+ #
7
+ # In this implementation, the program is hard-coded in an internal ROM
8
+ system :mei8 do |prog_file = "./prog_encrypt.obj"|
9
+ # Clock and reset.
10
+ input :clk, :rst
11
+ # Bus.
12
+ output :req, :rwb
13
+ [8].output :addr
14
+ [8].inout :dbus
15
+ input :ack
16
+ # Interrupts.
17
+ input :iq0, :iq1
18
+ # The signals for controlling the io unit.
19
+ inner :io_req, :io_rwb, :io_done # Request, read/not write, done.
20
+ inner :io_r_done # Read done.
21
+ [8].inner :io_out,:io_in # The write and read inner buses.
22
+ [8].inner :data # The read buffer.
23
+
24
+ # The rom containing the program.
25
+ instance :prog do
26
+ [7..0].input :addr # The address bus
27
+ [7..0].output :instr # The instruction bus
28
+ bit[7..0][-256].constant content: # The content of the memory
29
+ ( File.readlines(prog_file).map {|l| l.split[0] }.select do |l|
30
+ ["0","1"].include?(l[2])
31
+ end.map {|l| l[2..9] } )
32
+ instr <= content[addr] # The access procedure
33
+ end
34
+
35
+ # The registers.
36
+ [8].inner :a, :b, :c, :d, :e, :f, :g, :h # General purpose registers
37
+ inner :zf, :cf, :sf, :vf # Flags
38
+ [8].inner :ir # Instruction register
39
+ [8].inner :pc # Program counter
40
+ [8].inner :s # Status register
41
+
42
+ # The ALU
43
+ instance :alu do
44
+ [4].input :opr # The operator bus
45
+ [8].input :x,:y # The input buses
46
+ [8].output :z # The output bus
47
+ output :zf, :cf, :sf, :vf # The flag signals
48
+
49
+ # The only adder instance.
50
+ instance :add do
51
+ [8].input :x,:y # The input buses
52
+ input :cin # The input carry
53
+ [9].output :z # The output bus (including
54
+ # the output carry)
55
+ z <= x.as([9])+y+cin
56
+ end
57
+
58
+ # The control part for choosing between 0, add, sub and neg.
59
+ par do
60
+ # Default computations
61
+ cf <= 0; vf <= 0; zf <= (z == 0); sf <= z[7]
62
+ add.(0,0,0)
63
+ # Depending on the operator
64
+ hcase(opr)
65
+ hwhen(0) { add.(x ,y ,0,[cf,z]) # add
66
+ vf <= (~x[7] & ~y[7] & z[7]) | (x[7] & y[7] & ~z[7]) }
67
+ hwhen(1) { add.(x ,~y,1,[cf,z]) # sub
68
+ vf <= (~x[7] & y[7] & z[7]) | (x[7] & ~y[7] & ~z[7]) }
69
+ hwhen(2) { add.(x ,0 ,1,[cf,z]) # inc
70
+ vf <= (~x[7] & ~y[7] & z[7]) | (x[7] & y[7] & ~z[7]) }
71
+ hwhen(3) { add.(x ,0xFF ,0,[cf,z]) # dec
72
+ vf <= (~x[7] & ~y[7] & z[7]) | (x[7] & y[7] & ~z[7]) }
73
+ hwhen(4) { z <= x & y } # and
74
+ hwhen(5) { z <= x | y } # or
75
+ hwhen(6) { z <= x ^ y } # xor
76
+ hwhen(7) { z <= x } # mov
77
+ hwhen(8) { add.(~x,0 ,1,[cf,z]) # neg
78
+ vf <= (x[7] & ~z[7]) }
79
+ hwhen(9) { z <= ~x } # not
80
+ hwhen(10) { z <= x << 1 ; cf <= x[7] } # shl
81
+ hwhen(11) { z <= x >> 1 ; cf <= x[0] } # shr
82
+ hwhen(12) { z <= [x[7], x[7..1] ] ; cf <= x[0] } # sar
83
+ helse { z <= 0 } # zero
84
+ end
85
+ end
86
+
87
+ # Signals relative to the decoder
88
+ [3].inner :dst # Index of the destination register.
89
+ [8].inner :src0, :src1 # Values of the source registers.
90
+ inner :branch # Tells if the instruction is a branch.
91
+ inner :cc # Tells if a branch condition is met.
92
+ inner :wr, :wf # Tells the computation result is to write to a gpr/flag.
93
+ inner :ld, :st # Tells if the instruction is a load/store.
94
+ inner :iq_calc # Tells if the interrupt unit is preempting calculation.
95
+
96
+ # The decoder.
97
+ par do
98
+ # By default, no branch, no load, no store, write to gpr but not to
99
+ # flags and destination is a and output value is a
100
+ branch <= 0; ld <= 0; st <= 0; wr <= 1; wf <= 0; dst <= 0; io_out <= a
101
+ # And transfer 0.
102
+ alu.(15,0,0)
103
+ # Compute the possible sources
104
+ src0 <= mux(ir[5..3],a,b,c,d,e,f,g,h)
105
+ src1 <= mux(ir[2..0],a,b,c,d,e,f,g,h)
106
+ # Compute the branch condition.
107
+ cc <= mux(ir[5..3],1,zf,cf,sf,vf,~zf,0)
108
+ # Is it an interrupt?
109
+ hif (iq_calc) { alu.(2,h,0) }
110
+ # No, do a normal decoding of the instruction in ir.
111
+ helse do
112
+ decoder(ir) do
113
+ # Format 0
114
+ entry("00000000") { wr <= 0 } # nop
115
+ entry("00xxxyyy") {
116
+ hif (x == y) { alu.(15,0,0) } # mov 0,y
117
+ helse { alu.(7,src0) } # mov x,y
118
+ dst <= y }
119
+ # Format 1
120
+ entry("01oooyyy") { wf <= 1
121
+ # Destination is also y in case of inc/dec
122
+ hif (ir[6..4] == _101) { dst <= y }
123
+ alu.(o,a,src1) } # binary alu
124
+ # Format 1 extended.
125
+ entry("10000yyy") { wr <= 0; wf <= 1
126
+ alu.(1,a,src1) } # cp y
127
+ entry("10001yyy") { ld <= 1; dst <= y } # ld y
128
+ entry("10010yyy") { st <= 1; wr <= 0 # st y
129
+ [a,b,c,d,e,f,g,h].hcase(y) {|r| io_out <= r } }
130
+ entry("10011yyy") { branch <= 1 # jr y, must inc y
131
+ alu.(2,src1) } # since pc-1 is used
132
+ # Format 2
133
+ entry("1010iiii") { alu.(7,[_0000,i]) } # movl i
134
+ entry("1011iiii") { alu.(7,[i,a[3..0]]) } # movh i
135
+ # Format 4
136
+ entry("11110110") { branch <= 1 # trap
137
+ alu.(7,0xFC) }
138
+ entry("11110ooo") { wf <= 1; alu.([_1,o],a) } # unary alu
139
+ entry("111110os") { st <= s; ld <= ~s # ++--ld / ++--st
140
+ alu.([_001,o],g); dst <= 6 }
141
+ entry("1111110i") { branch <= i
142
+ st <= ~i; ld <= i
143
+ alu.([_001,~i],h)
144
+ dst <= 7; io_out <= pc } # push / pop pc
145
+ # Format 3
146
+ entry("11cccsii") { branch <= cc; wr <= 0
147
+ alu.(0,pc,[s]*6+[i]) }# br c i
148
+ # xs / halt / reset: treated without decoding
149
+ end
150
+ end
151
+ end
152
+
153
+ # The io unit.
154
+ fsm(clk.posedge,rst,:async) do
155
+ default { io_done <= 0; req <= 0; rwb <= 0; addr <= 0
156
+ io_r_done <= 0
157
+ # Default handling of the 3-state data bus
158
+ hif(io_rwb) { dbus <= _zzzzzzzz }
159
+ helse { dbus <= io_out }
160
+ io_in <= dbus }
161
+ reset(:sync) { data <= 0; }
162
+ state(:wait) { goto(io_req,:start,:wait) } # Waiting for an IO
163
+ state(:start) { req <= 1; rwb <= io_rwb; addr <= g # Start an IO
164
+ goto(ack,:end,:start) } # Wait exteral ack to end IO
165
+ sync(:start) { data <= io_in }
166
+ state(:end) { io_done <= 1; io_r_done <= io_rwb # End IO
167
+ goto(:wait) }
168
+ end
169
+
170
+ inner :calc # Tell if calculation is to be writen back to a register.
171
+ inner :init # Tell CPU is in initialization mode (soft reset).
172
+
173
+ [8].inner :npc # Next pc
174
+ inner :nbr # Tell if must branch next.
175
+
176
+ # Write back unit: handles the writing to registers.
177
+ par(clk.posedge) do
178
+ nbr <= 0; npc <= 0 # By default no branch to schedule.
179
+ hif(rst) do
180
+ # In case of hard reset all the registers of the operative part
181
+ # are to put to 0.
182
+ [a,b,c,d,e,f,g,h,zf,cf,sf,vf,nbr,npc,s].each { |r| r <= 0 }
183
+ end
184
+ # Ensures a is 0 and enable interrupts when starting.
185
+ helsif(init) { a<= 0; s <= _00000011; }
186
+ helsif(iq_calc) do
187
+ s[7] <= 1
188
+ hif(iq1) { s[1] <= 0 }
189
+ helse { s[0] <= 0 }
190
+ h <= alu.z
191
+ end
192
+ helsif(calc) do
193
+ hif wr do # Write to the destination gpr.
194
+ [a,b,c,d,e,f,g,h].hcase(dst) { |r| r <= alu.z }
195
+ end
196
+ hif wf do # Write the the flags.
197
+ zf <= alu.zf; cf <= alu.cf; sf <= alu.sf; vf <= alu.vf
198
+ end
199
+ # Specific cases
200
+ hif(ir == _11110111) { s <= a; a <= s } # xs
201
+ hif(ir == _11110110) { s[7] <= 1 } # trap
202
+ hif(branch) { npc <= alu.z; nbr <= 1 } # Branch
203
+ end
204
+ # Write memory read result to a register if any.
205
+ helsif (io_r_done) do
206
+ hif(branch) { npc <= data; nbr <= 1 } # pop case
207
+ helsif(ir[7..3] == _10001) do # ld case
208
+ [a,b,c,d,e,f,g,h].hcase(dst) {|r| r <= data }
209
+ end
210
+ helse { a <= data } # ld++-- case
211
+ end
212
+ end
213
+
214
+ prog.addr <= pc # Buses permanent connections.
215
+
216
+ inner :iq_chk # Interrupt check buffer.
217
+
218
+ # The main FSM
219
+ fsm(clk.posedge,rst,:async) do
220
+ default { init <= 0; calc <= 0; io_req <= 0; io_rwb <= 1
221
+ iq_calc <= 0 }
222
+ reset(:sync) { pc <= 0; ir <= 0; iq_chk <= 0 } # Hard reset
223
+ # Soft reset state.
224
+ state(:re) { init <= 1 }
225
+ sync(:re) { pc <= 0; ir <= 0; iq_chk <= 0 }
226
+ # Standard execution states.
227
+ state(:fe) { }
228
+ sync(:fe) { ir <= prog.instr; pc <= pc + 1 # Standard fetch
229
+ iq_chk <= (iq0 & s[0]) | (iq1 & s[1]) } # Check interrupt
230
+ state(:ex) { calc <= 1 # Activate the write back unit
231
+ hif(ld|st) { io_req <= 1; io_rwb <= ld } # Prepare IO unit if ld or st
232
+ goto(:fe) # By default execution is over
233
+ goto(iq_chk,:iq_s) # Interrupt / No interrupt
234
+ goto(branch,:br) # Branch instruction
235
+ goto((ld|st) & ~io_done,:ld_st) # ld/st instruction
236
+ goto(ir == _11111110,:ht) # Halt instruction
237
+ goto(ir == _11111111,:re) } # Reset instruction
238
+ # Branch state.
239
+ state(:br) { goto(iq_chk,:iq_s,:fe) } # Interrupt / No interrupt
240
+ sync(:br) { hif(nbr) { pc <= npc-1 } } # Next pc is the branch target
241
+ # State waiting the end of a load/store.
242
+ state(:ld_st){ io_rwb <= ld # Tell IO unit if read or write
243
+ goto(branch,:br,:fe) # In case of pop, branch after ld
244
+ goto(~io_done,:ld_st) # ld/et not finished yet
245
+ goto(io_done & iq_chk,:iq_s)}# Interrupt / No interrupt
246
+ # States handling the interrupts.
247
+ # Push PC
248
+ state(:iq_s) { iq_calc <= 1;
249
+ io_req <= 1; io_rwb <= 0; # io_out <= pc
250
+ goto(io_done, :iq_d, :iq_s) }
251
+ # Jump to interrupt handler.
252
+ state(:iq_d) { goto(:fe) }
253
+ sync(:iq_d) { pc <= 0xF8 }
254
+ # State handling the halt (until a reset or an interrupt).
255
+ state(:ht) { goto(iq_chk,:iq_s,:ht) } # Interrupt / No interrupt
256
+ sync(:ht) { iq_chk <= (iq0 & s[0]) | (iq1 & s[1]) }
257
+ end
258
+ end
259
+
260
+
261
+
262
+ system :mei8_bench do
263
+ # Clock and reset.
264
+ inner :clk, :rst
265
+ # Bus.
266
+ inner :req, :rwb
267
+ [8].inner :addr
268
+ [8].inner :dbus
269
+ inner :ack
270
+ # Interrupts.
271
+ inner :iq0, :iq1
272
+
273
+ mei8(:my_mei8).(clk,rst,req,rwb,addr,dbus,ack,iq0,iq1)
274
+
275
+ timed do
276
+ # Initialize the processor
277
+ clk <= 0
278
+ rst <= 0
279
+ dbus <= 0
280
+ ack <= 0
281
+ iq0 <= 0
282
+ iq1 <= 0
283
+ !10.ns
284
+ clk <= 1
285
+ rst <= 0
286
+ !10.ns
287
+ clk <= 0
288
+ rst <= 1
289
+ !10.ns
290
+ clk <= 1
291
+ rst <= 1
292
+ !10.ns
293
+ clk <= 0
294
+ rst <= 0
295
+ !10.ns
296
+ clk <= 1
297
+ rst <= 0
298
+ !10.ns
299
+ # Now loop a few cycles.
300
+ 100.times do |i|
301
+ clk <= 0
302
+ ack <= 1
303
+ dbus <= i
304
+ !10.ns
305
+ clk <= 1
306
+ !10.ns
307
+ end
308
+ end
309
+ end
@@ -0,0 +1,8 @@
1
+ # A simple generic multiplier
2
+ system :multer do |i0,i1,o|
3
+ [(i0-1)..0].input :x
4
+ [(i1-1)..0].input :y
5
+ [(o-1)..0].output :s
6
+
7
+ s <= x * y
8
+ end
@@ -0,0 +1,29 @@
1
+ require '../std/fsm.rb'
2
+ include HDLRuby::High::Std
3
+
4
+ # A sequential 16x16 -> 32 multer
5
+ system :multer do
6
+ input :clk, :rst
7
+ input :start
8
+ [16].input :x,:y
9
+ [32].output :s
10
+ output :done
11
+
12
+ [32].inner :wx
13
+ [16].inner :wy
14
+
15
+ fsm(clk.posedge,rst) do
16
+ state(:init) { s <= 0 ; wx <= x ; wy <= y ; done <= 0
17
+ goto(start,:test,:init) }
18
+
19
+ state(:test) { goto(wy[0],:add,:next) }
20
+
21
+ state(:add) { s <= s + wx }
22
+
23
+ state(:next) { wx <= wx << 1 ; wy <= wy >> 1
24
+ goto(wy == 0,:end,:test) }
25
+
26
+ state(:end) { done <= 1
27
+ goto(:end) }
28
+ end
29
+ end
@@ -0,0 +1,9 @@
1
+ system :a do |typ, activate|
2
+ input :clk, :din
3
+ typ.input :vin # Former addr
4
+ typ.output :dout
5
+
6
+ par(clk.posedge) do
7
+ dout <= mux(din == 1, activate.(vin), :"_#{"z"*typ.width}")
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ require "./a.rb"
2
+ require "./sigmoid.rb"
3
+
4
+ system :a_sub, a([32].to_type,proc{|addr| sigmoid(8,4,32,24,addr)}) do
5
+ end