OpenCores
URL https://opencores.org/ocsvn/ds1621/ds1621/trunk

Subversion Repositories ds1621

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /ds1621
    from Rev 6 to Rev 7
    Reverse comparison

Rev 6 → Rev 7

/trunk/files/24LC16B.v
0,0 → 1,633
// *******************************************************************************************************
// ** **
// ** 24LC16B.v - Microchip 24LC16B 16K-BIT I2C SERIAL EEPROM (VCC = +2.5V TO +5.5V) **
// ** **
// *******************************************************************************************************
// ** **
// ** This information is distributed under license from Young Engineering. **
// ** COPYRIGHT (c) 2003 YOUNG ENGINEERING **
// ** ALL RIGHTS RESERVED **
// ** **
// ** **
// ** Young Engineering provides design expertise for the digital world **
// ** Started in 1990, Young Engineering offers products and services for your electronic design **
// ** project. We have the expertise in PCB, FPGA, ASIC, firmware, and software design. **
// ** From concept to prototype to production, we can help you. **
// ** **
// ** http://www.young-engineering.com/ **
// ** **
// *******************************************************************************************************
// ** This information is provided to you for your convenience and use with Microchip products only. **
// ** Microchip disclaims all liability arising from this information and its use. **
// ** **
// ** THIS INFORMATION IS PROVIDED "AS IS." MICROCHIP MAKES NO REPRESENTATION OR WARRANTIES OF **
// ** ANY KIND WHETHER EXPRESS OR IMPLIED, WRITTEN OR ORAL, STATUTORY OR OTHERWISE, RELATED TO **
// ** THE INFORMATION PROVIDED TO YOU, INCLUDING BUT NOT LIMITED TO ITS CONDITION, QUALITY, **
// ** PERFORMANCE, MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR PURPOSE. **
// ** MICROCHIP IS NOT LIABLE, UNDER ANY CIRCUMSTANCES, FOR SPECIAL, INCIDENTAL OR CONSEQUENTIAL **
// ** DAMAGES, FOR ANY REASON WHATSOEVER. **
// ** **
// ** It is your responsibility to ensure that your application meets with your specifications. **
// ** **
// *******************************************************************************************************
// ** Revision : 1.0 **
// ** Modified Date : 12/04/2006 **
// ** Revision History: **
// ** **
// ** 12/04/2006: Initial design **
// ** **
// *******************************************************************************************************
// ** TABLE OF CONTENTS **
// *******************************************************************************************************
// **---------------------------------------------------------------------------------------------------**
// ** DECLARATIONS **
// **---------------------------------------------------------------------------------------------------**
// **---------------------------------------------------------------------------------------------------**
// ** INITIALIZATION **
// **---------------------------------------------------------------------------------------------------**
// **---------------------------------------------------------------------------------------------------**
// ** CORE LOGIC **
// **---------------------------------------------------------------------------------------------------**
// ** 1.01: START Bit Detection **
// ** 1.02: STOP Bit Detection **
// ** 1.03: Input Shift Register **
// ** 1.04: Input Bit Counter **
// ** 1.05: Control Byte Register **
// ** 1.06: Byte Address Register **
// ** 1.07: Write Data Buffer **
// ** 1.08: Acknowledge Generator **
// ** 1.09: Acknowledge Detect **
// ** 1.10: Write Cycle Timer **
// ** 1.11: Write Cycle Processor **
// ** 1.12: Read Data Multiplexor **
// ** 1.13: Read Data Processor **
// ** 1.14: SDA Data I/O Buffer **
// ** **
// **---------------------------------------------------------------------------------------------------**
// ** DEBUG LOGIC **
// **---------------------------------------------------------------------------------------------------**
// ** 2.01: Memory Data Bytes **
// ** 2.02: Write Data Buffer **
// ** **
// **---------------------------------------------------------------------------------------------------**
// ** TIMING CHECKS **
// **---------------------------------------------------------------------------------------------------**
// ** **
// *******************************************************************************************************
 
 
`timescale 1ns/10ps
 
module M24LC16B (A0, A1, A2, WP, SDA, SCL, RESET);
 
input A0; // unconnected pin
input A1; // unconnected pin
input A2; // unconnected pin
 
input WP; // write protect pin
 
inout SDA; // serial data I/O
input SCL; // serial data clock
 
input RESET; // system reset
 
 
// *******************************************************************************************************
// ** DECLARATIONS **
// *******************************************************************************************************
 
reg SDA_DO; // serial data - output
reg SDA_OE; // serial data - output enable
 
wire SDA_DriveEnable; // serial data output enable
reg SDA_DriveEnableDlyd; // serial data output enable - delayed
 
reg [03:00] BitCounter; // serial bit counter
 
reg START_Rcvd; // START bit received flag
reg STOP_Rcvd; // STOP bit received flag
reg CTRL_Rcvd; // control byte received flag
reg ADDR_Rcvd; // byte address received flag
reg MACK_Rcvd; // master acknowledge received flag
 
reg WrCycle; // memory write cycle
reg RdCycle; // memory read cycle
 
reg [07:00] ShiftRegister; // input data shift register
 
reg [07:00] ControlByte; // control byte register
wire [02:00] BlockSelect; // memory block select
wire RdWrBit; // read/write control bit
 
reg [10:00] StartAddress; // memory access starting address
reg [03:00] PageAddress; // memory page address
 
reg [07:00] WrDataByte [0:15]; // memory write data buffer
wire [07:00] RdDataByte; // memory read data
 
reg [15:00] WrCounter; // write buffer counter
 
reg [03:00] WrPointer; // write buffer pointer
reg [10:00] RdPointer; // read address pointer
 
reg WriteActive; // memory write cycle active
 
reg [07:00] MemoryBlock0 [0:255]; // EEPROM data memory array
reg [07:00] MemoryBlock1 [0:255]; // EEPROM data memory array
reg [07:00] MemoryBlock2 [0:255]; // EEPROM data memory array
reg [07:00] MemoryBlock3 [0:255]; // EEPROM data memory array
reg [07:00] MemoryBlock4 [0:255]; // EEPROM data memory array
reg [07:00] MemoryBlock5 [0:255]; // EEPROM data memory array
reg [07:00] MemoryBlock6 [0:255]; // EEPROM data memory array
reg [07:00] MemoryBlock7 [0:255]; // EEPROM data memory array
 
integer LoopIndex; // iterative loop index
 
integer tAA; // timing parameter
integer tWC; // timing parameter
 
 
// *******************************************************************************************************
// ** INITIALIZATION **
// *******************************************************************************************************
 
initial tAA = 900; // SCL to SDA output delay
initial tWC = 5000000; // memory write cycle time
 
initial begin
SDA_DO = 0;
SDA_OE = 0;
end
 
initial begin
START_Rcvd = 0;
STOP_Rcvd = 0;
CTRL_Rcvd = 0;
ADDR_Rcvd = 0;
MACK_Rcvd = 0;
end
 
initial begin
BitCounter = 0;
ControlByte = 0;
end
 
initial begin
WrCycle = 0;
RdCycle = 0;
 
WriteActive = 0;
end
 
 
// *******************************************************************************************************
// ** CORE LOGIC **
// *******************************************************************************************************
// -------------------------------------------------------------------------------------------------------
// 1.01: START Bit Detection
// -------------------------------------------------------------------------------------------------------
 
always @(negedge SDA) begin
if (SCL == 1) begin
START_Rcvd <= 1;
STOP_Rcvd <= 0;
CTRL_Rcvd <= 0;
ADDR_Rcvd <= 0;
MACK_Rcvd <= 0;
 
WrCycle <= #1 0;
RdCycle <= #1 0;
 
BitCounter <= 0;
end
end
 
// -------------------------------------------------------------------------------------------------------
// 1.02: STOP Bit Detection
// -------------------------------------------------------------------------------------------------------
 
always @(posedge SDA) begin
if (SCL == 1) begin
START_Rcvd <= 0;
STOP_Rcvd <= 1;
CTRL_Rcvd <= 0;
ADDR_Rcvd <= 0;
MACK_Rcvd <= 0;
 
WrCycle <= #1 0;
RdCycle <= #1 0;
 
BitCounter <= 10;
end
end
 
// -------------------------------------------------------------------------------------------------------
// 1.03: Input Shift Register
// -------------------------------------------------------------------------------------------------------
 
always @(posedge SCL) begin
ShiftRegister[00] <= SDA;
ShiftRegister[01] <= ShiftRegister[00];
ShiftRegister[02] <= ShiftRegister[01];
ShiftRegister[03] <= ShiftRegister[02];
ShiftRegister[04] <= ShiftRegister[03];
ShiftRegister[05] <= ShiftRegister[04];
ShiftRegister[06] <= ShiftRegister[05];
ShiftRegister[07] <= ShiftRegister[06];
end
 
// -------------------------------------------------------------------------------------------------------
// 1.04: Input Bit Counter
// -------------------------------------------------------------------------------------------------------
 
always @(posedge SCL) begin
if (BitCounter < 10) BitCounter <= BitCounter + 1;
end
 
// -------------------------------------------------------------------------------------------------------
// 1.05: Control Byte Register
// -------------------------------------------------------------------------------------------------------
 
always @(negedge SCL) begin
if (START_Rcvd & (BitCounter == 8)) begin
if (!WriteActive & (ShiftRegister[07:04] == 4'b1010)) begin
if (ShiftRegister[00] == 0) WrCycle <= 1;
if (ShiftRegister[00] == 1) RdCycle <= 1;
 
ControlByte <= ShiftRegister[07:00];
 
CTRL_Rcvd <= 1;
end
 
START_Rcvd <= 0;
end
end
 
assign BlockSelect = ControlByte[03:01];
assign RdWrBit = ControlByte[00];
 
// -------------------------------------------------------------------------------------------------------
// 1.06: Byte Address Register
// -------------------------------------------------------------------------------------------------------
 
always @(negedge SCL) begin
if (CTRL_Rcvd & (BitCounter == 8)) begin
if (RdWrBit == 0) begin
StartAddress <= {BlockSelect[02:00],ShiftRegister[07:00]};
RdPointer <= {BlockSelect[02:00],ShiftRegister[07:00]};
 
ADDR_Rcvd <= 1;
end
 
WrCounter <= 0;
WrPointer <= 0;
 
CTRL_Rcvd <= 0;
end
end
 
// -------------------------------------------------------------------------------------------------------
// 1.07: Write Data Buffer
// -------------------------------------------------------------------------------------------------------
 
always @(negedge SCL) begin
if (ADDR_Rcvd & (BitCounter == 8)) begin
if ((WP == 0) & (RdWrBit == 0)) begin
WrDataByte[WrPointer] <= ShiftRegister[07:00];
 
WrCounter <= WrCounter + 1;
WrPointer <= WrPointer + 1;
end
end
end
 
// -------------------------------------------------------------------------------------------------------
// 1.08: Acknowledge Generator
// -------------------------------------------------------------------------------------------------------
 
always @(negedge SCL) begin
if (!WriteActive) begin
if (BitCounter == 8) begin
if (WrCycle | (START_Rcvd & (ShiftRegister[07:04] == 4'b1010))) begin
SDA_DO <= 0;
SDA_OE <= 1;
end
end
if (BitCounter == 9) begin
BitCounter <= 0;
 
if (!RdCycle) begin
SDA_DO <= 0;
SDA_OE <= 0;
end
end
end
end
 
// -------------------------------------------------------------------------------------------------------
// 1.09: Acknowledge Detect
// -------------------------------------------------------------------------------------------------------
 
always @(posedge SCL) begin
if (RdCycle & (BitCounter == 8)) begin
if ((SDA == 0) & (SDA_OE == 0)) MACK_Rcvd <= 1;
end
end
 
always @(negedge SCL) MACK_Rcvd <= 0;
 
// -------------------------------------------------------------------------------------------------------
// 1.10: Write Cycle Timer
// -------------------------------------------------------------------------------------------------------
 
always @(posedge STOP_Rcvd) begin
if (WrCycle & (WP == 0) & (WrCounter > 0)) begin
WriteActive = 1;
#(tWC);
WriteActive = 0;
end
end
 
always @(posedge STOP_Rcvd) begin
#(1.0);
STOP_Rcvd = 0;
end
 
// -------------------------------------------------------------------------------------------------------
// 1.11: Write Cycle Processor
// -------------------------------------------------------------------------------------------------------
 
always @(negedge WriteActive) begin
for (LoopIndex = 0; LoopIndex < WrCounter; LoopIndex = LoopIndex + 1) begin
PageAddress = StartAddress[03:00] + LoopIndex;
 
case (StartAddress[10:08])
3'b000 : MemoryBlock0[{StartAddress[07:04],PageAddress[03:00]}] = WrDataByte[LoopIndex[03:00]];
3'b001 : MemoryBlock1[{StartAddress[07:04],PageAddress[03:00]}] = WrDataByte[LoopIndex[03:00]];
3'b010 : MemoryBlock2[{StartAddress[07:04],PageAddress[03:00]}] = WrDataByte[LoopIndex[03:00]];
3'b011 : MemoryBlock3[{StartAddress[07:04],PageAddress[03:00]}] = WrDataByte[LoopIndex[03:00]];
3'b100 : MemoryBlock4[{StartAddress[07:04],PageAddress[03:00]}] = WrDataByte[LoopIndex[03:00]];
3'b101 : MemoryBlock5[{StartAddress[07:04],PageAddress[03:00]}] = WrDataByte[LoopIndex[03:00]];
3'b110 : MemoryBlock6[{StartAddress[07:04],PageAddress[03:00]}] = WrDataByte[LoopIndex[03:00]];
3'b111 : MemoryBlock7[{StartAddress[07:04],PageAddress[03:00]}] = WrDataByte[LoopIndex[03:00]];
endcase
end
end
 
// -------------------------------------------------------------------------------------------------------
// 1.12: Read Data Multiplexor
// -------------------------------------------------------------------------------------------------------
 
always @(negedge SCL) begin
if (BitCounter == 8) begin
if (WrCycle & ADDR_Rcvd) begin
RdPointer <= StartAddress + WrPointer + 1;
end
if (RdCycle) begin
RdPointer <= RdPointer + 1;
end
end
end
 
assign RdDataByte = {8{(RdPointer[10:08] == 0)}} & MemoryBlock0[RdPointer[07:00]]
| {8{(RdPointer[10:08] == 1)}} & MemoryBlock1[RdPointer[07:00]]
| {8{(RdPointer[10:08] == 2)}} & MemoryBlock2[RdPointer[07:00]]
| {8{(RdPointer[10:08] == 3)}} & MemoryBlock3[RdPointer[07:00]]
| {8{(RdPointer[10:08] == 4)}} & MemoryBlock4[RdPointer[07:00]]
| {8{(RdPointer[10:08] == 5)}} & MemoryBlock5[RdPointer[07:00]]
| {8{(RdPointer[10:08] == 6)}} & MemoryBlock6[RdPointer[07:00]]
| {8{(RdPointer[10:08] == 7)}} & MemoryBlock7[RdPointer[07:00]];
 
// -------------------------------------------------------------------------------------------------------
// 1.13: Read Data Processor
// -------------------------------------------------------------------------------------------------------
 
always @(negedge SCL) begin
if (RdCycle) begin
if (BitCounter == 8) begin
SDA_DO <= 0;
SDA_OE <= 0;
end
else if (BitCounter == 9) begin
SDA_DO <= RdDataByte[07];
 
if (MACK_Rcvd) SDA_OE <= 1;
end
else begin
SDA_DO <= RdDataByte[7-BitCounter];
end
end
end
 
// -------------------------------------------------------------------------------------------------------
// 1.14: SDA Data I/O Buffer
// -------------------------------------------------------------------------------------------------------
 
bufif1 (SDA, 1'b0, SDA_DriveEnableDlyd);
 
assign SDA_DriveEnable = !SDA_DO & SDA_OE;
always @(SDA_DriveEnable) SDA_DriveEnableDlyd <= #(tAA) SDA_DriveEnable;
 
 
// *******************************************************************************************************
// ** DEBUG LOGIC **
// *******************************************************************************************************
// -------------------------------------------------------------------------------------------------------
// 2.01: Memory Data Bytes
// -------------------------------------------------------------------------------------------------------
 
wire [07:00] MemoryByte0_00 = MemoryBlock0[00];
wire [07:00] MemoryByte0_01 = MemoryBlock0[01];
wire [07:00] MemoryByte0_02 = MemoryBlock0[02];
wire [07:00] MemoryByte0_03 = MemoryBlock0[03];
wire [07:00] MemoryByte0_04 = MemoryBlock0[04];
wire [07:00] MemoryByte0_05 = MemoryBlock0[05];
wire [07:00] MemoryByte0_06 = MemoryBlock0[06];
wire [07:00] MemoryByte0_07 = MemoryBlock0[07];
 
wire [07:00] MemoryByte0_08 = MemoryBlock0[08];
wire [07:00] MemoryByte0_09 = MemoryBlock0[09];
wire [07:00] MemoryByte0_0A = MemoryBlock0[10];
wire [07:00] MemoryByte0_0B = MemoryBlock0[11];
wire [07:00] MemoryByte0_0C = MemoryBlock0[12];
wire [07:00] MemoryByte0_0D = MemoryBlock0[13];
wire [07:00] MemoryByte0_0E = MemoryBlock0[14];
wire [07:00] MemoryByte0_0F = MemoryBlock0[15];
 
wire [07:00] MemoryByte1_00 = MemoryBlock1[00];
wire [07:00] MemoryByte1_01 = MemoryBlock1[01];
wire [07:00] MemoryByte1_02 = MemoryBlock1[02];
wire [07:00] MemoryByte1_03 = MemoryBlock1[03];
wire [07:00] MemoryByte1_04 = MemoryBlock1[04];
wire [07:00] MemoryByte1_05 = MemoryBlock1[05];
wire [07:00] MemoryByte1_06 = MemoryBlock1[06];
wire [07:00] MemoryByte1_07 = MemoryBlock1[07];
 
wire [07:00] MemoryByte1_08 = MemoryBlock1[08];
wire [07:00] MemoryByte1_09 = MemoryBlock1[09];
wire [07:00] MemoryByte1_0A = MemoryBlock1[10];
wire [07:00] MemoryByte1_0B = MemoryBlock1[11];
wire [07:00] MemoryByte1_0C = MemoryBlock1[12];
wire [07:00] MemoryByte1_0D = MemoryBlock1[13];
wire [07:00] MemoryByte1_0E = MemoryBlock1[14];
wire [07:00] MemoryByte1_0F = MemoryBlock1[15];
 
wire [07:00] MemoryByte2_00 = MemoryBlock2[00];
wire [07:00] MemoryByte2_01 = MemoryBlock2[01];
wire [07:00] MemoryByte2_02 = MemoryBlock2[02];
wire [07:00] MemoryByte2_03 = MemoryBlock2[03];
wire [07:00] MemoryByte2_04 = MemoryBlock2[04];
wire [07:00] MemoryByte2_05 = MemoryBlock2[05];
wire [07:00] MemoryByte2_06 = MemoryBlock2[06];
wire [07:00] MemoryByte2_07 = MemoryBlock2[07];
 
wire [07:00] MemoryByte2_08 = MemoryBlock2[08];
wire [07:00] MemoryByte2_09 = MemoryBlock2[09];
wire [07:00] MemoryByte2_0A = MemoryBlock2[10];
wire [07:00] MemoryByte2_0B = MemoryBlock2[11];
wire [07:00] MemoryByte2_0C = MemoryBlock2[12];
wire [07:00] MemoryByte2_0D = MemoryBlock2[13];
wire [07:00] MemoryByte2_0E = MemoryBlock2[14];
wire [07:00] MemoryByte2_0F = MemoryBlock2[15];
 
wire [07:00] MemoryByte3_00 = MemoryBlock3[00];
wire [07:00] MemoryByte3_01 = MemoryBlock3[01];
wire [07:00] MemoryByte3_02 = MemoryBlock3[02];
wire [07:00] MemoryByte3_03 = MemoryBlock3[03];
wire [07:00] MemoryByte3_04 = MemoryBlock3[04];
wire [07:00] MemoryByte3_05 = MemoryBlock3[05];
wire [07:00] MemoryByte3_06 = MemoryBlock3[06];
wire [07:00] MemoryByte3_07 = MemoryBlock3[07];
 
wire [07:00] MemoryByte3_08 = MemoryBlock3[08];
wire [07:00] MemoryByte3_09 = MemoryBlock3[09];
wire [07:00] MemoryByte3_0A = MemoryBlock3[10];
wire [07:00] MemoryByte3_0B = MemoryBlock3[11];
wire [07:00] MemoryByte3_0C = MemoryBlock3[12];
wire [07:00] MemoryByte3_0D = MemoryBlock3[13];
wire [07:00] MemoryByte3_0E = MemoryBlock3[14];
wire [07:00] MemoryByte3_0F = MemoryBlock3[15];
 
wire [07:00] MemoryByte4_00 = MemoryBlock4[00];
wire [07:00] MemoryByte4_01 = MemoryBlock4[01];
wire [07:00] MemoryByte4_02 = MemoryBlock4[02];
wire [07:00] MemoryByte4_03 = MemoryBlock4[03];
wire [07:00] MemoryByte4_04 = MemoryBlock4[04];
wire [07:00] MemoryByte4_05 = MemoryBlock4[05];
wire [07:00] MemoryByte4_06 = MemoryBlock4[06];
wire [07:00] MemoryByte4_07 = MemoryBlock4[07];
 
wire [07:00] MemoryByte4_08 = MemoryBlock4[08];
wire [07:00] MemoryByte4_09 = MemoryBlock4[09];
wire [07:00] MemoryByte4_0A = MemoryBlock4[10];
wire [07:00] MemoryByte4_0B = MemoryBlock4[11];
wire [07:00] MemoryByte4_0C = MemoryBlock4[12];
wire [07:00] MemoryByte4_0D = MemoryBlock4[13];
wire [07:00] MemoryByte4_0E = MemoryBlock4[14];
wire [07:00] MemoryByte4_0F = MemoryBlock4[15];
 
wire [07:00] MemoryByte5_00 = MemoryBlock5[00];
wire [07:00] MemoryByte5_01 = MemoryBlock5[01];
wire [07:00] MemoryByte5_02 = MemoryBlock5[02];
wire [07:00] MemoryByte5_03 = MemoryBlock5[03];
wire [07:00] MemoryByte5_04 = MemoryBlock5[04];
wire [07:00] MemoryByte5_05 = MemoryBlock5[05];
wire [07:00] MemoryByte5_06 = MemoryBlock5[06];
wire [07:00] MemoryByte5_07 = MemoryBlock5[07];
 
wire [07:00] MemoryByte5_08 = MemoryBlock5[08];
wire [07:00] MemoryByte5_09 = MemoryBlock5[09];
wire [07:00] MemoryByte5_0A = MemoryBlock5[10];
wire [07:00] MemoryByte5_0B = MemoryBlock5[11];
wire [07:00] MemoryByte5_0C = MemoryBlock5[12];
wire [07:00] MemoryByte5_0D = MemoryBlock5[13];
wire [07:00] MemoryByte5_0E = MemoryBlock5[14];
wire [07:00] MemoryByte5_0F = MemoryBlock5[15];
 
wire [07:00] MemoryByte6_00 = MemoryBlock6[00];
wire [07:00] MemoryByte6_01 = MemoryBlock6[01];
wire [07:00] MemoryByte6_02 = MemoryBlock6[02];
wire [07:00] MemoryByte6_03 = MemoryBlock6[03];
wire [07:00] MemoryByte6_04 = MemoryBlock6[04];
wire [07:00] MemoryByte6_05 = MemoryBlock6[05];
wire [07:00] MemoryByte6_06 = MemoryBlock6[06];
wire [07:00] MemoryByte6_07 = MemoryBlock6[07];
 
wire [07:00] MemoryByte6_08 = MemoryBlock6[08];
wire [07:00] MemoryByte6_09 = MemoryBlock6[09];
wire [07:00] MemoryByte6_0A = MemoryBlock6[10];
wire [07:00] MemoryByte6_0B = MemoryBlock6[11];
wire [07:00] MemoryByte6_0C = MemoryBlock6[12];
wire [07:00] MemoryByte6_0D = MemoryBlock6[13];
wire [07:00] MemoryByte6_0E = MemoryBlock6[14];
wire [07:00] MemoryByte6_0F = MemoryBlock6[15];
 
wire [07:00] MemoryByte7_00 = MemoryBlock7[00];
wire [07:00] MemoryByte7_01 = MemoryBlock7[01];
wire [07:00] MemoryByte7_02 = MemoryBlock7[02];
wire [07:00] MemoryByte7_03 = MemoryBlock7[03];
wire [07:00] MemoryByte7_04 = MemoryBlock7[04];
wire [07:00] MemoryByte7_05 = MemoryBlock7[05];
wire [07:00] MemoryByte7_06 = MemoryBlock7[06];
wire [07:00] MemoryByte7_07 = MemoryBlock7[07];
 
wire [07:00] MemoryByte7_08 = MemoryBlock7[08];
wire [07:00] MemoryByte7_09 = MemoryBlock7[09];
wire [07:00] MemoryByte7_0A = MemoryBlock7[10];
wire [07:00] MemoryByte7_0B = MemoryBlock7[11];
wire [07:00] MemoryByte7_0C = MemoryBlock7[12];
wire [07:00] MemoryByte7_0D = MemoryBlock7[13];
wire [07:00] MemoryByte7_0E = MemoryBlock7[14];
wire [07:00] MemoryByte7_0F = MemoryBlock7[15];
 
// -------------------------------------------------------------------------------------------------------
// 2.02: Write Data Buffer
// -------------------------------------------------------------------------------------------------------
 
wire [07:00] WriteData_0 = WrDataByte[00];
wire [07:00] WriteData_1 = WrDataByte[01];
wire [07:00] WriteData_2 = WrDataByte[02];
wire [07:00] WriteData_3 = WrDataByte[03];
wire [07:00] WriteData_4 = WrDataByte[04];
wire [07:00] WriteData_5 = WrDataByte[05];
wire [07:00] WriteData_6 = WrDataByte[06];
wire [07:00] WriteData_7 = WrDataByte[07];
wire [07:00] WriteData_8 = WrDataByte[08];
wire [07:00] WriteData_9 = WrDataByte[09];
wire [07:00] WriteData_A = WrDataByte[10];
wire [07:00] WriteData_B = WrDataByte[11];
wire [07:00] WriteData_C = WrDataByte[12];
wire [07:00] WriteData_D = WrDataByte[13];
wire [07:00] WriteData_E = WrDataByte[14];
wire [07:00] WriteData_F = WrDataByte[15];
 
 
// *******************************************************************************************************
// ** TIMING CHECKS **
// *******************************************************************************************************
 
wire TimingCheckEnable = (RESET == 0) & (SDA_OE == 0);
 
specify
specparam
tHI = 600, // SCL pulse width - high
tLO = 1300, // SCL pulse width - low
tSU_STA = 600, // SCL to SDA setup time
tHD_STA = 600, // SCL to SDA hold time
tSU_DAT = 100, // SDA to SCL setup time
tSU_STO = 600, // SCL to SDA setup time
tBUF = 1300; // Bus free time
 
$width (posedge SCL, tHI);
$width (negedge SCL, tLO);
 
$width (posedge SDA &&& SCL, tBUF);
 
$setup (posedge SCL, negedge SDA &&& TimingCheckEnable, tSU_STA);
$setup (SDA, posedge SCL &&& TimingCheckEnable, tSU_DAT);
$setup (posedge SCL, posedge SDA &&& TimingCheckEnable, tSU_STO);
 
$hold (negedge SDA &&& TimingCheckEnable, negedge SCL, tHD_STA);
endspecify
 
endmodule
/trunk/files/eeprom_macros.sv
0,0 → 1,125
// Timing with undefined `DS1621_STANDARD ( more than 100kHz)
 
