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

Subversion Repositories ssbcc

[/] [ssbcc/] [trunk/] [ssbcc] - Blame information for rev 9

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

Line No. Rev Author Line
1 2 sinclairrf
#!/usr/bin/python2.7
2
 
3
################################################################################
4
#
5
# Copyright 2012, Sinclair R.F., Inc.
6
#
7
# Build an SSBCC system.
8
#
9
################################################################################
10
 
11
import math
12
import os
13
import re
14
import sys
15
import tempfile
16
 
17
from ssbccUtil import *;
18
from ssbccConfig import SSBCCconfig;
19
 
20
################################################################################
21
#
22
# Surround the program with a try ... except clause
23
#
24
################################################################################
25
 
26
try:
27
 
28
  ################################################################################
29
  #
30
  # Parse the command line arguments
31
  #
32
  ################################################################################
33
 
34
  #
35
  # Construct the command-line argument list parser
36
  #
37
 
38
  def validateFile(filename):
39
    if filename == '-':
40
      filename = '/dev/stdin';
41
    try:
42
      return file(filename,'r');
43
    except:
44
      raise SSBCCException('Error opening "%s"' % filename);
45
 
46
  import argparse
47
  argListParser = argparse.ArgumentParser(description='SSBCC system builder');
48 9 sinclairrf
  argListParser.add_argument('-D', metavar='D_name', type=str, action='append', help='Define symbol (must start with "D_")');
49 2 sinclairrf
  argListParser.add_argument('-G', metavar='parameter_name=value', type=str, action='append', help='Override parameter value');
50
  argListParser.add_argument('-I', metavar='include_dir', type=str, action='append', help='Add search directory for included files and peripherals');
51 3 sinclairrf
  argListParser.add_argument('-M', metavar='macropath', action='append', help='Macro search path');
52 2 sinclairrf
  argListParser.add_argument('-P', metavar='peripheral_name[="parameters"]', type=str, action='append', help='Add peripheral');
53
  argListParser.add_argument('-o', metavar='outCoreName', type=str, help='output core name');
54
  argListParser.add_argument('-q', action='store_true', help='quiet');
55
  argListParser.add_argument('--define-clog2', action='store_true', help='define clog2 instead of using built-in $clog2');
56
  argListParser.add_argument('--display-opcode', action='store_true', help='add 3-letter decode of opcode (for trace viewer)');
57 3 sinclairrf
  argListParser.add_argument('--rand-instr-mem', action='store_true', help='fill unused instruction memory with random values');
58
  argListParser.add_argument('--synth-instr-mem', type=str, help='synthesis constraint for instruction memory');
59 2 sinclairrf
  argListParser.add_argument('--verilator-tracing-on', action='store_true', help='show all signals in verilator waveform files');
60
  argListParser.add_argument('filename', metavar='filename', type=validateFile, help='SSBCC configuration file');
61
  argList = argListParser.parse_args();
62
 
63
  #
64
  # Set the command-line dependent configuration parameters.
65
  #
66
 
67
  config = SSBCCconfig();
68
 
69
  config.Set('define_clog2',argList.define_clog2);
70 3 sinclairrf
  config.Set('rand_instr_mem',argList.rand_instr_mem);
71 2 sinclairrf
  config.Set('verilator_tracing_on',argList.verilator_tracing_on);
72
 
73
  if argList.display_opcode:
74
    config.functions['display_opcode'] = True;
75
 
76
  if argList.D:
77 9 sinclairrf
    for name in argList.D:
78
      if not re.match('D_',name):
79
        raise SSBCCException('Bad define name "%s" should start with "D_"' % name);
80
      config.AddDefine(name);
81 2 sinclairrf
 
82 3 sinclairrf
  if argList.I:
83
    for pathString in argList.I:
84
      if not os.path.isdir(pathString):
85 9 sinclairrf
        raise SSBCCException('Bad path string:  "%s/%s"' % (os.getcwd(),pathString,));
86 3 sinclairrf
      config.AppendIncludePath(pathString);
87
      config.InsertPeripheralPath(pathString);
88
 
89 2 sinclairrf
  if argList.o:
90
    config.Set('outCoreName',argList.o);
91
  else:
92
    config.Set('outCoreName',os.path.splitext(os.path.basename(argList.filename.name))[0]);
