OpenCores
URL https://opencores.org/ocsvn/soc_maker/soc_maker/trunk

Subversion Repositories soc_maker

[/] [soc_maker/] [trunk/] [spec/] [soc_def_spec.rb] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 feddischso
###############################################################
2
#
3
#  File:      soc_def_spec.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 .
31
#
32
#
33
###############################################################
34
#
35
#   Description:
36
#     Test spec. for SOCMaker::SOCDef
37
#
38
#
39
#
40
###############################################################
41
require_relative( 'spec_helper' )
42
 
43
 
44
describe SOCMaker::SOCDef, "structure verification for loading a core-definition" do
45
 
46
  # not implemented at the moment
47
 
48
  # test for invalid path
49
  # it "should raise an error if a non-existing path is given" do
50
  #   expect { SOCMaker::from_f( 'blabla.txt' ) }.
51
  #       to raise_error( IOError )
52
  # end
53
 
54
 
55
 
56
 
57
  #
58
  # A yaml example, which contains
59
  #   - a full definition
60
  #   - an interface with one port
61
  #   - one hdl file
62
  #   - one instance parameter
63
  #   - one static parameter
64
  #
65
  FULL_SOC_YAML = '''SOCM_SOC
66
name: my_soc
67
description: A test SOC
68
version: rel2
69
date: 1.1.2014
70
license: LGPL
71
licensefile:
72
toplevel: soc_top
73
author: Christian Haettich
74
authormail: feddischson@opencores.org
75
repocmd: svn co http://some-address/
76
'''
77
 
78
 
79
SOC_YAML_WITH_CORE = '''SOCM_SOC
80
name: my_soc
81
description: A test SOC
82
version: rel2
83
date: 1.1.2014
84
license: LGPL
85
licensefile:
86
author: Christian Haettich
87
authormail: feddischson@opencores.org
88
repocmd: svn co http://some-address/
89
toplevel: soc_top
90
cores:
91
  :inst1: SOCM_INST
92
    type: mycorerel1
93
'''
94
 
95
 
96
 
97
 
98
 
99
 
100
  # process all valid YAMLs
101
  #  each should result in a CoreDef
102
  it 'should return a class of type SOCDef when loading a full soc-def' do
103
    SOCMaker::from_s( FULL_SOC_YAML ).class.should == SOCMaker::SOCDef
104
  end
105
 
106
  it "should rise an error if soc is loaded with a core, which is not in our library" do
107
    SOCMaker::lib.clear
108
    expect { SOCMaker::from_s( SOC_YAML_WITH_CORE ) }.
109
      to raise_error( SOCMaker::ERR::LibError )
110
  end
111
 
112
 
113
  it "should return an SOC-object if soc is loaded with a core, which is in our library" do
114
    file = { "file.vhd".to_sym => SOCMaker::HDLFile.new( "./file.vhd" ) }
115
    core = SOCMaker::CoreDef.new( "mycore", "rel1", file, "top" )
116
    SOCMaker::lib.add_core( core )
117
    soc = SOCMaker::from_s( SOC_YAML_WITH_CORE )
118
    soc.class.should be SOCMaker::SOCDef
119
  end
120
 
121
end
122
 
123
 
124
describe SOCMaker::SOCDef, "processing verification" do
125
 
126
    before( :each )do
127
      file = { "file.vhd".to_sym => SOCMaker::HDLFile.new( "./file.vhd" ) }
128
      core = SOCMaker::CoreDef.new( "mycore", "rel1", file, "top" )
129
      SOCMaker::lib.add_core( core )
130
      @soc = SOCMaker::SOCDef.new( "test-soc", "v1", "my_soc_top" )
131
    end
132
 
133
    describe "adding/removing cores, connections etc." do
134
 
135
 
136
      it "inst_in_use should return true, if there is already an core instance with that name" do
137
        @soc.cores[ :core_inst ] = SOCMaker::CoreInst.new( "mycorerel1" )
