Verilog HDL 建模技巧低级建模仿顺序操作思路篇Word格式文档下载.docx

上传人:b****8 文档编号:22755183 上传时间:2023-02-05 格式:DOCX 页数:38 大小:146.49KB
下载 相关 举报
Verilog HDL 建模技巧低级建模仿顺序操作思路篇Word格式文档下载.docx_第1页
第1页 / 共38页
Verilog HDL 建模技巧低级建模仿顺序操作思路篇Word格式文档下载.docx_第2页
第2页 / 共38页
Verilog HDL 建模技巧低级建模仿顺序操作思路篇Word格式文档下载.docx_第3页
第3页 / 共38页
Verilog HDL 建模技巧低级建模仿顺序操作思路篇Word格式文档下载.docx_第4页
第4页 / 共38页
Verilog HDL 建模技巧低级建模仿顺序操作思路篇Word格式文档下载.docx_第5页
第5页 / 共38页
点击查看更多>>
下载资源
资源描述

Verilog HDL 建模技巧低级建模仿顺序操作思路篇Word格式文档下载.docx

《Verilog HDL 建模技巧低级建模仿顺序操作思路篇Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《Verilog HDL 建模技巧低级建模仿顺序操作思路篇Word格式文档下载.docx(38页珍藏版)》请在冰豆网上搜索。

Verilog HDL 建模技巧低级建模仿顺序操作思路篇Word格式文档下载.docx

Counter<

=8'

d0;

elseif(Counter==200)

else

=Counter+1'

b1;

0]i;

i<

=i+1'

elseif(i==8)

d0

0]rData;

rData<

b0000_0001;

elseif(i<

8)

={rData[6:

0],1'

b0};

assignData_Out=rData;

endmodule

没错,上面是实现流水灯的代码。

如果我说我要求:

“自左向右循环3次,自右向左循环5次,然后自左向右一次,自右向左一次,然后自左向右循环30次”。

当你听到这样的要求,你可能会崩溃....如果按照上面的写法,你会写得很长很长。

相比之下,C语言要实现以上的要求,根本就是“小儿科”的功夫。

inti;

for(i=0;

3;

i++)Flashing_To_Right();

i++)Flashing_To_Left();

Flashing_To_Left();

