vertix7 时钟频率配置(verilog源代码)

接这篇文章,vertix7 时钟频率配置(VC707 USER_CLOCK_P与USER_CLOCK_N 这两路差分输入时钟频率配置 )(SI570芯片配置),把源代码附上!!!仅供参考!

一个top.v  一个configuration.v  ,两个.v文件

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Create Date: 2018/10/02 
// 这是配置user_clock 时钟输入频率的模块,通过IIC写SI570芯片寄存器,设置具体频率值,具体见博客,
//这个时钟默认输出156.25MHz,在这个例子里,配置之后输出125MHz
//////////////////////////////////////////////////////////////////////////////////


module clock_top(
	input 	clk_p,
   	input 	clk_n,
   	input	USER_CLOCK_P,
   	input	USER_CLOCK_N,
   	input 	rst,
   	inout iic_sda,			
  	inout iic_scl,
   	output iic_reset,		//I2C 1-to-8 device PCA9548 的复位,低有效
   	output reg led7,
   	output	led6,
   	output	led5,
   	output	led4,
   	output reg	led3,
   	output	led2,
   	output	led1,
   	output	led0
    );
    wire	clk_100;
 	wire	clk_25;
    //系统输入时钟200MHz。分频为100和25MHz
dcm_200_100 dcm_100_25(
	// Clock out ports
	.clk_out1(clk_100),
	.clk_out2(clk_25),
	// Clock in ports
	.clk_in1_p(clk_p),
	.clk_in1_n(clk_n)
); 

	//user_clock,配置完成后,输出125MHz,在这分频为100MHz
	wire clk100;
dcm_125_100 dcm_100(
	// Clock out ports
	.clk_out1(clk100),
	// Clock in ports
	.clk_in1_p(USER_CLOCK_P),
	.clk_in1_n(USER_CLOCK_N)
); 

reg [31:0] number0;
reg [31:0] number1;
always@(posedge clk100)
if(rst)
begin
	led7<=1;
	number0<=0;
end
else
	if(number0==100_000_000)
	begin
		led7<=~led7;
		number0<=0;
	end
	else
		number0<=number0+1;
		
always@(posedge clk_100)
		if(rst)
		begin
			led3<=1;
			number1<=0;
		end
		else
			if(number1==100_000_000)
			begin
				led3<=~led3;
				number1<=0;
			end
			else
				number1<=number1+1;
	
    	user_clock_config user_clock_config(
    	  	.clk_100(clk_100),
    	  	.clk_25(clk_25),   
    	  	.rst(rst),     
    	  	.iic_scl(iic_scl), 
    	  	.iic_sda(iic_sda),
    	  	.iic_reset(iic_reset),
//    	  	.led7(led7),
    	  	.led6(led6),
    	  	.led5(led5),
    	  	.led4(led4),
//    	  	.led3(led3),
    	  	.led2(led2),
    	  	.led1(led1),
    	  	.led0(led0)
    	  	);  
endmodule   
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Create Date: 2018/10/02 
// 这是配置user_clock 时钟输入频率的模块,通过IIC写SI570芯片寄存器,设置具体频率值,具体见博客,
//这个时钟默认输出156.25MHz,在这个例子里,配置之后输出125MHz
//////////////////////////////////////////////////////////////////////////////////