138
        @soc.inst_in_use?( "core_inst" ).should be == true
139
      end
140
 
141
      it "inst_in_use should return false, if there is no core instance with that name" do
142
        @soc.inst_in_use?( "core_inst" ).should be == false
143
      end
144
 
145
      it "inst_in_use should return true, if there is already an connection instance with that name" do
146
        @soc.cons[ :a_con ] = { rule: "or", mapping: [ { :core_a => :ifc_a }, { :core_b => :ifc_b } ] }
147
        @soc.inst_in_use?( "a_con" ).should be == true
148
      end
149
 
150
 
151
 
152
      it "removing a core instance should be possible" do
153
        @soc.cores[ :core_inst ] = SOCMaker::CoreInst.new( "mycorerel1" )
154
        @soc.inst_in_use?( "core_inst" ).should be == true
155
        @soc.rm( "core_inst" ).should be == true
156
        @soc.inst_in_use?( "core_inst" ).should be == false
157
      end
158
 
159
 
160
      it "removing a connection instance should be possible" do
161
        @soc.cons[ :a_con ] = { rule: "or", mapping: [ { :core_a => :ifc_a }, { :core_b => :ifc_b } ] }
162
        @soc.inst_in_use?( "a_con" ).should be == true
163
        @soc.rm( "a_con" ).should be == true
164
        @soc.inst_in_use?( "a_con" ).should be == false
165
      end
166
 
167
      it "should return false, when removing a non-existance instance" do
168
        @soc.rm( "a_con" ).should be == false
169
      end
170
 
171
      it "should return nil if a instance is added twice" do
172
        @soc.cores[ :core_inst ] = SOCMaker::CoreInst.new( "mycorerel1" )
173
        @soc.add_core(  "mycore", "rel1", "core_inst" ).should be == false
174
      end
175
 
176
      it "should return non-nil value, if a instance is added once" do
177
        @soc.add_core(  "mycore", "rel1", "core_inst" ).should_not be == false
178
      end
179
 
180
      it "should return nil if a connection is added twice" do
181
        @soc.cons[ :a_con ] = { rule: "or", mapping: [ { :core_a => :ifc_a }, { :core_b => :ifc_b } ] }
182
        @soc.add_connection(  "core_a", "ifc_a", "core_c", "ifc_b", "a_con" ).should be == nil
183
      end
184
 
185
      it "should raise a library error when adding an unknown core" do
186
        expect{ @soc.add_core( "some_unknown_core", "v_xyz", "test" ) }.
187
          to raise_error( SOCMaker::ERR::LibError )
188
      end
189
 
190
      it "should create a dir and return the absolute path for a core inside the build/hdl dir" do
191
        SOCMaker::conf[ :build_dir ] = "./spec/tmp_build"
192
        SOCMaker::conf[ :hdl_dir   ] = "hdl"
193
        path = File.expand_path "./spec/tmp_build/hdl/a_core"
194
        FileUtils.rmdir( path ) if File.directory?( path )
195
        res = @soc.get_and_ensure_dst_dir!( "a_core" )
196
        File.directory?( path ).should be == true
197
        res.should be == path
198
      end
199
 
200
      it "should return false, when an interface is not used" do
201
        # setup interface ifc_b and ifc_c, test for ifc_a
202
        a_con = { rule: "or", mapping: [ { :core_a => :ifc_b }, { :core_b => :ifc_c } ] }
203
        @soc.cons[ :my_con ] = a_con
204
        @soc.ifc_in_use?( "core_a", "ifc_a" ).should be == false
205
      end
206
 
207
      it "should return true, if an interface is used" do
208
        a_con = { rule: "or", mapping: [ { :core_a => :ifc_a }, { :core_b => :ifc_b } ] }
209
        @soc.cons[ :my_con ] = a_con
210
        @soc.ifc_in_use?( "core_a", "ifc_a" ).should be == true
