verilog / DAC_SPI2


verilog

・DAC_SPI2

目的: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のジャンパー設定

記号ショートピン機能
W12-3VREFLピンへの入力信号をJ1-18pinへ設定(Refer to J1)
W22-3RSTSELをGNDショート。リセット時出力をGNDレベルとする。
W31-2VREFH入力をオンボード REF102出力10Vとする。
W41-2RSTプルアップ3.3V。RST入力アクティブLowを有効とする。
W52-3チップセレクト信号NCSにて制御するように設定。
W62-3nLDAC信号をLow固定とする。
W71-2VREFH入力をオンボード REF102出力10Vとする。
W8not insertedオンボードREF102の出力トリミング。不使用。
J117-18J1-18pinをGNDとショートする。W1の設定とともにVREFLの入力をGNDとする。

・特殊ピン ピンアサイン

ピン番号信号名MAX5ペリフェラル信号名
-IO/CLKH5発振器CLK

・GPIOピン ピンアサイン

ConnectorAConnectorB
ピン番号信号名pin番号信号名ピン番号信号名pin番号信号名ピン番号品名pin番号信号名品名pin番号信号名
MAX5ペリフェラルMAX5ペリフェラルMAX5ペリフェラルMAX5ペリフェラル
1AGPIO1P216a12AGPIO2M415b11BGPIO_P_1_R2BGPIO_P_2_R
3AGPIO3L43c14AGPIO4N32d13BGPIO_N_1_R4BGPIO_N_2_R
5AGPIO5N21e16AGPIO6N118f15BGPIO_P_3_R6BGPIO_7
7AGPIO7M317g18AGPIO8M24DP17BGPIO_N_3_R8BGPIO_8
9AGPIO9M1SCK10AGPIO10L3nSCK9BGPIO_910BGPIO_10
115VIN_CONN12GND115VIN_CONN12GND
13AGPIO11L1RST14AGPIO12L2SOUT13BGPIO_1114BGPIO_12
15AGPIO13K2cs_counter016AGPIO14K3cs_counter115BGPIO_1316BGPIO_14
17AGPIO15J3cs_counter218AGPIO16K1cs_counter317BGPIO_1518BGPIO_16
19AGPIO17J1cs_counter420AGPIO1819BGPIO_1720BGPIO_18
21AGPIO1922AGPIO2021BGPIO_1922BGPIO_20
23AGPIO2124AGPIO2223BGPIO_2124BGPIO_22
25AGPIO2326AGPIO2425BGPIO_2326BGPIO_24
27AGPIO2528AGPIO2627BGPIO_2528BGPIO_26
293.3VIN_CONN30GND293.3VIN_CONN30GND
31AGPIO27E3SEL432AGPIO28F1SEL331BGPIO_2732BGPIO_28
33AGPIO29E1SEL134AGPIO30E2SEL233BGPIO_2934BGPIO_30
35AGPIO31D2SW136AGPIO32D3SW235BGPIO_3136BGPIO_32
37AGPIO33C3SW338AGPIO34D1SW437BGPIO_3338BGPIO_34
39AGPIO35E4SW540AGPIO36C2NCS39BGPIO_3540BGPIO_36

・RTL記述内容ソース

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

結果

下表に、実際に出力させてみたときの電圧値を示す。~
添付ファイルの画像