接这篇文章,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