module user_clock_config(
	input 	clk_100,
	input	clk_25,
	input	rst,
	inout	iic_scl,
	inout 	iic_sda,	
	output reg 	iic_reset,	//iic 复位,低有效
//    output reg	led7,
    output reg	led6,
    output reg	led5,
    output reg	led4,
//    output reg	led3,
    output reg	led2,
    output reg	led1,
    output reg	led0
    );
    wire rst_low;
	assign rst_low = ~rst;//低有效复位
	
	always@(posedge clk_100 or posedge rst)
		if(rst)
			iic_reset<=0;
		else
			iic_reset<=1;
    
    //...............................................AXI port 
        reg[8:0] w_addr,r_addr;	//write address,read address
        reg[31:0] w_data;		//write data register	
        wire[31:0] r_data;		//read data register
    	
     	//..............................AXI handshake signal
        reg 	aw_valid;	//write adress valid(master send)
        reg 	w_valid;	//write  valid(master send)
        wire	aw_ready;	//表明从机可以接收写地址(slave send)
        wire 	w_ready;	//表明从机可以接收写数据(slave send)
        
        reg 	ar_valid;	//read address valid(master send)
        wire	ar_ready;	//表明从机可接收读地址(slave send)
        wire 	r_valid;	//read data valid(slave send)
        reg		r_ready;	//表明主机可以接收读数据(master send)
        reg 	b_ready;	//表明主机可以接收写响应(axi 的通信协议,每次写数据发送后,从机会发送一个写响应信号,表明数据已经接收到,这个要在写响应之前拉高,表明主机可以接收该信号)
        wire 	b_valid;	//写响应有效(slave send)
        //...............................AXI handshake signal
        
       
        reg [3:0]w_strb;	//写数据有效的字节线,表明哪8bit是有效的,共32bit,分成4个通道
        wire [1:0]b_resp;	//写响应,表明写传输的状态,slave send,00表示正常,10:从机故障
        //...............................................AXI port 
        
        //...............................................I2c port 
        wire	sda_i;  //IIC Serial Data Input from 3-state buffer
        wire	sda_o;  //IIC Serial Data Output to 3-state buffer
        wire 	sda_t; 	//IIC Serial Data Output Enable to 3-state buffer
       wire 	scl_i; 	//IIC Serial Clock Input from 3-state buffer
        wire 	scl_o;  //IIC Serial Clock Output to 3-state buffer
        wire 	scl_t; 	//IIC Serial Clock Output Enable to 3-state buffer
        //...............................................I2c port
        
        reg [7:0] state;	//通过I2C来配置ADV7511的state,配置的寄存器较多
        reg [3:0] register_num;
        reg [31:0] delay_num;
        
        always @(posedge clk_25 or posedge rst)
            	if(rst)
            	begin
//            		led7<=0;
            		led6<=0;
            		led5<=0;
            		led4<=0;
