Archived
368 lines
8.0 KiB
Verilog
368 lines
8.0 KiB
Verilog
`timescale 1ns / 1ps
|
||
//////////////////////////////////////////////////////////////////////////////////
|
||
// Company:
|
||
// Engineer:
|
||
//
|
||
// Create Date: 13:59:21 10/19/2020
|
||
// Design Name:
|
||
// Module Name: DS18B20
|
||
// Project Name:
|
||
// Target Devices:
|
||
// Tool versions:
|
||
// Description:
|
||
|
||
//+125 0000 0111 1101 0000 07D0h
|
||
//+85* 0000 0101 0101 0000 0550h
|
||
//+25.0625 0000 0001 1001 0001 0191h
|
||
//+10.125 0000 0000 1010 0010 00A2h
|
||
//+0.5 0000 0000 0000 1000 0008h
|
||
//0 0000 0000 0000 0000 0000h
|
||
//-0.5 1111 1111 1111 1000 FFF8h
|
||
//-10.125 1111 1111 0101 1110 FF5Eh
|
||
//-25.0625 1111 1110 0110 1111 FE6Fh
|
||
//-55 1111 1100 1001 0000 FC90h
|
||
//////////////////////////////////////////////////////////////////////////////////
|
||
module ds18b20_temp(
|
||
input clk , //40_000_000
|
||
input rstn ,
|
||
inout dq ,
|
||
output reg signed[15:0] temp_data //LSB =0.625 C
|
||
);
|
||
|
||
parameter FRE = 40 ;// //clk为40M时钟,若clk为50M,则 FRE=50;
|
||
|
||
parameter INIT = 3'b000 , //Gray code
|
||
WR_CMD = 3'b001 ,
|
||
WAIT = 3'b011 ,
|
||
INIT_AGAIN = 3'b010 ,
|
||
RD_CMD = 3'b110 ,
|
||
RD_TEMP = 3'b111 ;
|
||
|
||
localparam WR_CC_44 = 16'h44cc ;
|
||
localparam WR_CC_BE = 16'hbecc ;
|
||
localparam cnt_max = FRE[31:1]-1 ;
|
||
localparam WAIT_TEMP_CNT = 20'd750_000 ;//750ms
|
||
|
||
reg flag ;
|
||
reg [15:0] data_reg ;
|
||
reg [2:0] state ;
|
||
reg clk_1us ;
|
||
reg [31:0] cnt_1us ;
|
||
reg dq_en ;
|
||
reg dq_reg ;
|
||
reg [19:0] cnt ;
|
||
reg [3:0] bit_cnt ;
|
||
|
||
assign dq = dq_en ? dq_reg : 1'bz;
|
||
|
||
always@(posedge clk,negedge rstn)
|
||
if(!rstn)
|
||
cnt_1us<=32'b0;
|
||
else if(cnt_1us==cnt_max)
|
||
cnt_1us<=32'b0;
|
||
else
|
||
cnt_1us<=cnt_1us+1'b1;
|
||
|
||
always@(posedge clk,negedge rstn)
|
||
if(!rstn)
|
||
clk_1us<=1'b0;
|
||
else if(cnt_1us==cnt_max)
|
||
clk_1us<=~clk_1us;
|
||
else
|
||
clk_1us<=clk_1us;
|
||
|
||
always@(posedge clk_1us,negedge rstn)
|
||
if(!rstn)
|
||
begin
|
||
dq_en <=1'b1;
|
||
dq_reg <=1'b0;
|
||
state <=INIT;
|
||
cnt <=20'd0;
|
||
flag <=1'b0;
|
||
bit_cnt <=4'b0;
|
||
data_reg <=16'd0;
|
||
temp_data<=12'b0;
|
||
end
|
||
else case(state)
|
||
INIT :begin
|
||
//if(cnt==16'd999)begin //for sim
|
||
if(cnt==16'd9999)
|
||
cnt <=20'd0;
|
||
else if(cnt==16'd999&&flag)begin
|
||
cnt <=20'd0;
|
||
state<=WR_CMD;
|
||
end
|
||
else begin
|
||
cnt <=cnt+1'd1;
|
||
state<=INIT;
|
||
end
|
||
//------------------
|
||
if(cnt==16'd9999)begin
|
||
dq_en <=1'b1;
|
||
dq_reg<=1'b0;
|
||
end
|
||
//else if(cnt==16'd499)begin
|
||
else if(cnt==16'd599)begin
|
||
dq_en <=1'b0;
|
||
dq_reg<=1'b0;
|
||
end
|
||
else begin
|
||
dq_en <=dq_en;
|
||
dq_reg<=dq_reg;
|
||
end
|
||
//------------------
|
||
// if(cnt==20'd570)//&&dq==1'b0)
|
||
if(cnt==20'd670)//&&dq==1'b0)
|
||
flag<= ~dq;
|
||
else if(cnt==20'd999)
|
||
flag<=1'b0;
|
||
else
|
||
flag<=flag;
|
||
end
|
||
/* INIT :begin
|
||
//if(cnt==16'd999)begin //for sim
|
||
if(cnt==16'd999&&flag)begin
|
||
cnt <=20'd0;
|
||
state<=WR_CMD;
|
||
end
|
||
else begin
|
||
cnt <=cnt+1'd1;
|
||
state<=INIT;
|
||
end
|
||
//------------------
|
||
if(cnt==16'd499)begin
|
||
dq_en <=1'b0;
|
||
dq_reg<=1'b0;
|
||
end
|
||
else begin
|
||
dq_en <=dq_en;
|
||
dq_reg<=dq_reg;
|
||
end
|
||
//------------------
|
||
if(cnt==20'd570)//&&dq==1'b0)
|
||
flag<= ~dq;
|
||
else if(cnt==20'd999)
|
||
flag<=1'b0;
|
||
else
|
||
flag<=flag;
|
||
end */
|
||
WR_CMD :begin
|
||
if(cnt==20'd64 && bit_cnt==4'd15)
|
||
begin
|
||
bit_cnt<=4'd0;
|
||
state<=WAIT;
|
||
end
|
||
else if(cnt==20'd64)
|
||
begin
|
||
bit_cnt<=bit_cnt+1'd1;
|
||
state<=WR_CMD;
|
||
end
|
||
else
|
||
begin
|
||
bit_cnt<=bit_cnt;
|
||
state<=WR_CMD;
|
||
end
|
||
//------------------
|
||
if(cnt==20'd64 && bit_cnt==4'd15)
|
||
cnt<=20'd0;
|
||
else if(cnt==20'd64)
|
||
cnt<=20'd0;
|
||
else
|
||
cnt<=cnt+1'd1;
|
||
//------------------
|
||
if(WR_CC_44[bit_cnt]==1'b0 && cnt<=20'd62)
|
||
begin
|
||
dq_en <=1'b1;
|
||
dq_reg<=1'b0;
|
||
end
|
||
else if(WR_CC_44[bit_cnt]==1'b1 && cnt<=20'd1)
|
||
begin
|
||
dq_en <=1'b1;
|
||
dq_reg<=1'b0;
|
||
end
|
||
else
|
||
begin
|
||
dq_en <=1'b0;
|
||
dq_reg<=1'b0;
|
||
end
|
||
end
|
||
WAIT : if(cnt==WAIT_TEMP_CNT)
|
||
begin
|
||
dq_en <=1'b1;
|
||
dq_reg<=1'b0;
|
||
cnt<=20'd0;
|
||
state<=INIT_AGAIN;
|
||
end
|
||
else
|
||
begin
|
||
dq_en <=1'b1;
|
||
dq_reg<=1'b1;
|
||
cnt<=cnt+1'd1;
|
||
state<=WAIT;
|
||
end
|
||
INIT_AGAIN :begin
|
||
if(cnt==16'd999&&flag)
|
||
//if(cnt==16'd999) //for sim
|
||
begin
|
||
cnt <=20'd0;
|
||
state<=RD_CMD;
|
||
end
|
||
else
|
||
begin
|
||
cnt <=cnt+1'd1;
|
||
state<=INIT_AGAIN;
|
||
end
|
||
//------------------
|
||
if(cnt==16'd499)
|
||
begin
|
||
dq_en <=1'b0;
|
||
dq_reg<=1'b0;
|
||
end
|
||
else
|
||
begin
|
||
dq_en <=dq_en;
|
||
dq_reg<=dq_reg;
|
||
end
|
||
//------------------
|
||
if(cnt==20'd570)//&&dq==1'b0)
|
||
flag<=~dq;
|
||
else if(cnt==20'd999)
|
||
flag<=1'b0;
|
||
else
|
||
flag<=flag;
|
||
end
|
||
RD_CMD :begin
|
||
if(cnt==20'd64 && bit_cnt==4'd15)
|
||
begin
|
||
bit_cnt<=4'd0;
|
||
state<=RD_TEMP;
|
||
end
|
||
else if(cnt==20'd64)
|
||
begin
|
||
bit_cnt<=bit_cnt+1'd1;
|
||
state<=RD_CMD;
|
||
end
|
||
else
|
||
begin
|
||
bit_cnt<=bit_cnt;
|
||
state<=RD_CMD;
|
||
end
|
||
//------------------
|
||
if(cnt==20'd64 && bit_cnt==4'd15)
|
||
cnt<=20'd0;
|
||
else if(cnt==20'd64)
|
||
cnt<=20'd0;
|
||
else
|
||
cnt<=cnt+1'd1;
|
||
//------------------
|
||
if(WR_CC_BE[bit_cnt]==1'b0 && cnt<=20'd62)
|
||
begin
|
||
dq_en <=1'b1;
|
||
dq_reg<=1'b0;
|
||
end
|
||
else if(WR_CC_BE[bit_cnt]==1'b1 && cnt<=20'd1)
|
||
begin
|
||
dq_en <=1'b1;
|
||
dq_reg<=1'b0;
|
||
end
|
||
else
|
||
begin
|
||
dq_en <=1'b0;
|
||
dq_reg<=1'b0;
|
||
end
|
||
end
|
||
RD_TEMP :begin
|
||
if(cnt==20'd64 && bit_cnt==4'd15)
|
||
cnt <=20'd0;
|
||
else if(cnt==20'd64)
|
||
cnt<=20'd0;
|
||
else
|
||
cnt<=cnt+1'd1;
|
||
//------------------
|
||
if(cnt<=20'd1|| (cnt==20'd64 && bit_cnt==4'd15))
|
||
begin
|
||
dq_en <=1'b1;
|
||
dq_reg<=1'b0;
|
||
end
|
||
else
|
||
begin
|
||
dq_en <=1'b0;
|
||
dq_reg<=1'b0;
|
||
end
|
||
//------------------
|
||
if(cnt==20'd64 && bit_cnt==4'd15)
|
||
begin
|
||
bit_cnt<=4'd0;
|
||
state<=INIT;
|
||
end
|
||
else if(cnt==20'd64)
|
||
begin
|
||
bit_cnt<=bit_cnt+1'd1;
|
||
state<=RD_TEMP;
|
||
end
|
||
else
|
||
begin
|
||
bit_cnt<=bit_cnt;
|
||
state<=RD_TEMP;
|
||
end
|
||
//------------------
|
||
if(cnt==20'd8)
|
||
data_reg<={dq,data_reg[15:1]};
|
||
else
|
||
data_reg<=data_reg;
|
||
//------------------
|
||
if(cnt==20'd64 && bit_cnt==4'd15)
|
||
temp_data<=data_reg;
|
||
else
|
||
temp_data<=temp_data;
|
||
end
|
||
default: state<=INIT;
|
||
endcase
|
||
|
||
|
||
/* wire[33:0]SYNC_OUT;
|
||
wire[35:0]CONTROL0;
|
||
wire[35:0]CONTROL1;
|
||
wire[149:0]TRIG0;
|
||
|
||
vio u_vio (
|
||
.CONTROL (CONTROL0), // INOUT BUS [35:0]
|
||
.CLK (clk), // IN
|
||
.SYNC_OUT (SYNC_OUT) // OUT BUS [33:0]
|
||
);
|
||
|
||
|
||
icon u_icon (
|
||
.CONTROL0 (CONTROL0), // INOUT BUS [35:0]
|
||
.CONTROL1 (CONTROL1) // INOUT BUS [35:0]
|
||
);
|
||
|
||
|
||
ila u_ila (
|
||
.CONTROL (CONTROL1), // INOUT BUS [35:0]
|
||
.CLK (clk), // IN
|
||
.TRIG0 (TRIG0) // IN BUS [39:0]
|
||
);
|
||
|
||
|
||
assign TRIG0[2:0] = state ;
|
||
assign TRIG0[21:3] = cnt ;
|
||
assign TRIG0[22] = dq ;
|
||
*/
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
endmodule |