#!/bin/csh -f

alias BEGIN 'cat <<END'


# figure out where on the pbus data lines to put the cam chips
@ p_lsb = 0
foreach arg ($*)
  if ($arg =~ "lsb4") then
    @ p_lsb = 4
  else if ($arg =~ "lsb8") then
    @ p_lsb = 8
  else if ($arg =~ "lsb12") then
    @ p_lsb = 12
  endif
end


# determine whether to use full chip model
set ucam = "u1"
foreach arg ($*)
  if ( $arg =~ fullcam ) then
    set ucam = "u1"
    break
  endif
end


# check for interface vector generation
#   for vectors, change pbus pullups to pulldowns and
#   make the delay be 10 nsec (normally 10,000)
set pbus_pull = "pulldown_slow"
set pull_delay = "10000"
@ ivectors = 0
foreach arg ($*)
  if ($arg =~ "+ivectors") then
    set pbus_pull = "pullup_slow"
    set pull_delay = "10"
    @ ivectors = 1
    break
  endif
end


BEGIN
/* Model of SBus and Interface Board */


\`timescale 1 ns / 10 ps


module system ;

	parameter cycle = 1000,
		boxes = $3,		// no. of boxes in system
		mpb = $2,		// no. of modules per box
		cpm = $1,		// no. of chips per module
		p_lsb = $p_lsb;		// lowest order pbus bit for
					//   group of cam chips

        parameter
                BUFFER_TYPE = "CD74AC245";
 
	defparam
		U8.boxes = boxes,
		U8.mpb = mpb,
		U8.cpm = cpm;

	// signals the end of the simulation
	integer
		last_vector;

	// Sbus signals
	reg	sb_clk;			// Clock from System
	tri     sb_as_;			// Address Strobe from System
	tri     [27:0] sb_pa;		// Phys. Adress bus from System
	tri     [31:0] sb_d;		// Data Bus from System/Master/Slave
	tri     [2:0] sb_siz;		// Transfer Size from System/Master
	tri     sb_rd;			// Read from System/Master
	tri     [2:0] sb_ack_;		// Acknowledge bits
	tri     sb_merr_;		// LateError_ in new spec
	tri     [7:0] sb_br_;		// Bus Request from Master
	tri     [7:0] sb_bg_;		// Bus Grant from System
	tri     [7:0] sb_sel_;		// Select from System
	tri     [7:1] sb_irq_;		// Interrupt Requests from Master/Slave
	reg     sb_reset_;		// Reset from System
	tri     sb_ext;			// parity bit: see Assignments below...
	reg     parity;			// 1=auto-parity generation; 0=sb_ext never driven
END


# hierarchical names used in lower modules
set u1_name = "system.U1.U1.U1"
set u2_name = "system.U1.U2.U1"
set u3_name = "system.U1.U3.U1"
set u4_name = "system.U1.U4.U1"
set u5_name = "system.U1.U5.U1"

foreach arg ($*)
  if ($arg =~ fullctlsva) then
    set u1_name = "system.U1.U1.u10"
  else if ($arg =~ fullctlsvb) then
    set u2_name = "system.U1.U2.u10"
  else if ($arg =~ fullfsm) then
    set u3_name = "system.U1.U3.u9"
  else if ($arg =~ fulldataa) then
    set u4_name = "system.U1.U4.u8"
  else if ($arg =~ fulldatab) then
    set u5_name = "system.U1.U5.u8"
  endif  
end
 

BEGIN

	// aliases for control register 0 bits
	wire
		cam_rd = $u1_name.u2.u1.u112\$2.q ,
		immd = $u1_name.u2.u1.u112\$3.q ,
		flg8 = $u1_name.u2.u1.u112\$4.q ,
		hj = $u2_name.u2.u1.u112\$1.q ,
		hw = $u2_name.u2.u1.u112\$2.q ,
		soft_int = $u2_name.u2.u1.u112\$3.q ,
		wait_eos = $u2_name.u2.u1.u112\$4.q ;

	wire [3:0]
		sctlfsm_q =
			{  
			$u3_name.u4.u1.sr4.q,
			$u3_name.u4.u1.sr3.q,
			$u3_name.u4.u1.sr2.q,
			$u3_name.u4.u1.sr1.q
			};

	wire [4:0]
		opcode =
			{
			$u2_name.u2.u1.u96\$1.q ,
			$u2_name.u2.u1.u96\$2.q ,
			$u2_name.u2.u1.u96\$3.q ,
			$u2_name.u2.u1.u96\$4.q ,
			$u2_name.u2.u1.u96\$5.q
			} ;

	wire [2:0]
		pctlfsm_q =
			{  
			$u3_name.u1.u4.u2.sr3.q,
			$u3_name.u1.u4.u2.sr2.q,
			$u3_name.u1.u4.u2.sr1.q
			};

	wire [31:0]
		xfer_addr =
			{
			$u1_name.u1.u124.u72.u8\$1.q ,
			$u1_name.u1.u124.u72.u8\$2.q ,
			$u1_name.u1.u124.u72.u8\$3.q ,
			$u1_name.u1.u124.u72.u8\$4.q ,
			$u1_name.u1.u124.u72.u8\$5.q ,
			$u1_name.u1.u124.u72.u8\$6.q ,
			$u1_name.u1.u124.u72.u8\$7.q ,
			$u1_name.u1.u124.u72.u8\$8.q ,
			$u1_name.u1.u124.u72.u8\$9.q ,
			$u1_name.u1.u124.u72.u8\$10.q ,
			$u1_name.u1.u124.u72.u8\$11.q ,
			$u1_name.u1.u124.u72.u8\$12.q ,
			$u1_name.u1.u124.u72.u8\$13.q ,
			$u1_name.u1.u124.u72.u8\$14.q ,
			$u1_name.u1.u124.u72.u8\$15.q ,
			$u1_name.u1.u124.u72.u8\$16.q ,
			$u2_name.u1.u124.u72.u8\$1.q ,
			$u2_name.u1.u124.u72.u8\$2.q ,
			$u2_name.u1.u124.u72.u8\$3.q ,
			$u2_name.u1.u124.u72.u8\$4.q ,
			$u2_name.u1.u124.u72.u8\$5.q ,
			$u2_name.u1.u124.u72.u8\$6.q ,
			$u2_name.u1.u124.u72.u8\$7.q ,
			$u2_name.u1.u124.u72.u8\$8.q ,
			$u2_name.u1.u124.u72.u8\$9.q ,
			$u2_name.u1.u124.u72.u8\$10.q ,
			$u2_name.u1.u124.u72.u8\$11.q ,
			$u2_name.u1.u124.u72.u8\$12.q ,
			$u2_name.u1.u124.u72.u8\$13.q ,
			$u2_name.u1.u124.u72.u8\$14.q ,
			$u2_name.u1.u124.u72.u8\$15.q ,
			$u2_name.u1.u124.u72.u8\$16.q
			} ;

	wire [31:0]
		xfer_length =
			{
			$u1_name.u2.u1.u97\$1.q ,
			$u1_name.u2.u1.u97\$2.q ,
			$u1_name.u2.u1.u97\$3.q ,
			$u1_name.u2.u1.u97\$4.q ,
			$u1_name.u2.u1.u97\$5.q ,
			$u1_name.u2.u1.u97\$6.q ,
			$u1_name.u2.u1.u97\$7.q ,
			$u1_name.u2.u1.u97\$8.q ,
			$u1_name.u2.u1.u97\$9.q ,
			$u1_name.u2.u1.u97\$10.q ,
			$u1_name.u2.u1.u97\$11.q ,
			$u1_name.u2.u1.u97\$12.q ,
			$u1_name.u2.u1.u97\$13.q ,
			$u1_name.u2.u1.u97\$14.q ,
			$u1_name.u2.u1.u97\$15.q ,
			$u1_name.u2.u1.u97\$16.q ,
			$u2_name.u2.u1.u97\$1.q ,
			$u2_name.u2.u1.u97\$2.q ,
			$u2_name.u2.u1.u97\$3.q ,
			$u2_name.u2.u1.u97\$4.q ,
			$u2_name.u2.u1.u97\$5.q ,
			$u2_name.u2.u1.u97\$6.q ,
			$u2_name.u2.u1.u97\$7.q ,
			$u2_name.u2.u1.u97\$8.q ,
			$u2_name.u2.u1.u97\$9.q ,
			$u2_name.u2.u1.u97\$10.q ,
			$u2_name.u2.u1.u97\$11.q ,
			$u2_name.u2.u1.u97\$12.q ,
			$u2_name.u2.u1.u97\$13.q ,
			$u2_name.u2.u1.u97\$14.q ,
			$u2_name.u2.u1.u97\$15.q ,
			$u2_name.u2.u1.u97\$16.q
			} ;

	wire [31:0]
		// host next pointer
		r0 =
			{
			$u1_name.u1.u124.u71.u8\$1.q,
			$u1_name.u1.u124.u71.u8\$2.q,
			$u1_name.u1.u124.u71.u8\$3.q,
			$u1_name.u1.u124.u71.u8\$4.q,
			$u1_name.u1.u124.u71.u8\$5.q,
			$u1_name.u1.u124.u71.u8\$6.q,
			$u1_name.u1.u124.u71.u8\$7.q,
			$u1_name.u1.u124.u71.u8\$8.q,
			$u1_name.u1.u124.u71.u8\$9.q,
			$u1_name.u1.u124.u71.u8\$10.q,
			$u1_name.u1.u124.u71.u8\$11.q,
			$u1_name.u1.u124.u71.u8\$12.q,
			$u1_name.u1.u124.u71.u8\$13.q,
			$u1_name.u1.u124.u71.u8\$14.q,
			$u1_name.u1.u124.u71.u8\$15.q,
			$u1_name.u1.u124.u71.u8\$16.q,
			$u2_name.u1.u124.u71.u8\$1.q,
			$u2_name.u1.u124.u71.u8\$2.q,
			$u2_name.u1.u124.u71.u8\$3.q,
			$u2_name.u1.u124.u71.u8\$4.q,
			$u2_name.u1.u124.u71.u8\$5.q,
			$u2_name.u1.u124.u71.u8\$6.q,
			$u2_name.u1.u124.u71.u8\$7.q,
			$u2_name.u1.u124.u71.u8\$8.q,
			$u2_name.u1.u124.u71.u8\$9.q,
			$u2_name.u1.u124.u71.u8\$10.q,
			$u2_name.u1.u124.u71.u8\$11.q,
			$u2_name.u1.u124.u71.u8\$12.q,
			$u2_name.u1.u124.u71.u8\$13.q,
			$u2_name.u1.u124.u71.u8\$14.q,
			$u2_name.u1.u124.u71.u8\$15.q,
			$u2_name.u1.u124.u71.u8\$16.q
			},

		// "interrupt" register
		r1 =
			{
			$u1_name.u1.u124.\intreg[15] ,
			$u1_name.u1.u124.\intreg[14] ,
			$u1_name.u1.u124.\intreg[13] ,
			$u1_name.u1.u124.\intreg[12] ,
			$u1_name.u1.u124.\intreg[11] ,
			$u1_name.u1.u124.\intreg[10] ,
			$u1_name.u1.u124.\intreg[9] ,
			$u1_name.u1.u124.\intreg[8] ,
			$u1_name.u1.u124.\intreg[7] ,
			$u1_name.u1.u124.\intreg[6] ,
			$u1_name.u1.u124.\intreg[5] ,
			$u1_name.u1.u124.\intreg[4] ,
			$u1_name.u1.u124.\intreg[3] ,
			$u1_name.u1.u124.\intreg[2] ,
			$u1_name.u1.u124.\intreg[1] ,
			$u1_name.u1.u124.\intreg[0] ,
			$u2_name.u1.u124.\intreg[15] ,
			$u2_name.u1.u124.\intreg[14] ,
			$u2_name.u1.u124.\intreg[13] ,
			$u2_name.u1.u124.\intreg[12] ,
			$u2_name.u1.u124.\intreg[11] ,
			$u2_name.u1.u124.\intreg[10] ,
			$u2_name.u1.u124.\intreg[9] ,
			$u2_name.u1.u124.\intreg[8] ,
			$u2_name.u1.u124.\intreg[7] ,
			$u2_name.u1.u124.\intreg[6] ,
			$u2_name.u1.u124.\intreg[5] ,
			$u2_name.u1.u124.\intreg[4] ,
			$u2_name.u1.u124.\intreg[3] ,
			$u2_name.u1.u124.\intreg[2] ,
			$u2_name.u1.u124.\intreg[1] ,
			$u2_name.u1.u124.\intreg[0] 
			},

		// Step list pointer
		r2 =
			{
			$u1_name.u1.u124.u72.u8\$1.q,
			$u1_name.u1.u124.u72.u8\$2.q,
			$u1_name.u1.u124.u72.u8\$3.q,
			$u1_name.u1.u124.u72.u8\$4.q,
			$u1_name.u1.u124.u72.u8\$5.q,
			$u1_name.u1.u124.u72.u8\$6.q,
			$u1_name.u1.u124.u72.u8\$7.q,
			$u1_name.u1.u124.u72.u8\$8.q,
			$u1_name.u1.u124.u72.u8\$9.q,
			$u1_name.u1.u124.u72.u8\$10.q,
			$u1_name.u1.u124.u72.u8\$11.q,
			$u1_name.u1.u124.u72.u8\$12.q,
			$u1_name.u1.u124.u72.u8\$13.q,
			$u1_name.u1.u124.u72.u8\$14.q,
			$u1_name.u1.u124.u72.u8\$15.q,
			$u1_name.u1.u124.u72.u8\$16.q,
			$u2_name.u1.u124.u72.u8\$1.q,
			$u2_name.u1.u124.u72.u8\$2.q,
			$u2_name.u1.u124.u72.u8\$3.q,
			$u2_name.u1.u124.u72.u8\$4.q,
			$u2_name.u1.u124.u72.u8\$5.q,
			$u2_name.u1.u124.u72.u8\$6.q,
			$u2_name.u1.u124.u72.u8\$7.q,
			$u2_name.u1.u124.u72.u8\$8.q,
			$u2_name.u1.u124.u72.u8\$9.q,
			$u2_name.u1.u124.u72.u8\$10.q,
			$u2_name.u1.u124.u72.u8\$11.q,
			$u2_name.u1.u124.u72.u8\$12.q,
			$u2_name.u1.u124.u72.u8\$13.q,
			$u2_name.u1.u124.u72.u8\$14.q,
			$u2_name.u1.u124.u72.u8\$15.q,
			$u2_name.u1.u124.u72.u8\$16.q
			},

		// Previous step list pointer
		r3 =
			{
			$u1_name.u1.u124.u73.u8\$1.q,
			$u1_name.u1.u124.u73.u8\$2.q,
			$u1_name.u1.u124.u73.u8\$3.q,
			$u1_name.u1.u124.u73.u8\$4.q,
			$u1_name.u1.u124.u73.u8\$5.q,
			$u1_name.u1.u124.u73.u8\$6.q,
			$u1_name.u1.u124.u73.u8\$7.q,
			$u1_name.u1.u124.u73.u8\$8.q,
			$u1_name.u1.u124.u73.u8\$9.q,
			$u1_name.u1.u124.u73.u8\$10.q,
			$u1_name.u1.u124.u73.u8\$11.q,
			$u1_name.u1.u124.u73.u8\$12.q,
			$u1_name.u1.u124.u73.u8\$13.q,
			$u1_name.u1.u124.u73.u8\$14.q,
			$u1_name.u1.u124.u73.u8\$15.q,
			$u1_name.u1.u124.u73.u8\$16.q,
			$u2_name.u1.u124.u73.u8\$1.q,
			$u2_name.u1.u124.u73.u8\$2.q,
			$u2_name.u1.u124.u73.u8\$3.q,
			$u2_name.u1.u124.u73.u8\$4.q,
			$u2_name.u1.u124.u73.u8\$5.q,
			$u2_name.u1.u124.u73.u8\$6.q,
			$u2_name.u1.u124.u73.u8\$7.q,
			$u2_name.u1.u124.u73.u8\$8.q,
			$u2_name.u1.u124.u73.u8\$9.q,
			$u2_name.u1.u124.u73.u8\$10.q,
			$u2_name.u1.u124.u73.u8\$11.q,
			$u2_name.u1.u124.u73.u8\$12.q,
			$u2_name.u1.u124.u73.u8\$13.q,
			$u2_name.u1.u124.u73.u8\$14.q,
			$u2_name.u1.u124.u73.u8\$15.q,
			$u2_name.u1.u124.u73.u8\$16.q
			} ;

	wire
		reg3_ld = $u1_name.u2.u1.u42.zn,
		eos = $u3_name.u49.eos,
		u4_pden_n = $u4_name.pdata_dr_n,
		u5_pden_n = $u5_name.pdata_dr_n,
		u4_sd_dr_n = $u4_name.sdr,
		u5_sd_dr_n = $u5_name.sdr;
END


BEGIN

	// Pbus signals
	tri [15:0]
END


@ i = 0
while ( $i < $3 )

BEGIN
		pb_dlb${i},
END

  @ j = 0
  while ( $j < $2 )

BEGIN
		pb_dr${i}${j},
END

  @ j = $j + 1
  end

@ i = $i + 1
end


BEGIN
		pb_dl;
	wire
		pb_rst_n,
		pb_eofout,
		pb_iosel,
		pb_status,
		pb_eofin,
		pb_sync;	// Encoded sync

	wire [boxes - 1:0]
		box_en_n,
		box_dir;

	reg
		pb_clk;

	reg
		loop_mode,	// set to 1 if +loop command line arg
		idebug,		// set to 1 if +debug or +idebug command line arg
		cdebug,		// set to 1 if +debug or +cdebug command line arg
		vectors,	// set to 1 if +vectors command line arg
		ivectors,	// set to 1 if +ivectors command line arg
		random_delay,	// set to 1 if +random command line arg
		abort,		// set to 1 if +abort command line arg
		slow;		// set to 1 if +slow command line arg

	// Pullups
	assign (pull0, pull1) sb_bg_ = 8'hff ;
	assign (pull0, pull1) sb_br_ = 8'hff ;
	assign (pull0, pull1) sb_sel_ = 8'hff ;
	assign (pull0, pull1) sb_irq_ = 7'h7f ;
	assign (pull0, pull1) sb_siz = 3'h7 ;
END


# do pulldowns for pb_dl lines
@ i = 0
while ( $i < 16 )

BEGIN
	$pbus_pull #($pull_delay) pull0${i} (pb_dl [$i]);
END

@ i = $i + 1
end


BEGIN

	iboard U1 (.sb_clk(sb_clk), .sb_as_(sb_as_), .sb_pa(sb_pa),
		.sb_d(sb_d), .sb_siz(sb_siz), .sb_rd(sb_rd),
		.sb_ack_(sb_ack_), .sb_merr_(sb_merr_),
		.sb_br_(sb_br_), .sb_bg_(sb_bg_), .sb_sel_(sb_sel_), 
		.sb_irq_(sb_irq_), .sb_reset_n(sb_reset_),
		.sb_ext(sb_ext), .parity(parity),
		.pb_d(pb_dl), .pb_rst_(pb_rst_n), 
		.pb_iosel(pb_iosel), .pb_eofout(pb_eofout),
		.pb_clk(pb_clk), .pb_eosi(pb_status),
		.pb_eofin(pb_eofin), .pb_sync(pb_sync)
		);

	SBUSD U2 (sb_clk, sb_as_, sb_pa, sb_d, sb_siz, sb_rd,
		sb_ack_, sb_merr_, sb_br_, sb_bg_, sb_sel_,
		sb_irq_, sb_reset_, sb_ext, parity);

	SBUSM U3 (sb_clk, sb_as_, sb_pa, sb_d, sb_siz, sb_rd,
		sb_ack_, sb_merr_, sb_br_, sb_bg_, sb_sel_,
		sb_irq_, sb_reset_, sb_ext, parity);

	test #(cycle) U5 (loop_mode) ;

        slaveout U104 () ;

	halt #(cycle) U7 () ;

END


foreach varg ($*)
  if ($varg =~ "+idebug") then

BEGIN
	ifcout #(cycle) U100 () ;

	camout #(cycle) U1000 () ;
END

    break
  endif
end


foreach arg ($*)
  if ($arg =~ "+vectors") then

BEGIN
	// cam vector output
	cvout U9 ();
END
    break
  endif
end


if ($ivectors == 1) then

BEGIN
	// interface vector output
	ivout U120 ();
END
endif


BEGIN

	header U8 () ;
END


if ($2 > $3) then
  @ k = $2
else
  @ k = $3
endif

@ i = 0
while ( $i < $k )

BEGIN

	wire [cpm - 1:0]
		glue${i}_x,
		glue${i}_y,
		glue${i}_z;
END

@ i = $i + 1
end


@ i = 0
while ( $i < $3 )

  @ j = 0
  while ( $j < $2 )

BEGIN

	wire [cpm - 1:0]
		fly_out$i$j;
	wire [cpm - 1:0]
		fly_in$i$j = fly_out$i$j;
	wire [cpm - 1:0]
		disp$i$j;
END

  @ j = $j + 1
  end

@ i = $i + 1
end


@ i = 0
while ( $i < $3)

BEGIN
 
	wire [mpb -1:0]
		rsout$i,
		lsout$i,
		rsin$i,
		ioout$i,
		cam_rst_n$i,
		cam_status$i,
		scan$i,
		capture_n$i,
		disp_valid_n$i;
END

  @ i = $i + 1
end


# instantiate frame grabber if specified
foreach arg ($*)
  if ($arg =~ "grab") then

    @ k = 8 - $1
    if ($k < 1) then
      set msbs = ""
    else
      set msbs = "$k'b0, "
    endif

BEGIN

        // frame grabber--the data is wired to module 0, box 0
        frame_grabber U1a
		(
		.eclk(pb_clk), .clk(pb_clk), .reset_(!pb_rst_n),
                .sync(pb_sync), .capture_(capture_n0 [0]),
                .data_valid_(disp_valid_n0 [0]),
		.video_data( {$msbs disp00} )
		);
END
    break
  endif
end


# instantiate cam modules
@ i = 0
while ( $i < $3 )

  if ( $i == 0 ) then
    set sync = "pb_sync"
  else
    @ t = $i - 1
    set sync = "U${t}0.sync_out"
  endif

  @ j = 0
  while ( $j < $2 )

    @ k = $i + $j

    # calc the glue line subscript
    if ( ($2 * $3) != 4) then
      @ x = ( ($2 * $3) + $k - 1) % ($2 * $3)
      @ y = $k
    else
      switch ($k)
        case 0:
          @ x = 1
          @ y = 2
          breaksw
        case 1:
          @ x = 0
          @ y = 3
          breaksw
        case 2:
          @ x = 3
          @ y = 0
          breaksw
        case 3:
          @ x = 2
          @ y = 1
          breaksw
      endsw
    endif

    # one less than current module in box
    @ jm = $j - 1

    # wire up lsin and iosel according to levels of the bus
    if ($i == 0) then
      set pb_dl = "pb_dl"
      set lsin = "pb_eofout"
      set iosel_in = "pb_iosel"
      set lsout = "lsout0 [$j]"
      if ($j == 0) then
# Changed scan_in to pulldown
#        set scan_in = "1'b1"
        set scan_in = "1'bz"
      else
        set scan_in = "scan0 [$jm]"
      endif
    else
      @ t = $i - 1
      set pb_dl = "pb_dr${t}0"
      set lsin = "rsout${t} [0]"
      set iosel_in = "ioout${t} [0]"
      set lsout = "rsin${t} [$j]"
      if ($j == 0) then
        set scan_in = "scan${t} [0]"
      else
        set scan_in = "scan${i} [$jm]"
      endif
    endif

    @ u = $i + 1
    if ($u == $3) then
      set status_in = "1'bz"
    else
      set status_in = "|(cam_status${u})"
    endif

BEGIN

	cammod #(cpm) U${i}${j} (.fly_out(fly_out$i$j), .disp(disp$i$j),
		.status_in($status_in),
		.status_out(cam_status${i} [$j]),
		.scan_in($scan_in),
		.scan_out(scan${i} [$j]),
		.lsout($lsout),
		.rsout(rsout${i} [$j]),
		.n_dl(pb_dlb${i} [cpm + p_lsb - 1:p_lsb]),
		.n_dr(pb_dr${i}${j} [cpm + p_lsb - 1:p_lsb]),
		.glue_xp(glue${k}_x), .glue_xm(glue${x}_x),
		.glue_yp(glue${k}_y), .glue_ym(glue${y}_y),
		.glue_zp(glue${k}_z), .glue_zm(glue${k}_z),
		.n_lsin($lsin), .n_rsin(rsin${i} [$j]),
		.n_iosel($iosel_in), .fly_in(fly_in$i$j),
		.pb_rst_n(cam_rst_n${i} [0]), .pb_clk(pb_clk),
		.sync($sync), .ioout(ioout${i} [$j]),
		.capture_n(capture_n${i} [$j]),
		.disp_valid_n(disp_valid_n${i} [$j]),
		.box_en_n(box_en_n [$i]), .box_dir(box_dir [$i])
		) ;
END


  # insert one data buffer per box
  if ($j == 0) then

BEGIN
	// data buffers
        TTL245 #(BUFFER_TYPE) UB50$i (
END
 
    @ m = 0
    while ( $m < $1 )

      @ p = $m + $p_lsb 
      @ n = $m + 1
 
BEGIN
                .A${n}($pb_dl [$p]),
                .B${n}(pb_dlb${i} [$p]),
END
 
      @ m = $m + 1
    end

BEGIN
                .DIR(box_dir [$i]),
                .G(box_en_n [$i])
                ) ;
END

  endif
 
  @ j = $j + 1
  end

@ i = $i + 1
end


BEGIN

		// module select (status) pins
END

@ i = 0
while ( $i < $3 )

  @ j = 0
  # put a pullup on the *special* module
  set pull = "pullup_slow"
  while ( $j < $2 )

BEGIN
		$pull #($pull_delay) U20$i$j (cam_status${i} [$j]) ;
END

  # put a pulldown on all other modules
  set pull = "pulldown_slow"
  @ j = $j + 1
  end

@ i = $i + 1
end


BEGIN

		// lsout
END


@ i = 0
while ( $i < $3 )

  @ j = 0
  while ( $j < $2 )

BEGIN
		pulldown_slow #($pull_delay) U21$i$j (lsout${i} [$j]) ;
END

  @ j = $j + 1
  end

@ i = $i + 1
end


BEGIN

		// rsin
END


@ i = 0
while ( $i < $3 )

  @ j = 0
  while ( $j < $2 )

BEGIN
		pulldown_slow #($pull_delay) U22$i$j (rsin${i} [$j]) ;
END

  @ j = $j + 1
  end

@ i = $i + 1
end


BEGIN

		// "right side" data lines
END


# do pulldowns for right side data lines
@ i = 0
while ( $i < $3 )
    @ x = 0
    while ( $x < 16 )

BEGIN
	$pbus_pull #($pull_delay) PUB$i${x} (pb_dlb$i [$x]);
END
      @ x = $x + 1
    end

  @ j = 0
  while ( $j < $2 )

    @ x = 0
    while ( $x < 16 )

BEGIN
	$pbus_pull #($pull_delay) PU$i$j${x} (pb_dr$i${j} [$x]);
END

      @ x = $x + 1
    end

BEGIN

END

    @ j = $j + 1
  end

  @ i = $i + 1
end


BEGIN

		// disp
END


@ i = 0
while ( $i < $3 )

  @ j = 0
  while ( $j < $2 )

    @ k = 0
    while ( $k < $1 )

BEGIN
		pulldown_slow #($pull_delay) U23$i$j$k (disp${i}${j} [$k]) ;
END

    @ k = $k + 1
    end

  @ j = $j + 1
  end

@ i = $i + 1
end


BEGIN

		assign pb_status = |(cam_status0) ;

		assign pb_eofin = |(lsout0) ;

		dfctnb U240 (cam_rst_n0 [0], , pb_rst_n, pb_clk, 1'b1) ;
END

@ i = 1
while ($i < $3)
  @ j = $i - 1

BEGIN
		dfctnb U24${i} (cam_rst_n$i [0], , cam_rst_n$j [0], pb_clk, 1'b1) ;
END

  @ i = $i + 1
end


BEGIN

	integer i;

	initial
		fork

			begin

			last_vector = 0;

			// display configuration
			U8.disp_config ;

			// check for loop mode
			if (\$test\$plusargs ("noloop") )
				loop_mode = 0;
			else
				begin
				loop_mode = 1;
				\$display ("") ;
				\$display ("***") ;
				\$display ("*** Loop mode on") ;
				\$display ("***") ;
				\$display ("") ;
				end

			// check for interface debug mode
                        if (
			   \$test\$plusargs ("idebug") ||
			   \$test\$plusargs ("debug")
			   )
                                begin
				idebug = 1;
				\$display ("") ;
				\$display ("***") ;
                                \$display ("*** Interface Debug mode on") ;
				\$display ("***") ;
				\$display ("") ;
                                end
			else
				idebug = 0;

			// check for cam debug mode
                        if (
			   \$test\$plusargs ("cdebug") ||
			   \$test\$plusargs ("debug")
			   )
                                begin
				cdebug = 1;
				\$display ("") ;
				\$display ("***") ;
                                \$display ("*** Cam debug mode on") ;
				\$display ("***") ;
				\$display ("") ;
                                end
			else
				cdebug = 0;

			// check for cam vectors
                        if (
			   \$test\$plusargs ("vectors")
			   )
                                begin
				vectors = 1;
				\$display ("") ;
				\$display ("***") ;
                                \$display ("*** Vector generation on") ;
				\$display ("***") ;
				\$display ("") ;
                                end
			else
				vectors = 0;

			// check for interface vectors
			if (
			   \$test\$plusargs ("ivectors")
			   )
				begin
				ivectors = 1;
				\$display ("") ;
				\$display ("***") ;
				\$display ("*** Interface vector generation on") ;
				\$display ("***") ;
				\$display ("") ;
				end
			else
				ivectors = 0;

			U2.init_bus ;

			// check for random delays
			if (
			   \$test\$plusargs ("random")
			   )
				begin
				U2.precision = 0;
				\$display ("") ;
				\$display ("***") ;
				\$display ("***  Random SBus delays selected") ;
				\$display ("***") ;
				\$display ("") ;
				end
			else
				U2.precision = 1;

			// check for abort option
			if (
			   \$test\$plusargs ("abort")
			   )
				begin
				abort = 1;
				\$display ("") ;
				\$display ("***") ;
				\$display ("***  Abort option selected") ;
				\$display ("***") ;
				\$display ("") ;
				end
			else
				abort = 0;

			// check for slow option
			if (
			   \$test\$plusargs ("slow")
			   )
				begin
				slow= 1;
				\$display ("") ;
				\$display ("***") ;
				\$display ("***  Slow mode selected") ;
				\$display ("***  (Cam clock not suppressed)") ;
				\$display ("***") ;
				\$display ("") ;
				end
			else
				begin
				slow = 0;
				\$display ("") ;
				\$display ("***") ;
				\$display ("***  Fast mode enabled") ;
				\$display ("***  (Cam clock suppressed during dead cycles)") ;
				\$display ("***  Clock off delay = %0d", U5.vector_off_delay) ;
				\$display ("***") ;
				\$display ("") ;
				end

			// set Translation Cycle delay (0 = random)
			//  this is commented out because of addition
			//  of +random option
//			U2.precision = 1 ;

			// choice of 5 cycle or 512 cycle SBus reset
			sb_reset_ = 0 ;
/*			for (i = 0; i < 512; i = i + 1)
				#cycle;
*/
			for (i = 0; i < 5; i = i + 1)
				#cycle;
			sb_reset_ = 1 ;
			#cycle;
			#cycle;

			// reset interface (1 cycle)
			U5.U1.cam_slave_wr (2'h1, 32'hc0000000) ;

			U5.do_test ;

			// signal vector capture that the last
			//   vector is here
			last_vector = 1; #(2 * cycle);

			\$finish (2);

			end

			// sb_clk = 4/5 (pb_clk)
			forever
				begin
				#(cycle/4) sb_clk = 1 ;
				#(cycle/2) sb_clk = 0 ;
				#(cycle/4) ;
				end

			forever
				begin
				#(cycle/5) pb_clk = 1 ;
				#(2*cycle/5) pb_clk = 0 ;
				#(2*cycle/5) pb_clk = 1 ;
				#(2*cycle/5) pb_clk = 0 ;
				#(2*cycle/5) pb_clk = 1 ;
				#(2*cycle/5) pb_clk = 0 ;
				#(2*cycle/5) pb_clk = 1 ;
				#(2*cycle/5) pb_clk = 0 ;
				#(2*cycle/5) pb_clk = 1 ;
				#(2*cycle/5) pb_clk = 0 ;
				#(cycle/5);
				end

			// fast pb_clk
/*			forever
				begin
				#(cycle/4) sb_clk = 1 ;
				pb_clk = 1 ;
				#(cycle/4) pb_clk = 0 ;
				#(cycle/4) sb_clk = 0 ;
				pb_clk = 1 ;
				#(cycle/4) pb_clk = 0 ;
				end
*/
			// slow pb_clk
/*			forever
				begin
				#(cycle/4) sb_clk = 1 ;
				pb_clk = 1 ;
				#(cycle/2) sb_clk = 0 ;
				#(cycle/4) ;
				#(cycle/4) sb_clk = 1 ;
				pb_clk = 0 ;
				#(cycle/2) sb_clk = 0 ;
				#(cycle/4) ;
				end
*/
		join


END


set vbase = "/im/cam8/vsim/"
set vsource = "release/"
foreach arg ($*)
  if ($arg =~ td) then
    set vsource = "td/"
  else if ($arg =~ df) then
    set vsource = "df/"
  endif
end


foreach arg ($*)
  if ( $arg =~ *.v ) then
    if ( -r $vbase$vsource$arg ) then
      cat $vbase$vsource$arg
    else
      sh -c "echo can\'t read file $vbase$vsource$arg >&2"
      exit (-1)
    endif
  endif
end


BEGIN

endmodule


END

exit (0)