//            		led3<=0;
            		led2<=0;
            		led1<=0;
            		led0<=0;
            		w_addr<=0;w_data<=0;aw_valid<=0;w_valid<=0;
            		r_ready<=0;ar_valid<=0;r_addr<=9'h104;//地址104,状态寄存器,可查看TX_FIFO 是否full 或 empty等状态
            		w_strb<=1'b1; //the first 8-bit channel enable 
            		
            		b_ready<=1;
            		state<=0;
            		register_num<=0;
        			delay_num<=0;
            	end
            	else
            	begin
            		case(state)
            			0:	begin  //state 0 and 1  configure AXI mode,后面的开始配置 ADV7511
								if(delay_num==25_000_000)//ADV上电200ms才能被寻址,暂时定个1s
								begin
									aw_valid<=1;
									w_valid<=1;   
									delay_num<=0;
								end
								else
									delay_num<=delay_num+1;
								w_addr<=9'h120;//120h is RX_FIFO_PIRQ address
								//重点重点重点::::务必要设置这一个寄存器,receive_data的字节数,只有设置了这个,
								//再收完数据后才会,主机才会产生stop信号,释放iic总线
								w_data<=32'h0f;//Rx_FIFO can receive 16 bytes
								if(aw_ready)
								begin
									state<=1;
								end
            				end
            				1:	begin
            						w_addr<=9'h100;//100h is CR address
            						w_data<=32'h2;//reset Tx_FIFO 
            						if(aw_ready)
            							state<=2;
            					end
        						2:	begin
            	    					w_data<=32'h9;//IIC 正常工作模式
            	    					if(aw_ready)
            	    						state<=3; 
            	    				end
            					3:	begin
            							w_addr<=9'h108;//TX_FIFO address 
            							w_data<=32'h1E8;////PCA9548 的地址,这是一个1 to 8 的IIC转换芯片,一共8个通道,配置好通道后,才能与后面设备通信
            											//也就是说,存入TX_FIFO的数据第一个是带有start的,最后一个是带有stop信号的数据
            											//第一组传送完毕,才能传送第二组
            							if(aw_ready)
            	    						state<=4; 
            						end
            					4:	begin
            							w_data<=32'h201;//si570 IIC 在第1路通道,选通第1路,0b0010_0000
            							if(aw_ready)//重要:::::发完停止信号后,待总线不忙时,才能再次往TX_FIFO写数据(开始信号+数据)
            							begin
            								state<=5; 
            								aw_valid<=0;
            								w_valid<=0; 
            								r_ready<=1;
            								ar_valid<=1;
            							end
            						end
            					5:	begin
            							if(r_valid)
            								if(r_data & 8'h80)//等待TX_FIFO 空
            									state<=6;
            						end
            					6:	begin
            						if(r_valid)
            							if(!(r_data & 3'b100))////重要:::::发完停止信号后,待iic总线不忙时,才能再次往TX_FIFO写数据(开始信号+数据)
            							begin
            								state<=7; 
            								aw_valid<=1;
            								w_valid<=1; 
            								r_ready<=0;
            								ar_valid<=0;
            							end
            						end
        						7:	begin
            							w_data<=32'h1ba;//SI570 Clock  地址,写数据
            							if(aw_ready)
            								state<=8;
            						end
            					8:	begin
            							w_data<=137;//Freeze DCO 地址, Freeze the DCO (bit 5 of Register 137).
            							if(aw_ready)
											state<=9;
            						end 
            					9:	begin
            							w_data<=32'h220;//Freeze the DCO
										if(aw_ready)
										begin
											state<=10;
											aw_valid<=0;
											w_valid<=0; 
											r_ready<=1;
											ar_valid<=1;
										end
            						end
            					10:	begin
            						if(r_valid)
            							if(r_data & 8'h80)//等待TX_FIFO 空
            								state<=11;
            						end
            					11:	begin
            						if(r_valid)
            							if(!(r_data & 3'b100))////重要:::::发完停止信号后,待iic总线不忙时,才能再次往TX_FIFO写数据(开始信号+数据)
            							begin
            								state<=12; 
            								aw_valid<=1;
            								w_valid<=1; 
            								r_ready<=0;
            								ar_valid<=0;
            							end
            						end	
            					12:	begin
            							w_data<=32'h1ba;//ASi5324 Clock  地址,写数据
            							if(aw_ready)
            								state<=13;
            						end
            					13:	begin
            							w_data<=7;//寄存器第一个地址,连续写4个byte
            							if(aw_ready)
            								state<=14;
            						end
            					14:	begin
            							w_data<=32'h221;//写数据
            							if(aw_ready)
            							begin
            								state<=15;
            								aw_valid<=0;
            								w_valid<=0; 
            								r_ready<=1;
            								ar_valid<=1;
            							end
            						end
            					15:	begin
            						if(r_valid)
            							if(r_data & 8'h80)//等待TX_FIFO 空
            								state<=16;
            						end
            					16:	begin
            							if(r_valid)
            						    	if(!(r_data & 3'b100))////重要:::::发完停止信号后,待iic总线不忙时,才能再次往TX_FIFO写数据(开始信号+数据)
            						    	begin
            						    		state<=17; 
            						    		r_ready<=0;
            						    		ar_valid<=0;
            						    	end
            						end
            					17:	begin
            						if(delay_num==300_000)//Unfreeze the DCO within the maximum delay 10ms
            						begin
            							state<=18;  
            							delay_num<=0;
            						end
            						else
            							delay_num<=delay_num+1;
            						end
            					18:	begin
            							w_data<=32'h1ba;//SI570 Clock  地址,写数据
            							aw_valid<=1;
            							w_valid<=1; 
            							if(aw_ready)
            								state<=19;
            						end
            					19:	begin
            							w_data<=137;//UnFreeze DCO 地址, Freeze the DCO (bit 5 of Register 137).
            							if(aw_ready)
            								state<=20;
            						end 
            					20:	begin
            							w_data<=32'h200;//UnFreeze the DCO
            							if(aw_ready)
            							begin
            								state<=21;
            								aw_valid<=0;
            								w_valid<=0; 
            								r_ready<=1;
            								ar_valid<=1;
            							end
            						 end
            					21:	begin
            						if(r_valid)
            							if(r_data & 8'h80)//等待TX_FIFO 空
            								state<=22;
            						end
								22:	begin
            						if(r_valid)
            							if(!(r_data & 3'b100))////重要:::::发完停止信号后,待iic总线不忙时,才能再次往TX_FIFO写数据(开始信号+数据)
            							begin
            								state<=23; 
            								aw_valid<=1;
            								w_valid<=1; 
            								r_ready<=0;
            								ar_valid<=0;
            							end
            						end	
            					23:	begin
            					    	w_data<=32'h1ba;//SI570 Clock  地址,写数据
            					    	if(aw_ready)
            					    		state<=24;
            					    end
								24:	begin
										w_data<=135;//New frequency applied.寄存器地址
										if(aw_ready)
											state<=25;
            						end
            					25:	begin
            						  	w_data<=32'h240;//Bit[6] Alerts the DSPLL that a new frequency configuration has been applied. 
            										//This bit willclear itself when the new frequency is applied.
            						  	if(aw_ready)
            						  	begin
            						  		state<=26;
											aw_valid<=0;
											w_valid<=0; 
											r_ready<=1;
											ar_valid<=1;
            						     end
									end 
								26:	begin
									  	if(r_valid)
									  		if(r_data & 8'h80)//等待TX_FIFO 空
									  			state<=27;
									  	end
								27:	begin
									  	if(r_valid)
									  		if(!(r_data & 3'b100))////重要:::::发完停止信号后,待iic总线不忙时,才能再次往TX_FIFO写数据(开始信号+数据)
									  		begin
									  			state<=28; 
									  			aw_valid<=0;
									  			w_valid<=0; 
									  			r_ready<=0;
									  			ar_valid<=0;
									  		end
									  end	
								
            					28:	begin
            						led6<=1;
            						led5<=1;
            						led4<=1;
            						end
        		endcase
        end
        
        //例化了两个三态门电路,根据AXI IIC ip 技术手册
            IOBUF #(
            	.DRIVE(12), // Specify the output drive strength
            	.IBUF_LOW_PWR("TRUE"), // Low Power - "TRUE", High Performance = "FALSE" 
            	.IOSTANDARD("DEFAULT"), // Specify the I/O standard
            	.SLEW("SLOW") // Specify the output slew rate
            	)
            IOBUF_inst (	
            	.O(sda_i), // Buffer output
            	.IO(iic_sda), // Buffer inout port (connect directly to top-level port)
            	.I(sda_o), // Buffer input
            	.T(sda_t) // 3-state enable input, high=input, low=output
            	);             
            	   	
            IOBUF #(
            	.DRIVE(12), // Specify the output drive strength
            	.IBUF_LOW_PWR("TRUE"), // Low Power - "TRUE", High Performance = "FALSE" 
            	.IOSTANDARD("DEFAULT"), // Specify the I/O standard
            	.SLEW("SLOW") // Specify the output slew rate
            	)
            IOBUF_inst1 (
            	.O(scl_i), // Buffer output
            	.IO(iic_scl), // Buffer inout port (connect directly to top-level port)
            	.I(scl_o), // Buffer input
            	.T(scl_t) // 3-state enable input, high=input, low=output
            	);
            	
            //例化AXI IIC IP核
            axi_iic_0 axi_iic_0(                                      
            	.s_axi_aclk(clk_25),                                       
            	.s_axi_aresetn(rst_low),//复位,低有效                         
            	//.iic2intc_irpt(),//iic产生中断的输出port                        
            	.s_axi_awaddr(w_addr),//写地址[8:0]                         
            	.s_axi_awvalid(aw_valid),//表示主发送的地址有效                    
            	.s_axi_awready (aw_ready),//表明“从”可以接收该地址                 
            	.s_axi_wdata(w_data),//写数据[31:0],4个数据通道                  
            	.s_axi_wstrb(w_strb),//数据通道选择[3:0],1111选通4个通道            
            	.s_axi_wvalid(w_valid),//表示主发送的数据有效                      
            	.s_axi_wready(w_ready),//表示从可以接收该数据                      
            	.s_axi_bresp(b_resp),//[1:0],00代表ok                      
            	.s_axi_bvalid(b_valid),//写响应有效,由‘从’发出                    
            	.s_axi_bready(b_ready),//表示主机能够接收‘响应’                    
            	.s_axi_araddr(r_addr),                                   
            	.s_axi_arvalid(ar_valid),                                
            	.s_axi_arready(ar_ready),                                
            	.s_axi_rdata(r_data),                                    
            	.s_axi_rresp(),                                          
            	.s_axi_rvalid(r_valid),                                  
            	.s_axi_rready(r_ready),                                  
            	.sda_o(sda_o),                                           
            	.sda_i(sda_i),                                           
            	.sda_t(sda_t),                                           
            	.scl_o(scl_o),                                           
            	.scl_i(scl_i),                                           
            	.scl_t(scl_t)                                            
            );                        
endmodule
//ila_0 ila_0(
//	.clk(clk_50),
//	.probe0(sda_t),
//	.probe1(scl_t),
//	.probe2(led0),
//	.probe3(led1),
//	.probe4(led2),
//	.probe5(sda_i),
//	.probe6(r_data[7:0])
//	);
     
        

//		0:	begin  //state 0 and 1  configure AXI mode,后面的开始配置 ADV7511
//						if(delay_num==25_000_000)//ADV上电200ms才能被寻址,暂时定个1s
//						begin
//							aw_valid<=1;
//							w_valid<=1;   
//							delay_num<=0;
//						end
//						else
//							delay_num<=delay_num+1;
//						w_addr<=9'h120;//120h is RX_FIFO_PIRQ address
//						//重点重点重点::::务必要设置这一个寄存器,receive_data的字节数,只有设置了这个,
//						//再收完数据后才会,主机才会产生stop信号,释放iic总线
//						w_data<=32'h0f;//Rx_FIFO can receive 16 bytes
//						if(aw_ready)
//						begin
//							state<=1;
//						end
//            				end
//            				1:	begin
//            						w_addr<=9'h100;//100h is CR address
//            						w_data<=32'h2;//reset Tx_FIFO 
//            						if(aw_ready)
//            						begin
//            							state<=2;
//            						end
//            					end
//        						2:	begin
//            	    					w_data<=32'h9;//IIC 正常工作模式
//            	    					if(aw_ready)
//            							begin
//            	    						state<=3; 
//            							end
//            	    				end
//            					3:	begin
//            							w_addr<=9'h108;//TX_FIFO address 
//            							w_data<=32'h1E8;////PCA9548 的地址,这是一个1 to 8 的IIC转换芯片,一共8个通道,配置好通道后,才能与后面设备通信
//            											//也就是说,存入TX_FIFO的数据第一个是带有start的,最后一个是带有stop信号的数据
//            											//第一组传送完毕,才能传送第二组
//            							if(aw_ready)
//            	    						state<=4; 
//            						end
//            					4:	begin
//            							w_data<=32'h201;//si570 IIC 在第1路通道,选通第1路,0b0010_0000
//            							if(aw_ready)//重要:::::发完停止信号后,待总线不忙时,才能再次往TX_FIFO写数据(开始信号+数据)
//            							begin
//            								state<=5; 
//            								aw_valid<=0;
//            								w_valid<=0; 
//            								r_ready<=1;
//            								ar_valid<=1;
//            							end
//            						end
//            					5:	begin
//            							if(r_valid)
//            								if(r_data & 8'h80)//等待TX_FIFO 空
//            									state<=6;
//            						end
//            					6:	begin
//            							if(r_valid)
//            								if(!(r_data & 3'b100))////重要:::::发完停止信号后,待iic总线不忙时,才能再次往TX_FIFO写数据(开始信号+数据)
//            								begin
//            									state<=7; 
//            									aw_valid<=1;
//            									w_valid<=1; 
//            									r_ready<=0;
//            									ar_valid<=0;
//            								end
//            						end
//        						7:	begin
//            							w_data<=32'h1ba;//SI570 Clock  地址,写数据
//            							if(aw_ready)
//            							begin
//            								state<=8;
//            							end
//            						end
//            					8:	begin
//            							w_data<=30;//ADV7511 寄存器地址
//            							if(aw_ready)
//								begin
//									state<=9;
//								end
//            						end 
//            					9:	begin
//            							w_data<=32'h1bb;//ASi5324 Clock  地址,读数据
//								if(aw_ready)
//								begin
									
//									state<=10;
									
//								end
//            						end
//            					10:	begin
//            							w_data<=32'h206;//读6个字节
//            						       if(aw_ready)
//            						       begin
//										state<=11;
//										aw_valid<=0;
//										w_valid<=0; 
//										r_ready<=1;
//										ar_valid<=1;
//									end
//            						end
//            					11:	begin
//            							led2<=1;
//            							if(r_valid)
//            					         	if(r_data & 8'h80)//等待TX_FIFO 空
//            					         		state<=12;
//            						end
//            					12:	begin
//            							led0<=1;
//            							if(r_valid)
//            					        	if(!(r_data & 3'b100))//(!(r_data & 8'b01000000))////重要:::::发完停止信号后,待iic总线不忙时,才能再次往TX_FIFO写数据(开始信号+数据)
//            					        	begin
//            					        		led1<=1;
//            					        		state<=13;
//            					        		r_addr<=9'h10c;
//            					            end
//            						end
//            					13:	begin
//            							if(r_valid)
//            							begin
//            								led7<=r_data[0];
//            								led6<=r_data[1];
//            								led5<=r_data[2];
//            								led4<=r_data[3];
//            								led3<=r_data[4];
//            								led2<=r_data[5];
//            								led1<=r_data[6];
//            								led0<=r_data[7];
//            								state<=16;
//            							end
//            						end

 

你可能感兴趣的:(FPGA,Verilog)