www.pudn.com > noc.rar > benif.py


#!/usr/bin/env python

import os, sys, string

# generating wrapper around NoC for implementation in BenOne Nallatech board

if len(sys.argv) != 3 :
    print 'Usage: python benif.py  '
    sys.exit(1)

X,Y = map( int, sys.argv[1:3] )
N = X*Y

net = 'NETWORK%dx%d'%(X,Y)
lnet = string.lower(net)

# generated CPP and H files

cf = open( 'benif_%s.cpp'%lnet, 'w' )
hf = open( 'benif_%s.h'%lnet, 'w' )

################################################################################
################################################################################
# header file
################################################################################
################################################################################

#includes
hf.write('''
#include 
#include "netmips.h"
#include "%s.h"
'''%lnet)


################################################################################
# wrapper module

hf.write('\nSC_MODULE(BENIF_NET_WRAPPER)\n{\n')

# wrapper ports to Nallatech communication core
for s in ('IFCLK','WRITE_STROBE','READ_STROBE','DMA_ENABLE','DMA_DIRECTION',
          'DMA_RDY','DMA_DATA_AVAILABLE','RST','SYNC_RESET','DMA_RESET'):
    hf.write('  sc_in< bool > %s;\n'%s)

hf.write('''
  sc_in< sc_uint<31> > ADDRESS;
  sc_inout_rv< 32 > DATA;

  sc_inout_rv< 32 > DMA_DATA;
  sc_in< sc_uint<32> > COUNT;
  sc_in< sc_uint<4> > DMA_SEL;

  sc_out< bool > DMA_WEN;
  sc_out< bool > DMA_REN;
  sc_out< bool > INT;

  sc_out< sc_bv<4> > LEDS;
''')

# wrapper ports to data processor's memories
hf.write('''
  sc_out > memADDR;
  sc_out > memDI;
  sc_out memEN;
  sc_out memCLK;
  sc_out memRST;
''')

hf.write('  sc_in > %s;\n'%string.join( map( lambda i : 'ramDO%d,romDO%d'%(i,i), range(N)),','))
hf.write('  sc_out %s;\n'%string.join( map( lambda i : 'ramWE%d,romWE%d'%(i,i), range(N)),','))
hf.write('  sc_in > %s;\n'%string.join( map( lambda i : 'pc%d'%(i), range(N)),','))
hf.write('  sc_out %s;\n'%string.join( map( lambda i : 'enable%d'%(i), range(N)),','))
hf.write('  sc_out reset;\n')

hf.write('''
#ifdef USEXRAM
  sc_out > xADDR;
  sc_out xCLK;
''')

hf.write('  sc_in > %s;\n'%string.join( map( lambda i : 'xDO%d'%(i), range(N)),','))
hf.write('  sc_out %s;\n'%string.join( map( lambda i : 'xWE%d'%(i), range(N)),','))  
hf.write('#endif\n')

# internal signals and constructor
hf.write('''
  sc_signal< sc_uint<32> > addr;
  sc_signal< sc_uint<32> > memsel;
  sc_signal< sc_uint<25> > cnt;
  
  sc_signal< sc_uint<32> > control;
  
  void logic();
  void count();
  void register_write();
  void register_read();
  void memory_input();
  
  SC_CTOR(BENIF_NET_WRAPPER)
  {
    SC_METHOD(logic);
    sensitive << IFCLK << WRITE_STROBE << READ_STROBE << DMA_ENABLE 
              << DMA_DIRECTION << DMA_RDY << DMA_DATA_AVAILABLE
              << RST << SYNC_RESET << DMA_RESET
              << ADDRESS << DATA
              << DMA_DATA << COUNT << DMA_SEL
              << control << addr << memsel << cnt;

    SC_METHOD(memory_input);
    sensitive << IFCLK << DATA << addr << memsel << ADDRESS << WRITE_STROBE << control;

    SC_METHOD(count);
    sensitive_pos << IFCLK << RST;
    
    SC_METHOD(register_write);
    sensitive_pos << IFCLK << RST;
    
    SC_METHOD(register_read);
    sensitive << READ_STROBE << ADDRESS << addr << memsel;
''')
hf.write('  sensitive << %s;\n'%string.join( map( lambda i : 'pc%d'%(i), range(N)),' << '))
hf.write('  sensitive << %s;\n'%string.join( map( lambda i : 'ramDO%d << romDO%d'%(i,i), range(N)),' << '))

