ICAP原语的使用
一、杂谈
有一段时间没写博客了,因为从学校回家了。现在正值肺炎流行,不给社会添麻烦,自己在家调调程序看看论文。可是今天写的icap原语在板子上的验证没通过,因为学的是icap原语是用在S6芯片上的,但是因为自己回家没带S6的开发板,这里用7系列的icape2原语进行做实验,虽然板上验证没通过,但是还是非常用实用意义。最后在这个不平稳的日子里,希望武汉加油、中国加油、一起共度难关!!!
ICAP原语的介绍
ICAP原语是S6芯片上的一个原语,这里有必要对原语的概念说明一下,我们可以把原语想象成一个IP核,只不过IP核是图形化界面,而原语就相当于生成IP核生成的.v文件,原语的使用不需要添加相应的文件。对于ISE软件,原语调用的位置如下:
其中对应的ICAP原语的调用位置如下:
其中,icap原语的内容如下:
// ICAP_SPARTAN6 : In order to incorporate this function into the design,
// Verilog : the following instance declaration needs to be placed
// instance : in the body of the design code. The instance name
// declaration : (ICAP_SPARTAN6_inst) and/or the port declarations within the
// code : parenthesis may be changed to properly reference and
// : connect this function to the design. All inputs
// : and outputs must be connected.
// <-----Cut code below this line---->
// ICAP_SPARTAN6: Internal Configuration Access Port
// Spartan-6
// Xilinx HDL Language Template, version 14.7
ICAP_SPARTAN6 #(
.DEVICE_ID(0'h4000093), // Specifies the pre-programmed Device ID value
.SIM_CFG_FILE_NAME("NONE") // Specifies the Raw Bitstream (RBT) file to be parsed by the simulation
// model
)
ICAP_SPARTAN6_inst (
.BUSY(BUSY), // 1-bit output: Busy/Ready output
.O(O), // 16-bit output: Configuartion data output bus
.CE(CE), // 1-bit input: Active-Low ICAP Enable input
.CLK(CLK), // 1-bit input: Clock input
.I(I), // 16-bit input: Configuration data input bus
.WRITE(WRITE) // 1-bit input: Read/Write control input
);
// End of ICAP_SPARTAN6_inst instantiation
这里对原语中得分几个信号的使用做出介绍:
1、DEVICE_ID:不同芯片的DEVICE_ID不相同,在使用该原语时,一定要查找对用芯片的ID,具体查找的数据手册UG380 ;
2、SIM_CFG_FILE_NAME:仿真使用,默认即可。
3、BUSY:原语对应的忙信号
4、O:配置数据的输出
5、CE:原语的使能信号,低电平有效
6、CLK:原语的时钟信号
7、I:原语配置数据的输入信号
8、WRITE:读写原语的使能信号,低电平有效
这里需要在DEVICE_ID中填入对应的ID号
然后按照上面的要求该原语得从I中输入相应的指令,FPGA才能从指定的存储地址启动。
按照上面的数据输入到ICAP原语中,FPGA便可以从制定的存储器件指定的存储地址中读取代码,这里需要注意的是I中的数据与上表中的数据要按照字节反转,这部分内容在手册中也能查找到,如下:
这里需要重点解释Opcode的含义,如下图:
该Opcode的物理意义是对用flash的读命令代码,对应镁光的一般是0x03。其余配置数据的含义从图中可以知道。有了以上信息,我们便可以操作S6系列的ICAP原语。
ICAPE2原语的介绍
由于在家没带S6的开发板,我们紧接着介绍A7开发板中ICAP原语的使用,通S6一样知道上述信息如下:
对于vivado软件,原语调用的位置如下:
其中对应的ICAP原语的调用位置如下:
其中,icap原语的内容如下:
// ICAPE2 : In order to incorporate this function into the design,
// Verilog : the following instance declaration needs to be placed
// instance : in the body of the design code. The instance name
// declaration : (ICAPE2_inst) and/or the port declarations within the
// code : parenthesis may be changed to properly reference and
// : connect this function to the design. All inputs
// : and outputs must be connected.
// <-----Cut code below this line---->
// ICAPE2: Internal Configuration Access Port
// Artix-7
// Xilinx HDL Language Template, version 2019.1
ICAPE2 #(
.DEVICE_ID(0'h3651093), // Specifies the pre-programmed Device ID value to be used for simulation
// purposes.
.ICAP_WIDTH("X32"), // Specifies the input and output data width.
.SIM_CFG_FILE_NAME("NONE") // Specifies the Raw Bitstream (RBT) file to be parsed by the simulation
// model.
)
ICAPE2_inst (
.O(O), // 32-bit output: Configuration data output bus
.CLK(CLK), // 1-bit input: Clock Input
.CSIB(CSIB), // 1-bit input: Active-Low ICAP Enable
.I(I), // 32-bit input: Configuration data input bus
.RDWRB(RDWRB) // 1-bit input: Read/Write Select input
);
// End of ICAPE2_inst instantiation
ICAPE2原语的代码
工程1的代码:
top模块的代码
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : [email protected]
// Website :
// Module Name : top.v
// Create Time : 2020-01-29 13:45:19
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module top(
input sclk ,
input rst_n ,
input key_i ,
output wire [ 3:0] led
);
//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
wire key_flag ;
//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
led led_inst(
.sclk (sclk ),
.rst_n (rst_n ),
.led (led )
);
key key_inst(
.sclk (sclk ),
.rst_n (rst_n ),
.key (~key_i ),
.key_o (key_flag )
);
icap_start icap_start_inst(
.sclk (sclk ),
.rst_n (rst_n ),
.icap_flag (key_flag ),
.icap_done ( )
);
endmodule
icap_start模块的代码:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : [email protected]
// Website :
// Module Name : icap_start.v
// Create Time : 2020-01-29 13:02:26
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module icap_start(
input sclk ,
input rst_n ,
input icap_flag ,
output reg icap_done
);
//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
wire csib ;
reg [31:0] con_data [ 7:0] ;
wire [31:0] con_data_r ;
reg [ 2:0] cnt ;
reg busy_flag ;
reg rdwrb ;
//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
initial begin
con_data[0] = 32'hFFFF_FFFF;
con_data[1] = 32'hAA99_5566;
con_data[2] = 32'h2000_0000;
con_data[3] = 32'h3002_0001;
con_data[4] = 32'h00a0_0000;
con_data[5] = 32'h3000_8001;
con_data[6] = 32'h0000_000F;
con_data[7] = 32'h2000_0000;
end
assign csib = ~busy_flag;
assign con_data_r = {con_data[cnt][24],con_data[cnt][25],con_data[cnt][26],con_data[cnt][27],con_data[cnt][28],con_data[cnt][29],
con_data[cnt][30],con_data[cnt][31],con_data[cnt][16],con_data[cnt][17],con_data[cnt][18],con_data[cnt][19],
con_data[cnt][20],con_data[cnt][21],con_data[cnt][22],con_data[cnt][23],con_data[cnt][08],con_data[cnt][09],
con_data[cnt][10],con_data[cnt][11],con_data[cnt][12],con_data[cnt][13],con_data[cnt][14],con_data[cnt][15],
con_data[cnt][00],con_data[cnt][01],con_data[cnt][02],con_data[cnt][03],con_data[cnt][04],con_data[cnt][05],
con_data[cnt][06],con_data[cnt][07]};
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
busy_flag <= 1'b0;
else if(icap_flag == 1'b1 && busy_flag == 1'b0)
busy_flag <= 1'b1;
else if(cnt == 3'd7 && rdwrb == 1'b0)
busy_flag <= 1'b0;
else
busy_flag <= busy_flag;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
cnt <= 3'd0;
else if(busy_flag == 1'b1 && rdwrb == 1'b0)
cnt <= cnt + 1'b1;
else if(cnt == 3'd7 && rdwrb == 1'b0)
cnt <= 3'd0;
else
cnt <= cnt;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
icap_done <= 1'b0;
else if(cnt == 3'd7 && rdwrb == 1'b0)
icap_done <= 1'b1;
else
icap_done <= 1'b0;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
rdwrb <= 1'b1;
else if(cnt == 3'd7 && rdwrb == 1'b0)
rdwrb <= 1'b1;
else if(busy_flag == 1'b1)
rdwrb <= 1'b0;
else
rdwrb <= rdwrb;
ICAPE2 #(
.DEVICE_ID (32'h3631093 ), // Specifies the pre-programmed Device ID value to be used for simulation
// purposes.
.ICAP_WIDTH ("X32" ), // Specifies the input and output data width.
.SIM_CFG_FILE_NAME ("NONE" ) // Specifies the Raw Bitstream (RBT) file to be parsed by the simulation
)ICAPE2_inst(
.O ( ), // 32-bit output: Configuration data output bus
.CLK (sclk ), // 1-bit input: Clock Input
.CSIB (csib ), // 1-bit input: Active-Low ICAP Enable
.I (con_data_r ), // 32-bit input: Configuration data input bus
.RDWRB (rdwrb ) // 1-bit input: Read/Write Select input
);
//========================================================================================\
//******************************* Debug **********************************
//========================================================================================/
ila_0 ila_0_inst (
.clk (sclk ), // input wire clk
.probe0 (icap_flag ), // input wire [0:0] probe0
.probe1 (icap_done ), // input wire [0:0] probe1
.probe2 (csib ), // input wire [0:0] probe2
.probe3 (rdwrb ), // input wire [0:0] probe3
.probe4 (con_data_r ) // input wire [31:0] probe4
);
endmodule
led模块的代码:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : [email protected]
// Website :
// Module Name : led.v
// Create Time : 2020-01-30 11:47:29
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module led(
input sclk ,
input rst_n ,
output reg [ 3:0] led
);
//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
led <= 4'b0000;
else
led <= 4'b1010;
endmodule
key模块的代码:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : [email protected]
// Website :
// Module Name : key.v
// Create Time : 2020-01-05 13:49:36
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module key(
input sclk ,
input rst_n ,
input key ,
output reg key_o
);
//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
parameter IDLE = 4'b0001 ;
parameter S1 = 4'b0010 ;
parameter S2 = 4'b0100 ;
parameter S3 = 4'b1000 ;
reg [ 3:0] state ;
reg [ 9:0] cnt ;
reg key_r1 ;
reg key_r2 ;
reg key_r3 ;
reg nege_flag ;
reg pose_flag ;
//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
always @(posedge sclk)
key_r1 <= key;
always @(posedge sclk)
key_r2 <= key_r1;
always @(posedge sclk)
key_r3 <= key_r2;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
nege_flag <= 1'b0;
else if(key_r3 == 1'b1 && key_r2 == 1'b0)
nege_flag <= 1'b1;
else
nege_flag <= 1'b0;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
pose_flag <= 1'b0;
else if(key_r3 == 1'b0 && key_r2 == 1'b1)
pose_flag <= 1'b1;
else
pose_flag <= 1'b0;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
state <= IDLE;
else case(state)
IDLE : if(nege_flag == 1'b1)
state <= S1;
else
state <= IDLE;
S1 : if(cnt == 10'd999)
state <= S2;
else if(pose_flag == 1'b1)
state <= IDLE;
else
state <= S1;
S2 : if(pose_flag == 1'b1)
state <= S3;
else
state <= S2;
S3 : if(cnt == 10'd999)
state <= IDLE;
else if(nege_flag == 1'b1)
state <= S2;
else
state <= S3;
default : state <= IDLE;
endcase
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
cnt <= 10'd0;
else if(state != S1 && state != S3)
cnt <= 10'd0;
else
cnt <= cnt + 1'b1;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
key_o <= 1'b0;
else if(state == S1 && cnt == 10'd999)
key_o <= 1'b1;
else
key_o <= 1'b0;
endmodule
工程2的代码:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : [email protected]
// Website :
// Module Name : led.v
// Create Time : 2020-01-30 11:47:29
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module led(
input sclk ,
input rst_n ,
output reg [ 3:0] led
);
//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
led <= 4'b0000;
else
led <= 4'b1010;
endmodule
验证
上面的程序是我按照ICAP原语的使用直接扩展到ICAPE2原语上面,上板结果有点小问题,但是按照该方法写ICAP原语是没问题的,应该是自己对ICAPE2的使用还没熟悉,等回到学校仔细读了技术手册再做相应的改正。
结束语
创作不易,认为文章有帮助的同学们可以收藏点赞支持。(工程也都在群中)对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群: