soc_maker 0.1.1

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 (116) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/History.txt +4 -0
  4. data/LICENSE +678 -0
  5. data/README.rdoc +228 -0
  6. data/Rakefile +46 -0
  7. data/bin/soc_maker_cli +80 -0
  8. data/bin/soc_maker_parser +85 -0
  9. data/core_lib/cores/adv_debug_sys/01_adv_debug_sys.yaml +245 -0
  10. data/core_lib/cores/or1200_rel2/01_or1200.yaml +208 -0
  11. data/core_lib/cores/or1200_rel2/02_or1200_files.yaml +421 -0
  12. data/core_lib/cores/or1200_rel2/03_or1200_sparam.yaml +188 -0
  13. data/core_lib/cores/or1200_rel2/or1200_defines.v.in +1799 -0
  14. data/core_lib/cores/ram_wb/ram_wb.yaml +102 -0
  15. data/core_lib/cores/ram_wb/ram_wb_b3.v.in +259 -0
  16. data/core_lib/cores/uart16550/01_uart16550.yaml +99 -0
  17. data/core_lib/cores/uart16550/02_uart16550_files.yaml +70 -0
  18. data/core_lib/cores/wb_connect/minsoc_tc_top.v +1802 -0
  19. data/core_lib/cores/wb_connect/wb_connect.yaml +733 -0
  20. data/core_lib/inc.yaml +13 -0
  21. data/core_lib/interfaces/clk_rst/clk.yaml +9 -0
  22. data/core_lib/interfaces/clk_rst/rst.yaml +9 -0
  23. data/core_lib/interfaces/clk_rst/single.yaml +7 -0
  24. data/core_lib/interfaces/debug/debug.yaml +32 -0
  25. data/core_lib/interfaces/jtag/jtag.yaml +13 -0
  26. data/core_lib/interfaces/jtag/jtag_tap.yaml +22 -0
  27. data/core_lib/interfaces/power/or_power.yaml +25 -0
  28. data/core_lib/interfaces/uart/uart.yaml +21 -0
  29. data/core_lib/interfaces/wishbone/wishbone_ma_b3.yaml +54 -0
  30. data/core_lib/interfaces/wishbone/wishbone_sl_b3.yaml +51 -0
  31. data/doc/class_arch.uml +5113 -0
  32. data/doc/fig/hierarchical.svg +273 -0
  33. data/examples/or1200_test/or1200_test.cmd +78 -0
  34. data/examples/or1200_test/or1200_test.rb +136 -0
  35. data/examples/or1200_test/rtl/or1200_test_top.vhd +274 -0
  36. data/examples/or1200_test/rtl/s3astarter.ucf +10 -0
  37. data/examples/or1200_test/rtl/xilinx_internal_jtag.v +438 -0
  38. data/examples/or1200_test/rtl/xilinx_internal_jtag_options.v +12 -0
  39. data/examples/or1200_test/sw/README.txt +35 -0
  40. data/examples/or1200_test/sw/bin2vmem.c +159 -0
  41. data/examples/or1200_test/sw/board.h +24 -0
  42. data/examples/or1200_test/sw/compile.sh +18 -0
  43. data/examples/or1200_test/sw/except.S +152 -0
  44. data/examples/or1200_test/sw/int.c +79 -0
  45. data/examples/or1200_test/sw/int.h +14 -0
  46. data/examples/or1200_test/sw/interconnect.h +17 -0
  47. data/examples/or1200_test/sw/interrupts.c +14 -0
  48. data/examples/or1200_test/sw/main.c +16 -0
  49. data/examples/or1200_test/sw/or1200.h +454 -0
  50. data/examples/or1200_test/sw/orp.ld +60 -0
  51. data/examples/or1200_test/sw/reset.S +112 -0
  52. data/examples/or1200_test/sw/support.c +123 -0
  53. data/examples/or1200_test/sw/support.h +33 -0
  54. data/examples/or1200_test/sw/tick.c +30 -0
  55. data/examples/or1200_test/sw/tick.h +2 -0
  56. data/examples/or1200_test/sw/uart.c +136 -0
  57. data/examples/or1200_test/sw/uart.h +126 -0
  58. data/lib/soc_maker.rb +324 -0
  59. data/lib/soc_maker/cli.rb +544 -0
  60. data/lib/soc_maker/conf.rb +310 -0
  61. data/lib/soc_maker/core_def.rb +579 -0
  62. data/lib/soc_maker/core_inst.rb +305 -0
  63. data/lib/soc_maker/err.rb +211 -0
  64. data/lib/soc_maker/hdl_coder.rb +500 -0
  65. data/lib/soc_maker/hdl_file.rb +166 -0
  66. data/lib/soc_maker/hdl_parser.rb +431 -0
  67. data/lib/soc_maker/ifc_def.rb +193 -0
  68. data/lib/soc_maker/ifc_port.rb +133 -0
  69. data/lib/soc_maker/ifc_spc.rb +180 -0
  70. data/lib/soc_maker/lib.rb +289 -0
  71. data/lib/soc_maker/lib_inc.rb +109 -0
  72. data/lib/soc_maker/parameter.rb +149 -0
  73. data/lib/soc_maker/soc_def.rb +847 -0
  74. data/lib/soc_maker/sparameter.rb +289 -0
  75. data/lib/soc_maker/version.rb +8 -0
  76. data/lib/soc_maker/ypp.rb +130 -0
  77. data/soc_maker.gemspec +28 -0
  78. data/spec/cli_cmds1.txt +39 -0
  79. data/spec/cli_spec.rb +49 -0
  80. data/spec/conf_spec.rb +44 -0
  81. data/spec/core_def_spec.rb +503 -0
  82. data/spec/core_inst_spec.rb +169 -0
  83. data/spec/hdl_file_spec.rb +154 -0
  84. data/spec/hdl_parser_spec.rb +201 -0
  85. data/spec/ifc_def_spec.rb +121 -0
  86. data/spec/ifc_port_spec.rb +92 -0
  87. data/spec/ifc_spc_spec.rb +196 -0
  88. data/spec/lib_inc_spec.rb +99 -0
  89. data/spec/lib_spec.rb +209 -0
  90. data/spec/parameter_spec.rb +86 -0
  91. data/spec/soc_def_spec.rb +611 -0
  92. data/spec/soc_maker_spec.rb +7 -0
  93. data/spec/sparameter_spec.rb +182 -0
  94. data/spec/spec_helper.rb +78 -0
  95. data/spec/test_soc.yaml +105 -0
  96. data/spec/test_soc2.yaml +60 -0
  97. data/spec/test_soc_lib/cores/core_A_rel1/00_core_a.yaml +75 -0
  98. data/spec/test_soc_lib/cores/core_A_rel1/01_core_a.yaml +57 -0
  99. data/spec/test_soc_lib/cores/core_A_rel1/core_a.vhd +29 -0
  100. data/spec/test_soc_lib/cores/core_A_rel1/core_a_pkg.vhd.src +3 -0
  101. data/spec/test_soc_lib/cores/core_A_rel1/core_a_pkg2.vhd.src +4 -0
  102. data/spec/test_soc_lib/cores/core_A_rel1/core_a_pkg3.v.src +6 -0
  103. data/spec/test_soc_lib/cores/core_B_rel1/core_b.vhd +25 -0
  104. data/spec/test_soc_lib/cores/core_B_rel1/core_b.yaml +36 -0
  105. data/spec/test_soc_lib/cores/core_C_v1/core_C.vhd +57 -0
  106. data/spec/test_soc_lib/cores/core_C_v1/core_c.yaml +42 -0
  107. data/spec/test_soc_lib/cores/soc_A/soc_A.yaml +12 -0
  108. data/spec/test_soc_lib/cores/soc_maker_include.yaml +6 -0
  109. data/spec/test_soc_lib/ifcs/core_AB_ifc/bidir_ifc.yaml +19 -0
  110. data/spec/test_soc_lib/ifcs/core_AB_ifc/core_AB_ifc.yaml +15 -0
  111. data/spec/test_soc_lib/ifcs/core_AB_ifc/top_ifc.yaml +9 -0
  112. data/spec/test_soc_lib/soc_maker_include.yaml +4 -0
  113. data/spec/yaml_examples.rb +367 -0
  114. data/spec/ypp_spec.rb +156 -0
  115. data/test/test_soc_maker.rb +0 -0
  116. metadata +255 -0
