目的:DAC ICのSPI制御用マニュアル入力装置を作成する。
(1)構成概略
下記のような構成を考える。
入力デバイスはタクトSWとし、これにて16bitデータを入力し、FPGAでSPI制御してDAC8871を動作させる。出力は0~10Vのアナログ値とする。
(2)仕様
項目 | 内容 | 備考 |
主要デバイス | MAX5 5M570ZF256C5 | 評価ボードDK-DEV-5M570ZNを使用。理由は安かったから。 |
FPGA書き込みデバイス | 上記評価ボードにオンボード搭載。 | PCとは、USBケーブルを接続するだけでUSB blasterとして認識する。 |
記憶デバイス | FPGA内蔵 | レジスタとして適宜宣言 |
入力インターフェース | 16bitデータ入力用4個、リセット用1個、セット送信用1個、計6個 | |
DACデバイス | DAC8871 16bit | 評価ボードDAC8871-EVMを使用。 |
出力 | アナログ0〜10V | 出力精度0.153mV /1LSB |
表示 | 7seg 4桁---16bitデータ表示用 | |
入力インターフェース | 16bitデータ入力用4個、リセット用1個、セット送信用1個、計6個 | |
DACデバイス | DAC8871 16bit | 評価ボードDAC8871-EVMを使用。 |
表示 | 7seg 4桁---16bitデータ表示 |
(3)ハードウェア構成
・DAC8871-EVMのジャンパー設定
記号 | ショートピン | 機能 |
W1 | 2-3 | VREFLピンへの入力信号をJ1-18pinへ設定(Refer to J1) |
W2 | 2-3 | RSTSELをGNDショート。リセット時出力をGNDレベルとする。 |
W3 | 1-2 | VREFH入力をオンボード REF102出力10Vとする。 |
W4 | 1-2 | RSTプルアップ3.3V。RST入力アクティブLowを有効とする。 |
W5 | 2-3 | チップセレクト信号NCSにて制御するように設定。 |
W6 | 2-3 | nLDAC信号をLow固定とする。 |
W7 | 1-2 | VREFH入力をオンボード REF102出力10Vとする。 |
W8 | not inserted | オンボードREF102の出力トリミング。不使用。 |
J1 | 17-18 | J1-18pinをGNDとショートする。W1の設定とともにVREFLの入力をGNDとする。 |
・特殊ピン ピンアサイン
ピン番号 | 信号名 | MAX5 | ペリフェラル | 信号名 |
- | IO/CLK | H5 | 発振器 | CLK |
・GPIOピン ピンアサイン
ConnectorA | ConnectorB | |||||||||||||||||
ピン番号 | 信号名 | pin番号 | 信号名 | ピン番号 | 信号名 | pin番号 | 信号名 | ピン番号 | 品名 | pin番号 | 信号名 | 品名 | pin番号 | 信号名 | ||||
MAX5 | ペリフェラル | MAX5 | ペリフェラル | MAX5 | ペリフェラル | MAX5 | ペリフェラル | |||||||||||
1 | AGPIO1 | P2 | 16 | a1 | 2 | AGPIO2 | M4 | 15 | b1 | 1 | BGPIO_P_1_R | 2 | BGPIO_P_2_R | |||||
3 | AGPIO3 | L4 | 3 | c1 | 4 | AGPIO4 | N3 | 2 | d1 | 3 | BGPIO_N_1_R | 4 | BGPIO_N_2_R | |||||
5 | AGPIO5 | N2 | 1 | e1 | 6 | AGPIO6 | N1 | 18 | f1 | 5 | BGPIO_P_3_R | 6 | BGPIO_7 | |||||
7 | AGPIO7 | M3 | 17 | g1 | 8 | AGPIO8 | M2 | 4 | DP1 | 7 | BGPIO_N_3_R | 8 | BGPIO_8 | |||||
9 | AGPIO9 | M1 | SCK | 10 | AGPIO10 | L3 | nSCK | 9 | BGPIO_9 | 10 | BGPIO_10 | |||||||
11 | 5VIN_CONN | 12 | GND | 11 | 5VIN_CONN | 12 | GND | |||||||||||
13 | AGPIO11 | L1 | RST | 14 | AGPIO12 | L2 | SOUT | 13 | BGPIO_11 | 14 | BGPIO_12 | |||||||
15 | AGPIO13 | K2 | cs_counter0 | 16 | AGPIO14 | K3 | cs_counter1 | 15 | BGPIO_13 | 16 | BGPIO_14 | |||||||
17 | AGPIO15 | J3 | cs_counter2 | 18 | AGPIO16 | K1 | cs_counter3 | 17 | BGPIO_15 | 18 | BGPIO_16 | |||||||
19 | AGPIO17 | J1 | cs_counter4 | 20 | AGPIO18 | 19 | BGPIO_17 | 20 | BGPIO_18 | |||||||||
21 | AGPIO19 | 22 | AGPIO20 | 21 | BGPIO_19 | 22 | BGPIO_20 | |||||||||||
23 | AGPIO21 | 24 | AGPIO22 | 23 | BGPIO_21 | 24 | BGPIO_22 | |||||||||||
25 | AGPIO23 | 26 | AGPIO24 | 25 | BGPIO_23 | 26 | BGPIO_24 | |||||||||||
27 | AGPIO25 | 28 | AGPIO26 | 27 | BGPIO_25 | 28 | BGPIO_26 | |||||||||||
29 | 3.3VIN_CONN | 30 | GND | 29 | 3.3VIN_CONN | 30 | GND | |||||||||||
31 | AGPIO27 | E3 | SEL4 | 32 | AGPIO28 | F1 | SEL3 | 31 | BGPIO_27 | 32 | BGPIO_28 | |||||||
33 | AGPIO29 | E1 | SEL1 | 34 | AGPIO30 | E2 | SEL2 | 33 | BGPIO_29 | 34 | BGPIO_30 | |||||||
35 | AGPIO31 | D2 | SW1 | 36 | AGPIO32 | D3 | SW2 | 35 | BGPIO_31 | 36 | BGPIO_32 | |||||||
37 | AGPIO33 | C3 | SW3 | 38 | AGPIO34 | D1 | SW4 | 37 | BGPIO_33 | 38 | BGPIO_34 | |||||||
39 | AGPIO35 | E4 | SW5 | 40 | AGPIO36 | C2 | NCS | 39 | BGPIO_35 | 40 | BGPIO_36 |
module seg7_dynamic4( SW1, //input LSB SW2, SW3, SW4, //input MSB SW5,//set out CLK, //standard clock SCK, //serial clock NSCK, NCS, RST, SEVEN_SEG_DATA[7:0], SEL[4:1], SOUT, CS_COUNTER[4:0] ); input CLK; input RST; input SW1; input SW2; input SW3; input SW4; input SW5; output SCK; output NSCK; output NCS; output reg[7:0] SEVEN_SEG_DATA; output [4:1] SEL; output SOUT; output [4:0]CS_COUNTER; reg sw1; reg sw2; reg sw3; reg sw4; reg sw5; reg sw5out; reg [15:0] sout; reg[15:0] sw1_counter; reg[15:0] sw2_counter; reg[15:0] sw3_counter; reg[15:0] sw4_counter; reg[4:0] sw5_counter; reg[31:0] sec_cnt; //slow clock generation reg sec1_flag; //slow clock generation reg toggle_flag; //slow clock generation reg[1:0] enable_seg; reg[4:1] sel; reg[3:0] seven_seg1_counter; reg[3:0] seven_seg2_counter; reg[3:0] seven_seg3_counter; reg[3:0] seven_seg4_counter; reg[7:0] seven_seg1_hold; reg[7:0] seven_seg2_hold; reg[7:0] seven_seg3_hold; reg[7:0] seven_seg4_hold; reg[7:0] seven_seg; reg sck; reg ncs; reg nsck; reg[4:0]cs_counter; initial ncs <= 1'b1 ; //parameter F33M000_cnt=32'h004c4b40 ;//0.5sec interval //parameter F33M000_cnt=32'h000f4240 ;//0.1sec interval // parameter F33M000_cnt=32'h00027100 ;//0.016sec interval inputting clk: at 10Mhz //parameter F33M000_cnt=32'h000186A0 ;//0.01sec interval parameter F33M000_cnt=32'h00002710 ; //0.001sec interval
parameter selinit_value = 4'b1000 ; initial cs_counter = 5'b00000; initial sout = 16'b0000; always@(posedge CLK or negedge RST) begin if(RST ==1'b0)begin sw1_counter <= 16'b0000000000000000; //16bit 65535times(aprroximately 6.5msec sampling) end else begin sw1_counter <= sw1_counter +1'b1; end end
always@(posedge CLK) begin if(sw1_counter ==0)begin sw1 <= SW1; end end
always@(posedge CLK or negedge RST) begin if(RST ==1'b0)begin sw2_counter <= 16'b0000000000000000; end else begin sw2_counter <= sw2_counter +1'b1; end end
always@(posedge CLK) begin if(sw2_counter ==0)begin sw2 <= SW2; end end
always@(posedge CLK or negedge RST) begin if(RST ==1'b0)begin sw3_counter <= 16'b0000000000000000; end else begin sw3_counter <= sw3_counter +1'b1; end end
always@(posedge CLK) begin if(sw3_counter ==0)begin sw3 <= SW3; end end
always@(posedge CLK or negedge RST) begin if(RST ==1'b0)begin sw4_counter <= 16'b0000000000000000; end else begin sw4_counter <= sw4_counter +1'b1; end end
always@(posedge CLK) begin if(sw4_counter ==0)begin sw4 <= SW4; end end
always@(posedge NSCK or negedge RST) begin if(RST ==1'b0)begin sw5_counter <= 5'b00000; end else begin sw5_counter <= sw5_counter +1'b1; end end
always@(posedge CLK) begin if(sw5_counter ==0)begin sw5 <= SW5; end end
always@(posedge CLK) begin if(sec_cnt == F33M000_cnt) begin sec_cnt <= 32'h00000000 ; //counter counting up to the parameter(refer to No 52th row) sec1_flag <= 1'b1; end else begin sec_cnt <= sec_cnt + 1 ; sec1_flag <= 1'b0 ; end end
always@(posedge CLK) begin if(sec1_flag == 1'b1 )begin toggle_flag <= !toggle_flag ; end end
assign SCK =!toggle_flag; assign NSCK =toggle_flag;
always@(negedge sw1 or negedge sw2 or negedge sw3 or negedge sw4 or negedge RST or posedge CLK) begin if(RST ==1'b0)begin seven_seg1_hold <=8'b00000110; seven_seg2_hold <=8'b00000110; seven_seg3_hold <=8'b00000110; seven_seg4_hold <=8'b00000110; end else begin case(seven_seg1_counter) 4'b0000 : seven_seg1_hold<= 8'b00111111 ; //'0' 4'b0001 : seven_seg1_hold <= 8'b00000110 ; //'1' 4'b0010 :seven_seg1_hold<= 8'b01011011 ; //'2' 4'b0011 : seven_seg1_hold <= 8'b01001111 ; //'3' 4'b0100 : seven_seg1_hold <= 8'b01100110 ; //'4' 4'b0101 : seven_seg1_hold <= 8'b01101101 ; //'5' 4'b0110 : seven_seg1_hold <= 8'b01111101 ; //'6' 4'b0111 : seven_seg1_hold <= 8'b00100111 ; //'7' 4'b1000 : seven_seg1_hold <= 8'b01111111 ; //'8' 4'b1001 : seven_seg1_hold <= 8'b01101111 ; //'9' 4'b1010 : seven_seg1_hold <= 8'b01110111 ; //'A' 4'b1011 : seven_seg1_hold <= 8'b01111100 ; //'b' 4'b1100 : seven_seg1_hold <= 8'b01011000 ; //'c' 4'b1101 : seven_seg1_hold <= 8'b01011110 ; //'d' 4'b1110 : seven_seg1_hold <= 8'b01111001 ; //'E' 4'b1111 : seven_seg1_hold <= 8'b01110001 ; //'F' default: seven_seg1_hold <= 8'b00000110; endcase case(seven_seg2_counter) 4'b0000 : seven_seg2_hold<= 8'b00111111 ; //'0 4'b0001 : seven_seg2_hold <= 8'b00000110 ; //'1' 4'b0010 :seven_seg2_hold<= 8'b01011011 ; //'2' 4'b0011 : seven_seg2_hold <= 8'b01001111 ; //'3' 4'b0100 : seven_seg2_hold <= 8'b01100110 ; //'4' 4'b0101 : seven_seg2_hold <= 8'b01101101 ; //'5' 4'b0110 : seven_seg2_hold <= 8'b01111101 ; //'6' 4'b0111 : seven_seg2_hold <= 8'b00100111 ; //'7' 4'b1000 : seven_seg2_hold <= 8'b01111111 ; //'8' 4'b1001 : seven_seg2_hold <= 8'b01101111 ; //'9' 4'b1010 : seven_seg2_hold <= 8'b01110111 ; //'A' 4'b1011 : seven_seg2_hold <= 8'b01111100 ; //'b' 4'b1100 : seven_seg2_hold <= 8'b01011000 ; //'c' 4'b1101 : seven_seg2_hold <= 8'b01011110 ; //'d' 4'b1110 : seven_seg2_hold <= 8'b01111001 ; //'E' 4'b1111 : seven_seg2_hold <= 8'b01110001 ; //'F' default: seven_seg2_hold <= 8'b00000110; endcase case(seven_seg3_counter) 4'b0000 : seven_seg3_hold<= 8'b00111111 ; //'0' 4'b0001 : seven_seg3_hold <= 8'b00000110 ; //'1' 4'b0010 :seven_seg3_hold<= 8'b01011011 ; //'2' 4'b0011 : seven_seg3_hold <= 8'b01001111 ; //'3' 4'b0100 : seven_seg3_hold <= 8'b01100110 ; //'4' 4'b0101 : seven_seg3_hold <= 8'b01101101 ; //'5' 4'b0110 : seven_seg3_hold <= 8'b01111101 ; //'6' 4'b0111 : seven_seg3_hold <= 8'b00100111 ; //'7' 4'b1000 : seven_seg3_hold <= 8'b01111111 ; //'8' 4'b1001 : seven_seg3_hold <= 8'b01101111 ; //'9' 4'b1010 : seven_seg3_hold <= 8'b01110111 ; //'A' 4'b1011 : seven_seg3_hold <= 8'b01111100 ; //'b' 4'b1100 : seven_seg3_hold <= 8'b01011000 ; //'c' 4'b1101 : seven_seg3_hold <= 8'b01011110 ; //'d' 4'b1110 : seven_seg3_hold <= 8'b01111001 ; //'E' 4'b1111 : seven_seg3_hold <= 8'b01110001 ; //'F' default: seven_seg3_hold <= 8'b00000110; endcase case(seven_seg4_counter) 4'b0000 : seven_seg4_hold<= 8'b00111111 ; //'0' 4'b0001 : seven_seg4_hold <= 8'b00000110 ; //'1' 4'b0010 :seven_seg4_hold<= 8'b01011011 ; //'2' 4'b0011 : seven_seg4_hold <= 8'b01001111 ; //'3' 4'b0100 : seven_seg4_hold <= 8'b01100110 ; //'4' 4'b0101 : seven_seg4_hold <= 8'b01101101 ; //'5' 4'b0110 : seven_seg4_hold <= 8'b01111101 ; //'6' 4'b0111 : seven_seg4_hold <= 8'b00100111 ; //'7' 4'b1000 : seven_seg4_hold <= 8'b01111111 ; //'8' 4'b1001 : seven_seg4_hold <= 8'b01101111 ; //'9' 4'b1010 : seven_seg4_hold <= 8'b01110111 ; //'A' 4'b1011 : seven_seg4_hold <= 8'b01111100 ; //'b' 4'b1100 : seven_seg4_hold <= 8'b01011000 ; //'c' 4'b1101 : seven_seg4_hold <= 8'b01011110 ; //'d' 4'b1110 : seven_seg4_hold <= 8'b01111001 ; //'E' 4'b1111 : seven_seg4_hold <= 8'b01110001 ; //'F' default: seven_seg4_hold <= 8'b00000110; endcase end end always@(posedge SCK or negedge RST)begin if(RST == 1'b0 )begin enable_seg <= 2'b00; end else begin enable_seg <= enable_seg +1'b1; end end
always@(posedge SCK or negedge RST)begin if(RST == 1'b0 )begin sel <= selinit_value; end else begin sel[2] <= sel[1] ; //シフト動作を開始する sel[3] <= sel[2] ; //シフト動作を開始する sel[4] <= sel[3] ; //シフト動作を開始する sel[1] <= sel[4] ; end end
assign SEL[4:1] = ~sel[4:1];
always@( negedge RST or posedge sw1 )begin if( RST == 1'b0 )begin seven_seg1_counter <= 4'b0000; end else begin seven_seg1_counter <= seven_seg1_counter + 1'b1; end end always@( negedge RST or negedge sw2)begin if( RST == 1'b0)begin seven_seg2_counter <= 4'b0000; end else begin seven_seg2_counter <= seven_seg2_counter + 1'b1; end end always@( negedge RST or negedge sw3)begin if( RST == 1'b0)begin seven_seg3_counter <= 4'b0000; end else begin seven_seg3_counter <= seven_seg3_counter + 1'b1; end end always@( negedge RST or negedge sw4)begin if( RST == 1'b0)begin seven_seg4_counter <= 4'b0000; end else begin seven_seg4_counter <= seven_seg4_counter + 1'b1; end end always@* //* whenever inputs change, holding counter value as the resister "SEVEN_SEG_DATA" begin case(enable_seg) 2'b00: SEVEN_SEG_DATA <= ~seven_seg4_hold; 2'b01: SEVEN_SEG_DATA<=~seven_seg1_hold; 2'b10: SEVEN_SEG_DATA<=~seven_seg2_hold; 2'b11: SEVEN_SEG_DATA<=~seven_seg3_hold; endcase end always@(negedge RST or negedge sw5 or posedge cs_counter[4] ) begin if( RST == 1'b0)begin sw5out <= 1'b1; end else if(cs_counter[4] == 1'b1)begin sw5out <= 1'b1; end else begin sw5out <=1'b0; end end assign NCS = sw5out;
always@(posedge NSCK or negedge RST )//SCK begin if(RST == 1'b0 )begin cs_counter<= 5'b00000; end else if(cs_counter == 5'b10001)begin cs_counter <=5'b00000; end else if(sw5out ==1'b0) begin cs_counter <= cs_counter +1'b1; end else begin cs_counter <=5'b00000; end end
assign CS_COUNTER = cs_counter ;
always@(posedge NSCK or negedge RST ) begin if(RST == 1'b0 )begin sout<=16'b0000000000000000; end else if(sw5out ==1'b0) begin sout <= {sout[14:0],sout[15] }; end else begin sout <={seven_seg4_counter,seven_seg3_counter,seven_seg2_counter,seven_seg1_counter}; end end
//assign SOUT = (sw5out==0)? sout[15]:1'b0; assign SOUT = sout[15]; endmodule
下表に、実際に出力させてみたときの電圧値を示す。~