win70xc000000e修复 (win70xc000000e修复引导)

来源:创芯大讲堂

创芯大讲堂:EETOP旗下在线教育平台,欢迎关注。

春节期间,EETOP分享了网友通过Vivado直接板级调试时钟用的PCIE IP输出的:春节快乐时序抓取图,纯粹的硬逻辑产生。如下图:

作者:CETC41-缪国锋

实现原理:因为项目需要,需要在板子上完成PCIE接口的通信,还要完成两路AD,两路DA的调试,还有四个颗粒的内存颗粒,来完成信号的收发,FPGA用的是XC7V690T,还有时钟芯片AD9512,ADI的这些芯片多是用SPI来控制寄存器,因此我在写寄存器的时候就想把寄存器的值换成节日祝福,应该挺有新意的,就从新例化了一个module,每配置完一个寄存器自动跳转到下一个,直到所有寄存器配置完成结束,每一个寄存器位数为16位,每个汉字16个值,前后加0隔开,一共74个,时钟也可以根据需要分频更改。

经作者授权,现将实现代码公布给大家:

实现代码包含两个模块:

SPI_16Bit_Controller.v

Spi_Festival_Config.v

SPI_16Bit_Controller.v

`timescale 1ns / 1ps

//////////////////////////////////////////////////////////////////////////////////

// Company:

// Engineer:

//

// Create Date: 2019/01/29 09:18:43

// Design Name:

// Module Name: SPI_16Bit_Controller

// Project Name:

// Target Devices:

// Tool Versions:

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

//////////////////////////////////////////////////////////////////////////////////

module SPI_16Bit_Controller(

input clk_i, //SPI 控制器时钟输入,

input [15:0] spi_data,//SPI 总线时钟信号并行输入

input spi_start,//启动传输

input rst_n,//SPI 控制器复位信号

(* mark_debug = \"true\" *)input spi_miso,//SPI 总线数据信号输入

(* mark_debug = \"true\" *)output wire spi_mosi,//SPI 总线数据信号输出

(* mark_debug = \"true\" *)output wire spi_sclk,//SPI 总线时钟信号输出

(* mark_debug = \"true\" *)output wire spi_cs, //SPI 总线片选信号输出

output reg data_end//传输结束标志

);

//以下信号为测试信号

(* mark_debug = \"true\" *)reg [5:0] sd_counter;//SPI 数据发送计数器

(* mark_debug = \"true\" *)reg spi_sdo_reg;//SPI 控制器发送的串行数据

(* mark_debug = \"true\" *)reg spi_cs_reg;

(* mark_debug = \"true\" *)reg [15:0] spi_data_reg;

assign spi_sclk= (~spi_cs_reg )& ( ((sd_counter >= 2) & (sd_counter <=18))? ~clk_i :0 );

assign spi_mosi =spi_sdo_reg ; //如果输出数据为 1,spi_SDAT 设为高阻

assign spi_cs=spi_cs_reg;

//--SPI 计数器

always @(negedge rst_n or posedge clk_i )

begin

if (!rst_n) sd_counter=6'b000000;

else begin

if (spi_start==0)

sd_counter=0;

else

begin

if (sd_counter == 6'b010011)

sd_counter<=0;

else

sd_counter=sd_counter+1;

end

end

end

always @(negedge rst_n or posedge clk_i )

begin

if (!rst_n)

begin spi_cs_reg=1'b1; spi_sdo_reg=1'b0 ; data_end=1'b1;end

else

case (sd_counter)

6'd0 : begin spi_cs_reg<=1'b1;data_end<=1'b0; spi_sdo_reg=1'b0; end

////////////////////////SPI START////////////////////////////////////

6'd1 : begin spi_cs_reg<=1'b1;spi_data_reg<=spi_data;end

//发送从设备地址

6'd2 : begin spi_cs_reg<=1'b0; spi_sdo_reg<=spi_data_reg[15]; end

6'd3 : begin spi_cs_reg<=1'b0; spi_sdo_reg<=spi_data_reg[14]; end

6'd4 : begin spi_cs_reg<=1'b0; spi_sdo_reg<=spi_data_reg[13]; end

6'd5 : begin spi_cs_reg<=1'b0; spi_sdo_reg<=spi_data_reg[12]; end

6'd6 : begin spi_cs_reg<=1'b0; spi_sdo_reg<=spi_data_reg[11]; end

6'd7 : begin spi_cs_reg<=1'b0; spi_sdo_reg<=spi_data_reg[10]; end

6'd8 : begin spi_cs_reg<=1'b0; spi_sdo_reg<=spi_data_reg[9]; end

6'd9 : begin spi_cs_reg<=1'b0; spi_sdo_reg<=spi_data_reg[8]; end

6'd10: begin spi_cs_reg<=1'b0; spi_sdo_reg<=spi_data_reg[7]; end

6'd11 : begin spi_cs_reg<=1'b0; spi_sdo_reg<=spi_data_reg[6]; end

6'd12 : begin spi_cs_reg<=1'b0; spi_sdo_reg<=spi_data_reg[5]; end

6'd13 : begin spi_cs_reg<=1'b0; spi_sdo_reg<=spi_data_reg[4]; end

6'd14 : begin spi_cs_reg<=1'b0; spi_sdo_reg<=spi_data_reg[3]; end

6'd15 : begin spi_cs_reg<=1'b0; spi_sdo_reg<=spi_data_reg[2]; end

6'd16 : begin spi_cs_reg<=1'b0; spi_sdo_reg<=spi_data_reg[1]; end

6'd17 : begin spi_cs_reg<=1'b0; spi_sdo_reg<=spi_data_reg[0]; end

//////////////////////SPI STOP//////////////////////////////////////

6'd18 : begin spi_cs_reg<=1'b0; spi_sdo_reg<=1'b0; data_end<=1'b0 ; end

6'd19 : begin spi_cs_reg<=1'b1; spi_sdo_reg<=1'b0; data_end<=1'b1 ; end

default : begin spi_cs_reg<=1'b1; spi_sdo_reg<=1'b0; data_end<=1'b0 ; end

endcase

end

endmodule

Spi_Festival_Config.v 代码

`timescale 1ns / 1ps

