[[FpgaI2c]] * 概要 [#eb6f98e9] - Nexys 4 付属のI2C温度計の SDA, SCL 信号線を直接スイッチで ON/OFFしながら、温度計を操作してみます。チャタリング防止や LED 表示などのため、ちょっと verilog で回路を作ります。 -- 参考: Nesys4 のマニュアル --- https://www.digilentinc.com/Data/Products/NEXYS4/Nexys4_RM_VB2_Final_5.pdf -- このマニュアルを確認しながら設定を行うと良いと思います。 - Nexys 4 付属の温度計, Analog Devices の ADT7420 -- 詳しい情報は以下の pdf に載っています。 --- http://www.analog.com/media/jp/technical-documentation/data-sheets/ADT7420_jp.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 にする。 * 回路の概要 [#k7443f7f] - 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個に出力する回路に接続します。 - 回路図 -- &ref(I2Cデバイスを手で動かしてみる/i2c-1-circuit.jpg,75%); * Vivado または ISEで以下の verilog を入力 [#nb68637a] - 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 のコピペで良いです) --- &ref(I2Cデバイスを手で動かしてみる/i2c-1-1.jpg,50%); -- 構文チェック --- &ref(I2Cデバイスを手で動かしてみる/i2c-1-2.jpg,50%); * verilog のコンパイルと bit ファイルの作成 [#h5a17f69] - startup clock を jtag に変更 -- Generate programming file を右クリック, Process Properties を選択 --- &ref(I2Cデバイスを手で動かしてみる/i2c-1-3.jpg,50%); -- Process Properties ウィンドウの Startup Options を選択し、FPGA Start-Up Clock をJTAG-Clockに変更し、OKをクリック --- &ref(I2Cデバイスを手で動かしてみる/i2c-1-4.jpg,50%); - bitファイルの生成 -- Process Window で, Generate programming file をダブルクリック。もしくは、右クリックして、rerun all. --- &ref(I2Cデバイスを手で動かしてみる/i2c-1-6.jpg,50%); * Nexys4とパソコンの接続, bit ファイルのダウンロード [#cc8b9d07] - パソコンとNexys4を接続 --- &ref(I2Cデバイスを手で動かしてみる/i2c-1-7-s.jpg,30%); - bitファイルのダウンロード -- Process Windowで Configure Target Device をダブルクリック --- &ref(I2Cデバイスを手で動かしてみる/i2c-1-8.jpg,50%); -- Warning ウィンドウで OKをクリック --- &ref(I2Cデバイスを手で動かしてみる/i2c-1-9.jpg,50%); -- ISE IMPACT ウィンドウが表示される。 --- &ref(I2Cデバイスを手で動かしてみる/i2c-1-10.jpg,50%); -- ISE iMPACT ウィンドウでBoundary Scan をダブルクリック --- &ref(I2Cデバイスを手で動かしてみる/i2c-1-11.jpg,50%); -- ISE iMPACT の "Right click to Add Device or Initiate JTAG chain" のところで右クリック --- &ref(I2Cデバイスを手で動かしてみる/i2c-1-12.jpg,50%); -- 出てきたダイアログで, Add Xilinx Device を選択 --- &ref(I2Cデバイスを手で動かしてみる/i2c-1-13.jpg,50%); -- ダウンロードする bit ファイルを間違えないように選択(過去に保存した bit ファイルが最初に出る場合があります) --- &ref(I2Cデバイスを手で動かしてみる/i2c-1-14.jpg,50%); -- チップのアイコンが表示されるので, そこを右クリックして, 出てきたメニューから "program"を選択。 --- &ref(I2Cデバイスを手で動かしてみる/i2c-1-16.jpg,50%); -- Device Programming Properties のウィンドウで OK をクリック --- &ref(I2Cデバイスを手で動かしてみる/i2c-1-17.jpg,50%); -- bit ファイルのダウンロード状況(転送状況)が表示される。 --- &ref(I2Cデバイスを手で動かしてみる/i2c-1-18.jpg,50%); -- ダウンロードが終了すると、ボードの7セグメントLEDに"0000 0000"が表示される(スライドスイッチがすべてOffの場合)。 --- &ref(I2Cデバイスを手で動かしてみる/i2c-1-19-s.jpg,50%); &br; (スライドスイッチ 0 がONになっているので、左端が1になっています。) * 実行 [#d88c502b] - 手順詳細 -- 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へ送られます。これで一通りのサイクルが終了します。 ---- - 実際に操作しているところの動画です。 -- http://youtu.be/mjl-93KeypM - 説明 -- 最初のスイッチの操作 ... I2C通信開始信号送信 --- center button を押して sclを 1にして、押したままにしておく。&br; &ref(I2Cデバイスを手で動かしてみる/i2c-1-23.jpg,50%); ---スライドスイッチをOffからONにして, sdaを1にする。&br; &ref(I2Cデバイスを手で動かしてみる/i2c-1-24.jpg,50%); --- スライドスイッチをONからOFFにする。&br; &ref(I2Cデバイスを手で動かしてみる/i2c-1-25.jpg,50%); -- アドレスの送信の最初の部分 --- sclを0にしたあと, sdaを1にして、sclを 0->1->0 &br; &ref(I2Cデバイスを手で動かしてみる/i2c-1-26.jpg,50%); --- led[8]が点灯(1がsdaに流れたことを示す)。&br; &ref(I2Cデバイスを手で動かしてみる/i2c-1-27.jpg,50%); -- 再スタート, アドレス指定, 読み込みbit (1)送信, ack受信(0)受信の後, 最初に読み込んだ8bitのデータが 00010000 --- &ref(I2Cデバイスを手で動かしてみる/i2c-1-r-data-2.jpg,50%); -- 次の8bit が, 11010000 --- &ref(I2Cデバイスを手で動かしてみる/i2c-1-r-data-3.jpg,50%); -- この2つの01の列を接続した16bitの値が計測された温度です。最初の1bitは符号で、そのあとの8bit が摂氏で表した温度の小数点より大きいあたい、残りが、小数点より小さい値です。 -- 従って、0010 0001 が摂氏の小数点より大きい値となり、摂氏33度であることがわかります(ボードの熱で、ちょっと高い温度になるようです)。小数点以下の部分は、101なので 1/2 + 1/8=0.5+0.125=0.625となり、整数部分に加えると、33.625度、ということになります。 --- 実際に赤外線温度計で計測すると、摂氏33.6度となっており、かなり近い値が計測されていることが確認できます。&br; --- &ref(I2Cデバイスを手で動かしてみる/i2c-1-28.jpg,50%); * 考察 [#k3142c1f] - 手でI2Cデバイスを制御するのは大変。ちょっと間違えたら1からやり直し。 - tinyCPUを作ったのだから、それを使って、プログラムで制御したらいいじゃん。 ---- #counter