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. |