module DS18B20Verlog(
RESET,
Fresh,
TempCLK1,
TempCLK2,
DQ,
EOC,
PDATA
);
input RESET;
input Fresh;
input TempCLK1;
input TempCLK2;
inout DQ;
output EOC;
output [7:0]PDATA;
reg [7:0]PDATA;
parameter
STATE_RST1 = 3'd0,
STATE_WRITE1 = 3'd1,
STATE_READ = 3'd2,
STATE_RST2 = 3'd3,
STATE_WRITE2 = 3'd4,
STATE_WAIT = 3'd5;
reg [2:0]state;
//------------------------------------------------
//-- Command for DS18B20 : 0xBECC, 0x44CC
reg [15:0]COMMAND1 = 16'b1011_1110_1100_1100;
reg [15:0]COMMAND2 = 16'b0100_0100_1100_1100;
reg [15:0]DATA; //-- Temperature
//------------------------------------------------
//-- SIGNAL CLKCNT : STD_LOGIC_VECTOR(5 DOWNTO 0); -- 64uS
wire CLKRW,CLKread,CLKwrite0,CLKwrite1;
reg [4:0]Count; //RANGE 0 TO 20
reg EOCtemp,VALUE;
//--------------------------------------------------------------------------------------------------
//-- State
reg [5:0]CLKCNT_1; //-- 64uS
//-----------------------------------------------
//-- The primary period for write and read
always@(posedge TempCLK1 or negedge RESET)
begin
if(!RESET)
CLKCNT_1 <= 6'b0;
else
CLKCNT_1 <= CLKCNT_1 + 1'b1;
end
//-----------------------------------------------
//-- Read plus
assign CLKread = (CLKCNT_1 < 6'd14 )? 1'b0: 1'b1;
//--------------------------------------------------------------------------------------------------
//-- State
reg [5:0]CLKCNT_2; //-- 64uS
//-----------------------------------------------
//-- The primary period for write and read
always@(posedge TempCLK2 or negedge RESET)
begin
if(!RESET)
CLKCNT_2 <= 6'b0;
else
CLKCNT_2 <= CLKCNT_2 + 1'b1;
end
assign CLKRW = CLKCNT_2[5]; //-- Period : 64uS
//-----------------------------------------------
//-- Write plus
//-- Write "0"
assign CLKwrite0 = (CLKCNT_2 < 6'd61)? 1'b0:1'b1;
//-- Write "1"
assign CLKwrite1 = (CLKCNT_2 < 6'd5)? 1'b0:1'b1;
//--=============================================
//-- Update the state
always@(negedge RESET or posedge CLKRW)
begin
if(!RESET)
begin
state <= STATE_RST1;
Count <= 5'd0;
end
else
begin
case(state)
//-----------------------------------
//-- RESET
STATE_RST1:
begin
if(Count > 5'd20 )
begin
Count <= 5'd0;
state <= STATE_WRITE1;
end
else
Count <= Count + 1'b1;
end
//-----------------------------------
//-- Write command to DS18B20 : 0xCC, 0xBE
STATE_WRITE1:
begin
if(Count > 5'd14 )
begin
Count <= 5'd0;
state <= STATE_READ;
end
else
Count <= Count + 1'b1;
end
//-----------------------------------
//-- Read the temperature from DS18B20
STATE_READ:
begin
if(Count > 5'd14 )
begin
Count <= 5'd0;
state <= STATE_RST2;
end
else
Count <= Count + 1'b1;
end
//-----------------------------------
//-- Interval power
//-----------------------------------
//-----------------------------------
//-- Start the converter for the next turn
STATE_RST2:
begin
if(Count > 5'd20 )
begin
Count <= 5'd0;
state <= STATE_WRITE2;
end
else
Count <= Count + 1'b1;
end
//-----------------------------------
//-- Write command to DS18B20 : 0xCC, 0x44
STATE_WRITE2:
begin
if(Count > 5'd14 )
begin
Count <= 5'd0;
state <= STATE_WAIT;
end
else
Count <= Count + 1'b1;
end
//-----------------------------------
//-----------------------------------
//-----------------------------------
//-----------------------------------
//-- Wait for the next turn ... ( Update rate : 1S )
STATE_WAIT:
begin
Count <= 5'd0;
if(Fresh == 1'd0)
state <= STATE_RST1;
end
default:
Count <= 5'd0;
endcase
end
end
//--==============================================
//------------------------------------------------
//-- End of getting temperature
always@(state)
begin
case(state)
//-----------------------------------
//-- RESET
STATE_RST1:
begin
if(Count < 5'd11 )
VALUE <= 1'd0;
else
VALUE <= 1'd1;
end
//-----------------------------------
//-- Write command to DS18B20 : 0xCC, 0xBE
STATE_WRITE1:
begin
if(COMMAND1[Count] == 1'b0)
VALUE <= CLKwrite0;
else
VALUE <= CLKwrite1;
end
//-----------------------------------
//-- Read the temperature from DS18B20
STATE_READ:
VALUE <= CLKwrite1;
//-----------------------------------
//-- Interval power
//-----------------------------------
//-----------------------------------
//-- RESET
STATE_RST2:
begin
if(Count < 5'd11 )
VALUE <= 1'd0;
else
VALUE <= 1'd1;
end
//-----------------------------------
//-- Write command to DS18B20 : 0xCC, 0xBE
STATE_WRITE2:
begin
if(COMMAND2[Count] == 1'b0)
VALUE <= CLKwrite0;
else
VALUE <= CLKwrite1;
end
default:
VALUE <= 1'b1;
endcase
end
//--==============================================
//------------------------------------------------
//-- Getting the temperature
//-- Read datum from DS18B20
wire Receive;
always@(posedge CLKread or negedge RESET)
begin
if(!RESET)
DATA <= 16'b0000000000000000;
else if(Receive == 1'b0)
DATA[Count] <= 16'b0;
else
DATA[Count] <= 16'b1;
end
assign DQ = (VALUE == 1'b0)?1'b0:1'bz;
assign Receive = (VALUE == 1'b0)?1'b1:DQ;
//--==============================================
//------------------------------------------------
//-- Getting the temperature
//-- Read datum from DS18B20
always@(state)
begin
if(state == STATE_READ)
EOCtemp <= 1'b0;
else
EOCtemp <= 1'b1;
end
//--==============================================
//------------------------------------------------
//-- End of getting temperature
wire [7:0]FIGURE;
wire [3:0]VLOW,VHIGH;
always@(posedge EOCtemp or negedge RESET)
begin
if(!RESET)
PDATA <= 8'b00000000;
else
PDATA <= {VHIGH,VLOW};
end
assign FIGURE = DATA[11:4];
assign VHIGH = FIGURE/4'd10;
assign VLOW = FIGURE%4'd10;
assign EOC = EOCtemp;
endmodule
RESET,
Fresh,
TempCLK1,
TempCLK2,
DQ,
EOC,
PDATA
);
input RESET;
input Fresh;
input TempCLK1;
input TempCLK2;
inout DQ;
output EOC;
output [7:0]PDATA;
reg [7:0]PDATA;
parameter
STATE_RST1 = 3'd0,
STATE_WRITE1 = 3'd1,
STATE_READ = 3'd2,
STATE_RST2 = 3'd3,
STATE_WRITE2 = 3'd4,
STATE_WAIT = 3'd5;
reg [2:0]state;
//------------------------------------------------
//-- Command for DS18B20 : 0xBECC, 0x44CC
reg [15:0]COMMAND1 = 16'b1011_1110_1100_1100;
reg [15:0]COMMAND2 = 16'b0100_0100_1100_1100;
reg [15:0]DATA; //-- Temperature
//------------------------------------------------
//-- SIGNAL CLKCNT : STD_LOGIC_VECTOR(5 DOWNTO 0); -- 64uS
wire CLKRW,CLKread,CLKwrite0,CLKwrite1;
reg [4:0]Count; //RANGE 0 TO 20
reg EOCtemp,VALUE;
//--------------------------------------------------------------------------------------------------
//-- State
reg [5:0]CLKCNT_1; //-- 64uS
//-----------------------------------------------
//-- The primary period for write and read
always@(posedge TempCLK1 or negedge RESET)
begin
if(!RESET)
CLKCNT_1 <= 6'b0;
else
CLKCNT_1 <= CLKCNT_1 + 1'b1;
end
//-----------------------------------------------
//-- Read plus
assign CLKread = (CLKCNT_1 < 6'd14 )? 1'b0: 1'b1;
//--------------------------------------------------------------------------------------------------
//-- State
reg [5:0]CLKCNT_2; //-- 64uS
//-----------------------------------------------
//-- The primary period for write and read
always@(posedge TempCLK2 or negedge RESET)
begin
if(!RESET)
CLKCNT_2 <= 6'b0;
else
CLKCNT_2 <= CLKCNT_2 + 1'b1;
end
assign CLKRW = CLKCNT_2[5]; //-- Period : 64uS
//-----------------------------------------------
//-- Write plus
//-- Write "0"
assign CLKwrite0 = (CLKCNT_2 < 6'd61)? 1'b0:1'b1;
//-- Write "1"
assign CLKwrite1 = (CLKCNT_2 < 6'd5)? 1'b0:1'b1;
//--=============================================
//-- Update the state
always@(negedge RESET or posedge CLKRW)
begin
if(!RESET)
begin
state <= STATE_RST1;
Count <= 5'd0;
end
else
begin
case(state)
//-----------------------------------
//-- RESET
STATE_RST1:
begin
if(Count > 5'd20 )
begin
Count <= 5'd0;
state <= STATE_WRITE1;
end
else
Count <= Count + 1'b1;
end
//-----------------------------------
//-- Write command to DS18B20 : 0xCC, 0xBE
STATE_WRITE1:
begin
if(Count > 5'd14 )
begin
Count <= 5'd0;
state <= STATE_READ;
end
else
Count <= Count + 1'b1;
end
//-----------------------------------
//-- Read the temperature from DS18B20
STATE_READ:
begin
if(Count > 5'd14 )
begin
Count <= 5'd0;
state <= STATE_RST2;
end
else
Count <= Count + 1'b1;
end
//-----------------------------------
//-- Interval power
//-----------------------------------
//-----------------------------------
//-- Start the converter for the next turn
STATE_RST2:
begin
if(Count > 5'd20 )
begin
Count <= 5'd0;
state <= STATE_WRITE2;
end
else
Count <= Count + 1'b1;
end
//-----------------------------------
//-- Write command to DS18B20 : 0xCC, 0x44
STATE_WRITE2:
begin
if(Count > 5'd14 )
begin
Count <= 5'd0;
state <= STATE_WAIT;
end
else
Count <= Count + 1'b1;
end
//-----------------------------------
//-----------------------------------
//-----------------------------------
//-----------------------------------
//-- Wait for the next turn ... ( Update rate : 1S )
STATE_WAIT:
begin
Count <= 5'd0;
if(Fresh == 1'd0)
state <= STATE_RST1;
end
default:
Count <= 5'd0;
endcase
end
end
//--==============================================
//------------------------------------------------
//-- End of getting temperature
always@(state)
begin
case(state)
//-----------------------------------
//-- RESET
STATE_RST1:
begin
if(Count < 5'd11 )
VALUE <= 1'd0;
else
VALUE <= 1'd1;
end
//-----------------------------------
//-- Write command to DS18B20 : 0xCC, 0xBE
STATE_WRITE1:
begin
if(COMMAND1[Count] == 1'b0)
VALUE <= CLKwrite0;
else
VALUE <= CLKwrite1;
end
//-----------------------------------
//-- Read the temperature from DS18B20
STATE_READ:
VALUE <= CLKwrite1;
//-----------------------------------
//-- Interval power
//-----------------------------------
//-----------------------------------
//-- RESET
STATE_RST2:
begin
if(Count < 5'd11 )
VALUE <= 1'd0;
else
VALUE <= 1'd1;
end
//-----------------------------------
//-- Write command to DS18B20 : 0xCC, 0xBE
STATE_WRITE2:
begin
if(COMMAND2[Count] == 1'b0)
VALUE <= CLKwrite0;
else
VALUE <= CLKwrite1;
end
default:
VALUE <= 1'b1;
endcase
end
//--==============================================
//------------------------------------------------
//-- Getting the temperature
//-- Read datum from DS18B20
wire Receive;
always@(posedge CLKread or negedge RESET)
begin
if(!RESET)
DATA <= 16'b0000000000000000;
else if(Receive == 1'b0)
DATA[Count] <= 16'b0;
else
DATA[Count] <= 16'b1;
end
assign DQ = (VALUE == 1'b0)?1'b0:1'bz;
assign Receive = (VALUE == 1'b0)?1'b1:DQ;
//--==============================================
//------------------------------------------------
//-- Getting the temperature
//-- Read datum from DS18B20
always@(state)
begin
if(state == STATE_READ)
EOCtemp <= 1'b0;
else
EOCtemp <= 1'b1;
end
//--==============================================
//------------------------------------------------
//-- End of getting temperature
wire [7:0]FIGURE;
wire [3:0]VLOW,VHIGH;
always@(posedge EOCtemp or negedge RESET)
begin
if(!RESET)
PDATA <= 8'b00000000;
else
PDATA <= {VHIGH,VLOW};
end
assign FIGURE = DATA[11:4];
assign VHIGH = FIGURE/4'd10;
assign VLOW = FIGURE%4'd10;
assign EOC = EOCtemp;
endmodule