📄 onewire_master.v
字号:
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
// SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR
// XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION
// AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION
// OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS
// IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
// AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
// FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
// WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
// IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
// REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
// INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE.
//
// (c) Copyright 2004 Xilinx, Inc.
// All rights reserved.
//
/*
-------------------------------------------------------------------------------
-- Title : 1-Wire (TM) Master
-- Project : XUP Virtex-II Pro Demonstration System
-------------------------------------------------------------------------------
-- File : ONEWIRE_MASTER.v
-- Company : Xilinx, Inc.
-- Created : 2001/03/15
-- Last Update: 2001/04/12
-- Copyright : (c) Xilinx Inc, 2001
-------------------------------------------------------------------------------
-- Uses : sr1.v, sr2.v, bit_reg.v, crc_reg.v, jcnt1.v, jcnt2.v, parallel_sn_data.v
-------------------------------------------------------------------------------
-- Used by : ONEWIRE_IFACE.v
-------------------------------------------------------------------------------
-- Description: This is the master module to drive the Serial Number Device.
--
-- When communicate with the Serial Number Device, this module
-- works as the master, while the Serial Number Device works as
-- slave. For more information about the Serial Number Device,
-- please refer to the datasheet at:
-- http://www.dalsemi.com/datasheets/pdfs/2401.pdf
--
-- This module has been verified to work with Dallas DS2401
-- Silicon Serial Number Device and DS2430A EEPROM.
--
-- The function provided by this master module include:
-- (1) Send "Reset Pulse" to the Serial Number Device to reset it
-- (2) Detect "Presence Pulse" from the Serial Number Device
-- (3) Control data flow on the bidirectional one-wire bus which
-- connects the Serial Number Device and this master module
-- through one-wire.
-- (4) Read in the 8 bytes of data from the Serial Number Device
-- which include the family code (x01), the serial number
-- (6 bytes), and the CRC value (1 byte)
-- (5) Output the data to the data bus (data) as individual
-- bytes (total 8 bytes) with a data enable signal (data_valid)
-- as the strobe signal.
-- The data bytes follow the sequence:
-- 1. Family Code: (e.g. 0x01 for DS2401 device)
-- 2. Serial Number (Byte 0)
-- 3. Serial Number (Byte 1)
-- 4. Serial Number (Byte 2)
-- 5. Serial Number (Byte 3)
-- 6. Serial Number (Byte 4)
-- 7. Serial Number (Byte 5)
-- 8. CRC Value
-- (6) Output the six Serial number bytes in parallel (sn_data)
-- (7) (optional) Calculate CRC and match it with the CRC value
-- received from the device.
-- (8) Assert CRC OK if [a] all the bytes has been received and
-- sent out to the data bus, and [b] CRC values are
-- matched ([b] is optional).
--
--
-- This module needs an 1MHz (1us period) clock input.
-------------------------------------------------------------------------------
*/
module ONEWIRE_MASTER (clk, reset, dq, data_out, data_valid, crc_ok, sn_data, sys_clk);
input clk;
input sys_clk;
input reset;
inout dq;
output [7:0] data_out;
output data_valid;
output crc_ok;
output [47:0] sn_data;
wire clk_1MHz;
wire reset;
reg [2:0] PRESENT_STATE;
reg [2:0] NEXT_STATE;
// define the state machine state names
parameter [2:0]
INIT = 3'b000, // Reset/Initialization state
TX_RST_PLS = 3'b001, // Transmit Reset Pulse state
RX_PRE_PLS = 3'b011, // Receive Presence Detect state
TX_RD_CMD = 3'b111, // Transmit ROM READ command state
RX_DATA = 3'b110, // Recieve Serial Number Data state
IDLE = 3'b100; // Idle state
/*
-- constant to issue Read ROM Command for DS2401 Serial Number Device
-- which is either 0x33h (for both DS2401 and DS2430A)
-- or 0x0Fh (for DS2401 only).
*/
parameter [7:0] ReadROMCmd = 8'b00110011;
// -- command data bit to transmit
reg tx_cmd_bit;
// -- internal generated clock (50KHz)
wire clk_50KHz;
// -- time slot identification signals
wire ts_60_to_80us;
wire ts_0_to_10us;
wire ts_0_to_1us;
wire ts_14_to_15us;
// -- signals for shift register 1 (SR1) BIT position counter
reg sr1_reset;
reg sr1_en;
wire [7:0] sr1_q;
// -- signals for shift register 2 (SR2) BYTE transfer counter
reg sr2_reset;
reg sr2_en;
wire [7:0] sr2_q;
// -- signals for Johnson counter 1(JC1)
reg jc1_reset;
wire [1:0] jc1_q;
// -- signals for Johnson counter 2(JC2)
wire [9:0] jc2_q;
// -- signals for the bidirectional data I/O buffer and data path
wire data_from_one_wire_bus; // data from one-wire bus
reg data_to_one_wire_bus; // data to one-wire bus
reg read_one_wire_dq; // if 0 then dq <= data_to_one_wire_bus (write to the bus)
// if 1 then data_from_one_wire_bus <= dq (read from the bus)
reg data_from_one_wire_bus_pp; // data of presence pulse
// it'll be 0 if presence pulse is detected.
reg d_ctrl; // registered version of read_one_wire_dq
reg d_out; // registered version of data_to_one_wire_bus
// -- signals for bit register (BitReg)
wire [7:0] bitreg_en; // enable signal to load one bit of data into the register
wire [7:0] bitreg_data;
// -- several data valid signals
reg databit_valid; // databit_valid signal generated from sr1
// (which identifies states), it's
// 1us pulse. It indicates
// the valid data received from the
// Serial Number Device, excludes
// the Presence Pulse.
reg databyte_valid; // valid signal for receiving a byte of
// the number data from the Serial Number Device.
// Includes: family code, serial number
// and crc value. It's 1 us pulse.
// -- signals for CRC check circuit
wire crcreg_en; // enable one bit data loaded into the CRC Register.
wire [7:0] crc_value; // The calculated CRC value from the CRC register
// -- data outputs
wire [47:0] sn_data; // parallel serial number data
wire [7:0] data_out; // data output one byte at a time
// -- status flag outputs
reg crc_ok; // crc ok output registered version of crc
reg data_valid; // registered version of databyte_valid
reg crc; // crc match flag
always @ (negedge clk_1MHz) begin
data_valid <= databyte_valid;
end
// -- some signals for wiring
wire high;
wire low;
assign high = 1'b1;
assign low = 1'b0;
assign data_out[7:0] = bitreg_data[7:0];
/*
-------------------------------------------------------------------
-- Clock generation
-------------------------------------------------------------------
*/
assign clk_50KHz = !jc2_q[9]; // use the msb of JC2 to generate
// 50KHz slow clock
// use "not" here to generate rising
// edge at proper position
assign clk_1MHz = clk;
/*
-------------------------------------------------------------------
-- Several time slot identification signals
-------------------------------------------------------------------
-- Suppose the beginning of each state is time 0.
-- Use combination of JC1 and JC2, we can id any time slot during
-- each state as small as 1 us.
*/
assign ts_60_to_80us = ( jc1_q[1] & !jc1_q[0]);
assign ts_0_to_10us = (!jc1_q[1] & !jc1_q[0] & !jc2_q[9]);
assign ts_0_to_1us = (!jc1_q[1] & !jc1_q[0] & !jc2_q[9] & !jc2_q[0]);
assign ts_14_to_15us = (!jc1_q[1] & !jc1_q[0] & jc2_q[4] & !jc2_q[3]);
/*
-------------------------------------------------------------------
-- ROM Command data bit to transmit (write) to the one wire bus
-- Use SR1 to pick up each bit out of the Command data byte.
-------------------------------------------------------------------
*/
always @ (sr1_q[7:0]) begin
case (sr1_q)
8'b00000001:begin
tx_cmd_bit = ReadROMCmd[0];
end
8'b00000010:begin
tx_cmd_bit = ReadROMCmd[1];
end
8'b00000100:begin
tx_cmd_bit = ReadROMCmd[2];
end
8'b00001000:begin
tx_cmd_bit = ReadROMCmd[3];
end
8'b00010000:begin
tx_cmd_bit = ReadROMCmd[4];
end
8'b00100000:begin
tx_cmd_bit = ReadROMCmd[5];
end
8'b01000000:begin
tx_cmd_bit = ReadROMCmd[6];
end
8'b10000000:begin
tx_cmd_bit = ReadROMCmd[7];
end
default:begin
tx_cmd_bit = 1'b0;
end
endcase
end
/*
-------------------------------------------------------------------
-- Bidirectional iobuffer to control the direction of data flow on
-- the one-wire bus
-------------------------------------------------------------------
*/
IOBUF IOBUF(
.O(data_from_one_wire_bus),
.IO(dq),
.I(d_out),
.T(d_ctrl)
);
always @ (negedge sys_clk) begin
d_ctrl <= read_one_wire_dq;
d_out <= data_to_one_wire_bus;
end
/*
-------------------------------------------------------------------
-- Shift Register 1
-- Used to count 8 bits in a byte of data
-------------------------------------------------------------------
*/
SR1 SR1 (
.clk(clk_50KHz),
.reset(sr1_reset),
.en(sr1_en),
.q(sr1_q[7:0])
);
/*
-------------------------------------------------------------------
-- Shift Register 2
-- Used to count 8 bytes stored in the Serial Number Device
-------------------------------------------------------------------
*/
SR2 SR2 (
.clk(clk_50KHz),
.reset(sr2_reset),
.en(sr2_en),
.q(sr2_q)
);
/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -