寄存器链设计思路
一、打2拍输出的寄存器链
void register_chain_2stage(data_t input[1024], data_t output[1024]) {
// 5级寄存器链
data_t reg1, reg2;
for (int i = 0; i < 1024; i++) {
#pragma HLS PIPELINE II=1
// 移位操作
reg2 = reg1;
reg1 = input[i];
// 输出是5个周期前的输入
if (i >= 1) {
output[i-1] = reg2;
}
}
}
二、打5拍输出的寄存器链
void register_chain_5stage(data_t input[1024], data_t output[1024]) {
// 5级寄存器链
data_t reg1, reg2, reg3, reg4, reg5;
for (int i = 0; i < 1024; i++) {
#pragma HLS PIPELINE II=1
// 移位操作
reg5 = reg4;
reg4 = reg3;
reg3 = reg2;
reg2 = reg1;
reg1 = input[i];
// 输出是5个周期前的输入
if (i >= 4) {
output[i-4] = reg5;
}
}
}
三、上述的两个设计打拍存在的问题
1.寄存器链本身是没有问题的
2.存在的问题,是输出的数据少了一部分
四、如何解决少了的一部分数据?
void register_chain_5stage(data_t input[1024], data_t output[1024]) {
// 5级寄存器链
data_t reg1, reg2, reg3, reg4, reg5;
for (int i = 0; i < (1024 + 5); i++) {
#pragma HLS PIPELINE II=1
// 移位操作
reg5 = reg4;
reg4 = reg3;
reg3 = reg2;
reg2 = reg1;
if(i<1024)
reg1 = input[i];
// 输出是5个周期前的输入
if (i >= 4) {
output[i-4] = reg5;
}
}
五、寄存器链的核心设计部分
// 移位操作
reg5 = reg4;
reg4 = reg3;
reg3 = reg2;
reg2 = reg1;
reg1 = input[i];
要仔细体会,这块代码。这个和verilog和system verilog设计不一样的。
vivado hls中必须倒着写,才能实现移位的操作设计,因为这个是阻塞式的设计,不是非阻塞的设计;
阻塞式的设计,必须这么干,否则功能是不正确的。
