HDLRuby 2.0.8

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