存档

2007年3月 的存档

选择VHDL还是verilog HDL?

2007年3月22日

硬件描述语言HDL(Hardware Describe Language)

HDL概述

随着EDA技术的发展,使用硬件语言设计PLD/FPGA成为一种趋势。目前最主要的硬件描述语言是VHDL和Verilog HDL。 VHDL发展的较早,语法严格,而Verilog HDL是在C语言的基础上发展起来的一种硬件描述语言,语法较自由。 VHDL和Verilog HDL两者相比,VHDL的书写规则比Verilog烦琐一些,但verilog自由的语法也容易让少数初学者出错。国外电子专业很多会在本科阶段教授VHDL,在研究生阶段教授verilog。从国内来看,VHDL的参考书很多,便于查找资料,而Verilog HDL的参考书相对较少,这给学习Verilog HDL带来一些困难。从EDA技术的发展上看,已出现用于CPLD/FPGA设计的硬件C语言编译软件,虽然还不成熟,应用极少,但它有可能会成为继VHDL和Verilog 之后,设计大规模CPLD/FPGA的又一种手段。

选择VHDL还是verilog HDL?

这是一个初学者最常见的问题。其实两种语言的差别并不大,他们的描述能力也是类似的。掌握其中一种语言以后,可以通过短期的学习,较快的学会另一种语言。选择何种语言主要还是看周围人群的使用习惯,这样可以方便日后的学习交流。当然,如果您是集成电路(ASIC)设计人员,则必须首先掌握verilog,因为在IC设计领域,90%以上的公司都是采用verilog进行IC设计。对于PLD/FPGA设计者而言,两种语言可以自由选择。

学习HDL的几点重要提示

1.了解HDL的可综合性问题:

HDL 有两种用途:系统仿真和硬件实现。 如果程序只用于仿真,那么几乎所有的语法和编程方法都可以使用。但如果我们的程序是用于硬件实现(例如:用于FPGA设计),那么我们就必须保证程序“可综合”(程序的功能可以用硬件电路实现)。不可综合的HDL语句在软件综合时将被忽略或者报错。我们应当牢记一点:“所有的HDL描述都可以用于仿真,但不是所有的HDL描述都能用硬件实现。”

2. 用硬件电路设计思想来编写HDL:

学好HDL的关键是充分理解HDL语句和硬件电路的关系。 编写HDL,就是在描述一个电路,我们写完一段程序以后,应当对生成的电路有一些大体上的了解, 而不能用纯软件的设计思路来编写硬件描述语言。 要做到这一点,需要我们多实践,多思考,多总结。

3.语法掌握贵在精,不在多

30%的基本HDL语句就可以完成95%以上的电路设计,很多生僻的语句并不能被所有的综合软件所支持,在程序移植或者更换软件平台时,容易产生兼容性问题,也不利于其他人阅读和修改。建议多用心钻研常用语句,理解这些语句的硬件含义,这比多掌握几个新语法要有用的多。

HDL与原理图输入法的关系

HDL和传统的原理图输入方法的关系就好比是高级语言和汇编语言的关系。HDL的可移植性好,使用方便,但效率不如原理图;原理图输入的可控性好,效率高,比较直观,但设计大规模CPLD/FPGA时显得很烦琐,移植性差。在真正的PLD/FPGA设计中,通常建议采用原理图和HDL结合的方法来设计,适合用原理图的地方就用原理图,适合用HDL的地方就用HDL,并没有强制的规定。在最短的时间内,用自己最熟悉的工具设计出高效,稳定,符合设计要求的电路才是我们的最终目的。

HDL开发流程

用VHDL/VerilogHD语言开发PLD/FPGA的完整流程为:

1.文本编辑:用任何文本编辑器都可以进行,也可以用专用的HDL编辑环境。通常VHDL文件保存为.vhd文件,Verilog文件保存为.v文件

2.功能仿真:将文件调入HDL仿真软件进行功能仿真,检查逻辑功能是否正确(也叫前仿真,对简单的设计可以跳过这一步,只在布线完成以后,进行时序仿真)

3.逻辑综合:将源文件调入逻辑综合软件进行综合,即把语言综合成最简的布尔表达式和信号的连接关系。逻辑综合软件会生成.edf(edif)的EDA工业标准文件。

