<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>起点博客 &#187; 学习笔记</title>
	<atom:link href="http://xinzero.com/category/study-note/feed" rel="self" type="application/rss+xml" />
	<link>http://xinzero.com</link>
	<description>起于学习，点与应用，一切只为更高效</description>
	<lastBuildDate>Mon, 06 Feb 2012 14:29:24 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>LTM8032电压调节电阻计算方法</title>
		<link>http://xinzero.com/ltm8032-adj-resistor-equation.html</link>
		<comments>http://xinzero.com/ltm8032-adj-resistor-equation.html#comments</comments>
		<pubDate>Mon, 25 Jul 2011 00:23:00 +0000</pubDate>
		<dc:creator>will</dc:creator>
				<category><![CDATA[学习笔记]]></category>
		<category><![CDATA[电源]]></category>

		<guid isPermaLink="false">http://xinzero.com/?p=529</guid>
		<description><![CDATA[


LTM8032以其超低的噪声（Ultralow Noise），以及宽电压输入（3.6V~36V），宽电压输出（0.8V~10V），大负载能力（2A），完全可以替换掉LTM8023。
然而在使用过程中调节电压输出的电阻计算公式，如下图所示。

而实际使用中需要将最终Radj乘以2
随机文章USB转串口驱动打包下载题注与交叉引用，批量更新域&#8212;&#8212;word使用技巧TMS320VC33字长问题解决&#34;应用程序配置不正确，程序无法启动&#34;问题QQ阅读空间再次更新]]></description>
			<content:encoded><![CDATA[<p>LTM8032以其超低的噪声（<strong>Ultralow Noise</strong>），以及宽电压输入（3.6V~36V），宽电压输出（0.8V~10V），大负载能力（2A），完全可以替换掉LTM8023。</p>
<p>然而在使用过程中调节电压输出的电阻计算公式，如下图所示。</p>
<p><a href="http://xinzero.com/wordpress/wp-content/uploads/2011/07/clip_image0025.jpg"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image002" src="http://xinzero.com/wordpress/wp-content/uploads/2011/07/clip_image002_thumb5.jpg" border="0" alt="clip_image002" width="416" height="173" /></a></p>
<p><strong>而实际使用中需要将最终Radj</strong><strong>乘以2</strong></p>
<h3  class="related_post_title">随机文章</h3><ul class="related_post"><li><a href="http://xinzero.com/cet-test.html" title="又到了四六级考试的时间了">又到了四六级考试的时间了</a></li><li><a href="http://xinzero.com/tornado22-for-all-download.html" title="Tornado2.2下载与安装-VxWorks开发工具">Tornado2.2下载与安装-VxWorks开发工具</a></li><li><a href="http://xinzero.com/edit-word-catalog-style.html" title="word自动生成目录的样式控制">word自动生成目录的样式控制</a></li><li><a href="http://xinzero.com/toshiba-l525-disable-touchpad.html" title="东芝L525笔记本XP系统下禁用触摸板">东芝L525笔记本XP系统下禁用触摸板</a></li><li><a href="http://xinzero.com/uart-rx-and-tx.html" title="UART收发数据的讨论">UART收发数据的讨论</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://xinzero.com/ltm8032-adj-resistor-equation.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>QuartusII.sof文件转换为.jic文件的几种方法</title>
		<link>http://xinzero.com/quartus-tansfer-sof-file-to-jic-file.html</link>
		<comments>http://xinzero.com/quartus-tansfer-sof-file-to-jic-file.html#comments</comments>
		<pubDate>Fri, 01 Jul 2011 02:51:00 +0000</pubDate>
		<dc:creator>will</dc:creator>
				<category><![CDATA[学习笔记]]></category>
		<category><![CDATA[FPGA]]></category>
		<category><![CDATA[quartus]]></category>

		<guid isPermaLink="false">http://xinzero.com/?p=465</guid>
		<description><![CDATA[在默认的情况下，Quartus编译综合之后生成的sof文件，而通常都使用JTAG方式下载FPGA外部的配置芯片，这就需要就.sof文件转换为.jic文件。有点像TI DSP的.out文件转换.bin文件，也是为了烧写下载方便。
1、通过Quartus的图像化界面转换
Quartus已经提供了转换工具，并且是图形化的。在“File-&#62;Convert Programming Files”,转化界面如下图所示。

2、通过命令行工具quartus_cpf.exe
quartus_cpf -d EPCS16 &#8211;sfl_device=EP3C40F324 -c sEP3CTest.sof sEP3CTest.jic
但每次输入命令行太麻烦，还是使用批处理简化一下操作，双击即可搞定O(∩_∩)O哈哈~。下载示例文件
在命令行下输入quartus_cpf –help=jic，可以查看sof文件转jic文件的帮助。
PS:quartus_cpf.exe是Quartus的bin目录下的文件，此软件功能非常完备，可以查看—help中的说明。这个软件的编写非常完备，值得学习呀。
相关文章FPGA中的多时钟设计]]></description>
			<content:encoded><![CDATA[<p>在默认的情况下，Quartus编译综合之后生成的sof文件，而通常都使用JTAG方式下载FPGA外部的配置芯片，这就需要就.sof文件转换为.jic文件。有点像<a href="http://xinzero.com/trans-ti-out-file-to-bin-file.html" target="_blank">TI DSP的.out文件转换.bin文件</a>，也是为了烧写下载方便。</p>
<p>1、通过Quartus的图像化界面转换</p>
<p>Quartus已经提供了转换工具，并且是图形化的。在“File-&gt;Convert Programming Files”,转化界面如下图所示。</p>
<p><a href="http://xinzero.com/wordpress/wp-content/uploads/2011/06/quartus_programfileconvert.png"><img style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" title="quartus_program file convert副本" src="http://xinzero.com/wordpress/wp-content/uploads/2011/06/quartus_programfileconvert_thumb.png" border="0" alt="quartus_program file convert副本" width="572" height="500" /></a></p>
<p>2、通过命令行工具quartus_cpf.exe</p>
<p>quartus_cpf -d EPCS16 &#8211;sfl_device=EP3C40F324 -c sEP3CTest.sof sEP3CTest.jic</p>
<p>但每次输入命令行太麻烦，还是使用批处理简化一下操作，双击即可搞定O(∩_∩)O哈哈~。<a href="http://dl.dbank.com/c005ex2fb3" target="_blank">下载示例文件</a></p>
<p>在命令行下输入quartus_cpf –help=jic，可以查看sof文件转jic文件的帮助。</p>
<p>PS:quartus_cpf.exe是Quartus的bin目录下的文件，此软件功能非常完备，可以查看—help中的说明。这个软件的编写非常完备，值得学习呀。</p>
<h3  class="related_post_title">相关文章</h3><ul class="related_post"><li><a href="http://xinzero.com/multiclock-designs-in-fpga.html" title="FPGA中的多时钟设计">FPGA中的多时钟设计</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://xinzero.com/quartus-tansfer-sof-file-to-jic-file.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>开关电源与线性电源</title>
		<link>http://xinzero.com/linear-voltage-regulator-and-switch-regulator.html</link>
		<comments>http://xinzero.com/linear-voltage-regulator-and-switch-regulator.html#comments</comments>
		<pubDate>Mon, 30 May 2011 13:29:08 +0000</pubDate>
		<dc:creator>will</dc:creator>
				<category><![CDATA[学习笔记]]></category>

		<guid isPermaLink="false">http://xinzero.com/?p=348</guid>
		<description><![CDATA[用过的电源芯片也比较多了，主要就是线性电源与开关电源。
线性电源的优点全线性稳压，线性稳压的好处是抗干扰能力强，如果再加一些滤波电容，可以控制纹（Ripple）波到很小很小，据说能到0.1mV。
线性电源的缺点就是转换效率低，发热量很大，烫手，大电流输出时一般都需要加散热片，效率低是线性稳压电源的致命缺点。线性电源的输入端与输出端的电流是相等的，效率一般是由输入电压与输出电压的压差控制的，为输出电压值与输入电压值之比。现在有些低压差的线性电源芯片，可以适当的提高效率，如LT3021、LTC1844等，压差200mV即可驱动下级输出，只是在实际使用中用不到此极限值，因输入电压很难调准到某个准确的值，而且个电路板之间存在差异，为了减少批生产的工作的工作量，会选择500mV以上的压差，从而损失一些效率。
开关电源是通过变压器原理将电压进行变化，输入端的电流与输出端的电流不等，效率一般与负载使用输出的电压与电流均有关。
开关电源的优点，效率高，效率在90%以上是比较正常，封装够小，外围元器件又少。缺点是电磁兼容性（EMC）不好，由于开关有频率，脉冲啊，当开关电源芯片后面有一个高频的脉冲信号，比如一个完整的电路中有两款开关电源或者，开关电源后面接一个频率很高的MCU，好的情况下看看的电路纹波，简直就是正弦波，差的情况电路就出错，引起电路不稳定。往往是比较难解决的。
目前开关电源工艺的改进，开发出了超低噪的开关电源芯片，如LTM8032，电磁兼容性好，效率高且可接较大的负载。
PS：我们使用凌特的电源较多，比较熟并非AD。凌特的电源也是出了名的贵，焊接费都高一些，LGA封装嘛。
随机文章卡巴斯基7.0（kav7.0）数据库损毁，解决办法最佳黑色背景的Visual Studio 2005配置编程读取注册表获取串口信息（支持Vista）Windows下subversion强制写日志强制Source insight代码对齐]]></description>
			<content:encoded><![CDATA[<p>用过的电源芯片也比较多了，主要就是线性电源与开关电源。</p>
<p>线性电源的优点全线性稳压，线性稳压的好处是抗干扰能力强，如果再加一些滤波电容，可以控制纹（Ripple）波到很小很小，据说能到0.1mV。</p>
<p>线性电源的缺点就是转换效率低，发热量很大，烫手，大电流输出时一般都需要加散热片，效率低是线性稳压电源的致命缺点。线性电源的输入端与输出端的电流是相等的，效率一般是由输入电压与输出电压的压差控制的，为输出电压值与输入电压值之比<a href="http://xinzero.com/wordpress/wp-content/uploads/2011/05/clip_image002.gif"><img style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" title="clip_image002" src="http://xinzero.com/wordpress/wp-content/uploads/2011/05/clip_image002_thumb.gif" border="0" alt="clip_image002" width="57" height="47" /></a>。现在有些低压差的线性电源芯片，可以适当的提高效率，如LT3021、LTC1844等，压差200mV即可驱动下级输出，只是在实际使用中用不到此极限值，因输入电压很难调准到某个准确的值，而且个电路板之间存在差异，为了减少批生产的工作的工作量，会选择500mV以上的压差，从而损失一些效率。</p>
<p>开关电源是通过变压器原理将电压进行变化，输入端的电流与输出端的电流不等，效率一般与负载使用输出的电压与电流均有关。</p>
<p>开关电源的优点，效率高，效率在90%以上是比较正常，封装够小，外围元器件又少。缺点是电磁兼容性（EMC）不好，由于开关有频率，脉冲啊，当开关电源芯片后面有一个高频的脉冲信号，比如一个完整的电路中有两款开关电源或者，开关电源后面接一个频率很高的MCU，好的情况下看看的电路纹波，简直就是正弦波，差的情况电路就出错，引起电路不稳定。往往是比较难解决的。</p>
<p>目前开关电源工艺的改进，开发出了超低噪的开关电源芯片，如LTM8032，电磁兼容性好，效率高且可接较大的负载。</p>
<p>PS：我们使用凌特的电源较多，比较熟并非AD。凌特的电源也是出了名的贵，焊接费都高一些，LGA封装嘛。</p>
<h3  class="related_post_title">随机文章</h3><ul class="related_post"><li><a href="http://xinzero.com/crackpdf-crack-pdf-files.html" title="CrackPDF破解加密的pdf文件">CrackPDF破解加密的pdf文件</a></li><li><a href="http://xinzero.com/word-caption-and-cross-reference.html" title="题注与交叉引用，批量更新域&mdash;&mdash;word使用技巧">题注与交叉引用，批量更新域&mdash;&mdash;word使用技巧</a></li><li><a href="http://xinzero.com/ccs3-3-bool-type-redeclared.html" title="CCS3.3 Bool类型重复定义">CCS3.3 Bool类型重复定义</a></li><li><a href="http://xinzero.com/qq-domain-mail.html" title="QQ域名邮箱，使QQ邮箱更拉风">QQ域名邮箱，使QQ邮箱更拉风</a></li><li><a href="http://xinzero.com/boot-vxworks-on-vmware.html" title="VmWare中安装VxWorks-常见问题解决方法">VmWare中安装VxWorks-常见问题解决方法</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://xinzero.com/linear-voltage-regulator-and-switch-regulator.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>俄罗斯套娃问题的C语言解</title>
		<link>http://xinzero.com/russian-doll-problems.html</link>
		<comments>http://xinzero.com/russian-doll-problems.html#comments</comments>
		<pubDate>Sun, 06 Jun 2010 03:51:19 +0000</pubDate>
		<dc:creator>will</dc:creator>
				<category><![CDATA[学习笔记]]></category>
		<category><![CDATA[C语言]]></category>

		<guid isPermaLink="false">http://xinzero.com/russian-doll-problems.html</guid>
		<description><![CDATA[貌似是中兴出的题目，原题如下：
伊万洛夫在比武大会上力克群雄，成为新一届“草原雄鹰”，为部落赢得了莫大荣誉。首领决定要重重奖赏，他对伊万洛夫说：“孩子，你是知道的，面前的这片草原，南北向和东西向的道路纵横交错。现在，路口放着纯金打造的俄罗斯娃娃，重量大小不等，重的都能装下轻的。你可以沿着道路飞奔，拾取路口的娃娃，要求是任何时刻必须是一个套娃，装好后就不能再拆开了。注意不要走重复路。”      请你为伊万洛夫规划路线，使得他能够有最大的收获。       Input:&#160; cross.txt       输入包括多组测试用例；       每个测试用例开始是一对整数&#60;R, C&#62;，R表示东西向道路数，C表示南北向道路总数；接下来R行，每行包括C个正整数W[r,c] ，分别表示第r条东西向道路与第c条南北向道路交叉处路口放置的俄罗斯娃娃的重量。       Output:       输出能有最大收获的路径规划。       假设1：    [...]]]></description>
			<content:encoded><![CDATA[<p>貌似是中兴出的题目，原题如下：</p>
<blockquote><p>伊万洛夫在比武大会上力克群雄，成为新一届“草原雄鹰”，为部落赢得了莫大荣誉。首领决定要重重奖赏，他对伊万洛夫说：“孩子，你是知道的，面前的这片草原，南北向和东西向的道路纵横交错。现在，路口放着纯金打造的俄罗斯娃娃，重量大小不等，重的都能装下轻的。你可以沿着道路飞奔，拾取路口的娃娃，要求是任何时刻必须是一个套娃，装好后就不能再拆开了。注意不要走重复路。”      <br />请你为伊万洛夫规划路线，使得他能够有最大的收获。       <br />Input:&#160; cross.txt       <br />输入包括多组测试用例；       <br />每个测试用例开始是一对整数&lt;R, C&gt;，R表示东西向道路数，C表示南北向道路总数；接下来R行，每行包括C个正整数W[r,c] ，分别表示第r条东西向道路与第c条南北向道路交叉处路口放置的俄罗斯娃娃的重量。       <br />Output:       <br />输出能有最大收获的路径规划。       <br />假设1：       <br />&#160;&#160; cross.txt       <br />&#160;&#160; 2&#160;&#160;&#160;&#160; 7       <br />&#160;&#160; 1&#160;&#160;&#160;&#160; 2&#160;&#160; 13&#160;&#160; 6&#160;&#160; 7&#160; 12&#160; 11       <br />&#160;&#160; 14&#160;&#160; 3&#160;&#160; 4&#160;&#160;&#160;&#160; 5&#160;&#160; 8&#160;&#160; 9&#160;&#160; 10       <br />输出：       <br />1 2 3 4 5 6 7 8 9 10 11 12       <br />假设2：       <br />&#160;&#160; cross.txt       <br />&#160;&#160; 5&#160;&#160;&#160; 5</p>
<p>1&#160;&#160; 16&#160;&#160; 15&#160;&#160; 14&#160;&#160; 13</p>
<p>2&#160;&#160; 17&#160;&#160; 24&#160;&#160; 23&#160;&#160; 12      <br />3&#160;&#160; 18&#160;&#160; 25&#160;&#160; 22&#160;&#160; 11       <br />4&#160;&#160; 19&#160;&#160; 20&#160;&#160; 21&#160;&#160; 10       <br />5&#160;&#160;&#160; 6&#160;&#160;&#160;&#160; 7&#160;&#160;&#160;&#160; 8&#160;&#160;&#160;&#160; 9       <br />输出：       <br />1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25       <br />注释:       <br />1)从&lt;0,0&gt;出发;       <br />2)路线不能重复;       <br />3)不要求最后回到出发点。</p>
</blockquote>
<p>貌似很多人都想到了递归方法的实现，由于对于递归使用很少，没有把握，就使用以前维特比译码相类似的方法。直接放代码，代码质量较差，见谅。</p>
<pre><span style="color: #008000">/*
http://xinzero.com
will@xinzero.com
*/</span>
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

<span style="color: #0000ff">struct</span> stat{
	<span style="color: #0000ff">int</span> met;	<span style="color: #008000">//profit</span>
	<span style="color: #0000ff">int</span> value;
	<span style="color: #0000ff">int</span> x;
	<span style="color: #0000ff">int</span> y;
	stat *plast;
};

<span style="color: #0000ff">void</span> main()
{
	<span style="color: #0000ff">int</span> *pint=NULL,*pInit=NULL;
	stat *pPath=NULL,*pSta=NULL,*pMax=NULL;
	<span style="color: #0000ff">int</span> row=0,col=0;
	<span style="color: #0000ff">int</span> i=0,j=0,k=0;
	<span style="color: #0000ff">int</span> m=0,n=0,l=0;
	<span style="color: #0000ff">int</span> imax=0;
	<span style="color: #0000ff">int</span> M=0,R=0;
	printf(&quot;<span style="color: #8b0000">input R,C value:</span>&quot;);
	scanf_s(&quot;<span style="color: #8b0000">%d %d</span>&quot;,&amp;row,&amp;col);
	printf(&quot;<span style="color: #8b0000">[R,C]=[%d,%d]\r\n</span>&quot;,row,col);
	pInit = (<span style="color: #0000ff">int</span>*)malloc(<span style="color: #0000ff">sizeof</span>(<span style="color: #0000ff">int</span>)*row*col);
	pint = pInit;
	<span style="color: #0000ff">for</span>(i=0;i&lt;row;i++)
	{
		<span style="color: #0000ff">for</span>(j=0;j&lt;col;j++)
		{
			scanf_s(&quot;<span style="color: #8b0000">%d</span>&quot;,pint++);
		}
	}

	pint = pInit;
	printf(&quot;<span style="color: #8b0000">The path\r\n</span>&quot;);
	<span style="color: #0000ff">for</span>(i=0;i&lt;row;i++)
	{
		<span style="color: #0000ff">for</span>(j=0;j&lt;col;j++)
		{
			printf(&quot;<span style="color: #8b0000">%d </span>&quot;,*pint++);
		}
		printf(&quot;<span style="color: #8b0000">\r\n</span>&quot;);
	}

	pint = pInit;
	pPath = (stat*)malloc(<span style="color: #0000ff">sizeof</span>(stat)*row*row*col*col);
	pSta = pPath;
	<span style="color: #0000ff">for</span>(i=0;i&lt;row*col*row*col;i++)
	{
		pSta-&gt;met =-1;
		pSta-&gt;value = 0;
		pSta-&gt;plast =NULL;
		pSta++;
	}
	pSta = pPath;
	pSta-&gt;met = *pint;
	pSta-&gt;value = *pint;
	pSta-&gt;x=0;
	pSta-&gt;y=0;
	i=j=0;
	<span style="color: #0000ff">for</span>(k=1;k&lt;row*col;k++)
	{
		M = 0;
		<span style="color: #0000ff">for</span>(l=0;l&lt;row*col;l++)
		{
			m = l*row*col+k;	<span style="color: #008000">//current valid</span>
			<span style="color: #0000ff">if</span>(pSta[m-1].met==-1)
			{
				<span style="color: #0000ff">continue</span>;
			}
			<span style="color: #0000ff">else</span>
			{
				i = pSta[m-1].x;
				j = pSta[m-1].y;
				printf(&quot;<span style="color: #8b0000">i=%d,j=%d</span>&quot;,i,j);
				<span style="color: #0000ff">if</span>((i+1)&lt;row)
				{
					n = (i+1)*col + j;
					<span style="color: #0000ff">if</span>(pint[n]&gt;pSta[m-1].value)
					{
						R = M*row*col + k;
						pSta[R].met = pSta[m-1].met + pint[n];
						pSta[R].value = pint[n];
						pSta[R].x = i+1;
						pSta[R].y = j;
						pSta[R].plast = &amp;pSta[m-1];
						printf(&quot;<span style="color: #8b0000">[%d,%d],%d,met:%d</span>&quot;,i+1,j,R,pSta[R].met);
						M++;
					}
				}
				<span style="color: #0000ff">if</span>((i-1)&gt;=0)
				{
					n = (i-1)*col + j;
					<span style="color: #0000ff">if</span>(pint[n]&gt;pSta[m-1].value)
					{
						R = M*row*col + k;
						pSta[R].met = pSta[m-1].met + pint[n];
						pSta[R].value = pint[n];
						pSta[R].x = i-1;
						pSta[R].y = j;
						pSta[R].plast = &amp;pSta[m-1];
						printf(&quot;<span style="color: #8b0000">[%d,%d],%d,met:%d</span>&quot;,i-1,j,R,pSta[R].met);
						M++;
					}
				}
				<span style="color: #0000ff">if</span>((j+1)&lt;col)
				{
					n = i*col + j+1;
					<span style="color: #0000ff">if</span>(pint[n]&gt;pSta[m-1].value)
					{
						R = M*row*col + k;
						pSta[R].met = pSta[m-1].met + pint[n];
						pSta[R].value = pint[n];
						pSta[R].x = i;
						pSta[R].y = j+1;
						pSta[R].plast = &amp;pSta[m-1];
						printf(&quot;<span style="color: #8b0000">[%d,%d],%d,met:%d</span>&quot;,i,j+1,pSta[R],pSta[R].met);
						M++;
					}
				}
				<span style="color: #0000ff">if</span>((j-1)&gt;=0)
				{
					n = i*col + j-1;
					<span style="color: #0000ff">if</span>(pint[n]&gt;pSta[m-1].value)
					{
						R = M*row*col + k;
						pSta[R].met = pSta[m-1].met + pint[n];
						pSta[R].value = pint[n];
						pSta[R].x = i;
						pSta[R].y = j-1;
						pSta[R].plast = &amp;pSta[m-1];
						printf(&quot;<span style="color: #8b0000">[%d,%d],%d,met:%d</span>&quot;,i,j-1,pSta[R],pSta[R].met);
						M++;
					}
				}
				printf(&quot;<span style="color: #8b0000">\r\n</span>&quot;);
			}
		}
		printf(&quot;<span style="color: #8b0000">\r\n</span>&quot;);
	}

	<span style="color: #0000ff">for</span>(k=row*col-1;k&gt;=0;k--)
	{
		<span style="color: #0000ff">for</span>(l=0;l&lt;row*col;l++)
		{
			m = l*row*col+k;
			<span style="color: #008000">//printf(&quot;%d,%d,&quot;,m,pSta[m].met);</span>
			<span style="color: #0000ff">if</span>(pSta[m].met==-1)
			{
				<span style="color: #0000ff">continue</span>;
			}
			<span style="color: #0000ff">else</span>
			{
				<span style="color: #0000ff">if</span>(imax&lt;pSta[m].met)
				{
					imax = pSta[m].met;
					pMax = &amp;pSta[m];
					printf(&quot;<span style="color: #8b0000">imax:%d\n</span>&quot;,imax);
				}

			}
		}
	}
	pint = pInit;
	i=0;
	<span style="color: #008000">//do</span>
	<span style="color: #0000ff">while</span>(pMax-&gt;plast!=NULL)
	{
		*pint = pMax-&gt;value;
		pMax = pMax-&gt;plast;
		printf(&quot;<span style="color: #8b0000">%d,%d </span>&quot;,i,*pint);
		pint++;
		i++;
	}<span style="color: #008000">//while(pMax-&gt;plast!=NULL);</span>

	*pint = pMax-&gt;value;
	pMax = pMax-&gt;plast;
	printf(&quot;<span style="color: #8b0000">%d,%d </span>&quot;,i,*pint);
	pint++;
	i++;
	printf(&quot;<span style="color: #8b0000">\r\n</span>&quot;);
	pint = pInit;
	<span style="color: #0000ff">while</span>(i&gt;0)
	{
		printf(&quot;<span style="color: #8b0000">%d </span>&quot;,pint[i-1]);
		i--;
	}
	printf(&quot;<span style="color: #8b0000">\r\n</span>&quot;);
	<span style="color: #008000">//system(&quot;pause&quot;);</span>
	free(pInit);
	free(pPath);
}</pre>
<h3  class="related_post_title">相关文章</h3><ul class="related_post"><li><a href="http://xinzero.com/source-insight-file-switch-tabbar.html" title="source insight的切换标签栏工具（switch Tabbar）">source insight的切换标签栏工具（switch Tabbar）</a></li><li><a href="http://xinzero.com/ccs3-3-__strasgi-bug.html" title="CCS3.3关于__strasgi的bug">CCS3.3关于__strasgi的bug</a></li><li><a href="http://xinzero.com/tm320vc33-ccitt-crc-c-programing.html" title="TMS320VC33下crc16源程序">TMS320VC33下crc16源程序</a></li><li><a href="http://xinzero.com/vc2005-console-project-problem.html" title="VC2005下基于控制台(console)程序设计的小问题">VC2005下基于控制台(console)程序设计的小问题</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://xinzero.com/russian-doll-problems.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CCS3.3关于__strasgi的bug</title>
		<link>http://xinzero.com/ccs3-3-__strasgi-bug.html</link>
		<comments>http://xinzero.com/ccs3-3-__strasgi-bug.html#comments</comments>
		<pubDate>Wed, 28 Apr 2010 15:25:20 +0000</pubDate>
		<dc:creator>will</dc:creator>
				<category><![CDATA[学习笔记]]></category>
		<category><![CDATA[C语言]]></category>

		<guid isPermaLink="false">http://xinzero.com/?p=273</guid>
		<description><![CDATA[今天在用TI CCS3.3编译程序的是否发现一个关于__strasgi 未定义的bug。将以下代码放到CCS3.3中编译

//test.h
typedef struct{
	float p[10];
	unsigned char d[6];
	unsigned char valid[6];
}szero;
void tefun(szero vi);
//test.c
#include &#34;Test.h&#34;
void tefun(szero vi)
{
}
就会出现__strasgi 未定义的错误，经测试发现，使用C++编译器也会出现类似的错误，而将此代码用VC2005编译则没有错误提示。测试还发现只有szero中的变量类型为int或float的数组且长度大于3才会出这样的问题。出现的原因不清楚，但是解决办法倒是很简单，将参数改成指针型就可以了。

相关文章source insight的切换标签栏工具（switch Tabbar）俄罗斯套娃问题的C语言解TMS320VC33下crc16源程序VC2005下基于控制台(console)程序设计的小问题]]></description>
			<content:encoded><![CDATA[<p>今天在用TI CCS3.3编译程序的是否发现一个关于__strasgi 未定义的bug。将以下代码放到CCS3.3中编译</p>
<div>
<pre><span style="color: #008000">//test.h</span>
typedef <span style="color: #0000ff">struct</span>{
	<span style="color: #0000ff">float</span> p[10];
	unsigned <span style="color: #0000ff">char</span> d[6];
	unsigned <span style="color: #0000ff">char</span> valid[6];
}szero;
<span style="color: #0000ff">void</span> tefun(szero vi);
<span style="color: #008000">//test.c</span>
#include &quot;<span style="color: #8b0000">Test.h</span>&quot;
<span style="color: #0000ff">void</span> tefun(szero vi)
{
}</pre>
<p>就会出现__strasgi 未定义的错误，经测试发现，使用C++编译器也会出现类似的错误，而将此代码用VC2005编译则没有错误提示。测试还发现只有szero中的变量类型为int或float的数组且长度大于3才会出这样的问题。出现的原因不清楚，但是解决办法倒是很简单，将参数改成指针型就可以了。</p>
</div>
<h3  class="related_post_title">相关文章</h3><ul class="related_post"><li><a href="http://xinzero.com/source-insight-file-switch-tabbar.html" title="source insight的切换标签栏工具（switch Tabbar）">source insight的切换标签栏工具（switch Tabbar）</a></li><li><a href="http://xinzero.com/russian-doll-problems.html" title="俄罗斯套娃问题的C语言解">俄罗斯套娃问题的C语言解</a></li><li><a href="http://xinzero.com/tm320vc33-ccitt-crc-c-programing.html" title="TMS320VC33下crc16源程序">TMS320VC33下crc16源程序</a></li><li><a href="http://xinzero.com/vc2005-console-project-problem.html" title="VC2005下基于控制台(console)程序设计的小问题">VC2005下基于控制台(console)程序设计的小问题</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://xinzero.com/ccs3-3-__strasgi-bug.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>windows下修改环境变量的方法</title>
		<link>http://xinzero.com/modify-windows-environment-variables.html</link>
		<comments>http://xinzero.com/modify-windows-environment-variables.html#comments</comments>
		<pubDate>Sun, 25 Apr 2010 16:03:17 +0000</pubDate>
		<dc:creator>will</dc:creator>
				<category><![CDATA[学习笔记]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://xinzero.com/?p=270</guid>
		<description><![CDATA[Windows环境变量是Windows系统定义的环境变量，可以在命令行下（运行中输入cmd回车），通过set命令查看，这些变量对于编写批处理文件用处很大，在批处理中%XXX%来使用一个环境变量即可，XXX代表你想使用的环境变量。环境变量中使用较多的是%path%，通常用来方便命令行处理，在运行中快速运行程序，用到了该环境变量。
通常可以通过cmd命令行下set xname=xxx来设置环境变量，如set %path%=%path%；c:，这是将c盘根目录增加至path环境变量。其它的修改方法类似。但这么改变是临时的，在下次本次关闭cmd之后，此环境变量将失效。如果需要永久设置一个环境变量可以通过“我的电脑右键属性-&#62;高级系统设置-&#62;高级-&#62;环境变量”来设置。由于Windows系统定义的环境变量很多，如果每次都这么设置在某些时候也是件很麻烦的事情。将已经修改后的环境变量导出备份，备份位置为[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session  Manager\Environment]，下次需要修改直接双击导入就可以了。
相关文章Windows下如何更改串口号东芝L525笔记本XP系统下禁用触摸板解决XP进入桌面后，加载网络与用户名超慢UltraEdit Windows下常用的编辑器-UEStudio下载编程读取注册表获取串口信息（支持Vista）]]></description>
			<content:encoded><![CDATA[<p>Windows环境变量是Windows系统定义的环境变量，可以在命令行下（运行中输入cmd回车），通过set命令查看，这些变量对于编写批处理文件用处很大，在批处理中%XXX%来使用一个环境变量即可，XXX代表你想使用的环境变量。环境变量中使用较多的是%path%，通常用来方便命令行处理，在<a href="http://http://xinzero.com/windows-run-launch.html">运行中快速运行程序</a>，用到了该环境变量。</p>
<p>通常可以通过cmd命令行下set xname=xxx来设置环境变量，如set %path%=%path%；c:，这是将c盘根目录增加至path环境变量。其它的修改方法类似。但这么改变是临时的，在下次本次关闭cmd之后，此环境变量将失效。如果需要永久设置一个环境变量可以通过“我的电脑右键属性-&gt;高级系统设置-&gt;高级-&gt;环境变量”来设置。由于Windows系统定义的环境变量很多，如果每次都这么设置在某些时候也是件很麻烦的事情。将已经修改后的环境变量导出备份，备份位置为[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session  Manager\Environment]，下次需要修改直接双击导入就可以了。</p>
<h3  class="related_post_title">相关文章</h3><ul class="related_post"><li><a href="http://xinzero.com/change-rs232-com-port.html" title="Windows下如何更改串口号">Windows下如何更改串口号</a></li><li><a href="http://xinzero.com/toshiba-l525-disable-touchpad.html" title="东芝L525笔记本XP系统下禁用触摸板">东芝L525笔记本XP系统下禁用触摸板</a></li><li><a href="http://xinzero.com/windows-xp-start-time-fix.html" title="解决XP进入桌面后，加载网络与用户名超慢">解决XP进入桌面后，加载网络与用户名超慢</a></li><li><a href="http://xinzero.com/windows-ultraedit-startup.html" title="UltraEdit Windows下常用的编辑器-UEStudio下载">UltraEdit Windows下常用的编辑器-UEStudio下载</a></li><li><a href="http://xinzero.com/registry-serialcomm.html" title="编程读取注册表获取串口信息（支持Vista）">编程读取注册表获取串口信息（支持Vista）</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://xinzero.com/modify-windows-environment-variables.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TMS320VC33下crc16源程序</title>
		<link>http://xinzero.com/tm320vc33-ccitt-crc-c-programing.html</link>
		<comments>http://xinzero.com/tm320vc33-ccitt-crc-c-programing.html#comments</comments>
		<pubDate>Fri, 23 Apr 2010 16:25:52 +0000</pubDate>
		<dc:creator>will</dc:creator>
				<category><![CDATA[学习笔记]]></category>
		<category><![CDATA[C语言]]></category>
		<category><![CDATA[TMS320VC33]]></category>

		<guid isPermaLink="false">http://xinzero.com/?p=262</guid>
		<description><![CDATA[在对DSP编程，或者说是嵌入式编程之前必须对芯片有所了解，Datasheet和User‘s Guide必不可少。在编写CRC校验的时候遇到了TMS320VC33的字长问题，在解决了问题之后将多项式为X16+X12+X5+1的符合CCITT标准的CRC16源码发上来。目前VC33中运行正常的是查表法的程序。还有一个移位法的程序，对于非整字节校验也是有很有用的，但未经过验证，其实也很简单，就是运算效率较低，就不发了。    
/*******************************
writer:will@xinzero.com
date:2010-4-9
*******************************/
static unsigned short CRC16Table[256] = {
 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
 0xA56A, 0xB54B, 0x8528, 0x9509, [...]]]></description>
			<content:encoded><![CDATA[<p>在对DSP编程，或者说是嵌入式编程之前必须对芯片有所了解，Datasheet和User‘s Guide必不可少。在编写CRC校验的时候遇到了<a title="TMS320VC33字长问题" href="http://xinzero.com/tms320vc33-word-length.html" target="_self">TMS320VC33的字长问题</a>，在解决了问题之后将多项式为X16+X12+X5+1的符合CCITT标准的CRC16源码发上来。目前VC33中运行正常的是查表法的程序。还有一个移位法的程序，对于非整字节校验也是有很有用的，但未经过验证，其实也很简单，就是运算效率较低，就不发了。    </p>
<pre><span style="color: #008000">/*******************************
writer:will@xinzero.com
date:2010-4-9
*******************************/</span>
<span style="color: #0000ff">static</span> <span style="color: #0000ff">unsigned</span> <span style="color: #0000ff">short</span> CRC16Table[256] = {
 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0,
};

<span style="color: #0000ff">unsigned</span> <span style="color: #0000ff">short</span> getCRC16(<span style="color: #0000ff">unsigned</span> <span style="color: #0000ff">long</span> <span style="color: #0000ff">int</span> *pMsg,<span style="color: #0000ff">unsigned</span> <span style="color: #0000ff">int</span> len)
{
 <span style="color: #0000ff">unsigned</span> <span style="color: #0000ff">int</span> i=0,j= 0;
 <span style="color: #0000ff">unsigned</span> <span style="color: #0000ff">int</span> CRCindex = 0;
 <span style="color: #0000ff">unsigned</span> <span style="color: #0000ff">short</span> CRC16Temp=0;
 CMD_WORD byte_word;

 <span style="color: #0000ff">for</span>(i=0;i&lt;len;i++)
 {
  byte_word.i = pMsg[i];

  CRCindex   = ((CRC16Temp&gt;&gt;8) ^ (byte_word.b.cmd0&amp;0xff))&amp;0xff;
  CRC16Temp&lt;&lt;= 8;
  CRC16Temp ^= CRC16Table[CRCindex];
  CRC16Temp &amp;= 0xffff;

  CRCindex   = ((CRC16Temp&gt;&gt;8) ^ (byte_word.b.cmd1&amp;0xff))&amp;0xff;
  CRC16Temp&lt;&lt;= 8;
  CRC16Temp ^= CRC16Table[CRCindex];
  CRC16Temp &amp;= 0xffff;

  CRCindex   = ((CRC16Temp&gt;&gt;8) ^ (byte_word.b.cmd2&amp;0xff))&amp;0xff;
  CRC16Temp&lt;&lt;= 8;
  CRC16Temp ^= CRC16Table[CRCindex];
  CRC16Temp &amp;= 0xffff;

  CRCindex   = ((CRC16Temp&gt;&gt;8) ^ (byte_word.b.cmd3&amp;0xff))&amp;0xff;
  CRC16Temp&lt;&lt;= 8;
  CRC16Temp ^= CRC16Table[CRCindex];
  CRC16Temp &amp;= 0xffff;
 }
 <span style="color: #0000ff">return</span> CRC16Temp;
}</pre>
<h3  class="related_post_title">相关文章</h3><ul class="related_post"><li><a href="http://xinzero.com/source-insight-file-switch-tabbar.html" title="source insight的切换标签栏工具（switch Tabbar）">source insight的切换标签栏工具（switch Tabbar）</a></li><li><a href="http://xinzero.com/russian-doll-problems.html" title="俄罗斯套娃问题的C语言解">俄罗斯套娃问题的C语言解</a></li><li><a href="http://xinzero.com/ccs3-3-__strasgi-bug.html" title="CCS3.3关于__strasgi的bug">CCS3.3关于__strasgi的bug</a></li><li><a href="http://xinzero.com/tms320vc33-word-length.html" title="TMS320VC33字长问题">TMS320VC33字长问题</a></li><li><a href="http://xinzero.com/vc2005-console-project-problem.html" title="VC2005下基于控制台(console)程序设计的小问题">VC2005下基于控制台(console)程序设计的小问题</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://xinzero.com/tm320vc33-ccitt-crc-c-programing.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TMS320VC33字长问题</title>
		<link>http://xinzero.com/tms320vc33-word-length.html</link>
		<comments>http://xinzero.com/tms320vc33-word-length.html#comments</comments>
		<pubDate>Wed, 21 Apr 2010 14:22:04 +0000</pubDate>
		<dc:creator>will</dc:creator>
				<category><![CDATA[学习笔记]]></category>
		<category><![CDATA[DSP]]></category>
		<category><![CDATA[TMS320VC33]]></category>

		<guid isPermaLink="false">http://xinzero.com/?p=260</guid>
		<description><![CDATA[TMS320VC33是TI经典的浮点运算DSP，是从c3x中演变而来的，具有低功耗，大RAM（与c3x相比），在2000年的设计中使用较多，目前已经停产。就这么个片子把我搞惨了。
首先是原本的程序用C编程，使用File级的优化-03，优化级别最高了，对于代码的分析就有困难了，但原本的程序经过使用验证是没有问题的。现在的工作是需要加入一个CRC校验函数。首先通过VC2005编写一个可以在windows下正确运行的crc c程序，用cc编译后下载到片子上运行，从串口看数据crc校验错，程序有问题。开始怀疑编译器优化有问题，将此文件的优化去掉，还是不对。又怀疑是crc算法效率太低，采用bit移位法计算，改变crc算法，采用查表法，但是不对。
由于完整程序太大，不能在线仿真，所以调试起来很麻烦。最后没有办法，单单将crc函数挂上仿真器单独跑，结果crc错。这么就好找原因了，将每次crc查表的结果printf出来，很快就找到原因了。在程序中查表的位置号用unsigned char变量，crc结果用unsigned short，从中间结果看unsigned char型变量可以达到0&#215;400值，unsigned short可以达到0&#215;1287D0，这crc能校验对才有问题呢？printf sizeof 各种数据类型发现，在VC33中unsigned char、unsigned short、unsigned int、unsigned long int的长度都是1，位长度都是32bit，也就是说在VC33定义的变量类型只是个符号，与内存的分配无关，通常情况在cc下将float赋给int，连个warning都没有。在软件仿真和硬件仿真下都可以验证，这是编译器决定的。找到了原因，在每次运算完之后，根据理想的数据类型，取有效的位数即可（铵位与运算）。
另外VC33的地址空间也是与1字（int）对应的，就是一个地址对应一个存储空间，只是这个存储空间是32bit长。
最早使用ADI的BF系列芯片也没有这样的，到后期使用TI的C6000系列数据类型也是与存储空间严格对应的。
相关文章TI CCS3.3 out文件转bin文件说明hex转bin方法与工具TI DSP生成.out文件转换为.Bin文件TMS320VC33下crc16源程序]]></description>
			<content:encoded><![CDATA[<p>TMS320VC33是TI经典的浮点运算DSP，是从c3x中演变而来的，具有低功耗，大RAM（与c3x相比），在2000年的设计中使用较多，目前已经停产。就这么个片子把我搞惨了。</p>
<p>首先是原本的程序用C编程，使用File级的优化-03，优化级别最高了，对于代码的分析就有困难了，但原本的程序经过使用验证是没有问题的。现在的工作是需要加入一个CRC校验函数。首先通过VC2005编写一个可以在windows下正确运行的crc c程序，用cc编译后下载到片子上运行，从串口看数据crc校验错，程序有问题。开始怀疑编译器优化有问题，将此文件的优化去掉，还是不对。又怀疑是crc算法效率太低，采用bit移位法计算，改变crc算法，采用查表法，但是不对。</p>
<p>由于完整程序太大，不能在线仿真，所以调试起来很麻烦。最后没有办法，单单将crc函数挂上仿真器单独跑，结果crc错。这么就好找原因了，将每次crc查表的结果printf出来，很快就找到原因了。在程序中查表的位置号用unsigned char变量，crc结果用unsigned short，从中间结果看unsigned char型变量可以达到0&#215;400值，unsigned short可以达到0&#215;1287D0，这crc能校验对才有问题呢？printf sizeof 各种数据类型发现，在VC33中unsigned char、unsigned short、unsigned int、unsigned long int的长度都是1，位长度都是32bit，也就是说在VC33定义的变量类型只是个符号，与内存的分配无关，通常情况在cc下将float赋给int，连个warning都没有。在软件仿真和硬件仿真下都可以验证，这是编译器决定的。找到了原因，在每次运算完之后，根据理想的数据类型，取有效的位数即可（铵位与运算）。</p>
<p>另外VC33的地址空间也是与1字（int）对应的，就是一个地址对应一个存储空间，只是这个存储空间是32bit长。</p>
<p>最早使用ADI的BF系列芯片也没有这样的，到后期使用TI的C6000系列数据类型也是与存储空间严格对应的。</p>
<h3  class="related_post_title">相关文章</h3><ul class="related_post"><li><a href="http://xinzero.com/out-to-bin-direction-for-use.html" title="TI CCS3.3 out文件转bin文件说明">TI CCS3.3 out文件转bin文件说明</a></li><li><a href="http://xinzero.com/mothod-and-tool-of-hex-to-bin.html" title="hex转bin方法与工具">hex转bin方法与工具</a></li><li><a href="http://xinzero.com/trans-ti-out-file-to-bin-file.html" title="TI DSP生成.out文件转换为.Bin文件">TI DSP生成.out文件转换为.Bin文件</a></li><li><a href="http://xinzero.com/tm320vc33-ccitt-crc-c-programing.html" title="TMS320VC33下crc16源程序">TMS320VC33下crc16源程序</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://xinzero.com/tms320vc33-word-length.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>编程读取注册表获取串口信息（支持Vista）</title>
		<link>http://xinzero.com/registry-serialcomm.html</link>
		<comments>http://xinzero.com/registry-serialcomm.html#comments</comments>
		<pubDate>Wed, 10 Mar 2010 15:21:19 +0000</pubDate>
		<dc:creator>will</dc:creator>
				<category><![CDATA[学习笔记]]></category>
		<category><![CDATA[vc2005]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[串口通信]]></category>

		<guid isPermaLink="false">http://xinzero.com/?p=16</guid>
		<description><![CDATA[在编写串口通信程序时，经常需要列举计算机上目前可用的串口。最简单的方法是通过CreateFile串口号1~256（XP系统系统下最大支持的串口号为256），查看返回值，如果返回非INVALID_HANDLE_VALUE就证明此串口号存在。此方法简单实用，因为在只有一个串口的情况也需要遍历256个串口，需CreateFile256次，效率较低，而且不能显示目前正在使用的串口号。
下面介绍通过读取注册表获取串口号与串口个数的方法。
#define MAXCOMNO 256  //最大COM号256
typedef struct{
 char name[8];
 short no;
}SCOM;

/////用读注册表的方式查看系统的串口设备
void GetAvailableCom(SCOM *port,int &#38;cnt)
{
 HKEY  hKey; 
 LONG  ret; 
 OSVERSIONINFO    osvi; 
 BOOL  bOsVersionInfoEx; 
 CString  keyinfo;
 unsigned char comm_name[40];
 char ValueName[40];
 char szNO[3];
 int  i=0,j=0;
 cnt=0;
 DWORD  sType,Reserved,cbData,cbValueName;
 
 ZeroMemory(&#38;osvi,  sizeof(OSVERSIONINFO)); 
 osvi.dwOSVersionInfoSize  =  sizeof(OSVERSIONINFO); 
 
 keyinfo.Format(_T("HARDWARE\\DEVICEMAP\\SERIALCOMM"));
 //CString  keyinfo=_T("HARDWARE\\DEVICEMAP\\SERIALCOMM");

 i=0;  sType=REG_SZ;Reserved=0; 
 bOsVersionInfoEx  = GetVersionEx(&#38;osvi); 

 ret=RegOpenKeyEx(HKEY_LOCAL_MACHINE,keyinfo,0,KEY_ALL_ACCESS,&#38;hKey); 
 if  (ret==ERROR_SUCCESS)
 {
  if  (osvi.dwPlatformId  ==  VER_PLATFORM_WIN32_WINDOWS)    //WIN32,not used
  { 
   for(i=1;i&#60;=MAXCOMNO;i++) 
   {
    memset(comm_name, 0, 40);
    sprintf((char*)comm_name,"COM%d",i);
    ret=RegEnumValue(hKey, i, ValueName, &#38;cbValueName, NULL, &#38;sType, comm_name, &#38;cbData);
    if(ret==ERROR_SUCCESS)
    {
     i++;
    }

   } 
  } 
  else  if  (osvi.dwPlatformId  ==  VER_PLATFORM_WIN32_NT) //WINNT XP 2000
  { 
   do   
   { 
    cbData=40;cbValueName=40; 
    memset(comm_name,0,40);   
    memset(ValueName,0,40);
    memset(szNO,     0, 3);
    ret=RegEnumValue(hKey, i, ValueName, &#38;cbValueName, NULL, &#38;sType, comm_name, [...]]]></description>
			<content:encoded><![CDATA[<p>在编写<a title="调试串口通信程序" href="http://xinzero.com/serialport-communication-debug.html" target="_blank">串口通信程序</a>时，经常需要列举计算机上目前可用的串口。最简单的方法是通过CreateFile串口号1~256（XP系统系统下最大支持的串口号为256），查看返回值，如果返回非INVALID_HANDLE_VALUE就证明此串口号存在。此方法简单实用，因为在只有一个串口的情况也需要遍历256个串口，需CreateFile256次，效率较低，而且不能显示目前正在使用的串口号。</p>
<p>下面介绍通过读取注册表获取串口号与串口个数的方法。</p>
<pre name="code" class="cpp">#define MAXCOMNO 256  //最大COM号256
typedef struct{
 char name[8];
 short no;
}SCOM;

/////用读注册表的方式查看系统的串口设备
void GetAvailableCom(SCOM *port,int &amp;cnt)
{
 HKEY  hKey; 
 LONG  ret; 
 OSVERSIONINFO    osvi; 
 BOOL  bOsVersionInfoEx; 
 CString  keyinfo;
 unsigned char comm_name[40];
 char ValueName[40];
 char szNO[3];
 int  i=0,j=0;
 cnt=0;
 DWORD  sType,Reserved,cbData,cbValueName;
 
 ZeroMemory(&amp;osvi,  sizeof(OSVERSIONINFO)); 
 osvi.dwOSVersionInfoSize  =  sizeof(OSVERSIONINFO); 
 
 keyinfo.Format(_T("HARDWARE\\DEVICEMAP\\SERIALCOMM"));
 //CString  keyinfo=_T("HARDWARE\\DEVICEMAP\\SERIALCOMM");

 i=0;  sType=REG_SZ;Reserved=0; 
 bOsVersionInfoEx  = GetVersionEx(&amp;osvi); 

 ret=RegOpenKeyEx(HKEY_LOCAL_MACHINE,keyinfo,0,KEY_ALL_ACCESS,&amp;hKey); 
 if  (ret==ERROR_SUCCESS)
 {
  if  (osvi.dwPlatformId  ==  VER_PLATFORM_WIN32_WINDOWS)    //WIN32,not used
  { 
   for(i=1;i&lt;=MAXCOMNO;i++) 
   {
    memset(comm_name, 0, 40);
    sprintf((char*)comm_name,"COM%d",i);
    ret=RegEnumValue(hKey, i, ValueName, &amp;cbValueName, NULL, &amp;sType, comm_name, &amp;cbData);
    if(ret==ERROR_SUCCESS)
    {
     i++;
    }

   } 
  } 
  else  if  (osvi.dwPlatformId  ==  VER_PLATFORM_WIN32_NT) //WINNT XP 2000
  { 
   do   
   { 
    cbData=40;cbValueName=40; 
    memset(comm_name,0,40);   
    memset(ValueName,0,40);
    memset(szNO,     0, 3);
    ret=RegEnumValue(hKey, i, ValueName, &amp;cbValueName, NULL, &amp;sType, comm_name, &amp;cbData); 
    if  (ret==ERROR_SUCCESS) 
    { 
     for(j=0;j&lt;cbData;j++)
     {
      port-&gt;name[j]=comm_name[j];
      if(j&gt;2 &amp;&amp; j&lt;6)
      {
       szNO[j-3] = comm_name[j];
      }
     }
     port-&gt;no = atoi(szNO);
     port++;
     cnt++;
     i++; 
    } 
   }while(ret==ERROR_SUCCESS); 
  } 
 }
 RegCloseKey(hKey);
}</pre>
<p>port包含串口名称与编号，由于注册表中的串口名称排列并非安装串口号顺序排列而是随即排列的，便于界面中顺序列出串口号，故分别保存便于判断。cnt返回当前计算机中包含的串口数量。</p>
<p><span style="color: #ff0000;"><strong>注：由于在串口号大于8之后，不能直接用COM10来CreateFile，而要用<a>\\\\.\\COM10</a>的形式，而在COM8一下采用<a>\\\\.\\COM1</a>来CreateFile也是可以的。<br />
在Vista下用此程序来读取串口号失败，其实并没有失败而是在Vista下访问注册表需要管理员权限。解决办法单击你的程序，右键属性，选择“兼容性”选项卡，勾选最下面的“请以管理员身份运行改程序”。</strong></span></pre>
<h3  class="related_post_title">相关文章</h3><ul class="related_post"><li><a href="http://xinzero.com/change-rs232-com-port.html" title="Windows下如何更改串口号">Windows下如何更改串口号</a></li><li><a href="http://xinzero.com/serialport-communication-debug.html" title="调试串口通信程序">调试串口通信程序</a></li><li><a href="http://xinzero.com/convert-usb-to-rs232-uart-driver-download.html" title="USB转串口驱动打包下载">USB转串口驱动打包下载</a></li><li><a href="http://xinzero.com/windows-virtual-serial-port-tool-vspd.html" title="串口调试助手_虚拟串口">串口调试助手_虚拟串口</a></li><li><a href="http://xinzero.com/test-rs232-communication-error-code-rate.html" title="串口测试通信软件">串口测试通信软件</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://xinzero.com/registry-serialcomm.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FPGA中的多时钟设计</title>
		<link>http://xinzero.com/multiclock-designs-in-fpga.html</link>
		<comments>http://xinzero.com/multiclock-designs-in-fpga.html#comments</comments>
		<pubDate>Wed, 27 Jan 2010 10:29:17 +0000</pubDate>
		<dc:creator>will</dc:creator>
				<category><![CDATA[学习笔记]]></category>
		<category><![CDATA[FPGA]]></category>

		<guid isPermaLink="false">http://xinzero.com/multiclock-designs-in-fpga.html</guid>
		<description><![CDATA[多种独立时钟在SoC（system-on-chip）设计中已普遍存在。很多SoC设备接有许多接口，这些接口根据标准运用了完全不同的时钟频率。
很多现代的串行接口继承了片上其它接口的异步性；而有些则直接从输入数据流中继承时钟。通过设计主要的SoCs子模块运行独立的时钟解决大片子中的时钟脉冲相位差，已经成为一种趋势。
由于这些原因，做SoC项目的设计人员一定会遇到多时钟和面对设计使用两个独立时钟芯片的逻辑连接问题。每个不同的时钟部分被认为是一个时钟域。在不同时钟上的逻辑接口被称作时钟域交叉或时钟域边界。对穿越时钟域边界的信号的处理是成功设计SoC的关键。
问题1：亚稳定性
设计人员必须考虑的第一个多时钟问题是信号从一个时钟域到另一个时钟域的亚稳定性问题。许多设计人员明白在实际电路中亚稳定性确实是个问题，现代RTL（寄存传输级）设计的抽象概念和静态的时序分析并不能完全屏蔽设计者对根本物理实现的担心。
无论何时一个信号进入一个时钟域的元件，如触发器，无论此时钟域与信号时钟多接近，都存在潜在的亚稳态问题。每当发生这样的情况，触发器立即产生不确定的值，在触发器的值被设置之前它的输出信号将不能使用。
在一个异步时钟边界，接收端时钟用来捕获发送端触发器的每一个信号。因为没有定义时钟与信号间的时间关系，所以它们完全可以同时传输。这样，在接收时钟域存在亚稳定性的问题。
这不是理论的、潜在的。在实际系统运行中，GHz时钟速率芯片的设计错误可以很快表现出亚稳态的效果。这些影响通常包括在时钟域之间丧失关键握手信号，以及失效多比特数据的严重问题，很有可能需要芯片的重新设计。
很多设计师也知道，教科书中通过在每路穿越时钟域边界的信号上使用两级触发器解决亚稳定性问题。即使第一级触发器没有成为亚稳态，也有极高的可能性使信号通过第二级的时间将被确定。这种两级触发器结构被称为同步器，和设计师通常讲的穿越时钟域同步信号。
问题2：复位同步
复位信号不同步是多时钟设计的一个相关问题。设计师有时会忘记，复位信号为受到亚稳定影响，应该加同步器加以保护。一般来说，整个系统可以使用单一信号复位，因此，必须传到所有时钟域的所有时钟元件。
复位信号的有效沿没有必要同步，因为所有的状态元件复位定义为初始值，并且复位信号会保持足够的时钟周期，取出所有的亚稳定状态。
但是，复位停止必须保持同步，这样触发器在复位状态恢复后不会处于亚稳态。在设计中，通过给进入每一个时钟域的复位信号一个独立的同步器来实现。
问题3：毛刺消除跨时钟域
尽管出于实际的目的同步消除了亚稳态，但是它不足以解决其它类型的多时钟设计错误。在多时钟设计中第三类常见错误是允许毛刺从驱动时钟域传播到接收时钟域。
因为一个接收时钟域的触发器可以及时的从驱动时钟域的任意点采样信号，甚至是很窄的毛刺也可能被捕获，并视为一个有效值。由于时钟关系的变化特性，这种毛刺电压不能通过静态时序分析检测。
避免种类问题最常见的方式是，使从驱动时钟域触发器输出的信号直接进入同步器。这有效地定义了一个三个阶段同步器，第一个触发器由驱动时钟驱动，剩余的两级由接收时钟驱动。尽管设计及时钟结构的自动分析更加可靠，但这种方法可以作为设计审查。
问题4：接收时钟域不恰当的保持时间（hold times）
在多时钟设计中第四类问题是，不稳定数据从一个时钟域到另一个没有遵守保持时间。信号从一个快速时钟域到一个慢速时钟域时，在驱动时钟域必须稳定几个时钟周期，保证接收域中的慢速时钟不会完全丢失转换。
如果这个转换丢失，数据将丢失。例如一个信号从33MHz的PCI域到12MHz的USB域，必须保持稳定3个时钟周期，才能保证被接收。
当数据信号在逻辑控制信号的保护下，跨越时钟边界，保持时间（hold times）也是非常重要的。
问题5：跨越式中边界丢失信号间的相关性
在多时钟设计中的最后一类问题是，相关信号在跨越时钟边界后失去相关。这个问题是最不直观的。这将导致非常不确定的行为，如数据丢失，算术结果破坏。
这类不直观的问题在可视化的检查中很难被发现，特别是用RTL电路形式，在设计审查是经常被忽视。必须将严格的设计规则和有效的自动分析用于这类问题。
在广泛的相关信号中，可能产生相关性丢失的几种不同方式，包括：

总线的多数据位
单信号的多次复制
握手信号，如请求与应答信号
明显不相关的信号合并在接收时钟域的同一逻辑中

无论何时一个信号进入亚稳态，可以使用同步器确定它的值，但是在接收时钟域不能保证在信号有效之前的精确周期数。因此，任何一个多位信号，每位有独立的时钟同步，每位在到达接收时钟域时，相对其它位将产生倾斜。
即使亚稳定不发生，任何成对数据位信号在到达相应的同步器之前，通过不同的线路或者电特性使两个信号产生不同的延时，都可能丢失同步。
可能一个同步器采样输入信号，并且在另一个同步器捕获信号变化之前，先捕获信号的变化，这样，两个信号将在一个时钟周期内倾斜，并且不再相关。
两个明显独立的信号来两个分离的时钟域，最终反馈进相同的接收时钟域，这是可能产生丢失相关性。这一模式被称作再收敛。在设计复查中，通过同步原理的手动检查方式很发现。
解决方法：时钟验证（Clock intent verification）
尽管多时钟设计的挑战的确让人沮丧，但是幸运的是以上所有描述的问题，是可以自动分析的。然而不是所有的问题都是完全一致的。可能为了避免可疑逻辑的细节警告，设计人员可以检查逻辑是否正确。时钟验证（CIV）是分析时钟结构，报告错误与警告的一个过程，然后使用详细正式的报告验证这些不能被证明问题。
任何CIV必须解决多时钟设计中五个问题的一个。这一进程始于RTL的结构分析，追查设计中从触发器到其它级元器件的时钟与复位。这一过程可以自动设别：

设计中的所有异步时钟域
穿越时钟域的所有控制和数据信号
任何丢失同步或者不正确同步的跨时钟域信号
任何在输入端有潜在毛刺的同步器
任何信号有扇出倍同步器
任何在接收时钟域再收敛的独立同步信号
任何复位信号没有合理同步的时钟域
任何存在潜在毛刺的门时钟或派生时钟

如果合理实现，这些结构的分析可以很快的在SoC上实现，最少的设计输入要求，尽管在对输入信号做简单的描述，对分析是有好处的。
根据这些信息，分析可以极端正确，以至于虚假的错误和警告将不会报告。设计者将只会看到真正的问题，或者是有关设计的有用反馈信息（例如一系列合理同步的信号）。
尽管很多类型的多时钟设计问题可以通过CIV的结构分析来检测，但还是有部分不能。对于变化的多时钟域信号处理与跨时钟域数据的稳定性验证，需要彻底地分析与正式的验证。
既然正式的验证需要对设计断定，一个CIV解决方案必须能够产生三种类型的断定，来表现信号穿过多时钟域的期望行为：

断定多位数据跨域时钟域时，必须是灰数据（每次仅有一位数据改变）；这是为了避免丢失相关性
断定具有同步器的信号能够保持稳定，持续足够长的时钟周期，以便接收时钟域能够检测，这是为了避免丢失数据
断定没有同步器的信号（比如数据总线），在接收时钟域采样时间内，能够保持稳定，这也是为了避免数据丢失

正式的验证试图证明这些断定在任何假定下都不能违反，或者试图通过举反例来证明断言不能违反。
无论何时一个证据被发现，设计者将信心大增，因为他们知道没有可能特定时钟跨越错误将会发生。无论何时一个范例被发现，正式验证已经发现了一个实际的bug，如果不解决，将导致芯片不能工作。正式的工具必须能够提供足够的信息让设计者解决问题，然后重新运行观察是否能够找到证据，去除心中久留的顾虑。
尽管正式验证是一个彻底的技术，但是在复杂的SoC设计中，并不是所有的断定都能够被证明的。出于这个原因，如果CIV方法能够产生符合仿真形式的断定，将是有价值的。如果无法找到证据，但是断定在整个成百万甚至上十亿个时钟周期内运行都不产生冲突，那么，设计师仍然可以获得一项多时钟设计正确性推断的重要措施。
相关文章QuartusII.sof文件转换为.jic文件的几种方法]]></description>
			<content:encoded><![CDATA[<p>多种独立时钟在SoC（system-on-chip）设计中已普遍存在。很多SoC设备接有许多接口，这些接口根据标准运用了完全不同的时钟频率。</p>
<p>很多现代的串行接口继承了片上其它接口的异步性；而有些则直接从输入数据流中继承时钟。通过设计主要的SoCs子模块运行独立的时钟解决大片子中的时钟脉冲相位差，已经成为一种趋势。</p>
<p>由于这些原因，做SoC项目的设计人员一定会遇到多时钟和面对设计使用两个独立时钟芯片的逻辑连接问题。每个不同的时钟部分被认为是一个时钟域。在不同时钟上的逻辑接口被称作时钟域交叉或时钟域边界。对穿越时钟域边界的信号的处理是成功设计SoC的关键。</p>
<p>问题1：亚稳定性<br />
设计人员必须考虑的第一个多时钟问题是信号从一个时钟域到另一个时钟域的亚稳定性问题。许多设计人员明白在实际电路中亚稳定性确实是个问题，现代RTL（寄存传输级）设计的抽象概念和静态的时序分析并不能完全屏蔽设计者对根本物理实现的担心。</p>
<p>无论何时一个信号进入一个时钟域的元件，如触发器，无论此时钟域与信号时钟多接近，都存在潜在的亚稳态问题。每当发生这样的情况，触发器立即产生不确定的值，在触发器的值被设置之前它的输出信号将不能使用。</p>
<p>在一个异步时钟边界，接收端时钟用来捕获发送端触发器的每一个信号。因为没有定义时钟与信号间的时间关系，所以它们完全可以同时传输。这样，在接收时钟域存在亚稳定性的问题。</p>
<p>这不是理论的、潜在的。在实际系统运行中，GHz时钟速率芯片的设计错误可以很快表现出亚稳态的效果。这些影响通常包括在时钟域之间丧失关键握手信号，以及失效多比特数据的严重问题，很有可能需要芯片的重新设计。</p>
<p>很多设计师也知道，教科书中通过在每路穿越时钟域边界的信号上使用两级触发器解决亚稳定性问题。即使第一级触发器没有成为亚稳态，也有极高的可能性使信号通过第二级的时间将被确定。这种两级触发器结构被称为同步器，和设计师通常讲的穿越时钟域同步信号。</p>
<p>问题2：复位同步<br />
复位信号不同步是多时钟设计的一个相关问题。设计师有时会忘记，复位信号为受到亚稳定影响，应该加同步器加以保护。一般来说，整个系统可以使用单一信号复位，因此，必须传到所有时钟域的所有时钟元件。</p>
<p>复位信号的有效沿没有必要同步，因为所有的状态元件复位定义为初始值，并且复位信号会保持足够的时钟周期，取出所有的亚稳定状态。</p>
<p>但是，复位停止必须保持同步，这样触发器在复位状态恢复后不会处于亚稳态。在设计中，通过给进入每一个时钟域的复位信号一个独立的同步器来实现。</p>
<p>问题3：毛刺消除跨时钟域<br />
尽管出于实际的目的同步消除了亚稳态，但是它不足以解决其它类型的多时钟设计错误。在多时钟设计中第三类常见错误是允许毛刺从驱动时钟域传播到接收时钟域。</p>
<p>因为一个接收时钟域的触发器可以及时的从驱动时钟域的任意点采样信号，甚至是很窄的毛刺也可能被捕获，并视为一个有效值。由于时钟关系的变化特性，这种毛刺电压不能通过静态时序分析检测。</p>
<p>避免种类问题最常见的方式是，使从驱动时钟域触发器输出的信号直接进入同步器。这有效地定义了一个三个阶段同步器，第一个触发器由驱动时钟驱动，剩余的两级由接收时钟驱动。尽管设计及时钟结构的自动分析更加可靠，但这种方法可以作为设计审查。</p>
<p>问题4：接收时钟域不恰当的保持时间（hold times）<br />
在多时钟设计中第四类问题是，不稳定数据从一个时钟域到另一个没有遵守保持时间。信号从一个快速时钟域到一个慢速时钟域时，在驱动时钟域必须稳定几个时钟周期，保证接收域中的慢速时钟不会完全丢失转换。</p>
<p>如果这个转换丢失，数据将丢失。例如一个信号从33MHz的PCI域到12MHz的USB域，必须保持稳定3个时钟周期，才能保证被接收。</p>
<p>当数据信号在逻辑控制信号的保护下，跨越时钟边界，保持时间（hold times）也是非常重要的。</p>
<p>问题5：跨越式中边界丢失信号间的相关性<br />
在多时钟设计中的最后一类问题是，相关信号在跨越时钟边界后失去相关。这个问题是最不直观的。这将导致非常不确定的行为，如数据丢失，算术结果破坏。</p>
<p>这类不直观的问题在可视化的检查中很难被发现，特别是用RTL电路形式，在设计审查是经常被忽视。必须将严格的设计规则和有效的自动分析用于这类问题。</p>
<p>在广泛的相关信号中，可能产生相关性丢失的几种不同方式，包括：</p>
<ul>
<li>总线的多数据位</li>
<li>单信号的多次复制</li>
<li>握手信号，如请求与应答信号</li>
<li>明显不相关的信号合并在接收时钟域的同一逻辑中</li>
</ul>
<p>无论何时一个信号进入亚稳态，可以使用同步器确定它的值，但是在接收时钟域不能保证在信号有效之前的精确周期数。因此，任何一个多位信号，每位有独立的时钟同步，每位在到达接收时钟域时，相对其它位将产生倾斜。</p>
<p>即使亚稳定不发生，任何成对数据位信号在到达相应的同步器之前，通过不同的线路或者电特性使两个信号产生不同的延时，都可能丢失同步。</p>
<p>可能一个同步器采样输入信号，并且在另一个同步器捕获信号变化之前，先捕获信号的变化，这样，两个信号将在一个时钟周期内倾斜，并且不再相关。</p>
<p>两个明显独立的信号来两个分离的时钟域，最终反馈进相同的接收时钟域，这是可能产生丢失相关性。这一模式被称作再收敛。在设计复查中，通过同步原理的手动检查方式很发现。</p>
<p>解决方法：时钟验证（Clock intent verification）</p>
<p>尽管多时钟设计的挑战的确让人沮丧，但是幸运的是以上所有描述的问题，是可以自动分析的。然而不是所有的问题都是完全一致的。可能为了避免可疑逻辑的细节警告，设计人员可以检查逻辑是否正确。时钟验证（CIV）是分析时钟结构，报告错误与警告的一个过程，然后使用详细正式的报告验证这些不能被证明问题。</p>
<p>任何CIV必须解决多时钟设计中五个问题的一个。这一进程始于RTL的结构分析，追查设计中从触发器到其它级元器件的时钟与复位。这一过程可以自动设别：</p>
<ul>
<li>设计中的所有异步时钟域</li>
<li>穿越时钟域的所有控制和数据信号</li>
<li>任何丢失同步或者不正确同步的跨时钟域信号</li>
<li>任何在输入端有潜在毛刺的同步器</li>
<li>任何信号有扇出倍同步器</li>
<li>任何在接收时钟域再收敛的独立同步信号</li>
<li>任何复位信号没有合理同步的时钟域</li>
<li>任何存在潜在毛刺的门时钟或派生时钟</li>
</ul>
<p>如果合理实现，这些结构的分析可以很快的在SoC上实现，最少的设计输入要求，尽管在对输入信号做简单的描述，对分析是有好处的。</p>
<p>根据这些信息，分析可以极端正确，以至于虚假的错误和警告将不会报告。设计者将只会看到真正的问题，或者是有关设计的有用反馈信息（例如一系列合理同步的信号）。</p>
<p>尽管很多类型的多时钟设计问题可以通过CIV的结构分析来检测，但还是有部分不能。对于变化的多时钟域信号处理与跨时钟域数据的稳定性验证，需要彻底地分析与正式的验证。</p>
<p>既然正式的验证需要对设计断定，一个CIV解决方案必须能够产生三种类型的断定，来表现信号穿过多时钟域的期望行为：</p>
<ul>
<li>断定多位数据跨域时钟域时，必须是灰数据（每次仅有一位数据改变）；这是为了避免丢失相关性</li>
<li>断定具有同步器的信号能够保持稳定，持续足够长的时钟周期，以便接收时钟域能够检测，这是为了避免丢失数据</li>
<li>断定没有同步器的信号（比如数据总线），在接收时钟域采样时间内，能够保持稳定，这也是为了避免数据丢失</li>
</ul>
<p>正式的验证试图证明这些断定在任何假定下都不能违反，或者试图通过举反例来证明断言不能违反。</p>
<p>无论何时一个证据被发现，设计者将信心大增，因为他们知道没有可能特定时钟跨越错误将会发生。无论何时一个范例被发现，正式验证已经发现了一个实际的bug，如果不解决，将导致芯片不能工作。正式的工具必须能够提供足够的信息让设计者解决问题，然后重新运行观察是否能够找到证据，去除心中久留的顾虑。</p>
<p>尽管正式验证是一个彻底的技术，但是在复杂的SoC设计中，并不是所有的断定都能够被证明的。出于这个原因，如果CIV方法能够产生符合仿真形式的断定，将是有价值的。如果无法找到证据，但是断定在整个成百万甚至上十亿个时钟周期内运行都不产生冲突，那么，设计师仍然可以获得一项多时钟设计正确性推断的重要措施。</p>
<h3  class="related_post_title">相关文章</h3><ul class="related_post"><li><a href="http://xinzero.com/quartus-tansfer-sof-file-to-jic-file.html" title="QuartusII.sof文件转换为.jic文件的几种方法">QuartusII.sof文件转换为.jic文件的几种方法</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://xinzero.com/multiclock-designs-in-fpga.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