93
 
94 3 sinclairrf
  if argList.synth_instr_mem:
95
    config.Set('synth_instr_mem',argList.synth_instr_mem);
96
  else:
97
    config.Set('synth_instr_mem',None);
98
 
99 2 sinclairrf
  #
100
  # Read the configuration file into a line-by-line buffer.
101 3 sinclairrf
  # Note:  argList.filename is a file handle, so no paths will be searched by
102
  #        LoadFile.  This is ensured by setting config to None.
103 2 sinclairrf
  #
104
 
105
  filename = argList.filename.name;
106 3 sinclairrf
  configList = LoadFile(argList.filename,None);
107 2 sinclairrf
  ifstack = list();
108
 
109
  configListStack = list();
110
 
111
  #
112
  # Read the configuration file.
113
  #
114
 
115
  bufLine = "";
116
  compiler = [];
117
  user_header = list();
118
  while configList or configListStack:
119
    # If the current file has ended, then proceed to the next file.
120
    if not configList:
121
      if not len(bufLine) == 0:
122
        raise SSBCCException('Malformed configuration command at the end of %s' % filename);
123
      if ifstack:
124
        raise SSBCCException('%d unmatched conditional(s) at end of %s' % (len(ifstack),filename,));
125
      (filename,configList,ifstack) = configListStack.pop();
126
      continue;
127
    # Get the next line to process and its line number.
128
    (tmpLine,ixLine) = configList.pop(0);
129
    # Use the start line of a sequence of lines for error messages.
130
    if not bufLine:
131
      loc = '%s:%d' % (filename,ixLine,);
132
    # Merge continuation lines.
133
    bufLine += tmpLine;
134
    if bufLine and bufLine[-1] == '\\':
135
      bufLine = bufLine[:-1];
136
      continue;
137
    line = bufLine;
138
    bufLine = "";
139
    # Reject blank and comment lines
140
    if re.match(r'\s*(#.*)?$',line):
141
      pass;
142
    # .ELSE
143
    elif re.match(r'\s*\.ELSE\b',line):
144
      if not ifstack:
145
        raise SSBCCException('unmatched ".ELSE" at %s' % loc);
146
      ifstack[-1] = not ifstack[-1];
147
    # .ENDIF
148
    elif re.match(r'\s*\.ENDIF\b',line):
149
      if not ifstack:
150
        raise SSBCCException('unmatched ".ENDIF" at %s' % loc);
151
      ifstack.pop();
152
    # .IFDEF conditional
153
    elif re.match(r'\s*\.IFDEF\b',line):
154
      cmd = re.findall(r'\s*\.IFDEF\s+(\w+)\s*$',line);
155
      if not cmd:
156
        raise SSBCCException('Malformed ".IFDEF" configuration command on %s' % loc);
157
      cmd = cmd[0];
158
      ifstack.append(config.IsSymbol(cmd));
159
    # .IFNDEF conditional
160
    elif re.match(r'\s*\.IFNDEF\b',line):
161
      cmd = re.findall(r'\s*\.IFNDEF\s+(\w+)\s*$',line);
162
      if not cmd:
163
        raise SSBCCException('Malformed ".IFNDEF" configuration command on %s' % loc);
164
      cmd = cmd[0];
165
      ifstack.append(not config.IsSymbol(cmd));
166
    elif re.match(r'\s*.INCLUDE\b',line):
167
      cmd = re.findall(r'\s*\.INCLUDE\s+(\S+)\s*$',line);
168
      if not cmd:
169
        raise SSBCCException('Malformed ".INCLUDE" configuration command on %s' % loc);
170
      configListStack.append((filename,configList,ifstack,));
171
      filename = cmd[0];
172 3 sinclairrf
      configList = LoadFile(filename,config);
173 2 sinclairrf
      ifstack = list();
174
    # Consume configuration commands disabled by conditionals
175
    elif ifstack and not ifstack[-1]:
176
      pass;
177
    # ARCHITECTURE
178
    elif re.match(r'\s*ARCHITECTURE\b',line):
179
      if config.Exists('architecture'):
180
        raise SSBCCException('ARCHITECTURE already specified before %s' % loc);
181
      cmd = re.findall(r'\s*ARCHITECTURE\s+(\S+)\s+(\S+)$',line);
