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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +5 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/HDLRuby.gemspec +36 -0
- data/LICENSE.txt +21 -0
- data/README.md +2774 -0
- data/README.pdf +0 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/hdrcc +3 -0
- data/lib/HDLRuby/alcc.rb +137 -0
- data/lib/HDLRuby/backend/hruby_allocator.rb +69 -0
- data/lib/HDLRuby/backend/hruby_c_allocator.rb +76 -0
- data/lib/HDLRuby/hdr_samples/adder.rb +7 -0
- data/lib/HDLRuby/hdr_samples/adder_assign_error.rb +11 -0
- data/lib/HDLRuby/hdr_samples/adder_bench.rb +27 -0
- data/lib/HDLRuby/hdr_samples/adder_gen.rb +7 -0
- data/lib/HDLRuby/hdr_samples/adder_nodef_error.rb +7 -0
- data/lib/HDLRuby/hdr_samples/addsub.rb +19 -0
- data/lib/HDLRuby/hdr_samples/addsubz.rb +22 -0
- data/lib/HDLRuby/hdr_samples/alu.rb +47 -0
- data/lib/HDLRuby/hdr_samples/calculator.rb +48 -0
- data/lib/HDLRuby/hdr_samples/counter_bench.rb +83 -0
- data/lib/HDLRuby/hdr_samples/dff.rb +9 -0
- data/lib/HDLRuby/hdr_samples/dff_bench.rb +66 -0
- data/lib/HDLRuby/hdr_samples/dff_counter.rb +20 -0
- data/lib/HDLRuby/hdr_samples/include.rb +14 -0
- data/lib/HDLRuby/hdr_samples/instance_open.rb +23 -0
- data/lib/HDLRuby/hdr_samples/mei8.rb +256 -0
- data/lib/HDLRuby/hdr_samples/mei8_bench.rb +309 -0
- data/lib/HDLRuby/hdr_samples/multer_gen.rb +8 -0
- data/lib/HDLRuby/hdr_samples/multer_seq.rb +29 -0
- data/lib/HDLRuby/hdr_samples/neural/a.rb +9 -0
- data/lib/HDLRuby/hdr_samples/neural/a_sub.rb +5 -0
- data/lib/HDLRuby/hdr_samples/neural/bw.rb +23 -0
- data/lib/HDLRuby/hdr_samples/neural/counter.rb +16 -0
- data/lib/HDLRuby/hdr_samples/neural/dadz.rb +9 -0
- data/lib/HDLRuby/hdr_samples/neural/dadz_sub.rb +4 -0
- data/lib/HDLRuby/hdr_samples/neural/forward.rb +153 -0
- data/lib/HDLRuby/hdr_samples/neural/forward_sub.rb +62 -0
- data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand.rb +41 -0
- data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand_typedef.rb +47 -0
- data/lib/HDLRuby/hdr_samples/neural/mem.rb +30 -0
- data/lib/HDLRuby/hdr_samples/neural/random.rb +23 -0
- data/lib/HDLRuby/hdr_samples/neural/selector.rb +29 -0
- data/lib/HDLRuby/hdr_samples/neural/sigmoid.rb +20 -0
- data/lib/HDLRuby/hdr_samples/neural/z.rb +33 -0
- data/lib/HDLRuby/hdr_samples/prog.obj +256 -0
- data/lib/HDLRuby/hdr_samples/ram.rb +18 -0
- data/lib/HDLRuby/hdr_samples/register_with_code_bench.rb +98 -0
- data/lib/HDLRuby/hdr_samples/rom.rb +10 -0
- data/lib/HDLRuby/hdr_samples/struct.rb +14 -0
- data/lib/HDLRuby/hdr_samples/sumprod.rb +29 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_bench.rb +103 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_cpu_bench.rb +261 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_cpusim_bench.rb +302 -0
- data/lib/HDLRuby/hdr_samples/system_open.rb +11 -0
- data/lib/HDLRuby/hdr_samples/tuple.rb +16 -0
- data/lib/HDLRuby/hdr_samples/with_channel.rb +118 -0
- data/lib/HDLRuby/hdr_samples/with_class.rb +199 -0
- data/lib/HDLRuby/hdr_samples/with_decoder.rb +17 -0
- data/lib/HDLRuby/hdr_samples/with_fsm.rb +34 -0
- data/lib/HDLRuby/hdr_samples/with_reconf.rb +103 -0
- data/lib/HDLRuby/hdrcc.rb +623 -0
- data/lib/HDLRuby/high_samples/_adder_fault.rb +23 -0
- data/lib/HDLRuby/high_samples/_generic_transmission2.rb +146 -0
- data/lib/HDLRuby/high_samples/adder.rb +21 -0
- data/lib/HDLRuby/high_samples/adder_common_errors.rb +25 -0
- data/lib/HDLRuby/high_samples/addsub.rb +33 -0
- data/lib/HDLRuby/high_samples/addsubz.rb +37 -0
- data/lib/HDLRuby/high_samples/after.rb +28 -0
- data/lib/HDLRuby/high_samples/all_signals.rb +29 -0
- data/lib/HDLRuby/high_samples/alu.rb +61 -0
- data/lib/HDLRuby/high_samples/anonymous.rb +41 -0
- data/lib/HDLRuby/high_samples/before.rb +28 -0
- data/lib/HDLRuby/high_samples/blockblock.rb +26 -0
- data/lib/HDLRuby/high_samples/bugs/dadz.rb +22 -0
- data/lib/HDLRuby/high_samples/bugs/misample_instan.rb +20 -0
- data/lib/HDLRuby/high_samples/bugs/misample_updown.rb +22 -0
- data/lib/HDLRuby/high_samples/bugs/sample_add.rb +16 -0
- data/lib/HDLRuby/high_samples/bugs/sample_barrel.rb +13 -0
- data/lib/HDLRuby/high_samples/bugs/sample_daice.rb +57 -0
- data/lib/HDLRuby/high_samples/bugs/sample_kumiawase.rb +52 -0
- data/lib/HDLRuby/high_samples/bugs/sample_multi.rb +18 -0
- data/lib/HDLRuby/high_samples/bugs/sample_sub.rb +14 -0
- data/lib/HDLRuby/high_samples/bugs/z2.rb +32 -0
- data/lib/HDLRuby/high_samples/case.rb +32 -0
- data/lib/HDLRuby/high_samples/case2.rb +30 -0
- data/lib/HDLRuby/high_samples/change.rb +23 -0
- data/lib/HDLRuby/high_samples/clocks.rb +35 -0
- data/lib/HDLRuby/high_samples/comparer.rb +21 -0
- data/lib/HDLRuby/high_samples/conditionals.rb +29 -0
- data/lib/HDLRuby/high_samples/dff.rb +23 -0
- data/lib/HDLRuby/high_samples/each.rb +28 -0
- data/lib/HDLRuby/high_samples/exporter.rb +42 -0
- data/lib/HDLRuby/high_samples/functions.rb +60 -0
- data/lib/HDLRuby/high_samples/if_seq.rb +26 -0
- data/lib/HDLRuby/high_samples/inherit_as_dff.rb +32 -0
- data/lib/HDLRuby/high_samples/inherit_dff.rb +36 -0
- data/lib/HDLRuby/high_samples/instance.rb +37 -0
- data/lib/HDLRuby/high_samples/memory.rb +64 -0
- data/lib/HDLRuby/high_samples/multi_file.rb +27 -0
- data/lib/HDLRuby/high_samples/overload.rb +32 -0
- data/lib/HDLRuby/high_samples/paper_after.rb +49 -0
- data/lib/HDLRuby/high_samples/ram.rb +27 -0
- data/lib/HDLRuby/high_samples/registers.rb +139 -0
- data/lib/HDLRuby/high_samples/rom.rb +23 -0
- data/lib/HDLRuby/high_samples/scopeblockname.rb +37 -0
- data/lib/HDLRuby/high_samples/scopescope.rb +26 -0
- data/lib/HDLRuby/high_samples/shift.rb +31 -0
- data/lib/HDLRuby/high_samples/shift2.rb +40 -0
- data/lib/HDLRuby/high_samples/simple_instance.rb +31 -0
- data/lib/HDLRuby/high_samples/test_all.sh +10 -0
- data/lib/HDLRuby/high_samples/typedef.rb +24 -0
- data/lib/HDLRuby/high_samples/values.rb +70 -0
- data/lib/HDLRuby/high_samples/vector.rb +22 -0
- data/lib/HDLRuby/high_samples/with_decoder.rb +30 -0
- data/lib/HDLRuby/high_samples/with_fsm.rb +46 -0
- data/lib/HDLRuby/high_samples/with_pipe.rb +43 -0
- data/lib/HDLRuby/high_samples/with_seq.rb +25 -0
- data/lib/HDLRuby/hruby_bstr.rb +1085 -0
- data/lib/HDLRuby/hruby_check.rb +317 -0
- data/lib/HDLRuby/hruby_db.rb +432 -0
- data/lib/HDLRuby/hruby_error.rb +44 -0
- data/lib/HDLRuby/hruby_high.rb +4103 -0
- data/lib/HDLRuby/hruby_low.rb +4735 -0
- data/lib/HDLRuby/hruby_low2c.rb +1986 -0
- data/lib/HDLRuby/hruby_low2high.rb +738 -0
- data/lib/HDLRuby/hruby_low2seq.rb +248 -0
- data/lib/HDLRuby/hruby_low2sym.rb +126 -0
- data/lib/HDLRuby/hruby_low2vhd.rb +1437 -0
- data/lib/HDLRuby/hruby_low_bool2select.rb +295 -0
- data/lib/HDLRuby/hruby_low_cleanup.rb +193 -0
- data/lib/HDLRuby/hruby_low_fix_types.rb +437 -0
- data/lib/HDLRuby/hruby_low_mutable.rb +1803 -0
- data/lib/HDLRuby/hruby_low_resolve.rb +165 -0
- data/lib/HDLRuby/hruby_low_skeleton.rb +129 -0
- data/lib/HDLRuby/hruby_low_with_bool.rb +141 -0
- data/lib/HDLRuby/hruby_low_with_port.rb +167 -0
- data/lib/HDLRuby/hruby_low_with_var.rb +302 -0
- data/lib/HDLRuby/hruby_low_without_bit2vector.rb +88 -0
- data/lib/HDLRuby/hruby_low_without_concat.rb +162 -0
- data/lib/HDLRuby/hruby_low_without_connection.rb +113 -0
- data/lib/HDLRuby/hruby_low_without_namespace.rb +718 -0
- data/lib/HDLRuby/hruby_low_without_outread.rb +107 -0
- data/lib/HDLRuby/hruby_low_without_select.rb +206 -0
- data/lib/HDLRuby/hruby_serializer.rb +398 -0
- data/lib/HDLRuby/hruby_tools.rb +37 -0
- data/lib/HDLRuby/hruby_types.rb +239 -0
- data/lib/HDLRuby/hruby_values.rb +64 -0
- data/lib/HDLRuby/hruby_verilog.rb +1888 -0
- data/lib/HDLRuby/hruby_verilog_name.rb +52 -0
- data/lib/HDLRuby/low_samples/adder.yaml +97 -0
- data/lib/HDLRuby/low_samples/after.yaml +228 -0
- data/lib/HDLRuby/low_samples/before.yaml +223 -0
- data/lib/HDLRuby/low_samples/blockblock.yaml +48 -0
- data/lib/HDLRuby/low_samples/bugs/sample_add.yaml +97 -0
- data/lib/HDLRuby/low_samples/bugs/sample_daice.yaml +444 -0
- data/lib/HDLRuby/low_samples/bugs/sample_kumiawase.yaml +332 -0
- data/lib/HDLRuby/low_samples/bugs/sample_sub.yaml +97 -0
- data/lib/HDLRuby/low_samples/bugs/seqpar.yaml +184 -0
- data/lib/HDLRuby/low_samples/case.yaml +327 -0
- data/lib/HDLRuby/low_samples/change.yaml +135 -0
- data/lib/HDLRuby/low_samples/clocks.yaml +674 -0
- data/lib/HDLRuby/low_samples/cloner.rb +22 -0
- data/lib/HDLRuby/low_samples/comparer.yaml +85 -0
- data/lib/HDLRuby/low_samples/conditionals.yaml +133 -0
- data/lib/HDLRuby/low_samples/dff.yaml +107 -0
- data/lib/HDLRuby/low_samples/each.yaml +1328 -0
- data/lib/HDLRuby/low_samples/exporter.yaml +226 -0
- data/lib/HDLRuby/low_samples/functions.yaml +298 -0
- data/lib/HDLRuby/low_samples/generic_transmission.yaml +597 -0
- data/lib/HDLRuby/low_samples/inherit_as_dff.yaml +125 -0
- data/lib/HDLRuby/low_samples/inherit_dff.yaml +107 -0
- data/lib/HDLRuby/low_samples/load_yaml.rb +11 -0
- data/lib/HDLRuby/low_samples/memory.yaml +678 -0
- data/lib/HDLRuby/low_samples/namespace_extractor.rb +23 -0
- data/lib/HDLRuby/low_samples/overload.yaml +226 -0
- data/lib/HDLRuby/low_samples/paper_after.yaml +431 -0
- data/lib/HDLRuby/low_samples/port_maker.rb +14 -0
- data/lib/HDLRuby/low_samples/ram.yaml +207 -0
- data/lib/HDLRuby/low_samples/registers.yaml +228 -0
- data/lib/HDLRuby/low_samples/rom.yaml +2950 -0
- data/lib/HDLRuby/low_samples/shift.yaml +230 -0
- data/lib/HDLRuby/low_samples/shift2.yaml +2095 -0
- data/lib/HDLRuby/low_samples/simple_instance.yaml +102 -0
- data/lib/HDLRuby/low_samples/test_all.sh +43 -0
- data/lib/HDLRuby/low_samples/typedef.yaml +115 -0
- data/lib/HDLRuby/low_samples/values.yaml +577 -0
- data/lib/HDLRuby/low_samples/variable_maker.rb +14 -0
- data/lib/HDLRuby/low_samples/vector.yaml +56 -0
- data/lib/HDLRuby/low_samples/with_seq.yaml +188 -0
- data/lib/HDLRuby/low_samples/yaml2hdr.rb +10 -0
- data/lib/HDLRuby/low_samples/yaml2vhd.rb +19 -0
- data/lib/HDLRuby/sim/Makefile +19 -0
- data/lib/HDLRuby/sim/hruby_sim.h +590 -0
- data/lib/HDLRuby/sim/hruby_sim_calc.c +2362 -0
- data/lib/HDLRuby/sim/hruby_sim_core.c +589 -0
- data/lib/HDLRuby/sim/hruby_sim_list.c +93 -0
- data/lib/HDLRuby/sim/hruby_sim_vizualize.c +91 -0
- data/lib/HDLRuby/sim/hruby_value_pool.c +64 -0
- data/lib/HDLRuby/std/channel.rb +354 -0
- data/lib/HDLRuby/std/clocks.rb +165 -0
- data/lib/HDLRuby/std/counters.rb +82 -0
- data/lib/HDLRuby/std/decoder.rb +214 -0
- data/lib/HDLRuby/std/fsm.rb +516 -0
- data/lib/HDLRuby/std/pipeline.rb +220 -0
- data/lib/HDLRuby/std/reconf.rb +309 -0
- data/lib/HDLRuby/test_hruby_bstr.rb +2259 -0
- data/lib/HDLRuby/test_hruby_high.rb +594 -0
- data/lib/HDLRuby/test_hruby_high_low.rb +99 -0
- data/lib/HDLRuby/test_hruby_low.rb +934 -0
- data/lib/HDLRuby/v_samples/adder.v +10 -0
- data/lib/HDLRuby/v_samples/dff.v +12 -0
- data/lib/HDLRuby/v_samples/ram.v +20 -0
- data/lib/HDLRuby/v_samples/rom.v +270 -0
- data/lib/HDLRuby/version.rb +3 -0
- data/lib/HDLRuby.rb +11 -0
- data/makedoc +1 -0
- data/metadata.yaml +4 -0
- metadata +299 -0
|
@@ -0,0 +1,516 @@
|
|
|
1
|
+
module HDLRuby::High::Std
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
# Standard HDLRuby::High library: fsm generator.
|
|
5
|
+
#
|
|
6
|
+
########################################################################
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
# Describes a high-level fsm type.
|
|
11
|
+
class FsmT
|
|
12
|
+
include HDLRuby::High::HScope_missing
|
|
13
|
+
|
|
14
|
+
# The state class
|
|
15
|
+
class State
|
|
16
|
+
attr_accessor :value, :name, :code, :gotos
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# The name of the FSM type.
|
|
20
|
+
attr_reader :name
|
|
21
|
+
|
|
22
|
+
# The namespace associated with the FSM
|
|
23
|
+
attr_reader :namespace
|
|
24
|
+
|
|
25
|
+
# The reset codes for the synchronous and the asynchronous operative
|
|
26
|
+
# parts of the fsm
|
|
27
|
+
attr_reader :reset_sync, :reset_async
|
|
28
|
+
|
|
29
|
+
# The current and next state signals.
|
|
30
|
+
attr_accessor :cur_state_sig, :next_state_sig, :work_state
|
|
31
|
+
|
|
32
|
+
# Creates a new fsm type with +name+.
|
|
33
|
+
# +options+ allows to specify the type of fsm:
|
|
34
|
+
# synchronous (default) / asynchronous and
|
|
35
|
+
# mono-front(default) / dual front
|
|
36
|
+
def initialize(name,*options)
|
|
37
|
+
# Check and set the name
|
|
38
|
+
@name = name.to_sym
|
|
39
|
+
# Check and set the type of fsm depending of the options.
|
|
40
|
+
@dual = false
|
|
41
|
+
@type = :sync
|
|
42
|
+
options.each do |opt|
|
|
43
|
+
case opt
|
|
44
|
+
when :sync,:synchronous then
|
|
45
|
+
@type = :sync
|
|
46
|
+
when :async, :asynchronous then
|
|
47
|
+
@type = :async
|
|
48
|
+
when :dual then
|
|
49
|
+
@dual = true
|
|
50
|
+
else
|
|
51
|
+
raise AnyError, "Invalid option for a fsm: :#{type}"
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Initialize the internals of the FSM.
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# Initialize the environment for building the FSM
|
|
59
|
+
|
|
60
|
+
# The main states.
|
|
61
|
+
@states = []
|
|
62
|
+
|
|
63
|
+
# The extra synchronous states.
|
|
64
|
+
@extra_syncs = []
|
|
65
|
+
# The extra asynchronous states.
|
|
66
|
+
@extra_asyncs = []
|
|
67
|
+
|
|
68
|
+
# The default code of the operative part.
|
|
69
|
+
@default_codes = []
|
|
70
|
+
|
|
71
|
+
# The current and next state signals
|
|
72
|
+
@cur_state_sig = nil
|
|
73
|
+
@next_state_sig = nil
|
|
74
|
+
|
|
75
|
+
# The event synchronizing the fsm
|
|
76
|
+
@mk_ev = proc { $clk.posedge }
|
|
77
|
+
|
|
78
|
+
# The reset check.
|
|
79
|
+
@mk_rst = proc { $rst }
|
|
80
|
+
|
|
81
|
+
# The code executed in case of reset.
|
|
82
|
+
# (By default, nothing).
|
|
83
|
+
@reset_sync = nil
|
|
84
|
+
@reset_async = nil
|
|
85
|
+
|
|
86
|
+
# Creates the namespace to execute the fsm block in.
|
|
87
|
+
@namespace = Namespace.new(self)
|
|
88
|
+
|
|
89
|
+
# Generates the function for setting up the fsm
|
|
90
|
+
# provided there is a name.
|
|
91
|
+
obj = self # For using the right self within the proc
|
|
92
|
+
HDLRuby::High.space_reg(@name) do |&ruby_block|
|
|
93
|
+
if ruby_block then
|
|
94
|
+
# Builds the fsm.
|
|
95
|
+
obj.build(&ruby_block)
|
|
96
|
+
else
|
|
97
|
+
# Return the fsm as is.
|
|
98
|
+
return obj
|
|
99
|
+
end
|
|
100
|
+
end unless name.empty?
|
|
101
|
+
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
## builds the fsm by executing +ruby_block+.
|
|
105
|
+
def build(&ruby_block)
|
|
106
|
+
# Use local variable for accessing the attribute since they will
|
|
107
|
+
# be hidden when opening the sytem.
|
|
108
|
+
states = @states
|
|
109
|
+
namespace = @namespace
|
|
110
|
+
this = self
|
|
111
|
+
mk_ev = @mk_ev
|
|
112
|
+
mk_rst = @mk_rst
|
|
113
|
+
type = @type
|
|
114
|
+
dual = @dual
|
|
115
|
+
extra_syncs = @extra_syncs
|
|
116
|
+
extra_asyncs = @extra_asyncs
|
|
117
|
+
default_codes = @default_codes
|
|
118
|
+
|
|
119
|
+
return_value = nil
|
|
120
|
+
|
|
121
|
+
# Enters the current system
|
|
122
|
+
HDLRuby::High.cur_system.open do
|
|
123
|
+
sub do
|
|
124
|
+
HDLRuby::High.space_push(namespace)
|
|
125
|
+
# Execute the instantiation block
|
|
126
|
+
return_value =HDLRuby::High.top_user.instance_exec(&ruby_block)
|
|
127
|
+
|
|
128
|
+
# Expands the extra state processing so that al all the
|
|
129
|
+
# parts of the state machine are in par (clear synthesis).
|
|
130
|
+
[extra_syncs,extra_asyncs].each do |extras|
|
|
131
|
+
# Set the values of the extra states from their name.
|
|
132
|
+
extras.each do |extra|
|
|
133
|
+
st = states.find {|st| st.name == extra.name }
|
|
134
|
+
unless st then
|
|
135
|
+
raise "Unknown state name: #{extra.name}"
|
|
136
|
+
end
|
|
137
|
+
extra.value = st.value
|
|
138
|
+
end
|
|
139
|
+
# Fills the holes in the extra syncs and asyncs.
|
|
140
|
+
if extras.any? then
|
|
141
|
+
# Sort by value in a new array using counter sort.
|
|
142
|
+
results = [ nil ] * states.size
|
|
143
|
+
extras.each {|st| results[st.value] = st }
|
|
144
|
+
# Fill the whole with empty states.
|
|
145
|
+
results.map!.with_index do |st,i|
|
|
146
|
+
unless st then
|
|
147
|
+
st = State.new
|
|
148
|
+
st.value = i
|
|
149
|
+
st.code = proc {}
|
|
150
|
+
end
|
|
151
|
+
st
|
|
152
|
+
end
|
|
153
|
+
# Replace the content of extras
|
|
154
|
+
extras.clear
|
|
155
|
+
results.each {|st| extras << st }
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Create the state register.
|
|
160
|
+
name = HDLRuby.uniq_name
|
|
161
|
+
# Declare the state register.
|
|
162
|
+
this.cur_state_sig = [states.size.width].inner(name)
|
|
163
|
+
# Declare the next state wire.
|
|
164
|
+
name = HDLRuby.uniq_name
|
|
165
|
+
this.next_state_sig = [states.size.width].inner(name)
|
|
166
|
+
|
|
167
|
+
# Create the fsm code
|
|
168
|
+
|
|
169
|
+
# Control part: update of the state.
|
|
170
|
+
par(mk_ev.call) do
|
|
171
|
+
hif(mk_rst.call) do
|
|
172
|
+
# Reset: current state is to put to 0.
|
|
173
|
+
this.cur_state_sig <= 0
|
|
174
|
+
end
|
|
175
|
+
helse do
|
|
176
|
+
# No reset: current state is updated with
|
|
177
|
+
# next state value.
|
|
178
|
+
this.cur_state_sig <= this.next_state_sig
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Operative main-part: one case per state.
|
|
183
|
+
# (clock-dependent if synchronous mode).
|
|
184
|
+
if type == :sync then
|
|
185
|
+
# Synchronous case.
|
|
186
|
+
event = mk_ev.call
|
|
187
|
+
event = event.invert if dual
|
|
188
|
+
else
|
|
189
|
+
# Asynchronous case: no event required.
|
|
190
|
+
event = []
|
|
191
|
+
end
|
|
192
|
+
# The process
|
|
193
|
+
par(*event) do
|
|
194
|
+
# The operative code.
|
|
195
|
+
oper_code = proc do
|
|
196
|
+
# The default code.
|
|
197
|
+
default_codes.each(&:call)
|
|
198
|
+
# Depending on the state.
|
|
199
|
+
hcase(this.cur_state_sig)
|
|
200
|
+
states.each do |st|
|
|
201
|
+
# Register the working state (for the gotos)
|
|
202
|
+
this.work_state = st
|
|
203
|
+
hwhen(st.value) do
|
|
204
|
+
# Generate the content of the state.
|
|
205
|
+
st.code.call
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
# Is there reset code?
|
|
210
|
+
if type == :sync and this.reset_sync then
|
|
211
|
+
# Yes in case of synchronous fsm,
|
|
212
|
+
# use it before the operative code.
|
|
213
|
+
hif(mk_rst.call) do
|
|
214
|
+
this.reset_sync.call
|
|
215
|
+
end
|
|
216
|
+
helse(&oper_code)
|
|
217
|
+
elsif type == :async and this.reset_async then
|
|
218
|
+
# Yes in case of asynchronous fsm,
|
|
219
|
+
# use it before the operative code.
|
|
220
|
+
hif(mk_rst.call) do
|
|
221
|
+
this.reset_async.call
|
|
222
|
+
end
|
|
223
|
+
helse(&oper_code)
|
|
224
|
+
else
|
|
225
|
+
# Use only the operative code.
|
|
226
|
+
oper_code.call
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# Control part: computation of the next state.
|
|
231
|
+
# (clock-independent)
|
|
232
|
+
hcase(this.cur_state_sig)
|
|
233
|
+
states.each do |st|
|
|
234
|
+
hwhen(st.value) do
|
|
235
|
+
if st.gotos.any? then
|
|
236
|
+
# Gotos were present, use them.
|
|
237
|
+
st.gotos.each(&:call)
|
|
238
|
+
else
|
|
239
|
+
# No gotos, by default the next step is
|
|
240
|
+
# current + 1
|
|
241
|
+
# this.next_state_sig <= mux(mk_rst.call , 0, this.cur_state_sig + 1)
|
|
242
|
+
this.next_state_sig <= this.cur_state_sig + 1
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
# By default set the next state to 0.
|
|
247
|
+
helse do
|
|
248
|
+
this.next_state_sig <= 0
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# Operative additional parts.
|
|
252
|
+
# Extra synchronous operative part.
|
|
253
|
+
if extra_syncs.any? then
|
|
254
|
+
event = mk_ev.call
|
|
255
|
+
event = event.invert if @dual
|
|
256
|
+
# The extra code.
|
|
257
|
+
par(*event) do
|
|
258
|
+
# Build the extra synchronous part.
|
|
259
|
+
sync_code = proc do
|
|
260
|
+
hcase(this.cur_state_sig)
|
|
261
|
+
extra_syncs.each do |st|
|
|
262
|
+
hwhen(st.value) do
|
|
263
|
+
# Generate the content of the state.
|
|
264
|
+
st.code.call
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
# Place it.
|
|
269
|
+
if this.reset_sync then
|
|
270
|
+
# There some synchronous reset code, use
|
|
271
|
+
# it.
|
|
272
|
+
hif(mk_rst.call) do
|
|
273
|
+
this.reset_sync.call
|
|
274
|
+
end
|
|
275
|
+
helse(&sync_code)
|
|
276
|
+
else
|
|
277
|
+
# No syncrhonous code, place the extra
|
|
278
|
+
# synchronous states as is.
|
|
279
|
+
sync_code.call
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
# Extra asynchronous operative part.
|
|
285
|
+
if extra_asyncs.any? then
|
|
286
|
+
par do
|
|
287
|
+
# Build the extra synchronous part.
|
|
288
|
+
async_code = proc do
|
|
289
|
+
hcase(this.cur_state_sig)
|
|
290
|
+
extra_asyncs.each do |st|
|
|
291
|
+
hwhen(st.value) do
|
|
292
|
+
# Generate the content of the state.
|
|
293
|
+
st.code.call
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
# Place it with possible reset.
|
|
298
|
+
if this.reset_async then
|
|
299
|
+
# There some synchronous reset code, use
|
|
300
|
+
# it.
|
|
301
|
+
hif(mk_rst.call) do
|
|
302
|
+
this.reset_async.call
|
|
303
|
+
end
|
|
304
|
+
helse(&sync_code)
|
|
305
|
+
else
|
|
306
|
+
# No syncrhonous code, place the extra
|
|
307
|
+
# synchronous states as is.
|
|
308
|
+
sync_code.call
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
HDLRuby::High.space_pop
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
return return_value
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
## The interface for building the fsm
|
|
322
|
+
|
|
323
|
+
# Sets the event synchronizing the fsm.
|
|
324
|
+
def for_event(event = nil,&ruby_block)
|
|
325
|
+
if event then
|
|
326
|
+
# An event is passed as argument, use it.
|
|
327
|
+
@mk_ev = proc { event.to_event }
|
|
328
|
+
else
|
|
329
|
+
# No event given, use the ruby_block as event generator.
|
|
330
|
+
@mk_ev = ruby_block
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
# Sets the reset.
|
|
335
|
+
def for_reset(reset = nil,&ruby_block)
|
|
336
|
+
if reset then
|
|
337
|
+
# An reset is passed as argument, use it.
|
|
338
|
+
@mk_rst = proc { reset.to_expr }
|
|
339
|
+
else
|
|
340
|
+
# No reset given, use the ruby_block as event generator.
|
|
341
|
+
@mk_rst = ruby_block
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
# Adds a code to be executed in case of reset.
|
|
346
|
+
# +type+ indicates if it is the synchronous part or the
|
|
347
|
+
# asynchronous part that is to reset.
|
|
348
|
+
def reset(type = @type,&ruby_block)
|
|
349
|
+
if type == :sync or type == :synchronous then
|
|
350
|
+
# Reset of the synchronous part.
|
|
351
|
+
if @reset_sync then
|
|
352
|
+
raise AnyError.new("Reset of the synchronous part already declared.")
|
|
353
|
+
end
|
|
354
|
+
@reset_sync = ruby_block
|
|
355
|
+
elsif type == :async or type == :asynchronous then
|
|
356
|
+
# Reset if the asynchronous part.
|
|
357
|
+
if @reset_async then
|
|
358
|
+
raise AnyError.new("Reset of the asynchronosu part already declared.")
|
|
359
|
+
end
|
|
360
|
+
else
|
|
361
|
+
raise AnyError.new("Invalid fsm type for declaring a reset code: #{type}")
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
# Adds a default operative code.
|
|
366
|
+
def default(&ruby_block)
|
|
367
|
+
@default_codes << ruby_block
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
# Declares a new state with +name+ and executing +ruby_block+.
|
|
371
|
+
def state(name = :"", &ruby_block)
|
|
372
|
+
# Create the resulting state
|
|
373
|
+
result = State.new
|
|
374
|
+
# Its value is the current number of states
|
|
375
|
+
result.value = @states.size
|
|
376
|
+
result.name = name.to_sym
|
|
377
|
+
result.code = ruby_block
|
|
378
|
+
result.gotos = []
|
|
379
|
+
# Add it to the list of states.
|
|
380
|
+
@states << result
|
|
381
|
+
# Return it.
|
|
382
|
+
return result
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
# Declares an extra synchronous code to execute for state +name+.
|
|
386
|
+
def sync(name, &ruby_block)
|
|
387
|
+
# Create the resulting state.
|
|
388
|
+
result = State.new
|
|
389
|
+
result.name = name.to_sym
|
|
390
|
+
result.code = ruby_block
|
|
391
|
+
# Add it to the lis of extra synchronous states.
|
|
392
|
+
@extra_syncs << result
|
|
393
|
+
# Return it
|
|
394
|
+
return result
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
# Declares an extra asynchronous code to execute for state +name+.
|
|
398
|
+
def async(name, &ruby_block)
|
|
399
|
+
# Create the resulting state.
|
|
400
|
+
result = State.new
|
|
401
|
+
result.name = name.to_sym
|
|
402
|
+
result.code = ruby_block
|
|
403
|
+
# Add it to the lis of extra synchronous states.
|
|
404
|
+
@extra_asyncs << result
|
|
405
|
+
# Return it
|
|
406
|
+
return result
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
# Sets the next state. Arguments can be:
|
|
410
|
+
#
|
|
411
|
+
# +name+: the name of the next state.
|
|
412
|
+
# +expr+, +names+: an expression with the list of the next statements
|
|
413
|
+
# in order of the value of the expression, the last
|
|
414
|
+
# one being necesserily the default case.
|
|
415
|
+
def goto(*args)
|
|
416
|
+
# Make reference to the fsm attributes.
|
|
417
|
+
next_state_sig = @next_state_sig
|
|
418
|
+
states = @states
|
|
419
|
+
# Add the code of the goto to the working state.
|
|
420
|
+
@work_state.gotos << proc do
|
|
421
|
+
# Depending on the first argument type.
|
|
422
|
+
unless args[0].is_a?(Symbol) then
|
|
423
|
+
# expr + names arguments.
|
|
424
|
+
# Get the predicate
|
|
425
|
+
pred = args.shift
|
|
426
|
+
# hif or hcase?
|
|
427
|
+
if args.size <= 2 then
|
|
428
|
+
# 2 or less cases, generate an hif
|
|
429
|
+
arg = args.shift
|
|
430
|
+
hif(pred) do
|
|
431
|
+
next_state_sig <=
|
|
432
|
+
(states.detect { |st| st.name == arg }).value
|
|
433
|
+
end
|
|
434
|
+
arg = args.shift
|
|
435
|
+
if arg then
|
|
436
|
+
# There is an else.
|
|
437
|
+
helse do
|
|
438
|
+
next_state_sig <=
|
|
439
|
+
(states.detect { |st| st.name == arg }).value
|
|
440
|
+
end
|
|
441
|
+
end
|
|
442
|
+
else
|
|
443
|
+
# More than 2, generate a hcase
|
|
444
|
+
hcase (pred)
|
|
445
|
+
args[0..-2].each.with_index do |arg,i|
|
|
446
|
+
# Ensure the argument is a symbol.
|
|
447
|
+
arg = arg.to_sym
|
|
448
|
+
# Make the when statement.
|
|
449
|
+
hwhen(i) do
|
|
450
|
+
next_state_sig <=
|
|
451
|
+
(states.detect { |st| st.name == arg }).value
|
|
452
|
+
end
|
|
453
|
+
end
|
|
454
|
+
# The last name is the default case.
|
|
455
|
+
# Ensure it is a symbol.
|
|
456
|
+
arg = args[-1].to_sym
|
|
457
|
+
# Make the default statement.
|
|
458
|
+
helse do
|
|
459
|
+
next_state_sig <=
|
|
460
|
+
(states.detect { |st| st.name == arg }).value
|
|
461
|
+
end
|
|
462
|
+
end
|
|
463
|
+
else
|
|
464
|
+
# single name argument, check it.
|
|
465
|
+
raise AnyError, "Invalid argument for a goto: if no expression is given only a single name can be used." if args.size > 1
|
|
466
|
+
# Ensure the name is a symbol.
|
|
467
|
+
name = args[0].to_sym
|
|
468
|
+
# Get the state with name.
|
|
469
|
+
next_state_sig <= (states.detect { |st| st.name == name }).value
|
|
470
|
+
end
|
|
471
|
+
end
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
## Declare a new fsm.
|
|
478
|
+
# The arguments can be any of (but in this order):
|
|
479
|
+
#
|
|
480
|
+
# - +name+:: name.
|
|
481
|
+
# - +clk+:: clock.
|
|
482
|
+
# - +event+:: clock event.
|
|
483
|
+
# - +rst+:: reset. (must be declared AFTER clock or clock event).
|
|
484
|
+
#
|
|
485
|
+
# If provided, +ruby_block+ the fsm is directly instantiated with it.
|
|
486
|
+
def fsm(*args, &ruby_block)
|
|
487
|
+
# Sets the name if any
|
|
488
|
+
unless args[0].respond_to?(:to_event) then
|
|
489
|
+
name = args.shift.to_sym
|
|
490
|
+
else
|
|
491
|
+
name = :""
|
|
492
|
+
end
|
|
493
|
+
# Get the options from the arguments.
|
|
494
|
+
options, args = args.partition {|arg| arg.is_a?(Symbol) }
|
|
495
|
+
# Create the fsm.
|
|
496
|
+
fsmI = FsmT.new(name,*options)
|
|
497
|
+
|
|
498
|
+
# Process the clock event if any.
|
|
499
|
+
unless args.empty? then
|
|
500
|
+
fsmI.for_event(args.shift)
|
|
501
|
+
end
|
|
502
|
+
# Process the reset if any.
|
|
503
|
+
unless args.empty? then
|
|
504
|
+
fsmI.for_reset(args.shift)
|
|
505
|
+
end
|
|
506
|
+
# Is there a ruby block?
|
|
507
|
+
if ruby_block then
|
|
508
|
+
# Yes, generate the fsm.
|
|
509
|
+
fsmI.build(&ruby_block)
|
|
510
|
+
else
|
|
511
|
+
# No return the fsm structure for later generation.
|
|
512
|
+
return fsmI
|
|
513
|
+
end
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
end
|