当前位置: 首页 > news >正文

青岛做网站公司电话免费建工作室网站

青岛做网站公司电话,免费建工作室网站,wordpress分享文章插件,电商网站商品页的优化目标是什么?Introduction 功耗是当今许多技术都要考虑的重要因素。例如#xff0c;手机生产商总是谈论他们在电源管理方面的改进#xff0c;以及如何延长电池的使用寿命。功能与功耗之间的平衡是许多人都在研究的有趣课题。然而#xff0c;当我们做实验时#xff0c;我们很少会考虑我…Introduction 功耗是当今许多技术都要考虑的重要因素。例如手机生产商总是谈论他们在电源管理方面的改进以及如何延长电池的使用寿命。功能与功耗之间的平衡是许多人都在研究的有趣课题。然而当我们做实验时我们很少会考虑我们消耗了多少电能因为我们从来没有受到电能的限制。在本课实验 3 中合成巨型鼓时我们耗尽了 FPGA 上的所有 DSP 块并使用了大量 M10K 内存。这种对硬件的大量使用很可能会导致高功耗我们很想知道有哪些因素会影响 FPGA 的功耗。带着这个目标我们构建了一个电路使用基于 I2C 的电流传感器 MIKROE-2987 测量流经电源电缆的电流同时假设有稳定的 12V 电压供应并在 FPGA 中实施了一个带积分器的 I2C 接收器以持续增加消耗的能量。根据获得的数据我们在 VGA 上建立了一个直观的用户界面显示电流、实时功率和平均能量以监控 DE1-SoC 的功耗。 Design testing methods design overview 功率估算器的整体设计如图 1 所示。MIKOE-2987 利用霍尔效应测量通过内部熔断器输入引脚的电流具有约 1.2m Ω 的极低串联电阻不会影响提供给 FPGA 的电流。 该电路板使用 I2C 接口SDA 表示数据SCL 表示时钟来传输经过处理的电流数据。根据规范我们在 FPGA 中构建了 I2C 主站作为接收器将比特流转换为实际的高分辨率电流数据并以有效信号传递给 HPS。 该接收器还包含一个乘法器和积分器分别用于计算实时功率和累积能量。它由 HPS 控制以实现复位、启动和停止。HPS 将处理数据并在 VGA 上显示相应的用户界面。为了加快调试我们还采用了 7 段显示器来显示测量到的电流。 图 1功率估算器的总体设计 Hardware design 我们都知道物理课上的公式 PI∗V 表示功率W∑tP∗dt 表示能量这两个简单的公式就是本项目的精髓。根据电源适配器的规格可提供稳定的 12V 电压。在这种情况下实时功率通过一个乘法器来计算 I∗12。 至于消耗的功率我们设计了一个与 Lab1 相同的积分器在计算开始后以单位时间 P∗dt 为每个可用采样点增加能量dt 取决于采样率。 这个项目的关键在于我们需要一种方法来测量电源适配器提供的电流以便计算功率和能量。在网上进行了一番研究后我们决定使用 MIKROE-2987 电流测量板原因如上所述。 该电流传感器的输出进入一个 12 位 ADC并通过 MCP3221 的 I2C 接口提供。因此我们在 FPGA 中建立了 I2C 主接收器以便与之通信。 MCP3221 的 I2C 协议如图 2 所示。I2C 通信只涉及 2 根导线SDA 用于数据SCL 用于时钟。SCL 是单向的由 I2C 接收器提供而 SDA 是双向的可由主设备I2C 接收器或从设备MCP3221控制。 图 2MCP3221 指定的 I2C 协议 根据数据手册主站和从站之间的每个事务长度应为 8 位并总是在 ACK/NAK 之后。当 MCP3221 不忙时SDA 和 SCL 都将置高。 要启动数据交易主设备必须在 SCL 为高电平时将 SDA 线路从高电平拉低到低电平从而发出启动条件信号。 当芯片被唤醒时它将接收来自主站的地址字节以便在 SDA 中配置芯片。前 4 位是设备位后 3 位是地址位最后一位是 R/W 选择位。我们将其默认配置为 1001_101_1以便从芯片读取数据。 当接受到一个有效的地址字节时芯片会将 SDA 设置为低电平作为 ACK 信号然后开始提供数据。每次提供的数据以字节为单位。当提供完一个字节后需要主站发出低电平有效的 ACK 信号以便从站继续提供数据。 由于数据为 12 位形式因此需要两个字节我们称之为上字节和下字节来完成一个数据交易上字节的前四位为零。 当主站发出连续 ACK 时从站将继续提供当前值而不会重复地址字节。 要终止交易主站可在 SCL 也为高电平时将 SDA 拉高从而产生 NAK在 SCL 为高电平时将 SDA 从低电平拉高从而以停止条件结束交易。值得注意的是SDA 线路的变化应始终发生在 SCL 为低电平时并在时钟的高电平部分保持稳定启动和停止条件除外而且每个数据位应有一个时钟脉冲。 根据上述 I2C 协议我们在 SystemVerilog 中开发了一个 11 状态的 FSM如图 3 所示。 在 IDLE 状态下SDA 和 SCL 都将切换。当检测到来自 HPS 的启动信号时将提供启动条件然后传输地址字节。 当内部计数器检测到地址字节已传送完毕时将对从站进行确认。否则主站将回到 IDLE 状态。如果提供了 ACK主站将在收到数据后接收从站的上下字节。 在 STATE_DATA_RECEIVED_UPPER 和 STATE_DATA_RECEIVED_LOWER 状态下主站从从站接收数据并将其放入 16 位长的 FIFO 中。 当 HPS 通过拨动停止信号指示停止系统时将提供 NACK然后提供停止条件随后进入等待状态以确保 MCP3221 不再忙。 值得注意的是由于 SDA 线路可同时由主设备和从设备控制我们编写了一个三态缓冲器来决定由哪个设备控制该线路。 三态缓冲器带有一个使能信号当主设备在事务中充当输入时该信号为高电平当该使能信号断言时SDA 在主设备端应变为高阻抗。 否则SDA 从主站输出。在不发送启动/停止条件、不等待或不空闲时SCL 时钟线作为 200K Hz 时钟信号跟随输入。当主站确认数据的较低位或主站发出 NAK 时数据有效信号被拉为高电平表明我们可以从 MCP3221 获取正确的值。该信号稍后将用于控制计算累积能量的积分器。 通过 I2C 接收器我们可以获得 12 位数据但仍需将其转换为实际电流数据我们将其设置为 9.23 位定点数据。相应的电压可计算为 d a t a o u t 2 12 ∗ 3.3 \frac{dataout}{2^{12}} * 3.3 212dataout​∗3.3 V。根据规范电流传感器的灵敏度为 110mv/A原点为 1.65V因此我们可以计算出实际电流为 I V − 1.65 V 110 m V / A I \frac{V-1.65V}{110mV/A} I110mV/AV−1.65V​。 MCP3221 I2C 接口还规定它能达到的最大时钟频率为 400kHz我们选择 200KHz 应该是一个合理的选择。 这意味着 50MHz 的 FPGA 时钟速度过快无法运行因此我们增加了一个时钟分频器将其降到 200kHz。 如上所述我们接着实施了一个积分器通过在单位时间内不断增加能量来计算累积能量。 我们使用 HPS 发出的停止信号来暂停积分然后继续启动。只要停止信号未被断言且 I2C 接口的数据有效我们就会通过计算 V∗I∗dt 来计算新的单位能量并将其与消耗的总能量相加。 dt 的值是通过使用 SignalTap 计数两个连续数据有效信号之间的脉冲数确定的。我们计算了 18 个脉冲与协议相符16 个脉冲用于传输数据2 个脉冲用于 ACK。 这意味着我们在每次新的电流采样时的单位能量为 V ∗ I ∗ 18 200000 \frac{V∗I∗18}{200000} 200000V∗I∗18​。尽管输入电流使用的是 7.23 定点值但我们的积分器模块的能量输出被设置为 41.23 定点即 64 位长数据因为能量是累积的所以需要更多位数来防止溢出。 但是Qsys PIO 的最大位宽只有 32 位因此我们必须创建两个 PIO 端口一个用于传输较高的 32 位另一个用于传输较低的 32 位。然后我们使用 long long 类型变量在 HPS 中存储 64 位值之后通过除法 223 将其从定点转换为双倍。位数增加一倍也提高了读数精度。 每当电流有效时我们也会递增一个计数器通过计算 (cycle_count - 1)*KaTeX parse error: Unexpected end of input in a macro argument, expected } at end of input: …rac{18}{200000] 就能确定 FPGA 开始运行后所经过的时间。这里我们不考虑第一个事务的时间即不计算前 27 个周期因为其中包括传输地址比特的时间而这并不代表中间的事务。 为了使调试更加直观我们在 FPGA 上实现了一个简单的段解码器来显示测量的电流值。如上所述电流值为 9.23 固定点我们使用分段显示器 0 作为符号后面两位作为整数其余作为分数部分。我们建立了一个映射表将前 9 位作为整数小数点后 23 位中的 4 位作为分数。 Software design 所有需要的硬件都已实例化我们开始添加与 HPS 的通信。由于我们的目标是在 VGA 显示屏上以图形方式显示数据因此从软件方面着手更为方便。 为了保证软件的正确性我们在设计软件时采用了渐进式方法。首先我们通过在 Qsys 总线上添加 PIO允许数据从 FPGA 流向 HPS。 每个 PIO 都有一个来自轻量级 AXI 主站的偏移量我们可以通过查看地址偏移量 轻量级 AXI 主站地址来访问数据。 由于积分器模块的输出是能量而不是功率我们需要进行一些转换。每个给定实例的动态功率等于瞬时电流 * 12V平均功率等于累积能量/总耗时。在实际绘制这些数据之前我们要确保我们的数据是有意义的因此每当数据有效信号被拉到高电平时我们就会在串行监视器上打印电流值、动态功率、平均功率、周期计数和时间。 在这个过程中我们意识到需要有意让程序休眠一段时间因为 HPS 的运行速度比 FPGA 快得多所以数据有效信号的一个高电平部分将对应 HPS 的数百个周期从而产生比需要多得多的数据点。 在确认数据正确无误后我们需要一种适当的方式来显示数据。我们决定在 VGA 上显示三个图表电流与时间、动态功率与时间、平均功率与时间。 我们将屏幕上的时间刻度限制为 3 秒这意味着每隔 3 秒就会擦除图表并使用新数据重新绘制。Y 轴刻度由变量决定。就电流而言它受限于我们电流传感器的能力该传感器最多可处理 2 安培的电流。对于动态功率和平均功率最大值为 IMax∗VMax2∗1224W。 因此从 y 轴的底部开始每增加一个像素功率就增加 24 119 \frac{24}{119} 11924​ 瓦。我们还在屏幕右侧创建了一个文本框用于显示这些变量的实际值。最终的 VGA 显示界面如图 4 所示。 在这里插入图片描述 图 4在 VGA 上显示图表 在 VGA 上绘制数据后我们开始将更多的控制权转移到 HPS 端。我们首先禁用了启动、停止和校准信号的按钮控制采用了纯软件控制。 这就需要一个能检测键盘输入的用户界面我们通过使用多个 pthreads 实现了这一点。用户可以在 1-3 之间选择一个数字每个数字分别对应按下重置、停止或校准键。当检测到停止时绘图会立即停止数据显示也会冻结而启动则会恢复绘图。 另一方面校准会清除能量和时间数据并从 0 重新开始。选择校准后所有图形都将清除并立即开始重新绘制。下面的视频演示了校准的效果。 Testing strategy 为了确保设计中的所有模块都能按预期工作我们采用了分层测试方法。在最底层我们首先编写了一个测试平台根据上述 I2C 协议输入控制信号、时钟和数据测试 I2C 状态机并在 ModelSim 中验证输出波形。 如图 5 所示主站能够发送正确的地址位在适当的时候生成 ACK读取输入数据并在 12 位事务完成时将数据有效信号拉高。 图 5用于 I2C 主站实施的测试平台的 Modelsim 波形 在仿真中证明 I2C 接口功能正常后我们在 Quartus 中实例化了模块并使用 SignalTap 验证了来自 FPGA 的信号反馈。SignalTap 在 FPGA 中创建了真正的硬件电路并提供了电路产生的实际输出波形。 在使用 SignalTap 时我们使用实验室的电流源直接向电流传感器馈送电流因此我们清楚地知道电流输出的预期值。我们还使用 FPGA 上的按钮来控制复位、启动和停止信号因此可以轻松触发 SignalTap 的数据捕获。通过比较电源上的电流输出和 SignalTap 的数据输出我们可以知道我们的实现是否正确。 在项目的最后我们不再使用电流源而是直接测量 FPGA 的电流。我们在面包板上放置了一个 2.1 毫米内螺纹直流电源插孔并将 FPGA 电源适配器连接到该插孔。 使用跳线将电源插孔的电源引脚连接到 mikroe-2987 电路板的 P 引脚电流将通过电路板到达其 P- 引脚我们将另一根跳线连接到公头插孔至开口电源线的正端。 公电源插孔插入 FPGA而其负端则连接回面包板上母电源插孔的接地引脚。 这种设置形成了一个串联电路其中电流传感器测量的电流应与 FPGA 的电流相同。图 6 和图 7 显示了我们如何设置这个串联电路。我们观察屏幕上的图形和不同读数以确定数据是否合理。 在这种设置下我们观察到电流和功率读数相当稳定这在意料之中因为 FPGA 始终在运行相同的程序。在这一阶段我们还改用纯软件控制而非按钮并将 VGA 输出在软件中发出信号时的行为与预期进行了比较。 我们可以看到在选择停止时图形停止而在开始时又恢复绘制。校准工作也正常进行因为图形被擦除时间轴被正确重置电流和能量的数据显示回到 0。 图 6直接测量 FPGA 电流的电路设置 图 7近距离观察电流传感器周围的电路 Results Analysis 在对系统进行上述进一步验证后我们能够利用它来探索 FPGA 中一些有趣的功耗行为。根据我们在英特尔社区中发现的一些讨论以太网calble会导致大量能耗。我们的系统可以很好地证明这一点。因此我们选择使用串口来控制 FPGA。我们首先在插入以太网电缆的情况下运行功率估算器。如图 8 所示这种情况下的平均功率约为 7.72W。 然后我们断开以太网电缆通过断定串行接口的信号来校准读数。如图 9 所示平均功率立即下降到 6.24W。我们多次重复这一过程以确认我们的发现每次断开以太网电缆时我们总能看到平均功率下降近 1W。因此我们可以得出结论使用以太网连接 FPGA 会显著增加功耗。 我们还尝试在 FPGA 中增加两千个 32 位计数器以观察功耗的变化但功耗的变化很难观察到。 在这里插入图片描述 图 8连接以太网电缆后的读数 图 9以太网电缆断开时的读数 Code I2C master code module i2c_master (// basic signalinput logic clk,input logic reset, // active high// control signalsinput logic start,input logic stop,// i2c portsoutput logic scl,inout wire sda,// To HPSoutput logic [11:0] data_out,output logic data_valid );//-----------------------------------------------------// SIGNAL DEFINITION//-----------------------------------------------------localparam STATE_IDLE 4d0;localparam STATE_START 4d1;localparam STATE_ADDR 4d2;localparam STATE_SLAVE_ACK 4d3;localparam STATE_DATA_RECEIVE_UPPER 4d4;localparam STATE_MASTER_ACK_UPPER 4d5;localparam STATE_DATA_RECEIVE_LOWER 4d6;localparam STATE_MASTER_ACK_LOWER 4d7;localparam STATE_MASTER_NACK 4d8;localparam STATE_STOP 4d9;localparam STATE_WAIT 4d10;logic [2:0] addr_cnt; // counter for addresslogic [2:0] upper_cnt; // counter for upper 8-bitlogic [2:0] lower_cnt; // counter for lower 8-bit//-----------------------------------------------------// STATE UPDATE//-----------------------------------------------------logic [3:0] state_current;logic [3:0] state_next;always ( negedge clk ) beginif ( reset ) beginstate_current STATE_IDLE;endelse beginstate_current state_next;endend//----------------------------------------------------------------------// STATE TRANSITION//----------------------------------------------------------------------always_comb begincase( state_current )STATE_IDLE: beginif ( start ) state_next STATE_START;else state_next STATE_IDLE;endSTATE_START: beginstate_next STATE_ADDR;endSTATE_ADDR: beginif ( addr_cnt 3d7 ) state_next STATE_SLAVE_ACK; else state_next STATE_ADDR;endSTATE_SLAVE_ACK: beginif ( !sda ) state_next STATE_DATA_RECEIVE_UPPER;else state_next STATE_IDLE;endSTATE_DATA_RECEIVE_UPPER: beginif ( upper_cnt 3d7 ) state_next STATE_MASTER_ACK_UPPER;else state_next STATE_DATA_RECEIVE_UPPER;endSTATE_MASTER_ACK_UPPER: beginif ( !sda ) state_next STATE_DATA_RECEIVE_LOWER;else state_next STATE_IDLE;endSTATE_DATA_RECEIVE_LOWER: beginif ( lower_cnt 3d7 !stop ) state_next STATE_MASTER_ACK_LOWER;else if ( lower_cnt 3d7 stop ) state_next STATE_MASTER_NACK;else state_next STATE_DATA_RECEIVE_LOWER;endSTATE_MASTER_ACK_LOWER: beginstate_next STATE_DATA_RECEIVE_UPPER;endSTATE_MASTER_NACK: beginstate_next STATE_STOP;endSTATE_STOP: beginstate_next STATE_WAIT;endSTATE_WAIT: beginstate_next STATE_IDLE;enddefault:state_next STATE_IDLE;endcase end//----------------------------------------------------------------------// STATE OUTPUT//----------------------------------------------------------------------always_comb begin // sck logicif ( ( state_current ! STATE_IDLE ) ( state_current ! STATE_START ) ( state_current ! STATE_STOP ) ( state_current ! STATE_WAIT ) ) scl clk;else if ( state_current STATE_STOP ) scl 1b0;else scl 1b1;endlogic master_is_input; // tri-state logic for sdalogic sda_temp;assign sda master_is_input ? 1bz : sda_temp; always_comb begincase( state_current )STATE_IDLE: beginmaster_is_input 1b0;endSTATE_START: beginmaster_is_input 1b0;endSTATE_ADDR: beginmaster_is_input 1b0;endSTATE_SLAVE_ACK: beginmaster_is_input 1b1;endSTATE_DATA_RECEIVE_UPPER: beginmaster_is_input 1b1;endSTATE_MASTER_ACK_UPPER: beginmaster_is_input 1b0;endSTATE_DATA_RECEIVE_LOWER: beginmaster_is_input 1b1;endSTATE_MASTER_ACK_LOWER: beginmaster_is_input 1b0;endSTATE_MASTER_NACK: beginmaster_is_input 1b0;end STATE_STOP: beginmaster_is_input 1b0;endSTATE_WAIT: beginmaster_is_input 1b0;enddefault: beginmaster_is_input 1b1;endendcaseendalways_comb begin // master output for sda logiccase( state_current )STATE_IDLE: beginsda_temp 1b1;endSTATE_START: beginsda_temp 1b0;endSTATE_ADDR: beginif ( addr_cnt 0 ) sda_temp 1b1;else if ( addr_cnt 1 ) sda_temp 1b0;else if ( addr_cnt 2 ) sda_temp 1b0;else if ( addr_cnt 3 ) sda_temp 1b1;else if ( addr_cnt 4 ) sda_temp 1b1;else if ( addr_cnt 5 ) sda_temp 1b0;else if ( addr_cnt 6 ) sda_temp 1b1;else if ( addr_cnt 7 ) sda_temp 1b1;else sda_temp 1b0;endSTATE_MASTER_ACK_UPPER: beginsda_temp 1b0;endSTATE_MASTER_ACK_LOWER: beginsda_temp 1b0;endSTATE_MASTER_NACK: beginsda_temp 1b1;end STATE_STOP: beginsda_temp 1b0;endSTATE_WAIT: beginsda_temp 1b0;enddefault: beginsda_temp 1b0;endendcaseendalways_ff ( negedge clk ) begin // data_out storeif ( ( state_current STATE_DATA_RECEIVE_UPPER ) ( upper_cnt 7 ) ( upper_cnt 4 ) ) begindata_out { data_out[10:0], sda };endelse if ( state_current STATE_DATA_RECEIVE_LOWER ) begindata_out { data_out[10:0], sda };endend assign data_valid ( state_current STATE_MASTER_ACK_LOWER ) || ( state_current STATE_MASTER_NACK ); // data valid signal logic //----------------------------------------------------------------------// CONTROL SIGNALS//----------------------------------------------------------------------always_ff ( negedge clk ) beginif ( state_current STATE_ADDR ) addr_cnt addr_cnt 1;else addr_cnt 3d0;endalways_ff ( negedge clk ) beginif ( state_current STATE_DATA_RECEIVE_UPPER ) upper_cnt upper_cnt 1;else upper_cnt 3d0;endalways_ff ( negedge clk ) beginif ( state_current STATE_DATA_RECEIVE_LOWER ) lower_cnt lower_cnt 1;else lower_cnt 3d0;endendmoduleHardware implementation on FPGA //----------------------------------------------------- // Segment decoder //-----------------------------------------------------module segment_decoder (input logic clk,//input logic current_val,input logic signed [26:0] current,output logic [6:0] hex0,output logic [6:0] hex1,output logic [6:0] hex2, // fractionoutput logic [6:0] hex3, // integeroutput logic [6:0] hex4 // sign );always_ff ( posedge clk ) beginif ( current[26] ) hex4 7b0111111;else hex4 7b1111111; endlogic signed [4:0] current_int; assign current_int current[26:22];always_ff ( posedge clk ) beginif ( !current[26] ) begincase( current_int )5d1: beginhex3 7b1111001;end5d2: beginhex3 7b0100100;enddefault: beginhex3 7b1000000;endendcaseendelse begincase( current_int )-5d1: beginif (current[21:18]4d0) hex3 7b1111001;else hex3 7b1000000;end-5d2: beginif (current[21:18]4d0) hex3 7b0100100;else hex3 7b1111001;enddefault: beginhex3 7b1000000;endendcaseendendalways_ff ( posedge clk ) begincase( current[21:18] )4d0: beginhex2 7b1000000;hex1 7b1000000;hex0 7b1000000;end4d1: beginhex2 current[26] ? 7b0010000 : 7b1000000;hex1 current[26] ? 7b0110000 : 7b0000010;hex0 current[26] ? 7b1111000 : 7b0110000;end4d2: beginhex2 current[26] ? 7b0000000 : 7b1111001;hex1 current[26] ? 7b1111000 : 7b0100100;hex0 current[26] ? 7b0010010 : 7b0010010;end4d3: beginhex2 current[26] ? 7b0000000 : 7b1111001;hex1 current[26] ? 7b1111001 : 7b0000000;hex0 current[26] ? 7b0100100 : 7b0000000;end4d4: beginhex2 current[26] ? 7b1111000 : 7b0100100;hex1 current[26] ? 7b0010010 : 7b0010010; hex0 current[26] ? 7b1000000 : 7b1000000;end4d5: beginhex2 current[26] ? 7b0000010 : 7b0110000;hex1 current[26] ? 7b0000000 : 7b1111001;hex0 current[26] ? 7b1111000 : 7b0110000;end4d6: beginhex2 current[26] ? 7b0000010 : 7b0110000;hex1 current[26] ? 7b0100100 : 7b1111000;hex0 current[26] ? 7b0010010 : 7b0010010;end4d7: beginhex2 current[26] ? 7b0010010 : 7b0011001;hex1 current[26] ? 7b0000010 : 7b0110000; hex0 current[26] ? 7b0100100 : 7b0000000;end4d8: beginhex2 current[26] ? 7b0010010 : 7b0010010;hex1 current[26] ? 7b1000000 : 7b1000000;hex0 current[26] ? 7b1000000 : 7b1000000;end4d9: beginhex2 current[26] ? 7b0011001 : 7b0010010;hex1 current[26] ? 7b0110000 : 7b0000010;hex0 current[26] ? 7b1111000 : 7b0110000;end4d10: beginhex2 current[26] ? 7b0110000 : 7b0000010;hex1 current[26] ? 7b1111000 : 7b0100100;hex0 current[26] ? 7b0010010 : 7b0010010;end4d11: beginhex2 current[26] ? 7b0110000 : 7b0000010;hex1 current[26] ? 7b1111001 : 7b0000000;hex0 current[26] ? 7b0100100 : 7b0000000;end4d12: beginhex2 current[26] ? 7b0100100 : 7b1111000;hex1 current[26] ? 7b0010010 : 7b0010010;hex0 current[26] ? 7b1000000 : 7b1000000;end4d13: beginhex2 current[26] ? 7b1111001 : 7b0000000;hex1 current[26] ? 7b0000000 : 7b1111001;hex0 current[26] ? 7b1111000 : 7b0110000;end4d14: beginhex2 current[26] ? 7b1111001 : 7b0000000;hex1 current[26] ? 7b0100100 : 7b1111000;hex0 current[26] ? 7b0010010 : 7b0010010;end4d15: beginhex2 current[26] ? 7b1000000 : 7b0010000;hex1 current[26] ? 7b0000010 : 7b0110000;hex0 current[26] ? 7b0100100 : 7b0000000;endendcase endendmodule//----------------------------------------------------- // Fixed point multipliers //----------------------------------------------------- module signed_mult_27bit (input logic signed [26:0] a,input logic signed [26:0] b,output logic signed [26:0] out );logic signed [53:0] mult_out; assign mult_out a * b; assign out {mult_out[53], mult_out[47:22]};endmodulemodule signed_mult_32bit (input logic signed [31:0] a,input logic signed [31:0] b,output logic signed [31:0] out );logic signed [63:0] mult_out; assign mult_out a * b; assign out {mult_out[63], mult_out[53:23]};endmodule//----------------------------------------------------- // 200kHz clock //----------------------------------------------------- module clk_divider_400k(input logic reset,input logic clk_50M,output logic clk_400k );logic [6:0] counter;always_ff( posedge clk_50M ) begin if ( reset ) beginclk_400k 1b1;counter 0;endelse if ( counter 124 ) beginclk_400k !clk_400k;counter 0;endelse begincounter counter 1;endend endmodule//----------------------------------------------------- // Integrater //----------------------------------------------------- module integrater(// basicinput logic reset,input logic clk,// control: signals to start and clear integrationinput logic data_valid, // data_valid from i2c interfaceinput logic start,input logic stop,input logic cali,// From I2C interfaceinput logic signed [26:0] input_data, // 5.22// To HPS output logic signed [63:0] energy_out,output logic [31:0] cycle_cnt );// PARAMETER DEFINITION logic signed [31:0] unit_voltage 32d9059; // (2^23)*18*12*1/200000logic signed [31:0] input_data_32bit; // 9.23assign input_data_32bit { {4{input_data[26]}}, input_data, 1b0};logic signed [31:0] unit_energy;// UNIT ENERGYsigned_mult_32bit multiply(.a(unit_voltage),.b(input_data_32bit),.out(unit_energy));// CONTROLlogic out_ind;always_ff ( posedge clk or posedge reset or posedge cali ) beginif ( reset || cali ) out_ind 1b0;else if ( stop ) out_ind 1b1;else if ( start ) out_ind 1b0;end// ENERGY COMPUTATIONalways_ff ( posedge clk or posedge reset or posedge cali ) beginif ( reset || cali ) energy_out 32d0;else if ( !out_ind data_valid ) energy_out energy_out { {32{unit_energy[31]}}, unit_energy}; end// TIME COUNTERalways_ff ( posedge clk or posedge reset or posedge cali ) beginif ( reset || cali ) cycle_cnt 32d0;else if ( !out_ind data_valid ) cycle_cnt cycle_cnt 1;endendmoduleC code #include stdio.h #include stdlib.h #include unistd.h #include fcntl.h #include sys/types.h #include sys/ipc.h #include sys/shm.h #include sys/mman.h #include sys/time.h #include math.h #include string.h #include errno.h // Definition for error handling #include sys/wait.h // Definition for wait() //#include address_map_arm_brl4.h// threads #include pthread.h/***************************************************************************************** Prameter Definition ****************************************************************************************/// VGA PLOT PARAMS /* Cyclone V FPGA devices */ #define HW_REGS_BASE 0xff200000 //#define HW_REGS_SPAN 0x00200000 #define HW_REGS_SPAN 0x00005000 #define FPGA_ONCHIP_BASE 0xC8000000 //#define FPGA_ONCHIP_END 0xC803FFFF // modified for 640x480 // #define FPGA_ONCHIP_SPAN 0x00040000 #define FPGA_ONCHIP_SPAN 0x00080000#define FPGA_CHAR_BASE 0xC9000000 #define FPGA_CHAR_END 0xC9001FFF #define FPGA_CHAR_SPAN 0x00002000// ADDRESS OFFSET #define FPGA_CURRENT 0x00000070 // #define FPGA_ENERGY 0x00000080 #define FPGA_CYCLE_CNT 0x00000090 #define FPGA_START 0x000000a0 #define FPGA_STOP 0x000000b0 #define FPGA_RESET 0x000000c0 #define FPGA_DATA_VALID 0x000000d0 #define FPGA_CALIBRATE 0x000000f0 #define ENERGY_OUT_LOWER 0x00000200 #define ENERGY_OUT_UPPER 0x00000100 // /* function prototypes */ void VGA_text (int, int, char *); void VGA_text_clear(); void VGA_box (int, int, int, int, short); void VGA_line(int, int, int, int, short) ; void VGA_disc (int, int, int, short);// 16-bit primary colors #define red (0(05)(3111)) #define dark_red (0(05)(1511)) #define green (0(635)(011)) #define dark_green (0(315)(011)) #define blue (31(05)(011)) #define dark_blue (15(05)(011)) #define yellow (0(635)(3111)) #define cyan (31(635)(011)) #define magenta (31(05)(3111)) #define black (0x0000) #define gray (15(315)(5111)) #define white (0xffff) int colors[] {red, dark_red, green, dark_green, blue, dark_blue, yellow, cyan, magenta, gray, black, white};// 8-bit color #define rgb(r,g,b) ((((r)7)5) | (((g)7)2) | (((b)3)))// pixel macro #define VGA_PIXEL(x,y,color) do{\char *pixel_ptr ;\pixel_ptr (char *)vga_pixel_ptr ((y)10) (x) ;\*(char *)pixel_ptr (color);\ } while(0)// SOLVER-LW-AXI POINTER volatile char * fpga_reset_ptr NULL ; volatile char * fpga_start_ptr NULL ; volatile char * fpga_stop_ptr NULL ; volatile char * fpga_data_valid_ptr NULL ; volatile signed int * fpga_current_ptr NULL ; // volatile signed int * fpga_energy_ptr NULL ; volatile int * fpga_cycle_cnt_ptr NULL ; volatile char * fpga_calibration_ptr NULL ; volatile unsigned int * energy_out_lower_ptr NULL ; volatile signed int * energy_out_upper_ptr NULL ; //// the light weight buss base void *h2p_lw_virtual_base;// pixel buffer volatile unsigned int * vga_pixel_ptr NULL ; void *vga_pixel_virtual_base;// character buffer volatile unsigned int * vga_char_ptr NULL ; void *vga_char_virtual_base;// /dev/mem file id int fd;// measure time struct timeval t1, t2; double elapsedTime; /**************************************************************************************** // Energy estimator variables ****************************************************************************************/ double time_spent; float current_float; double energy_double; float power_float; float cycle_cnt;long long energy_64bit;// Coordinate variables for plotting graphs int coord_x_pre; int coord_x; signed int current_y_pre; signed int current_y; signed int power_y_pre; signed int power_y; signed int avg_power_y_pre; signed int avg_power_y; double time_start; double time_pre;// Time axis variable int time_axis1; int time_axis2; int time_axis3;// Calibrate indicator int cali_flag;/***************************************************************************************** Thread stuff ****************************************************************************************/#define TRUE 1 #define FALSE 0// access to enter condition // -- for signalling enter done pthread_mutex_t enter_lock PTHREAD_MUTEX_INITIALIZER; // access to print condition // -- for signalling print done pthread_mutex_t print_lock PTHREAD_MUTEX_INITIALIZER; // counter protection pthread_mutex_t count_lock PTHREAD_MUTEX_INITIALIZER;// the two condition variables related to the mutex above pthread_cond_t enter_cond ; pthread_cond_t print_cond ; pthread_cond_t hardware_cond ;// globals for perfromance int count1, count2;// Thread variables char input_buffer[64]; // int threshold;//Thread functions void * hardware(); void * software(); void * read1(); void * write1(); void * counter1();/***************************************************************************************** Main Function ****************************************************************************************/ int main() {// need to mmap: // FPGA_CHAR_BASE// FPGA_ONCHIP_BASE // HW_REGS_BASE // get FPGA addresses // Open /dev/memif( ( fd open( /dev/mem, ( O_RDWR | O_SYNC ) ) ) -1 ) {printf( ERROR: could not open \/dev/mem\...\n );return( 1 );}// get virtual addr that maps to physicalh2p_lw_virtual_base mmap( NULL, HW_REGS_SPAN, ( PROT_READ | PROT_WRITE ), MAP_SHARED, fd, HW_REGS_BASE ); if( h2p_lw_virtual_base MAP_FAILED ) {printf( ERROR: mmap1() failed...\n );close( fd );return(1);}// get VGA char addr // get virtual addr that maps to physicalvga_char_virtual_base mmap( NULL, FPGA_CHAR_SPAN, ( PROT_READ | PROT_WRITE ), MAP_SHARED, fd, FPGA_CHAR_BASE ); if( vga_char_virtual_base MAP_FAILED ) {printf( ERROR: mmap2() failed...\n );close( fd );return(1);}// Get the address that maps to the FPGA LED control vga_char_ptr (unsigned int *)(vga_char_virtual_base);// get VGA pixel addr // get virtual addr that maps to physicalvga_pixel_virtual_base mmap( NULL, FPGA_ONCHIP_SPAN, ( PROT_READ | PROT_WRITE ), MAP_SHARED, fd, FPGA_ONCHIP_BASE); if( vga_pixel_virtual_base MAP_FAILED ) {printf( ERROR: mmap3() failed...\n );close( fd );return(1);}// Get the address that maps to the FPGA pixel buffervga_pixel_ptr (unsigned int *)(vga_pixel_virtual_base);/***************************************************************************************** Draw things on VGA ****************************************************************************************//* create a message to be displayed on the VGA and LCD displays */char time_text[30] Time/s\0;char curent_text[30] Current/A\0;char dyn_power_text[30] Dynamic power/W\0;char avg_power_text[30] Average power/W\0;char curren_y_text1[10] 0.5;char curren_y_text2[10] 1.0;char curren_y_text3[10] 1.5;char curren_y_text4[10] 2.0;char dyn_power_y_text1[10] 6;char dyn_power_y_text2[10] 12;char dyn_power_y_text3[10] 18;char dyn_power_y_text4[10] 24;char avg_power_y_text1[10] 6;char avg_power_y_text2[10] 12;char avg_power_y_text3[10] 18;char avg_power_y_text4[10] 24;// clear the screenVGA_box (0, 0, 639, 479, 0x0000);// clear the textVGA_text_clear();// Plot graphs // Current VGA_line(40,20,40,139,dark_blue);VGA_line(40,139,420,139,dark_blue);VGA_text(4,1,curent_text);VGA_text(45,18,time_text);// Y axis data points// 0.5AVGA_line(40,110,37,110,dark_blue);VGA_text(1,13,curren_y_text1);// 1.0AVGA_line(40,81,37,81,dark_blue);VGA_text(1,10,curren_y_text2);// 1.5AVGA_line(40,52,37,52,dark_blue);VGA_text(1,6,curren_y_text3);// 2.0AVGA_line(40,23,37,23,dark_blue);VGA_text(1,3,curren_y_text4);// Dynamic ower VGA_line(40,169,40,288,yellow);VGA_line(40,288,420,288,yellow);VGA_text(4,19,dyn_power_text);VGA_text(45,37,time_text); // Y axis data points// 6WVGA_line(40,259,37,259,yellow);VGA_text(2,33,dyn_power_y_text1);// 12kWVGA_line(40,230,37,230,yellow);VGA_text(2,29,dyn_power_y_text2);// 18WVGA_line(40,201,37,201,yellow);VGA_text(2,25,dyn_power_y_text3);// 24WVGA_line(40,172,37,172,yellow);VGA_text(2,21,dyn_power_y_text4);// Average power VGA_line(40,329,40,448, magenta);VGA_line(40,448,420,448,magenta);VGA_text(4,39,avg_power_text);// VGA_text(45,57,time_text); // Y axis data points// 6WVGA_line(40,419,37,419,magenta);VGA_text(2,52,avg_power_y_text1);// 12kWVGA_line(40,390,37,390,magenta);VGA_text(2,49,avg_power_y_text2);// 18WVGA_line(40,361,37,361,magenta);VGA_text(2,45,avg_power_y_text3);// 24WVGA_line(40,332,37,332,magenta);VGA_text(2,41,avg_power_y_text4);// Time axisVGA_line(166,448,166,451,magenta);// VGA_text(20,57,time_axis_text1);VGA_line(292,448,292,451,magenta);// VGA_text(36,57,time_axis_text2);VGA_line(418,448,418,451,magenta);// VGA_text(51,57,time_axis_text3);// Box to print data VGA_line(440,30,630,30,white);VGA_line(440,450,630,450,white);VGA_line(440,30,440,450,white);VGA_line(630,30,630,450,white);// LW AXI connection fpga_reset_ptr (char *)(h2p_lw_virtual_base FPGA_RESET); fpga_start_ptr (char *)(h2p_lw_virtual_base FPGA_START); fpga_stop_ptr (char *)(h2p_lw_virtual_base FPGA_STOP); fpga_data_valid_ptr (char *)(h2p_lw_virtual_base FPGA_DATA_VALID); fpga_current_ptr (signed int *)(h2p_lw_virtual_base FPGA_CURRENT); // fpga_energy_ptr (signed int *)(h2p_lw_virtual_base FPGA_ENERGY); fpga_cycle_cnt_ptr (int *)(h2p_lw_virtual_base FPGA_CYCLE_CNT); fpga_calibration_ptr (char *)(h2p_lw_virtual_base FPGA_CALIBRATE);energy_out_lower_ptr (unsigned int *)(h2p_lw_virtual_base ENERGY_OUT_LOWER);energy_out_upper_ptr (signed int *)(h2p_lw_virtual_base ENERGY_OUT_UPPER);// printf(start setting power estimator\n);*(fpga_stop_ptr) 0;*(fpga_stop_ptr) 1;usleep(1000);*(fpga_stop_ptr) 0;printf(set stop to 1\n);usleep(100);*(fpga_reset_ptr) 0;*(fpga_reset_ptr) 1;usleep(1000);*(fpga_reset_ptr) 0;printf(set reset to 1\n);usleep(100);*(fpga_start_ptr) 0;*(fpga_start_ptr) 1;usleep(1000);*(fpga_start_ptr) 0;printf(set start to 1\n);// Thread int status;// the thread identifierspthread_t thread_read, thread_write, thread_count1, thread_count2, thread_hardware;// pthread_t software_thread;// the condition variablespthread_cond_init (enter_cond, NULL);pthread_cond_init (print_cond, NULL);pthread_cond_init (hardware_cond, NULL);//For portability, explicitly create threads in a joinable state // thread attribute used here to allow JOINpthread_attr_t attr;pthread_attr_init(attr);pthread_attr_setdetachstate(attr, PTHREAD_CREATE_JOINABLE);// now the threadspthread_create(thread_read,NULL,read1,NULL);pthread_create(thread_write,NULL,write1,NULL);pthread_create(thread_count1,NULL,counter1,NULL);pthread_create(thread_hardware, NULL, hardware(),NULL);pthread_join(thread_read,NULL);pthread_join(thread_write,NULL);// Initialize calibration flagcali_flag 0;} // end main/***************************************************************************************** Thread functions ****************************************************************************************/ void * hardware(){// print data stringchar current_string[20] Current:;char current_data_string[20];char dyn_power_string[20] Dynamic power:;char dyn_power_data_string[20];char avg_power_string[20] Average power:;char avg_power_data_string[20];char energy_string[20] Energy:;char energy_data_string[20];char time_string[20] Time:;char time_data_string[20];char current_unit_string[5] A;char power_unit_string[5] W;char energy_unit_string[5] J;char time_unit_string[5] s;char title_string[30] Data table ;char assume_vol1[20] Assuming constant;char assume_vol2[20] voltage at 12V;char choose_operation[30] Choose from below:;char operation1[30] 1 -- start;char operation2[30] 2 -- stop;char operation3[30] 3 -- calibrate;char time_axis_text1[10];char time_axis_text2[10];char time_axis_text3[10];// Initialize variabletime_start 0;time_axis1 1;time_axis2 2;time_axis3 3;// Dot coordinatecoord_x_pre 41;current_y_pre 139;power_y_pre 288;avg_power_y_pre 448;time_pre 0;while(1){// start timergettimeofday(t1, NULL);if(*(fpga_data_valid_ptr) 1){current_float (float)(*(fpga_current_ptr)/pow(2,23));// energy_float (float)((*(fpga_energy_ptr)/pow(2,23)));energy_64bit (((long long) *(energy_out_upper_ptr))32) | *(energy_out_lower_ptr);energy_double energy_64bit/pow(2,23);cycle_cnt *(fpga_cycle_cnt_ptr);time_spent ((cycle_cnt-1)*18)/200000;usleep(1000);coord_x 41 (time_spent - time_start)/0.00789; current_y 139 - current_float/0.0167;power_y 288 - (current_float*12)/0.2017;avg_power_y 448 - (energy_double/time_spent)/0.2017;if(current_y 139 ){current_y 139;}if(power_y 288){power_y 288;}if(avg_power_y 448){power_y 448;}// VGA_PIXEL(coord_x, current_y, dark_blue);// VGA_PIXEL(coord_x, power_y, yellow);// VGA_PIXEL(coord_x,avg_power_y,magenta);if(cali_flag){// clear graphsVGA_box (41, 15, 435, 138, 0x000);VGA_box (41, 164, 435, 287, 0x000);VGA_box (41, 324, 435, 447, 0x000);time_axis1 1;time_axis2 2;time_axis3 3;coord_x_pre 41;coord_x 41;time_pre 0;cali_flag 0;time_start 0;}VGA_line(coord_x_pre, current_y_pre,coord_x, current_y,dark_blue);VGA_line(coord_x_pre, power_y_pre, coord_x, power_y, yellow);VGA_line(coord_x_pre, avg_power_y, coord_x, avg_power_y, magenta);if(time_spent-time_pre3){// clear graphsVGA_box (41, 15, 435, 138, 0x000);VGA_box (41, 164, 435, 287, 0x000);VGA_box (41, 324, 435, 447, 0x000);time_start time_spent;// increment timetime_axis1 time_axis3 1;time_axis2 time_axis3 2;time_axis3 time_axis3 3;coord_x_pre 41;coord_x 41;time_pre time_pre 3;}// // Print current and power data on VGAVGA_text (57, 7, title_string);VGA_text(57,9,assume_vol1);VGA_text(57,10,assume_vol2);// CurrentVGA_text (57, 16, current_string);sprintf(current_data_string, %f, current_float);VGA_text (57, 17, current_data_string);VGA_text (68, 17, current_unit_string);// Dynamic powerVGA_text (57, 19, dyn_power_string);sprintf(dyn_power_data_string, %f, current_float*12);VGA_text (57, 20, dyn_power_data_string);VGA_text (68, 20, power_unit_string);// Average powerVGA_text (57, 22, avg_power_string);sprintf(avg_power_data_string, %lf, energy_double/time_spent);VGA_text (57, 23, avg_power_data_string);VGA_text (68, 23, power_unit_string);// EnergyVGA_text (57, 25, energy_string);sprintf(energy_data_string, %lf, energy_double);VGA_text (57, 26, energy_data_string);VGA_text (68, 26, energy_unit_string);// TimeVGA_text (57, 28, time_string);sprintf(time_data_string, %lf, time_spent);VGA_text (57, 29, time_data_string);VGA_text (57, 29, time_data_string);VGA_text (68, 29, time_unit_string);// Choose from operations textVGA_text(57, 34, choose_operation);VGA_text(57, 38, operation1);VGA_text(57, 40, operation2);VGA_text(57, 42, operation3);// Time axissprintf(time_axis_text1, %d , time_axis1);VGA_text (20, 57, time_axis_text1);sprintf(time_axis_text2, %d , time_axis2);VGA_text(36,57,time_axis_text2);sprintf(time_axis_text3, %d , time_axis3);VGA_text(51,57,time_axis_text3);coord_x_pre coord_x;current_y_pre current_y;power_y_pre power_y;avg_power_y_pre avg_power_y;}} }void * read1() {printf(\n);printf(Power estimator user interface\n);printf(**************************************************************\n);while(1){//wait for print donepthread_mutex_lock(print_lock);pthread_cond_wait(print_cond,print_lock);// the actual enter printf(Plese choose an operation:\n);printf(1-start 2-stop 3-calibrate\n);scanf(%s,input_buffer);// unlock the input_bufferpthread_mutex_unlock(print_lock);// and tell write1 thread that enter is completepthread_cond_signal(enter_cond);} // while(1) }void * write1() {sleep(1);// signal that the print process is ready when startedpthread_cond_signal(print_cond);while(1){// wait for enter donepthread_mutex_lock(enter_lock);pthread_cond_wait(enter_cond,enter_lock);// the protected print (with protected counter)pthread_mutex_lock(count_lock);gettimeofday(t1, NULL);if(strcmp(input_buffer,1)0){*(fpga_start_ptr) 0;*(fpga_start_ptr) 1;usleep(1000);*(fpga_start_ptr) 0;}else if(strcmp(input_buffer,2)0){*(fpga_stop_ptr) 0;*(fpga_stop_ptr) 1;usleep(1000);*(fpga_stop_ptr) 0;}else if(strcmp(input_buffer,3)0){*(fpga_calibration_ptr) 0;*(fpga_calibration_ptr) 1;usleep(1000);*(fpga_calibration_ptr) 0;cali_flag 1;}count1 0;pthread_mutex_unlock(count_lock);// unlock the input_bufferpthread_mutex_unlock(enter_lock);// and tell read1 thread that print is donepthread_cond_signal(print_cond); } // while(1) }void * counter1() {//while(1){// count as fast as possiblepthread_mutex_lock(count_lock);count1; pthread_mutex_unlock(count_lock);} // while(1) }/***************************************************************************************** Subroutine to send a string of text to the VGA monitor ****************************************************************************************/ void VGA_text(int x, int y, char * text_ptr) {volatile char * character_buffer (char *) vga_char_ptr ; // VGA character bufferint offset;/* assume that the text string fits on one line */offset (y 7) x;while ( *(text_ptr) ){// write to the character buffer*(character_buffer offset) *(text_ptr); text_ptr;offset;// Added to slow print on vgausleep(250);} }/***************************************************************************************** Subroutine to clear text to the VGA monitor ****************************************************************************************/ void VGA_text_clear() {volatile char * character_buffer (char *) vga_char_ptr ; // VGA character bufferint offset, x, y;for (x0; x79; x){for (y0; y59; y){/* assume that the text string fits on one line */offset (y 7) x;// write to the character buffer*(character_buffer offset) ; }} }/***************************************************************************************** Draw a filled rectangle on the VGA monitor ****************************************************************************************/ #define SWAP(X,Y) do{int tempX; XY; Ytemp;}while(0) void VGA_box(int x1, int y1, int x2, int y2, short pixel_color) {char *pixel_ptr ; int row, col;/* check and fix box coordinates to be valid */if (x1639) x1 639;if (y1479) y1 479;if (x2639) x2 639;if (y2479) y2 479;if (x10) x1 0;if (y10) y1 0;if (x20) x2 0;if (y20) y2 0;if (x1x2) SWAP(x1,x2);if (y1y2) SWAP(y1,y2);for (row y1; row y2; row)for (col x1; col x2; col){//640x480pixel_ptr (char *)vga_pixel_ptr (row10) col ;// set pixel color*(char *)pixel_ptr pixel_color; } }/***************************************************************************************** Draw a filled circle on the VGA monitor ****************************************************************************************/void VGA_disc(int x, int y, int r, short pixel_color) {char *pixel_ptr ; int row, col, rsqr, xc, yc;rsqr r*r;for (yc -r; yc r; yc)for (xc -r; xc r; xc){col xc;row yc;// add the r to make the edge smootherif(col*colrow*row rsqrr){col x; // add the center pointrow y; // add the center point//check for valid 640x480if (col639) col 639;if (row479) row 479;if (col0) col 0;if (row0) row 0;pixel_ptr (char *)vga_pixel_ptr (row10) col ;// set pixel color*(char *)pixel_ptr pixel_color;}} }// // Draw a line // //plot a line //at x1,y1 to x2,y2 with color //Code is from David Rodgers, //Procedural Elements of Computer Graphics,1985 void VGA_line(int x1, int y1, int x2, int y2, short c) {int e;signed int dx,dy,j, temp;signed int s1,s2, xchange;signed int x,y;char *pixel_ptr ;/* check and fix line coordinates to be valid */if (x1639) x1 639;if (y1479) y1 479;if (x2639) x2 639;if (y2479) y2 479;if (x10) x1 0;if (y10) y1 0;if (x20) x2 0;if (y20) y2 0;x x1;y y1;//take absolute valueif (x2 x1) {dx x1 - x2;s1 -1;}else if (x2 x1) {dx 0;s1 0;}else {dx x2 - x1;s1 1;}if (y2 y1) {dy y1 - y2;s2 -1;}else if (y2 y1) {dy 0;s2 0;}else {dy y2 - y1;s2 1;}xchange 0; if (dydx) {temp dx;dx dy;dy temp;xchange 1;} e ((int)dy1) - dx; for (j0; jdx; j) {//video_pt(x,y,c); //640x480pixel_ptr (char *)vga_pixel_ptr (y10) x; // set pixel color*(char *)pixel_ptr c; if (e0) {if (xchange1) x x s1;else y y s2;e e - ((int)dx1);}if (xchange1) y y s2;else x x s1;e e ((int)dy1);} }
http://www.pierceye.com/news/466434/