for(i=0;

30;

给自己5分钟的思考,想想我到底要表达什么?

在C语言上,有“顺序操作”或者“泛型编程”的概念。

从上述的代码中,for循环利用i变量,控制循环次数,然后调用3次“Flashing_To_Right()”函数。

相反的V语言是“并行操作”的概念,类似的方法完全行不通。

这就是新手们常常遇到的问题。

方法行不通,但是不代表思路不行。

“低级建模”最基本的思路就是“仿顺序操作”。

“低级建模”不是什么困难的东西,它只是一中的“手段”而已,只要你了解它的基本构思,它会成为很有用的工具。

第2章“低级建模”的结构

2.1“低级建模”的基本结构

从一个管理系统看来,“低级建模”会是一个从上直下层次的一个概念。

从上面的示意图可以看出,老板是最顶级的,而员工是最低级的。

老板从上头发号,然后经经理呀,领导呀,最后苦力集团就开始动工了。

当完工的时候,一一向上报告。

低级建模的概念类似如此。

除了老板以外,所有经理,领导,员工的“集合”称为“低级建模”。

而老板是“独立模块”,因为老板不受命令,而且也不用报告。

而多个“功能模块”的集合称为“组织模块”,如上面示意图中的“永远垂死的苦力集团”

2.2“低级建模”的准则

根据上文和上示意图的分析,“低级建模”基本上有以下几个准则:

1.有“组织模块”和“功能模块”之分。

2.“低级建模”中的“功能模块”均称为“低级功能模块”。

3.“低级功能模块”有如特点:

有开始信号,完成信号,一个模块只有一个功

能。

4.多个“低级功能模块”组织起来称为“组织模块”。

注意点:

功能模块又分成“低级功能模块”和“非低级功能模块”?

这话何解呢?

从上面的示意图中可以分辨出“低级功能模块”和“非低级功能模块”。

“低级功能模块”包含“开始信号”和“完成信号”而“非低级功能模块”则没有(就是这样简单而已)。

2.3“开始信号”和“完成信号”的作用

先看看以下一段代码:

//独立模块

alway@(posedgeCLKornegedgeRSTn)

......

case(cState)

"

打扫"

:

if(打扫完成)nState<

="

洗厕所"

else"

发号打扫命令"

if(洗厕所完成)nState<

跑腿"

发送洗厕所命令"

/*******************************************************************/

//低级功能模块1-打扫工作

always@(posedgeCLKornegedgeRSTn)

case(cState)

IDLE:

if(到扫命令)nSate<

elsenState<

=IDLE;

执行打扫"

打扫完毕后报告"

;

待命..."

nState<

/*********************************************************************/

//低级功能模块2-洗厕所工作

elseif

IDLE:

if(洗厕所命令)nSate<

执行洗厕所"

洗厕所完毕后报告"

//低级功能模块3-跑腿工作

case(cState)

if(跑腿命令)nState<

上面的代码可以分成两个部分,一部分是“独立模块”和另一部分是“低级功能模块”。

独立模块只有一个则打工模块有三个,而且每一个打工模块仅包含一个功能而已“打扫”,“洗厕所”和“跑腿”....

注意:

独立模块不属于低级建模。

假设老板有一系列的命令要发号:

打扫==>

洗厕所==>

跑腿

当“负责打扫”的“低级功能模块”收到老板的第一号命令“打扫”时,该模块从“待命状态”变成“打扫状态”,此时老板可以睡一觉或者干其他的活儿。

该模块便开始“执行打扫任务”,当该模块“打扫完毕”后,就给老板“报告”,然后返回“待命状态”。

故老板听到“打扫完成”报告后,就给下一个“低功能模块”发下一号命令...

在“低级建模”的结构上,为了使不同层次的“低级功能模块”可以协调的工作,“开始信号”和“完成信号”扮演着很重要的角色。

在现实中,如果“打扫==>

跑腿”是一个有“次序的三部曲”,那么老板不可能要员工颠倒次序来干活儿。

老板得按次序,一个一个的命令员工干活。

除此之外老板也不可能实时监督员工的工作状况,做老板真的很辛苦,除了“发号”以外,还要干很多事情,所以员工的“完成报告”在某种程度上可以减轻老板的活儿(使编程更简单),毕竟老板也是人,他也有疲惫的时候。

接下来的话题便是:

“每一个低功能模块仅包含一个功能”。

虽然在现实中,确实存在“全能的人类”打扫,洗厕所,跑腿等技能全都集于一身。

但是“低级建模”的准则必须遵守。

你尝试想象一下,如果一个“低级功能模块”,包含了如上的工作“打扫==>

跑腿”或者更多,即不是要把代码写得很长很长...

所以呀,“低级建模”的准则有它一定的“重要性”(在日后的深入中,你会慢慢了解的)。

 

2.4组织的概念

“组织模块”在“低级建模”中,非常的重要。

它不但简化对多个“低级功能模块”的调用,而且也解决了“两义性”或者“多义性”的问题。

你尝试想象一下:

如果有多个打工仔,散落在不同的地方。

当老板要发号的时候,既不是非常不方便。

同样的,在模块化设计中,设计者往往为了使使用更简单,常常都会使用“顶层模块”将多个模块“封装”到一个模块中,亦即将复杂的东西“隐藏”了起来,只剩下简单“接口”而已。

这样的做法是为了使该模块可以容易被使用。

然而在“低级建模”的设计中,“模块化的组织”更有“层次感”。

为了使“上一层模块”可以很方便调用“下一层组织模块”。

“低级建模”的设计常常将一组或者一个“组织模块+低级功能模块”,“低级功能模块+低级功能模块”,“组织模块+组织模块”组织起来。

虽然感觉上会有一种“杂乱感”,但是实际运用起来,真的非常方便。

如上面的示意图中,3个员工被组织了起来,然后3个员工的组合又和领导组织了起来。

故这样的组织方法因层次关系,如此类推,最后会有两个“大组织”

组织1={经理=>

领导=>

3个用工}

组织2={经理=>

3个员工}

“低级建模”的“组织”结果会是示意图中所示。

除老板意外,大家都有自己的“组织”。

假设老板要命了员工干活,那么老板只要命令任意一个经理就行。

至于“二义性”或者“多义性”的问题,后面会讨论到。

3.1模板基本结构

moduleTemplate

CLK,RSTn,

......,//"

n个输入输出"

Start_Sig,Done_Sig

);

inputCLK;

inputRSTn;

inputStart_Sig;

inputDone_Sig;

......//"

n个输出输入声明"

/*******************************************/

