Home   Documentation: Introduction Python Perl PCI_Model Demo Future   Other: Download Contact_Info


Perl Demo


Sorry, but these have not been updated, and currently only show the most basic functionality.
The Python demos have been updated, and the same functionality is also available with perl.
 

These are real working demos which you will find in the installation 'demo' directory.

Driver Application - Showing a basic bus controller.

Slave Application - Showing a typical memory.

Monitor Application - Displays simulation activity in a Tk window.

Demo.v - Verilog code using all 3 applications.

Resulting Display using this verilog and these 3 scripts.
 
 

Driver Application

# Here is a simple application which generates read and write commands
# on a simple bus. The verilog nets consist of a clock signal
# called 'clk', a 2-bit control bus called 'control' which indicates
# read and write operations, an address bus, and a data bus.

# Here it is assumed that the verilog code generates the clock and
# also has a memory. As a demo, a separate perl program implements the memory.

# You need to add the following line to your verilog code,
# specifying the name of the perl program to run and the names
# of the verilog nets.

$scriptsim("master.pl", clk, control, address, data_in, data_out);

# Now lets create a perl program which drives the control, address,
# and (for writes) data. You must use the ScriptSim module which
# provides all the interfaces to the simulator and display:

use ScriptSim;

# The $sim object will be used later to control the simulation

$sim = new ScriptSim::Sim;

# Now lets make some magic variables which directly link to the verilog nets.
# The number at the end of the 'tie' commands is the verilog $scriptsim
# argument number, with the first argument being argument 0.

tie $clk, ScriptSim::Arg, $sim, 1;
tie $control, ScriptSim::Arg, $sim, 2;
tie $address, ScriptSim::Arg, $sim, 3;
tie $data_in, ScriptSim::Arg, $sim, 4;
tie $data_out, ScriptSim::Arg, $sim, 5;

# Lets tell the simulator to do everything on the rising edge of the clock:

$sim->event(tied $clk, 'rising');

# Lets randomly create read, write, and idle operations on the bus.
# Lets make the address and write data random as well.

srand 0;  # lets not be too unpredictable

# lets make some defines for the idle, read, write, and read_data bus cycles

($OP_IDLE, $OP_WRITE, $OP_READ, $OP_DATA) = (0 .. 3);

# initialize the nets:

$control = $OP_IDLE;  # start with idle on the control bus
$address = 0;
$data_out = 'z';  # sets ALL data bits to 'z'

$op = $OP_IDLE;

while (1) {
  $sim->wait(); # wait for the next rising clock edge

  # if we were doing a read, the next bus cycle is always 'read_data'
  if ($op == $OP_READ) {
    $op = $OP_DATA;
  }
  # otherwise select some operation at random
  # which will be 'idle', 'write', or 'read'
  else { $op = int(rand 3); }

  $control = $op;  # drive the control bus

  # for writes, lets send some random data
  if ($op == $OP_WRITE) {
    $data_out = rand 0x10000;
  } else {
    $data_out = 'z'; # otherwise tri-state the data bus
  }

  # select an address for reads or writes at random
  if (($op == $OP_WRITE) || ($op == $OP_READ)) {
    $address = rand 16;
  }
}
 

Slave Application

Here is a basic memory application from the 'demo' directory:

You need to add the following line to your verilog code, specifying the name of the perl program to run and the names of the verilog nets.

$scriptsim("slave.pl", clk, control, address, data_in, data_out);
 

#
#   This is the memory model
#
# It implements a memory such that:
#   for writes, the write data is saved in memory
#     and later returned for a read
#   reading an uninitialized location returns 'x'
#

use ScriptSim;

# The $sim object will be used later to control the simulation

$sim = new ScriptSim::Sim;

# give names to the $scriptsim() arguments

tie $clk, ScriptSim::Arg, $sim, 1;
tie $control, ScriptSim::Arg, $sim, 2;
tie $address, ScriptSim::Arg, $sim, 3;
tie $data_in, ScriptSim::Arg, $sim, 4;
tie $data_out, ScriptSim::Arg, $sim, 5;

# $time holds the current simulation time

tie $time, ScriptSim::Time, $sim;

# Lets tell the simulator to do everything on the rising edge of the clock:

$sim->event(tied $clk, 'rising');

# lets make some defines for the idle, read, write, and read_data bus cycles

($OP_IDLE, $OP_WRITE, $OP_READ, $OP_DATA) = (0 .. 3);

#
#  initialize all outputs
#

$data_out = 'z';  # sets ALL data bits to 'z'

#
#  A hash will be used as a memory
#
#  This memory is infinite size and supports any
#  address or data width (even vector sizes > 64 bits)
#

