FpgaI2c

概要

  • Nexys 4 付属のI2C温度計の SDA, SCL 信号線を直接スイッチで ON/OFFしながら、温度計を操作してみます。チャタリング防止や LED 表示などのため、ちょっと verilog で回路を作ります。
  • Nexys 4 付属の温度計, Analog Devices の ADT7420
    • 詳しい情報は以下の pdf に載っています。
    • ADT7420 をNexys 4 で使うとき、
      • Vivadoのxdcファイルの場合は、sclの PACKAGE_PIN は "F16", sdaの PACKAGE_PINは "G16" を指定します。
        ##Temperature Sensor
        ##Bank = 15, Pin name = IO_L14N_T2_SRCC_15,					Sch name = TMP_SCL
        set_property PACKAGE_PIN F16 [get_ports scl]					
        	set_property IOSTANDARD LVCMOS33 [get_ports scl]
        ##Bank = 15, Pin name = IO_L13N_T2_MRCC_15,					Sch name = TMP_SDA
        set_property PACKAGE_PIN G16 [get_ports sda]					
        	set_property IOSTANDARD LVCMOS33 [get_ports sda]
  • ISEのUCFの場合は、sclの LOCは "F16", sdaの LOCは "G16" を指定します。 (Nexys4のマニュアルのpage 22, 12 Temperature Sensor で確認してください)
    NET "scl"			LOC = "F16"	| IOSTANDARD = "LVCMOS33";		#Bank = 15, Pin name = IO_L14N_T2_SRCC_15,					Sch name = TMP_SCL
    NET "sda"			LOC = "G16"	| IOSTANDARD = "LVCMOS33";		#Bank = 15, Pin name = IO_L13N_T2_MRCC_15,					Sch name = TMP_SDA
  • ADT7420 の(slave)device addressは、0x4b (=1001011) です。
  • 温度データを取り出すには、以下の手順を実行します。
    • Master がStart 信号を送信。... scl=1, sda=1の状態から、scl=1, sda=0 の状態にして、その後、scl=0, sda=0 とする。
    • これ以降、通信を終了するまで、Master またはdeviceが sda に high(=Z=1)または low(=0)を設定し、その状態で、Master が sclを 0->1->0 に変化することを繰り返す。
    • Master がdevice(ADT7420)のアドレス(0x4b)と、Masterからデータが送信されることを表す 0 (レジスタ番号書き込み)を送信。
    • device が ack 信号(成功していれば、0)を出力。 Master側ではこのとき、 sda 端子をZ状態(=1)として、入力を待つ。
    • Master がレジスタを表す 8bitのデータ(0000 0000)を出力。
    • device が ack 信号 0 を出力
    • Master がrestart 信号を送信(start と同じ)
    • Master が device address (0x4b)と、入力を表す 1を出力。
    • device が ack 信号 0 を出力
    • device が 最初の 8 bit を出力... この時のbit 列を Master 側で入力。
    • Master が ack 0 を出力。
    • device が次の8 bit を出力 ... この時の bit 列を Master 側で入力。
    • Master が nack 1 を出力。
    • 通信終了手順を行う。 ... sclを 1 にして、その間に sdaを 0から 1 にする。

回路の概要

  • sw[7:0]と up button, left button, center button, right button をチャタリング防止回路に通し、その出力をswx[7:0], BUx, BLx, BCx, BRx とします。
  • sw[0]をチャタリング防止回路を通して(swx[o]), sda に接続します。
  • center button をチャタリング防止回路を通して(BCx), sclに接続します。
  • down button をリセット信号とします。
  • sda を led[8] に接続します。scl が 0->1 に変化するたびに、これをシフトして、過去8回のsda の High/Low の遷移を led[15:8] に表示します。 これを実現するために、レジスタ data[7:0] を使っています。
  • 1つのポートで入出力を行う為、scl, sda は verilog の inout 型を使います。
  • data[7:0]の値を16進法4桁でLEDマトリックスの左側4個に出力する回路に接続します。
  • sw[7:0]をled[7:0]に接続します。
  • sw[7:0]を16進法4桁でLEDマトリックスの右側4個に出力する回路に接続します。
  • 回路図
    • i2c-1-circuit.jpg