reg[3:

regisDone;

begin

=4'

isDone<

=1'

b0;

......//任何复位的动作

end

elseif(Start_Sig)

case(i)

4'

b0:

//一般都是用于初始化

Init;

......//任何相关的步骤

bn+1,4'

bn+2:

//最后两个步骤用来产生完成信号

Done;

endcase

taskInit;

begin

......//任何初始化的动作

=1+1b'

1;

//指向下一个步骤

endtask

task"

n个Task"

;

.......//"

n个Task的执行任务"

taskDone;

//产生Done信号

if(isDone==1)beginisDone<

elsebeginisDone<

end

Endtask

assignDone_Sig=isDone;

......//相关的输出

endmodule

从上述中,模板的基本结构有以下的特征:

1)Start_Sig和Done_Sig是固定的。

2)寄存器i用于控制次序步骤。

3)最后两个i步骤用于产生完成信号。

4)i等于0的时候,多半都是用于初始化动作(选择性)。

正如准则的要求,“开始信号”和“完成信号”都是必须的。

“开始信号”可以视为“片选信号”而“完成信号”如字面上的意思。

寄存器i有一个重要的功能,它指向任何下一个步骤,而通常所编写的格式如下:

=i+1;

除此之外该模板还引入了“task-endtask”。

目的是为了提升和“结构性”。

新手们应该知道,使用V语言如果没有良好的编程风格,代码的“可读性”是非常的糟糕。

在这里我先简单复习一下,“task-endtask”的用法:

reg[7:

always@(posedgeCLKornegedgeRSTn)

else

case(i)

d0:

case(i)

Next;

/**********************************/

taskNext;

上面的两个写法都是等价的。

如果模块是小功能,那么左边的写法很适合。

但是一旦模块的功能很复杂,那么右边的写法会凸显出优势。

3.2建议

为什么需要模板结构?

创建代码的工作往往都是一次性,为了供人参考,或者为日后“升级”的打算。

我们不得不养成好的“编程风格”,这也是许多参考书上提出的重点之一。

而“模板”便是一种已经制定好的“编程风格”,故这样会简化了编程风格上的问题,只要加以修改,便会完整一个有“结构”和“有风格”的代码。

为什么“低级功能模块”的步骤,需要一个计数寄存器来指向呢?

其实这个问题我也考虑了很久,因为是“仿顺序操作”的关系,故人类对“1,2,3...”类似的次序(步骤)有更直接的效果。

而且也很好的为代码扩展。

编写“低级功能模块”时,必须遵守笔者提议的模板结构吗?

模板的结构只是一个参考而已。

该“模板”结论是我经过不同风格的编程,得出“最通用”的结果。

当然你可以无视我的规定,完全自定义自己的模板结构。

但是有一点请注意,必须以“解读性”为优先考虑。

因为好的代码不是在“执行效率”上,而是“可维护”和“被解读”。

4.1建立2个“低级功能模块”

“自左向右循环3次,自右向左循环5次,然后自左向右一次,自右向左一次,然后自左向右循环30次”

假设这是实验的要求,首先我们先建立两个“低级功能模块”。

一个名为flashing_to_left和flashing_to_right。

1.moduleflashing_to_right

2.(

3.CLK,RSTn,

4.Start_Sig,Done_Sig,

5.Q

6.);

7.

8.inputCLK;

9.inputRSTn;

10.inputStart_Sig;

11.outputDone_Sig;

12.output[7:

0]Q;

13.

14./***********************************/

15.

16.parameterDELAY=8'

d200;

17.

18./***********************************/

19.

20.reg[7:

21.

22.always@(posedgeCLKornegedgeRSTn)

23.if(!

24.Counter<

25.elseif(Counter==DELAY)

26.Counter<

27.elseif(Start_Sig)

28.Counter<

29.else

30.Counter<

31.

32./***************************************/

33.

34.reg[3:

35.reg[7:

36.regisDone;

37.

38.always@(posedgeCLKornegedgeRSTn)

39.if(!

40.begin

41.i<

42.isDone<

43.rData<

dx;

44.end

45.elseif(Start_Sig)

46.case(i)

47.

48.4'

49.beginrData<

50.

51.4'

d1,4'

d2,4'

d3,4'

d4,4'

d5,4'

d6,4'

d7,4'

d8:

52.if(Counter==DELAY)i<

53.elserData<

=(8'

h80>

>

i-1);

54.

55.4'

d9:

56.begini<

d10;

57.

58.4'

d10:

59.begini<

60.

61.endcase

62.

63.

64./**********************************/

65.

66.assignDone_Sig=isDone;

67.assignQ=(i>

0&

&

9)?

rData:

8'

68.

69./**********************************/

70.

71.endmodule

1.moduleflashing_to_left

18./***********************************/

32./***************************************/

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1