4.布局布线:将.edf文件调入PLD厂家提供的软件中进行布线,即把设计好的逻辑安放到PLD/FPGA内

5.时序仿真:需要利用在布局布线中获得的精确参数,用仿真软件验证电路的时序。(也叫后仿真)

6.编程下载:确认仿真无误后,将文件下载到芯片中

通常以上过程可以都在PLD/FPGA厂家提供的开发工具(如MAXPLUSII,Foundation,ISE)中完成,但许多集成的PLD开发软件只支持VHDL/Verilog的子集,可能造成少数语法不能编译,如果采用专用HDL工具分开执行,效果会更好,否则这么多出售专用HDL开发工具的公司就没有存在的理由了。

Jacob 技术

FPGA配置方式总结

2007年3月21日

手头上的片子是Altera的EP2C5,就这个片子讲下它的配置方式,对于其他的FPGA芯片,基本类似,或者增加或者减少一些配置方式。

Altera 公司的配置方式主要有Passive Serial(PS),Active Serial(AS),Fast Passive Parallel(FPP),Passive Parallel Synchronous(PPS),Passive Parallel Asynchronous(PPA),Passive Serial Asynchronous(PSA),JTAG等七种配置方式,其中Cyclone支持的配置方式有PS,AS,JTAG三种。

下面分别介绍

PS,被动配置方式,通过加强型配置器件(EPC16,EPC8,EPC4)等配置器件来完成,在PS配置期间,配置数据从外部储存部件,通过DATA0引脚送入FPGA。配置数据在DCLK上升沿锁存,1个时钟周期传送1位数据。

AS,主动串行配置方式,目前只支持Cyclone系列。使用Altera串行配置器件来完成。Cyclone期间处于主动地位,配置期间处于从属地位。配置数据通过DATA0引脚送入FPGA。配置数据被同步在DCLK输入上,1个时钟周期传送1位数据。

JTAG,使用IEEE Std 1149.1联合边界扫描接口引脚,支持JAM STAPL标准,可以使用Altera下载电缆或主控器来完成。

Jacob 技术

开关式1A稳压块LM2575资料

2007年3月15日

我们常用7805稳压块产生5V电压。但7805的一个明显缺点,是当输入电压大于12伏时,发热会很厉害,最大的输入电压也只能到15伏左右。原因在于7805属于线性稳压。即如果输入 12V,就有7V电压是完全的发热浪费掉。

解决这个问题的有效方法是改用开关式的电源IC

LM2575系列的主要特性是:

1、有3.3、5、12、15伏,及可以调整输出电压的版本可供选择。比如本文介绍的 LM2575T-5.0 P+ , 就是固定输出5V电压。
2、可调整输出的电压版本输出电压是1.37到37伏 (HV版本可达57V)
3、最大输出电流1A
4、输入电压最高40V (HV版本最高60V)
5、只需要4只外围元件
6、内部振荡频率为52K
7、TTL关闭功能,待机状态极低功耗。
8、使用高可靠的标准电感 (330uH)
9、温度及电流限制保护
10、+版本提供增加的测试功能。

Jacob 技术

今天研究TCP/IP的一些精华部分

2007年3月11日

我搞电子,不搞网络,但是这玩意也得懂,郁闷~

OSI模型各层:
应用层,表示层,会话层,传输层,网络层,数据链路层,物理层

TCP/IP模型各层
应用层:Telnet,FTP,SMTP,SNMP,DNS,POP3,HTTP,NNTP,UUCP
传输层:TCP,UDP,分段加传输协议报头
网际层:IP(ARP,ICMP,IGMP),加IP报头
网络接口层:定义主机如何连接网络,加物理网络报头,和校验和

目的结点受到数据包后,反向处理

===================

Internet寻址

IPv4
32位地址段

A类001.hhh.hhh.hhh–126.hhh.hhh.hhh
B类128.001.hhh.hhh–191.254.hhh.hhh
C类192.000.001.hhh–223.255.254.hhh
D类224.000.000.000–239.255.255.255
E类240.xxx.yyy.zzz–247.xxx.yyy.zzz

