HierarchyFilesModulesSignalsTasksFunctionsHelp
// ds1822_driver.v
// "Fire and Forget" Dallas 1-Wire[TM] driver
// $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)"

// Initial coding August 2003
// Synthesizes by both Xilinx XST and Icarus
// XST reports 46 slices, 70 MHz on XC2S150-5
// Simulates correctly against model DS2401

`timescale 1ns / 1ns

// OWP and owp stand for 1-Wire Pin
[Up: llrf_fcm ds1822_driver]
module ds1822_driverIndex(
	inout         DS_DFE,        // pin 0
	inout         DS_FCM,        // pin 1
	inout         DS_RFO,        // pin 2
	inout         DS_AFE,        // pin 3
	output [15:0] read_data,     // register DS1822_DATA
	input         host_clk,      // interconnect
	input         host_we,       // interconnect
	input         data_sel,      // select DS1822_DATA
	input         cntl_sel,      // select DS1822_CNTL
	input  [15:0] host_data,     // interconnect
	input         rst            // interconnect
);

`define OWP0 DS_DFE
`define OWP1 DS_FCM
`define OWP2 DS_RFO
`define OWP3 DS_AFE

// most of the host interface logic
// also see the run logic, and the FIFO control
reg [7:0] control_reg;
wire data_load    = host_we & data_sel;
wire control_load = host_we & cntl_sel;
always @(posedge host_clk or posedge rst) if (rst) begin
	control_reg <= 0;
end else begin
	if (control_load) control_reg <= host_data[7:0];
end
wire       send_reset = control_reg[7];
wire       broadcast  = control_reg[6];
wire [1:0] ow_address = control_reg[5:4];
wire [3:0] fifo_addr  = control_reg[3:0];

// Tune this divider to generate proper pulse widths.
// This version good for 25 MHz host_clk
reg [6:0] divider;
reg tick;
always @(posedge host_clk or posedge rst) if (rst) begin
	divider <= 0;
	tick <= 0;
end else begin
	divider <= divider + 1'b1;
	tick <= (divider == 0);
end

// handle the 1-Wire pins as outputs
reg drive;
   assign `OWP0 = (drive & (ow_address==2'd0 | broadcast)) ? 1'b0 : 1'bz ;
   assign `OWP1 = (drive & (ow_address==2'd1 | broadcast)) ? 1'b0 : 1'bz ;
   assign `OWP2 = (drive & (ow_address==2'd2 | broadcast)) ? 1'b0 : 1'bz ;
   assign `OWP3 = (drive & (ow_address==2'd3 | broadcast)) ? 1'b0 : 1'bz ;

// handle the 1-Wire pins as inputs
reg owpd0, owpd1, owpd2, owpd3;
always @(posedge host_clk) if (tick) begin
	owpd0 <= `OWP0;
	owpd1 <= `OWP1;
	owpd2 <= `OWP2;
	owpd3 <= `OWP3;
end
wire ow_in = ~ow_address[1] ? ( ~ow_address[0] ? owpd0 : owpd1 )
                            : ( ~ow_address[0] ? owpd2 : owpd3 ) ;

// state machine that runs this mess
reg [3:0] count;
reg [6:0] bit_count;
reg [7:0] shifter;
reg run, shift_in;
wire zero_count    = (count == 4'd0);
wire indata_count  = (count == 4'd3);
wire end_of_count  = (count == 4'd13);
wire byte_mark     = (bit_count[2:0] == 3'd7);
wire reset_low     = (bit_count[6:3] == 4'd0) & send_reset & run;
wire reset_high    = (bit_count[6:3] == 4'd1) & send_reset;
wire xmit_complete = (bit_count[6:3] == fifo_addr) & byte_mark;
wire [7:0] next_shifter  = {shift_in,shifter[7:1]};
wire       shift_out     = shifter[0];
wire [7:0] fifo_read;
always @(posedge host_clk or posedge rst) if (rst) begin
	run <= 0;
	count <= 0;
	drive <= 0;
	shift_in <= 0;
	bit_count <= 0;
	shifter <= 0;
end else begin
	if (control_load | tick & end_of_count & xmit_complete)
		run <= control_load & host_data[15];
	if (tick) begin
		count <= (run & ~end_of_count) ? (count + 1) : 0;
		drive <= run & ~reset_high & (reset_low |
			~end_of_count & (zero_count | ~shift_out));
	end
	if (tick & indata_count) shift_in <= ow_in;
	if (tick & end_of_count) begin
		bit_count <= xmit_complete ? 0 : (bit_count + 1);
		shifter   <= byte_mark ? fifo_read : next_shifter;
	end
end
wire byte_shift = data_load | tick & end_of_count & byte_mark;
wire [7:0] byte_data = data_load ? host_data : next_shifter;

// FIFO that holds up to 128 bits of data, both outgoing and incoming
srl16x8e byte_fifo(
	.CLK(host_clk), .CE(byte_shift),
	.Q(fifo_read), .D(byte_data),
	.A0(fifo_addr[0]), .A1(fifo_addr[1]),
	.A2(fifo_addr[2]), .A3(fifo_addr[3])
);

// results presented to the host
// should add the 1-Wire presence bit
assign read_data = {run,7'b0,fifo_read};

endmodule

HierarchyFilesModulesSignalsTasksFunctionsHelp

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

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