HierarchyFilesModulesSignalsTasksFunctionsHelp
// sporty.v
// Serial device support for AMC7820 and ADF4001
// $Id$
// Larry Doolittle, LBNL

// llc-suite Copyright (c) 2004, The Regents of the University of
// California, through Lawrence Berkeley National Laboratory (subject
// to receipt of any required approvals from the U.S. Dept. of Energy).
// All rights reserved.

// Your use of this software is pursuant to a "BSD-style" open
// source license agreement, the text of which is in license.txt
// (md5sum a1e0e81c78f6eba050b0e96996f49fd5) that should accompany
// this file.  If the license agreement is not there, or if you
// have questions about the license, please contact Berkeley Lab's
// Technology Transfer Department at TTD@lbl.gov referring to
// "llc-suite (LBNL Ref CR-1988)"

`timescale 1ns / 1ns

[Up: llrf_fcm sporty]
module sportyIndex(
	input  host_clk, // interconnect
	input  host_we,  // interconnect
	input  [15:0] host_data, // interconnect
	output reg [15:0] data,     // register SPORTY_DATA
	output [15:0] status,       // register SPORTY_CNTL
	input         select_data,  // select   SPORTY_DATA
	input         select_cntl,  // select   SPORTY_CNTL
	output pll_muxout_,      // interconnect
	output reg AMC_CLK,   // pin a
	output reg AMC_SDI,   // pin b
	output reg AMC_CS,    // pin c
	input      AMC_SDO,   // pin d
	output     AMC_RST,   // pin e
	output reg PLL_CLK,   // pin g
	output reg PLL_DATA,  // pin h
	output reg PLL_LE,    // pin i
	input      PLL_MUXOUT // pin k
);

// reads are passive
// host_we is guaranteed to be valid for exactly one (posedge host_clk)

// ADF4001 pins are kept separate for noise reasons.
// Leave them quiet when using other devices.

// ====================end of Verilog interface definition

// Software register map:
//     16 bit data shift register
//     control:
//        0x01 running   shared for all devices
//             devsel    two bits to choose active device
//                          00 - AMC7820
//                          01 - unused
//                          10 - ADF4001
//                          11 - unused
//        0x08 MUXOUT    from ADF4001     (read only)
//        0x10 CE        to ADF4001       (1 to turn on chip)
//        0x20 LE        to ADF4001       (0 during shifts)
//        0x80 CS        to AMC7820       (0 during shifts)
//
// All serial devices share a common data shift register and a common
// timing state machine.  The software may only interact with one at a time.
//
// Software driver notes (also see the associated sportx_tb for example use):
//
//      all: writing a '1' to the run bit starts a serial shift operation
//           to the specified device.  Software should poll the status
//           register until that bit drops back to '0' at completion.
//
//  adf4001: data is written 8 bits at a time.  Lower 'LE', send
//           24 bits split into three transactions, finally raise 'LE'.
//           You can turn off the chip by setting 'CE' low.  The MUXOUT
//           pin is available at all times in the status register, useful
//           if you configure that output as LD.

// "output reg [15:0] data" above is a shift register shared for all devices

// Special note on timing: the FCM module where this is used uses
// 40 MHz for the host clock.  The test benches put this on a virtual
// nanoEngine where the host clock is 25 MHz.  The SCLK times documented
// below reflect reality; simulations will seem slow.

assign AMC_RST = 1'b1;  // Really !RST

reg running;  // control bits, also PLL_LE, CS5742
reg [1:0] devsel;
reg [1:0] divider;      // slows down incoming 40 MHz clock
reg [5:0] bitcnt;       // runs at double the bit shift rate
reg muxout_sample;

`ifdef SIMULATE
initial divider=0;
`endif

// This status readback is overkill, the software really only needs
// to know {muxout_sample, running}
assign status = {AMC_CS, 1'b0, PLL_LE, 1'b1,
	muxout_sample, devsel, running};
assign pll_muxout_ = muxout_sample;

reg tick, ldin, endc, dout, sck;
always @(devsel or bitcnt or AMC_SDO or muxout_sample or
         divider or data or running)
	case (devsel)
 2'b00: begin // AMC7820
	tick = (divider[1:0] == 2'b00);  // 100 ns ticks -> 200 ns clock period
	ldin = AMC_SDO;
	endc = (bitcnt == 6'd32);  // 16 clock rising edges
	dout = data[15];
	sck  = bitcnt[0];
	end
 2'b01: begin // unused
	tick = (divider[1:0] == 2'b00);  // 100 ns ticks -> 200 ns clock period
	ldin = 1'b0;
	endc = (bitcnt == 6'd20);  // 9 clock pulses
	dout = 1'b0;
	sck  = 1'b0;
	end
 2'b10: begin // ADF4001
	tick = (divider[1:0] == 2'b00);  // 100 ns ticks -> 200 ns clock period
	ldin = muxout_sample;  // only useful if MUXOUT=SD_out
	endc = (bitcnt == 6'd15);  // 8 clock rising edges
	dout = 1'b0;
	sck  = 1'b0;
	end
 2'b11: begin // unused
	tick = (divider[1:0] == 2'b00);  // 100 ns ticks -> 200 ns clock period
	ldin = 1'b0;
	endc = (bitcnt == 6'd31);  // 16 clock falling edges
	dout = 1'b0;
	sck  = 1'b0;
	end
endcase

wire shift_enable = tick & running & bitcnt[0];
wire host_write_data = host_we & select_data;
wire host_write_cntl = host_we & select_cntl;

always @(posedge host_clk) begin
	divider <= divider + 1'b1;
	if (host_write_cntl | endc)
		running <= host_write_cntl & host_data[0];
	if (host_write_cntl) begin
		devsel    <= host_data[2:1];
		// host_data[3] ignored, since muxout_sample is read-only
		// host_data[4] ignored, see sportx.v
		PLL_LE    <= host_data[5];
		// host_data[6] ignored, see sportx.v
		AMC_CS    <= host_data[7];
	end
	if (shift_enable | host_write_data)
		data <= host_write_data ? host_data : {data[14:0],ldin};
	if (tick) bitcnt <= running ? (bitcnt + 1'b1) : 0 ;
	AMC_CLK  <= sck;
	if (bitcnt[0]) AMC_SDI  <= dout;
	PLL_CLK  <= bitcnt[0] & (devsel == 2'b10);
	PLL_DATA <= data[7]   & (devsel == 2'b10);
	muxout_sample <= PLL_MUXOUT;
end

endmodule

HierarchyFilesModulesSignalsTasksFunctionsHelp

This page: Maintained by: ldoolitt@recycle.lbl.gov
Created:Wed May 19 11:23:21 2004
From: ../source/sporty.v

Verilog converted to html by v2html 7.30 (written by Costas Calamvokis).Help