【Vivado那些事】简谈FPGA比特流结构

比特流是一个常用词汇,用于描述包含FPGA完整内部配置状态的文件,包括布线、逻辑资源和IO设置。大多数现代FPGA都是基于SRAM的,包括Xilinx Spartan和Virtex系列。在FPGA上电或随后的FPGA重新配置期间,比特流从外部诸如闪存这样的非易失性存储器中读取,通过FPGA配置控制器的处理,加载到内部的配置SRAM中。

在有些情况下,设计者需要很好地了解FPGA比特流的内部结构。例如,使用FPGA物理实现工具的参数不能访问自定义的低级比特流、实现复杂的配置回溯方案、通过内部配置端口(ICAP)产生用于FPGA重新配置的短命令序列、读配置状态等。遗憾的是,逆向工程和篡改比特流以非法获取专利设计信息也属于这些使用范畴。

比特流格式

Xilinx FPGA的比特流结构如图1所示。

比特流包括以下组成部分:填充、同步字、用于访问配置寄存器的命令、存储器帧和解同步字。

填充

填充的数据是全0或全1序列,被FPGA配置控制器忽略。填充数据用于非易失性存储器中分离比特流。一般使用全1填充较为方便,因为执行擦除后闪存的状态一般也是全1。

同步字

同步字是一个特殊值(0xAA995566),通知FPGA配置控制器处理后续的比特流数据。

解同步字

解同步字通知FPGA配置控制器比特流的末端位置。解同步字之后,所有的比特流数据被忽略,直到遇到下一个同步字。

命令

命令用于读和写FPGA配置控制器寄存器。每个比特流中出现的一些命令,有的是ID-CODE,用于标识比特流属于哪个FPGA器件。帧地址寄存器(FAR)、帧数据寄存器(FDRI)和无操作(NOOP)将被忽略。

存储器帧

存储器帧是配置Xilinx FPGA的比特流基本单元。帧的大小与具体的FPGA系列有关,系列不同,帧的大小也不同。Virtex 6器件的帧有2592位。每个Virtex 6器件具有的帧数不同,从最小7491(对于LX75T)到最大55548(对于LX550T)。帧用于多个逻辑片、IO、BRAM及其他FPGA的配置。每帧都有一个地址,对应于FPGA配置空间的位置。比特流使用FAR和FDRI命令序列来配置帧。

Virtex 6 FPGA配置用户指南包含足够的关于比特流和访问FPGA配置控制器寄存器命令的文档。然而,关于存储器帧的详细文档不仅对于Xilinx FPGA无法获得,而且对于其他供应商的FPGA也是如此。

Xilinx的BITGEN实用程序

BITGEN是Xilinx的实用程序,利用本地电路描述(NCD)格式的布局布线后文件,创建用于FPGA配置的比特流。BITGEN是一个高度可配置的工具,具有100多个命令行选项(在命令行工具用户指南(Xilinx Command Line Tools User Guide,http://www.xilinx.com/support/documentation/sw_manuals/xilinxl 2_2/devref.pdf)中描述)。有些选项用于确定比特流输出格式、启用压缩处理减少比特流大小、提高FPGA配置速度、使用CRC来确保数据完整性、对比特流加密等。

示例

以下示例用于根据差异部分配置的短比特流, 通过脚本语言描述比特流命令。

#!/devl/perl/bin/perluse Switch;# -----------------------------------------------------------------------------
#  Copyright (C) 2011 OutputLogic.com
#  This source file may be used and distributed without restriction
#  provided that this copyright statement is not removed from the file
#  and that any derivative work contains the original copyright notice
#  and the associated disclaimer.
#
#  THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS
#  OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
#  WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
# -----------------------------------------------------------------------------
#
# A script to parse Xilinx FPGA bitstream in .RBT format
#
if ($#ARGV < 0)
{die "Usage: xilinx_bitstream_parser <rbt file>\n";
}$verbose = 2;open(RBT_FILE,"<$ARGV[0]")          || die "Error: can't open $ARGV[0] for input\n";# Bus OP codes
$opcode{"00"} = "no op";
$opcode{"01"} = "read";
$opcode{"10"} = "write";
$opcode{"11"} = "decrypt";# Regster Addresses
$reg{"00000"} = "CRC ";
$reg{"00001"} = "FAR ";
$reg{"00010"} = "FDRI";
$reg{"00011"} = "FDRO";
$reg{"00100"} = "CMD ";
$reg{"00101"} = "CTL ";
$reg{"00110"} = "MASK";
$reg{"00111"} = "STAT";
$reg{"01000"} = "LOUT";
$reg{"01001"} = "COR ";
$reg{"01010"} = "MFWR";
$reg{"01011"} = "CBC ";
$reg{"01100"} = "ID  ";
$reg{"01101"} = "AXSS";
$reg{"01110"} = "COR1";
$reg{"01111"} = "CSOB";
$reg{"10000"} = "WBSTAR";
$reg{"10001"} = "TIMER";
$reg{"10010"} = "RBCRC0";
$reg{"10011"} = "RBCRC1";
$reg{"10100"} = "RBCRC2";
$reg{"10101"} = "EFAR";
$reg{"10110"} = "BOOTSTS";
$reg{"10111"} = "TESTMODE";
$reg{"11000"} = "CTL1";# Configuration Commands
$command{"00000"} = "NULL";
$command{"00001"} = "WCFG";
$command{"00010"} = "MFW";
$command{"00011"} = "LFRM";
$command{"00100"} = "RCFG";
$command{"00101"} = "START";
$command{"00110"} = "RCAP";
$command{"00111"} = "RCRC";
$command{"01000"} = "AGHIGH";
$command{"01001"} = "SWITCH";
$command{"01010"} = "GRESTORE";
$command{"01011"} = "SHUTDOWN";
$command{"01100"} = "GCAPTURE";
$command{"01101"} = "DESYNCH";
$command{"01110"} = "DRTEST";
$command{"01111"} = "IPROG";
$command{"10000"} = "CRCC";$fa = -1;
$last_fa = -1;
$in_LOUT = 0;
@LOUT_wordcnt = ();while (<RBT_FILE>)
{$type = "";$op   = "";$reg  = "";chop;next if (! /^[01]/);   if (/^10101010100110010101010101100110/) {$type = "Sync word";}elsif (/^11111111111111111111111111111111/) {$type = "Dummy word";}elsif (/^00000000000000000000000010111011/) {$type = "Bus Width word ";}elsif (/^00010001001000100000000001000100/) {$type = "8/16/32 BusWidth";}elsif (/^001/) {$type = "Type 1";}elsif (/^010/) {$type = "Type 2";}elsif (/^00000000000000000000000000000000/) {$type = "NO OP";$wordcnt = 0;}else {if (($register eq "FDRI") || ($register eq "FDRO") || ($last_command eq "LFRM")) {$type = "Partial CRC word";}else{$type = "Type Unknown";}}if ($type eq "Type 1" || $type eq "Type 2")    {$s = substr($_,3,2);if ($opcode{$s} ne "") {$op = $opcode{$s};}else {$op = "Unknown";}}if ($type eq "Type 1") {$s = substr($_,14,5);if ($reg{$s} ne "") {$register = $reg{$s};}else {$register = "Unknown";}$wordcnt = &bin2dec(substr($_,21,11));}if ($type eq "Type 2"){$wordcnt = &bin2dec(substr($_,5,27));}$text = "$type";if ($op eq "read") {$text .= " $op " . "$wordcnt words from " . "$register";}elsif (($op eq "write") || ($op eq "decrypt")){$text .= " $op " . "$wordcnt words to " . "$register";}elsif ($op eq "no op") {$text .= " NO OP";}printf ("%10s %s\n", &bin2hex($_), $text);# A little hack so we can see the next stream alsoif (($register eq "LOUT") && ($wordcnt > 1)) {$in_LOUT++;push @LOUT_wordcnt, $wordcnt;$wordcnt = 0;}# start printing out everythingfor ($i=0; $i<$wordcnt && (($op eq "write") || ($op eq "decrypt") || ($op eq "read")) && ($_ = <RBT_FILE>); $i++) {chop;if (($op eq "write") && ($register eq "FAR ")){$fa = $_;}if (($register eq "FDRI") || ($register eq "FDRO")) {# printf ("%s %10s\n", "data word " . $i, $_ );# don't print all frame wordsif ($i == 0) {printf ("%s %d...%d \n", "data words " , $i , $wordcnt-1);}}elsif ($register eq "LOUT") {$this_fa = &bin2dec($_);$BlkType = &bin2dec(substr($_,8,3));$TopBot  = (&bin2dec(substr($_,11,1)) == 0) ? "Top" : "Bot";$MajRow  = &bin2dec(substr($_,12,5));$MajCol  = &bin2dec(substr($_,17,8));$MinCol  = &bin2dec(substr($_,25,7));printf ("%10s %s [Block %d %s Row %d Col %d Minor %d] \n", &bin2hex($_) , "Frame Address", $BlkType, $TopBot, $MajRow, $MajCol, $MinCol);        if ($this_fa < $last_fa) {printf ("ERROR: Frame Address going down (%d < %d)?\n", $this_fa, $last_fa);}$last_fa = $this_fa;}elsif ($register eq "FAR ") {$BlkType = &bin2dec(substr($_,8,3));$TopBot  = (&bin2dec(substr($_,11,1)) == 0) ? "Top" : "Bot";$MajRow  = &bin2dec(substr($_,12,5));$MajCol  = &bin2dec(substr($_,17,8));$MinCol  = &bin2dec(substr($_,25,7));printf ("%10s %s [Block %d %s Row %d Col %d Minor %d] \n", &bin2hex($_) , $register . " data word " . $i, $BlkType, $TopBot, $MajRow, $MajCol, $MinCol);            }elsif ($register ne "CMD ") {printf ("%10s %s\n", &bin2hex($_) , $register . " data word " . $i);} else {$s = substr($_,27,5);if ($command{$s} ne "") {$last_command = $command{$s};printf ("%10s %s\n", &bin2hex($_), $command{$s} . " command",  );}else{printf ("%10s %s\n", &bin2hex($_), "Unknown command" );}}}
} # whileclose(RBT_FILE);sub bin2dec
{local($num) = @_;$retval = 0;while ($num ne ""){$retval = $retval * 2;if (substr($num,0, 1) eq "1") {$retval++;}$num = substr($num,1);}return $retval;
}# convert 32-digit bin number to hex
sub bin2hex
{local($num) = @_;my $str_hex = "";for ($i=0; $i<8; $i++) {# left to rightmy $chunk = substr($num, 4 * $i ,4); my $retval = "0";switch ($chunk) {case "0000" { $retval = "0" }case "0001" { $retval = "1" }        case "0010" { $retval = "2" }case "0011" { $retval = "3" }        case "0100" { $retval = "4" }case "0101" { $retval = "5" }        case "0110" { $retval = "6" }case "0111" { $retval = "7" }        case "1000" { $retval = "8" }case "1001" { $retval = "9" }        case "1010" { $retval = "A" }case "1011" { $retval = "B" }        case "1100" { $retval = "C" }case "1101" { $retval = "D" }        case "1110" { $retval = "E" }case "1111" { $retval = "F" }        }#  print $chunk. " : " . $retval . "\n";$str_hex .= $retval;}#  print $str_hex;    return $str_hex;
}

关于脚本的使用,可以查看《Verilog数字系统基础设计-CRC》。

仔细观察比特流,能区分出同步和解同步命令、属于Virtex-6 LX240T FPGA的IDCODE,以及两个405个和243个字的帧。

上诉脚本及比特流文件如下:

** 链接:https://pan.baidu.com/s/1nXknXYGbiDGx6e4YOb3zrg 提取码:open  **

参考资料

Xilinx UG360

Xilinx Command Line Tools User Guide

推荐阅读

【Vivado那些事】如何查找官网例程及如何使用官网例程

【Vivado使用误区与进阶】总结篇

【Vivado那些事】Vivado中常用的快捷键(二)其他常用快捷键

SystemVerilog数字系统设计_夏宇闻 PDF

图书推荐|ARM Cortex-M0 全可编程SoC原理及实现

1202年了,还在使用虚拟机吗?Win10安装Ubuntu子系统及图形化界面详细教程

Github 上有哪些优秀的 VHDL/Verilog/FPGA 项目

AD936x+ZYNQ搭建OpenWIFI

面试中经常会遇到的FPGA基本概念,你会几个?

Xilinx FPGA MIPI 接口简单说明

介绍一些新手入门FPGA的优秀网站

Vivado ML(机器学习) 2021尝鲜

推荐一些可以获取免费的国外的原版书籍(电子版)网站

FPGA 的重构

浅析FPGA局部动态可重构技术

ISP(图像信号处理)算法概述、工作原理、架构、处理流程

国产CPU概括

从电子游戏历史看IC发展的助推剂

80年代电子游戏及电脑游戏的发展历史

PCIe总线的基础知识

万字长文带你回顾电子游戏的七十多年历史(完整版)

FPGA中异步复位,同步释放的理解

OpenFPGA系列文章总结

用Verilog设计一个16 位 RISC 处理器

介绍一些新手入门FPGA的优秀网站(新增)
如何提高FPGA的工作频率

【Verilog】深入理解阻塞和非阻塞赋值的不同

简谈 Xilinx FPGA 原理及结构

【官方推荐】学习Zynq-7000的入门书单

【Vivado那些事】Xilinx 7系列时钟结构详解
Verilog数字系统基础设计-CRC

点击上方字体即可跳转阅读

【Vivado那些事】简谈FPGA比特流结构相关推荐

  1. 简谈FPGA比特流结构

    比特流是一个常用词汇,用于描述包含FPGA完整内部配置状态的文件,包括布线.逻辑资源和IO设置.大多数现代FPGA都是基于SRAM的,包括Xilinx Spartan和Virtex系列.在FPGA上电 ...

  2. FPGA知识汇集-了解FPGA比特流结构

    比特流是一个常用词汇,用于描述包含FPGA完整内部配置状态的文件,包括布线.逻辑资源和IO设置.大多数现代FPGA都是基于SRAM的,包括Xilinx Spartan 和Virtex 系列.在FPGA ...

  3. 简谈FPGA的上电复位

    简谈FPGA的上电复位 今天和大侠简单聊一聊FPGA设计中的上电复位,话不多说,上货. 在基于verilog的FPGA设计中,我们常常可以看到以下形式的进程: 信号rst_n用来对进程中所用变量的初始 ...

  4. 简谈FPGA设计中不同设计方法资源消耗对比

    简谈FPGA设计中不同设计方法资源消耗对比 今天和大侠简单聊一聊FPGA设计中不同设计方法硬件资源消耗对比,话不多说,上货. 在这里,我们使用Verilog HDL 设计计数器,通过两种不同的写法,对 ...

  5. Zynq 开发板FPGA比特流文件下载方式

    Zynq开发板FPGA比特流文件可以通过三种途径下载: 1. 利用SDK生成的FSBL.elf文件自动加载FPGA比特流配置文件,将比特流文件,FSBL.elf文件和u-boot.elf文件利用SDK ...

  6. FPGA工具vivado中约束文件格式错误导致比特流生成失败

    在vivado中生成比特流时,综合和实现都能成功,在最后一步bit 的生成出现报错. 检查代码.约束都没发现什么错误. 最后发现约束文件有一个小小的格式错误,改正后,bit流成功生成 改正前(T11后 ...

  7. Zynq动态更新FPGA比特流

    https://blog.csdn.net/vinnie__/article/details/52829874 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn ...

  8. 【Vivado那些事】Xilinx 7系列时钟结构详解

    Xilinx 7系列时钟结构 xilinx 的 FPGA 时钟结构,7 系列 FPGA 的时钟结构和前面几个系列的时钟结构有了很大的区别,7系列的时钟结构如下图所示. Clock Region:FPG ...

  9. 无招胜有招-Vivado非工程模式下的FPGA设计流程

    参考:UG892 UG835 Vivado集成开发工具为设计者提供了非工程模式下的FPGA设计流程.在Vivado非工程模式下,FPGA开发人员可以更加灵活地对设计过程的每个阶段进行控制,从而进一步提 ...

最新文章

  1. 数据化管理在餐饮业中的应用
  2. 深度学习对机器人有多大的影响
  3. 我的一次尴尬的维护经历
  4. 机器学习中有哪些距离度量方式
  5. HihoCoder - 1877 Approximate Matching(AC自动机+dp)
  6. MyBatis之八:需要说明的几个java api的生命周期以及封装
  7. python requests编码的问题_python requests 编码问题
  8. 【转】win32 的DLL中创建windows窗口
  9. 【iOS开发】崩溃问题汇总
  10. 查找文件中每行第二个单词_日语单词中的长短音区别在哪里,日语长短音发音有什么规律...
  11. win10子系统 php,启用 Win10 的 Linux 子系统
  12. 当子元素用position:relative;时,父元素的overflow:hidden;在ie中失效的解决办法
  13. Threat Risk Modeling Learning
  14. win10自带sftp服务器_用于Windows系统的免费SFTP服务器-Free SFTP Servers及各款软件功能对比...
  15. vim 常用的快捷键
  16. redis3.0源码学习之可持久化化操作
  17. CDN是什么?以及CDN的原理
  18. docker学习(十三)docker安装dejavu
  19. 大数据系统包含哪些组件?需要过等保吗?
  20. 计算机考研360能去哪里,考研360分是什么水平

热门文章

  1. Python 之 处理 Excel 数据(2)—— 读取数据
  2. 计算机专业湖北二本大学排名及分数线,2019-2020湖北二本大学排名及分数线(理科+文科)...
  3. SpringCloud-服务调用
  4. WorkStation创建linux虚拟机
  5. 数字电子技术实验作业(8)
  6. Canvas 使用 toDataUrl 导出图片的各类错误
  7. Echarts之甘特图type: ‘custom‘参数详解
  8. html双击事件 jq,jQ双击事件用原生写的方法.html
  9. selenium登录 京东滑动验证码
  10. 三年级计算机教案 渔舟唱晚,大班艺术教案:渔舟唱晚