純記錄
| 
module IOT_Bridge( 
                output   [7:0] seg,  
                output   [3:0] dig,  
                output   reg [3:0] led, 
                input   clock, 
                input   [3:0] sw, 
                inout   dht22_sda 
        ); 
        //   variables of clocks 
        wire   ck1Mhz; 
        wire   ck1KHz;     
        wire   ck1Hz;       
        CLK_1MHZ  clk_1MHz(clock, ck1Mhz); 
        CLK_1KHZ  clk_1KHz(clock, ck1Khz); 
        CLK_1HZ   clk_1Hz(clock, ck1Hz); 
        //   variables of 7-seg LED  
     wire [3:0] D3; 
     wire [3:0] D2; 
     wire [3:0] D1; 
     wire [3:0] D0; 
     wire [15:0] number;  // number   to display 
     BIN2BCD bin2bcd(number, D3, D2, D1, D0); 
     Seg7    seg7(seg, dig, ck1Khz,   D3, D2, D1, D0);     
        //DHT22   variables 
        reg   dht22_reset; 
        reg   dht22_get; 
        reg   dht22_select; //1=humidity, 0=temperature  
        wire  [39:0] dht22_data; 
        DHT22   dht22(ck1Mhz, dht22_reset, dht22_get, dht22_sda, dht22_data); 
        assign   number[15:0] = dht22_select ? dht22_data[39:24]:dht22_data[23:8]; 
        //   clock 
        reg   [9:0] clock_counter;  
        //   initial 
        initial 
        begin 
                dht22_reset   = 0; 
                dht22_get   = 1; 
                dht22_select   = 1; 
                clock_counter   = 0; 
                led[3:0]=   4'b1111; //LED off 
        end           
        //   select to show humidity or temperture 
        always   @ (posedge sw[0]) 
        begin        
                dht22_select   = ~dht22_select;                 
        end 
        always   @ (posedge ck1Khz) 
        begin                                
                if   (dht22_reset==0) 
                        begin 
                                dht22_reset   = 1;  
                                dht22_get   = 0; //start to read DHT22 
                        end 
                led[3]   = dht22_get; 
                clock_counter   = clock_counter + 1'b1; 
                if(clock_counter==10'd1000) 
                        begin 
                                clock_counter   = 0;   
                                dht22_reset   = 0;  
                        end 
                if(clock_counter==10'd10)   
                        begin                        
                                dht22_get   = 1; //stop read DHT22 
                        end                   
        end                   
endmodule | 
| 
/* 
        DHT22.v   : read DHT22 data 
        source:   https://github.com/evrinoma/AM2302 
        Modify:   Ghosty Guo 
          Date: 2019/06/10 
*/ 
module DHT22( 
        input   wire clk, 
        input   wire reset, 
        input   wire get, 
        inout   sda, 
        output   reg [39:0] outdata 
); 
reg lastSda       = 0; 
reg wdata       = 0; 
reg rw              =   1; 
reg [39:0] data; 
reg [9:0] address; 
reg [3:0] state; 
reg [9:0] count; 
reg [3:0] trace; 
reg [9:0] countTrace; 
localparam STATE_IDLE                          = 0; 
localparam STATE_START                        = 1; 
localparam STATE_RELEASE                   = 2; 
localparam STATE_RESPONSE_LOW      = 3; 
localparam STATE_RESPONSE_HIGH     = 4; 
localparam STATE_DATA_LOW                        = 5; 
localparam STATE_DATA_HIGH                       = 6; 
localparam STATE_STOP                                =   7; 
localparam STATE_HALT                                 = 8; 
localparam DELAY_HALT                                = 2; 
assign sda = (rw)? 1'bz : wdata; 
initial 
begin 
        outdata[39:0]   = 40'd0; 
end 
always@(posedge clk) 
begin 
        if   (!reset) 
                begin 
                        state   <= STATE_IDLE; 
                        rw            <= 1; 
                        count   <= 10'd0; 
                        address   <= 10'd39; 
                        data   <= 40'd0; 
                        lastSda     <= 0; 
                end 
        else 
                begin 
                        case   (state)  
                                STATE_IDLE   : begin //0 
                                        if   (!get)  
                                                state   <= STATE_START; 
                                        else 
                                                state <= STATE_IDLE; 
                                        rw            <= 1; 
                                        count       <= 10'd0; 
                                        address   <= 10'd39; 
                                end 
                                STATE_START   : begin //1          
                                        if   (count == 1000) //1ms 
                                                begin 
                                                        state   <= STATE_RELEASE; 
                                                        count   <= 10'd0; 
                                                end 
                                        else 
                                                begin 
                                                        state   <= STATE_START; 
                                                        count   <= count + 10'd1; 
                                                end 
                                        wdata   <= 0; 
                                        rw            <= 0;                         
                                end 
                                STATE_RELEASE   : begin //2 
                                        if   (count == 30) //30us 
                                                begin 
                                                        state   <= STATE_RESPONSE_LOW; 
                                                        count   <= 10'd0; 
                                                        rw            <= 1; 
                                                end 
                                        else 
                                                begin 
                                                        state   <= STATE_RELEASE; 
                                                        count   <= count + 10'd1; 
                                                        rw            <= 0; 
                                                end 
                                        wdata   <= 1; 
                                end 
                                STATE_RESPONSE_LOW   : begin //3 
                                        if   (trace != STATE_HALT )  
                                                begin 
                                                        if   (count == 40)        //80us/2 
                                                                begin 
                                                                        if   (sda && !lastSda)  
                                                                                begin 
                                                                                        state   <= STATE_RESPONSE_HIGH; 
                                                                                        count   <= 10'd0; 
                                                                                end                                                           
                                                                        else 
                                                                                begin 
                                                                                        state   <= STATE_RESPONSE_LOW;                                                     
                                                                                end 
                                                                end 
                                                        else 
                                                                begin 
                                                                        count   <= count + 10'd1; 
                                                                end   
                                                        rw                    <= 1;         
                                                        lastSda     <= sda; 
                                                end 
                                        else 
                                                begin 
                                                        state   <= STATE_IDLE; 
                                                end 
                                end 
                                STATE_RESPONSE_HIGH   : begin //4 
                                        if   (trace != STATE_HALT )  
                                                begin 
                                                        if   (count == 40)        //80us/2 
                                                                begin 
                                                                        if   (!sda && lastSda)  
                                                                                begin 
                                                                                        state   <= STATE_DATA_LOW; 
                                                                                        count   <= 10'd0; 
                                                                                end                                                           
                                                                        else 
                                                                                begin 
                                                                                        state   <= STATE_RESPONSE_HIGH;                                                   
                                                                                end 
                                                                end 
                                                        else 
                                                                begin 
                                                                        count   <= count + 10'd1; 
                                                                end   
                                                        rw                    <= 1;         
                                                        lastSda     <= sda; 
                                                end 
                                        else 
                                                begin 
                                                        state   <= STATE_IDLE; 
                                                end 
                                end 
                                STATE_DATA_LOW   : begin //5 
                                        if   (trace != STATE_HALT )  
                                                begin 
                                                        if   (sda)  
                                                                begin 
                                                                        state   <= STATE_DATA_HIGH; 
                                                                end 
                                                        else 
                                                                begin 
                                                                        state   <= STATE_DATA_LOW; 
                                                                end 
                                                        rw            <= 1;         
                                                end 
                                        else 
                                                begin 
                                                        state   <= STATE_IDLE; 
                                                end   
                                end 
                                STATE_DATA_HIGH   : begin //6 
                                        if   (trace != STATE_HALT )  
                                                begin 
                                                        if   (sda)  
                                                                begin 
                                                                        count   <= count + 10'd1; 
                                                                        state   <= STATE_DATA_HIGH; 
                                                                end 
                                                        else 
                                                                begin 
                                                                        if   (count < 30)  
                                                                                begin 
                                                                                        data[address]   = 1'b0; 
                                                                                end 
                                                                        else 
                                                                                begin 
                                                                                        data[address]   = 1'b1; 
                                                                                end 
                                                                        if   (address) 
                                                                                begin 
                                                                                        address   = address - 10'd1; 
                                                                                        state   <= STATE_DATA_LOW; 
                                                                                        count   <= 10'd0; 
                                                                                end 
                                                                        else 
                                                                                begin 
                                                                                        //   get all 40 bits 
                                                                                        address   <= 10'd39; 
                                                                                        state   <= STATE_STOP; 
                                                                                        outdata[39:0]   <= data[39:0]; 
                                                                                end 
                                                                end 
                                                        rw            <= 1;         
                                                end 
                                        else 
                                                begin 
                                                        state   <= STATE_IDLE; 
                                                end 
                                end 
                                STATE_STOP   : begin //7 
                                        if   (trace != STATE_HALT )  
                                        begin 
                                                if   (sda)  
                                                        begin 
                                                                state   <= STATE_IDLE; 
                                                        end 
                                                else 
                                                        begin 
                                                                state   <= STATE_STOP; 
                                                        end 
                                                rw            <= 1;         
                                                end 
                                        else 
                                         begin 
                                                state   <= STATE_IDLE;                
                                         end 
                                end 
                        endcase 
                end 
end 
always@(posedge clk) 
begin 
        if   (!reset) 
                begin 
                        trace   <= STATE_IDLE; 
                        countTrace      <= 10'd0; 
                end 
        else 
                begin                
                        case   (trace)  
                                STATE_IDLE,   STATE_START,STATE_RELEASE : begin //0, 1, 2 
                                                trace   <= state; 
                                                countTrace      <= 10'd0;                                  
                                end                           
                                STATE_RESPONSE_LOW,STATE_RESPONSE_HIGH,STATE_DATA_LOW,STATE_DATA_HIGH,STATE_STOP   : begin //3, 4, 5, 6, 7 
                                        if   (state == trace) 
                                                if   (countTrace > 85 ) //85us - max time for Responce period 
                                                        begin 
                                                                trace   <= STATE_HALT; 
                                                                countTrace      <= 10'd0; 
                                                        end 
                                                else 
                                                        begin                                
                                                                countTrace   <= countTrace + 10'd1; 
                                                        end 
                                        else 
                                                begin 
                                                        trace   <= state; 
                                                        countTrace      <= 10'd0; 
                                                end 
                                end 
                                STATE_HALT   : begin //8 
                                        if   (countTrace == DELAY_HALT) 
                                                begin 
                                                        trace   <= STATE_IDLE; 
                                                        countTrace      <= 10'd0;                                  
                                                end 
                                        else 
                                                begin 
                                                        countTrace   <= countTrace + 10'd1; 
                                                end 
                                end 
                        endcase 
                end           
end 
endmodule | 
| 
module CLK_1KHZ( 
                input   clk_in, 
                output   reg clk_out 
        ); 
        reg   [14:0] clk_count;  
        //   initial 
        initial 
        begin 
                clk_count   = 0; 
                clk_out   = 0; 
        end   
        //   clock counts 
        always   @ (posedge clk_in) 
        begin    
                clk_count   = clk_count + 1'b1; 
                if(clk_count==25000)   //50Mhz 
                begin 
                        clk_count   = 0;   
                        clk_out   = ~clk_out; 
                end 
        end 
endmodule | 
| 
module CLK_1MHZ( 
                input   clk_in, 
                output   reg clk_out 
        ); 
        reg   [4:0] clk_count;  
        //   initial 
        initial 
        begin 
                clk_count   = 0; 
                clk_out   = 0; 
        end   
        //   clock counts 
        always   @ (posedge clk_in) 
        begin    
                clk_count   = clk_count + 1'b1; 
                if(clk_count==25)   //50Mhz 
                begin 
                        clk_count   = 0;   
                        clk_out   = ~clk_out; 
                end 
        end 
endmodule | 
| 
module CLK_1MHZ( 
                input   clk_in, 
                output   reg clk_out 
        ); 
        reg   [4:0] clk_count;  
        //   initial 
        initial 
        begin 
                clk_count   = 0; 
                clk_out   = 0; 
        end   
        //   clock counts 
        always   @ (posedge clk_in) 
        begin    
                clk_count   = clk_count + 1'b1; 
                if(clk_count==25)   //50Mhz 
                begin 
                        clk_count   = 0;   
                        clk_out   = ~clk_out; 
                end 
        end 
endmodule | 
| 
/* 
        Bin2BCD:   Convert binary to 4 BCDs         
        ref:   http://alex9ufoexploer.blogspot.com/2013/12/binary-to-bcd-conversion-algorithm.html 
*/ 
module BIN2BCD( 
        input   [15:0] binary, 
        output   reg [3:0] BCD3, 
        output   reg [3:0] BCD2, 
        output   reg [3:0] BCD1, 
        output   reg [3:0] BCD0 
        ); 
        integer   i; 
        always@(binary) 
        begin 
                BCD3   = 4'd0; 
                BCD2   = 4'd0; 
                BCD1   = 4'd0; 
                BCD0   = 4'd0; 
                for   (i=14; i>=0; i=i-1) 
                begin 
                        if   (BCD3>=4'd5) 
                                BCD3   = BCD3 + 4'd3; 
                        if   (BCD2>=4'd5) 
                                BCD2   = BCD2 + 4'd3; 
                        if   (BCD1>=4'd5) 
                                BCD1   = BCD1 + 4'd3; 
                        if   (BCD0>=4'd5) 
                                BCD0   = BCD0 + 4'd3; 
                        BCD3   = BCD3 << 1; 
                        BCD3[0]   = BCD2[3]; 
                        BCD2   = BCD2 << 1; 
                        BCD2[0]   = BCD1[3]; 
                        BCD1   = BCD1 << 1; 
                        BCD1[0]   = BCD0[3]; 
                        BCD0   = BCD0 << 1; 
                        BCD0[0]   = binary[i]; 
                end 
        end 
endmodule | 
 
沒有留言:
張貼留言