[color=#FF0000]注意:这种分类体系已经有历史了,现在的IP地址是没有级别的。这意味着一个组织的IP地址的确定是基于一个IP地址和一个网络掩码。网络掩码确定了地址的网络部分。[/color]

ip地址中定义的主机部分不能全1,全1代表网段内的所有主机

ip地址中定义网络部分不能全0,全0代表这个网络

127段指定用于回送测试功能。

专业或预留地址
10.0.0.0–10.255.255.255
172.16.0.0–172.31.255.255
192.168.0.0–192.168.255.255

Jacob 技术

74LS373和74LS573

2007年3月7日

74LS573与74LS373–8数据锁存器

引入几个概念:
1. 真值表

参见74LS373的PDF的第2页:
Dn LE OE On
H H L H
L H L L
X L L Qo
X X H Z

这个就是真值表,表示这个芯片在输入和其它的情况下的输出情况。
每个芯片的数据手册(datasheet)中都有真值表。
布尔逻辑比较简单,在此不赘述;

2. 高阻态

就是输出既不是高电平,也不是低电平,而是高阻抗的状态;在这种状态下,可以多个芯片并联输出;但是,这些芯片中只能有一个处于非高阻态状态,否则会将芯片烧毁;高阻态的概念在RS232和RS422通讯中还可以用到。

3. 数据锁存

当输入的数据消失时,在芯片的输出端,数据仍然保持;这个概念在并行数据扩展中经常使用到。

4. 数据缓冲

加强驱动能力。74LS244/74LS245/74LS373/74LS573都具备数据缓冲的能力。

OE:output_enable,输出使能;
LE:latch_enable,数据锁存使能,latch是锁存的意思;
Dn:第n路输入数据;
On:第n路输出数据;

再看这个真值表,意思如下:
第四行:当OE=1是,无论Dn、LE为何,输出端为高阻态;
第三行:当OE=0、LE=0时,输出端保持不变;
第二行第一行:当OE=0、LE=1时,输出端数据等于输入端数据;
结合下面的波形图,在实际应用的时候是这样做的:

a. OE=0;
b. 先将数据从单片机的口线上输出到Dn;
c. 再将LE从0->1->0
d. 这时,你所需要输出的数据就锁存在On上了,输入的数据在变化也影响不到输出的数据了;实际上,单片机现在在忙着干别的事情,串行通信、扫描键盘……单片机的资源有限啊。
在单片机按照RAM方式进行并行数据的扩展时,使用movx @dptr, A这条指令时,这些时序是由单片机来实现的。后面的表格中还有需要时间的参数,你不需要去管它,因为这些参数都是几十ns级别的,对于单片机在12M下的每个指令周期最小是1us的情况下,完全可以实现;如果是你自己来实现这个逻辑,类似的指令如下:

mov P0,A ;将数据输出到并行数据端口
clr LE
setb LE
clr LE ;上面三条指令完成LE的波形从0->1->0的变化

74ls573跟74LS373逻辑上完全一样,只不过是管脚定义不一样,数据输入和输出端各在一侧,PCB容易走线;所以大家都喜欢使用这个芯片。

Jacob 技术

关于ro(rw)的问答

2007年3月4日

2007-03-4,23:04:47
请再解释一个关于ADS中ro/rw base的疑惑(已查阅资料)!

首先说一下,我认为我还是看了不少的资料,然后再来问这个问题的,看起来下面我写的很多,其实我只是想把问题描述清楚一点,我认为我已经写的比较详细了,所以应该不会耽误各位大侠多少时间,所以希望能耐心看完,谢谢 !

我的CPU是4510,我在各种资料上都看过相关的解释:
-ro-base address(即设定Image$$RO$$Base--我的理解)
这个选项将包含有RO(Read-Only属性)输出段的加载地址和运行地址设置为address,
该地址必须是字对齐的,如果没有指定这个选项,则默认的RO基地址值为0×8000。
-rw-base address
这个选项设置包含RW(Read/Write属性)输出段的域的运行时地址,该地址必须是字对
齐的。

Image$$RO$$Base is the address of the read-only execution region (usually
contains code and read-only data).--ro运行时地址

Image$$RW$$Base is the address of the read-write execution region (usually
contains data).--rw运行时地址

所以大致意思,我是知道的,不过在还是在有几个问题想不明白:

问题1、就是这个设定的Image$$RO$$Base与我们复位时CPU读取第一条指令的 0×0 地址有什么关系?这个“Image$$RO$$Base”到底又设定了那些源代码的运行起始地址?比如在一个Bootloader中,往往包含同时包含汇编代码和C语言代码两部分,这个“Image$$RO$$Base”只设定了C语言中RO段的运行地址 ?(拷贝RO RW段代码到Image$$RO$$Base,Image$$RW$$Base标识的位置是我的bootloader 汇编代码进入C前做的最后一件事)
如果说也设定了汇编中ro部分代码的运行地址,那问题2又怎么解释 ?

问题2、有人说“请注意,将工程编译为烧入Flash的二进制代码时,需要将链接器重新设置,将调试时程序空间定位地址(RO Base地址)改为0×00000000”,但我明明刚刚编译的Bootloader就将ro base设为了0xf00000,现在我已将其烧写入Flash中测试过,Bootloader运行良好,而且在上电时Flash首先被映射到0地址开始的地方,这与设定的0xf00000差的很远,当然在程序将进入C语言前,会remap SDRAM到0~16M空间,并将RO RW段拷贝到Image$$RO$$Base,Image$$RW$$Base标识的位置,问题是这个拷贝之前我的所有代码(比如SDRAM初始化,remap,堆栈初始化等)都运行的很正常,这又怎么解释呢?
这样一来我到有个奇怪的想法就是,如果我的程序没有C语言代码,岂不是就可以不用管这个ro base的设置?因为从一开机到拷贝ro/rw段前,我所有的汇编代码执行良好。

问题3、我的vector.S中复位入口“ResetEntry”的部分代码如下,用AXD载入ADS编译的这个.bin文件的时候可以看到,这个 “ResetEntry”标号开始的代码被编译到了.bin文件的最前面,因为我在链接设置里面把reset section放在了img的最前面。我有点不明白就是这个“ResetEntry”标号代表着的一个地址与Image$$RO$$Base又有什么关系?与复位时CPU读取第一条指令的 0×0 地址又有什么关系?因为我的Bootloader在拷贝ro段代码时用到了这个标号,同时我的Bootloader代码也并不是真正放在Flash的起始部分(即开机的0地址处),只是在0地址处放了一条跳转到Flash的高端,再执行哪里存放的Bootloader代码。

AREA reset, CODE, READONLY
ENTRY
;复位和上电启动的入口
ResetEntry
b SYS_RST_HANDLER
b UDF_INS_HANDLER
…………………………………..

4、我在AXD调试程序时还发现,调试过程中我可以把ADS生成的.bin文件载入SDRAM中任何位置,然后修改pc值执行之,不论你的 Image$$RO$$Base,Image$$ROW$$Base设定在什么地方,当然我的这个调试的程序肯定没有对ro/rw段做任何的拷贝操作。这让我更对RW段运行时地址和Image$$ROW$$Base的关系感到疑惑,因为rw段中不是保存有程序需要的变量或数据么?Image$$ROW$$Base设定了rw段的运行地址,那岂不是也就设定了运行时变量或数据在内存中的存在位置?那我用AXD加载的这个程序又在哪里获得的程序运行需要的变量和数据呢 ?

上面的问题其实一直就困扰了我好久,不过因为项目方面比较急,所以也就一直放在哪里没有对其深究,现在稍微有点空,才放到网上来,请各位解惑,非常感谢 !
我的表达能力也不怎么好,上面的问题也许有点罗嗦,如果还有什么没有说清楚的也希望能提出来,3KS ag !

********************************************************************************************

四个问题其实就是一个,即链接器到底指定了什么东西。简单地说,linker把对函数的调用转成向某一地址的跳转,把对变量的读写转成对某一地址的访问。

但是,一段正在执行的代码本身,从本质上来说,并不需要知道自己运行在什么地址。只要PC指针有一个初值(比如0×0),然后每次加4之后,能取到下一条指令就行了。与此相关的另一个概念就是PIC(Position Independent Code,与位置无关的代码)。

只有当代码中调用了函数,向某个symbol跳转或访问了变量,才需要知道真实的地址。所以Image$$RO$$Base是否起作用,并不取决于C代码和汇编代码的区别,而在于PIC与PDC的区别。
********************************************************************************************

版主和TALISKER已经回答了楼主的问题。我也说说自己的看法,希望对你有帮助。
1. Image$$RO$$Base is the address of the read-only execution region
你仔细琢磨RO BASE的意思,RO BASE指定的只是RO段的起始地址,注意:并没
有说始第一条指令的地址。所以,如果你的程序包括多个段的时候,有可能别
的段放到了RO BASE指定的地址上,而并不是期望执行的第一条指令。在调试
的时候,这不会造成什么问题,因为DEBUGGER会把PC指向程序的第一条指令。
如果你把程序烧写到FLASH里面后,这可能会造成问题,因为CPU在RESET后只
从地址0×0处开始取指令。所以,如果你写一个程序,期望程序从地址0×0开始
执行,要满足两个条件:1-RO BASE要为0×0,2-告诉linker,把包括你希望
执行的第一天指令SECTION链接到RO段的最前面。

2. 对于你说到的第二个问题,为什么你把RO BASE设置为0xF0000000还能从地址
0×0开始执行?这是因为4510的地址绕卷问题造成的,其实地址0xF0000000就是
地址0×0,不信你可以自己测试一下,从地址0xF00000读出来的指令和地址0×0
的指令一样。所以,你的第二个问题不是问题,这和RO BASE没什么关系。

3. 前面说过了,一个程序包括了RO段,但程序可能包括了很多个SECTION,在编译
的时候,各个section的RO段都是被链接到你指定的RO BASE开始的地方的,这
就涉及到另外一个问题:在RO段里面,你怎么安排各个sedtion在RO段的顺序?
如果你写的是BOOTLOADER的话,你必须要把包括你要执行的第一条指令的段放
在最前面,这样才能保证板子上电后能正常运行。

4. 我不知道你的程序里面是否有RW段?程序分为RO段和RW段,但并不是每个程序
都一定有RW段,如果你的程序里面没有全局变量等,那编译后,肯定是没有RW
段的,在这种情况下,你不进行RW段的拷贝,程序也能正常运行的。OK,在来
看看你的问题,你说在编译生成bin文件后,在bin文件里如何定位RW段?答案
是:单单依赖bin文件是无法定位RW段的。所以 - 如果你的程序有RW段的话,
你必须在自己程序里面处理RW段的拷贝。
********************************************************************************************

首先谢谢各位兄弟、大哥的回复,非常感谢 !

其次针对各位的回复,再综合我所知道的别人给的解释,我想再谈一下我自己现在的想法:
to Talisker:我不知道你想设定ro base在0×04的意思是什么?

to Twentyone:
针对你的回答1:
“在调试的时候,这不会造成什么问题,因为DEBUGGER会把PC指向程序的第一条指令。”---我调试的时候采用的是ADW载入ADS编译的二进制bin文件的方式,所以pc值或bin文件载入地址都是由我指定的,但都与ro base设定的值不同。
针对你的回答2:“对于你说到的第二个问题,为什么你把RO BASE设置为0xF0000000还能从地址0×0开始执行?这是因为4510的地址绕卷问题造成的,其实地址0xF0000000就是地址 0×0”---你说的没错,0xF0000000地址最终会对应到0地址,不过我是将ro base设在了0xf00000,即15M内存的地方,而调试使用的obey xxx.ini命令将0~16M的内存都分配给了SDRAM,所以将ro base 设在0xf00000,还没有到地址卷绕的地方。
针对你的回答4:
我调试的程序首先是比较简单,那是不错,不过变量肯定是有的,不论全局、局部变量,都有 !是一个同时包含串口和IO口简单测试的程序。

另外有人回答说:

解答问题1&2:这说明你的bootloader是基于相对地址的,也就是说与地址无关,而这也是对bootloader的一个基本要求。一般的bootloader都设计成地址无关的。

解答问题4:这说明你的程序比较小,或者函数调用不复杂,堆栈操作不频繁等。也就是说,不按照你的设置的ro和rw基址调入程序,有可能数据空间不够,或者代码和数据重叠,程序执行就可能出错。

------我看这个回答好像是对的,不知道各位对此有什么理解或看法 ?

********************************************************************************************
Twentyone:

文后附的是一个测试程序,这个程序可以验证RW的影响。
测试的之前,你把你的板子的MEMORY给配置好,把SDRAM配置到地址0X0开始的地方。

测试1:程序的RO_BASE = 0×0,RW_BASE不设置,你用仿真器单步运行程序,然后观察
内存0×800的内容变化,变化顺序应该是0×0 -> 0×1 -> 0×2 … -> 0×9

测试2:程序的R0_BASE不变,还是RO_BASE = 0×0,RW_BASE设置为0×400,单步运行程
序,观察内存0×800的内容变化,看看结果和第一次测试的是否一样

我:

我试过了,也基本上清楚了,按照你的实验设定测试2会看到0×800地址的数据不规则的变化,我又看了一下对应的汇编代码(我是指编译后的汇编代码),发现程序在读取array数组值时,是从rw base开始的地方读取数据的,因此如果一开始没有将rw段放到rw base开始的地方,则程序执行后读取的数据肯定是不对的,这也符合rw base本身的意思,现在我应该说是彻底的清楚了,谢谢 !
我以前的问题是:我在程序中使用变量前首先就先改变了变量的值,因此RW段首先就被我程序先修改了,也就是说虽然我没有搬移RW 段的操作,但是我重新修改了rw base开始的数据的值,对应到你的这个测试程序,也就是说本来我没做搬移RW段的操作,则0×400地址开始的数据(在你这个测试程序中存放的是 array数组的值)是不确定的,但后来程序一开始我就修改了array数组的数据,也即修改了0×400开始的数据,因此RW段虽然我没有搬移操作,但其实也就被我重新设定正确了,然后再读取使用,当然执行起来,当然就没有什么问题了,不过这里有一点:就是我的程序本来就比较小,RW段也很小,所以没有什么问题,但如果程序大一点,RW段太大,我不能够一一重新指定,那程序就会出错了,问题解决,非常感谢 !
不过关于RO段的问题:RO base 设定值与bin程序载入值不同,但程序仍能正确执行的问题 。
我想可能只能用我得代码都是“地址无关”的这个来解释了,对吧 ?
这东西有点绞,不知道我上面的表达清楚没? 呵呵,如果没什么问题,我想就把上面这段话转到电子产品世界去了,然后我那个帖子也就可以方封贴了,呵呵,不过真的非常感谢你的帮助,谢谢 !

Twentyone:

不用客气!

你说的很清楚,你的理解是正确的,关于RO_BASE的问题,如果程序完全运行正确的话
,只能用与地址无关来解释。

如果你想做一个RO_BASE的测试的话,你可以写一个测试程序,在程序里面包括一些绝
对寻址的指令,你就会发现程序运行时用不同的RO_BASE的话,运行会有问题的(可能
不影响结果,但中间肯定是有地方和你期望的不一样的)。

ft,忘了贴代码了,Twentyone大侠的测试程序如下:

init.s:

AREA Init, CODE, READONLY
CODE32
ENTRY
ARM
LDR SP, =0xC00
IMPORT CTEST
B CTEST
END

test.c:

unsigned int array[] = {0×1230,1,2,3,4,5,6,7,8,9};

int CTEST(void)
{
int i;
unsigned int base;
i = 0;
base = 0×800;
for(i = 0; i < 10; i++){
*((unsigned int*)(base)) = array[i];
}
return 0;
}

引用自
http://bbs.edw.com.cn/dispbbs.asp?boardid=20&replyid=249879&id=46592&page=1&skin=0&Star=1

Jacob 技术

S12单片机BDM仿真器莫名损坏

2007年3月2日

学校做小车竞赛用的Freescale的S12系列单片机配了一个BDM调试器。清华的,芯片是MC86HC908JB8,昨天一直用的好好的,今天插电脑上就没反应了。无法识别,没有提示安装驱动。服了清华的这东西。。。。

还好该调试的程序都调试出来了,PWM和ADC基本都正常工作。

Jacob 技术