// for Opencores users:
// Delays are system bus specific. Adapt them to your system bus timing.
// Tasks are acceptable by both 24LC16B and DS1621S devices.
// "write/read" are the tasks from the bus interface
// (create your own interface or change the write read just to be the tasks).
// "data" is the value returned by the interface task.
// Format: Bit 2, 1, 0
// WP SCL SDA
// if EEPROM
// is present
//
 
task iic__stop();
#500 write( 3'b000 );
#1100 write( 3'b010 );
#900 write( 3'b011 );
endtask
 
task iic_ctlop( bit [3:0] EE_or_DS, bit [2:0] blk_adr, bit op, output bit ACK );
#1150 write( 3'b011 );
#650 write( 3'b010 );
#650 write( 3'b000 );
#650 write( {2'b00, EE_or_DS[3]} );
#650 write( {2'b01, EE_or_DS[3]} );
#650 write( {2'b00, EE_or_DS[3]} );
#650 write( {2'b00, EE_or_DS[2]} );
#650 write( {2'b01, EE_or_DS[2]} );
#650 write( {2'b00, EE_or_DS[2]} );
#650 write( {2'b00, EE_or_DS[1]} );
#650 write( {2'b01, EE_or_DS[1]} );
#650 write( {2'b00, EE_or_DS[1]} );
#650 write( {2'b00, EE_or_DS[0]} );
#650 write( {2'b01, EE_or_DS[0]} );
#650 write( {2'b00, EE_or_DS[0]} );
#650 write( {2'b00, blk_adr[2]} );
#650 write( {2'b01, blk_adr[2]} );
#650 write( {2'b00, blk_adr[2]} );
#650 write( {2'b00, blk_adr[1]} );
#650 write( {2'b01, blk_adr[1]} );
#650 write( {2'b00, blk_adr[1]} );
#650 write( {2'b00, blk_adr[0]} );
#650 write( {2'b01, blk_adr[0]} );
#650 write( {2'b00, blk_adr[0]} );
#650 write( {2'b00, op} );
#650 write( {2'b01, op} );
#650 write( 3'b001 ); // ACK check
#1250 write( 3'b011 ); //
#650 read( ACK );
#650 write( 3'b000 ); // ACK end with SCL=0 & SDA=0 (hold time is 0 for devices on IIC)
#650 write( 3'b001 );
endtask
 
