Line 1... |
Line 1... |
#!/usr/bin/python2.7
|
#!/usr/bin/python2.7
|
|
|
################################################################################
|
|
#
|
|
# Copyright 2012, Sinclair R.F., Inc.
|
|
#
|
#
|
|
# Copyright 2012-2015, Sinclair R.F., Inc.
|
# Build an SSBCC system.
|
# Build an SSBCC system.
|
#
|
|
################################################################################
|
|
|
|
import math
|
import math
|
import os
|
import os
|
import re
|
import re
|
import sys
|
import sys
|
import tempfile
|
import tempfile
|
|
|
from ssbccUtil import *;
|
from ssbccUtil import *;
|
from ssbccConfig import SSBCCconfig;
|
from ssbccConfig import SSBCCconfig;
|
|
from ssbccPeripheral import InterruptPeripheralAssigned;
|
|
|
################################################################################
|
################################################################################
|
#
|
#
|
# Surround the program with a try ... except clause
|
# Surround the program with a try ... except clause
|
#
|
#
|
Line 76... |
Line 72... |
config.functions['display_opcode'] = True;
|
config.functions['display_opcode'] = True;
|
|
|
if argList.D:
|
if argList.D:
|
for name in argList.D:
|
for name in argList.D:
|
if not re.match('D_',name):
|
if not re.match('D_',name):
|
raise SSBCCException('Bad define name "%s" should start with "D_"' % name);
|
raise SSBCCException('Argument "%s" to %s should start with "D_"' % (name,sys.argv[0],));
|
config.AddDefine(name);
|
config.AddDefine(name);
|
|
|
if argList.I:
|
if argList.I:
|
for pathString in argList.I:
|
for pathString in argList.I:
|
if not os.path.isdir(pathString):
|
if not os.path.isdir(pathString):
|
Line 383... |
Line 379... |
cmd = os.path.join(config.Get('corepath'), compiler[0]);
|
cmd = os.path.join(config.Get('corepath'), compiler[0]);
|
if argList.help_macro:
|
if argList.help_macro:
|
cmd += ' --help-macro %s' % argList.help_macro
|
cmd += ' --help-macro %s' % argList.help_macro
|
if argList.list_macros:
|
if argList.list_macros:
|
cmd += ' --list-macros'
|
cmd += ' --list-macros'
|
|
if InterruptPeripheralAssigned():
|
|
cmd += ' -i';
|
for name in config.constants:
|
for name in config.constants:
|
cmd += (' -C %s=%s' % (name,config.constants[name],));
|
cmd += (' -C %s=%s' % (name,config.constants[name],));
|
for name in config.defines:
|
for name in config.defines:
|
cmd += (' -D %s' % name);
|
cmd += (' -D %s' % name);
|
for ix in range(len(config.parameters)):
|
for ix in range(len(config.parameters)):
|
Line 454... |
Line 452... |
config.SetMemoryParameters(memParam,dict(bank=int(cmd[2]),length=int(cmd[3]),body=memoryBody));
|
config.SetMemoryParameters(memParam,dict(bank=int(cmd[2]),length=int(cmd[3]),body=memoryBody));
|
# program .main, optional .interrupt, and length
|
# program .main, optional .interrupt, and length
|
elif re.match(':program',line):
|
elif re.match(':program',line):
|
cmd = re.findall(':program (\d+) (\S+) (\d+)',line);
|
cmd = re.findall(':program (\d+) (\S+) (\d+)',line);
|
mainStart = int(cmd[0][0]);
|
mainStart = int(cmd[0][0]);
|
if cmd[0][1] == '[]':
|
if cmd[0][1] != '[]':
|
interruptStart = -1;
|
config.Set('interruptAddress',int(cmd[0][1]));
|
else:
|
|
interruptStart = int(cmd[0][1]);
|
|
mainLength = int(cmd[0][2]);
|
mainLength = int(cmd[0][2]);
|
for line in fpAssemberOutput:
|
for line in fpAssemberOutput:
|
ixLine = ixLine + 1;
|
ixLine = ixLine + 1;
|
while line and line[-1] in ('\n','\r',):
|
while line and line[-1] in ('\n','\r',):
|
line = line[:-1];
|
line = line[:-1];
|
Line 482... |
Line 478... |
#
|
#
|
# Ensure the processor has been consistently defined.
|
# Ensure the processor has been consistently defined.
|
#
|
#
|
################################################################################
|
################################################################################
|
|
|
|
# Ensure consistent implementation of an interrupt peripheral and an interrupt
|
|
# handler in the source assembly.
|
|
if InterruptPeripheralAssigned() and not config.InterruptVector():
|
|
raise SSBCCException('Interrupt peripheral defined but no .interrupt function defined');
|
|
if config.InterruptVector() and not InterruptPeripheralAssigned():
|
|
raise ssbccPeripheral('.interrupt function defined but no interrupt peripheral defined');
|
|
|
# Ensure all memories are used.
|
# Ensure all memories are used.
|
for ixMem in range(config.NMemories()):
|
for ixMem in range(config.NMemories()):
|
memParam = config.GetMemoryParameters(ixMem);
|
memParam = config.GetMemoryParameters(ixMem);
|
if 'length' not in memParam:
|
if 'length' not in memParam:
|
raise SSBCCException('Memory "%s" not used in program' % memParam['name']);
|
raise SSBCCException('Memory "%s" not used in program' % memParam['name']);
|
Line 534... |
Line 537... |
if config.IsSymbol(cmd[0][-1]):
|
if config.IsSymbol(cmd[0][-1]):
|
raise SSBCCException('Symbol "%s" is used by the core and cannot be used by peripherals, etc.' % cmd[0][-1]);
|
raise SSBCCException('Symbol "%s" is used by the core and cannot be used by peripherals, etc.' % cmd[0][-1]);
|
fpOutCore.write(line);
|
fpOutCore.write(line);
|
continue;
|
continue;
|
fillCommand = re.findall(r'..@SSBCC@\s+(\S+)',line)[0];
|
fillCommand = re.findall(r'..@SSBCC@\s+(\S+)',line)[0];
|
# functions and tasks
|
|
if fillCommand == "functions":
|
|
genFunctions(fpOutCore,config);
|
|
# inports
|
|
elif fillCommand == 'inports':
|
|
genInports(fpOutCore,config);
|
|
# localparam
|
|
elif fillCommand == 'localparam':
|
|
genLocalParam(fpOutCore,config);
|
|
# memories
|
# memories
|
elif fillCommand == 'memories':
|
if fillCommand == 'memories':
|
genMemories(fpOutCore,fpMemFile,config,programBody);
|
genMemories(fpOutCore,fpMemFile,config,programBody);
|
# module
|
|
elif fillCommand == 'module':
|
|
genModule(fpOutCore,config);
|
|
# outports
|
|
elif fillCommand == 'outports':
|
|
genOutports(fpOutCore,config);
|
|
# peripherals
|
# peripherals
|
elif fillCommand == 'peripherals':
|
elif fillCommand == 'peripherals':
|
if not config.peripheral:
|
if not config.peripheral:
|
fpOutCore.write('//\n// No peripherals\n//\n');
|
fpOutCore.write('//\n// No peripherals\n//\n');
|
for p in config.peripheral:
|
for p in config.peripheral:
|
Line 566... |
Line 554... |
elif fillCommand == 's_memory':
|
elif fillCommand == 's_memory':
|
if config.NMemories() == 0:
|
if config.NMemories() == 0:
|
fpOutCore.write('wire [7:0] s_memory = 8\'h00;\n');
|
fpOutCore.write('wire [7:0] s_memory = 8\'h00;\n');
|
else:
|
else:
|
fpOutCore.write('wire [7:0] s_memory;\n');
|
fpOutCore.write('wire [7:0] s_memory;\n');
|
# additional signals
|
|
elif fillCommand == 'signals':
|
|
genSignals(fpOutCore,config);
|
|
# user_header
|
# user_header
|
elif fillCommand == 'user_header':
|
elif fillCommand == 'user_header':
|
genUserHeader(fpOutCore,user_header);
|
genUserHeader(fpOutCore,user_header);
|
# Verilator tracing on/off
|
# Verilator tracing on/off
|
elif fillCommand == "verilator_tracing":
|
elif fillCommand == "verilator_tracing":
|
if config.Get('verilator_tracing_on'):
|
if config.Get('verilator_tracing_on'):
|
fpOutCore.write('/* verilator tracing_on */\n');
|
fpOutCore.write('/* verilator tracing_on */\n');
|
else:
|
else:
|
fpOutCore.write('/* verilator tracing_off */\n');
|
fpOutCore.write('/* verilator tracing_off */\n');
|
# error
|
# All others are specific to the core.
|
else:
|
else:
|
print 'WARNING: Unimplemented command ' + fillCommand;
|
doFillCommand(fillCommand,fpOutCore,config);
|
|
|
#
|
#
|
# Write package file (for use in VHDL or mixed-language projects)
|
# Write package file (for use in VHDL or mixed-language projects)
|
#
|
#
|
|
|