明德扬至简设计规范(学习笔记)

一、电路设计的语法

1.设计不用的语法

a)initial 【设计不用,仿真时使用】

b)  #5 【设计不用,仿真时使用】

下面的均设计不用,仿真时亦不用

task/function   

for/while/repeat/forever

integer

casex/casez

force/wait/fork

模块内部不能有X态(不定态)、Z态(高阻态),内部不能有三态接口

2.设计使用的语法

a)reg/wire、parameter

b)assign【建议改名时使用】、always

c)只允许使用if else 和case两种条件语句

只用a)、b)、c)就能搞定所有的设计

d)算术运算符(+,-,*,/,%)

e)赋值运算符(<=,=)【时序逻辑用<=,组合逻辑用=,其他 情况不存在】

注:不必纠结二者的区别,只需记住时序逻辑用<=,组合逻辑用=

f)关系运算符(>,<,>=,<=)

g)逻辑运算符(&&,||,!)【为避免歧义,逻辑运算符两边必须用1bit信号】

h)位运算符(~,|,^,&)【重点关注异或】

i) 移位运算符(<<,>>)

j)拼接运算符({})

二、电路设计的结构

1.电路设计的3种结构

1)组合逻辑

always @(*) begin

   语句

end

2)时序逻辑

a)同步复位的时序逻辑

always @ (posedge clk )begin
     if(rst_n==1'b0)begin
     语句
     else begin
     语句
     end
end
b)异步复位的时序逻辑

always @ (posedge clk or negedge rst_n)begin
     if(rst_n==1'b0)begin
     语句
     else begin
     语句
     end
end
三、电路设计的要点

1.一个always只产生一个信号

例如

always@(posedge clk  or negedge rst_n) begin 
if(rst_n==1’b0)begin 
            b <= 1’b0; 
            a <= 1’b0; 
else begin 
            b <= 1’b1; 
            a <= b; 
end 
end 
通常的verilog代码,一个 always里面会设计多个信号,例如上图,这个 always 语句同时设计了a和 b两个信号。明德扬建议一个 always只设计一个信号,例如上面 代码应该改为以下代码。 
 
always@(posedge clk  or negedge rst_n) begin 
if(rst_n==1’b0)begin 
            b <= 1’b0; 
else begin 
            b <= 1’b1; 
end 
end 
always@(posedge clk  or negedge rst_n) begin 
if(rst_n==1’b0)begin 
            a <= 1’b0; 
else begin 
            a <= b; 
end 
end 

a). 一心一用。每段 always 同时只考虑 1 个信号的设计,不用考虑其他无关的信号。 例如设计 a 时,就全力想 a 信号,不用考虑 b 信号。这样有助于写出最简、最高 效的代码。

b). 有助于按照定义实现信号。设计的第一步是定义信号,该信号干什么用,什么时 候为 0,什么时候为其他值,都在设计前定义好。always 就根据这个定义来写代 码,非常简单。

c). 方便查找和定位问题。如果代码出现问题,方便查找问题的源头。只要找到与定 义不一致的那段 always代码,修改该段代码,就能解决好问题。

d). 修改代码影响最小。修改代码时,只修改本信号,而不会对其他信号造成影响。 否则很有可能修改 1 个信号,导致其他本来已经正确的信号又变错误。很多同学 设计时,容易反反复复,经常按下葫芦又起瓢,最后是勉勉强强成功,但这样的 系统,可靠性能有多高呢。

e). 有助于衡量工作进度。做好设计定义后,就非常清楚有多少信号需要设计。只要 按照定义写好代码,该信号的设计就基本完成,出错的概率很低。即使后期有错 误,修改相应的那个信号就解决问题。但如果多个信号集中到一个 always,每个 信号之间相互影响,不到最后时刻,你都不清楚还有多少设计未完成。工作中曾 经出现这样情景:产品设计号称进度是 99%,但后期修改 1 个错误,进而影响了 其他信号,基本上其他信号都要重新设计,进度一下子又退回了 50%。

f). 容易修改代码。多个信号集中在一个 always,修改代码时,你只能见缝插针,还 要极力避免影响其他信号,非常困难。

g). 有助于硬件思维设计。一个 always设计 1个信号,这段 always很容易理解为一个 电路模块,从而设计出最高效的电路。多个信号在一个 always,容易按软件思维 来进行 FPGA设计。

2.一个信号只能在一个always产生

上图第1个触发器的输出值为 0,第2个触发器的输出值为 1,由于两个触发器输 出信号名都是 b,那自然就是同一根线,那么在这种情况下,b的值到底是 0还是 1呢? 谁也不知道,因此FPGA内部不允许有这种不确定的情况出来。所以下面两段代码是 不允许的,b只能在一个always里产生,而不能是两个。 
always@(posedge clk  or negedge rst_n) begin 
if(rst_n==1’b0)begin 
            b <= 1’b0; 
else begin 
if(a==1’b1) 
                   b <= 1’b1; 
end 
end 
 
always@(posedge clk  or negedge rst_n) begin 
if(rst_n==1’b0)begin 
            b <= 1’b0; 
else begin 
if(c==1’b1) 
                   b <= 1’b0; 
end 
end 

3.硬件设计思维

FPGA不是一行一行顺序执行的,FPGA是将代码变成 电路后,上电运行的。其 always描述的是一个信号在什么情况下,这个信号的值为多 少;在其他情况下,值为多少。 

 

下面就是一个很典型的软件思维写出的代码。 
 
always@(posedge clk  or negedge rst_n) begin 
if(rst_n==1’b0)begin 
            b <= 4’b0; 
else begin 
            b<= b+1; //line_0 
if(b==8) 
b <= 0;//line_1 
end 
end 

例如某个信号在三种情况下取不同的值:条件 A满足时值为2、条件 B满足时值 为1,以及其他情况时值为 0,如上图。则对应的always代码如下: 
always@(posedge clk  or negedge rst_n) begin 
if(rst_n==1’b0)begin 
a <= 0; 
    else if(条件 A) 
a <= 2; 
else if(条件B) 
        a <= 1; 
else 
        a <= 0; 
end 
 
FPGA设计的步骤:首先考虑这个信号有多少种值,然后这些值分别在哪几种情况 获得。把情况划分好之后,就可以用 if else语句来写代码了。 
 
前面错误的代码,其正确的代码应该是这样的,将情况分成 b等于7(值为0)和 b不等于7(值等于上一次值加 1)两种情况: 
always@(posedge clk  or negedge rst_n) begin 
if(rst_n==1’b0)begin 
            b <= 4’b0; 
else begin 
if(b==7) 
b <= 0;//line_1 
else 
               b <= b+1; 
end 
end 

 

4.条件判断只允许使用if else 和 case  ,其他全不用(包括casex)。

5.含有posedge或negedge的,一定是D触发器,是时序电路。

6.设计时,如果你想立刻有结果,那就用组合逻辑,如果你想延时一拍有结果,那就用时序逻辑。

 

重点:

1,三种电路

2,两种条件

3,一一法则

即标红部分。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值