211
      end
212
 
213
 
214
      it "should raise an SOCMaker::ERR::ProcessingError add_connection tries to add a interface, wich is already used" do
215
        a_con = { rule: "or", mapping: [ { :core_a => :ifc_a }, { :core_b => :ifc_b } ] }
216
        @soc.cons[ :my_con ] = a_con
217
        expect{ @soc.add_connection(  "core_a", "ifc_a", "core_b", "ifc_c", "a_new_con" ) }.
218
          to raise_error( SOCMaker::ERR::ProcessingError )
219
        expect{ @soc.add_connection(  "core_a", "ifc_a", "core_c", "ifc_b", "a_new_con" ) }.
220
          to raise_error( SOCMaker::ERR::ProcessingError )
221
      end
222
 
223
      it "should raise an SOCMaker::ERR::ProcessingError if a connection is added from a non-existing core instance" do
224
        expect{ @soc.add_connection(  "core_a", "ifc_a", "core_c", "ifc_b", "a_new_con" ) }.
225
          to raise_error( SOCMaker::ERR::ProcessingError )
226
      end
227
 
228
      it "should raise an ProcessingError if a interface doesn't exist" do
229
        @soc.cores[ :core_a ] = SOCMaker::CoreInst.new( "mycorerel1" )
230
        @soc.cores[ :core_b ] = SOCMaker::CoreInst.new( "mycorerel1" )
231
        expect{ @soc.add_connection(  "core_a", "ifc_a", "core_b", "ifc_c", "a_new_con" ) }.
232
          to raise_error( SOCMaker::ERR::ProcessingError )
233
      end
234
 
235
 
236
      it "should raise an ProcessingError if the ifc.-version is wrong" do
237
 
238
        ifc_spc1 = SOCMaker::IfcSpc.new( "myifc", "v1", 'ports' => { port_a: 1, port_b: 0 } )
239
        ifc_spc2 = SOCMaker::IfcSpc.new( "myifc", "v2", 'ports' => { port_a: 1, port_b: 0 } )
240
        ifc_def_1 = SOCMaker::IfcDef.new( "myifc", "v1", 0, { a: SOCMaker::IfcPort.new( "port_a", 1 ) } )
241
        ifc_def_0 = SOCMaker::IfcDef.new( "myifc", "v2", 1, { b: SOCMaker::IfcPort.new( "port_b", 1 ) } )
242
        file = { "file.vhd".to_sym => SOCMaker::HDLFile.new( "./file.vhd" ) }
243
        core_a = SOCMaker::CoreDef.new( "core_a", "v1", file, "top" )
244
        core_b = SOCMaker::CoreDef.new( "core_b", "v1", file, "top" )
245
        core_a.interfaces[ :ifc_a ] = ifc_def_0
246
        core_a.interfaces[ :ifc_b ] = ifc_def_1
247
        core_b.interfaces[ :ifc_a ] = ifc_def_0
248
        core_b.interfaces[ :ifc_b ] = ifc_def_1
249
 
250
        SOCMaker::lib.add_ifc( ifc_spc1 )
251
        SOCMaker::lib.add_ifc( ifc_spc2 )
252
        SOCMaker::lib.add_core( core_a )
253
        SOCMaker::lib.add_core( core_b )
254
        @soc.cores[ :core_a ] = SOCMaker::CoreInst.new( "core_av1" )
255
        @soc.cores[ :core_b ] = SOCMaker::CoreInst.new( "core_bv1" )
256
        expect { @soc.add_connection(  "inst_a", "ifc_a", "inst_b", "ifc_b", "a_new_con" ) }.
257
          to raise_error( SOCMaker::ERR::ProcessingError )
258
      end
259
 
260
 
261
 
262
 
263
      it "should add a connection entry" do
264
 
265
        ifc_spc = SOCMaker::IfcSpc.new( "myifc", "v1", 'ports' => { port_a: 1, port_b: 0 } )
266
        ifc_def_1 = SOCMaker::IfcDef.new( "myifc", "v1", 0, { a: SOCMaker::IfcPort.new( "port_a", 1 ) } )
267
        ifc_def_0 = SOCMaker::IfcDef.new( "myifc", "v1", 1, { b: SOCMaker::IfcPort.new( "port_b", 1 ) } )
268
        file = { "file.vhd".to_sym => SOCMaker::HDLFile.new( "./file.vhd" ) }
269
        core_a = SOCMaker::CoreDef.new( "core_a", "v1", file, "top" )
270
        core_b = SOCMaker::CoreDef.new( "core_b", "v1", file, "top" )
271
        core_a.interfaces[ :ifc_a ] = ifc_def_0
272
        core_a.interfaces[ :ifc_b ] = ifc_def_1
273
        core_b.interfaces[ :ifc_a ] = ifc_def_0
274
        core_b.interfaces[ :ifc_b ] = ifc_def_1
275
 
276
        SOCMaker::lib.add_ifc( ifc_spc )
277
        SOCMaker::lib.add_core( core_a )
278
        SOCMaker::lib.add_core( core_b )
279
 
280
 
281
 
282
        @soc.cores[ :inst_a ] = SOCMaker::CoreInst.new( "core_av1" )
283
        @soc.cores[ :inst_b ] = SOCMaker::CoreInst.new( "core_bv1" )
284
        @soc.add_connection(  "inst_a", "ifc_a", "inst_b", "ifc_b", "a_new_con" )
285
        @soc.cons[ :a_new_con ].should be == { rule:'or', mapping: [ {inst_a: :ifc_a},{inst_b: :ifc_b} ] }
286
      end
287
 
288
      it "should raise an error, if a parameter of unkonwn core is set" do
289
        expect{ @soc.set_param( "a_unknown_core", "p1", 1234 ) }.
290
          to raise_error( SOCMaker::ERR::ProcessingError )
291
      end
292
 
293
      it "should raise an error, if a parameter of unkonwn core is requested" do
294
        expect{ @soc.get_param( "a_unknown_core", "p1" ) }.
295
          to raise_error( SOCMaker::ERR::ProcessingError )
296
      end
297
 
298
      it "should raise an error, if a unknown parameter is set and requested" do
299
        file = { "file.vhd".to_sym => SOCMaker::HDLFile.new( "./file.vhd" ) }
300
        core_a = SOCMaker::CoreDef.new( "core_a", "v1", file, "top" )
301
        parameter = SOCMaker::Parameter.new( "integer" )
302
        core_a.inst_parameters[ :p1 ] = parameter
303
        SOCMaker::lib.add_core( core_a )
304
        @soc.cores[ :inst_a ] = SOCMaker::CoreInst.new( "core_av1" )
305
        expect{ @soc.set_param( "inst_a", "px", 1234 ) }.
306
          to raise_error( SOCMaker::ERR::ProcessingError )
307
        expect{ @soc.get_param( "inst_a", "px" ) }.
308
          to raise_error( SOCMaker::ERR::ProcessingError )
309
      end
310
 
311
      it "should set a parameter and provide a parameter" do
312
        file = { "file.vhd".to_sym => SOCMaker::HDLFile.new( "./file.vhd" ) }
313
        core_a = SOCMaker::CoreDef.new( "core_a", "v1", file, "top" )
314
        parameter = SOCMaker::Parameter.new( "integer" )
315
        core_a.inst_parameters[ :p1 ] = parameter
316
        SOCMaker::lib.add_core( core_a )
317
        @soc.cores[ :inst_a ] = SOCMaker::CoreInst.new( "core_av1" )
318
        @soc.set_param( "inst_a", "p1", 1234 )
319
        @soc.cores[ :inst_a ].params[ :p1 ].should be == 1234
320
        @soc.get_param( "inst_a", "p1" ).should be == 1234