182
      if not cmd:
183
        raise SSBCCException('Malformed ARCHITECTURE configuration command at %s: "%s"' % (loc,line,));
184
      cmd = cmd[0];
185
      config.Set('architecture',cmd[0]);
186
      config.Set('hdl',cmd[1]);
187
      config.Set('corepath',os.path.join(sys.path[0],config.Get('architecture')));
188
      if not os.path.isdir(config.Get('corepath')):
189
        raise SSBCCException('Architecture "%s" does not exist at %s' % (cmd,loc,));
190
      config.InsertPeripheralPath(os.path.join(config.Get('corepath'),'peripherals'));
191
      # TODO -- move these assignments into an object
192
      config.Set('data_width',8);
193
    # ASSEMBLY language for processor code
194
    elif re.match(r'\s*ASSEMBLY\b',line):
195
      cmd = re.findall(r'\s*ASSEMBLY\s+(\S.*)',line);
196
      compiler = ('asm',cmd[0],);
197
    # COMBINE
198
    elif re.match(r'\s*COMBINE\b',line):
199
      config.ProcessCombine(loc,line);
200
    # CONSTANTS
201
    elif re.match(r'\s*CONSTANT\b',line):
202
      if not config.Exists('architecture'):
203
        raise SSBCCException('"CONSTANT"s cannot be defined before the "ARCHITECTURE" is defined at %s' % loc);
204 9 sinclairrf
      cmd = re.findall(r'\s*CONSTANT\s+(C_\w+)\s+(-?[1-9]\d*|\w+)\s*$',line);
205 2 sinclairrf
      if not cmd:
206
        raise SSBCCException('Malformed "CONSTANT" configuration command on %s: "%s"' % (loc,line,));
207
      cmd = cmd[0];
208
      config.AddConstant(cmd[0],cmd[1],loc);
209
    # DATA_STACK
210
    elif re.match(r'\s*DATA_STACK\b',line):
211
      if config.Exists('data_stack'):
212
        raise SSBCCException('DATA_STACK already defined before %s' % loc);
213
      cmd = re.findall(r'\s*DATA_STACK\s+([1-9]\d*)',line);
214
      if not cmd:
215
        raise SSBCCException('Malformed "DATA_STACK" configuration command on %s: "%s"' % (loc,line,));
216
      x = int(cmd[0]);
217
      if math.modf(math.log(x,2))[0] != 0:
218
        raise SSBCCException('DATA_STACK must be set to a power of 2, not %d, at %s' % (x,loc,));
219
      if x < 8:
220
        raise SSBCCException('DATA_STACK must be at least 8, not %d, at %s' % (x,loc,));
221
      config.Set('data_stack',int(cmd[0]));
222
    # INPORT
223
    elif re.match(r'\s*INPORT\b',line):
224
      if not config.Exists('architecture'):
225
        raise SSBCCException('"INPORT"s cannot be defined before the "ARCHITECTURE" is defined at %s' % loc);
226
      config.ProcessInport(loc,line);
227
    # INSTRUCTION
228
    elif re.match(r'\s*INSTRUCTION\b',line):
229
      if config.Exists('nInstructions'):
230
        raise SSBCCException('INSTRUCTION already specified before %s' % loc);
231
      cmd = re.findall(r'\s*INSTRUCTION\s+([1-9]\d*\*?[1-9]?\d*)\s*$',line);
232
      if not cmd:
233
        raise SSBCCException('Malformed "INSTRUCTION" configuration command at %s: "%s"' % (loc,line,));
234
      config.SetMemoryBlock('nInstructions',cmd[0],(loc,line,));
235
    # INVERT_RESET
236
    elif re.match(r'\s*INVERT_RESET\s*$',line):
237
      if (config.Exists('invertReset')):
238
        raise SSBCCException('INVERT_RESET already specified before %s' % loc);
239
      config.Set('invertReset',True);
240
    # LOCALPARM
241
    elif re.match(r'\s*LOCALPARAM\b',line):
242
      cmd = re.findall(r'\s*LOCALPARAM\s+(L_\w+)\s+(\S+)$',line);
243
      if (not cmd) or (len(cmd[0]) != 2):
244
        raise SSBCCException('Malformed LOCALPARAM configuration command at %s: "%s"' % (loc,line,));
