2016-04-29 30 views
0

我有以下代碼嘗試在我的nexys4DDR FPGA電路板上讀取ADT7420。我似乎無法得到它的工作。所有的LED都被打開了,我找不到問題。我哪裏錯了?ADT7420溫度讀數-Verilog

reg [5:0] SD_COUNTER = 6'd0;//counter used for the sending all the signals  to the temperature sensor 
    reg [31:0] count= 32'h00000000;//counter used for slow clock 
//since we are using SDA as inout we cannot use it inside the always block. I created a temp. reg SDI 
    reg SDI;//register used for sending signals to temperature sensor inside the always block 
    reg SCLK; // clock used inside the always block which is equated to the SCL at the end. 
    reg dp = 1'b1;//decimal point for 7 segment display 
    reg [18:0] Counter; // temp. counter for multiplexing seven segment display 
// these are the registers used for 7 segment display 
    reg [3:0] first; 
reg [3:0] second; 
reg [3:0] third; 
reg [3:0] fourth; 
reg [3:0] fifth; 
reg [3:0] sixth; 
reg [3:0] seg; 
reg [15:0] led_temp = 16'b0000000000000000;//temp reg used in always block to asssign sda values 
reg CLK = 0;//slow clock 
// code for slow clock(200k) 
always @ (posedge clk) 
begin 
    count <= count + 1; 
    Counter <= Counter + 1; 

if (count == 32'h00030D40)//200k in hex 
    begin 
     count <= 0; 
     CLK <= ~CLK; 
    end 
else 
    count <= count + 1; 
end 
always @ (posedge CLK) //always on 200k clock 
begin 
    if (SD_COUNTER == 49) 
     SD_COUNTER <= 1; 
    else 
     SD_COUNTER <= SD_COUNTER + 1; 
end 

always @ (posedge CLK) 
begin 

    case (SD_COUNTER) 
     6'd0 : begin SDI <= 1; SCLK <= 1; end //initial condition 
     //START signal for I2C protocol 
     6'd1 : SDI <= 0; 
     6'd2 : SCLK <= 1; 
//  SLAVE ADDRESS 0x4B 
     6'd3 : SDI <= 1; 
     6'd4 : SDI <= 0; 
     6'd5 : SDI <= 0; 
     6'd6 : SDI <= 1; 
     6'd7 : SDI <= 0; 
     6'd8 : SDI <= 1; 
     6'd9 : SDI <= 1; 
     6'd10 : SDI <= 0; //write (R/W =1'b0 bit) 
     6'd11 : SDI <= 1'bz; //ACK (acknowledge from slave) 
     // Address of register inside the temperature sensor (0x00, temperature register) 
     6'd12 : SDI <= 0; 
     6'd13 : SDI <= 0; 
     6'd14 : SDI <= 0; 
     6'd15 : SDI <= 0; 
     6'd16 : SDI <= 0; 
     6'd17 : SDI <= 0; 
     6'd18 : SDI <= 0; 
     6'd19 : SDI <= 0; 
     6'd20 : SDI <= 1'bz; //acknowledge from the slave 
     //Re-Start signal for I2C protocol 
     6'd21 : begin SDI <= 1; SCLK <= 1;end 
     6'd22 : SDI <= 0; 
     6'd23 : SCLK <= 1; 
     //Slave Address 0x4B 

     6'd24 : SDI <= 1; 
     6'd25 : SDI <= 0; 
     6'd26 : SDI <= 0; 
     6'd27 : SDI <= 1; 
     6'd28 : SDI <= 0; 
     6'd29 : SDI <= 1; 
     6'd30 : SDI <= 1; 
     6'd31 : SDI <= 1;//read (R/W=1'b1 bit)(read from the temp. sensor) 
     6'd32 : SDI <= 1'bz;//acknowledge from the slave 
//we are storing in the values in a temporary led register, so that we can see the values on the leds. 
     //Reading and storing the temperature on led_temp(MSB) 
     6'd33 : led_temp[15] <= SDI; 
     6'd34 : led_temp[14] <= SDI; 
     6'd35 : led_temp[13] <= SDI; 
     6'd36 : led_temp[12] <= SDI; 
     6'd37 : led_temp[11] <= SDI; 
     6'd38 : led_temp[10] <= SDI; 
     6'd39 : led_temp[9] <= SDI; 
     6'd40 : led_temp[8] <= SDI; 
     6'd41 : SDI <= 1'bz; // acknowledge from the slave 

     //Reading and storing the temperature on led_temp(LSB) 
     6'd42 : led_temp[7] <= SDI; 
     6'd43 : led_temp[6] <= SDI; 
     6'd44 : led_temp[5] <= SDI; 
     6'd45 : led_temp[4] <= SDI; 
     6'd46 : led_temp[3] <= SDI; 
     6'd47 : led_temp[2] <= SDI; 
     6'd48 : led_temp[1] <= SDI; 
     6'd49 : led_temp[0] <= SDI; 
     6'd50 : SDI  <= 1'b1; //acknowledge from the master 

     //STOP signal for I2C protocol 
     6'd51 : begin SDI <= 1'b0; SCLK <= 1'b1; end 
     6'd52 : SDI <= 1'b1; 
     endcase 

end 
//assigning led_temp to led 
assign led = led_temp; 
//assigning the SCL(I2C clock) to either slow clock(200k) or SCLK. 
assign SCL = ((SD_COUNTER >= 4) & (SD_COUNTER <= 20) | ((SD_COUNTER >= 25) & (SD_COUNTER <= 49))) ? ~CLK : SCLK; 
//assignin SDA(I2C Serial data) to SDI 
assign SDA = SDI; 
+0

這是您可能通過http://electronics.stackexchange.com/ – wilcroft

回答

0

看起來像您使用SDI作爲三態,然而,三態必須是wire類型;不是reg。故意將xz分配給reg類型是一種指示器,在此場景下的值是無所謂,允許合成器將產生的網絡轉換爲任何值(通常基於邏輯優化)。它仍然是驅動,而不是三態。

三態應該是一個wire類型,作業應該是簡單的:

wire SDI; 
reg SDI_drv_en, SDI_drv_val; 
always @(posedge clk) begin 
    // ... assign SDI_drv_en & SDI_drv_val to known values (1 or 0), plus other logic ... 
end 
assign SDI = SDI_drv_en ? SDI_drv_val : 1'bz; // Simple tri-state driver 

FYI:
大多數RTL編碼指南建議從未分配reg類型xz
這聽起來像你直接綜合你的RTL代碼而不模擬。建議在合成之前進行模擬。在仿真中調試邏輯問題更容易。
您的代碼可能存在其他問題,但這應該足以讓您朝正確的方向發展。

+0

獲得更好迴應的其中一種情況。模擬inout的最佳方法是什麼?我是否希望僅將它作爲模擬的輸出? –

+0

該端口應該是'inout'。 RTL對其進行採樣時應該推動它;如另一個模塊或測試臺。 – Greg