321
      end
322
 
323
 
324
 
325
      it "should raise an error, if a static-parameter of unkonwn core is set" do
326
        expect{ @soc.set_sparam( "a_unknown_core", "p1", 1234 ) }.
327
          to raise_error( SOCMaker::ERR::ProcessingError )
328
      end
329
 
330
      it "should raise an error, if a statoc-parameter of unkonwn core is requested" do
331
        expect{ @soc.get_sparam( "a_unknown_core", "p1" ) }.
332
          to raise_error( SOCMaker::ERR::ProcessingError )
333
      end
334
 
335
      it "should an error, a static parameter doesn't exist" do
336
 
337
        file = { "file.vhd".to_sym => SOCMaker::HDLFile.new( "./file.vhd" ) }
338
        core_a = SOCMaker::CoreDef.new( "core_a", "v1", file, "top" )
339
        SOCMaker::lib.add_core( core_a )
340
        @soc.cores[ :inst_a ] = SOCMaker::CoreInst.new( "core_av1" )
341
 
342
        expect{ @soc.set_sparam( "core_av1", "p1", 1234 ) }.
343
          to raise_error( SOCMaker::ERR::ProcessingError )
344
        expect{ @soc.get_sparam( "core_av1", "p1" ) }.
345
          to raise_error( SOCMaker::ERR::ProcessingError )
346
      end
347
 
348
      it "should set a static-parameter and provide this static parameter" do
349
 
350
        file = { "file.vhd".to_sym => SOCMaker::HDLFile.new( "./file.vhd" ) }
351
        core_a = SOCMaker::CoreDef.new( "core_a", "v1", file, "top" )
352
        pentry = SOCMaker::SParameterEntry.new( "integer", "TOK" )
353
        parameter = SOCMaker::SParameter.new( "file/path.vhd.src",
354
                                              "file/path.vhd",
355
                                              'parameters' => { p1: pentry } )
356
        core_a.static_parameters[ :p1 ] = parameter
357
        SOCMaker::lib.add_core( core_a )
358
        @soc.cores[ :inst_a ] = SOCMaker::CoreInst.new( "core_av1" )
359
 
360
        @soc.set_sparam( "core_av1", "p1", 1234 )
361
        @soc.static[ :core_av1 ][ :p1 ].should be == 1234
362
        @soc.get_sparam( "core_av1", "p1" ).should be == 1234
363
      end
364
 
365
 
366
 
367
      it "should call coder functions for each core-def. (stub-version)" do
368
 
369
        coder = double()
370
 
371
        added_cores = {}
372
        coder.stub( :add_core_declaration ) do |name_arg, def_arg|
373
          added_cores[ name_arg.to_sym ] = def_arg
374
        end
375
 
376
        added_instances = {}
377
        coder.stub( :add_core_inst ) do |name_arg, inst_arg|
378
          added_instances[ name_arg.to_sym ] = inst_arg
379
        end
380
 
381
        coder.stub( :get_entity ){ |arg_soc,arg_str| }
382
 
383
        coder.stub( :is_a? ){ SOCMaker::VHDLCoder }
384
 
385
        added_cons = {}
386
        @soc.stub( :gen_toplevel_con ) do |name_arg,
387
                                           rule_arg,
388
                                           m0_arg,
389
                                           m1_arg |
390
          added_cons[ name_arg.to_sym ] = { rule: rule_arg,
391
                                            m0: m0_arg, m1: m1_arg }
392
        end
393
 
394
        dir_path = ""
395
        FileUtils.stub( :mkdir_p ) { |arg| dir_path = arg }
396
        SOCMaker::conf[ :build_dir ] = 'a'
397
        SOCMaker::conf[ :hdl_dir   ] = 'b'
398
        dir_path_ref = "a/b"
399
 
400
 
401
 
402
 
403
        file = { "file.vhd".to_sym => SOCMaker::HDLFile.new( "./file.vhd" ) }