hf.write('#ifdef USEXRAM\n')
hf.write('  sensitive << %s;\n'%string.join( map( lambda i : 'xDO%d'%(i), range(N)),' << '))
hf.write('#endif\n  }\n};\n')


################################################################################
# top-level module

hf.write('''
SC_MODULE(BENIF_NET)
{
''')

# instantiated modules: network
hf.write('  %s *%s;\n'%(net,lnet))
# ... and data processors
for y in range(Y):
    for x in range(X):
        hf.write('  NETmMIPS *dp_x%dy%d;\n'%(x,y))
# ... and the wrapper
hf.write('  BENIF_NET_WRAPPER *wrapper;\n')

# declaration of ports
hf.write('''
  
  sc_in   MIPSCLK;
  
  sc_in< bool > IFCLK;
  sc_in< bool > WRITE_STROBE;
  sc_in< bool > READ_STROBE;
  sc_in< bool > DMA_ENABLE;
  sc_in< bool > DMA_DIRECTION;
  sc_in< bool > DMA_RDY;
  sc_in< bool > DMA_DATA_AVAILABLE;
  sc_in< bool > RST;
  sc_in< bool > SYNC_RESET;
  sc_in< bool > DMA_RESET;

  sc_in< sc_uint<31> > ADDRESS;
  sc_inout_rv< 32 > DATA;
  sc_inout_rv< 32 > DMA_DATA;
  sc_in< sc_uint<32> > COUNT;
  sc_in< sc_uint<4> > DMA_SEL;

  sc_out< bool > DMA_WEN;
  sc_out< bool > DMA_REN;
  sc_out< bool > INT;
  sc_out< sc_bv<4> > LEDS;

  sc_signal > memADDR;
  sc_signal > memDI;
  sc_signal memEN;
  sc_signal memCLK;
  sc_signal memRST;

''')

# signals between DP memories and wrapper
hf.write('  sc_signal > %s;\n'%string.join( map( lambda i : 'ramDO%d,romDO%d'%(i,i), range(N)),','))
hf.write('  sc_signal %s;\n'%string.join( map( lambda i : 'ramWE%d,romWE%d'%(i,i), range(N)),','))
hf.write('  sc_signal > %s;\n'%string.join( map( lambda i : 'pc%d'%(i), range(N)),','))
hf.write('  sc_signal %s;\n'%string.join( map( lambda i : 'enable%d'%(i), range(N)),','))
hf.write('  sc_signal reset;\n')

hf.write('''
#ifdef USEXRAM
  sc_signal > xADDR;
  sc_signal xCLK;
''')

hf.write('  sc_signal > %s;\n'%string.join( map( lambda i : 'xDO%d'%(i), range(N)),','))
hf.write('  sc_signal %s;\n'%string.join( map( lambda i : 'xWE%d'%(i), range(N)),','))  
hf.write('#endif\n')

# signals between DP and network
for y in range(Y):
    for x in range(X):
        for s in ( 'din', 'dout') :
            hf.write('  sc_signal< sc_bv > x%dy%d%s;\n'%(x,y,s))
        for s in ( 'req_net', 'ack_net', 'ack_dp', 'req_dp' ) :
            hf.write('  sc_signal x%dy%d%s;\n'%(x,y,s))

# constructor
hf.write('\n  SC_CTOR(BENIF_NET)\n  {\n' )

# module creation
hf.write('    %s = new %s("%s");\n'%(lnet,net,lnet))
for y in range(Y):
    for x in range(X):
        hf.write('    dp_x%dy%d = new NETmMIPS("dp_x%dy%d");\n'%(x,y,x,y))
