2016-04-29 2 views
0

J'ai le code suivant pour essayer de lire l'ADT7420 sur ma carte FPGA nexys4DDR. Je n'arrive pas à le faire fonctionner. Tous les fils se rallument et je ne trouve pas le problème. Où vais-je mal?ADT7420 Lecture de la température -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

C'est l'un de ces cas où vous pourriez obtenir une meilleure réponse sur http://electronics.stackexchange.com/ – wilcroft

Répondre

0

On dirait que vous utilisez SDI comme un tri-état, mais un tri-état doit être de type wire; pas un reg. Attribuer délibérément x ou z à un type reg est un indicateur que la valeur dans ce scénario ne tient pas compte, permettant au synthétiseur de générer le résultat net à toute valeur (généralement basée sur l'optimisation logique). Il est toujours conduit, pas tri-déclaré.

Un tri-état doit être un type wire, et les missions doivent être simples:

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 

Pour votre information:
La plupart des directives de codage RTL ne préconisez jamais attribuer un type reg-x ou z.
Il semble que vous synthétisiez directement votre code RTL sans simuler. Il est recommandé de simuler avant de synthétiser. Il est plus facile de déboguer les problèmes de logique dans la simulation.
Vous pouvez avoir d'autres problèmes avec votre code, mais cela devrait suffire à vous diriger dans la bonne direction.

+0

Quelle est la meilleure façon de simuler un inout? Est-ce que je veux en faire une sortie uniquement pour la simulation? –

+0

Le port doit être 'inout'. Quelque chose devrait le conduire quand RTL l'échantillonnera; comme un autre module ou le banc d'essai. – Greg