1.FSL总线
FSL(Fast Simplex Line)是一种快速的单向FIFO总线,提供了统一的接口,很适合于设计可重构的ip核。
总线接口:
时钟:
FSL_M_Clk:主设备给FSL总线提供的时钟信号(ip核中不用)
FSL_S_Clk:从设备给FSL总线提供的始终信号(ip核中不用)
数据(32bit):
FSL_M_Data:32bit,主设备发送到总线上的数据
FSL_S_Data:32bit,总线发给从设备的数据
控制(1bit)
FSL_M_Control:主设备发给总线的控制信号(ip核中不用)
FSL_S_Control:总线发给从设备的控制信号(ip核中不用)
FSL_M_Write:主设备正在写总线的标志位 = state==WriteOutput?~FSL_M_Full:0
FSL_S_Read:从设备从总线读数据的标志位 = state==ReadInput?FSL_S_Exists:0
FSL_M_Full:总线发出总线满信号
FSL_S_Exists:总线发出总线上有数据的信号
下面以DES加密的ip核为例
2.ip核的封装
为了可重构的考虑,可以将ip核封装为统一的模块接口:
module des_enc
(
// DO NOT EDIT BELOW THIS LINE
// Bus protocol ports, do not add or delete.
FSL_Clk,
FSL_Rst,
FSL_S_Clk,
FSL_S_Read,
FSL_S_Data,
FSL_S_Control,
FSL_S_Exists,
FSL_M_Clk,
FSL_M_Write,
FSL_M_Data,
FSL_M_Control,
FSL_M_Full
// DO NOT EDIT ABOVE THIS LINE
);
input FSL_Clk;
input FSL_Rst;
input [0 : 31] FSL_S_Data;
input FSL_S_Exists;
input FSL_M_Full;
output FSL_S_Read;
output FSL_M_Write;
output [0 : 31] FSL_M_Data;
input FSL_S_Control;
output FSL_M_Control;
input FSL_S_Clk;
input FSL_M_Clk;
des_ip_core function_instance
(
.FSL_Clk(FSL_Clk)
,.FSL_Rst(FSL_Rst)
,.FSL_S_Read(FSL_S_Read)
,.FSL_M_Write(FSL_M_Write)
,.FSL_M_Data(FSL_M_Data)
,.FSL_S_Exists(FSL_S_Exists)
,.FSL_S_Data(FSL_S_Data)
,.FSL_M_Full(FSL_M_Full)
);
为了使功能清晰,一般采用状态机的方式设计,即 Idle->ReadInput->Calculate->Delay->WriteOutput
localparam Idle = 5'b10000;
localparam Read_Inputs = 5'b01000;
localparam Calc1 = 5'b00100;
localparam Calc2 = 5'b00101;
localparam Calc3 = 5'b00110;
localparam Calc4 = 5'b00111;
localparam Delay = 5'b00010;
localparam Write_Outputs = 5'b00001;
reg [0:4] state;
case (state)
Idle:
begin
if (FSL_S_Exists == 1)
begin
state <= Read_Inputs;
nr_of_reads <= NUMBER_OF_INPUT_WORDS - 1;
end
end
Read_Inputs:
begin
if (FSL_S_Exists == 1)
begin
InBuffer[nr_of_reads]<= FSL_S_Data;
if (nr_of_reads == 0)
begin
state <= Calc1;
end
else nr_of_reads <= nr_of_reads - 1;
end
end
Calc1:
begin
state <= Calc2;
data_i <= {InBuffer[0],InBuffer[1]};
key_i <= {InBuffer[2],InBuffer[3]};
load_i <= 1;
decrypt_i <= 0;
end
Calc2:
begin
state <= Calc3;
data_i <= {InBuffer[0],InBuffer[1]};
key_i <= {InBuffer[2],InBuffer[3]};
load_i <= 0;
end
Calc3:
begin
state <= Calc4;
data_i <= {InBuffer[0],InBuffer[1]};
key_i <= {InBuffer[2],InBuffer[3]};
end
Calc4:
begin
if(ready_o)
begin
state <= Delay;
nr_of_delay <= NUMBER_OF_DELAY-1;
OutBuffer[0] <= data_o[31:0];
OutBuffer[1] <= data_o[63:32];
end
else
begin
state <= Calc4;
end
end
Delay:
begin
if(nr_of_delay == 0)
begin
state <= Write_Outputs;
nr_of_writes <= NUMBER_OF_OUTPUT_WORDS - 1;
end
else nr_of_delay <= nr_of_delay - 1;
end
Write_Outputs:
begin
if (FSL_M_Full == 0)
begin
if (nr_of_writes == 0) state <= Idle;
else nr_of_writes <= nr_of_writes - 1;
end
end
default:
state <= Idle;
endcase
1.使用XPS建立基本系统(BSB)。
2.添加FSL总线和DES ip核,并将ip核同MB通过FSL总线连接。
3.设置好FSL总线的clk和rst信号。
4.生成bit流,并导出到SDK。
5.在SDK中设计测试程序(新建板级支持包,C工程)
其中主要包括
总线操作宏的定义:
#define write_into_fsl(val, id) putfsl(val, id)
#define read_from_fsl(val, id) getfsl(val, id)
#define write_fsl0(val) write_into_fsl(val, 0)
#define read_fsl0(val) read_from_fsl(val, 0)
int main()
{
init_platform();
print("\r\n\r\n************************************************");
print("\r\nDES IP-core Test Case\n\r");
xil_printf("Build at (%s) (%s)\r\n\r\n",__DATE__,__TIME__);
xil_printf("Sizeof(Int):%d\r\n",sizeof(int));
print("Use IP-core to run application:\r\n");
int i;
for(i = 0;i<4;i++)
{
write_fsl0(DES_InBuffer[i]);
xil_printf("InBuffer[%d] = %x \r\n",i,DES_InBuffer[i]);
}
print("read done!\r\n");
for(i = 0;i<4;i++)
{
read_fsl0(DES_OutBuffer[i]);
xil_printf("OutBuffer[%d] = %x \r\n",i,DES_OutBuffer[i]);
}
print("Complete!\r\n");
xil_printf("input data:64'h%x_%x\r\n",DES_InBuffer[3],DES_InBuffer[2]);
xil_printf("input key:64'h%x_%x\r\n",DES_InBuffer[1],DES_InBuffer[0]);
xil_printf("output data:64'h%x_%x\r\n",DES_OutBuffer[2],DES_OutBuffer[3]);
cleanup_platform();
return 0;
测试结果:
************************************************
DES IP-core Test Case
Build at (Oct 25 2011) (16:16:48)
Sizeof(Int):4
Use IP-core to run application:
InBuffer[0] = DBB4E094
InBuffer[1] = 14AAD7F4
InBuffer[2] = 0
InBuffer[3] = 0
read done!
OutBuffer[0] = 0
OutBuffer[1] = 0
OutBuffer[2] = F188D850
OutBuffer[3] = 4894139E
Complete!
input data:64'h0_0
input key:64'h14AAD7F4_DBB4E094
output data:64'hF188D850_4894139E