245
      cmd = cmd[0];
246
      config.AddParameter(cmd[0],cmd[1],loc);
247
    # MEMORY
248
    elif re.match(r'\s*MEMORY\b',line):
249
      if not config.Exists('architecture'):
250
        raise SSBCCException('"MEMORY"s cannot be defined before the "ARCHITECTURE" is defined at %s' % loc);
251
      # TODO -- make the maximum number of memories architecture dependent
252
      if config.NMemories() >= 4:
253
        raise SSBCCException('Program is limited to 4 memories');
254
      cmd = re.findall(r'\s*MEMORY\s+(RAM|ROM)\s+([A-Za-z]\w*)\s+(\d+)\s*$',line);
255
      if (not cmd) or (len(cmd[0]) != 3):
256
        raise SSBCCException('Malformed MEMORY configuration command at %s: "%s"' % (loc,line,));
257
      config.AddMemory(cmd[0],loc);
258
    # OUTPORT
259
    elif re.match(r'\s*OUTPORT\b',line):
260
      if not config.Exists('architecture'):
261
        raise SSBCCException('"OUTPORT"s cannot be defined before the "ARCHITECTURE" is defined at %s' % loc);
262
      config.ProcessOutport(line,loc);
263
    # PARAMETER
264
    elif re.match(r'\s*PARAMETER\b',line):
265
      cmd = re.findall(r'\s*PARAMETER\s+(G_\w+)\s+(\S+)$',line);
266
      if (not cmd) or (len(cmd[0]) != 2):
267
        raise SSBCCException('Malformed PARAMETER configuration command at %s: "%s"' % (loc,line,));
268
      cmd = cmd[0];
269
      config.AddParameter(cmd[0],cmd[1],loc);
270
    # PERIPHERAL
271
    elif re.match(r'\s*PERIPHERAL\b',line):
272
      if not config.Exists('architecture'):
273
        raise SSBCCException('"PERIPHERAL"s cannot be defined before the "ARCHITECTURE" is defined at %s' % loc);
274
      config.ProcessPeripheral(loc,line);
275
    # PORTCOMMENT
276
    elif re.match(r'\s*PORTCOMMENT\b',line):
277
      cmd = re.findall(r'\s*PORTCOMMENT\s+(.*)',line);
278
      config.AddIO(cmd[0],0,'comment',loc);
279
    # RETURN_STACK
280
    elif re.match(r'\s*RETURN_STACK\b',line):
281
      if config.Exists('return_stack'):
282
        raise SSBCCException('RETURN_STACK already specified before %s' % loc);
283
      cmd = re.findall(r'\s*RETURN_STACK\s+([1-9]\d*)',line);
284
      if not cmd:
285
        raise SSBCCException('Malformed "RETURN_STACK" configuration command at %s: "%s"' % (loc,line,));
286
      config.Set('return_stack',int(cmd[0]));
287
    # SRAM_WIDTH
288
    elif re.match(r'\s*SRAM_WIDTH\b',line):
289
      if config.Exists('sram_width'):
290
        raise SSBCCException('SRAM_WIDTH already specified before %s' % loc);
291
      cmd = re.findall(r'\s*SRAM_WIDTH\s+([1-9]\d*)',line);
292
      if not cmd:
293
        raise SSBCCException('Malformed "SRAM_WIDTH" configuration command %s: "%s"' % (loc,line,));
294
      config.Set('sram_width',int(cmd[0]));
295
    # USER_HEADER
296
    elif re.match(r'\s*USER_HEADER\b',line):
297
      user_header_done = False;
298 3 sinclairrf
      while configList:
299
        (line,ixLine) = configList.pop(0);
300
        if re.match(r'\s*END_USER_HEADER\b',line):
301 2 sinclairrf
          user_header_done = True;
302
          break;
303
        user_header.append(line);
304
      if not user_header_done:
305
        raise SSBCCException('No "END_USER_HEADER" found for "USER_HEADER" at %s' % loc);
306
    # error
307
    else:
308
      raise SSBCCException('Unrecognized configuration command at %s: "%s"' % (loc,line,));
309
  if bufLine:
310
    raise SSBCCException('Malformed last line(s): "%s"' % bufLine);
311
 
312
  if ifstack:
313
    raise SSBCCException('%d unmatched conditional(s) at end of %s' % (len(ifstack),filename,));
314
 
315
  #
316
  # Incorporate command-line specified parameter and localparam values.
317
  #
318
 
319
  if argList.G:
320
    for parameter in argList.G:
321
      if not re.match(r'[LG]_\w+=\S+$',parameter):
322
        raise SSBCCException('Malformed parameter specification: "%s"' % parameter);
323
      cmd = re.findall(r'([LG]_\w+)=(\S+)',parameter);
324
      cmd = cmd[0];
325
      config.OverrideParameter(cmd[0],cmd[1]);
326
 
327
  #
328
  # Append peripherals from command-line.
329
  #
330
 
331
  if argList.P:
332
    for peripheral in argList.P:
333
      config.ProcessPeripheral(-1,'PERIPHERAL '+peripheral);
334
 
335
  #
336
  # Set unspecified default values
337
  #
338
 
339
  if not config.Exists('sram_width'):
340
    config.Set('sram_width',9);
341
  if not config.Exists('invertReset'):
342
    config.Set('invertReset',False);
343
 
344
  #
345
  # end-of-file processing
346
  #
347
 
348
  if not config.Exists('architecture'):
349
    raise SSBCCException('Required ARCHITECTURE configuration command missing');
350
  if not config.Exists('data_stack'):
351
    raise SSBCCException('Required DATA_STACK configuration command missing');
352
  if not config.Exists('nInstructions'):
353
    raise SSBCCException('Required INSTRUCTION configuration command missing');
354
  if not config.Exists('return_stack'):
355
    raise SSBCCException('Required RETURN_STACK configuration command missing');
356
 
357
  # Ensure reasonable values
358
  if config.Get('nInstructions')['length'] > 2**13:
359
    raise SSBCCException('Instruction space cannot exceed %d at %s: "%s"' % (2**13,loc,line,));
360
 
361
  # Add memories that are not combined into singleton entries in the "combined"
362
  # list and complete the address range assignments.
363
  config.CompleteCombines();
364
 
365
  ################################################################################
366
  #
367
  # Compile the processor code and read the tables it generated.
368
  #
369
  ################################################################################
370
 
371
  # Generate peripheral libraries (if any).
372 9 sinclairrf
  for p in config.peripheral:
373
    p.GenAssembly(config);
374 2 sinclairrf
 
375
  # Compute the file name to store the assembler output
376
  assemblerOutput = os.path.splitext(argList.filename.name)[0]+'.9x8-meta'
377
 
378
  # Compute the command to invoke the compiler.
379
  if not compiler:
380
    raise SSBCCException('ASSEMBLY configuration command is missing');
381
  cmd = os.path.join(config.Get('corepath'), compiler[0]);
382
  for name in config.constants:
383
    cmd += (' -C %s=%s' % (name,config.constants[name],));
384 9 sinclairrf
  for name in config.defines:
385
    cmd += (' -D %s' % name);
386 2 sinclairrf
  for ix in range(len(config.parameters)):
387
    cmd += (' -G %s' % config.parameters[ix][0]);
388
  for ix in range(config.NInports()):
389
    cmd += (' -I %s=%d' % (config.inports[ix][0],ix));
390
  for ix in range(config.NOutports()):
391
    if config.IsStrobeOnlyOutport(config.outports[ix]):
392
      cmd += (' -R %s=%d' % (config.outports[ix][0],ix));
393
    else:
394
      cmd += (' -O %s=%d' % (config.outports[ix][0],ix));
395
  for memNameLength in config.MemoryNameLengthList():
396
    cmd += (' -S %s=%d' % memNameLength);
397
  for signalNameLength in config.SignalLengthList():
398
    cmd += (' -S %s=%d' % signalNameLength);
399
  cmd += ' -o ' + assemblerOutput;
400
  for stack_name in ('data_stack','return_stack',):
401
    cmd += ' -s %s=%d' % (stack_name,config.config[stack_name],);
402 3 sinclairrf
  cmd += ' -L %s' % os.path.join(sys.path[0],'lib','9x8');
403
  if argList.M:
404
    for path in argList.M:
405
      cmd += ' -M %s' % path;
406
  cmd += ' -M %s' % os.path.join(sys.path[0],'macros','9x8');