hf.write('    wrapper = new BENIF_NET_WRAPPER("wrapper");\n\n')

# connect wrapper to signals
hf.write('    wrapper->reset(reset);\n')
for n in range(N) : hf.write('    wrapper->enable%d(enable%d);\n'%(n,n))

# redirect i/o ports to wrapper
for s in ('IFCLK','WRITE_STROBE','READ_STROBE','DMA_ENABLE','DMA_DIRECTION',
          'DMA_RDY','DMA_DATA_AVAILABLE','RST','SYNC_RESET','DMA_RESET',
          'ADDRESS','DATA','DMA_DATA','COUNT','DMA_SEL','DMA_WEN','DMA_REN','INT','LEDS'):
    hf.write('    wrapper->%s(%s);\n'%(s,s))

# connect wrapper to memory signals
hf.write('\n')
for s in ('ADDR','DI','EN','CLK','RST'):
    hf.write('    wrapper->mem%s(mem%s);\n'%(s,s))

for n in range(N):
    for m in ('ram', 'rom'):
        for s in ('DO','WE'):
            hf.write('    wrapper->%s%s%d(%s%s%d);\n'%(m,s,n,m,s,n))

hf.write('\n')
# connect DP to memory signals
for y in range(Y):
    for x in range(X):
        dp = 'dp_x%dy%d'%(x,y)
        n = y*X + x
        
        for s in ('ADDR','DI','EN','CLK','RST'):
            hf.write('    %s->ram%s(mem%s); %s->rom%s(mem%s);\n'%(dp,s,s,dp,s,s))
        
        for m in ('ram', 'rom'):
            for s in ('DO','WE'):
                hf.write('    %s->%s%s(%s%s%d);\n'%(dp,m,s,m,s,n))
        hf.write('\n')

# xram memory connections
hf.write('#ifdef USEXRAM\n')
for s in ('ADDR','CLK'):
    hf.write('    wrapper->x%s(x%s);\n'%(s,s))

for n in range(N):
    for s in ('DO','WE'):
        hf.write('    wrapper->x%s%d(x%s%d);\n'%(s,n,s,n))
        
for y in range(Y):
    for x in range(X):
        dp = 'dp_x%dy%d'%(x,y)
        n = y*X + x
        
        for s in ('ADDR','CLK'):
            hf.write('    %s->x%s(x%s);\n'%(dp,s,s))
        
        for s in ('DO','WE'):
            hf.write('    %s->x%s(x%s%d);\n'%(dp,s,s,n))
        hf.write('\n')
hf.write('#endif\n')

# connect network with DPs

# first - network
hf.write('    %s->clk(MIPSCLK); %s->rst(reset);\n'%(lnet,lnet))
for y in range(Y):
    for x in range(X):
        c = 'x%dy%d'%(x,y)
        for s in ( 'din', 'dout', 'req_net', 'ack_net', 'ack_dp', 'req_dp') :
            hf.write('    %s->%s%s(%s%s);\n'%(lnet,c,s,c,s))
hf.write('\n')

# now - connect DP
for y in range(Y):
    for x in range(X):
        c = 'x%dy%d'%(x,y)
        dp = 'dp_'+c
        n = y*X + x

        hf.write('    %s->clock(MIPSCLK); %s->reset(reset); %s->enable(enable%d);\n'%(dp,dp,dp,n))
        for s,t in ( ('data_out','din'), ('data_in','dout'),
                     ('req_out','req_net'), ('ack_in','ack_net'),
                     ('ack_out','ack_dp'), ('req_in','req_dp') ):
            hf.write('    %s->%s(%s%s);\n'%(dp,s,c,t))
        hf.write('\n')

for y in range(Y):
    for x in range(X):
        c = 'x%dy%d'%(x,y)
        dp = 'dp_'+c
        n = y*X + x

        hf.write('    %s->bus_pc(pc%d); wrapper->pc%d(pc%d);\n'%(dp,n,n,n))

