1 / 47

嵌入式系统与结构 第 10 课 数码相机实例

嵌入式系统与结构 第 10 课 数码相机实例. 概述. 简单数码相机实现介绍 设计者的观点 需求说明 设计方案 4 种实现. Introduction. 几种技术相结合进行简单数码相机的设计 通用目的处理器 单目的处理器 定制 标准 存储器 接口设计. 简单数码相机功能 - 从用户观点. 捕获图像 以数字的形式保存图像 非胶片形式 在相机内保存多幅图像 图像的数量依赖每幅图像使用的位数和内存大小 可以把图像下载到 PC 数码相机的重要技术支持 片上系统的出现 Systems-on-a-chip 高容量的闪存存储器

kylee
Download Presentation

嵌入式系统与结构 第 10 课 数码相机实例

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 嵌入式系统与结构 第10课 数码相机实例

  2. 概述 • 简单数码相机实现介绍 • 设计者的观点 • 需求说明 • 设计方案 • 4种实现

  3. Introduction • 几种技术相结合进行简单数码相机的设计 • 通用目的处理器 • 单目的处理器 • 定制 • 标准 • 存储器 • 接口设计

  4. 简单数码相机功能-从用户观点 • 捕获图像 • 以数字的形式保存图像 • 非胶片形式 • 在相机内保存多幅图像 • 图像的数量依赖每幅图像使用的位数和内存大小 • 可以把图像下载到PC • 数码相机的重要技术支持 • 片上系统的出现 Systems-on-a-chip • 高容量的闪存存储器 • 本例采用一个非常简单的描述 • 实际相机会有更多的特性 • 可变尺寸图像,图像删除,图像放大与缩小等

  5. 设计者的观点 • 需要完成两个主要任务 • 处理图像并在存储器种保存 • 当快门按下: • 捕获图像 • 通过电荷耦合器件(CCD)转化成数字格式 • 在内存种完成压缩和保存 • 上传图像到PC • 数码相机连接到PC • 用专用软件串行的传送图像

  6. 当暴露在光下,每个单元带电荷,被转换成8bit数值, 0 表示没有曝光255表示最强的曝光 . 几列单元被遮挡,作为对所有其它单元的零偏校正. 电子机械快门使得CCD单元被曝光一个短时间段 电路获得命令后把单元放电,激活电子机械快门,读入每个单元的8bit值。这些数据通过并行总线接口读入。 Lens area Covered columns Electro-mechanical shutter Electronic circuitry Pixel rows Pixel columns 电荷耦合器件 (CCD) • 用来捕获图像的专用传感器 • 许多单元的光敏硅固态器件

  7. Covered cells Zero-bias adjustment Before zero-bias adjustment After zero-bias adjustment 零-偏差误差 • 单元的制造误差会引起测量值比实际值偏高或偏低 • 误差每一列相同,当每一行不同 • 最左的几列被用于进行零偏差校正

  8. 压缩 • 能够保存更多的图像 • 图像象PC传送更快 • JPEG (Joint Photographic Experts Group) • 数字图像压缩形式的最流行的标准 • 提供许多运算模式 • 本章采用模式使用离散余弦变换提供高压缩率 • 图像分成 8 x 8 的象素块 • 每个块执行3个运算步骤 • DCT变换 • 量化 • Huffman 编码

  9. DCT 步骤 • 将原始的8 x 8 block 转换到余弦频域 • 左上角表示图像的基本要素 • 右下角代表图像的细节 • 可以减小这些值的精度并保留可接受的图像质量 • FDCT (前向 DCT) 公式 • C(h) = if (h == 0) then 1/sqrt(2) else 1.0 • 辅助函数,主公式为 F(u,v) • F(u,v) = ¼ x C(u) x C(v) Σx=0..7 Σy=0..7 Dxy x cos(π(2u + 1)u/16) x cos(π(2y + 1)v/16) • 给出了第u行,第v列的编码象素值 • Dxy is是第x行第y列的原始象素值 • IDCT (反向DCT) • 为得到原始数据块而做的一个方向过程(本例中不使用)

  10. 量化 • 通过降低图像质量完成一个高压缩率 • 降低编码数据位精度 • 更少的位被编码 • 将所有值除2的指数倍 • 解量化是一个相反的过程 每个单元同除8 After being decoded using DCT After quantization

  11. Huffman编码 • 串行化 8 x 8 象素块 • 按照Z字形图形将这些数值转换成串行列表,然后再转成Huffman编码。 • 执行Huffman 编码 • 最经常出现的象素值分配最短二进制码 • 更长的二进制码留给更少使用的象素值 • 串行数列中的每个象素转换成Huffman 编码值 • 短的多的列表值,然后压缩

  12. Huffman codes Pixel frequencies Huffman tree 64 35 29 17 18 14 15 -1 11 10 9 6 8 5 -2 0 1 6 5 4 5 5 5 2 3 5 2 2 2 4 3 2 -5 -3 -10 1 1 1 1 1 1 -9 144 -4 -8 14 6 Huffman 编码举例 • 计算象素出现的频率 • 从低向上建立Huffman 树 • 遍历树得到叶子节点的二进制编码 • Huffman 编码是可逆的 • 任何节点不会是另一个节点的首部分

  13. 保存步骤 • 记录开始地址和图像大小 • 用链表数据结构来表示这些信息 • 保存图像的一种方案 • 若被保存的图像最大数目为N: • 为 N 个地址和 N 个图像尺寸变量保留存储器空间 • 用计数器来记录存储器下一个可用地址的位置 • 初始地址和图像尺寸变量设置成0 • 设置全局内存地址为N x 4 • 地址,图像尺寸变量占用 N x 4 bytes • 第一个保存的图像从地址N x 4开始 • 全局存储器地址更新到N x 4 + (compressed image size) • Memory 需求取决于N, 图像大小,编码得到的平均压缩比

  14. 上传到 PC • 当连接到PC 并且收到上传命令 • 从存储器中度图像 • 用UART串行发送 • 发送过程中 • 数据指针,图像尺寸变量和全局内存指针进行相应的改变

  15. 需求规范 • 系统需求 –系统应该干什么 • 非功能需求 • 设计指标约束 (e.g., “应不大于 0.001 watt”) • 功能需求 • 系统行为 (e.g., “输出 X 应为输入Y 乘以 2”) • 开始的规范可以非常笼统,可以来自市场部门 • E.g., 短文档描述低端数码相机的市场需求: • 捕获并保存至少 50幅低分辨图像,并且能上传到 PC, • 成本在$100左右,使用一个中等大小,成本低于$25的IC • 电池寿命越长越好 • 如果6个月内上市,则预期销售量为200,000 • 如果6到12个月上市,预期销售量为100,000 • 上市时间超过12个月,则销量很有限

  16. 非功能需求 • 基于初始规范确定重要设计指标 • Performance: 处理图像所需要的时间 • Size: IC 基本逻辑门的数量 (2-input NAND gate) • Power: 在处理图像时消耗的平均电能 • Energy: 电池寿命(power x time) • 约束性指标 • 值必须在某一门限值之下 • 最优化指标 • 为提高品质需要尽可能提高的指标 • 指标可以同时是约束指标和最优化指标

  17. 非功能需求 (cont.) • Performance • 必须处理图像足够快才又用 • 1 sec 是一个合理的约束 • 超过1s会觉得讨厌 • 远小于1s则在低端市场没有必要 • 因此这时一个约束指标 • Size • 必须使用IC才能得到合理尺寸的相机 • 是约束性和最优化指标 • 约束可以是 200,000 门, 但IC越小越便宜 • Power • IC必须运行在某一温度之下 (风冷不实际) • 是一个约束性指标(假设200mW) • Energy • 降低功耗或时间来降低能耗 • 优化指标: 希望电池能持续时间越长越好

  18. 零偏置调整 CCD input DCT Quantize yes Done? no 保存到内存 More 8×8 blocks? yes no 串行传输 serial output e.g., 011010... 非正式的功能规范 • 流程图将功能分成更简单的功能 • 每个功能可用文字详细描述 • 低质量图像采用分辨力64 x 64 • 没有映射每一个功能块一定要对应不同的处理器,只是对功能进行分解

  19. CCD.C 101011010110101010010101101... CODEC.C CCDPP.C image file CNTRL.C 1010101010101010101010101010... UART.C output file 精确的功能规范 • 将非正式规范细化成一个可执行的规范 • 可采用 C/C++ code to 描述每个功能 • 称为系统级模型,原型 • 是第一个可实现模型 • 能提供系统运行的深入理解 • Profiling can find computationally intensive functions • 能得到样本输出用于验证最终实现的正确性 Executable model of digital camera

  20. CCD module void CcdInitialize(const char *imageFileName) { imageFileHandle = fopen(imageFileName, "r"); rowIndex = -1; colIndex = -1; } • Simulates real CCD • CcdInitialize is passed name of image file • CcdCapture reads “image” from file • CcdPopPixel outputs pixels one at a time #include <stdio.h> #define SZ_ROW 64 #define SZ_COL (64 + 2) static FILE *imageFileHandle; static char buffer[SZ_ROW][SZ_COL]; static unsigned rowIndex, colIndex; void CcdCapture(void) { int pixel; rewind(imageFileHandle); for(rowIndex=0; rowIndex<SZ_ROW; rowIndex++) { for(colIndex=0; colIndex<SZ_COL; colIndex++) { if( fscanf(imageFileHandle, "%i", &pixel) == 1 ) { buffer[rowIndex][colIndex] = (char)pixel; } } } rowIndex = 0; colIndex = 0; } char CcdPopPixel(void) { char pixel; pixel = buffer[rowIndex][colIndex]; if( ++colIndex == SZ_COL ) { colIndex = 0; if( ++rowIndex == SZ_ROW ) { colIndex = -1; rowIndex = -1; } } return pixel; }

  21. CCDPP (CCD PreProcessing) module #define SZ_ROW 64 #define SZ_COL 64 static char buffer[SZ_ROW][SZ_COL]; static unsigned rowIndex, colIndex; • 完成 zero-bias 调整 • CcdppCapture调用 CcdCapture and CcdPopPixel获得图像 • 读入每一行后进行 zero-bias adjustment void CcdppInitialize() { rowIndex = -1; colIndex = -1; } void CcdppCapture(void) { char bias; CcdCapture(); for(rowIndex=0; rowIndex<SZ_ROW; rowIndex++) { for(colIndex=0; colIndex<SZ_COL; colIndex++) { buffer[rowIndex][colIndex] = CcdPopPixel(); } bias = (CcdPopPixel() + CcdPopPixel()) / 2; for(colIndex=0; colIndex<SZ_COL; colIndex++) { buffer[rowIndex][colIndex] -= bias; } } rowIndex = 0; colIndex = 0; } char CcdppPopPixel(void) { char pixel; pixel = buffer[rowIndex][colIndex]; if( ++colIndex == SZ_COL ) { colIndex = 0; if( ++rowIndex == SZ_ROW ) { colIndex = -1; rowIndex = -1; } } return pixel; }

  22. UART module • 实际完成了一半功能的 UART • Only transmits, does not receive • UartInitialize传送一个要输出的文件名 • UartSend一次发送一个字节 #include <stdio.h> static FILE *outputFileHandle; void UartInitialize(const char *outputFileName) { outputFileHandle = fopen(outputFileName, "w"); } void UartSend(char d) { fprintf(outputFileHandle, "%i\n", (int)d); }

  23. static short ibuffer[8][8], obuffer[8][8], idx; void CodecInitialize(void) { idx = 0; } void CodecPushPixel(short p) { if( idx == 64 ) idx = 0; ibuffer[idx / 8][idx % 8] = p; idx++; } void CodecDoFdct(void) { int x, y; for(x=0; x<8; x++) { for(y=0; y<8; y++) obuffer[x][y] = FDCT(x, y, ibuffer); } idx = 0; } short CodecPopPixel(void) { short p; if( idx == 64 ) idx = 0; p = obuffer[idx / 8][idx % 8]; idx++; return p; } CODEC module • 建模 FDCT编码 • ibuffer holds original 8 x 8 block • obuffer holds encoded 8 x 8 block • CodecPushPixel 被调用 64 times 用初始块填满 ibuffer • CodecDoFdct调用1次转换 8 x 8 block • CodecPopPixel 调用64 次从obuffer得到象素

  24. CODEC (cont.) static const short COS_TABLE[8][8] = { { 32768, 32138, 30273, 27245, 23170, 18204, 12539, 6392 }, { 32768, 27245, 12539, -6392, -23170, -32138, -30273, -18204 }, { 32768, 18204, -12539, -32138, -23170, 6392, 30273, 27245 }, { 32768, 6392, -30273, -18204, 23170, 27245, -12539, -32138 }, { 32768, -6392, -30273, 18204, 23170, -27245, -12539, 32138 }, { 32768, -18204, -12539, 32138, -23170, -6392, 30273, -27245 }, { 32768, -27245, 12539, 6392, -23170, 32138, -30273, 18204 }, { 32768, -32138, 30273, -27245, 23170, -18204, 12539, -6392 } }; • 实现 FDCT的公式 C(h) = if (h == 0) then 1/sqrt(2) else 1.0 F(u,v) = ¼ x C(u) x C(v) Σx=0..7 Σy=0..7 Dxy x cos(π(2u + 1)u/16) x cos(π(2y + 1)v/16) • 仅 64个可能输入值到COS, 因此可使用一个表来提高性能 • Floating-point values multiplied by 32,678 and rounded to nearest integer • 32,678 chosen in order to store each value in 2 bytes of memory • Fixed-point representation explained more later static short ONE_OVER_SQRT_TWO = 23170; static double COS(int xy, int uv) { return COS_TABLE[xy][uv] / 32768.0; } static double C(int h) { return h ? 1.0 : ONE_OVER_SQRT_TWO / 32768.0; } static int FDCT(int u, int v, short img[8][8]) { double s[8], r = 0; int x; for(x=0; x<8; x++) { s[x] = img[x][0] * COS(0, v) + img[x][1] * COS(1, v) + img[x][2] * COS(2, v) + img[x][3] * COS(3, v) + img[x][4] * COS(4, v) + img[x][5] * COS(5, v) + img[x][6] * COS(6, v) + img[x][7] * COS(7, v); } for(x=0; x<8; x++) r += s[x] * COS(x, u); return (short)(r * .25 * C(u) * C(v)); }

  25. void CntrlSendImage(void) { for(i=0; i<SZ_ROW; i++) for(j=0; j<SZ_COL; j++) { temp = buffer[i][j]; UartSend(((char*)&temp)[0]); /* send upper byte */ UartSend(((char*)&temp)[1]); /* send lower byte */ } } } void CntrlCompressImage(void) { for(i=0; i<NUM_ROW_BLOCKS; i++) for(j=0; j<NUM_COL_BLOCKS; j++) { for(k=0; k<8; k++) for(l=0; l<8; l++) CodecPushPixel( (char)buffer[i * 8 + k][j * 8 + l]); CodecDoFdct();/* part 1 - FDCT */ for(k=0; k<8; k++) for(l=0; l<8; l++) { buffer[i * 8 + k][j * 8 + l] = CodecPopPixel(); /* part 2 - quantization */ buffer[i*8+k][j*8+l] >>= 6; } } } void CntrlCaptureImage(void) { CcdppCapture(); for(i=0; i<SZ_ROW; i++) for(j=0; j<SZ_COL; j++) buffer[i][j] = CcdppPopPixel(); } #define SZ_ROW 64 #define SZ_COL 64 #define NUM_ROW_BLOCKS (SZ_ROW / 8) #define NUM_COL_BLOCKS (SZ_COL / 8) static short buffer[SZ_ROW][SZ_COL], i, j, k, l, temp; void CntrlInitialize(void) {} CNTRL (controller) module • 系统核心 • CntrlInitialize与其它模块一致 • CntrlCaptureImage利用 CCDPP 模块输入图像并放置到缓冲区 • CntrlCompressImage将 64 x 64 缓冲分成8 x 8 块并调用CODEC模块对每个块执行FDCT • 同时对每个块进行量化 • CntrlSendImage用UART模块发送编码图像

  26. 将模块放到一起 • Main 初始化所有的模块,然后使用CNTRL模块进行捕获,压缩和发送一个图像 • 这个系统级模型能够用于大量的实验, • 在这里进行Bugs 的纠正要比在后期模型进行纠正要容易的多 int main(int argc, char *argv[]) { char *uartOutputFileName = argc > 1 ? argv[1] : "uart_out.txt"; char *imageFileName = argc > 2 ? argv[2] : "image.txt"; /* initialize the modules */ UartInitialize(uartOutputFileName); CcdInitialize(imageFileName); CcdppInitialize(); CodecInitialize(); CntrlInitialize(); /* simulate functionality */ CntrlCaptureImage(); CntrlCompressImage(); CntrlSendImage(); }

  27. 设计过程 • 决定系统的结构 • 处理器 • 单目的与通用目的处理器的某一种结合 • 存储器,总线的选用 • 映射功能到这些结构上 • 多个功能到一个处理器上 • 一个功能到一个或多个处理器 • 实现 • 一种特定的结构和映射 • 解决方案空间是所有实现的集合 • 设计开始点 • 低端通用处理器连接到一个 • 全部功能映射到软件,在一个处理器上运行 • 一般能满足功耗,尺寸,上市时间的约束 • 如果性能约束不能满足,后续实现能够: • 利用单目的处理器设计时间约束严格的功能 • 重写功能规范

  28. 实现 1: 只使用微控制器 • 采用Intel 8051 microcontroller • 总的 IC 成本包括NRE大约$5 • 功耗远低于200 mW • 上市时间大约 3 months • 但每秒处理一幅图像不可能 • 时钟12 MHz,每条指令12 cycles • 每秒钟执行1百万指令 • CcdppCapture有嵌套循环进行4096 (64 x 64) 次遍历 • 每次遍历大约~100 汇编指令 • 每幅图像409,000 (4096 x 100) 指令 • 一半的预算用于读图像 • 加上计算密集型的DCT and Huffman encoding运算将大大超出预算

  29. EEPROM RAM 8051 UART CCDPP SOC 实现 2: 微控制器与CCDPP • CCDPP 功能利用单用途处理器实现 • 改进性能–更少的微控制器周期 • 增加了 NRE 成本和上市时间 • 易实现 • 简单的数据通道 • 控制器很少的状态 • 简单的 UART易于用单用途处理器实现 • 利用EEPROM 用于程序存储器, RAM用于数据存储器

  30. 4K ROM Instruction Decoder Controller 128 RAM ALU To External Memory Bus 微控制器 • Intel 8051 可综合版本能够获得 • VHDL编写 • 获得RTL级代码register transfer level (RTL) • 从ROM 取指令 • 译码 • ALU 执行算术运算 • 源和目的寄存器放在RAM中 • 通过外部存储器总线,用特殊的数据移动指令从外部存储器输入和存储数据 • ROM有特殊程序产生,可以读取C链接程序的输出,以产生ROM的VHDL描述 Block diagram of Intel 8051 processor core

  31. FSMD description of UART Start: Transmit LOW invoked Idle: I = 0 I < 8 Data: Transmit data(I), then I++ Stop: Transmit HIGH I = 8 UART • UART 处于空闲状态,直到被唤醒 • 当 8051用UART’s 使能寄存器作为目标地址执行存储指令时, UART被唤醒 • 内存映射的通信在8051 和全部单用途处理器之间进行 • 内存地址空间低8-bits地址分给RAM • 内存地址空间高 8-bits分给内存映射的 I/O设备 • 起始状态Start 发送 0表示数据字节发送开始,然后进入 Data 状态 • Data状态串行发送 8 bits ,然后迁移到Stop状态 • Stop state 发送1 表示发送结束,然后回到 idle mode

  32. FSMD description of CCDPP C < 66 GetRow: B[R][C]=Pxl C=C+1 Idle: R=0 C=0 invoked C = 66 R = 64 ComputeBias: Bias=(B[R][11] + B[R][10]) / 2 C=0 R < 64 NextRow: R++ C=0 C < 64 FixBias: B[R][C]=B[R][C]-Bias C = 64 CCDPP • 零偏置操作的硬件实现 • 与外部的 CCD 芯片交互 • 内部缓冲区B, 内存映射到8051 • 变量 R, C缓冲行,列索引 • GetRow 状态从CCD读一行到B • 66 bytes: 64 pixels + 2 blacked-out pixels • ComputeBias 状态计算行、列的偏移,并保存在变量 Bias • FixBias 状态遍历相同行,从每个单元减掉Bias • NextRow 迁移到 GetRow 并重复,当64行完成后转到 Idle state

  33. 连接 SOC 组件 • 内存映射 • 所有的单目的处理器核RAM都连接到 8051的 内存总线 • 读 • 处理器在16位地址总线上放置地址; • 确保1个时钟周期的读控制信号; • 1个时钟后从8bit数据总线上读数据 • 外部设备探测到读控制信号 • 检查地址 • 将被请求数据在数据总线上保持1个时钟; • 写 • 处理器在地址和数据总线上放置地址和数据; • 1个时钟周期的写控制信号 • 外部设备探测到写控制信号 • 检查地址总线 • 从数据总线上读入并保存数据。

  34. Original code from system-level model Rewritten UART module #include <stdio.h> static FILE *outputFileHandle; void UartInitialize(const char *outputFileName) { outputFileHandle = fopen(outputFileName, "w"); } void UartSend(char d) { fprintf(outputFileHandle, "%i\n", (int)d); } static unsigned char xdata U_TX_REG _at_ 65535; static unsigned char xdata U_STAT_REG _at_ 65534; void UARTInitialize(void) {} void UARTSend(unsigned char d) { while( U_STAT_REG == 1 ) { /* busy wait */ } U_TX_REG = d; } 软件的修改 • 系统级模型提供核心代码System-level model provides majority of code • 模块层次,程序名字和主程序不需要改变 • UART 和 CCDPP 模块的代码要进行重新设计 • 用内存赋值来代替 • xdata用来在外部内存总线上载入或保存变量 • _at_确定内存地址(端口地址) • 处理器发送字节到 U_TX_REG 将会调用 UART模块 • U_STAT_REG用来指示 UART 已准备好接收下一字节 • UART 会比处理器慢很多 • 类似的修改 CCDPP 代码 • 其它的模块不该变。

  35. VHDL VHDL VHDL Power equation VHDL simulator Synthesis tool Gate level simulator gates gates gates Sum gates Execution time Chip area 分析 • Entire SOC tested on VHDL simulator • Interprets VHDL descriptions and functionally simulates execution of system • Recall program code translated to VHDL description of ROM • Tests for correct functionality • Measures clock cycles to process one image (performance) • Gate-level description obtained through synthesis • Synthesis tool like compiler for SPPs • Simulate gate-level models to obtain data for power analysis • Number of times gates switch from 1 to 0 or 0 to 1 • Count number of gates for chip area Obtaining design metrics of interest Power

  36. 实现 2: 微控制器和CCDPP • 实现2的分析 • 一幅图像的总执行时间: • 9.1 seconds • 功耗: • 0.033 watt • 能耗: • 0.30 joule (9.1 s x 0.033 watt) • 总芯片面积: • 98,000 gates

  37. 实现 3: 微控制器和CCDPP/Fixed-Point DCT • 9.1 秒仍然不能满足1秒的性能约束 • DCT 操作时间作为主要的改进候选 • 实现2的执行过程显示微控制器的执行DCT操作的时间太长; • 考虑设计专用硬件完成DCT操作 • 更加复杂,需要更多的设计努力 • 同时通过修改行为来加速DCT功能。

  38. DCT 浮点运算的代价 • 浮点运算代价 • 每个象素变换中,DCT 使用~260 浮点操作 • 每个图像有4096 (64 x 64) pixels • 每个图像约执行1 million 浮点操作 • Intel 8051不支持浮点 • 编译器必须仿真浮点运算 • 每个浮点运算都要产生乘加操作 • 使用几十个整数操作 • 因此, 每个图像> 10 million 整数操作 • 增加了代码尺寸 • 浮点算法可以进行改进

  39. 固定点算法 • Integer used to represent a real number • Constant number of integer’s bits represents fractional portion of real number • More bits, more accurate the representation • Remaining bits represent portion of real number before decimal point • Translating a real constant to a fixed-point representation • Multiply real value by 2 ^ (# of bits used for fractional part) • Round to nearest integer • E.g., represent 3.14 as 8-bit integer with 4 bits for fraction • 2^4 = 16 • 3.14 x 16 = 50.24 ≈ 50 = 00110010 • 16 (2^4) possible values for fraction, each represents 0.0625 (1/16) • Last 4 bits (0010) = 2 • 2 x 0.0625 = 0.125 • 3(0011) + 0.125 = 3.125 ≈ 3.14 (more bits for fraction would increase accuracy)

  40. 固定点算法操作 • Addition • Simply add integer representations • E.g., 3.14 + 2.71 = 5.85 • 3.14 → 50 = 00110010 • 2.71 → 43 = 00101011 • 50 + 43 = 93 = 01011101 • 5(0101) + 13(1101) x 0.0625 = 5.8125 ≈ 5.85 • Multiply • Multiply integer representations • Shift result right by # of bits in fractional part • E.g., 3.14 * 2.71 = 8.5094 • 50 * 43 = 2150 = 100001100110 • >> 4 = 10000110 • 8(1000) + 6(0110) x 0.0625 = 8.375 ≈ 8.5094 • Range of real values used limited by bit widths of possible resulting values

  41. 实现CODEC的固定点运算 static const char code COS_TABLE[8][8] = { { 64, 62, 59, 53, 45, 35, 24, 12 }, { 64, 53, 24, -12, -45, -62, -59, -35 }, { 64, 35, -24, -62, -45, 12, 59, 53 }, { 64, 12, -59, -35, 45, 53, -24, -62 }, { 64, -12, -59, 35, 45, -53, -24, 62 }, { 64, -35, -24, 62, -45, -12, 59, -53 }, { 64, -53, 24, 12, -45, 62, -59, 35 }, { 64, -62, 59, -53, 45, -35, 24, -12 } }; • COS_TABLE gives 8-bit fixed-point representation of cosine values • 6 bits used for fractional portion • Result of multiplications shifted right by 6 static const char ONE_OVER_SQRT_TWO = 5; static short xdata inBuffer[8][8], outBuffer[8][8], idx; void CodecInitialize(void) { idx = 0; } static unsigned char C(int h) { return h ? 64 : ONE_OVER_SQRT_TWO;} static int F(int u, int v, short img[8][8]) { long s[8], r = 0; unsigned char x, j; for(x=0; x<8; x++) { s[x] = 0; for(j=0; j<8; j++) s[x] += (img[x][j] * COS_TABLE[j][v] ) >> 6; } for(x=0; x<8; x++) r += (s[x] * COS_TABLE[x][u]) >> 6; return (short)((((r * (((16*C(u)) >> 6) *C(v)) >> 6)) >> 6) >> 6); } void CodecPushPixel(short p) { if( idx == 64 ) idx = 0; inBuffer[idx / 8][idx % 8] = p << 6; idx++; } void CodecDoFdct(void) { unsigned short x, y; for(x=0; x<8; x++) for(y=0; y<8; y++) outBuffer[x][y] = F(x, y, inBuffer); idx = 0; }

  42. 实现 3: 微控制器和CCDPP/固定点DCT • 实现3的分析 • 使用类似实现2中的分析技术 • 一幅图像的总执行时间: • 1.5 seconds • 功耗: • 0.033 watt (same as 2) • 能耗: • 0.050 joule (1.5 s x 0.033 watt) • Battery life 6x longer!! • 总芯片面积: • 90,000 gates • 8,000 less gates (less memory needed for code)

  43. EEPROM RAM 8051 CODEC UART CCDPP SOC 实现 4: 微控制器和 CCDPP/DCT • 性能还不够好; • 必须重新用硬件来实现 CODEC • 单目的处理器执行 8 x 8 block的 DCT运算

  44. Rewritten CODEC software static unsigned char xdata C_STAT_REG _at_ 65527; static unsigned char xdata C_CMND_REG _at_ 65528; static unsigned char xdata C_DATAI_REG _at_ 65529; static unsigned char xdata C_DATAO_REG _at_ 65530; void CodecInitialize(void) {} void CodecPushPixel(short p) { C_DATAO_REG = (char)p; } short CodecPopPixel(void) { return ((C_DATAI_REG << 8) | C_DATAI_REG); } void CodecDoFdct(void) { C_CMND_REG = 1; while( C_STAT_REG == 1 ) { /* busy wait */ } } CODEC design • 4 个内存映射寄存器 • C_DATAI_REG/C_DATAO_REG用于 push/pop 8 x 8 block从/到 into and CODEC • C_CMND_REG向 CODEC发送命令 • 写1 调用 CODEC • C_STAT_REG 指示CODEC 已完成并准备下一块图像 • 用软件进行轮询 • 直接将 C code 翻译成HDL硬件实现 • 使用固定点版本 • 软件中的CODEC 模块响应的进行修改。

  45. 实现4: 微控制器和 CCDPP/DCT • 实现4的分析 • 单幅图像总执行时间: • 0.099 seconds (well under 1 sec) • 功耗: • 0.040 watt • 能耗: • 0.00040 joule (0.099 s x 0.040 watt) • Battery life 12x longer than previous implementation!! • 总芯片面积: • 128,000 gates • 比前面的实现有显著增加;

  46. 实现总结

  47. 小结 • 数码相机实例 • 规范说明用自然语言和可执行语言 • 设计特性:性能,功率和面积 • 几种实现方式 • 微控制器: 太慢! • 微控制器和协处理器:有改进,但还是慢; • 固定点算法:1.5s,几乎能满足要求; • 额外的压缩协处理器:足够快,但是设计难度大 • 软、硬件之间的权衡 –本们课程的主要内容

More Related