407 2 sinclairrf
  if argList.I:
408
    for pathString in argList.I:
409
      cmd += ' -L %s' % pathString;
410
  cmd += ' ' + compiler[1];
411
 
412
  # Invoke the compiler and exit if it failed.
413
  if not argList.q:
414
    print 'Invoking the assember with the following command:  ' + cmd;
415
  cmdStatus = os.system(cmd);
416
  if cmdStatus != 0:
417
    raise SSBCCException('Running the assembler');
418
 
419
  # Read the assembler output tables.
420
  fpAssemberOutput = open(assemblerOutput,'r');
421
  ixLine = 0;
422
  programBody = list();
423
  programBodyLength = 0;
424
  for line in fpAssemberOutput:
425
    ixLine = ixLine + 1;
426
    # blank line
427
    if re.match('^\s*$',line):
428
      continue;
429
    # memory type, name, index, and length
430
    elif re.match(':memory',line):
431
      cmd = re.findall(':memory (\S+) (\S+) (\S+) (\S+)',line);
432
      cmd = cmd[0];
433
      memName = cmd[1];
434
      if not config.IsMemory(memName):
435
        raise SSBCCException('%s "%s" not declared in %s' % (cmd[0],memName,argList.filename,));
436
      memParam = config.GetMemoryParameters(memName);
437
      if cmd[0] != memParam['type']:
438
        raise SSBCCException('Type of memory "%s" is inconsistent' % memName);
439
      if int(cmd[3]) > memParam['maxLength']:
440
        raise SSBCCException('Length of memory "%s" is %s which exceeds limit of %d' % (memName,cmd[3],memParam['maxLength'],));
441
      memoryBody = list();
442
      for line in fpAssemberOutput:
443
        ixLine = ixLine + 1;
444
        if len(line) > 1:
445
          memoryBody.append(line)
446
        else:
447
          break;
448
      config.SetMemoryParameters(memParam,dict(bank=int(cmd[2]),length=int(cmd[3]),body=memoryBody));
449
    # program .main, optional .interrupt, and length
450
    elif re.match(':program',line):
451
      cmd = re.findall(':program (\d+) (\S+) (\d+)',line);
452
      mainStart = int(cmd[0][0]);
453
      if cmd[0][1] == '[]':
454
        interruptStart = -1;
455
      else:
456
        interruptStart = int(cmd[0][1]);
457
      mainLength = int(cmd[0][2]);
458
      for line in fpAssemberOutput:
459
        ixLine = ixLine + 1;
460
        while line and line[-1] in ('\n','\r',):
461
          line = line[:-1];
462
        if not line:
463
          break;
464
        programBody.append(line);
465
        if line[0] != '-':
466
          programBodyLength = programBodyLength + 1;
467
      if programBodyLength != mainLength:
468
        raise SSBCCException('Program Bug:  program length doesn\'t match declared length');
469
      maxProgramBodyLength = config.Get('nInstructions')['length'];
470
      if programBodyLength > maxProgramBodyLength:
471
        raise SSBCCException('Program body length = %d is longer than the allocated instruction table = %d' % (programBodyLength,maxProgramBodyLength,));
472
    else:
473
      raise Exception('Program Bug:  Unrecognized line at %s:%d :  "%s"' % (fpAssemberOutput.filename,ixLine,line,));
474
 
475
  ################################################################################
476
  #
477
  # Ensure the processor has been consistently defined.
478
  #
479
  ################################################################################
480
 
481
  # Ensure all memories are used.
482
  for ixMem in range(config.NMemories()):
483
    memParam = config.GetMemoryParameters(ixMem);
484
    if 'length' not in memParam:
485
      raise SSBCCException('Memory "%s" not used in program' % memParam['name']);
486
 
487
  ################################################################################
488
  #
489
  # Generate the processor core.
490
  #
491
  ################################################################################
492
 
493
  #
494
  # Access the language-specific core generator and core.
495
  #
496
 
497
  if config.Get('hdl') == 'Verilog':
498
    ssbccGenFile = 'ssbccGenVerilog.py';
499
  elif config.Get('hdl') == 'VHDL':
500
    ssbccGenFile = 'ssbccGenVHDL.py';
501
  else:
502
    raise SSBCCException('Unrecognized hdl = "%s"' % config.Get('hdl'));
