一 : 百度高级UI设计师:规范、方法、一致性,真有那么重要?
本文来自百度用户体验部高级UI设计师大牙的佳作,此文是她对自身工作的一种思考:一个遵从设计规范,按照所谓的系统设计方法,步步推导而来的解决方案,是否真的就是一个好的设计?你的答案是怎样?不妨一起来看看大牙的吧~
不可否认,被我们经常挂在嘴边的设计规范、方法及一致性对我们日常工作很重要。它可以提升操作一致性、提高工作效率、延续品牌定位……
但是,不知道你们有没有发现,之所以有了这些方法和规范,导致很多设计师习惯性处于舒适区,从而放弃独立思考。每天做着重复性的工作,复用着前辈制定下来的模版,套用着别人的方法论,抱怨着工作没有挑战。
我最近也在思考:一个遵从设计规范,按照所谓的系统设计方法,步步推导而来的解决方案,是否真的就是一个好的设计?
规范,方法,一致性,重要的一面。
当我们刚从事UI设计时,自身对于用户体验设计的积淀还不够厚实的时候,遵循设计规范是最保守但也是最合理的做法,因为这种解决方案更加成熟和通用,也有了一定的用户认知。同时像公司内部的设计规范,有利于版本迭代的开发及设计效率,包括新人入职后更快上手工作,避免出错。
所以了解ios设计规范,安卓设计规范,或者是公司内部的设计规范等等,成为设计师必备的技能…
这里说的方法是指设计工作中的方法论。运用方法论,能够帮助设计师明确如何一步步的进行整个项目,更高效的推导设计,达成目标。从而说服合作的同学,而且看起来非常的有理有据。下面是我们常见到的一些导图例子:
为了减少用户学习成本,不管从视觉还是交互层面我们都要遵循一致性。
包括同一个产品不同终端,要保持视觉统一性,才能加深用户对产品品牌的认知,这些也都没毛病。
下面是咸鱼,顶导航颜色采用黄色,为了各端一致性。
微云各端引导页面,采用线性插画的处理手法,来确保品牌一致。
以上说的都是规范、方法、一致性重要的一方面。
但是,我们会看到更多优秀的创新的设计正在一步步脱离这些条条框框,从而做出让人眼前一亮的设计。所以我在思考在接下来的设计中,需要做的几点来帮助自己成长:
工作的前一两年,研读并遵循着平台设计规范,从而帮助我们在工作中做出不会出错的设计,同时提升工作效率和说服力。但是随着自身经验的累积和成长,需要对此产生警惕,如果我们一直局限在别人制定的规范里,不去思辨,很容易陷入十年如一日的工作状态中,很难做出创新的设计。
同时也可以看出很多优秀的设计作品,陆续跳出规范,不局限于规范制定的像“最大字号多少px”,“导航条多少px”,“上下间距多少px”等等… 而是设计出符合自己产品气质的界面。下面有几个例子:
下面是蜗牛装修APP的设计,可以看出:
像VUE的处理,没有严格遵循平台设计规范所谓的列表的的高度,而是用红的线条区分模块,间距来区分列表的内容,反而更符合产品本身的气质。
下面是大家所熟知的Airbnb,它大胆的体验设计被设计师们追崇模仿,这里想说的是它对底导航和按钮大小的处理,也是跳出规范,更符合功能本身的重要层级。
上面有讲到设计方法论如何帮助到我们的设计,使用过程当中,我们知道每一步应该怎么分解和运用。例如:市场调研、头脑风暴、梳理线上流程、研究了信息架构,并且还通过体验地图分析了行为路径……
但是往往最后的设计方案和前期的调研没有什么关系,而且复用到任何产品设计的前期都适用。所以,我认为这属于自我感动式的设计。感觉自己做了很多,但是真的往深入去问why why why的时候,很多设计师都会被卡住。
因此一定程度上我们要弱化已知的设计方法,少一些套路和形式主义,多一些深度解析的方式做设计。
比如,下面是facebook的总监讲述LIKE的设计方案:
他是这么阐述LIKE的设计方案的:这个设计的目的是优化LIKE的按钮,增强用户的互动意愿,以及提升LIKE的表现力。而他做的第一件事情就是理解什么叫增强互动,什么叫表现力,背后的产品目标是什么?是用户可以更多的表达。然后开始找如何让这个目标具体化。接下来寻找什么是被普通认知和广泛接受的reactions。
它通过各种途径去找用户最常用的表情是什么,最常搜索的表情是什么,最多的短评论是什么。设计师们希望可以从侧面寻找大家在表达过程中喜欢用什么reaction,然后找到他,并通过之前定义号的原则进行筛选,完成设计方案。
所以可以看出,这种解决方式不是方法论的堆砌和强调,无需逐步check的线性设计过程,而是以产品目标为起点,然后紧密围绕目标进行提问回答,这种方式才能让我们深入去思考,给出的解决方案才更有道理,经得起挑战。
在设计工作中,我们考虑着界面与界面的统一,端与端的统一,这样当然没错。但是我发现很多同学,都会过度的陷入所谓的统一,生怕做任何一个东西与统一相违背。
比如产品里面是线性的图标,那么就绝不允许有面状的出现;线性的图标如果是2px,那么全局各端都必须是2x;如果web端功能引导页面是真实照片的,那么别的端必须统一用真实照片等等…
这些问题我也遇到过,但是我发现是自己太局限里面了,其实我们应该考虑的是针对不同终端的使用场景,用户群体,在局部统一的基础上,可以做差异化处理,是没有问题的。包括icon的处理,也可以根据功能的强弱,出现的时机,做差异化处理。而不是固执的坚信只要不统一那就是错的,设计决策并不是非黑即白的。
比如,google drive的引导页面,在移动端用的是矢量插画的处理,在web端更强调的是产品官方形象,用的是真实照片,贴近生活。只是通过logo主色来延续品牌的DNA。
还有印象笔记各端引导页的处理,同样是针对不同的使用场景和用户的习惯,采用不同元素,来特殊处理。
像Web和Mac端,一般较长停留时间,因此会采用一些结合场景的真实图片,诠释功能特色,让用户更全面的了解产品能为他们做什么;而移动端,以碎片化场景为主,因此采用的是简洁插画处理,干净利索,利于get到重点。统一的部分,只是它们的绿色。
所以即便要统一、要一致,也不能特别轴,保持好度很重要。单纯的为了统一而统一,也是一种思维懒惰。
所以,在我们设计生涯的不同阶段,需要关注和帮助我们成长的点也不同。规范、方法、一致性很重要,但是要懂得如何平衡和运用。不要让它们成为你呆在舒适区的理由,学会思辨和推翻自己,才能进步和有所突破。
作者:大牙,百度用户体验部高级UI设计师。微信公众号:大牙的设计笔记。
二 : 我们并不需要更多会写代码的设计师!
编者按:在这个变革速度前所未有的时代,我们会听到各种各样的声音。有人说设计师得懂编程,程序员要懂市场规律,不会写文案的交互设计师不是好产品经理,等等等等。但是在这些叫嚣跨领域强调多技能的人群中,我们依然能听到一些不一样的声音。今天这篇短文来自Gaiam的产品设计总监 Jesse Weaver,作为一个资深的专业产品人,他有着不一样的考量。
越来越多的招聘条件上,明确要求需要懂代码的设计师。有的是需要设计师精通HTML、CSS和JS的,比较奇葩的是要求设计设计师懂JAVA,深入 理解C++的,至于要求设计师精通Android和iOS开发的一看就是想把开发的钱给省下来的鸡贼团队。如果你使用百度和Google搜索“设计师是否 需要懂代码”,搜索结果可能多达几十万条,看来被这个问题困扰的人真的很多,迷茫的设计师真的不少。
坦率的讲,在这个设计与开发愈来愈紧密的时代,我并非完全不同意“设计师懂代码”这件事,但是在“我们需要能写代码的设计师”这件事情上,我觉得大家存在着相当的误解和歪曲。
作为产品设计团队的领导,我同样可以多少写一些代码,前端和后端的都可以,我自然也很明白拥有多技能的重要性。我能画原型,拥有跨学科的背景和能 力,了解各种技能的特性,也拥有调整优化实践的技能。但是,我明白事情的界限在哪里。专业的事情,应该让专业的人来做。我不是开发者,更加不希望我写的代 码被作为基础,被大规模地应用到一个专业程序中去。
说设计师应该去写代码,给人一种感觉:团队中所[www.61k.com]有人都应该全身心参与到产品的开发和生产上来。或者说,设计团队和开发团队应该从某种程度上合而为一,组成某种无缝的全功能多栖超级开发团队。
咱们还是实在点儿的好。设计和开发(不论是前端还是后端),是高度专业化的职业,有着清晰的定位和分工。每一个这样的职业都需要若干年的时间来掌控,想在一个领域中成为专家是无法一蹴而就的。
我们真正需要的是,能真正能做好设计的设计师,能写好代码的开发者,并且设计师和开发者能够无缝地协作。
要实现两者的协作,需要一个关键的因素:移情。移情能力是设身处地理解他人感受的一种能力,这才是关键。
我们需要设计师能够了解代码和开发的流程和原理。这和会写代码是两回事。
我们希望设计师能了解开发了解代码,就像我们希望开发者能了解设计师的工作流程和原理。设计师希望开发者能用设计语言跟他们沟通,希望开发者能了解设计思考和思维过程,而不是让开发者自己打开PS给绿色的界面加一个红色的图标。
真正意义上的相互了解,深入到位的沟通,这样才能让孤立的环节有序地整合起来,在协作中打造伟大的产品。这样协作的关键点在于,了解和分工的程度要把控好,让真正的专家在他的领域自由驰骋,不要让其他人成为阻塞。
当有人说他们需要“能写代码的设计师”的时候,我想他想要的应该是一名“瑞士军刀式的设计师”。他们想要的这个角色功能很全,就像瑞士军刀一样,自 带多种工具,剪刀、牙签、螺丝刀、锉刀、锯一个都不少,干啥都能上。不过电工不会选用瑞士军刀上的螺丝刀,木工也看不上瑞士军刀上的锉刀和锯,裁缝更不会 指望其中内置的剪刀,至于士兵嘛,他们喜欢匕首,军刺,而且也玩得一手好工兵铲,然而工兵铲这种神器通常是不会出现在瑞士军刀上的。
瑞士军刀只是提供了最底层最基础的工具以及相当有限的功能,以至于在很多时候很难真的将其划归到“刀”这个品类中。
专业的人事需要专业的工具。同样,专业的团队需要有专业的团队成员。
我不希望我手底下的设计师,每天刷网站关注最新的跨浏览器CSS样式解决方案,或者到处找JS教程“充电”。同理,我也不希望我手下的开发者在配色理论和配色方案这样的事情上耗费时间。
我希望我的设计师能在移动端界面标注上钻研得更深,在可用性设计上有更好的实践,期待设计师们能深入研究用户习惯,能挖掘未曾被满足的用户需求,让 产品设计和体验更上一层楼,这是设计师的工作。同时我也承认,了解代码是他们工作的一小部分,但是仅仅是一小部分,这一部分工作必须是高效的,并且是基于合作需求而进行适当学习和了解。
如此一来,设计师对代码有所了解,开发者对于设计有所涉猎,那么开发者能够基于用户需求对设计师的构想有所评判,设计师也能够对设计如何实现为产品 深入认识,如果双方在产品原型设计上深入沟通,说不定能拿出更有说服力的方案。但是不论如何,都要规避让设计师“成为开发者”,或者让开发者“成为设计 师”这样的 想法。
融合是存在的,并且有它独到的意义,但是此处并不合适。
如果你希望你的团队发挥它真正的优势,做专业的事情,通过移情效果达成协作,那么你的团队不需要瑞士军刀式的成员。真正能在专业领域深入挖掘的成员——设计师、开发者——才是你需要的人,让他们走到一起,组成你的工具箱。
这才是我们要的。
原文来自:优设
原文地址:medium
优设译者:@陈子木
三 : 异步FIFO设计(易懂+verilog代码)
异步FIFO设计?
2011.6.22?
摘要?
本文采用格雷码设计了一个异步FIFO,经过DC综合的结果如下:?
时钟频率:1.1GHz?
面积:????10744.447um2?
功耗:????7.791mw?
??
目??录?
1.?异步FIFO的设计?................................................................................................................?2?
1.1?异步FIFO简介?..........................................................................................................?2?
1.2?FIFO的参数?................................................................................................................?2?
1.3?FIFO的设计原理?........................................................................................................?2?
1.4?FIFO的设计模块?........................................................................................................?6?
1.5?用modelsim仿真FIFO?...........................................................................................?11?
1.6?用DC对FIFO进行综合?..........................................................................................?13?
2.参考文献?..............................................................................................................................?15??
??
????1??????
1.??异步FIFO的设计??
1.1?异步FIFO简介?
FIFO是英文First?In?First?Out?的缩写,是一种先进先出的数据缓存器,它与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。?
根均FIFO工作的时钟域,可以将FIFO分为同步FIFO和异步FIFO。同步FIFO是指读时钟和写时钟为同一个时钟。在时钟沿来临时同时发生读写操作。异步FIFO是指读写时钟不一致,读写时钟是互相独立的。?
异步FIFO(Asynchronous?FIFO),一般用于不同时钟域之间的数据传输,比如FIFO的一端连接频率较低的AD数据采样信号,另一端与计算机的频率较高的PCI总线相连。另外,对于不同宽度的数据接口也可以用AFIFO,例如单片机为8位数据输出,而DSP可能是16位数据输入,在单片机与DSP连接时就可以使用AFIFO来达到数据匹配的目的。?
由于实际中,异步FIFO比较常见。为了便于描述,在后面的章节中将异步FIFO简称为FIFO.?
1.2?FIFO的参数?FIFO的宽度:??进行一次读写操作的数据的位宽。?
FIFO的深度:??双口存储器中能容纳的数据的总数。?
满标志:??????FIFO已满或将要满时由FIFO的状态电路送出的一个信号,以阻
止FIFO的写操作继续向FIFO中写数据而造成溢出。??
空标志:??????FIFO已空或将要空时由FIFO的状态电路送出的一个信号,以阻
止FIFO的读操作继续从FIFO中读出数据而造成无效数据的读出。??读时钟:??????读操作所遵循的时钟,在每个时钟沿来临时读数据。??写时钟:??????写操作所遵循的时钟,在每个时钟沿来临时写数据。??读指针:??????指向下一个读出地址。读完后自动加1。??
写指针:??????指向下一个要写入的地址的,写完自动加1。??
读写指针其实就是读写memory的地址,只不过这个地址不能任意选择,而是连续的。?
1.3?FIFO的设计原理?
整体的框图如下:?
??
????2??????
图1.1??FIFO的整体电路图?
1.3.1??FIFO的读写指针??
FIFO可以看成是先进新出的缓冲区,它不像普通的存储器那样,有专门的地址信号。它只能根据地址,顺序地读写缓冲区。所以需要有两个读写指针。这里定义如下:?
wptr:??写数据的指针?
rptr:???读数据的指针?
每读/写完一个数据,读/写指针就会加1,指向下一个待读/写的位置。?
1.3.2??同步器的设计??
为了产生空/满标志,需要对2个读/写指针进行比较。由于FIFO的读/写时钟信号,来自2个不同的时钟域,所以先要将这2个指针同步到一个时钟域。这里采用两级D触发器级联来构成同步器。?
1.3.3??格雷码计数器??
采用二进制码对地址指针进行计数时,从一个计数值变到下一个计数值时,可能有多位发生跳变,如从7?8变化时,低位由0111?1000,这样同步器在采样数据时,可能会发生错误。由于采用格雷码计数时,每次只有1位发生跳变,这样使亚稳态发生错误的可能性大大减小了。
??
????3??????
1.3.4??空标志的产生??
由于读/写指针,总是指向FIFO的memory中下一个要读/写的位置。只有在读/写复位的时候,读/写指针才回到0位置。复位后,随着数据的读出/写入,读/写指针指向的地址逐渐增加。如果读的速度比较快,当读指针赶上写指针,即读指针与写指针指向同一个位置时,输出的空标志有效。如下图所示:?
图1.2??FIFO的空/满标志?
1.3.5??满标志的产生??
满标志的产生,基于这样的原理:即“写指针比空指针多绕了一圈”后,又指向了空指针所指向的位置。由上可知,空标志的产生,也是由于读/写指针指向了同一位置。那怎么来区分,当读/写指针指向同一位置时,FIFO是满,还是空呢??
这里,采用增加一位地址位的方法,来区分满标志和空标志。假设FIFO的深度为16,那么采用5位的读/写地址指针。地址的低4位,用来对寻址memory,读/写指针的最高位用来判断FIFO为空还是为满。当读/写指针的低4位相同时,如果最高位也相同,那么空标志有效,否则满标志有效。?
由于格雷码具有一个特性:关于中间的计数值对称。如果从格雷码的中间划开,把它分成2段。分别从上往下看,会发现在对应的位置,只有最高的2位是完全相反,而其余的低位部分则是相同的。因此,当读/写指针的最高2位完全相反,而其余的低位完全相同时,满标志有效(“读指针比写指针多绕了一圈”)。具体如下图所示:?
??
????4??????
图1.3??格雷码的对称特性?
1.3.6??格雷码计数器??
如果读/写数据的使能信号(rinc/winc)有效,在下一个读/写时钟的上升沿到来时,会从(对)memory读出/写入一个数据,并且相应的读/写指针会加1。由于习惯上用二进制码来寻址memory,而且用二进制码能很方便地进行累积操作,所以这里以二进制码为主,并将二进制码转换为格雷码,以比较读/写指针来产生空/满标志位。?
二进制码可以通过以下方式转换成格雷码:?
gray?=?(bin?>>?1)?^?bin?
其中,gray表示格雷码,bin表示二进制码。?
如,设一个5位的二进制码为B[4:0],它对应的格雷码为G[4:0],则?
G[4]?=?B[4]?
G[3]?=?B[3]?^?B[3]?
G[2]?=?B[2]?^?B[2]?
G[1]?=?B[1]?^?B[1]?
G[0]?=?B[0]?^?B[0]?
具体如下图所示:
??
????5??????
图1.4??比较指针和寻址指针的产生电路?
1.4?FIFO的设计模块?
整个FIFO包括1个顶层模块和5个子模块。?
1.4.1??子模块fifomem??
这个子模块,主要实现对FIFO的memory进行操作。如果写使能信号(winc)有效,且FIFO满标志(wfull)无效,则在下一个写时钟(wclk)的上升沿到来时,将数据(wdata)写入到memory中写地址(waddr)指针所指向的位置。同时,只要给出读地址(raddr),就可以从memory中读出数据(rdata),与读时钟(rclk)无关。相应的代码如下所示:??
module?fifomem??#(parameter?DATASIZE?=?8,?//?Memory?data?word?width?
parameter?ADDRSIZE?=?4)?//?Number?of?mem?address?bits?
(output?[DATASIZE‐1:0]?rdata,?
input?[DATASIZE‐1:0]?wdata,?
input?[ADDRSIZE‐1:0]?waddr,?raddr,?
input????????wclken,?wfull,?wclk);?
//?RTL?Verilog?memory?model?
localparam?DEPTH?=?1<<ADDRSIZE;?
reg?[DATASIZE‐1:0]?mem?[0:DEPTH‐1];?
assign?rdata?=?mem[raddr];?
always?@(posedge?wclk)
??
????6??????
if?(wclken?&&?!wfull)?mem[waddr]?<=?wdata;?
endmodule?
1.4.2??子模块sync_r2w??
这个子模块,通过2个D触发器的级联,将格雷码表示的读指针,同步到写时钟域中。相应的代码如下:?
module?sync_r2w?#(parameter?ADDRSIZE?=?4)?
(output?reg?[ADDRSIZE:0]?wq2_rptr,?
input??[ADDRSIZE:0]?rptr,?
input?????????wclk,?wrst_n);?
reg?[ADDRSIZE:0]?wq1_rptr;?
always?@(posedge?wclk?or?negedge?wrst_n)?
if?(!wrst_n)?
{wq2_rptr,wq1_rptr}?<=?0;?
else????
{wq2_rptr,wq1_rptr}?<=?{wq1_rptr,rptr};?
endmodule?
1.4.3??子模块sync_w2r??
这个子模块,也采用2个D触发器的级联,将格雷码表示的读指针,同步到写时钟域中。相应的代码如下:?
module?sync_w2r?#(parameter?ADDRSIZE?=?4)?
(output?reg?[ADDRSIZE:0]?rq2_wptr,?
input??[ADDRSIZE:0]?wptr,?
input?????????rclk,?rrst_n);?
reg?[ADDRSIZE:0]?rq1_wptr;?
always?@(posedge?rclk?or?negedge?rrst_n)?
if?(!rrst_n)??
{rq2_wptr,rq1_wptr}?<=?0;?
else?????
{rq2_wptr,rq1_wptr}?<=?{rq1_wptr,wptr};?
Endmodule?
??
????7??????
1.4.4??子模块rptr_empty??
这个子模块的输入包括:读使能信号(rinc)、读时钟(rclk)、读复位信号(rrst_n,低电平有效)。输出包括:读寻址指针(raddr)、读比较指针(rptr)。其中读寻址指针为二进制码,读比较指针为格雷码,且读寻址指针比读比较指针少一位。可以参照图1.4,相关的代码如下:?
module?rptr_empty?#(parameter?ADDRSIZE?=?4)?
(output?reg???????rempty,?
output?[ADDRSIZE‐1:0]?raddr,?
output?reg?[ADDRSIZE?:0]?rptr,?
input??[ADDRSIZE?:0]?rq2_wptr,?
input??????????rinc,?rclk,?rrst_n);?
reg?[ADDRSIZE:0]?rbin;?
wire?[ADDRSIZE:0]?rgraynext,?rbinnext;?
always?@(posedge?rclk?or?negedge?rrst_n)?
if?(!rrst_n)?
{rbin,?rptr}?<=?0;?
else??????
{rbin,?rptr}?<=?{rbinnext,?rgraynext};?
//?Memory?read‐address?pointer?(okay?to?use?binary?to?address?memory)?
assign?raddr?=?rbin[ADDRSIZE‐1:0];?
assign?rbinnext?=?rbin?+?(rinc?&?~rempty);?
assign?rgraynext?=?(rbinnext>>1)?^?rbinnext;?
//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐?
//?FIFO?empty?when?the?next?rptr?==?synchronized?wptr?or?on?reset?
//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐?
assign?rempty_val?=?(rgraynext?==?rq2_wptr);?
always?@(posedge?rclk?or?negedge?rrst_n)?
if?(!rrst_n)??
rempty?<=?1'b1;?
else?????
rempty?<=?rempty_val;?
endmodule?
??
????8??????
1.4.5??子模块rptr_empty??
这个子模块的输入包括:写使能信号(winc)、写时钟(wclk)、写复位信号(wrst_n,低电平有效)。输出包括:写寻址指针(waddr)、写比较指针(wptr)。其中读寻址指针为二进制码,读比较指针为格雷码,且读寻址指针比读比较指针少一位。可以参照图1.4,相关的代码如下:?
module?wptr_full?#(parameter?ADDRSIZE?=?4)?
(output?reg???????wfull,?
output?[ADDRSIZE‐1:0]?waddr,?
output?reg?[ADDRSIZE?:0]?wptr,?
input??[ADDRSIZE?:0]?wq2_rptr,?
input??????????winc,?wclk,?wrst_n);?
reg?[ADDRSIZE:0]?wbin;?
wire?[ADDRSIZE:0]?wgraynext,?wbinnext;?
//?GRAYSTYLE2?pointer?
always?@(posedge?wclk?or?negedge?wrst_n)?
if?(!wrst_n)??
{wbin,?wptr}?<=?0;?
else?????
{wbin,?wptr}?<=?{wbinnext,?wgraynext};?
//?Memory?write‐address?pointer?(okay?to?use?binary?to?address?memory)?
assign?waddr?=?wbin[ADDRSIZE‐1:0];?
assign?wbinnext?=?wbin?+?(winc?&?~wfull);?
assign?wgraynext?=?(wbinnext>>1)?^?wbinnext;?
//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐?
//?Simplified?version?of?the?three?necessary?full‐tests:?
//?assign?wfull_val=((wgnext[ADDRSIZE]?!=wq2_rptr[ADDRSIZE]?)?&&?
//?????????(wgnext[ADDRSIZE‐1]?!=wq2_rptr[ADDRSIZE‐1])?&&?
//?????????(wgnext[ADDRSIZE‐2:0]==wq2_rptr[ADDRSIZE‐2:0]));?
//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐?
assign?wfull_val?=?(wgraynext=={~wq2_rptr[ADDRSIZE:ADDRSIZE‐1],?
wq2_rptr[ADDRSIZE‐2:0]});?
always?@(posedge?wclk?or?negedge?wrst_n)?
if?(!wrst_n)??
wfull?<=?1'b0;?
else?????
wfull?<=?wfull_val;?
???????????9??
endmodule?
1.4.6??顶层模块afifo??
这个顶层模块,主要完成5个子模块例化和互联。可以参照图1.1,相关的代码如下:??
module?afifo?#(parameter?DSIZE?=?8,?
parameter?ASIZE?=?4)?
(output?[DSIZE‐1:0]??rdata,?
output??????????????wfull,?
output??????????????rempty,?
input??[DSIZE‐1:0]??wdata,?
input???????????????winc,?wclk,?wrst_n,?
input???????????????rinc,?rclk,?rrst_n);?
wire???[ASIZE‐1:0]?waddr,?raddr;?
wire???[ASIZE??:0]?wptr,?rptr,?wq2_rptr,?rq2_wptr;?
sync_r2w?sync_r2w?
(.wq2_rptr(wq2_rptr),?.rptr(rptr),?
.wclk(wclk),?.wrst_n(wrst_n));?
sync_w2r?sync_w2r?
(.rq2_wptr(rq2_wptr),?.wptr(wptr),?
.rclk(rclk),?.rrst_n(rrst_n));?
fifomem?#(DSIZE,?ASIZE)?fifomem?
(.rdata(rdata),?.wdata(wdata),?
.waddr(waddr),?.raddr(raddr),?
.wclken(winc),?.wfull(wfull),?
.wclk(wclk));?
rptr_empty?#(ASIZE)?rptr_empty?
(.rempty(rempty),?
.raddr(raddr),?
.rptr(rptr),?.rq2_wptr(rq2_wptr),?
.rinc(rinc),?.rclk(rclk),?
.rrst_n(rrst_n));?
wptr_full?#(ASIZE)?wptr_full??
(.wfull(wfull),?.waddr(waddr),?
.wptr(wptr),?.wq2_rptr(wq2_rptr),?
.winc(winc),?.wclk(wclk),?
??
????10??????
.wrst_n(wrst_n));????
endmodule?
1.5?用modelsim仿真FIFO??
1.5.1编写测试代码??
根据前面的顶层模块afifo,编写测试代码如下:??
`timescale?1ns/1ns?
module?test;?
reg??[7:0]?wdata;?
reg????????winc;?
reg????????wclk;?
reg????????wrst_n;?
reg????????rinc;?
reg????????rclk;?
reg????????rrst_n;?
wire?[7:0]?rdata;?
wire???????wfull;?
wire???????rempty;?
integer????i;?
always??
begin?
#50?wclk?=?1;?
#50?wclk?=?0;?
end?
always?
begin?
#100?rclk?=?1;?
#100?rclk?=?0;?
end?
initial?
begin?
wrst_n?=?0;?
rrst_n?=?0;?
rinc???=?0;?
winc???=?0;?
wclk???=?0;?
rclk???=?0;?
wdata??=?0;?
??
????11??????
i??????=?0;?
#400;?
wrst_n?=?1;?
rrst_n?=?1;?
for?(i?=?0;?i?<?16;?i?=?i?+?1)?
begin?
repeat?(1)?@?(posedge?wclk)?
#20?winc?=?1;?
wdata?=?i;?
end?
repeat?(1)?@?(posedge?wclk)?
#20?winc?=?0;?
for?(i?=?0;?i?<?16;?i?=?i?+?1)?
begin?
repeat?(1)?@?(posedge?rclk)?
#20?rinc?=?1;?
end?
repeat?(1)?@?(posedge?rclk)?
#20?rinc?=?0;?
end?
afifo?afifo?(.rdata(rdata),?
.wdata(wdata),?
.wclk(wclk),?
.rclk(rclk),?
.wrst_n(wrst_n),?
.rrst_n(rrst_n),?
.wfull(wfull),?
.rempty(rempty),?
.winc(winc),?
.rinc(rinc)?
);?
endmodule?
1.5.2仿真波形??
当写时钟(wclk)和读时钟(rclk)的周期相同,且都为50ns时,波形如下:?
图1.5??仿真波形‐‐读写时钟的周期都为50ns?
??
????12??????
当写时钟(wclk)周期为100ns,读时钟(rclk)周期为50ns时,波形如下:?
图1.6??仿真波形‐‐读/写时钟的周期都为50ns/100ns?
当写时钟(wclk)周期为50ns,读时钟(rclk)周期为100ns时,波形如下:?
图1.6??仿真波形‐‐读/写时钟的周期都为100ns/50ns?
1.5.3仿真结果??
根据前面的3种仿真波形,可以看出所设计的FIFO,能满足功能要求。?
1.6?用DC对FIFO进行综合?
1.6.1编写DC的启动文件??
#.synopsys_dc.setup?for?afifo?
#modified?by?He?Zhongzhu?
#June?22nd,?2011?
set?search_path?".?$search_path?lib?rtl?scripts?mapped?unmapped"?
set?target_library??"tt_1v20_25c.db"?
set?link_library?"?*?$target_library?dw_foundation.sldb"?
set?symbol_library?"?smic13g.sdb?"?
#set?synthesis_library?"dw_foundation.sldb?standard.sldb"?
set?cache_write?~/?
??
????13??????
set?cache_read?$cache_write?
#?specify?directory?for?intermediate?files?from?analyze?
define_design_lib?DEFAULT?‐path?./analyzed?
#?suppress?Driving?cell?warning?
suppress_message?{UID‐401?DDB‐24}?
set?verilogout_no_tri?true?
define_name_rules?BORG?‐allowed?{A‐Za‐z0‐9_}?‐first_restricted?"_"?‐last_restricted?"_"?‐max_length?30?
set?verilogout_no_tri?true?
#?specify?varibles?
set?dw_prefer_mc_inside?true?
set?sh_enable_line_editing?true?
1.6.2编写DC的约束文件??
#top.con?for?afifo?
#created?by?zzhe?
#June?22th,?2011?
reset_design?
#create_clock?‐period?5?‐name?vclk;#virtual?clock?
create_clock?‐period?0.9?[get_ports?wclk]?
create_clock?‐period?0.9?[get_ports?rclk]?
#set_uncertain_delay?‐setup??[get_clocks?vclk]?
#set_clock_latency?‐source?‐max?[get_clocks?vclk]?
#set_clock_transition?[get_clocks?vclk]??
set?MAX_LOAD?[load_of?tt_1v20_25c/NAND2BX2M/AN]?
set_driving_cell?‐lib_cell?INVX16M?[all_inputs]?
set_input_delay?‐max?0?‐clock?wclk?[remove_from_collection?[get_ports?"w*"]?\?
[get_ports?"wfull?wclk"]]?
set_input_delay?‐max?0?‐clock?rclk?[remove_from_collection?[get_ports?"r*"]?\?
[get_ports?"rempty?rdata?rclk"]]?
??
????14??????
set_output_delay?‐max?0?‐clock?wclk?[get_ports?wfull]?
set_output_delay?‐max?0?‐clock?rclk?[get_ports?"rempty?rdata"]??
set_load?[expr?$MAX_LOAD*15]?[all_outputs]?
set_max_area?0?
#set?auto_wire_load_selection?
#set_operating_conditions?‐max?""?
set_max_capacitance?[expr?$MAX_LOAD*10]?[get_designs?*]?
alias?h?history?
alias?rc?"report_constraints?‐all_violators"?
alias?rt?report_timing?
alias?ra?report_area?
alias?rp?report_power?
1.6.3??DC的综合结果??
采用design_vision进行综合,得到的综合结果如下:?
时钟频率:1.1GHz?
面积:????10744.447um2?
功耗:????7.791mw?
2.参考文献??
[1]?Simulation?and?Synthesis?Techniques?for?Asynchronous?FIFO?Design.pdf?
[2?]Jan?M.Rabaey,?Digital?Integrated?Circuits,?A?Design?Perspective??
??
????15??????
本文标题:ui设计师需要懂代码吗-百度高级UI设计师:规范、方法、一致性,真有那么重要?61阅读| 精彩专题| 最新文章| 热门文章| 苏ICP备13036349号-1