hf.write('  }\n};\n' )


################################################################################
################################################################################
# cpp file
################################################################################
################################################################################

cf.write('#include "benif_%s.h"\n'%lnet)
cf.write('''
void BENIF_NET_WRAPPER::count()
{
  if( RST.read() ) cnt = 0;
  else cnt = cnt.read()+1;
}
void BENIF_NET_WRAPPER::register_write()
{
  sc_uint<8> reg = ADDRESS.read().range(7,0);
  if( RST.read() ) {
    addr = 0; memsel = 0; control = 0;
  }
  else if( WRITE_STROBE.read() )
    {
      switch(reg)
        {
        case 2 : memsel = DATA.read(); break;
        case 3 : addr = DATA.read(); break;
        case 4 : control = DATA.read(); break;
        }
    }

  if( (READ_STROBE.read()||WRITE_STROBE.read()) && reg==5 ) addr = addr.read()+4;
}

void BENIF_NET_WRAPPER::register_read()
{
  sc_uint<8> reg = ADDRESS.read().range(7,0);
  sc_int<32> memout;
  sc_lv<32> dout;
  sc_lv<32> z32;
  sc_uint<32> mem = memsel.read();
  for(int i=0;i<32;i++) z32[i]=\'z\'; 

  switch( mem ){
''')

for n in range(N):
    cf.write('  case 0x%08x : memout = romDO%d.read(); break;\n'%(0x1<<(2*n),n))
    cf.write('  case 0x%08x : memout = ramDO%d.read(); break;\n'%(0x1<<(2*n+1),n))

cf.write('#ifdef USEXRAM\n')
for n in range(N):
    cf.write('  case 0x%08x : memout = xDO%d.read(); break;\n'%(0x1<<(2*N+n),n))
cf.write('#endif\n')

cf.write('''
  default : memout = 0;
  }
  
  switch(reg)
    {
    case 2 : dout = memsel.read(); break;
    case 3 : dout = addr.read(); break;
    case 4 : dout = control.read(); break;
    case 5 : dout = memout; break;
''')
for n in range(N):
    cf.write('    case %d : dout = pc%d.read(); break;\n'%(6+n,n))
         
cf.write('''
    default : dout = memout; break;
    }
    
  if( READ_STROBE.read() )
    DATA.write( dout );
  else {
    DATA.write( z32 );
  }
  
  DMA_DATA.write( z32 );
}

void BENIF_NET_WRAPPER::logic()
{
  sc_bv<4> leds;
  
  reset.write(RST.read());
''')

for n in range(N):
    cf.write('  enable%d.write(control.read()[%d] != 0);\n'%(n,n))

cf.write('''  
  leds[3] = !(control.read()[0] != 0);
  leds[2] = !(cnt.read()[24] != 0);
  leds[1] = 1;
  leds[0] = 1;
  
  LEDS.write(leds);
  
  INT.write(false);
  DMA_REN.write(false);
  DMA_WEN.write(false);
}


void BENIF_NET_WRAPPER::memory_input()
{
  sc_uint<8> reg = ADDRESS.read().range(7,0);
  bool en = (reg==5);
  bool we = (en&&WRITE_STROBE.read());

  
#ifndef VERILOG
  memDI.write( we ? DATA.read() : 0 );
#else
  memDI.write( DATA.read() );
#endif
''')

for n in range(N):
    cf.write('  romWE%d.write(we && memsel.read()[%d]); ramWE%d.write(we && memsel.read()[%d]);\n'%(n,2*n,n,2*n+1))

cf.write('''
  memADDR.write( addr.read() );
  memCLK.write( IFCLK.read() );
  memEN.write(en);
  memRST.write(false);

#ifdef USEXRAM
  xADDR.write( addr.read() );
  xCLK.write( IFCLK.read() );
''')

for n in range(N):
  cf.write('  xWE%d.write( control.read()[31]!=0 );\n'%(n));  
cf.write('#endif\n}\n')

hf.close()
cf.close()