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

Subversion Repositories ssbcc

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

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

powered by: WebSVN 2.1.0

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