The use of ICAP primitives in FPGA -- the implementation of Multiboot function

Use of ICAP primitives First, gossip Introduction of ICAP primitives Introduction of ICAPE2 primitive Code of ICAPE2 primitive Verification Concludin...

Use of ICAP primitives

First, gossip

I haven't blogged for a while, because I went home from school. Now is the prevalence of pneumonia, not to add trouble to the community, their own adjustment procedures at home to see the paper. However, the verification of the icap primitives written today on the board failed, because the learning is that the icap primitives are used on the S6 chip, but because I didn't bring the development board of S6 home, I used 7 series of icape2 primitives to do the experiment here. Although the verification on the board failed, it is still not commonly used. Finally, in this unstable day, I hope that Wuhan refueling, China refueling, together to pass the difficulty!!!

Introduction of ICAP primitives

ICAP primitive is a primitive on S6 chip. It is necessary to explain the concept of primitive here. We can think of the primitive as an IP core, but the IP core is a graphical interface, and the primitive is equivalent to generating. v files generated by the IP core. The use of primitive does not need to add corresponding files. For ISE software, the location of primitive call is as follows:

The call location of the corresponding ICAP primitive is as follows:


Among them, the content of icap primitive is as follows:

// 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

Here is an introduction to the use of several signals scored in the primitive:
1. Device ID: the device ID of different chips is different. When using this primitive, it is necessary to find the ID of the chip to be used, and the specific data manual UG380 to be found;
2. Sim? CFG? File? Name: for simulation, it is OK by default.
3. BUSY: BUSY signal corresponding to primitive
4. O: output of configuration data
5. CE: enable signal of primitive, effective at low level
6. CLK: clock signal of primitive
7. I: input signal of primitive configuration data
8. WRITE: enable signal of read-WRITE primitive, effective at low level

Here, you need to fill in the corresponding ID number in the device? ID
Then according to the above requirements, the primitive has to input the corresponding instructions from I before the FPGA can start from the specified storage address.

Input the above data into the ICAP primitive, FPGA can read the code from the storage address specified by the memory device. Note that the data in I and the data in the table above should be inverted by bytes. This part can also be found in the manual, as follows:

Here we need to focus on the meaning of Opcode, as shown in the following figure:

The physical meaning of the Opcode is to read the command code with flash, and the corresponding mg light is generally 0x03. The meaning of the rest of the configuration data can be seen from the diagram. With the above information, we can operate the ICAP primitive of S6 series.

Introduction of ICAPE2 primitive

Since there is no development board with S6 at home, we will then introduce the use of ICAP primitives in the A7 development board. Through S6, we know the above information as follows:
For vivado software, the location of primitive call is as follows:

The corresponding call location of ICAP primitive is as follows:
Among them, the content of icap primitive is as follows:

// 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



Code of ICAPE2 primitive

Code for project 1:
Code of top module

`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

Code of icap_start module:

`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 module code:

`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

Code of key module:

`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

Code for project 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
Verification

The above procedure is that I directly extended to ICAPE2 primitives according to the use of ICAP primitives. There was a little problem in the result of board loading, but there is no problem in writing ICAP primitives according to this method. It should be that I am not familiar with the use of ICAPE2. I will read the technical manual carefully and make corresponding corrections when I return to school.

Concluding remarks

Creation is not easy. Students who think the article is helpful can collect some praise and support. (projects are also in the group) students who have any opinions on the article or need to communicate further can join the following group:

Rotten moon Published 15 original articles, won praise 6, visited 4526 Private letter follow

30 January 2020, 04:29 | Views: 2249

Add new comment

For adding a comment, please log in
or create account

0 comments