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

Subversion Repositories ssbcc

[/] [ssbcc/] [trunk/] [core/] [9x8/] [peripherals/] [latch.py] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 sinclairrf
################################################################################
2
#
3
# Copyright 2012-2013, Sinclair R.F., Inc.
4
#
5
################################################################################
6
 
7
import math;
8
import re;
9
 
10
from ssbccPeripheral import SSBCCperipheral
11
from ssbccUtil import SSBCCException;
12
 
13
class latch(SSBCCperipheral):
14
  """
15
  Latch a large input port for piecewise input to the processor core.\n
16
  This peripheral is used to input large counters and such so that the pieces of
17
  the counter input to the processor are all valid at the same time.\n
18
  The external signal is registered when the processor does an outport to
19
  O_name_LATCH and is broken into 8-bit chunks that can be read by the
20
  processor.  These chunks are number from 0 at the far right to ceil(n/8)-1 on
21
  the far left.  The chunk is specified by an outport to O_name_ADDR and is then
22
  read by an inport from I_name_READ.\n
23
  Usage:
24
    PERIPHERAL latch outport_latch=O_LATCH \\
25
                     outport_addr=O_ADDR \\
26
                     inport=I_READ \\
27
                     insignal=i_name \\
28
                     width=n\n
29
  Where:
30
    outport_latch=O_LATCH
31
      is the symbol used by the processor to register the input signal
32
      Note:  The name must start with "O_".
33
    outport_addr=O_ADDR
34
      is the symbol used by the processor to indicate which byte of the
35
      registered input signal is to input by the next inport from I_name_READ
36
      Note:  The name must start with "O_".
37
    inport=I_READ
38
      is the symbol used by the processor to read the byte specified by the last
39
      outport to O_name_ADDR
40
      Note:  The name must start with "I_".
41
    insignal=i_name
42
      specifies the name of the input signal
43
      Note:  The name must start with "i_".
44
    width=n
45
      specified with width of the input signal
46
      Note:  The signal is broken into ceil(n/8) 8-bit words
47
      Note:  This peripheral doesn't make sense when width < 8.  It will issue
48
             an error when this condition is encountered.\n
49
  The following outports are provided by this peripheral:
50
    O_LATCH
51
      this outport instructs the peripheral to latch the specified signal
52
      Note:  No argument is required for this outport.  I.e., it is equivalent
53
             to a "strobe" outport.
54
    O_ADDR
55
      this outport specifies which 8-bit chunk of the latched signal will be read
56
      by I_READ\n
57
  The following inport is provided by this peripheral:
58
    I_READ
59
      this inport is used to read the 8-bit segment of the latched signal as
60
      specified by O_ADDR\n
61
  The following processor inputs are provided by this peripheral:
62
    i_name
63
      this is a "width" wide signal connected to the FPGA fabric\n
64
  Example:  Capture an external 24-bit counter:\n
65
    Within the processor architecture file include the configuration command:\n
66
      PERIPHERAL latch outport_latch=O_COUNT_LATCH \\
67
                       outport_addr=O_COUNT_ADDR \\
68
                       inport=I_COUNT_READ \\
69
                       insignal=i_count \\
70
                       width=24\n
71
    To read the counter and put it on the stack with the MSB at the top of the
72
    stack:\n
73
      O_COUNT_LATCH outport       ; doesn't need a value to output
74
 
75
      1 .outport(O_COUNT_ADDR) .inport(I_COUNT_READ)
76
      2 .outport(O_COUNT_ADDR) .inport(I_COUNT_READ)\n
77
    or\n
78
      O_COUNT_LATCH outport
79
 
80
  """
81
 
82
  def __init__(self,peripheralFile,config,param_list,loc):
83
    # Use the externally provided file name for the peripheral
84
    self.peripheralFile = peripheralFile;
85
    # Parse the parameters.
86
    for param_tuple in param_list:
87
      param = param_tuple[0];
88
      param_arg = param_tuple[1];
89
      if param == 'outport_latch':
90
        self.AddAttr(config,param,param_arg,r'O_\w+$',loc);
91
      elif param == 'outport_addr':
92
        self.AddAttr(config,param,param_arg,r'O_\w+$',loc);
93
      elif param == 'inport':
94
        self.AddAttr(config,param,param_arg,r'I_\w+$',loc);
95
      elif param == 'insignal':
96
        self.AddAttr(config,param,param_arg,r'i_\w+$',loc);
97
      elif param == 'width':
98
        self.AddAttr(config,param,param_arg,r'[1-9]\d*$',loc,int);
99
      else:
100
        raise SSBCCException('Unrecognized parameter at %s: %s' % (loc,param,));
101
    # Ensure the required parameters are set.
102
    for param in ('outport_latch', 'outport_addr', 'inport', 'insignal', 'width', ):
103
      if not hasattr(self,param):
104
        raise SSBCCException('Required parameter "%s" not provided at %s', (param,loc,));
105
    # Ensure parameters are reasonable.
106
    if self.width <= 8:
107
      raise SSBCCException('The "latch" peripheral doesn\'t make sense when width <= 8 on %s' % loc);
108
    # Derived parameters
109
    self.latch_width = 8*((self.width+7)/8);
110
    self.addr_width = int(math.ceil(math.log(self.latch_width/8,2)));
111
    # Configure the processor I/Os, etc.
112
    config.AddIO(self.insignal,self.width,'input',loc);
113
    config.AddSignal('s__%s__select' % self.insignal,8,loc);
114
    config.AddInport((self.inport,
115
                     ('s__%s__select' % self.insignal,8,'data',),
116
                    ),loc);
117
    self.ix__o_latch = config.NOutports();
118
    config.AddOutport((self.outport_latch,True,),loc);
119
    self.ix__o_addr = config.NOutports();
120
    config.AddOutport((self.outport_addr,False,),loc);
121
 
122
  def GenVerilog(self,fp,config):
123
    body = self.LoadCore(self.peripheralFile,'.v');
124
    for subs in (
125
                  (r'\bix\b',           'ix__@INSIGNAL@',),
126
                  (r'\bs__',            's__@INSIGNAL@__',),
127
                  ('@ADDR_WIDTH@',      str(self.addr_width),),
128
                  ('@IX_O_ADDR@',       str(self.ix__o_addr),),
129
                  ('@IX_O_LATCH@',      str(self.ix__o_latch),),
130
                  ('@LATCH_WIDTH@',     str(self.latch_width),),
131
                  ('@INSIGNAL@',        self.insignal,),
132
                  ('@WIDTH@',           str(self.width),),
133
                ):
134
      body = re.sub(subs[0],subs[1],body);
135
    fp.write(body);

powered by: WebSVN 2.1.0

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