我正在维护与FPGA器件相关的生产代码.FPGA上的早期寄存器为32位,对这些寄存器的读/写工作正常。但硬件已更改,FPGA器件和最新版FPGA器件也已更改我们在读取和写入FPGA寄存器时遇到了麻烦。在一些R& D之后,我们发现FPGA寄存器不再是32位,现在是31位寄存器,并且已经被FPGA设备供应商所声称。
因此需要更改小代码。早些时候我们检查寄存器的地址是否为4字节对齐(因为寄存器为32位)现在我们必须检查地址是31位对齐。所以我们要检查一下 如果设置了地址的最高位(这意味着它不是有效的31位)。 我想我们在这里很好。
现在第二种情况对我来说有点棘手。 如果多个寄存器的读/写将超过0x7fff-fffc(这是31位方案中的最大地址)边界,则必须小心处理请求。
多个寄存器的读取和写入需要长度作为参数,这只是要读取或写入的寄存器的数量。
例如,如果读取以0x7fff-fff8开始,并且读取的长度为5.那么实际上,我们只能读取2个寄存器(即0x7fff-fff8和0x7fff-fffc)。
现在可以有人建议我使用某种伪代码来处理这种情况
有人认为如下
while(lenght>1)
{
if(!(address<<(lenght*31) <= 0x7fff-fffc))
{
length--;
}
}
我知道这不够好,但我可以使用相同的内容。
修改
我想出了一条可满足我要求的代码
int count;
Index_addr=addr;
while(Index_add <= 7ffffffc)
{
/*Wanted to move register address to next register address,each register is 31 bit wide and are at consecutive location. like 0x0,0x4 and 0x8 etc.*/
Index_add=addr<<1; // Guess I am doing wrong here ,would anyone correct it.
count++;
}
length=count;
答案 0 :(得分:1)
我不确定我是否正确地解释了给定的场景。但是这里有一个镜头:
// Assuming "address" starts 4-byte aligned and is just defined as an integer
unsigned uint32_t address; // (Assuming 32-bit unsigned longs)
while ( length > 0 ) // length is in bytes
{
// READ 4-byte value at "address"
// Mask the read value with 0x7FFFFFFF since there are 31 valid bits
// 32 bits (4 bytes) have been read
if ( (--length > 0) && (address < 0x7ffffffc) )
address += 4;
}
答案 1 :(得分:1)
根本问题似乎是程序没有正确处理FPGA寄存器 数据封装将有所帮助,而不是将31位FPGA寄存器视为存储器位置,它们应该被抽象化。
FPGA应被视为寄存器的向量(一维数组)
N FPGA寄存器的向量应该由register index
在0x0000到 N-1 的范围内寻址。
FPGA寄存器在base addr
处进行存储器映射
所以memory address
= 4 * FPGA register index
+ base addr
。
应通过读写程序封装对FPGA寄存器的访问:
int read_fpga_reg(int reg_index, uint32_t *reg_valp)
{
if (reg_index < 0 || reg_index >= MAX_REG_INDEX)
return -1; /* error return */
*reg_valp = *(uint32_t *)(reg_index << 2 + fpga_base_addr);
return 0;
}
只要正确定义了MAX_REG_INDEX和fpga_base_addr,此代码就永远不会生成无效的内存访问。