task iic_write( bit stop, bit [7:0] data, output bit ACK );
#750 write( {2'b00, data[7]} );
#650 write( {2'b01, data[7]} );
#650 write( {2'b00, data[7]} );
#650 write( {2'b00, data[6]} );
#650 write( {2'b01, data[6]} );
#650 write( {2'b00, data[6]} );
#650 write( {2'b00, data[5]} );
#650 write( {2'b01, data[5]} );
#650 write( {2'b00, data[5]} );
#650 write( {2'b00, data[4]} );
#650 write( {2'b01, data[4]} );
#650 write( {2'b00, data[4]} );
#650 write( {2'b00, data[3]} );
#650 write( {2'b01, data[3]} );
#650 write( {2'b00, data[3]} );
#650 write( {2'b00, data[2]} );
#650 write( {2'b01, data[2]} );
#650 write( {2'b00, data[2]} );
#650 write( {2'b00, data[1]} );
#650 write( {2'b01, data[1]} );
#650 write( {2'b00, data[1]} );
#650 write( {2'b00, data[0]} );
#650 write( {2'b01, data[0]} );
#650 write( {2'b00, data[0]} );
#650 write( 3'b001 ); // ACK check
#650 write( 3'b011 ); //
#650 read( ACK );
#650 write( 3'b000 ); // ACK end with SCL=0 & SDA=0 (hold time is 0 for devices on IIC)
if ( stop ) iic__stop;
else
#650 write( 3'b001 );
endtask
 
