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

Subversion Repositories ssbcc

[/] [ssbcc/] [trunk/] [core/] [9x8/] [ssbccGenVerilog.py] - Diff between revs 11 and 12

Show entire file | Details | Blame | View Log

Rev 11 Rev 12
Line 1... Line 1...
################################################################################
################################################################################
#
#
# Copyright 2012, Sinclair R.F., Inc.
# Copyright 2012-2015, Sinclair R.F., Inc.
#
#
# Verilog generation functions.
# Verilog generation functions.
#
#
################################################################################
################################################################################
 
 
Line 17... Line 17...
#
#
# Generate input and output core names.
# Generate input and output core names.
#
#
################################################################################
################################################################################
 
 
 
def doFillCommand(fillCommand,fpOutCore,config):
 
  """
 
  Do core-specific fill commands for the "..@SSBCC@ <fillCommand>" lines.
 
  """
 
  # functions and tasks
 
  if fillCommand == "functions":
 
    genFunctions(fpOutCore,config);
 
  # inports
 
  elif fillCommand == 'inports':
 
    genInports(fpOutCore,config);
 
  # interrupt conditionals
 
  elif fillCommand == 'interrupt__s_math_rotate':
 
    if config.InterruptVector():
 
      fpOutCore.write("""  if (s_interrupt || s_interrupted)
 
    s_math_rotate = s_T;
 
  else""");
 
  elif fillCommand == 'interrupt__s_opcode':
 
    if config.InterruptVector():
 
      fpOutCore.write("""  if (s_interrupted) begin
 
    // nop
 
  end else if (s_interrupt) begin
 
    s_return    = C_RETURN_INC;
 
  end else""");
 
  # localparam
 
  elif fillCommand == 'localparam':
 
    genLocalParam(fpOutCore,config);
 
  # module
 
  elif fillCommand == 'module':
 
    genModule(fpOutCore,config);
 
  # outports
 
  elif fillCommand == 'outports':
 
    genOutports(fpOutCore,config);
 
  # "s_PC_next" body
 
  elif fillCommand == 's_PC_next':
 
    genSPCnext(fpOutCore,config);
 
  # "s_R_pre" body
 
  elif fillCommand == 's_R_pre':
 
    genSRpre(fpOutCore,config);
 
  # additional signals
 
  elif fillCommand == 'signals':
 
    genSignals(fpOutCore,config);
 
  # error
 
  else:
 
    print 'WARNING:  Unimplemented command ' + fillCommand;
 
 
def genCoreName():
def genCoreName():
  """
  """
  Return the name of the file to use for the processor core.
  Return the name of the file to use for the processor core.
  """
  """
  return 'core.v';
  return 'core.v';