Vivado または ISEで以下の verilog を入力

  • verilog
    • top.v
      module top(sSegAnode, sSegCathode, sw, led, cled1, cled2, 
                         bu, bd, bl, br, bc, scl, sda, bclck );
        output [7:0] sSegAnode;
        output [7:0] sSegCathode;
        output [15:0] led;     // led[8] ... if sda is sending, corresponding to the last sended sda, else corresponding to the last received sda
                              //               it is shifted to left when a positive edge of scl is detected.
      		         //  led[0] corresponding to sw[0]
      		         //  led[1] corresponding to sw[1]
      			 //  led[2] corresponsing to center button, bc.
        output [2:0] cled1, cled2;
        input [15:0] sw;       // sw[15:8] ... for setting sda send data, sw[7:0] ... for controlling
                              //    sw[0] ... if 1 sda is high=Z=high impedance, else low;
                  												  
        input bu, bd, bl, br, bc, bclck;    //  bd corresponding to !reset.
                              //  bc corresponding to scl.  scl=sw[0]|bc
      			 //  if posedge bl is detected, sw is shown in hex in the 7seg led array.
        
        inout scl, sda;
        wire BNx, BWx, BEx, BCx;
        wire [7:0] swx;
        wire reset;
        wire sclRw, sdaRw; // write=1, read=0;
        reg [7:0] data;
        assign led[15:8]=data;
        assign led[7:0]=swx;
        assign reset=~bd;
        assign scl=BCx?1'bz:1'b0;
        assign cled1[2]=scl;
        assign sda=(swx[0])?1'bz:1'b0;
        assign cled2[2]=sda;
        always @(posedge scl, negedge reset) begin
          if(!reset) data<=0;
      	 else
          data<={data[6:0],sda};
        end
          
        chattering #(12) chattering0(.clk(bclck), .reset(reset), 
                   .in({bu,bl,br,bc,sw[7:0]}), .out({BNx,  BWx, BEx, BCx,swx}));
      //  assign BNx=BN;
      //  assign BWx=BW;
      //  assign BEx=BE;
      //  assign BCx=BC;
        sSegArray sSegArray0(.clk(bclck), .reset(reset), 
                  .load(1), .d({data,swx}), .anode(sSegAnode), .cathode(sSegCathode));
        
      endmodule
  • chattering.v
    module chattering(clk, reset, in, out
    );
    parameter N=1;
    input clk, reset;
    input [N-1:0]in;
    output [N-1:0]out;
    reg [N-1:0]out;
    reg [21:0] count;
    
    always @(posedge clk or negedge reset)
    if(!reset) count <=0;
    else count <= count +1;
    
    always @(posedge clk)
    if(count==0) out <= in;
    
    endmodule
  • sSegArray?.v
    module sSegArray(
        clk,reset,load,d, 
    	 anode, cathode
        ); 
    parameter N=32;
    input clk,reset,load;
    input [N-1:0] d; 
    output [7:0] anode;
    output [7:0] cathode;
    reg [7:0] anode;
    reg [7:0] cathode;
    reg [31:0] q;
    
    wire [2:0] selectedSeg;
    wire [7:0] wOneSeg;
    reg segClk;
    
    counter #(8) waitOneSeg(.clk(clk), .reset(reset), .load(0), .inc(1), .d(16'h0000), .q(wOneSeg));
    
    //assign segClk= (wOneSeg==0)? ~segClk: segClk;
    always @(posedge clk, negedge reset) begin
      if(!reset) segClk<=0;
      else
      if (wOneSeg==0) segClk<=~segClk; 
    end
    
    counter #(3) selector(.clk(segClk),.reset(reset),.load(0), .inc(1), .d(4'h0), .q(selectedSeg));
    //counter #(3) selector(.clk(clk), .reset(reset), .load(0), .inc(1), .d(4'h0), .q(selectedSeg));
     
    always @(posedge clk, negedge reset)
    begin
      if(!reset) anode=8'hFE;   // note!  anode is connected by pnp transistor.  
      else                      // in order to active one 7seg, low should be setted to the 7seg. 
       case (selectedSeg)
    	   3'b000: anode=8'hFE;
    		3'b001: anode=8'hFD;
    		3'b010: anode=8'hFB;
    		3'b011: anode=8'hF7;
    		3'b100: anode=8'hEF;
    		3'b101: anode=8'hDF;
    		3'b110: anode=8'hBF;
    		3'b111: anode=8'h7F;
    	endcase
    end
    
    reg [3:0] selectedVal;
    
    always @(posedge clk, negedge reset)
    begin
      if(!reset) cathode=8'h03;                   // note! when one segment of the cathode is low,
      else                                        //  and its anode is low, the segment glow.
      case (selectedVal)                         //          ca
        4'b0000: cathode=8'h03;   //8'hfc; 0              ------
        4'b0001: cathode=8'h9f;   //8'h60; 1              /     /
        4'b0010: cathode=8'h25;   //8'hda; 2              /cf   / cb 
        4'b0011: cathode=8'h0d;   //8'hf2; 3              /     /
        4'b0100: cathode=8'h99;   //8'h66; 4               -----
        4'b0101: cathode=8'h49;   //8'hb6; 5              /  cg  /
        4'b0110: cathode=8'h41;   //8'hbe; 6              /ce    / cc
        4'b0111: cathode=8'h1f;   //8'he0; 7              /      /
        4'b1000: cathode=8'h01;   //8'hfe; 8               ------     . ch
        4'b1001: cathode=8'h09;   //8'hf6; 9                  cd
        4'b1010: cathode=8'h11;   //8'hee; A
        4'b1011: cathode=8'hc1;   //8'h3e; B
        4'b1100: cathode=8'h63;   //8'h9c; C
        4'b1101: cathode=8'h85;   //8'h7c; D
        4'b1110: cathode=8'h61;   //8'h9e; E
        4'b1111: cathode=8'h71;   //8'h8e; F
       endcase
    end
    
    always @(posedge clk, negedge reset)
    begin
      if(!reset) selectedVal=q[3:0];
      else
       case (selectedSeg)
    	  3'b000: selectedVal=q[3:0];
    	  3'b001: selectedVal=q[7:4];
    	  3'b010: selectedVal=q[11:8];
    	  3'b011: selectedVal=q[15:12];
    	  3'b100: selectedVal=q[19:16];
    	  3'b101: selectedVal=q[23:20];
    	  3'b110: selectedVal=q[27:24];
    	  3'b111: selectedVal=q[31:28];
    	endcase
    end
    
    always @(posedge clk, negedge reset)
    begin
      if(!reset) q=0;
      else
      if(load) q=d;
    end
    
    endmodule
  • counter.v
    module counter(clk, reset, load, inc, d, q );
    parameter N=16;
    
    input clk, reset, load, inc;
    input [N-1:0] d; 
    output [N-1:0] q;
    reg [N-1:0] q;
    
    always @(posedge clk or negedge reset)
    if(!reset) q <=0;
    else if(load) q<=d; 
    else if(inc) q<=q+1;
    endmodule
  • top.xdc (Vivadoの場合)
    ## Clock signal
    ##Bank = 35, Pin name = IO_L12P_T1_MRCC_35,					Sch name = CLK100MHZ
    set_property PACKAGE_PIN E3 [get_ports bclck]	
    	set_property IOSTANDARD LVCMOS33 [get_ports bclck]
    #	create_clock -add -name sys_clk_pin  -period 10.00 -waveform {0 5} [get_ports bclk]
     
    ## Switches
    ##Bank = 34, Pin name = IO_L21P_T3_DQS_34,					Sch name = SW0
    set_property PACKAGE_PIN U9 [get_ports {sw[0]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sw[0]}]
    ##Bank = 34, Pin name = IO_25_34,							Sch name = SW1
    set_property PACKAGE_PIN U8 [get_ports {sw[1]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sw[1]}]
    ##Bank = 34, Pin name = IO_L23P_T3_34,						Sch name = SW2
    set_property PACKAGE_PIN R7 [get_ports {sw[2]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sw[2]}]
    ##Bank = 34, Pin name = IO_L19P_T3_34,						Sch name = SW3
    set_property PACKAGE_PIN R6 [get_ports {sw[3]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sw[3]}]
    ##Bank = 34, Pin name = IO_L19N_T3_VREF_34,					Sch name = SW4
    set_property PACKAGE_PIN R5 [get_ports {sw[4]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sw[4]}]
    ##Bank = 34, Pin name = IO_L20P_T3_34,						Sch name = SW5
    set_property PACKAGE_PIN V7 [get_ports {sw[5]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sw[5]}]
    ##Bank = 34, Pin name = IO_L20N_T3_34,						Sch name = SW6
    set_property PACKAGE_PIN V6 [get_ports {sw[6]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sw[6]}]
    ##Bank = 34, Pin name = IO_L10P_T1_34,						Sch name = SW7
    set_property PACKAGE_PIN V5 [get_ports {sw[7]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sw[7]}]
    ##Bank = 34, Pin name = IO_L8P_T1-34,						Sch name = SW8
    set_property PACKAGE_PIN U4 [get_ports {sw[8]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sw[8]}]
    ##Bank = 34, Pin name = IO_L9N_T1_DQS_34,					Sch name = SW9
    set_property PACKAGE_PIN V2 [get_ports {sw[9]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sw[9]}]
    ##Bank = 34, Pin name = IO_L9P_T1_DQS_34,					Sch name = SW10
    set_property PACKAGE_PIN U2 [get_ports {sw[10]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sw[10]}]
    ##Bank = 34, Pin name = IO_L11N_T1_MRCC_34,					Sch name = SW11
    set_property PACKAGE_PIN T3 [get_ports {sw[11]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sw[11]}]
    ##Bank = 34, Pin name = IO_L17N_T2_34,						Sch name = SW12
    set_property PACKAGE_PIN T1 [get_ports {sw[12]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sw[12]}]
    ##Bank = 34, Pin name = IO_L11P_T1_SRCC_34,					Sch name = SW13
    set_property PACKAGE_PIN R3 [get_ports {sw[13]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sw[13]}]
    ##Bank = 34, Pin name = IO_L14N_T2_SRCC_34,					Sch name = SW14
    set_property PACKAGE_PIN P3 [get_ports {sw[14]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sw[14]}]
    ##Bank = 34, Pin name = IO_L14P_T2_SRCC_34,					Sch name = SW15
    set_property PACKAGE_PIN P4 [get_ports {sw[15]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sw[15]}]
    
    ## LEDs
    ##Bank = 34, Pin name = IO_L24N_T3_34,						Sch name = LED0
    set_property PACKAGE_PIN T8 [get_ports {led[0]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
    ##Bank = 34, Pin name = IO_L21N_T3_DQS_34,					Sch name = LED1
    set_property PACKAGE_PIN V9 [get_ports {led[1]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
    ##Bank = 34, Pin name = IO_L24P_T3_34,						Sch name = LED2
    set_property PACKAGE_PIN R8 [get_ports {led[2]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
    ##Bank = 34, Pin name = IO_L23N_T3_34,						Sch name = LED3
    set_property PACKAGE_PIN T6 [get_ports {led[3]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
    ##Bank = 34, Pin name = IO_L12P_T1_MRCC_34,					Sch name = LED4
    set_property PACKAGE_PIN T5 [get_ports {led[4]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {led[4]}]
    ##Bank = 34, Pin name = IO_L12N_T1_MRCC_34,					Sch	name = LED5
    set_property PACKAGE_PIN T4 [get_ports {led[5]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {led[5]}]
    ##Bank = 34, Pin name = IO_L22P_T3_34,						Sch name = LED6
    set_property PACKAGE_PIN U7 [get_ports {led[6]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {led[6]}]
    ##Bank = 34, Pin name = IO_L22N_T3_34,						Sch name = LED7
    set_property PACKAGE_PIN U6 [get_ports {led[7]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {led[7]}]
    ##Bank = 34, Pin name = IO_L10N_T1_34,						Sch name = LED8
    set_property PACKAGE_PIN V4 [get_ports {led[8]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {led[8]}]
    ##Bank = 34, Pin name = IO_L8N_T1_34,						Sch name = LED9
    set_property PACKAGE_PIN U3 [get_ports {led[9]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {led[9]}]
    ##Bank = 34, Pin name = IO_L7N_T1_34,						Sch name = LED10
    set_property PACKAGE_PIN V1 [get_ports {led[10]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {led[10]}]
    ##Bank = 34, Pin name = IO_L17P_T2_34,						Sch name = LED11
    set_property PACKAGE_PIN R1 [get_ports {led[11]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {led[11]}]
    ##Bank = 34, Pin name = IO_L13N_T2_MRCC_34,					Sch name = LED12
    set_property PACKAGE_PIN P5 [get_ports {led[12]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {led[12]}]
    ##Bank = 34, Pin name = IO_L7P_T1_34,						Sch name = LED13
    set_property PACKAGE_PIN U1 [get_ports {led[13]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {led[13]}]
    ##Bank = 34, Pin name = IO_L15N_T2_DQS_34,					Sch name = LED14
    set_property PACKAGE_PIN R2 [get_ports {led[14]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {led[14]}]
    ##Bank = 34, Pin name = IO_L15P_T2_DQS_34,					Sch name = LED15
    set_property PACKAGE_PIN P2 [get_ports {led[15]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {led[15]}]
    
    ##Bank = 34, Pin name = IO_L5P_T0_34,						Sch name = LED16_R
    set_property PACKAGE_PIN K5 [get_ports {cled1[2]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {cled1[2]}]
    ##Bank = 15, Pin name = IO_L5P_T0_AD9P_15,					Sch name = LED16_G
    set_property PACKAGE_PIN F13 [get_ports {cled1[1]}]				
    	set_property IOSTANDARD LVCMOS33 [get_ports {cled1[1]}]
    ##Bank = 35, Pin name = IO_L19N_T3_VREF_35,					Sch name = LED16_B
    set_property PACKAGE_PIN F6 [get_ports {cled1[0]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {cled1[0]}]
    ##Bank = 34, Pin name = IO_0_34,								Sch name = LED17_R
    set_property PACKAGE_PIN K6 [get_ports {cled2[2]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {cled2[2]}]
    ##Bank = 35, Pin name = IO_24P_T3_35,						Sch name =  LED17_G
    set_property PACKAGE_PIN H6 [get_ports {cled2[1]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {cled2[1]}]
    ##Bank = CONFIG, Pin name = IO_L3N_T0_DQS_EMCCLK_14,			Sch name = LED17_B
    set_property PACKAGE_PIN L16 [get_ports {cled2[0]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {cled2[0]}]
    
    ##7 segment display
    ##Bank = 34, Pin name = IO_L2N_T0_34,						Sch name = CA
    set_property PACKAGE_PIN L3 [get_ports {sSegCathode[7]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sSegCathode[7]}]
    ##Bank = 34, Pin name = IO_L3N_T0_DQS_34,					Sch name = CB
    set_property PACKAGE_PIN N1 [get_ports {sSegCathode[6]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sSegCathode[6]}]
    ##Bank = 34, Pin name = IO_L6N_T0_VREF_34,					Sch name = CC
    set_property PACKAGE_PIN L5 [get_ports {sSegCathode[5]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sSegCathode[5]}]
    ##Bank = 34, Pin name = IO_L5N_T0_34,						Sch name = CD
    set_property PACKAGE_PIN L4 [get_ports {sSegCathode[4]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sSegCathode[4]}]
    ##Bank = 34, Pin name = IO_L2P_T0_34,						Sch name = CE
    set_property PACKAGE_PIN K3 [get_ports {sSegCathode[3]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sSegCathode[3]}]
    ##Bank = 34, Pin name = IO_L4N_T0_34,						Sch name = CF
    set_property PACKAGE_PIN M2 [get_ports {sSegCathode[2]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sSegCathode[2]}]
    ##Bank = 34, Pin name = IO_L6P_T0_34,						Sch name = CG
    set_property PACKAGE_PIN L6 [get_ports {sSegCathode[1]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sSegCathode[1]}]
    
    ##Bank = 34, Pin name = IO_L16P_T2_34,						Sch name = DP
    set_property PACKAGE_PIN M4 [get_ports sSegCathode[0]]							
    	set_property IOSTANDARD LVCMOS33 [get_ports sSegCathode[0]]
    
    
    ##Bank = 34, Pin name = IO_L18N_T2_34,						Sch name = AN0
    set_property PACKAGE_PIN N6 [get_ports {sSegAnode[0]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sSegAnode[0]}]
    ##Bank = 34, Pin name = IO_L18P_T2_34,						Sch name = AN1
    set_property PACKAGE_PIN M6 [get_ports {sSegAnode[1]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sSegAnode[1]}]
    ##Bank = 34, Pin name = IO_L4P_T0_34,						Sch name = AN2
    set_property PACKAGE_PIN M3 [get_ports {sSegAnode[2]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sSegAnode[2]}]
    ##Bank = 34, Pin name = IO_L13_T2_MRCC_34,					Sch name = AN3
    set_property PACKAGE_PIN N5 [get_ports {sSegAnode[3]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sSegAnode[3]}]
    ##Bank = 34, Pin name = IO_L3P_T0_DQS_34,					Sch name = AN4
    set_property PACKAGE_PIN N2 [get_ports {sSegAnode[4]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sSegAnode[4]}]
    ##Bank = 34, Pin name = IO_L16N_T2_34,						Sch name = AN5
    set_property PACKAGE_PIN N4 [get_ports {sSegAnode[5]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sSegAnode[5]}]
    ##Bank = 34, Pin name = IO_L1P_T0_34,						Sch name = AN6
    set_property PACKAGE_PIN L1 [get_ports {sSegAnode[6]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sSegAnode[6]}]
    ##Bank = 34, Pin name = IO_L1N_T034,							Sch name = AN7
    set_property PACKAGE_PIN M1 [get_ports {sSegAnode[7]}]					
    	set_property IOSTANDARD LVCMOS33 [get_ports {sSegAnode[7]}]
    
    ##Buttons
    ##Bank = 15, Pin name = IO_L3P_T0_DQS_AD1P_15,				Sch name = CPU_RESET
    #set_property PACKAGE_PIN C12 [get_ports btnCpuReset]				
    	#set_property IOSTANDARD LVCMOS33 [get_ports btnCpuReset]
    ##Bank = 15, Pin name = IO_L11N_T1_SRCC_15,					Sch name = BTNC
    set_property PACKAGE_PIN E16 [get_ports bc]						
    	set_property IOSTANDARD LVCMOS33 [get_ports bc]
    ##Bank = 15, Pin name = IO_L14P_T2_SRCC_15,					Sch name = BTNU
    set_property PACKAGE_PIN F15 [get_ports bu]						
    	set_property IOSTANDARD LVCMOS33 [get_ports bu]
    ##Bank = CONFIG, Pin name = IO_L15N_T2_DQS_DOUT_CSO_B_14,	Sch name = BTNL
    set_property PACKAGE_PIN T16 [get_ports bl]						
    	set_property IOSTANDARD LVCMOS33 [get_ports bl]
    ##Bank = 14, Pin name = IO_25_14,							Sch name = BTNR
    set_property PACKAGE_PIN R10 [get_ports br]						
    	set_property IOSTANDARD LVCMOS33 [get_ports br]
    ##Bank = 14, Pin name = IO_L21P_T3_DQS_14,					Sch name = BTND
    set_property PACKAGE_PIN V10 [get_ports bd]						
    	set_property IOSTANDARD LVCMOS33 [get_ports bd]
    
    ##Temperature Sensor
    ##Bank = 15, Pin name = IO_L14N_T2_SRCC_15,					Sch name = TMP_SCL
    set_property PACKAGE_PIN F16 [get_ports scl]					
    	set_property IOSTANDARD LVCMOS33 [get_ports scl]
    ##Bank = 15, Pin name = IO_L13N_T2_MRCC_15,					Sch name = TMP_SDA
    set_property PACKAGE_PIN G16 [get_ports sda]					
    	set_property IOSTANDARD LVCMOS33 [get_ports sda]
    ##Bank = 15, Pin name = IO_L1P_T0_AD0P_15,					Sch name = TMP_INT
    #set_property PACKAGE_PIN D14 [get_ports tmpInt]					
    	#set_property IOSTANDARD LVCMOS33 [get_ports tmpInt]
    ##Bank = 15, Pin name = IO_L1N_T0_AD0N_15,					Sch name = TMP_CT
    #set_property PACKAGE_PIN C14 [get_ports tmpCT]						
    	#set_property IOSTANDARD LVCMOS33 [get_ports tmpCT]
    
  • top.ucf (ISEの場合)
    ## Clock signal
    NET "bclck"   LOC = "E3"	| IOSTANDARD = "LVCMOS33";					#Bank = 35, Pin name = IO_L12P_T1_MRCC_35,					Sch name = CLK100MHZ
    #NET "clk" TNM_NET = sys_clk_pin;
    #TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 100 MHz HIGH 50%; 
    
    ## Switches
    NET "sw<0>"			LOC = "U9"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L21P_T3_DQS_34,					Sch name = SW0
    NET "sw<1>"			LOC = "U8"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_25_34,							Sch name = SW1
    NET "sw<2>"			LOC = "R7"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L23P_T3_34,						Sch name = SW2
    NET "sw<3>"			LOC = "R6"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L19P_T3_34,						Sch name = SW3
    NET "sw<4>"			LOC = "R5"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L19N_T3_VREF_34,					Sch name = SW4
    NET "sw<5>"			LOC = "V7"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L20P_T3_34,						Sch name = SW5
    NET "sw<6>"			LOC = "V6"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L20N_T3_34,						Sch name = SW6
    NET "sw<7>"			LOC = "V5"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L10P_T1_34,						Sch name = SW7
    NET "sw<8>"			LOC = "U4"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L8P_T1-34,						Sch name = SW8
    NET "sw<9>"			LOC = "V2"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L9N_T1_DQS_34,					Sch name = SW9
    NET "sw<10>"			LOC = "U2"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L9P_T1_DQS_34,					Sch name = SW10
    NET "sw<11>"			LOC = "T3"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L11N_T1_MRCC_34,					Sch name = SW11
    NET "sw<12>"			LOC = "T1"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L17N_T2_34,						Sch name = SW12
    NET "sw<13>"			LOC = "R3"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L11P_T1_SRCC_34,					Sch name = SW13
    NET "sw<14>"			LOC = "P3"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L14N_T2_SRCC_34,					Sch name = SW14
    NET "sw<15>"			LOC = "P4"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L14P_T2_SRCC_34,					Sch name = SW15
    
    ## LEDs
    NET "led<0>"			LOC = "T8"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L24N_T3_34,						Sch name = LED0
    NET "led<1>"			LOC = "V9"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L21N_T3_DQS_34,					Sch name = LED1
    NET "led<2>"			LOC = "R8"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L24P_T3_34,						Sch name = LED2
    NET "led<3>"			LOC = "T6"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L23N_T3_34,						Sch name = LED3
    NET "led<4>"			LOC = "T5"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L12P_T1_MRCC_34,					Sch name = LED4
    NET "led<5>"			LOC = "T4"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L12N_T1_MRCC_34,					Sch	name = LED5
    NET "led<6>"			LOC = "U7"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L22P_T3_34,						Sch name = LED6
    NET "led<7>"			LOC = "U6"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L22N_T3_34,						Sch name = LED7
    NET "led<8>"			LOC = "V4"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L10N_T1_34,						Sch name = LED8
    NET "led<9>"			LOC = "U3"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L8N_T1_34,						Sch name = LED9
    NET "led<10>"			LOC = "V1"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L7N_T1_34,						Sch name = LED10
    NET "led<11>"			LOC = "R1"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L17P_T2_34,						Sch name = LED11
    NET "led<12>"			LOC = "P5"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L13N_T2_MRCC_34,					Sch name = LED12
    NET "led<13>"			LOC = "U1"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L7P_T1_34,						Sch name = LED13
    NET "led<14>"			LOC = "R2"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L15N_T2_DQS_34,					Sch name = LED14
    NET "led<15>"			LOC = "P2"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L15P_T2_DQS_34,					Sch name = LED15
    
    NET "cled1<2>"			LOC = "K5"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L5P_T0_34,						Sch name = LED16_R
    #NET "cled1<1>"		LOC = "F13"	| IOSTANDARD = "LVCMOS33";		#Bank = 15, Pin name = IO_L5P_T0_AD9P_15,					Sch name = LED16_G
    #NET "cled1<0>"		LOC = "F6"	| IOSTANDARD = "LVCMOS33";		#Bank = 35, Pin name = IO_L19N_T3_VREF_35,					Sch name = LED16_B
    NET "cled2<2>"			LOC = "K6"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_0_34,								Sch name = LED17_R
    #NET "cled2<1>"		LOC = "H6"	| IOSTANDARD = "LVCMOS33";		#Bank = 35, Pin name = IO_24P_T3_35,						Sch name =  LED17_G
    #NET "cled2<0>"		LOC = "L16"	| IOSTANDARD = "LVCMOS33";		#Bank = CONFIG, Pin name = IO_L3N_T0_DQS_EMCCLK_14,			Sch name = LED17_B
    
    ## 7 segment display
    NET "sSegCathode<7>"			LOC = "L3"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L2N_T0_34,						Sch name = CA
    NET "sSegCathode<6>"			LOC = "N1"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L3N_T0_DQS_34,					Sch name = CB
    NET "sSegCathode<5>"			LOC = "L5"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L6N_T0_VREF_34,					Sch name = CC
    NET "sSegCathode<4>"			LOC = "L4"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L5N_T0_34,						Sch name = CD
    NET "sSegCathode<3>"			LOC = "K3"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L2P_T0_34,						Sch name = CE
    NET "sSegCathode<2>"			LOC = "M2"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L4N_T0_34,						Sch name = CF
    NET "sSegCathode<1>"			LOC = "L6"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L6P_T0_34,						Sch name = CG
    
    NET "sSegCathode<0>"				LOC = "M4"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L16P_T2_34,						Sch name = DP
    
    NET "sSegAnode<0>"			LOC = "N6"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L18N_T2_34,						Sch name = AN0
    NET "sSegAnode<1>"			LOC = "M6"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L18P_T2_34,						Sch name = AN1
    NET "sSegAnode<2>"			LOC = "M3"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L4P_T0_34,						Sch name = AN2
    NET "sSegAnode<3>"			LOC = "N5"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L13_T2_MRCC_34,					Sch name = AN3
    NET "sSegAnode<4>"			LOC = "N2"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L3P_T0_DQS_34,					Sch name = AN4
    NET "sSegAnode<5>"			LOC = "N4"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L16N_T2_34,						Sch name = AN5
    NET "sSegAnode<6>"			LOC = "L1"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L1P_T0_34,						Sch name = AN6
    NET "sSegAnode<7>"			LOC = "M1"	| IOSTANDARD = "LVCMOS33";		#Bank = 34, Pin name = IO_L1N_T034,							Sch name = AN7
    
    ## Buttons
    #NET "btnCpuReset"		LOC = "C12"	| IOSTANDARD = "LVCMOS33";		#Bank = 15, Pin name = IO_L3P_T0_DQS_AD1P_15,				Sch name = CPU_RESET
    NET "bc"				LOC = "E16"	| IOSTANDARD = "LVCMOS33";		#Bank = 15, Pin name = IO_L11N_T1_SRCC_15,					Sch name = BTNC
    NET "bu"				LOC = "F15"	| IOSTANDARD = "LVCMOS33";		#Bank = 15, Pin name = IO_L14P_T2_SRCC_15,					Sch name = BTNU
    NET "bl"				LOC = "T16"	| IOSTANDARD = "LVCMOS33";		#Bank = CONFIG, Pin name = IO_L15N_T2_DQS_DOUT_CSO_B_14,	Sch name = BTNL
    NET "br"				LOC = "R10"	| IOSTANDARD = "LVCMOS33";		#Bank = 14, Pin name = IO_25_14,							Sch name = BTNR
    NET "bd"				LOC = "V10"	| IOSTANDARD = "LVCMOS33";		#Bank = 14, Pin name = IO_L21P_T3_DQS_14,					Sch name = BTND
     
    ## Temperature Sensor
    #NET "tmpSCL"			LOC = "F16"	| IOSTANDARD = "LVCMOS33";		#Bank = 15, Pin name = IO_L14N_T2_SRCC_15,					Sch name = TMP_SCL
    #NET "tmpSDA"			LOC = "G16"	| IOSTANDARD = "LVCMOS33";		#Bank = 15, Pin name = IO_L13N_T2_MRCC_15,					Sch name = TMP_SDA
    #NET "tmpInt"			LOC = "D14"	| IOSTANDARD = "LVCMOS33";		#Bank = 15, Pin name = IO_L1P_T0_AD0P_15,					Sch name = TMP_INT
    #NET "tmpCT"			LOC = "C14"	| IOSTANDARD = "LVCMOS33";		#Bank = 15, Pin name = IO_L1N_T0_AD0N_15,					Sch name = TMP_CT
    NET "scl"			LOC = "F16"	| IOSTANDARD = "LVCMOS33";		#Bank = 15, Pin name = IO_L14N_T2_SRCC_15,					Sch name = TMP_SCL
    NET "sda"			LOC = "G16"	| IOSTANDARD = "LVCMOS33";		#Bank = 15, Pin name = IO_L13N_T2_MRCC_15,					Sch name = TMP_SDA
    #NET "tmpInt"			LOC = "D14"	| IOSTANDARD = "LVCMOS33";		#Bank = 15, Pin name = IO_L1P_T0_AD0P_15,					Sch name = TMP_INT
    #NET "tmpCT"			LOC = "C14"	| IOSTANDARD = "LVCMOS33";		#Bank = 15, Pin name = IO_L1N_T0_AD0N_15,					Sch name = TMP_CT
  • ISEの画面の例
    • 入力終了後の状態(上のverilog のコピペで良いです)
      • i2c-1-1.jpg
    • 構文チェック
      • i2c-1-2.jpg

verilog のコンパイルと bit ファイルの作成

  • startup clock を jtag に変更
    • Generate programming file を右クリック, Process Properties を選択
      • i2c-1-3.jpg
    • Process Properties ウィンドウの Startup Options を選択し、FPGA Start-Up Clock をJTAG-Clockに変更し、OKをクリック
      • i2c-1-4.jpg
  • bitファイルの生成
    • Process Window で, Generate programming file をダブルクリック。もしくは、右クリックして、rerun all.
      • i2c-1-6.jpg

Nexys4とパソコンの接続, bit ファイルのダウンロード

  • パソコンとNexys4を接続
    • i2c-1-7-s.jpg
  • bitファイルのダウンロード
    • Process Windowで Configure Target Device をダブルクリック
      • i2c-1-8.jpg
    • Warning ウィンドウで OKをクリック
      • i2c-1-9.jpg
    • ISE IMPACT ウィンドウが表示される。
      • i2c-1-10.jpg
    • ISE iMPACT ウィンドウでBoundary Scan をダブルクリック
      • i2c-1-11.jpg
    • ISE iMPACT の "Right click to Add Device or Initiate JTAG chain" のところで右クリック
      • i2c-1-12.jpg
    • 出てきたダイアログで, Add Xilinx Device を選択
      • i2c-1-13.jpg
    • ダウンロードする bit ファイルを間違えないように選択(過去に保存した bit ファイルが最初に出る場合があります)
      • i2c-1-14.jpg
    • チップのアイコンが表示されるので, そこを右クリックして, 出てきたメニューから "program"を選択。
      • i2c-1-16.jpg
    • Device Programming Properties のウィンドウで OK をクリック
      • i2c-1-17.jpg
    • bit ファイルのダウンロード状況(転送状況)が表示される。
      • i2c-1-18.jpg
    • ダウンロードが終了すると、ボードの7セグメントLEDに"0000 0000"が表示される(スライドスイッチがすべてOffの場合)。
      • i2c-1-19-s.jpg 
        (スライドスイッチ 0 がONになっているので、左端が1になっています。)

実行

  • 手順詳細
    • bitファイルのダウンロード終了時点で、自動的に回路に電源が供給されて、回路が動き始めます。
    • sw[0](sda) を1にします。center button (scl)は、押していない時に0, 押したときに 1 になります。
    • sclを1 にして、sda を 1->0にします。(center button を1にして、その状態のまま, sw[0]を1から0にする)
    • sclを0にします。(center buttonを離す)
    • sdaを1にして、sclを 0->1->0にします。(sw[0]を1にして、center button を押して離す)... これで device の7bit のアドレスのMSBの1bit がデバイス側に送られます。
    • sdaを0にして、sclを 0->1->0にします。
    • sdaを0のまま、sclを 0->1->0にします。
    • sdaを1にして、sclを 0->1->0にします。
    • sdaを0にして、sclを 0->1->0にします。
    • sdaを1にして、sclを 0->1->0にします。
    • sdaを1のまま、sclを 0->1->0にします。ここまでが、ADT7420のアドレス, 0x4bの出力です。
    • sdaを0にして、sclを 0->1->0にします。write (=0)の出力です。
    • sdaを1(Z)にして、sclを0->1->0にします。ADT7420から ack(=0)が出力され、led[8]に表示されるはずです。
    • sdaを0にして、sclを8回、0->1->0にします。 ... register 0の指定です。
    • sdaを1(Z)にして、sclを0->1->0にし、ADT7420から ackを入力します。
    • sdaを1のまま、sclを1にします。
    • sclを1のまま、sdaを0にして、restart します。そのあと、sclを0にします。
    • sdaを1にして、sclを 0->1->0にします。
    • sdaを0にして、sclを 0->1->0にします。
    • sdaを0のまま、sclを 0->1->0にします。
    • sdaを1にして、sclを 0->1->0にします。
    • sdaを0にして、sclを 0->1->0にします。
    • sdaを1にして、sclを 0->1->0にします。
    • sdaを1のまま、sclを 0->1->0にします。ADT7420のアドレス, 0x4bの再出力です。
    • sdaを1にして、sclを 0->1->0にします。read (=1)の出力です。
    • sdaを1のまま、sclを 0->1->0にし、ADT7420からackを入力します。
    • sdaを1のまま、sclを8回 0->1->0します。このとき、ADT7420から温度データが送られてきて、それが、led[8]から入力され、右にシフトされます。最初の bit は、符号を表します。符号を含む最初の8bitは、全16bitのMSB側の8bitです。
    • sdaを0にして、sclを 0->1->0にして、Master から ADT7420へ ack (0)を送ります。
    • sdaを1にして、そのまま、sclを8回 0->1->0します。このとき、ADT7420から温度データの下位8bitが送られてきて、それが、led[8]から入力され、右にシフトされます。入力された全16bitのうち、符号を除く上位8bit、(つまり、最初の1byte(8bit)のうち、2番目以降の7bit と、次に入力された1byte の最初の1bit )が、摂氏で表した温度の整数部分を表します。
    • 最後に、sdaを0, sclを1, そのまま sdaを1, にすることによって、通信終了信号がMaster からADT7420へ送られます。これで一通りのサイクルが終了します。

  • 実際に操作しているところの動画です。
  • 説明
    • 最初のスイッチの操作 ... I2C通信開始信号送信
      • center button を押して sclを 1にして、押したままにしておく。
        i2c-1-23.jpg
      • スライドスイッチをOffからONにして, sdaを1にする。
        i2c-1-24.jpg
      • スライドスイッチをONからOFFにする。
        i2c-1-25.jpg
    • アドレスの送信の最初の部分
      • sclを0にしたあと, sdaを1にして、sclを 0->1->0
        i2c-1-26.jpg
      • led[8]が点灯(1がsdaに流れたことを示す)。
        i2c-1-27.jpg
    • 再スタート, アドレス指定, 読み込みbit (1)送信, ack受信(0)受信の後, 最初に読み込んだ8bitのデータが 00010000
      • i2c-1-r-data-2.jpg
    • 次の8bit が, 11010000
      • i2c-1-r-data-3.jpg
    • この2つの01の列を接続した16bitの値が計測された温度です。最初の1bitは符号で、そのあとの8bit が摂氏で表した温度の小数点より大きいあたい、残りが、小数点より小さい値です。
    • 従って、0010 0001 が摂氏の小数点より大きい値となり、摂氏33度であることがわかります(ボードの熱で、ちょっと高い温度になるようです)。小数点以下の部分は、101なので 1/2 + 1/8=0.5+0.125=0.625となり、整数部分に加えると、33.625度、ということになります。
      • 実際に赤外線温度計で計測すると、摂氏33.6度となっており、かなり近い値が計測されていることが確認できます。
      • i2c-1-28.jpg

考察

  • 手でI2Cデバイスを制御するのは大変。ちょっと間違えたら1からやり直し。
  • tinyCPUを作ったのだから、それを使って、プログラムで制御したらいいじゃん。

Counter: 2070, today: 1, yesterday: 0

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-08-25 (金) 23:30:23 (2435d)