404
        core_a = SOCMaker::CoreDef.new( "core_a", "v1", file, "top" )
405
        core_b = SOCMaker::CoreDef.new( "core_b", "v1", file, "top" )
406
        SOCMaker::lib.add_core( core_a )
407
        SOCMaker::lib.add_core( core_b )
408
 
409
        ifc_spc = SOCMaker::IfcSpc.new( "myifc", "v1", 'ports' => { port_a: 1, port_b: 0 } )
410
        SOCMaker::lib.add_ifc( ifc_spc )
411
        ifc_def_1 = SOCMaker::IfcDef.new( "myifc", "v1", 0, { a: SOCMaker::IfcPort.new( "port_a", 1 ) } )
412
        ifc_def_0 = SOCMaker::IfcDef.new( "myifc", "v1", 1, { b: SOCMaker::IfcPort.new( "port_b", 1 ) } )
413
 
414
 
415
        core_a.interfaces[ :ifc_a ] = ifc_def_0
416
        core_a.interfaces[ :ifc_b ] = ifc_def_1
417
        core_b.interfaces[ :ifc_a ] = ifc_def_0
418
        core_b.interfaces[ :ifc_b ] = ifc_def_1
419
 
420
 
421
        i1 = SOCMaker::CoreInst.new( "core_av1" )
422
        i2 = SOCMaker::CoreInst.new( "core_av1" )
423
        i3 = SOCMaker::CoreInst.new( "core_bv1" )
424
        i4 = SOCMaker::CoreInst.new( "core_bv1" )
425
 
426
        @soc.cores[ :inst_a ] = i1
427
        @soc.cores[ :inst_b ] = i2
428
        @soc.cores[ :inst_c ] = i3
429
        @soc.cores[ :inst_d ] = i4
430
        @soc.add_connection(  "inst_a", "ifc_a", "inst_b", "ifc_b", "a_new_con" )
431
 
432
 
433
        # file writing stub
434
        file_mock = double()
435
        file_mock.stub( :write )
436
        File.should_receive(:open).and_yield(file_mock)
437
 
438
        @soc.gen_toplevel( coder )
439
        added_cores.should be == { :core_av1 => core_a, :core_bv1 => core_b }
440
        added_instances.should be == { inst_a: i1, inst_b: i2, inst_c: i3, inst_d: i4 }
441
        added_cons.should be == { a_new_con: { rule: "or", m0: {inst_a: :ifc_a}, m1: {inst_b: :ifc_b } } }
442
        dir_path.should be == dir_path_ref
443
      end
444
 
445
 
446
      it "should create valid vhdl output with our test library" do
447
 
448
        SOCMaker::conf[ :build_dir ] = 'spec/tmp_build2'
449
        SOCMaker::conf[ :hdl_dir   ] = 'b'
450
        coder = SOCMaker::VHDLCoder.new
451
        SOCMaker::lib.refresh( './spec/test_soc_lib' )
452
        soc = SOCMaker::from_f( './spec/test_soc.yaml' );
453
        soc.gen_toplevel( coder );
454
        soc.copy_files
455
       #p soc.cons
456
       #puts soc.to_yaml
457
      end
458
 
459
 
460
 
461
    end
462
 
463
  describe SOCMaker::SOCDef, "object handling, en-decoding:" do
464
 
465
    it "should be possible to encode and decode a core instance" do
466
      yaml_str = @soc.to_yaml
467
      o2 = YAML::load( yaml_str )
468
      @soc.should be == o2
469
    end
470
 
471
    it "should return false for two non-equal objects" do
472
      o2 = Marshal::load(Marshal.dump(@soc))
473
      o2.name << "X"
474
      ( o2 == @soc ).should be == false
475
    end
476
 
477
  end
478
 
479
 
480
end
481
 
482
 
483
 
484
 
485
# vim: noai:ts=2:sw=2

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.