@@ -0,0 +1,126 @@
1
+ #define UART_RX 0 /* In: Receive buffer (DLAB=0) */
2
+ #define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */
3
+ #define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */
4
+ #define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */
5
+ #define UART_IER 1 /* Out: Interrupt Enable Register */
6
+ #define UART_IIR 2 /* In: Interrupt ID Register */
7
+ #define UART_FCR 2 /* Out: FIFO Control Register */
8
+ #define UART_EFR 2 /* I/O: Extended Features Register */
9
+ /* (DLAB=1, 16C660 only) */
10
+ #define UART_LCR 3 /* Out: Line Control Register */
11
+ #define UART_MCR 4 /* Out: Modem Control Register */
12
+ #define UART_LSR 5 /* In: Line Status Register */
13
+ #define UART_MSR 6 /* In: Modem Status Register */
14
+ #define UART_SCR 7 /* I/O: Scratch Register */
15
+
16
+ /*
17
+ * These are the definitions for the FIFO Control Register
18
+ * (16650 only)
19
+ */
20
+ #define UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */
21
+ #define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */
22
+ #define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */
23
+ #define UART_FCR_DMA_SELECT 0x08 /* For DMA applications */
24
+ #define UART_FCR_TRIGGER_MASK 0xC0 /* Mask for the FIFO trigger range */
25
+ #define UART_FCR_TRIGGER_1 0x00 /* Mask for trigger set at 1 */
26
+ #define UART_FCR_TRIGGER_4 0x40 /* Mask for trigger set at 4 */
27
+ #define UART_FCR_TRIGGER_8 0x80 /* Mask for trigger set at 8 */
28
+ #define UART_FCR_TRIGGER_14 0xC0 /* Mask for trigger set at 14 */
29
+
30
+ /* 16650 redefinitions */
31
+ #define UART_FCR6_R_TRIGGER_8 0x00 /* Mask for receive trigger set at 1 */
32
+ #define UART_FCR6_R_TRIGGER_16 0x40 /* Mask for receive trigger set at 4 */
33
+ #define UART_FCR6_R_TRIGGER_24 0x80 /* Mask for receive trigger set at 8 */
34
+ #define UART_FCR6_R_TRIGGER_28 0xC0 /* Mask for receive trigger set at 14 */
35
+ #define UART_FCR6_T_TRIGGER_16 0x00 /* Mask for transmit trigger set at 16 */
36
+ #define UART_FCR6_T_TRIGGER_8 0x10 /* Mask for transmit trigger set at 8 */
37
+ #define UART_FCR6_T_TRIGGER_24 0x20 /* Mask for transmit trigger set at 24 */
38
+ #define UART_FCR6_T_TRIGGER_30 0x30 /* Mask for transmit trigger set at 30 */
39
+
40
+ /*
41
+ * These are the definitions for the Line Control Register
42
+ *
43
+ * Note: if the word length is 5 bits (UART_LCR_WLEN5), then setting
44
+ * UART_LCR_STOP will select 1.5 stop bits, not 2 stop bits.
45
+ */
46
+ #define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
47
+ #define UART_LCR_SBC 0x40 /* Set break control */
48
+ #define UART_LCR_SPAR 0x20 /* Stick parity (?) */
49
+ #define UART_LCR_EPAR 0x10 /* Even parity select */
50
+ #define UART_LCR_PARITY 0x08 /* Parity Enable */
51
+ #define UART_LCR_STOP 0x04 /* Stop bits: 0=1 stop bit, 1= 2 stop bits */
52
+ #define UART_LCR_WLEN5 0x00 /* Wordlength: 5 bits */
53
+ #define UART_LCR_WLEN6 0x01 /* Wordlength: 6 bits */
54
+ #define UART_LCR_WLEN7 0x02 /* Wordlength: 7 bits */
55
+ #define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */
56
+
57
+ /*
58
+ * These are the definitions for the Line Status Register
59
+ */
60
+ #define UART_LSR_TEMT 0x40 /* Transmitter empty */
61
+ #define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
62
+ #define UART_LSR_BI 0x10 /* Break interrupt indicator */
63
+ #define UART_LSR_FE 0x08 /* Frame error indicator */
64
+ #define UART_LSR_PE 0x04 /* Parity error indicator */
65
+ #define UART_LSR_OE 0x02 /* Overrun error indicator */
66
+ #define UART_LSR_DR 0x01 /* Receiver data ready */
67
+
68
+ /*
69
+ * These are the definitions for the Interrupt Identification Register
70
+ */
71
+ #define UART_IIR_NO_INT 0x01 /* No interrupts pending */
72
+ #define UART_IIR_ID 0x06 /* Mask for the interrupt ID */
73
+
74
+ #define UART_IIR_MSI 0x00 /* Modem status interrupt */
75
+ #define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
76
+ #define UART_IIR_TOI 0x0c /* Receive time out interrupt */
77
+ #define UART_IIR_RDI 0x04 /* Receiver data interrupt */
78
+ #define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
79
+
80
+ /*
81
+ * These are the definitions for the Interrupt Enable Register
82
+ */
83
+ #define UART_IER_MSI 0x08 /* Enable Modem status interrupt */
84
+ #define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */
85
+ #define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */
86
+ #define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
87
+
88
+ /*
89
+ * These are the definitions for the Modem Control Register
90
+ */
91
+ #define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
92
+ #define UART_MCR_OUT2 0x08 /* Out2 complement */
93
+ #define UART_MCR_OUT1 0x04 /* Out1 complement */
94
+ #define UART_MCR_RTS 0x02 /* RTS complement */
95
+ #define UART_MCR_DTR 0x01 /* DTR complement */
96
+
97
+ /*
98
+ * These are the definitions for the Modem Status Register
99
+ */
100
+ #define UART_MSR_DCD 0x80 /* Data Carrier Detect */
101
+ #define UART_MSR_RI 0x40 /* Ring Indicator */
102
+ #define UART_MSR_DSR 0x20 /* Data Set Ready */
103
+ #define UART_MSR_CTS 0x10 /* Clear to Send */
104
+ #define UART_MSR_DDCD 0x08 /* Delta DCD */
105
+ #define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */
106
+ #define UART_MSR_DDSR 0x02 /* Delta DSR */
107
+ #define UART_MSR_DCTS 0x01 /* Delta CTS */
108
+ #define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */
109
+
110
+ /*
111
+ * These are the definitions for the Extended Features Register
112
+ * (StarTech 16C660 only, when DLAB=1)
113
+ */
114
+ #define UART_EFR_CTS 0x80 /* CTS flow control */
115
+ #define UART_EFR_RTS 0x40 /* RTS flow control */
116
+ #define UART_EFR_SCD 0x20 /* Special character detect */
117
+ #define UART_EFR_ENI 0x10 /* Enhanced Interrupt */
118
+
119
+
120
+ void uart_init(unsigned long);
121
+ void uart_putc(char);
122
+ char uart_getc(void);
123
+ void uart_print_str(char *);
124
+ void uart_print_long(unsigned long);
125
+ void uart_interrupt();
126
+ void uart_print_short(unsigned long ul);
@@ -0,0 +1,324 @@
1
+ ###############################################################
2
+ #
3
+ # File: soc_maker.rb
4
+ #
5
+ # Author: Christian Hättich
6
+ #
7
+ # Project: System-On-Chip Maker
8
+ #
9
+ # Target: Linux / Windows / Mac
10
+ #
11
+ # Language: ruby
12
+ #
13
+ #
14
+ ###############################################################
15
+ #
16
+ #
17
+ # Copyright (C) 2014 Christian Hättich - feddischson [ at ] opencores.org
18
+ #
19
+ # This program is free software: you can redistribute it and/or modify
20
+ # it under the terms of the GNU General Public License as published by
21
+ # the Free Software Foundation, either version 3 of the License, or
22
+ # (at your option) any later version.
23
+ #
24
+ # This program is distributed in the hope that it will be useful,
25
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
26
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27
+ # GNU General Public License for more details.
28
+ #
29
+ # You should have received a copy of the GNU General Public License
30
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
31
+ #
32
+ #
33
+ ###############################################################
34
+ #
35
+ # Description:
36
+ # This part of the SOCMaker module contains
37
+ # - initialization of
38
+ # - logger
39
+ # - configuration
40
+ # - library
41
+ # (see SOCMaker::load)
42
+ # - creating objects from YAML files/strings
43
+ # (see from_f, from_s)
44
+ # - creating YAML files from objects
45
+ # (see SOCMaker::YAML_EXT::write_yaml)
46
+ #
47
+ #
48
+ #
49
+ ###############################################################
50
+ require 'logger'
51
+ require 'yaml'
52
+ require 'digest/md5'
53
+ require 'fileutils'
54
+
55
+
56
+ #
57
+ # This little extension allows to have a custom log level: PROC for processing.
58
+ # Found on
59
+ # http://stackoverflow.com/questions/2281490/how-to-add-a-custom-log-level-to-logger-in-ruby
60
+ class Logger
61
+
62
+ #
63
+ # Method to add a custom log level
64
+ #
65
+ def self.custom_level(tag)
66
+ SEV_LABEL << tag
67
+ idx = SEV_LABEL.size - 1
68
+
69
+ define_method(tag.downcase.gsub(/\W+/, '_').to_sym) do |progname, &block|
70
+ add(idx, nil, progname, &block)
71
+ end
72
+ end
73
+ # add processing log level
74
+ custom_level 'PROC'
75
+ end
76
+
77
+
78
+
79
+ module SOCMaker
80
+
81
+ #
82
+ # Static methods and attributes
83
+ #
84
+ class << self
85
+ public
86
+
87
+ # The global logging instance
88
+ attr_accessor :logger
89
+
90
+ # The global configuration
91
+ attr_accessor :conf
92
+
93
+ # The global library
94
+ attr_accessor :lib
95
+
96
+ #
97
+ # Global initialization method: this loads the config and
98
+ # refreshes the core library.
99
+ # Typically, this is the first method which is called during initialization.
100
+ #
101
+ # *options*::
102
+ # - skip_refresh=true/false: can be used to skip refreshing the core library
103
+ # - logger_out=<any file stream>: default is STDOUT, can be used to put the log into a file
104
+ #
105
+ #
106
+ #
107
+ def load( options={} )
108
+ options = { skip_refresh: false, logger_out: STDOUT }.merge( options )
109
+ @conf = Conf.instance
110
+ @logger = Logger.new(options[ :logger_out ] )
111
+ @lib = Lib.new()
112
+ @logger.progname = @conf[ :app_name ]
113
+ @lib.refresh( options[ :libpath ] ) unless options[ :skip_refresh ]
114
+ end
115
+
116
+
117
+
118
+ #
119
+ # Funtion to load a object from a YAML string.
120
+ # This includes the YPP,
121
+ # which replaces our custom object tags with yaml
122
+ # object information.
123
+ # Afterwards, the method YAML::load is used
124
+ # to create the object.
125
+ #
126
+ # In addition, it is possible to provide multiple objects in
127
+ # one string: YPP takes care and splits them into
128
+ # single object strings.
129
+ #
130
+ # *s*:: the object(s) as yaml string (before processing with YPP)
131
+ #
132
+ #
133
+ def from_s( s )
134
+
135
+ objs = []
136
+ SOCMaker::YPP.to_yaml( s ) do |yaml_obj_str|
137
+
138
+ begin
139
+ YAML::load( yaml_obj_str )
140
+ o = YAML::load( yaml_obj_str )
141
+
142
+ # ensure, that we load only our classes
143
+ if SOCMaker::conf[ :yaml_classes ].include?( o.class )
144
+ #o.verify
145
+ objs << o
146
+ else
147
+ SOCMaker::logger.warn( "Tried to load something, which does not belong to #{SOCMaker::conf[ :app_name ]}" )
148
+ end
149
+ rescue ArgumentError, Psych::SyntaxError => e
150
+ SOCMaker::logger.error( 'YAML loading failed, invalid YAML syntax?' )
151
+ SOCMaker::logger.error( ">>> #{e.to_s} <<<" )
152
+ raise ERR::YAMLParseError
153
+ else
154
+ end
155
+ end
156
+
157
+ if block_given?
158
+ objs.each{ |o| yield(o) }
159
+ end
160
+ return ( objs.size >1 ? objs : objs[0] )
161
+ end
162
+
163
+ #
164
+ # Method to load a yaml-based object(s) from one
165
+ # or multiple files. The files are read and concatenated.
166
+ # Path argument can be an array of paths
167
+ # or a file (wildcards are allowed)
168
+ # loading from a YAML file
169
+ def from_f( path )
170
+
171
+ path = Dir[ path ].sort if path.is_a?( String )
172
+
173
+ SOCMaker::logger.warn( "No file(s) found to load" ) if path.size == 0
174
+
175
+ yaml_str = ""
176
+ path.each do |file|
177
+ SOCMaker::logger.info "reading:" + file
178
+ yaml_str << File.read( file )
179
+ end
180
+ o = from_s( yaml_str )
181
+ o.src_dir = File.dirname( path.first )
182
+ return o
183
+ end
184
+
185
+ #
186
+ # This method takes an object, converts it to a YAML string and
187
+ # also applies the YPP to replace the YAML object-tags.
188
+ #
189
+ def to_yaml_s( o )
190
+ YPP.from_yaml( o.to_yaml )
191
+ end
192
+
193
+
194
+ #
195
+ # Deployes a System-on-Chip:
196
+ # - get all core-ids
197
+ # - get all static parameters
198
+ # - call deploy for each core which causes to copy and generate all HDL files
199
+ # *soc*:: the System-on-Chip, which is deployed
200
+ # *coder*:: the choosen HDL coder
201
+ #
202
+ def deploy_soc( soc, coder = VHDLCoder.new )
203
+
204
+ SOCMaker::logger.info "Deploying SOC #{soc.name}"
205
+ soc.consistence_check
206
+ ids = soc.all_core_id
207
+ static = soc.all_static_parameters
208
+ static = check_static_setup( static )
209
+
210
+ SOCMaker::logger.info "Core Occurrence"
211
+ SOCMaker::CoreDef.core_cnt( ids ).each do |k,v|
212
+ SOCMaker::logger.info "#{k}\t#{v}"
213
+ end
214
+ ids.uniq.each{ |core| lib.get_core( core ).deploy( coder: coder, static: static ) }
215
+
216
+ end
217
+
218
+
219
+ #
220
+ # Ensure, that there are no multiple defined static parameters
221
+ # for a core/soc.
222
+ # *static*:: Input hash with the structure { soc_id : { core_id1: { .... }, core_id2: { .... } } }
223
+ # *return*:: Output hash with the structure { core_id1: { ....}, core_id2: { .... } }
224
+ #
225
+ def check_static_setup( static )
226
+ static_tmp = {}
227
+ static.each do |core_id, static_setup|
228
+ static_setup.each do |core_id2, value |
229
+ if static_tmp.has_key?( core_id2 )
230
+ raise ConsistenceError.new( "Invalid static setup: #{core_id2} is defined multiple times" )
231
+ end
232
+ static_tmp[ core_id2 ] = value
233
+ end
234
+ end
235
+ return static_tmp
236
+ end
237
+
238
+
239
+ end
240
+
241
+
242
+
243
+ #
244
+ # small module to extend classes,
245
+ # which need to be written as yaml
246
+ # output
247
+ module YAML_EXT
248
+
249
+ # we remember always, were we've loaded a yaml file
250
+ attr_accessor :src_dir
251
+
252
+ def save_yaml( args )
253
+ path = args.size==0 ? @spec_path : args.first
254
+ File.open( path, 'w') {|f| f.write SOCMaker::YPP.from_yaml( YAML.dump( self ) ) }
255
+ end
256
+ end
257
+
258
+
259
+
260
+
261
+
262
+
263
+ # :stopdoc:
264
+ LIBPATH = ::File.expand_path('..', __FILE__) + ::File::SEPARATOR
265
+ PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
266
+ # :startdoc:
267
+
268
+ # Returns the library path for the module. If any arguments are given,
269
+ # they will be joined to the end of the libray path using
270
+ # <tt>File.join</tt>.
271
+ #
272
+ def self.libpath( *args )
273
+ rv = args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
274
+ if block_given?
275
+ begin
276
+ $LOAD_PATH.unshift LIBPATH
277
+ rv = yield
278
+ ensure
279
+ $LOAD_PATH.shift
280
+ end
281
+ end
282
+ return rv
283
+ end
284
+
285
+ # Returns the lpath for the module. If any arguments are given,
286
+ # they will be joined to the end of the path using
287
+ # <tt>File.join</tt>.
288
+ #
289
+ def self.path( *args )
290
+ rv = args.empty? ? PATH : ::File.join(PATH, args.flatten)
291
+ if block_given?
292
+ begin
293
+ $LOAD_PATH.unshift PATH
294
+ rv = yield
295
+ ensure
296
+ $LOAD_PATH.shift
297
+ end
298
+ end
299
+ return rv
300
+ end
301
+
302
+ #
303
+ # load all file for soc_maker
304
+ #
305
+ def self.require_all_libs
306
+ file = ::File.basename(__FILE__, '.*')
307
+ dir = ::File.dirname(__FILE__)
308
+ %w[ err ypp
309
+ lib_inc version
310
+ core_def core_inst
311
+ hdl_file ifc_def
312
+ ifc_port ifc_spc
313
+ soc_def parameter
314
+ sparameter hdl_coder
315
+ lib cli conf
316
+ hdl_parser ].each { |rb| require ::File.expand_path(
317
+ ::File.join( dir, file, rb ) ) }
318
+ end
319
+
320
+ end # module SOCMaker
321
+
322
+ SOCMaker.require_all_libs
323
+
324
+ # vim: noai:ts=2:sw=2
@@ -0,0 +1,544 @@
1
+ #!/usr/bin/env ruby
2
+ ###############################################################
3
+ #
4
+ # File: cli.rb
5
+ #
6
+ # Author: Christian Hättich
7
+ #
8
+ # Project: System-On-Chip Maker
9
+ #
10
+ # Target: Linux / Windows / Mac
11
+ #
12
+ # Language: ruby
13
+ #
14
+ #
15
+ ###############################################################
16
+ #
17
+ #
18
+ # Copyright (C) 2014 Christian Hättich - feddischson [ at ] opencores.org
19
+ #
20
+ # This program is free software: you can redistribute it and/or modify
21
+ # it under the terms of the GNU General Public License as published by
22
+ # the Free Software Foundation, either version 3 of the License, or
23
+ # (at your option) any later version.
24
+ #
25
+ # This program is distributed in the hope that it will be useful,
26
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
27
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28
+ # GNU General Public License for more details.
29
+ #
30
+ # You should have received a copy of the GNU General Public License
31
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
32
+ #
33
+ #
34
+ ###############################################################
35
+ require 'readline'
36
+ require 'optparse'
37
+ require 'singleton'
38
+
39
+ module SOCMaker
40
+
41
+ #
42
+ # Command-line interface for accessing the SOC-Maker functionallity
43
+ #
44
+ # PLEASE NOTE: this class is outdated and needs some work!!
45
+ #
46
+ # The following commands are available:
47
+ # - new -> create a new soc file
48
+ # - open -> open soc file
49
+ # - list -> list library
50
+ # - add -> add core to the SOC
51
+ # - add_interface -> add an interface to the SOC
52
+ # - parameter -> set/get parameter
53
+ # - sparameter -> set/get static parameter
54
+ # - connect -> connect cores
55
+ # - delete -> delete core or connection
56
+ # - save -> save soc
57
+ # - generate -> generate soc
58
+ # - quit -> quit this CLI
59
+ # - exit -> same than quit
60
+ # - help -> print some help
61
+ #
62
+ # Please use the help command to get more information about
63
+ # each command and its parameters.
64
+ #
65
+ # This CLI is a wrapper around SOCMaker::SOCDef and
66
+ # this class is realized as singleton.
67
+ #
68
+ # TODO: add commands for
69
+ # - selecting the coder (at the moment, only VHDL is supported)
70
+ # - refreshing the lib
71
+ #
72
+ class Cli
73
+
74
+ # to organize it as singleton
75
+ #
76
+ include Singleton
77
+
78
+
79
+ #
80
+ # the SOC, which is edited by this script
81
+ #
82
+ @soc = nil
83
+
84
+
85
+ #
86
+ # An abbreviation map.
87
+ #
88
+ @appr_map = {}
89
+
90
+
91
+ #
92
+ # All available commands
93
+ #
94
+ @commands = []
95
+
96
+ #
97
+ # Constructor of this CLI: it sets up a abbreviation map and a list
98
+ # of available commands. Moreover, it initializes readline.
99
+ #
100
+ def initialize
101
+
102
+ # abbreviation map
103
+ @appr_map = { 'n' => "new",
104
+ 'o' => "open",
105
+ 'q' => "quit",
106
+ 'h' => "help",
107
+ 'l' => "list",
108
+ 'a' => "add",
109
+ 'g' => "generate",
110
+ 's' => "save",
111
+ 'p' => "parameter",
112
+ 'd' => "delete",
113
+ 'c' => "connect",
114
+ 'i' => "print",
115
+ 'x' => "exit"
116
+ }
117
+
118
+ # all available commands
119
+ @commands = %w[ new open list add add_interface parameter sparameter
120
+ delete connect save help quit exit
121
+ generate print set get ]
122
+
123
+ comp = proc { |s| (@commands + Dir.entries( Dir.pwd )).grep( /^#{Regexp.escape(s)}/ ) }
124
+ Readline.completion_append_character = " "
125
+ Readline.completion_proc = comp
126
+
127
+ end
128
+
129
+ #
130
+ # Method to start processing the commands. Readline us used
131
+ # to receive input data. Each line to passed to process_cmd.
132
+ #
133
+ def run
134
+
135
+ ##
136
+ # process user commands
137
+ #
138
+ while buf = Readline.readline( "> ", true )
139
+ process_cmd buf
140
+ end
141
+ end
142
+
143
+ #
144
+ # Method to processes a single command
145
+ #
146
+ def process_cmd( c )
147
+
148
+ # remove the comments and split each line
149
+ match = SOCMaker::conf[ :COMMENT_REGEX ].match( c )
150
+ cmd_arr = match[1].split( ' ' )
151
+
152
+ # process the command, if there is one
153
+ if cmd_arr.size > 0
154
+ cmd = ""
155
+ if cmd_arr[ 0 ].size == 1 and @appr_map[ cmd_arr[ 0 ] ] != nil
156
+ cmd = @appr_map[ cmd_arr[ 0 ] ]
157
+ else
158
+ cmd = cmd_arr[ 0 ]
159
+ end
160
+
161
+ if @commands.include?( cmd )
162
+ cmd_str = "do_#{cmd}( cmd_arr[ 1..-1] )"
163
+ puts "evaluating >>#{cmd_str}<< "
164
+ eval( cmd_str )
165
+ elsif !Gem.win_platform? && system( "which #{cmd} > /dev/null 2>&1" )
166
+ # this is for linux only
167
+ system( c )
168
+ else
169
+ puts "Command #{cmd} not available"
170
+ end
171
+ #begin
172
+ #rescue
173
+ # puts "evaluating >>#{cmd_str}<< failed"
174
+ #end
175
+ end
176
+ end
177
+
178
+
179
+ private
180
+
181
+
182
+ # failed message
183
+ FMSG = ' -> failed '
184
+
185
+
186
+ #########################################
187
+ #
188
+ # command implementations:
189
+ # -> a usage string and
190
+ # a function for every command
191
+ #
192
+
193
+ #
194
+ # Usage message of the 'new' comand
195
+ #
196
+ NEW_USAGE =
197
+ " > new <<name>> <<id>> <<toplevel>> # opens a system-on-chip file
198
+ - <<name>> : the SOC name
199
+ - <<id>> : the SOC id
200
+ - <<toplevel>> : the toplevel name
201
+ "
202
+
203
+ #
204
+ # Implementation of the 'new' command
205
+ #
206
+ def do_new( args )
207
+ if args.size != 3
208
+ puts "three arguments are required:\nusage:\n#{NEW_USAGE}"
209
+ else
210
+ @soc = SOCMaker::SOCDef.new( args[0], args[1], args[2] )
211
+ SOCMaker::lib.add_core( @soc )
212
+ @soc.consistence_check
213
+ end
214
+ end
215
+
216
+ #
217
+ # Usage message of the 'open' comand
218
+ #
219
+ OPEN_USAGE =
220
+ " > open <<file>> # opens a system-on-chip file
221
+ - <<file>> : system-on-chip definition in in YAML format
222
+
223
+ "
224
+ #
225
+ # Implementation of the 'open' command
226
+ #
227
+ def do_open( args )
228
+ if args.size != 1
229
+ puts "only one argument is required:\nusage:\n#{OPEN_USAGE}"
230
+ else
231
+ puts "loading #{args[0]}"
232
+ @soc = SOCMaker::from_f( args[0] )
233
+ SOCMaker::lib.add_core( @soc )
234
+ @soc.consistence_check
235
+ end
236
+ end
237
+
238
+ #
239
+ # Usage message of the 'list' comand
240
+ #
241
+ LIST_USAGE =
242
+ " > list # prints list of cores and interfaces,
243
+ which are in the library
244
+
245
+ "
246
+ #
247
+ # Implementation of the 'list' command
248
+ #
249
+ def do_list( args )
250
+ puts SOCMaker::lib
251
+ end
252
+
253
+ #
254
+ # Usage message of the 'add' comand
255
+ #
256
+ ADD_USAGE =
257
+ " > add <<id>> <<name>>
258
+ # adds an ip-core from the library to the SOC
259
+ - <<id>> : id of the IP core
260
+ - <<name>> : instanciation name
261
+
262
+ "
263
+ #
264
+ # Implementation of the 'add' command
265
+ #
266
+ def do_add( args )
267
+ if args.size != 2
268
+ puts "two arguments are required:\nusage:\n#{ADD_USAGE}"
269
+ else
270
+ @soc.add_core( args[ 0 ].to_sym, args[ 1 ].to_sym )
271
+ @soc.consistence_check
272
+ end
273
+ end
274
+
275
+
276
+ ADD_INTERFACE_USAGE =
277
+ " > add_interface <<name>> <<id>> <<dir>> <<port_name>> <<port_size>> [ <<port_name>> <<port_size>> .... ]
278
+ # adds an interface to the SOC
279
+ - <<name>> name of the interface
280
+ - <<id>> id of the interface specification
281
+ - <<dir>> the direction
282
+ - <<port_name>> name of the port
283
+ - <<port_size>> size of the port
284
+
285
+ "
286
+ def do_add_interface( args )
287
+
288
+
289
+ if args.size < 5 || args.size % 2 != 1
290
+ puts "five or more (but odd) arguments required:\nusage:\n#{ADD_INTERFACE_USAGE}"
291
+ else
292
+ ports = {}
293
+ args[3..-1].each_slice(2).to_a.each do |entry|
294
+ ports[ entry[0].to_sym ] = SOCMaker::IfcPort.new( entry[0], entry[1] )
295
+ end
296
+
297
+ @soc.add_interface( args[0], args[ 1 ], args[2].to_i, ports )
298
+
299
+ end
300
+
301
+ end
302
+
303
+ #
304
+ # Usage message of the 'parameter' comand
305
+ #
306
+ PARAMETER_USAGE =
307
+ " > prameter <<instance>> <<parameter>> <<value>>
308
+ # modifies a parameter of an instance
309
+ - <<instance>> : the instance name of the core
310
+ - <<parameter>> : the instance parameter name
311
+ - <<value>> : the value which is set (optional). The current
312
+ value is printed, if omitted
313
+ "
314
+ #
315
+ # Implementation of the 'parameter' command
316
+ #
317
+ def do_parameter( args )
318
+ if args.size == 2
319
+ @soc.get_param( args[ 0 ].to_sym, args[ 1 ].to_sym )
320
+ elsif args.size == 3
321
+ @soc.set_param( args[ 0 ].to_sym, args[ 1 ].to_sym, args[ 2 ] )
322
+ @soc.consistence_check
323
+ else
324
+ puts "two or three arguments required:\nusage:\n#{PARAMETER_USAGE}"
325
+ end
326
+ end
327
+
328
+ #
329
+ # Usage message of the 'sparameter' comand
330
+ #
331
+ SPARAMETER_USAGE =
332
+ " > sprameter <<core>> <<parameter>> <<value>>
333
+ # modifies the static parameter of a core
334
+ - <<core>> : the name of the core
335
+ - <<parameter>> : the static parameter name
336
+ - <<value>> : the value which is set (optional). The current
337
+ value is printed, if omitted
338
+ "
339
+ #
340
+ # Implementation of the 'sparameter' command
341
+ #
342
+ def do_sparameter( args )
343
+ if args.size == 2
344
+ @soc.get_sparam( args[ 0 ].to_sym, args[ 1 ].to_sym )
345
+ elsif args.size == 3
346
+ @soc.set_sparam( args[ 0 ].to_sym, args[ 1 ].to_sym, args[ 2 ] )
347
+ @soc.consistence_check
348
+ else
349
+ puts "two or three arguments required:\nusage:\n#{SPARAMETER_USAGE}"
350
+ end
351
+ end
352
+
353
+ #
354
+ # Usage message of the 'connect' comand
355
+ #
356
+ CONNECT_USAGE =
357
+ " > connect <<name>> <<core1>> <<ifc1>> <<core2>> <<ifc2>>
358
+ # connects two cores
359
+ - <<name>> : connection name
360
+ - <<core1>> : instance name of the first core
361
+ - <<core2>> : instance name of the second core
362
+ - <<ifc1>> : interface name of the first core
363
+ - <<ifc2>> : interface name of the second core
364
+
365
+ "
366
+ #
367
+ # Implementation of the 'connect' command
368
+ #
369
+ def do_connect( args )
370
+ if args.size != 5
371
+ puts "five arguments are required:\nusage:\n#{CONNECT_USAGE}"
372
+ else
373
+ @soc.add_connection( args[ 0 ],
374
+ args[ 1 ].to_sym,
375
+ args[ 2 ].to_sym,
376
+ args[ 3 ].to_sym,
377
+ args[ 4 ].to_sym )
378
+ @soc.consistence_check
379
+ end
380
+ end
381
+
382
+ #
383
+ # Usage message of the 'delete' comand
384
+ #
385
+ DELETE_USAGE =
386
+ " > delete <<core/connection>>
387
+ # removes a core or a connection
388
+ - <<core/conection> : the core or connection, which is removed
389
+
390
+ "
391
+ #
392
+ # Implementation of the 'delete' command
393
+ #
394
+ def do_delete( args )
395
+ if args.size != 1
396
+ puts "five arguments are required:\nusage:\n#{DELETE_USAGE}"
397
+ else
398
+ @soc.rm( args[ 0 ].to_sym )
399
+ @soc.consistence_check
400
+ end
401
+ end
402
+ #
403
+ # Usage message of the 'save' comand
404
+ #
405
+ SAVE_USAGE =
406
+ " > save <<file>> # saves system-on-chip definition in YAML format to file
407
+ - <<file>> : optional destination file, when omitted: the
408
+ original file-path is used
409
+
410
+ "
411
+ #
412
+ # Implementation of the 'save' command
413
+ #
414
+ def do_save( args )
415
+ if args.size > 1
416
+ puts "zero or one argument is required:\nusage:\n#{SAVE_USAGE}"
417
+ else
418
+ p args
419
+ @soc.save_yaml( args )
420
+ File.open( args[0], 'w' ) { |f| f.write( SOCMaker::to_yaml_s( @soc ) ) }
421
+ end
422
+ end
423
+
424
+ #
425
+ # Usage message of the 'generate' comand
426
+ #
427
+ GENERATE_USAGE =
428
+ " > generate # generates a synthesizable system-on-chip implementation
429
+
430
+ "
431
+ #
432
+ # Implementation of the 'generate' command
433
+ #
434
+ def do_generate( args )
435
+ if args.size != 0
436
+ puts "no arguments are required:\nusage:\n#{GENERATE_USAGE}"
437
+ else
438
+ @soc.consistence_check
439
+ SOCMaker::deploy_soc( @soc )
440
+ end
441
+ end
442
+
443
+ #
444
+ # Usage message of the 'print' comand
445
+ #
446
+ PRINT_USAGE =
447
+ " > print # prints SOC information
448
+
449
+ "
450
+ #
451
+ # Implementation of the 'print' command
452
+ #
453
+ def do_print( args )
454
+ if args.size != 0
455
+ puts "no arguments are required:\nusage:\n#{PRINT_USAGE}"
456
+ else
457
+ puts @soc
458
+ end
459
+ end
460
+
461
+ #
462
+ # Usage message of the 'quit' comand
463
+ #
464
+ QUIT_USAGE =
465
+ " > quit # the same than exit
466
+
467
+ "
468
+ #
469
+ # Implementation of the 'quit' command
470
+ #
471
+ def do_quit( args )
472
+ do_exit( args )
473
+ end
474
+
475
+ #
476
+ # Usage message of the 'exit' comand
477
+ #
478
+ EXIT_USAGE =
479
+ " > exit # exits this tool
480
+
481
+ "
482
+ #
483
+ # Implementation of the 'exit' command
484
+ #
485
+ def do_exit( args )
486
+ puts "... bye bye!"
487
+ exit 0
488
+ end
489
+
490
+ #
491
+ # Usage message of the 'help' comand
492
+ #
493
+ HELP_USAGE =
494
+ " > help # prints some help information
495
+
496
+ "
497
+ #
498
+ # Implementation of the 'help' command
499
+ #
500
+ def do_help( args )
501
+ puts "The following commands are available:\n\n"
502
+ @commands.each { |c| eval "puts #{c.upcase}_USAGE" }
503
+ end
504
+
505
+ #
506
+ # Usage message of the 'set' comand
507
+ #
508
+ SET_USAGE =
509
+ " > set # not implemented yet
510
+
511
+ "
512
+ #
513
+ # Implementation of the 'set' command
514
+ #
515
+ def do_set( args )
516
+ puts "NOT IMPLEMENTED, YET"
517
+ end
518
+ #
519
+ # Usage message of the 'get' comand
520
+ #
521
+ GET_USAGE =
522
+ " > get # not implemented yet
523
+
524
+ "
525
+ #
526
+ # Implementation of the 'get' command
527
+ #
528
+ def do_get( args )
529
+ puts "NOT IMPLEMENTED, YET"
530
+ end
531
+
532
+ # end command implementations
533
+ #
534
+ #################################
535
+
536
+
537
+
538
+
539
+ end
540
+ end
541
+
542
+
543
+ # vim: noai:ts=2:sw=2
544
+