503
 
504
  ssbccGenFile = os.path.join(config.Get('corepath'),ssbccGenFile);
505
  if not os.path.isfile(ssbccGenFile):
506
    raise SSBCCException('Core generator "%s" missing for hdl = "%s"' % (ssbccGenFile,config.Get('hdl'),));
507
  execfile(ssbccGenFile);
508
 
509
  rawCoreName = os.path.join(config.Get('corepath'),genCoreName());
510
  if not os.path.isfile(rawCoreName):
511
    raise SSBCCException('Core "%s% missing for hdl = "%s"' % (rawCoreName,config.Get('hdl'),));
512
  fpRawCore = open(rawCoreName,'r');
513
 
514
  outName = genOutName(config.Get('outCoreName'));
515
  fpOutCore = open(outName,'wt');
516
 
517
  memFileName = re.sub(r'\.v.*','.mem',outName);
518
  fpMemFile = open(memFileName,'wt');
519
 
520
  #
521
  # Loop through the core, copying or filling in the file as required.
522
  #
523
 
524
  for line in fpRawCore:
525
    if not re.match(r'..@SSBCC@',line):
526
      if re.match(r'\s*(reg|wire)\s',line):
527
        cmd = re.findall(r'\s*(reg|wire)\s+([[][^]]+]\s+)?(\w+)\b',line);
528
        if config.IsSymbol(cmd[0][-1]):
529
          raise SSBCCException('Symbol "%s" is used by the core and cannot be used by peripherals, etc.' % cmd[0][-1]);
530
      fpOutCore.write(line);
531
      continue;
532
    fillCommand = re.findall(r'..@SSBCC@\s+(\S+)',line)[0];
533
    # functions and tasks
534
    if fillCommand == "functions":
535
      genFunctions(fpOutCore,config);
536
    # inports
537
    elif fillCommand == 'inports':
538
      genInports(fpOutCore,config);
539
    # localparam
540
    elif fillCommand == 'localparam':
541
      genLocalParam(fpOutCore,config);
542
    # memories
543
    elif fillCommand == 'memories':
544
      genMemories(fpOutCore,fpMemFile,config,programBody);
545
    # module
546
    elif fillCommand == 'module':
547
      genModule(fpOutCore,config);
548
    # outports
549
    elif fillCommand == 'outports':
550
      genOutports(fpOutCore,config);
551
    # peripherals
552
    elif fillCommand == 'peripherals':
553
      if not config.peripheral:
554
        fpOutCore.write('//\n// No peripherals\n//\n');
555 9 sinclairrf
      for p in config.peripheral:
556
        if p != config.peripheral[0]:
557 2 sinclairrf
          fpOutCore.write('\n');
558 9 sinclairrf
        p.GenHDL(fpOutCore,config);
559 2 sinclairrf
    # "s_memory" declaration
560
    elif fillCommand == 's_memory':
561
      if config.NMemories() == 0:
562
        fpOutCore.write('wire [7:0] s_memory = 8\'h00;\n');
563
      else:
564
        fpOutCore.write('wire [7:0] s_memory;\n');
565
    # additional signals
566
    elif fillCommand == 'signals':
567
      genSignals(fpOutCore,config);
568
    # user_header
569
    elif fillCommand == 'user_header':
570
      genUserHeader(fpOutCore,user_header);
571
    # Verilator tracing on/off
572
    elif fillCommand == "verilator_tracing":
573
      if config.Get('verilator_tracing_on'):
574
        fpOutCore.write('/* verilator tracing_on */\n');
575
      else:
576
        fpOutCore.write('/* verilator tracing_off */\n');
577
    # error
578
    else:
579
      print 'WARNING:  Unimplemented command ' + fillCommand;
580
 
581
  #
582
  # Write package file (for use in VHDL or mixed-language projects)
583
  #
584
 
585
  import ssbccGenVhdlPkg
586
  ssbccGenVhdlPkg.genVhdlPkg(config);
587
 
588
################################################################################
589
#
590
# Terminating except clause
591
#
592
################################################################################
593
 
594
except SSBCCException, msg:
595
  print >> sys.stderr, 'FATAL ERROR:  ' + str(msg);
596
  exit(1);

powered by: WebSVN 2.1.0

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