while (1) {
  $sim->wait();

  # lets wait until resetting is done
  if ($time < 10) { next }

  # nothing to do for idle and DATA cycles
  # except tri-state data
  if ($control == $OP_IDLE or $control == $OP_DATA) {
    $data_out = 'z';
  } elsif ($control == $OP_READ) {
    # read from the memory
    # but if that location is uninitialized, return '0'
    $data_out = $mem{$address};
  } else {  # OP_WRITE
    # simply save the write data in memory
    # so it can be retrieved later on a read
    $mem{$address} = $data_in;
  }
}

#
# BUT WHAT ABOUT THOSE NAGGING 'X' VALUES?
#
# In the example above, 'x' is treated as '0', which is a very 'perl'
# thing to do. But checking for 'x' values is very easy. First set up
# some 'magic' variables which have the value '1' if the net has
# 'x' or 'z' bits, otherwise the magic variables are '0'.

tie $control_x, ScriptSim::Arg, $sim, 2, "x";
tie $address_x, ScriptSim::Arg, $sim, 3, "x";
tie $data_x, ScriptSim::Arg, $sim, 4, "x";

# And then test these variables inside the preceding loop and print appropriate messages, such as:

if ($control_x) {
    print "At time $time, the control bus has 'x' bits\n";
} elsif ($address_x) {
   print "At time $time, the address bus has 'x' bits\n";} elsif ($data_x) {
} elsif ($data_x) {
   print "At time $time, the data bus has 'x' bits\n";
}
 
 

Monitor Application

#
#   This is a simple monitor program which monitors the simulation and
#   outputs to the console
#

use ScriptSim;

# The $sim object will be used later to control the simulation

$sim = new ScriptSim::Sim;

# give names to the $scriptsim() arguments
# some have 2 aliases. Normally getting the value on the bus
# returns a decimal number, but if
# 'x' is specified, a '1' is returned if unknown bits are present,
# otherwise 0 is returned.
# and format 'h0' says return a hex number with leading zeros

tie $clk, ScriptSim::Arg, $sim, 1;

tie $control, ScriptSim::Arg, $sim, 2;
tie $control_x, ScriptSim::Arg, $sim, 2, 'x'; # TRUE if control bus has 'x'
tie $address, ScriptSim::Arg, $sim, 3, '%0x'; # hex with leading zeros
tie $data, ScriptSim::Arg, $sim, 4, '%0x';    # hex with leading zeros

# $time holds the current simulation time

tie $time, ScriptSim::Time, $sim;

# Lets tell the simulator to do everything on the rising edge of the clock:

$sim->event(tied $clk, 'rising');

# lets make some defines for the idle, read, write, and read_data bus cycles

($OP_IDLE, $OP_WRITE, $OP_READ, $OP_DATA) = (0 .. 3);

#
#  infinite loop handling operations
#
while (1) {
  $sim->wait();
  if ($time < 10) { next } # ignore everything at start of simulation

  if ($control_x) {
    printf ("%8s Command is 'x'\n",  $time);
  } elsif ($control == $OP_WRITE) {
    printf ("%8s Write adr=%s data=%s\n", $time, $address, $data);
  } elsif ($control == $OP_DATA) {
    printf ("%8s Read  adr=%s data=%s\n", $time, $address, $data);
  }
}
 

Demo.v - Verilog Demo of these 3 perl modules

// basic demo which generates a clock
// and uses 3 ScriptSim programs to
// control the bus, act as memory, and monitor the bus

module Demo;
   wire clock;
   wire [1:0]  #1 op;
   wire [15:0] #1 adr;
   wire [31:0] #1 data;

   reg clock_reg;
   reg [1:0]  op_reg;
   reg [15:0] adr_reg;
   reg [31:0] data_read;
   reg [31:0] data_write;

   assign clock = clock_reg;
   assign op = op_reg;
   assign adr = adr_reg;
   assign data = data_write;
   assign data = data_read;

   initial begin: main_block
      clock_reg = 1;
      $scriptsim("monitor.pl", clock, op, adr, data);
      $scriptsim("master.pl",  clock, op_reg, adr_reg, data_write);
      $scriptsim("slave.pl",   clock, op, adr, data, data_read);
   end // block: main_block

   // generate a clock with 10ns period
   always begin: clock_gen
      #5 clock_reg = 1;
      #5 clock_reg = 0;
   end // block: clock_gen

endmodule // Demo
 

Resulting Display

Here is a real screen shot of the ScriptSim Tk console when running these 3 demo programs. The commands are generated by master.pl, the memory is implemented by slave.pl, and the prints to the console are generated by monitor.pl.

console screen shot
 

Copyright 2000-2002 NelSim Software Inc. All Rights Reserved.