EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 FPGA技术江湖 于 2023-3-2 19:56 编辑 ' q0 V% b u' N- g6 S' Z3 w2 y) q6 W
3 d' I8 g2 W! M; @' M
- o p m2 L0 d& ^
' N0 C: u+ T3 X4 a
本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的“傻瓜式”讲解,让电子、信息、通信类专业学生、初入职场小白及打算进阶提升的职业开发者都可以有系统性学习的机会。
3 i8 n- F7 ^- C$ @! `: n' ~: m
0 n- |3 |6 i, F# c' C! P5 l/ U8 j6 W+ |7 D( E 5 o, U, c) T, i7 \( l/ S2 _) v
f0 w K& r+ E B4 ?0 I9 H 系统性的掌握技术开发以及相关要求,对个人就业以及职业发展都有着潜在的帮助,希望对大家有所帮助。后续会陆续更新 Xilinx 的 Vivado、ISE 及相关操作软件的开发的相关内容,学习FPGA设计方法及设计思想的同时,实操结合各类操作软件,会让你在技术学习道路上无比的顺畅,告别技术学习小BUG卡破脑壳,告别目前忽悠性的培训诱导,真正的去学习去实战应用,这种快乐试试你就会懂的。话不多说,上货。 2 q2 x: k0 |$ g
$ N3 [; q: U- u
6 ]/ \1 `7 o) H- h. z
. ?3 E/ c. P# c, S ~) }3 V% B" G- ]8 n0 ?- O6 F: o
% ^" Y. a$ W& R% o- a) a, U. J3 I
8 B5 J8 j$ B4 l- J
7 r) d+ P4 A j- G3 y- _: O5 l
; g# _* o1 E/ q0 v- h
7 s3 y B9 q1 z1 b8 Y9 w
) {& w$ l( O/ F5 Y* Q8 r
在嵌入式设计中,是经常需要和最底层打交道。无论是利用mcu实现功能还是利用电路直接实现功能,都需要对数字极其敏感。 # i& N' S( p! U4 e |) G6 P
" k; V8 R8 L7 M2 l3 X
& X" a/ j& ^) C
" n1 ^3 B @* s! I( r1 Z3 E
在嵌入式中,所有的数值都是按照二进制码进行存储的。二进制与十进制的计算规则为: & J$ n0 h1 y- i) _4 x5 {
; y' T+ j) h$ E. p* L" V( U @
6 W+ F4 Y0 A- X0 L
4 S5 u/ N6 B5 i+ s, R1 F4 c5 h; d& p: Y0 A8 @ y3 X% J
4 Z, Q& X+ e1 z: a. f5 g. ?0 F $ G% p% {/ ]* b4 i. N5 ^) w9 m
0 e0 z/ B V) p- F& u) q 二进制的101.01,等于十进制的5.25。
6 f" o; d6 B9 B: e8 [9 U5 g
2 N7 s2 t* \' P & d- P+ @) m# l' V6 F
) G! I) u U- q# Q& s1 q 在不考虑小数时,我们在设计中,用的到所有的变量都要基于一个位宽,如果位宽不够时,就会出错。例如:十进制的100,转换为二进制为1100100,需要用到7位的位宽。当用低于7位的位宽去接收十进制的100时,就会得到错误的结果。
( u2 k- M/ L5 D) z2 R2 _, R4 b
& | f5 {8 S9 h- ]2 w- s
) L8 a2 `# [& G& P v$ G8 [+ a4 J3 ^' I+ B0 f0 q! f/ D2 k2 _- w
在C51设计中,比较常用的两个整数变量类型为:char和int。这两种类型可以拓展为四种类型:signed char、unsigned char 、signed int 和unsigned int。signed可以省略不写。
. W! G5 B/ I: ?; j; Y
6 ?- @7 x z5 C$ w6 @ g! \8 G7 e* ]8 A; s3 d
2 @4 G/ v% P2 @& X' \ 对于char来说,表示为1个字节(位宽为8),经常用来表示一个字符。对于数值来说,char表示有符号时,范围为-128至127;char表示无符号时,范围为0至255。所以在使用时,要牢记这个范围,当需要记录的数字超过这个范围时,将会出错。例:char类型的变量被赋值325;此时综合器的综合并不会报错,但是得不到正确的结果。 4 e4 D5 u2 Z7 P; p4 g3 j
% N' V8 I; G1 Q4 A( Q/ q! b+ n
+ \$ j$ z; K6 @ s1 [1 k0 P- y7 A2 s9 c) B0 b( u
对于int来说,表示为2个字节(位宽为16)。对于数值来说,int表示有符号时,范围为-32768至32767;int表示无符号时,范围为0至65535。所以在使用时,要牢记这个范围,当需要记录的数字超过这个范围时,将会出错。 2 b1 [3 |" Z; l2 r* g5 h( u1 b
7 h3 K* l! `: y, u/ s
]. b# L t7 _+ W+ A 在使用时,如果char可以时,尽量不要使用int,节省一部分资源。
; r; U8 C% O8 v& g
: i4 n8 W) @: G! ~0 |9 {! X( e
2 p. V2 M ]% o( W4 n6 `/ I; O) j
% B1 ?2 J6 ]/ H0 N+ J
在C51设计时,char和int是固定的,也没有其他的宽度的类型供给使用。 ) `' F# x% z5 z
b* ?. s; I2 T- I1 ?! E2 t
# L: o: Q' y0 g5 q' m0 q 在FPGA开发时,位宽是自己随意设置的。设置位宽不够时,将会计数出错;设置位宽过大时,将会浪费一部分位宽。
! Y2 j: v4 e! U" T! K$ N2 G* w
+ K. t. A! Z! `8 d P) s
" O( T, t1 z9 M, s! f
在50MHz的时钟驱动下,记录一秒钟。需要记录50_000_000个时钟周期,此时记录时无符号的记录,那么需要计数器的位宽为多少位才可以呢? ) q u; P! [2 ~2 p+ {
, G1 C/ }) B% b+ O1 V( v% `( ~$ l
" t+ ^5 _2 O$ R 可以利用PC自带的计算器,设置为程序员型,调成十进制将50_000_000输入进去,然后转换为二进制,查一下有多少位。 ; _( G3 w) d3 ~, f; j
+ m2 Q; ?9 u- |! [0 i
) X' E8 J- [8 p9 w1 P ) X6 d7 |* h: x/ a |" p4 G$ x' D
+ b/ v: U* M& [% V
) l1 {0 q( p/ k. g( E; H
) X5 ? H0 Q8 t |
) F8 `4 }- H% y/ i; {7 L
7 F6 V* q; ?& b* T: G v8 m7 W& U4 @9 M+ A% n( M3 J1 P4 f
很明显需要26位。 ! m* g' `) ^) ~4 C# ?% H
0 X M! r$ r2 M; h
5 @( w7 b2 M) C1 h
$ R2 R# j Y) {4 T( }. z 如果每次的计算都需要计算器的话,很多的时候可能不太方便。这里笔者整理出一种“看一眼就知道位宽”的技巧。 ) b: Z* V, t9 N, _% g
" A; V8 {3 T# D L9 ^/ ?3 t
9 L* y X0 z5 ?0 K% ?3 |& V3 R
$ u4 W4 I& r# y2 ^ 首先需要牢记2的0次幂至10次幂的值,这个难度并不大。下面来看一个例子:
* a+ k3 F. U/ H7 ~) u2 l* x+ m8 W ^
: ~" P+ I$ m1 Y9 O% H3 S( X# D8 ]0 c $ h" W. b% G* W5 j! t" r2 `
/ q* z: S+ F2 d7 S9 d- ?+ f$ t 计算147258369的二进制位宽。
* M1 p2 w& }1 b& T; R 1. 分隔为3个1组:147_258_369。 2. 将第一组的数加1,后面的数全部换为0,如果后面组已经是0,第一组不加1。
9 Q- H P. E2 i6 T: p6 q! ^
147258369 < 148_000_000 = 148*1000*1000 < 148*1024*1024
# F6 X, [6 V, i1 ~% ~- h( ]
8 q! B3 R# F+ e% n# p; x/ C
7 H% P+ A& i) i, X6 }" i! K T _ 2的次幂为1024,所以148*1024*1024为148乘以2的20次幂。148正好处于128和256中间,选择256。 3 J1 ^' F: c8 j( Y4 L3 k
9 D. L1 Z5 f6 V: n7 E 最后的数字为256*1024*1024,即最后的数字为2的28次幂,也就是利用28位的二进制就可以表示此数字。 * g* [ [+ ?7 l8 v; }) N
6 b9 M, }9 i) V2 P7 Q8 Y
所以对于50_000_000,后面的六个0为20位,50需要用64表示,所以共需要26位。
9 K1 Z6 S; G( s, O3 G
7 }) e O; ~4 M( }3 R 此方法会有一定的误差,但是误差最多为1个位宽。能够比较方便快捷的计算某个数字的位宽,加快了设计进度。 0 q3 l5 ?! J% {, S/ z. l! r5 V
1 B- f- `6 E! l1 l6 U' Q" U
在计算有符号数时,直接计算其绝对值的位宽,然后将位宽在扩大1位即可。
$ G5 r4 z Y/ z5 G; R3 I; ? ( R. g" Y6 H0 N5 X R
有符号数的表示为最高位为符号位,不表示数值大小,所以计算完绝对值的位宽后,需要加上一个符号位即可。 ' ^% j- R! ]7 F
# C" V9 T/ ?: w% U* w 在上述说明中,主要阐述了整数位宽的确定。对于小数来说,重点关注的不是位宽而是位宽所能达到的精度。 / V) o8 \& i+ A/ w* @
, s, X0 b9 d) W1 z
在数字电路中,所有的数字都是由二进制来表示,对于很多的数字是无法用有限的二进制来进行的,所以此时就需要用一个近似值来表示。 3 H$ x# c j3 h; \& f: V6 s9 c
" q* P0 ~: X( x, S6 N5 y# l 关于小数位宽的确定不做过多介绍,有兴趣的读者可以自行查询相关资料。 / c' q/ t" ?6 @
1 H# u& c- V$ ~6 x" n: m9 J2 Y
|