task iic__read( bit stop, output bit [7:0] data );
bit data_bit;
#1250 write( 3'b011 );
#650 read( data_bit ); data = {data[6:0], data_bit};
write( 3'b001 );
#1250 write( 3'b011 );
#650 read( data_bit ); data = {data[6:0], data_bit};
write( 3'b001 );
#1250 write( 3'b011 );
#650 read( data_bit ); data = {data[6:0], data_bit};
write( 3'b001 );
#1250 write( 3'b011 );
#650 read( data_bit ); data = {data[6:0], data_bit};
write( 3'b001 );
#1250 write( 3'b011 );
#650 read( data_bit ); data = {data[6:0], data_bit};
write( 3'b001 );
#1250 write( 3'b011 );
#650 read( data_bit ); data = {data[6:0], data_bit};
write( 3'b001 );
#1250 write( 3'b011 );
#650 read( data_bit ); data = {data[6:0], data_bit};
write( 3'b001 );
#1250 write( 3'b011 );
#650 read( data_bit ); data = {data[6:0], data_bit};
if ( stop ) begin
#650 write( 3'b001 ); // NO ACK
#1250 write( 3'b011 );
iic__stop;
end
else begin
#650 write( 3'b000 ); // ACK
#1250 write( 3'b010 );
#650 write( 3'b000 );
#650 write( 3'b001 );
end
endtask
/trunk/files/DS1621_b.sv
0,0 → 1,428
// LTX-CREDENCE
// Project: XXX-X
//
// Module: DS1621_b
// Revision: 01
// Language: SystemVerilog
//
// Engineer: Ashot Khachatryan
// Function: DS1621 temperature sensor. Behavioral model. Accesses the DS1621_b_nvm.sv memory file.
//
// Comments: 20091202 AKH: Created. ADAPTED TO CADENCE IUS8.2
// 20091216 AKH: Has given up adding the features.
// DS1621_CNT (8'hA8) & DS1621_SLP (8'hA9) registers are not supported by this model.
// 20100402 AKH: Replaced the global temperature variable with real input (convenient for stand alone using/testing).
//
// I couldn't find the model in the Internet. So, feel free to use it anywhere.
//
 
`timescale 1ns/10ps
 
`ifndef DS1621_STOP
`define DS1621_STOP 8'h22
`define DS1621_TH 8'hA1
`define DS1621_TL 8'hA2
`define DS1621_CNT 8'hA8
`define DS1621_SLP 8'hA9
`define DS1621_TMP 8'hAA
`define DS1621_CFG 8'hAC
`define DS1621_STRT 8'hEE
`endif
 
module DS1621_b(
input SCL
,inout SDA
,input A0
,input A1
,input A2
,output TOUT
,input [64:1] TEMP_R
);
 
parameter tsafe_sim = 1000;
parameter NVM_WRITE_TM = 10_000_000; // Write time
parameter NVM_WRITE_CP = 500; // internal clock period
parameter TMP_CONV_TIM = 1_000_000_000; // Temperature conversion time (can be shortened for simulation in the module instance)
`define DS1621_ID 4'h9
 
real int_tmp_port;
real int_tmp;
 
shortint TH, TL, TMP;
reg rst_n, rst_n_d;
reg POL, ONE_SHOT, t_alarm;
reg [15:0] TH_init, TL_init, word3_init;
reg POL_init, ONE_SHOT_init;
reg [15:0] nv_RAM [2:0];
reg [15:0] SRi;
reg [7:0] SRo, SLP, CNT;
reg [7:0] cur_acc;
reg [9:0] bit_cnt;
reg selected, rw_op;
reg ev_start, ev_stop, ev_TH, ev_TL;
reg st_write1, st_write2, st_read1, st_read2, st_ack_sl, st_ack_ms, st_pend_memw;
reg rst_ev_start, rst_sel, bcnt_strt, a_memwr;
reg int_clk;
reg [14:0] eewr_tmr; // 'h4E20 = 'd20_000 = 10ms
reg [20:0] tcnv_tmr; // 'h1E_8480 = 'd2_000_000_000 = 1s
reg [2:0] iic_sm, iic_smn;
reg [2:0] eewr_sm, eewr_smn;
reg [2:0] tcnv_sm, tcnv_smn;
reg [1:0] byte_cnt, ev_start_r, ev_stop_r;
reg SDA_r;
reg a_STOP_r;
reg THF, TLF; // status bits
 
tri1 SDA;
wire [2:0] A210;
wire select;
wire rst_bit_cnt, rst_start, rst_stop, rst_timer, rst_ttimer, rst_byte_cnt, rst_pend, rst_bcnt_strt, rst_a_stop;
wire THF_reset, TLF_reset, rst_thf, rst_tlf;
wire [7:0] stat;
wire DONE, NVB; // status bits
wire iic_start, ee_start, tcnv_start, timer_done, ttimer_done, a_START_w;
wire wrt_idle, wrt_wait, wrt_done, tcnv_idle, tcnv_wait, tcnv_done;
wire a_TH, a_TL, a_CNT, a_SLP, a_TMP, a_CFG;
wire byte_cmd, byte_one, byte_two, byte_thr, two_byte_cmd;
 
initial begin int_clk = 0; forever int_clk = #(NVM_WRITE_CP/2) ~int_clk; end // internal clock for EEPROM / Temperature convertion operations
 
// access units
assign a_STOP = SRi[7:0] == `DS1621_STOP;
assign a_TH = SRi[7:0] == `DS1621_TH;
assign a_TL = SRi[7:0] == `DS1621_TL;
assign a_CNT = SRi[7:0] == `DS1621_CNT;
assign a_SLP = SRi[7:0] == `DS1621_SLP;
assign a_TMP = SRi[7:0] == `DS1621_TMP;
assign a_CFG = SRi[7:0] == `DS1621_CFG;
assign a_STRT = SRi[7:0] == `DS1621_STRT;
// conditions
assign A210 = {A2, A1, A0};
assign select = ev_start & (SRi[7:1] == {`DS1621_ID, A210});
assign stat = {DONE, THF, TLF, NVB, 2'b00, POL, ONE_SHOT};
assign rst_bit_cnt = ev_stop | ((bcnt_strt | bit_cnt[9]) & ~SCL) | ~rst_n;
assign rst_bcnt_strt = ~SCL | ~rst_n;
assign rst_start = rst_ev_start | ev_stop | ~rst_n;
assign rst_timer = wrt_done | ~rst_n;
assign rst_ttimer = tcnv_done | ~rst_n;
assign rst_byte_cnt = bcnt_strt | ~rst_n; //rst_ev_start
assign rst_pend = (rst_timer & st_pend_memw) | ~rst_n;
assign rst_sel = (~ev_start_r[1] & ev_start_r[0]) | ev_stop | ~rst_n;
assign rst_stop = &ev_stop_r[1:0] | ~rst_n;
assign rst_a_stop = a_START_w | ~rst_n;
assign rst_thf = THF_reset | ~rst_n_d;
assign rst_tlf = TLF_reset | ~rst_n_d;
assign a_START_w = a_STRT & selected & byte_one & bit_cnt[8] & ~SCL & ~rw_op;
assign iic_start = (ev_start & ~SCL) | (bit_cnt[0] & selected);
assign ee_start = st_pend_memw & ev_stop;
assign tcnv_start = (ONE_SHOT & a_START_w) | (~ONE_SHOT & tcnv_idle & ~a_STOP_r);
assign timer_done = wrt_wait & (eewr_tmr == (NVM_WRITE_TM / NVM_WRITE_CP));
assign ttimer_done = tcnv_wait & (tcnv_tmr == (TMP_CONV_TIM / NVM_WRITE_CP));
assign byte_cmd = byte_cnt == 2'b00;
assign byte_one = byte_cnt == 2'b01;
assign byte_two = byte_cnt == 2'b10;
assign byte_thr = byte_cnt == 2'b11;
// status bits
assign NVB = ~wrt_idle;
assign DONE = tcnv_idle;
assign THF_reset = ~rw_op & bit_cnt[8] & cur_acc[1] & byte_two & ~SCL & ~SRi[6];
assign TLF_reset = ~rw_op & bit_cnt[8] & cur_acc[1] & byte_two & ~SCL & ~SRi[5];
 
// Start
always @( negedge SDA, posedge rst_start )
if ( rst_start ) ev_start <= 1'b0;
else if ( SCL ) ev_start <= 1'b1;
 
always @( negedge SCL ) rst_ev_start <= bit_cnt[9] & ev_start;
//
 
// Stop
always @( posedge SDA, posedge rst_stop )
if ( rst_stop ) ev_stop <= 1'b0;
else if ( SCL ) ev_stop <= 1'b1; // one int_clk period
 
always @( posedge int_clk, negedge rst_n )
if ( ~rst_n ) ev_stop_r[1:0] <= 1'b0;
else ev_stop_r[1:0] <= {ev_stop_r[0], ev_stop};
//
 
// bit counter
always @( posedge SCL, posedge rst_bit_cnt )
if ( rst_bit_cnt ) bit_cnt <= 10'h001;
else bit_cnt <= {bit_cnt, 1'b0};
 
always @( posedge ev_start, posedge rst_bcnt_strt ) // reset after the start condition received
if ( rst_bcnt_strt ) bcnt_strt <= 1'b0;
else bcnt_strt <= 1'b1;
//
 
// byte counter
always @( negedge SCL, posedge rst_byte_cnt )
if ( rst_byte_cnt ) byte_cnt <= 2'b00;
else if ( bit_cnt[9] & selected ) byte_cnt <= byte_cnt +1;
 
// EEPROM write timer
always @( posedge int_clk, posedge rst_timer )
if ( rst_timer ) eewr_tmr <= 15'h0000;
else if ( wrt_wait ) eewr_tmr <= eewr_tmr +1;
 
// Temperature conversion timer
always @( posedge int_clk, posedge rst_ttimer )
if ( rst_ttimer ) tcnv_tmr <= 21'h00_0000;
else if ( tcnv_wait ) tcnv_tmr <= tcnv_tmr +1;
 
// Operation control
always @( negedge SCL, posedge rst_sel )
if ( rst_sel ) rw_op <= 1'b1;
else if ( bit_cnt[8] & ev_start & select ) rw_op <= SRi[0]; // wr=0, rd=1
 
always @( negedge SCL, posedge rst_sel )
if ( rst_sel ) selected <= 1'b0;
else if ( bit_cnt[8] & ev_start & select ) selected <= 1'b1;
 
always @( posedge int_clk, negedge rst_n )
if ( ~rst_n ) ev_start_r[1:0] <= 1'b0;
else ev_start_r[1:0] <= {ev_start_r[0], ev_start};
//
 
// Current resource being accessed
always @( negedge SCL, negedge rst_n )
if ( ~rst_n ) cur_acc[7:0] <= 0;
else if ( bit_cnt[8] & selected & ~rw_op & byte_one ) cur_acc[7:0] <= {a_STOP, a_TH, a_TL, a_CNT, a_SLP, a_TMP, a_CFG, a_STRT};
 
// STOP command retention for not ONE_SHOT mode
always @( negedge SCL, posedge rst_a_stop )
if ( rst_a_stop ) a_STOP_r <= 1'b0;
else if ( cur_acc[7] ) a_STOP_r <= 1'b1;
 
// Pending NV memory write flag
always @( negedge SCL, posedge rst_pend )
if ( rst_pend ) st_pend_memw <= 0;
else if ( bit_cnt[9] ) st_pend_memw <= a_memwr | st_pend_memw;
 
always @( negedge SCL, posedge rst_pend )
if ( rst_pend ) a_memwr <= 0;
else if ( bit_cnt[8] & selected ) a_memwr <= ( ( byte_thr & ((cur_acc[6] & (SRi[15:0] != TH_init)) || (cur_acc[5] & (SRi[15:0] != TL_init))) )
|| ( byte_two & cur_acc[1] & (SRi[1:0] != word3_init[1:0]) )
) & ~rw_op & bit_cnt[8];
//
 
// Slave ACK
always @( negedge SCL, negedge rst_n )
if ( ~rst_n ) st_ack_sl <= 1'b0;
else if ( bit_cnt[8] & (~rw_op | ev_start) ) st_ack_sl <= 1'b1;
else st_ack_sl <= 1'b0;
 
// Master ACK
always @( negedge SCL, negedge rst_n )
if ( ~rst_n ) st_ack_ms <= 1'b0;
else if ( bit_cnt[8] & rw_op & ~ev_start ) st_ack_ms <= 1'b1;
else st_ack_ms <= 1'b0;
 
// Shift register: input
always @( posedge SCL, negedge rst_n )
if ( ~rst_n ) SRi[15:0] <= 16'h0000;
else if ( ~st_ack_sl & ~st_ack_ms ) SRi[15:0] <= {SRi[14:0], SDA};
 
// Shift register: output
always @(negedge SCL) // a_STOP, a_TH, a_TL, a_CNT, a_SLP, a_TMP, a_CFG, a_STRT
if ( bit_cnt[9] ) SRo[7:0] <= cur_acc[6] ? (byte_cmd ? TH[15:8] : TH[7:0]) :
cur_acc[5] ? (byte_cmd ? TL[15:8] : TL[7:0]) :
cur_acc[2] ? (byte_cmd ? TMP[15:8] : TMP[7:0]) :
cur_acc[1] ? stat : 8'hff;
else SRo[7:0] <= {SRo[6:0], 1'b1};
 
// DS1621 registers
// TH
always @( negedge SCL, negedge rst_n_d )
if ( ~rst_n_d ) TH[15:8] <= TH_init[15:8];
else if ( ~rw_op & bit_cnt[8] & cur_acc[6] & byte_two & ~wrt_wait ) TH[15:8] <= SRi[7:0];
 
always @( negedge SCL, negedge rst_n_d )
if ( ~rst_n_d ) TH[7:0] <= TH_init[7:0];
else if ( ~rw_op & bit_cnt[8] & cur_acc[6] & byte_thr & ~wrt_wait ) TH[7:0] <= SRi[7:0];
//
// TL
always @( negedge SCL, negedge rst_n_d )
if ( ~rst_n_d ) TL[15:8] <= TL_init[15:8];
else if ( ~rw_op & bit_cnt[8] & cur_acc[5] & byte_two & ~wrt_wait ) TL[15:8] <= SRi[7:0];
 
always @( negedge SCL, negedge rst_n_d )
if ( ~rst_n_d ) TL[7:0] <= TL_init[7:0];
else if ( ~rw_op & bit_cnt[8] & cur_acc[5] & byte_thr & ~wrt_wait ) TL[7:0] <= SRi[7:0];
//
// CFG status bits: POL, ONE_SHOT
always @( negedge SCL, negedge rst_n_d )
if ( ~rst_n_d ) begin
POL <= POL_init;
ONE_SHOT <= ONE_SHOT_init;
end
else if ( ~rw_op & bit_cnt[8] & cur_acc[1] & byte_two & ~wrt_wait ) begin
POL <= SRi[1];
ONE_SHOT <= SRi[0];
end
// THF, TLF
always @( posedge ev_TH, posedge rst_thf )
if ( rst_thf ) THF <= 1'b0;
else THF <= 1'b1;
// TLF
always @( posedge ev_TL, posedge rst_tlf )
if ( rst_tlf ) TLF <= 1'b0;
else TLF <= 1'b1;
//
 
// EEPROM write state machine
`define DS1621EE_IDLE eewr_sm[0]
`define DS1621EE_WAIT eewr_sm[1]
`define DS1621EE_DONE eewr_sm[2]
`define NDS1621EE_IDLE 3'b001
`define NDS1621EE_WAIT 3'b010
`define NDS1621EE_DONE 3'b100
 
always @( posedge int_clk, negedge rst_n )
if ( ~rst_n ) eewr_sm <= `NDS1621EE_IDLE;
else eewr_sm <= eewr_smn;
 
always @( * ) begin
eewr_smn = eewr_sm;
casex( 1 )
`DS1621EE_IDLE: if ( ee_start ) eewr_smn = `NDS1621EE_WAIT;
`DS1621EE_WAIT: if ( timer_done ) eewr_smn = `NDS1621EE_DONE;
`DS1621EE_DONE: eewr_smn = `NDS1621EE_IDLE;
default: eewr_smn = `NDS1621EE_IDLE;
endcase
end
 
assign wrt_idle = `DS1621EE_IDLE;
assign wrt_wait = `DS1621EE_WAIT;
assign wrt_done = `DS1621EE_DONE;
//
 
// Temperature conversion state machine
`define DS1621T_IDLE tcnv_sm[0]
`define DS1621T_WAIT tcnv_sm[1]
`define DS1621T_DONE tcnv_sm[2]
`define NDS1621T_IDLE 3'b001
`define NDS1621T_WAIT 3'b010
`define NDS1621T_DONE 3'b100
 
always @( posedge int_clk, negedge rst_n )
if ( ~rst_n ) tcnv_sm <= `NDS1621EE_IDLE;
else tcnv_sm <= tcnv_smn;
 
always @( * ) begin
tcnv_smn = tcnv_sm;
casex( 1 )
`DS1621T_IDLE: if ( tcnv_start ) tcnv_smn = `NDS1621T_WAIT;
`DS1621T_WAIT: if ( ttimer_done ) tcnv_smn = `NDS1621T_DONE;
`DS1621T_DONE: tcnv_smn = `NDS1621T_IDLE;
default: tcnv_smn = `NDS1621T_IDLE;
endcase
end
 
assign tcnv_idle = `DS1621T_IDLE;
assign tcnv_wait = `DS1621T_WAIT;
assign tcnv_done = `DS1621T_DONE;
//
 
// Temperature conversion, behavioral
initial assign int_tmp_port = $bitstoreal( TEMP_R );
 
always @( * )
if ( int_tmp_port < -55.0 ) int_tmp = -55.0;
else if ( int_tmp_port > 125.0 ) int_tmp = 125.0;
else int_tmp = int_tmp_port;
 
shortint TMP_tmp;
always @( posedge tcnv_done, negedge rst_n_d )
if ( ~rst_n_d ) TMP[15:0] = 16'h1700; // initial valkue is 23*C
else begin
TMP_tmp = $rtoi(int_tmp);
TMP[15:8] = TMP_tmp[7:0];
//$display("After rtoi TMP_tmp=%0h TMP[15:0]=%0h", TMP_tmp, TMP[15:0]);
if ( (TMP_tmp - int_tmp) != 0 ) TMP[7:0] = 8'h80;
else TMP[7:0] = 8'h00;
//$display("Final TMP[15:0]=%0h", TMP[15:0]);
end
//
 
// Temperature alarm
assign ev_TH = TMP > TH;
assign ev_TL = TMP < TL;
 
always @( * )
if ( ~rst_n_d ) t_alarm = 1'b0;
else if ( ev_TH ) t_alarm = 1'b1;
else if ( ev_TL ) t_alarm = 1'b0;
else t_alarm = t_alarm;
//
 
// Output generation
assign two_byte_cmd = |cur_acc[6:5] | cur_acc[2];
assign SDA = st_ack_sl ? 1'b0 : selected & rw_op & ~st_ack_ms & (byte_one | (byte_two & two_byte_cmd)) ? SRo[7] : 1'bz;
assign TOUT = t_alarm ^~ POL;
 
// NV memory read & write
always @( posedge wrt_done, negedge rst_n ) begin
if ( ~rst_n ) begin
$readmemh( "DS1621_b_nvm.sv", nv_RAM );
if ( nv_RAM[0] == 16'hxxxx ) TH_init = 16'h0000;
else TH_init = nv_RAM[0];
if ( nv_RAM[1] == 16'hxxxx ) TL_init = 16'h0000;
else TL_init = nv_RAM[1];
if ( nv_RAM[2] == 16'hxxxx ) word3_init = 16'h0000;
else word3_init = nv_RAM[2];
POL_init = word3_init[1];
ONE_SHOT_init = word3_init[0];
end
else if ( wrt_done ) begin
nv_RAM[0] = TH;
nv_RAM[1] = TL;
nv_RAM[2] = {14'h0000, POL, ONE_SHOT};
$writememh( "DS1621_b_nvm.sv", nv_RAM );
end
//$display("TH=%h, TL=%h, POL=%0h, ONE_SHOT=%0h", TH_init, TL_init, POL_init, ONE_SHOT_init);
end
 
// timing checks
initial begin
rst_n = 0;
rst_n_d = 1; // memory init signal
#(tsafe_sim / 2)
rst_n_d = 0;
#(tsafe_sim / 2)
rst_n = 1;
rst_n_d = 1;
end
 
specify
specparam
`ifdef DS1621_STANDARD
tBUF = 4700, // Bus free time
tHD_STA = 4000, // SCL+ hold time: start condition [repeated]
tLOW = 4700, // SCL- width
tHIGH = 4000, // SCL+ width
//tHD_DAT = 0, // SDA to SCL+ hold time
tSU_STA = 4700, // SCL+ to SDA setup time for repeated start
tSU_DAT = 250, // SDA to SCL+ setup time
tSU_STO = 4000; // SCL+ to SDA setup time
`else
tBUF = 1300, // Bus free time
tHD_STA = 600, // SCL+ hold time: start condition [repeated]
tLOW = 1300, // SCL- width
tHIGH = 600, // SCL+ width
//tHD_DAT = 0, // SDA to SCL+ hold time
tSU_STA = 600, // SCL+ to SDA setup time for repeated start
tSU_DAT = 100, // SDA to SCL+ setup time
tSU_STO = 600; // SCL+ to SDA setup time
`endif
$width( posedge SDA &&& SCL, tBUF );
$width( negedge SCL, tLOW );
$width( posedge SCL, tHIGH );
$hold ( negedge SDA, negedge SCL &&& rst_n, tHD_STA );
$setup( posedge SCL, negedge SDA &&& rst_n, tSU_STA );
$setup( SDA, posedge SCL &&& rst_n, tSU_DAT );
$setup( posedge SCL, posedge SDA &&& rst_n, tSU_STO );
endspecify
 
endmodule
/trunk/files/tb_ds1621.sv
0,0 → 1,213
// regs: DS1621 Temperature Sensor
 
`define DS1621_CODE 4'h9
`define DS1621_ADDR_01 3'b001
`define DS1621_ADDR_06 3'b110
 
`define DS1621_WROP 1'b0
`define DS1621_RDOP 1'b1
 
// Defined in the model
`ifndef DS1621_STOP
`define DS1621_STOP 8'h22
`define DS1621_TH 8'hA1
`define DS1621_TL 8'hA2
`define DS1621_CNT 8'hA8
`define DS1621_SLP 8'hA9
`define DS1621_TMP 8'hAA
`define DS1621_CFG 8'hAC
`define DS1621_STRT 8'hEE
`endif
 
$display("--DS1621 test 01 begin-->");
board_temp01 = 20.0; // set board temperature
 
$display("----DS1621 sending CFG=03, TH=16'h2800, TL=16'h0A00");
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 0, `DS1621_CFG, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_write( 0, 8'h63, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 0, `DS1621_TH, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_write( 0, 8'h28, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_write( 0, 8'h00, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 0, `DS1621_TL, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_write( 0, 8'h0A, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_write( 1, 8'h00, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
$display("----DS1621 sending done");
 
$display("----DS1621 reading TH");
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 0, `DS1621_TH, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_RDOP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic__read( 0, g_logic_8 ); g_logic_16[15:8]=g_logic_8;
iic__read( 1, g_logic_8 ); g_logic_16[7:0] =g_logic_8;
$display("----DS1621 TH = %0h", g_logic_16);
 
board_temp01 = 25.5; // set board temperature
 
$display("----DS1621 start TMP conversion");
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 1, `DS1621_STRT, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
#2_000_000 // conversion time is truncated in the top
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 0, `DS1621_CFG, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_RDOP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic__read( 1, g_logic_8 ); if ( g_logic_8[7] == 0 ) $display("--DS1621: iic__read, TCNV IS IN PROGRESS = %h", g_logic_8[7] );
//
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 0, `DS1621_TMP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_RDOP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic__read( 0, g_logic_8 ); g_logic_16[15:8]=g_logic_8;
iic__read( 1, g_logic_8 ); g_logic_16[7:0] =g_logic_8;
$display("----DS1621 T=25.5*C, expecting 1980, TMP = %0h", g_logic_16);
 
board_temp01 = -13.0; // set board temperature
 
$display("----DS1621 start TMP conversion");
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 1, `DS1621_STRT, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
#2_000_000 // conversion time is truncated in the top
//
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 0, `DS1621_TMP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_RDOP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic__read( 0, g_logic_8 ); g_logic_16[15:8]=g_logic_8;
iic__read( 1, g_logic_8 ); g_logic_16[7:0] =g_logic_8;
$display("----DS1621 T=-13.0*C, expecting F300, TMP = %0h", g_logic_16);
 
board_temp01 = -13.5; // set board temperature
 
$display("----DS1621 start TMP conversion");
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 1, `DS1621_STRT, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
#2_000_000 // conversion time is truncated in the top
//
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 0, `DS1621_TMP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_RDOP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic__read( 0, g_logic_8 ); g_logic_16[15:8]=g_logic_8;
iic__read( 1, g_logic_8 ); g_logic_16[7:0] =g_logic_8;
$display("----DS1621 T=-13.5*C, expecting F380, TMP = %0h", g_logic_16);
 
board_temp01 = 130.0; // set board temperature
 
$display("----DS1621 start TMP conversion");
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 1, `DS1621_STRT, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
#2_000_000 // conversion time is truncated in the top
//
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 0, `DS1621_TMP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_RDOP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic__read( 0, g_logic_8 ); g_logic_16[15:8]=g_logic_8;
iic__read( 1, g_logic_8 ); g_logic_16[7:0] =g_logic_8;
$display("----DS1621 T=130.0*C, expecting 7D00, TMP = %0h", g_logic_16);
 
board_temp01 = -60.0; // set board temperature
 
$display("----DS1621 start TMP conversion");
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 1, `DS1621_STRT, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
#2_000_000 // conversion time is truncated in the top
//
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 0, `DS1621_TMP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_RDOP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic__read( 0, g_logic_8 ); g_logic_16[15:8]=g_logic_8;
iic__read( 1, g_logic_8 ); g_logic_16[7:0] =g_logic_8;
$display("----DS1621 T=-60.0*C, expecting C900, TMP = %0h", g_logic_16);
// THF, TLF reset
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_01, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 0, `DS1621_CFG, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_write( 1, 8'h03, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
 
$display("--DS1621 test 01 end--<\n");
 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
$display("--------------------------------------------------------------------------------");
 
$display("--DS1621 test 06 begin-->");
$display("----DS1621 sending CFG=03, TH=16'h2800, TL=16'h0A00");
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_06, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 0, `DS1621_CFG, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_write( 0, 8'h63, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_06, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 0, `DS1621_TH, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_write( 0, 8'h28, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_write( 0, 8'h00, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_06, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 0, `DS1621_TL, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_write( 0, 8'h0A, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_write( 1, 8'h00, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
$display("----DS1621 sending done");
 
board_temp06 = 25.5; // set board temperature
 
$display("----DS1621 start TMP conversion");
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_06, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 1, `DS1621_STRT, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
#2_000_000 // conversion time is truncated in the top
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_06, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 0, `DS1621_CFG, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_06, `DS1621_RDOP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic__read( 1, g_logic_8 ); if ( g_logic_8[7] == 0 ) $display("--DS1621: iic__read, TCNV IS IN PROGRESS = %h", g_logic_8[7] );
//
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_06, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 0, `DS1621_TMP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_06, `DS1621_RDOP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic__read( 0, g_logic_8 ); g_logic_16[15:8]=g_logic_8;
iic__read( 1, g_logic_8 ); g_logic_16[7:0] =g_logic_8;
$display("----DS1621 T=25.5*C, expecting 1980, TMP = %0h", g_logic_16);
 
board_temp06 = -13.0; // set board temperature
 
$display("----DS1621 start TMP conversion");
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_06, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 1, `DS1621_STRT, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
#2_000_000 // conversion time is truncated in the top
//
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_06, `DS1621_WROP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic_write( 0, `DS1621_TMP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_write, WRONG ACK = %h", bit_status);
iic_ctlop( `DS1621_CODE, `DS1621_ADDR_06, `DS1621_RDOP, bit_status ); if ( bit_status != 0 ) $display("--DS1621: iic_ctlop, WRONG ACK = %h", bit_status);
iic__read( 0, g_logic_8 ); g_logic_16[15:8]=g_logic_8;
iic__read( 1, g_logic_8 ); g_logic_16[7:0] =g_logic_8;
$display("----DS1621 T=-13.0*C, expecting F300, TMP = %0h", g_logic_16);
 
$display("--DS1621 test 06 end--<\n");
 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
$display("--------------------------------------------------------------------------------");
 
`define EEPROM_CODE 4'hA
`define EEPROM_BLK0 3'b000
`define EEPROM_BLK1 3'b001
`define EEPROM_BLK2 3'b010
`define EEPROM_BLK3 3'b011
`define EEPROM_BLK4 3'b100
`define EEPROM_BLK5 3'b101
`define EEPROM_BLK6 3'b110
`define EEPROM_BLK7 3'b111
 
`define EEPROM_WROP 1'b0
`define EEPROM_RDOP 1'b1
 
$display("--EEPROM test begin-->");
 
$display("---- writing A=12'h001, D=8'h5A");
iic_ctlop( `EEPROM_CODE, `EEPROM_BLK0, `EEPROM_WROP, bit_status ); if ( bit_status != 0 ) $display("--EEPROM: WR1 iic_ctlop 1, WRONG ACK = %h", bit_status);
iic_write( 0, 8'h01, bit_status ); if ( bit_status != 0 ) $display("--EEPROM: WR1 iic_write 1, WRONG ACK = %h", bit_status);
iic_write( 1, 8'h5A, bit_status ); if ( bit_status != 0 ) $display("--EEPROM: WR1 iic_write 2, WRONG ACK = %h", bit_status);
#5_000_000
$display("---- writing done A=12'h001, D=8'h5A\n");
 
$display("---- reading A=12'h001");
iic_ctlop( `EEPROM_CODE, `EEPROM_BLK0, `EEPROM_WROP, bit_status ); if ( bit_status != 0 ) $display("--EEPROM: RD1 iic_ctlop 1, WRONG ACK = %h", bit_status);
iic_write( 0, 8'h01, bit_status ); if ( bit_status != 0 ) $display("--EEPROM: RD1 iic_write 1, WRONG ACK = %h", bit_status);
iic_ctlop( `EEPROM_CODE, `EEPROM_BLK0, `EEPROM_RDOP, bit_status ); if ( bit_status != 0 ) $display("--EEPROM: RD1 iic_ctlop 2, WRONG ACK = %h", bit_status);
iic__read( 1, g_logic_8 );
$display("---- reading done A=12'h001 contains %0h", g_logic_8);
$display("--EEPROM test end--<\n");
/trunk/files/tb_top.sv
0,0 → 1,105
// Module: top
// Revision: 01
// Language: SystemVerilog
// Engineer: Ashot Khachatryan
// Function: Simulation top module for DS1621 behavioral model testing in Cadence IUS8.2 environment
// Comments: 20100402 AKH: Created.
//
 
`timescale 1ns / 1ps
 
module top;
 
int cycle_count;
logic RST;
logic [2:0] I2C; // WP for EEPROM, SCL, SDA
wire SCL, SDA;
real board_temp01, board_temp06;
wire Temper_o01, Temper_o06;
wire [64:1] Temper_s01 = $realtobits(board_temp01);
wire [64:1] Temper_s06 = $realtobits(board_temp06);
bit clk1k;
 
// test vars
bit bit_status;
logic [7:0] data, g_logic_8;
logic [15:0] g_logic_16;
 
task write( logic [1:0] W_DATA ); I2C = W_DATA; endtask // {WP, SCL, SDA}
task read( output bit data ); data = SDA; endtask
 
assign WP = I2C[2];
assign SCL = I2C[1];
assign SDA = I2C[0] ? 1'bz : 1'b0;
 
`include "ds1621/files/eeprom_macros.sv" // EEPROM and DS1621 macro tasks
 
// Simulation recording
initial begin
$shm_open ("out.shm");
$shm_probe("ACMTF");
end
 
initial begin
cycle_count = 1;
I2C = 3'b111;
board_temp01 = 20.0;
board_temp06 = 20.0;
#1
RST = 1;
#100
RST = 0;
$display("*****************************");
$display("* *");
$display("* DS1621 simulation *");
$display("* *");
$display("*****************************");
 
`include "ds1621/files/tb_ds1621.sv"
 
#10_000
$finish;
end
 
// EEPROM
M24LC16B u_24LC16B(
.WP ( WP )
,.SCL ( SCL )
,.SDA ( SDA )
,.RESET ( RST ) // Model from Microchip
);
 
// Temperature sensors // for simulation acceleration the timing is reduced here
DS1621_b #(1000, 1_000_000, 500, 2_000_000) u_DS1621_b_01(
.SCL ( SCL )
,.SDA ( SDA )
,.A0 ( 1'b1 )
,.A1 ( 1'b0 )
,.A2 ( 1'b0 )
,.TOUT ( Temper_o01 )
,.TEMP_R ( Temper_s01 )
);
 
DS1621_b #(1000, 1_000_000, 500, 1_800_000) u_DS1621_b_06(
.SCL ( SCL )
,.SDA ( SDA )
,.A0 ( 1'b0 )
,.A1 ( 1'b1 )
,.A2 ( 1'b1 )
,.TOUT ( Temper_o06 )
,.TEMP_R ( Temper_s06 )
);
 
initial begin clk1k = 1; forever clk1k = #(1000/2) ~clk1k; end
 
clocking cb1k @( posedge clk1k );
default input #1step output #1step;
endclocking
 
// Cycle counter (cb1k)
always @( cb1k ) begin // posedge clk1k
cycle_count <= cycle_count +1;
if( !(cycle_count % 1000) ) $display("passing %0d us", cycle_count);
end
 
endmodule
/trunk/sim/r
0,0 → 1,11
# +ncelabargs+"-NOWarn CUVWSP " \
# +sst+ \
 
ncverilog +sv -f sim_args.v \
-f sim.files \
+notimingchecks \
+nowarn+LIBNOU \
+define+NOCHECKS \
+define+verbose_0 \
+define+nobanner \
+nclibdirname+.INCA_libs
/trunk/sim/DS1621_b_nvm.sv
0,0 → 1,3
2800
0a00
0003
/trunk/sim/ncverilog.log
0,0 → 1,144
ncverilog(64): 08.20-s010: (c) Copyright 1995-2009 Cadence Design Systems, Inc.
TOOL: ncverilog 08.20-s010: Started on Apr 02, 2010 at 14:33:38 AMST
/et/hw/vendor/cadence/ius/v8.2USR10/tools/bin/64bit/ncverilog
+sv
-f sim_args.v
+libext+.v+.vp
+access+rwc
+incdir+ds1621/files+
-f sim.files
ds1621/files/tb_top.sv
ds1621/files/DS1621_b.sv
ds1621/files/24LC16B.v
+notimingchecks
+nowarn+LIBNOU
+define+NOCHECKS
+define+verbose_0
+define+nobanner
+nclibdirname+.INCA_libs
file: ds1621/files/tb_top.sv
default input #1step output #1step;
|
ncvlog: *W,SAWSTP (ds1621/files/tb_top.sv,96|23): Time unit "step" seen in literal - using local precision.
default input #1step output #1step;
|
ncvlog: *W,SAWSTP (ds1621/files/tb_top.sv,96|37): Time unit "step" seen in literal - using local precision.
module worklib.top:sv
errors: 0, warnings: 2
file: ds1621/files/DS1621_b.sv
tri1 SDA;
|
ncvlog: *W,ILLPDX (ds1621/files/DS1621_b.sv,76|14): Multiple declarations for a port not allowed in module with ANSI list of port declarations (port 'SDA') [12.3.4(IEEE-2001)].
module worklib.DS1621_b:sv
errors: 0, warnings: 1
file: ds1621/files/24LC16B.v
Caching library 'worklib' ....... Done
Elaborating the design hierarchy:
M24LC16B u_24LC16B(
|
ncelab: *W,CUVWSI (../files/tb_top.sv,65|18): 3 input ports were not connected:
ncelab: (../files/24LC16B.v,81): A0
ncelab: (../files/24LC16B.v,81): A1
ncelab: (../files/24LC16B.v,81): A2
 
Building instance overlay tables: ...............
$readmemh( "DS1621_b_nvm.sv", nv_RAM );
|
ncelab: *W,MEMODR (../files/DS1621_b.sv,368|43): $readmem default memory order incompatible with IEEE1364.
.....
$readmemh( "DS1621_b_nvm.sv", nv_RAM );
|
ncelab: *W,MEMODR (../files/DS1621_b.sv,368|43): $readmem default memory order incompatible with IEEE1364.
Done
Generating native compiled code:
worklib.DS1621_b:sv <0x0a2e8c6e>
streams: 103, words: 33942
worklib.DS1621_b:sv <0x2dea07dd>
streams: 103, words: 33942
worklib.top:sv <0x5508e5e8>
streams: 18, words: 69160
Loading native compiled code: .................... Done
Building instance specific data structures.
Design hierarchy summary:
Instances Unique
Modules: 4 3
Primitives: 1 1
Registers: 165 109
Scalar wires: 111 -
Vectored wires: 152 -
Always blocks: 87 52
Initial blocks: 15 12
Clocking blocks: 1 1
Cont. assignments: 217 202
Pseudo assignments: 4 4
Timing checks: 21 -
Simulation timescale: 1ps
Writing initial simulation snapshot: worklib.top:sv
Loading snapshot worklib.top:sv .................... Done
ncsim> source /et/hw/vendor/cadence/ius/v8.2USR10/tools/inca/files/ncsimrc
ncsim> run
*****************************
* *
* DS1621 simulation *
* *
*****************************
--DS1621 test 01 begin-->
----DS1621 sending CFG=03, TH=16'h2800, TL=16'h0A00
----DS1621 sending done
----DS1621 reading TH
----DS1621 TH = 2800
----DS1621 start TMP conversion
passing 1000 us
passing 2000 us
----DS1621 T=25.5*C, expecting 1980, TMP = 1980
----DS1621 start TMP conversion
passing 3000 us
passing 4000 us
----DS1621 T=-13.0*C, expecting F300, TMP = f300
----DS1621 start TMP conversion
passing 5000 us
passing 6000 us
----DS1621 T=-13.5*C, expecting F380, TMP = f380
----DS1621 start TMP conversion
passing 7000 us
passing 8000 us
----DS1621 T=130.0*C, expecting 7D00, TMP = 7d00
----DS1621 start TMP conversion
passing 9000 us
passing 10000 us
passing 11000 us
----DS1621 T=-60.0*C, expecting C900, TMP = c900
--DS1621 test 01 end--<
 
--------------------------------------------------------------------------------
--DS1621 test 06 begin-->
----DS1621 sending CFG=03, TH=16'h2800, TL=16'h0A00
----DS1621 sending done
----DS1621 start TMP conversion
passing 12000 us
passing 13000 us
----DS1621 T=25.5*C, expecting 1980, TMP = 1980
----DS1621 start TMP conversion
passing 14000 us
passing 15000 us
----DS1621 T=-13.0*C, expecting F300, TMP = f300
--DS1621 test 06 end--<
 
--------------------------------------------------------------------------------
--EEPROM test begin-->
---- writing A=12'h001, D=8'h5A
passing 16000 us
passing 17000 us
passing 18000 us
passing 19000 us
passing 20000 us
---- writing done A=12'h001, D=8'h5A
 
---- reading A=12'h001
---- reading done A=12'h001 contains 5a
--EEPROM test end--<
 
Simulation complete via $finish(1) at time 20899601 NS + 0
../files/tb_top.sv:61 $finish;
ncsim> exit
TOOL: ncverilog 08.20-s010: Exiting on Apr 02, 2010 at 14:33:41 AMST (total: 00:00:03)
/trunk/sim/sim_args.v
0,0 → 1,3
+libext+.v+.vp
+access+rwc
+incdir+ds1621/files+
/trunk/sim/sim.files
0,0 → 1,3
ds1621/files/tb_top.sv
ds1621/files/DS1621_b.sv
ds1621/files/24LC16B.v
/trunk/simulation_IUS82.txt
0,0 → 1,11
For simulation in Cadence IUS8.2 environment:
 
1. Change the directory to /your_home_path/ds1621/sim
2. Create a link to the simulation top in "sim". The command line is
ln -s /your_home_path/ds1621
or
ln -s /your_home_path/ds1621 ds1621
or replace the link "ds1621" in "sim.files" with absolute path to the simulation top (ds1621 folder).
3. On the Linux OS command prompt type "./r" (you are in the "sim" folder).
4. The generated output is shown in "ncverilog.log" file.
5. If interested, run simvision to look at the waveforms.

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.