相关文章:

  • 我想在泉州做网站上上海网站设计
  • 百度seo网站优化一 网站开发体会
  • 成都58手机微信网站建设名录tiktok跨境电商好做吗
  • 电子科技 深圳 网站建设怎么做打码网站
  • 南宁小程序开发网站建设公司公司网站建设怎么选择
  • erp网站代做项目网络进度图
  • 网站建设胶州家园外贸网站怎么注册
  • 我想找阿里巴巴做网站推广建一个公司网站花多少钱
  • 最新购物网站建设框架wordpress 登录后台乱码
  • 音频网站开发做外贸网站需要营业执照
  • 企业网站搭建项目概述范文wordpress更改链接地址
  • 免费网站在线观看人数在哪直播建设工业网站首页
  • 权威的南昌网站设计wordpress游客评论游客
  • 乡镇府建设网站什么是外链
  • 营销型网站设计流程电子商务网站建设软件
  • 做个人网站的步骤wordpress 添加新页面
  • 公司建网站流程网站布局选择
  • 云南效果好的网站优化微信如何做有趣的短视频网站
  • wordpress个人网站后台登陆dedecms仿站
  • 网站没被收录什么原因上海哪家做网站
  • 电子商务网站建设含代码项目外包是什么意思
  • 此网站正在建设中页面重庆网上商城网站建设公司
  • 保定建设公司网站新产品上市的营销策划方案
  • 网站建设课程报告论文网络设计专业有前途吗
  • 苏州哪个公司做门户网站wordpress显示评论者地理位置 浏览器
  • 福州网站设计十年乐云seo推广网上国网有什么好处
  • 豪华网站建设wordpress推广提成
  • 网站优化外包价格搜索引擎费用
  • 网站建设基本范例sqlite开发网站
  • 网站建设顾问站建开发外包公司