- 追加された行はこの色です。
- 削除された行はこの色です。
[[FpgaI2c]]
- 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 で使うとき、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)デバイスアドレスは、0x4b (=1001011) です。
- 回路の作成
-- sw[0]を sda に接続します。
-- center button (BCx) を sclに接続します。
-- sda を led[8] に接続します。scl が 0->1 に変化するたびに、これをシフトして、過去8回のsda の High/Low の遷移を led[15:8] に表示します。
-- 1つのポートで入出力を行う為、scl, sda は verilog の inout 型を使います。
- 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.ucf
## 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
----
#counter