Line 48... Line 93...
                        on the ssbcc command line
                        on the ssbcc command line
    display_opcode      human-readable version of the opcode suitable for
    display_opcode      human-readable version of the opcode suitable for
                        waveform viewers
                        waveform viewers
    display_trace       when the trace or monitor_stack peripherals are included
    display_trace       when the trace or monitor_stack peripherals are included
  """
  """
 
  def DisableInterrupt(body):
 
    for replace in ('s_interrupt','s_interrupted',):
 
      replace = '\(' + replace + '\)';
 
      while re.search(replace,body):
 
        body = re.sub(replace,'(1\'b0)',body);
 
    return body;
  if 'display_opcode' in config.functions:
  if 'display_opcode' in config.functions:
    displayOpcodePath = os.path.join(config.Get('corepath'),'display_opcode.v');
    displayOpcodePath = os.path.join(config.Get('corepath'),'display_opcode.v');
    fpDisplayOpcode = open(displayOpcodePath,'rt');
    fpDisplayOpcode = open(displayOpcodePath,'rt');
    if not fpDisplayOpcode:
    if not fpDisplayOpcode:
      raise Exception('Program Bug -- "%s" not found' % displayOpcodePath);
      raise Exception('Program Bug -- "%s" not found' % displayOpcodePath);
    body = fpDisplayOpcode.read();
    body = fpDisplayOpcode.read();
    fpDisplayOpcode.close();
    fpDisplayOpcode.close();
 
    if not config.InterruptVector():
 
      body = DisableInterrupt(body);
    fp.write(body);
    fp.write(body);
  if ('clog2' in config.functions) and config.Get('define_clog2'):
  if ('clog2' in config.functions) and config.Get('define_clog2'):
    fp.write("""
    fp.write("""
// Use constant function instead of builtin $clog2.
// Use constant function instead of builtin $clog2.
function integer clog2;
function integer clog2;
Line 76... Line 129...
    fpDisplayTrace = open(displayTracePath,'rt');
    fpDisplayTrace = open(displayTracePath,'rt');
    if not fpDisplayTrace:
    if not fpDisplayTrace:
      raise Exception('Program Bug -- "%s" not found' % displayTracePath);
      raise Exception('Program Bug -- "%s" not found' % displayTracePath);
    body = fpDisplayTrace.read();
    body = fpDisplayTrace.read();
    fpDisplayTrace.close();
    fpDisplayTrace.close();
 
    if not config.InterruptVector():
 
      body = DisableInterrupt(body);
    fp.write(body);
    fp.write(body);
 
 
def genInports(fp,config):
def genInports(fp,config):
  """
  """
  Generate the logic for the input signals.
  Generate the logic for the input signals.
Line 159... Line 214...
 
 
def genLocalParam(fp,config):
def genLocalParam(fp,config):
  """
  """
  Generate the localparams for implementation-specific constants.
  Generate the localparams for implementation-specific constants.
  """
  """
  fp.write('localparam C_PC_WIDTH                              = %4d;\n' % CeilLog2(config.Get('nInstructions')['length']));
  pcWidth = CeilLog2(config.Get('nInstructions')['length']);
 
  fp.write('localparam C_PC_WIDTH                              = %4d;\n' % pcWidth);
  fp.write('localparam C_RETURN_PTR_WIDTH                      = %4d;\n' % CeilLog2(config.Get('return_stack')));
  fp.write('localparam C_RETURN_PTR_WIDTH                      = %4d;\n' % CeilLog2(config.Get('return_stack')));
  fp.write('localparam C_DATA_PTR_WIDTH                        = %4d;\n' % CeilLog2(config.Get('data_stack')));
  fp.write('localparam C_DATA_PTR_WIDTH                        = %4d;\n' % CeilLog2(config.Get('data_stack')));
  fp.write('localparam C_RETURN_WIDTH                          = (C_PC_WIDTH <= 8) ? 8 : C_PC_WIDTH;\n');
  fp.write('localparam C_RETURN_WIDTH                          = (C_PC_WIDTH <= 8) ? 8 : C_PC_WIDTH;\n');
 
 
def genMemories(fp,fpMemFile,config,programBody):
def genMemories(fp,fpMemFile,config,programBody):
Line 748... Line 804...
    for jx in range(len(thisPort)):
    for jx in range(len(thisPort)):
      signal = thisPort[jx];
      signal = thisPort[jx];
      signalName = signal[0];
      signalName = signal[0];
      signalWidth = signal[1];
      signalWidth = signal[1];
      signalType = signal[2];
      signalType = signal[2];
      signalInit = '%d\'d0' % signalWidth if len(signal)==3 else signal[3];
      signalInit = 0 if len(signal)==3 else signal[3];
 
      signalInit = InitSignal(signalWidth,signalInit)
      if signalType == 'data':
      if signalType == 'data':
        fp.write('initial %s = %s;\n' % (signalName,signalInit,));
        fp.write('initial %s = %s;\n' % (signalName,signalInit,));
        if bitWidth > 0:
        if bitWidth > 0:
          bitName += ', ';
          bitName += ', ';
          bitInit += ', '
          bitInit += ', '
Line 805... Line 862...
      maxLength = len(signalName);
      maxLength = len(signalName);
  maxLength = maxLength + 12;
  maxLength = maxLength + 12;
  for thisSignal in config.signals:
  for thisSignal in config.signals:
    signalName = thisSignal[0];
    signalName = thisSignal[0];
    signalWidth = thisSignal[1];
    signalWidth = thisSignal[1];
    signalInit = "%d'd0" % signalWidth if len(thisSignal) < 3 else thisSignal[2];
    signalInit = 0 if len(thisSignal)==2 else thisSignal[2];
    outString = 'reg ';
    outString = 'reg ';
    if signalWidth == 1:
    if signalWidth == 1:
      outString += '       ';
      outString += '       ';
    elif signalWidth <= 10:
    elif signalWidth <= 10:
      outString += (' [%d:0] ' % (signalWidth-1));
      outString += (' [%d:0] ' % (signalWidth-1));
    else:
    else:
      outString += ('[%2d:0] ' % (signalWidth-1));
      outString += ('[%2d:0] ' % (signalWidth-1));
    outString += signalName;
    outString += signalName;
    if signalInit != None:
    if signalInit != None:
      outString += ' '*(maxLength-len(outString));
      outString += ' '*(maxLength-len(outString));
      outString += ' = ' + signalInit;
      outString += ' = ' + InitSignal(signalWidth,signalInit);
    outString += ';\n'
    outString += ';\n'
    fp.write(outString);
    fp.write(outString);
 
 
 
def genSPCnext(fp,config):
 
  """
 
  Write the logic to generate the next PC address.\n
 
  Note:  This signal depends on whether or not interrupts are enabled.
 
  """
 
  pcWidth = CeilLog2(config.Get('nInstructions')['length']);
 
  fp.write("reg [C_PC_WIDTH-1:0] s_PC_next;\n");
 
  fp.write("always @ (*)\n");
 
  if config.InterruptVector():
 
    format_pc_addr = "%d\'h%%0%dx" % (pcWidth,(pcWidth+3)/4,);
 
    fp.write("  if (s_interrupt)\n");
 
    fp.write("    s_PC_next = %s;\n" % (format_pc_addr % config.InterruptVector()));
 
    fp.write("  else");
 
  fp.write("  case (s_bus_pc)\n");
 
  fp.write("    C_BUS_PC_NORMAL:\n");
 
  fp.write("      s_PC_next = s_PC_plus1;\n");
 
  fp.write("    C_BUS_PC_JUMP:\n");
 
  fp.write("      s_PC_next = s_PC_jump;\n");
 
  fp.write("    C_BUS_PC_RETURN:\n");
 
  fp.write("      s_PC_next = s_R[0+:C_PC_WIDTH];\n");
 
  fp.write("    default:\n");
 
  fp.write("      s_PC_next = s_PC_plus1;\n");
 
  fp.write("  endcase\n");
 
 
 
def genSRpre(fp,config):
 
  """
 
  Write the logic to select the value to be put onto the return stack.\n
 
  Note:  This also captures the pc value to be put onto the return stack as
 
         part of interrupt handling.
 
  """
 
  data_width = config.Get('data_width');
 
  pcWidth = CeilLog2(config.Get('nInstructions')['length']);
 
  if pcWidth <= data_width:
 
    assignT = "s_T";
 
  else:
 
    assignT = "{ {(C_PC_WIDTH-%d){1'b0}}, s_T }" % data_width;
 
  if pcWidth < data_width:
 
    assignPC = "{ {(%d-C_PC_WIDTH){1'b0}}, %%s }" % data_width;
 
  else:
 
    assignPC = "%s";
 
  if config.InterruptVector():
 
    fp.write("reg [C_RETURN_WIDTH-1:0] s_PC_s  = {(C_RETURN_WIDTH){1'b0}};\n");
 
    fp.write("always @ (posedge i_clk)\n");
 
    fp.write("  if (i_rst)\n");
 
    fp.write("    s_PC_s  <= {(C_RETURN_WIDTH){1'b0}};\n");
 
    fp.write("  else\n");
 
    fp.write("    s_PC_s  <= s_PC;\n");
 
    fp.write("\n");
 
  fp.write("reg [C_RETURN_WIDTH-1:0] s_R_pre;\n");
 
  fp.write("always @ (*)\n");
 
  if config.InterruptVector():
 
    fp.write("  if (s_interrupt)\n");
 
    fp.write("    s_R_pre = %s;\n" % (assignPC % "s_PC_s"));
 
    fp.write("  else");
 
  fp.write("  case (s_bus_r)\n");
 
  fp.write("    C_BUS_R_T:\n");
 
  fp.write("      s_R_pre = %s;\n" % assignT);
 
  fp.write("    C_BUS_R_PC:\n");
 
  fp.write("      s_R_pre = %s;\n" % (assignPC % "s_PC_plus1"));
 
  fp.write("    default:\n");
 
  fp.write("      s_R_pre = %s;\n" % assignT);
 
  fp.write("  endcase\n");
 
 
def genUserHeader(fp,user_header):
def genUserHeader(fp,user_header):
  """
  """
  Copy the user header to the output module.
  Copy the user header to the output module.
  """
  """
  for ix in range(len(user_header)):
  for ix in range(len(user_header)):

powered by: WebSVN 2.1.0

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