//////////////////////////////////////////////////////////////////////////////////

// Company:

// Engineer:

//

// Create Date: 2019/01/29 08:42:10

// Design Name:

// Module Name: Spi_Festival_Config

// Project Name:

// Target Devices:

// Tool Versions:

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

//////////////////////////////////////////////////////////////////////////////////

module Spi_Festival_Config(

input clk_i, //时钟输入

input rst_n, //复位信号

input [12:0] wr_addr,

input [31:0] wr_data,

input wr_en,

input spi_miso, //SPI 总线数据信号输入

output wire spi_sclk, //SPI 总线时钟信号输出

output wire spi_mosi, //SPI 总线数据信号

output wire spi_cs //SPI 使能

);

// 内部寄存器及连线

(* mark_debug = \"true\" *)reg [15:0] spi_data_reg;

(* mark_debug = \"true\" *)reg spi_start;

(* mark_debug = \"true\" *)wire SPI_END; //寄存器并串转换结束标志位

(* mark_debug = \"true\" *)reg [15:0] reg_data;

(* mark_debug = \"true\" *)reg [7:0] addr_index;

//时钟参数

parameter CLK_Freq = 100000000; //输入的系统时钟 100MHz

parameter SPI_Freq = 50000000; //SPI 总线时钟 10MHz

//存储SPI配置数据的查找表容量

parameter LUT_SIZE = 72;

(* mark_debug = \"true\" *)reg [1:0] state;

//state machine code

localparam S_IDLE = 2'b00;

localparam S_START = 2'b01; //start bit

localparam S_STOP = 2'b10;

//////100MHz 时钟分频得到 10MHz 的 SPI 控制时钟//////

(* mark_debug = \"true\" *)reg [7:0] spi_clk_div;

(* mark_debug = \"true\" *)reg spi_ctrl_clk;

always@(posedge clk_i or negedge rst_n)

begin

if(!rst_n)

begin

spi_ctrl_clk <= 0;

spi_clk_div <= 8'h00;

end

else

begin

if( spi_clk_div ==(CLK_Freq/SPI_Freq-1'b1))

begin

spi_clk_div <= 0;

spi_ctrl_clk <= ~spi_ctrl_clk;

end

else

spi_clk_div <= spi_clk_div+1;

end

end

wire initial_en; //触发信号,可使用单脉冲做触发源;

reg initial_clr; //初始化结束清零位;

reg wr_start_en; //初始化使能开始;

assign initial_en=(wr_addr==12'h660 & wr_en);

always@(posedge clk_i)

begin

if(initial_clr)

begin

wr_start_en<=1'b0;

end

else if(initial_en)

begin

wr_start_en<=1'b1;

end

end

////////////////////// 配置过程控制 ///////////////////////

always@(posedge spi_ctrl_clk or negedge rst_n)

begin

if(~rst_n) //复位

begin

addr_index <= 0;

spi_start <= 0;

end

else

begin

if (wr_start_en)

begin

if(addr_index<LUT_SIZE)

begin

case(state)

S_IDLE: begin //第一步:准备数据,启动传输

spi_data_reg <= reg_data;

spi_start <= 1'b1;

state <= 1'b1;end

S_START:

begin

if(SPI_END) //第二步:检验传输是否正常结束

begin

state <= S_STOP;

spi_start <= 1'b0;

end

else

state <= S_START;

end

S_STOP: begin //传输结束,改变 LUT_INDEX 的值,准备传输下一个数据

addr_index <= addr_index+1;

state <= S_IDLE;end

endcase

end

else

begin

state <= S_IDLE;

addr_index<=0;

initial_clr<=1'b1;

end

end

else initial_clr<=1'b0;

end

end

///////////////////// 配置数据查找表 //////////////////////////

always @(posedge clk_i )

begin

case(addr_index)

8'd00 : begin reg_data <= 16'h0000; end

8'd01 : begin reg_data <= 16'h0000; end

8'd02 : begin reg_data <= 16'h0020; end

8'd03 : begin reg_data <= 16'h0020; end

8'd04 : begin reg_data <= 16'h0040; end

8'd05 : begin reg_data <= 16'h1140; end

8'd06 : begin reg_data <= 16'h1180; end

8'd07 : begin reg_data <= 16'h15ff; end

8'd08 : begin reg_data <= 16'h1549; end

8'd09 : begin reg_data <= 16'h7f49; end

8'd10 : begin reg_data <= 16'h7f49; end

8'd11 : begin reg_data <= 16'h1549; end

8'd12 : begin reg_data <= 16'h15ff; end

8'd13 : begin reg_data <= 16'h1180; end

8'd14 : begin reg_data <= 16'h1140; end

8'd15 : begin reg_data <= 16'h0040; end

8'd16 : begin reg_data <= 16'h0020; end

8'd17 : begin reg_data <= 16'h0020; end

8'd18 : begin reg_data <= 16'h0000; end

8'd19 : begin reg_data <= 16'h0000; end

8'd20 : begin reg_data <= 16'h0800; end

8'd21 : begin reg_data <= 16'h0800; end

8'd22 : begin reg_data <= 16'h0900; end

8'd23 : begin reg_data <= 16'h0900; end

8'd24 : begin reg_data <= 16'h7f00; end

8'd25 : begin reg_data <= 16'h7f00; end

8'd26 : begin reg_data <= 16'h0900; end

8'd27 : begin reg_data <= 16'h09ff; end

8'd28 : begin reg_data <= 16'h09ff; end

8'd29 : begin reg_data <= 16'h0900; end

8'd30 : begin reg_data <= 16'h7f20; end

8'd31 : begin reg_data <= 16'h7f20; end

8'd32 : begin reg_data <= 16'h0910; end

8'd33 : begin reg_data <= 16'h09f0; end

8'd34 : begin reg_data <= 16'h0800; end

8'd35 : begin reg_data <= 16'h0800; end

8'd36 : begin reg_data <= 16'h0000; end

8'd37 : begin reg_data <= 16'h0000; end

8'd38 : begin reg_data <= 16'h0180; end

8'd39 : begin reg_data <= 16'h0e00; end

8'd40 : begin reg_data <= 16'h7fff; end

8'd41 : begin reg_data <= 16'h7fff; end

8'd42 : begin reg_data <= 16'h0c00; end

8'd43 : begin reg_data <= 16'h0443; end

8'd44 : begin reg_data <= 16'h0842; end

8'd45 : begin reg_data <= 16'h084c; end

8'd46 : begin reg_data <= 16'h0858; end

8'd47 : begin reg_data <= 16'h7fe0; end

8'd48 : begin reg_data <= 16'h0870; end

8'd49 : begin reg_data <= 16'h084c; end

8'd50 : begin reg_data <= 16'h0846; end

8'd51 : begin reg_data <= 16'h0fc2; end

8'd52 : begin reg_data <= 16'h0041; end

8'd53 : begin reg_data <= 16'h0040; end

8'd54 : begin reg_data <= 16'h0000; end

8'd55 : begin reg_data <= 16'h0000; end

8'd56 : begin reg_data <= 16'h0006; end

8'd57 : begin reg_data <= 16'h3f8c; end

8'd58 : begin reg_data <= 16'h2098; end

8'd59 : begin reg_data <= 16'h20b0; end

8'd60 : begin reg_data <= 16'h2081; end

8'd61 : begin reg_data <= 16'h2081; end

8'd62 : begin reg_data <= 16'h2083; end

8'd63 : begin reg_data <= 16'h2ffe; end

8'd64 : begin reg_data <= 16'h2080; end

8'd65 : begin reg_data <= 16'h4080; end

8'd66 : begin reg_data <= 16'h4080; end

8'd67 : begin reg_data <= 16'h4098; end

8'd68 : begin reg_data <= 16'h408c; end

8'd69 : begin reg_data <= 16'h4086; end

8'd70 : begin reg_data <= 16'h0000; end

8'd71 : begin reg_data <= 16'h0000; end

default: begin reg_data <= 16'h0000; end

endcase

end

// 定义上位机单独配置寄存器的值,无需更改不用配置

reg pci_write_en;

reg [15:0] spi_data;

reg [7:0] wr_en_cnt;

always@(posedge clk_i)

begin

if(SPI_END)

begin

pci_write_en<=1'b0;

end

else if(wr_addr==12'h650 & wr_en)

pci_write_en<=1'b1;

end

always@(posedge clk_i)

begin

if(~rst_n)

spi_data<=16'h0000;

else

begin

if((wr_addr[12:0]==13'h640) & wr_en)

spi_data<=wr_data[15:0];

else if(spi_start)

spi_data<=spi_data_reg[15:0];

end

end

wire spi_en;

assign spi_en=pci_write_en | spi_start;

////例化 SPI 控制器 将16位并行数据完成并串转换///

SPI_16Bit_Controller SPI_16Bit_Controller_inst(

.clk_i (spi_ctrl_clk), // SPI 控制器工作时钟

.spi_sclk , // SPI 总线时钟信号

.spi_miso , // SPI 总线数据信号

.spi_mosi , // SPI 总线数据信号

.spi_cs , // SPI 总线使能信号

.spi_data (spi_data), //寄存器data

.spi_start (spi_en), // 启动传输

.data_end (SPI_END), // 传输结束标志

.rst_n (rst_n) //复位信号

);

endmodule