代码:
module ds18b20_ctrl(sys_clk,sys_rst,data1_inout,data_out,sign); input wire sys_clk,sys_rst; inout wire data1_inout; output wire [15:0] data_out; output reg sign; //时钟定义 reg clk_1us; reg [4:0] cnt_clk1us; //状态机系列 reg [5:0] state; parameter init =6'b000001; parameter write_cmd =6'b000010; parameter waite_cmd =6'b000100; parameter init_again =6'b001000; parameter write_cmd_again =6'b010000; parameter read_cmd =6'b100000; parameter WR_44CC_CMD = 16'h44cc; parameter WR_BECC_CMD = 16'hbecc; reg flag_answer_init; reg [19:0] cnt_time; reg [4:0] cntBit15; reg [15:0] data16_temp; reg qout_temp; reg qout_en; wire [15:0] dataCmd_in_temp; wire qin_temp; reg [15:0] data16_out; //各个状态总延时 parameter init_time =20'd999; parameter write_time =20'd65; parameter waite_time =20'd750_000; parameter read_time =20'd64; //各个状态的输出方向的改变时间 parameter init_outend_time =20'd499; parameter init_answer_time =20'd570; parameter write_outend0_time =20'd62; parameter write_outend1_time =20'd5; parameter read_answer_time =20'd13; parameter read_outend =20'd2; //要输入数据的具体命令 parameter write_cmd_CCh=8'hCC;//跳过rom命令 parameter write_cmd_44h=8'h44;//温度转换命令 parameter write_cmd_again_CCh=8'hcc; parameter write_cmd_again_BEh=8'hBE; //时钟设置(50分频,1us) always@(posedge sys_clk or negedge sys_rst) begin if(!sys_rst) begin clk_1us<=1'b0; cnt_clk1us<=5'd0; end else if(cnt_clk1us==5'd24) begin clk_1us<=~clk_1us; cnt_clk1us<=5'd0; end else begin clk_1us<=clk_1us; cnt_clk1us=cnt_clk1us+1'b1; end end //全体状态机 always@(posedge clk_1us or negedge sys_rst) begin if(!sys_rst) state<=init; else case(state) init: if((flag_answer_init==1'b1)&&(cnt_time==init_time)) state<=write_cmd; else state<=state; write_cmd: if((cntBit15==5'd15)&&(cnt_time==write_time)) state<=waite_cmd; else state<=state; waite_cmd: if(cnt_time==waite_time) state<=init_again; else state<=state; init_again: if((flag_answer_init==1'b1)&&(cnt_time==init_time)) state<=write_cmd_again; else state<=state; write_cmd_again: if((cntBit15==5'd15)&&(cnt_time==write_time)) state<=read_cmd; else state<=state; read_cmd: if((cntBit15==5'd15)&&(cnt_time==read_time)) state<=init; else state<=state; default: state<=init; endcase end //Bit15计数 always@(posedge clk_1us or negedge sys_rst) begin if(!sys_rst) cntBit15<=5'd0; else case(state) init: cntBit15<=cntBit15; write_cmd: if((cntBit15==5'd15)&&(cnt_time==write_time)) cntBit15<=5'd0; else if(cnt_time==write_time) cntBit15<=cntBit15+1'b1; else cntBit15<=cntBit15; waite_cmd: cntBit15<=cntBit15; init_again: cntBit15<=cntBit15; write_cmd_again: if((cntBit15==5'd15)&&(cnt_time==write_time)) cntBit15<=5'd0; else if(cnt_time==write_time) cntBit15<=cntBit15+1'b1; else cntBit15<=cntBit15; read_cmd: if((cntBit15==5'd15)&&(cnt_time==read_time)) cntBit15<=5'd0; else if(cnt_time==read_time) cntBit15<=cntBit15+1'b1; else cntBit15<=cntBit15; default: cntBit15<=cntBit15; endcase end //全体计数 always@(posedge clk_1us or negedge sys_rst) begin if(!sys_rst) cnt_time<=20'd0; else case(state) init: if(cnt_time==init_time) cnt_time<=20'd0; else cnt_time<=cnt_time+1'b1; write_cmd: if((cnt_time==write_time)) cnt_time<=20'd0; else cnt_time<=cnt_time+1; waite_cmd: if(cnt_time==waite_time) cnt_time<=20'd0; else cnt_time<=cnt_time+1'b1; init_again: if(cnt_time==init_time) cnt_time<=20'd0; else cnt_time<=cnt_time+1'b1; write_cmd_again: if((cnt_time==write_time)) cnt_time<=20'd0; else cnt_time<=cnt_time+1; read_cmd: if(cnt_time==read_time) cnt_time<=20'd0; else cnt_time<=cnt_time+1'b1; default: cnt_time<=20'd0; endcase end // //cntBit15 // always@(posedge clk_1us or negedge sys_rst) // begin // if(!sys_rst) // cntBit15<=5'd0; // else if(((state==write_cmd||state==write_cmd_again)&&(cntBit15==5'd15&&cnt_time==write_time))||((state==read_cmd)&&(cntBit15==5'd15&&cnt_time==read_time))) // cntBit15<=5'd0; // else if(((state==write_cmd||state==write_cmd_again)&&(cnt_time==write_time))||(state==read_cmd&&cnt_time==read_time)) // cntBit15<=cntBit15+1'b1; // else // cntBit15<=cntBit15; // end //flag_answer_init always@(posedge clk_1us or negedge sys_rst) begin if(!sys_rst) flag_answer_init<=1'b0; else if((state==init||state==init_again)&&(data1_inout==1'b0)&&(cnt_time==init_answer_time)) flag_answer_init<=1'b1; else if(cnt_time==init_time) flag_answer_init<=1'b0; else flag_answer_init<=flag_answer_init; end //读数据 always@(posedge clk_1us or negedge sys_rst) begin if(!sys_rst) data16_temp<=16'd0; else if((state==read_cmd)&&(cnt_time==read_answer_time)) data16_temp[cntBit15]<=data1_inout; else data16_temp<=data16_temp; end //数据完整输出 always@(posedge clk_1us or negedge sys_rst) begin if(!sys_rst) data16_out<=16'd0; else if((cntBit15==5'd15)&&(cnt_time==read_time-4)&&(state==read_cmd)&&(data16_temp[14]==1'b0)) data16_out<=data16_temp[10:0]; else if((cntBit15==5'd10)&&(cnt_time==read_time-4)&&(state==read_cmd)&&(data16_temp[14]==1'b1)) data16_out<=~data16_temp[10:0]+1; else data16_out<=data16_out; end //符号输出 always@(posedge clk_1us or negedge sys_rst) begin if(!sys_rst) sign<=1'b0; else if(cntBit15==5'd15&&(state==read_cmd-4)&&data16_temp[13]==1'b1&&cnt_time==read_time) sign<=1'b1; else if(cntBit15==5'd15&&(state==read_cmd-4)&&data16_temp[13]==1'b0&&cnt_time==read_time) sign<=1'b0; else sign<=sign; end // //下面是管理单总线的输入还是输出 // always@(posedge clk_1us or negedge sys_rst) // begin // if(!sys_rst) // begin // qout_en<=1'b0; // qout_temp<=1'b0; // end // else case(state) // init: // if(cnt_time<init_outend_time) // begin // qout_en<=1'b1; // qout_temp<=1'b0; // end // else // begin // qout_en<=1'b0; // qout_temp<=1'b0; // end // write_cmd: // // if(qin_temp==1'b1) // // begin // // if((cnt_time<write_outend1_time)||cnt_time==write_time) // // begin // // qout_en<=1'b1; // // qout_temp<=1'b0; // // end // // else // // begin // // qout_en<=1'b0; // // qout_temp<=1'b0; // // end // // end // // else // // begin // // if((cnt_time<write_outend0_time)||cnt_time==write_time) // // begin // // qout_en<=1'b1; // // qout_temp<=1'b0; // // end // // else // // begin // // qout_en<=1'b0; // // qout_temp<=1'b0; // // end // // end // if(cnt_time > 20'd62) // begin // qout_temp <= 1'b0; // qout_en <= 1'b0; // end // else if(cnt_time <= 20'd2) // begin // qout_temp <= 1'b0; // qout_en <= 1'b1; // end // else if(WR_44CC_CMD[cntBit15] == 1'b0) // begin // qout_temp <= 1'b0; // qout_en <= 1'b1; // end // else if(WR_44CC_CMD[cntBit15] == 1'b1) // begin // qout_temp <= 1'b0; // qout_en <= 1'b0; // end // waite_cmd: // begin // qout_en<=1'b1; // qout_temp<=1'b1; // end // init_again: // if((cnt_time<init_outend_time)) // begin // qout_en<=1'b1; // qout_temp<=1'b0; // end // else // begin // qout_en<=1'b0; // qout_temp<=1'b0; // end // write_cmd_again: // //if(qin_temp==1'b1) // // begin // // if((cnt_time<write_outend1_time)||cnt_time==write_time) // // begin // // qout_en<=1'b1; // // qout_temp<=1'b0; // // end // // else // // begin // // qout_en<=1'b0; // // qout_temp<=1'b0; // // end // // end // // else // // begin // // if((cnt_time<write_outend0_time)||cnt_time==write_time) // // begin // // qout_en<=1'b1; // // qout_temp<=1'b0; // // end // // else // // begin // // qout_en<=1'b0; // // qout_temp<=1'b0; // // end // // end // if(cnt_time > 20'd62) // begin // qout_temp <= 1'b0; // qout_en <= 1'b0; // end // else if(cnt_time <= 20'd2) // begin // qout_temp <= 1'b0; // qout_en <= 1'b1; // end // else if(WR_BECC_CMD[cntBit15] == 1'b0) // begin // qout_temp <= 1'b0; // qout_en <= 1'b1; // end // else if(WR_BECC_CMD[cntBit15] == 1'b1) // begin // qout_temp <= 1'b0; // qout_en <= 1'b0; // end // read_cmd: // if(cnt_time<read_outend) // begin // qout_en<=1'b1; // qout_temp<=1'b0; // end // else // begin // qout_en<=1'b0; // qout_temp<=1'b0; // end // default: // begin // qout_en<=qout_en; // qout_temp<=qout_temp; // end // endcase // end //下面是管理单总线的输入还是输出 always@(posedge clk_1us or negedge sys_rst) begin if(!sys_rst) begin qout_en<=1'b0; qout_temp<=1'b0; end else case(state) init: if(cnt_time<init_outend_time) begin qout_en<=1'b1; qout_temp<=1'b0; end else begin qout_en<=1'b0; qout_temp<=1'b0; end write_cmd: begin if(WR_44CC_CMD[cntBit15]==1'b0) begin if(cnt_time<=write_outend0_time) begin qout_en<=1'b1; qout_temp<=1'b0; end else begin qout_en<=1'b0; qout_temp<=1'b0; end end else if(WR_44CC_CMD[cntBit15]==1'b1) begin if(cnt_time<=write_outend1_time) begin qout_en<=1'b1; qout_temp<=1'b0; end else begin qout_en<=1'b0; qout_temp<=1'b0; end end else begin qout_en<=1'b0; qout_temp<=1'b0; end end waite_cmd: begin qout_en<=1'b1; qout_temp<=1'b1; end init_again: if((cnt_time<init_outend_time)) begin qout_en<=1'b1; qout_temp<=1'b0; end else begin qout_en<=1'b0; qout_temp<=1'b0; end write_cmd_again: begin if(WR_BECC_CMD[cntBit15]==1'b0) begin if(cnt_time<=write_outend0_time) begin qout_en<=1'b1; qout_temp<=1'b0; end else begin qout_en<=1'b0; qout_temp<=1'b0; end end else if(WR_BECC_CMD[cntBit15]==1'b1) begin if(cnt_time<=write_outend1_time) begin qout_en<=1'b1; qout_temp<=1'b0; end else begin qout_en<=1'b0; qout_temp<=1'b0; end end else begin qout_en<=1'b0; qout_temp<=1'b0; end end read_cmd: if(cnt_time<read_outend) begin qout_en<=1'b1; qout_temp<=1'b0; end else begin qout_en<=1'b0; qout_temp<=1'b0; end default: begin qout_en<=qout_en; qout_temp<=qout_temp; end endcase end assign data1_inout=(qout_en==1'b1)? qout_temp:1'bz; assign data_out=data16_out*625/10; endmodule