FPGA技能树慢慢点之编码风格


前言

不知道先写什么,先写写代码规范吧。找资料的时候找到了一个专门讲Verilog代码规划的,转载复述一下,好像CSDN没用verilog的关键词高亮,我就统一用python的了。链接如下:Verilog编码风格

从哲学的角度出发(我猜的),任何语言都要求追“信达雅”,信指译文内容准确,达指的结构清晰,雅指富有文采。所以编写代码也要追求功能准确实现,结构清晰,可读性好。


编码风格

1、关于命名(信)

本铲屎官目前写的代码体量都不是很大,所以还没遇到很长的命名。
据悉信号变量模块一定要使用有意义的名字,不然

	reg 	[7:0]a;						
	reg		[7:0]b;					//a和b当时写的时候还记得,过了几天,a是啥??!

链接推荐了两种书写方法,不过我更喜欢我自动的第三种,好像首字母大写更好看一点

	reg     DataToDestinationClock ;
	reg     data_to_destination_clock ; 	//推荐
  	reg     Data_to_Destination_Clock;	//首字母大写

一些十分常用的信号线采用独特的命名方法,还有很多就不一一举例了

	wire clk;			//clk代替clock
	wire rst;			//rst代替reset
	reg clk4test;		//4代替for,原为clk_for_test
	wire clk_en;		//clock_enable
	wire wdata;			//write_data

建议一般功能模块的名称、端口、信号变量等全部使用小写(感觉我第三种写法也行)

	parameter		DW = 8;
	reg    [DW-1:0]	 wdata;

寄存器变量一般加后缀 _r ,延时打拍的变量加后缀 _r1、_r2

	reg indata_r;
	reg indata_r1,indata_r2;
	always@(posedge clk or negedge rst_n)begin
		indata_r1 <= indata_r;						
		indata_r2 <= indata_r1;						//打两拍实现同步并且减少冒险出现的概率
	end

还有的就是 _d 可以表示延迟后的信号,_t 可以表示暂时存储的信号,_n 可以表示低有效的信号,_s 可以表示 slave 信号,_m 可以表示 master 信号等


2、关于注释

注释可好用了,我第一次知道注释居然可以用来画波形,而且还可以画综合后的电路,把相关的时序描述写在注释里面就不用去查找功能文档了

	//	clk     ________/ ̄\_/ ̄\_/ ̄\_/ ̄\_/ ̄\_/ ̄\_/ ̄\_/ ̄\____________		//时钟信号
	//  rst_n   _____/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄		//复位信号

设计模块开头,应该包含文件说明信息,包括版权、模块名字、作者、日期、梗概、修改记录等信息。(下面的代码从链接直接抄过来了)

/**********************************************************
// Copyright 1891.06.02-2017.07.14
// Contact with willrious@sina.com
================ runoob.v ======================
>> Author       : 	willrious
>> Date         : 	1995.09.07
>> Description  : 	Welcome
>> note         : 	(1)To 
>>              : 	(2)My
>> V180121      : 	World.
************************************************************/

对于信号线和寄存器需要注明其用途,注释很短直接写在代码后面,若注释过长则写在前面


   //输出位宽小于输入位宽,求取缩小的倍数及对应的位数
   parameter       SHRINK       = DWI/DWO ;
   reg [AWI-1:0]         ADDR_WR ; //写地址
   

3、关于优化(达)

这里的优化所指的不是在算法层面对功能模块进行优化,而是通过添加括号的形式使模块更有结构感,更具有可读性。

	assign F = A + B + C + D;		//这种写法会被综合成三个加法器
	//这种写法也会被综合成三个加法器,但是A与B相加的和与C与D相加的和进行相加
	assign F = (A + B) + (C + D); 	
	
	//不推荐,结构不够清晰
    assign flag = cnt == 4'd2 && mode == 2'b01;
    //推荐
    assign flag = (cnt == 4'd2) && (mode == 2'b01);
    

(下面内容直接复制了,已经说的很好了)

条件语句尽量使用 case 语句代替 if 语句。当同级别的条件判断语句过多时,使用 case 语句综合后的硬件结构,往往比 if 语句消耗更少的资源,拥有更好的时序。

状态机编写时,尽量使用 3 段式,以保证代码具有良好的整洁性和安全性。

系统设计时,尽量采用模块按功能分割、然后进行模块例化的方法。相比成千上万行代码都集成在一个文件中,模块分割有利于团队设计,便于更新维护。


4、关于美观(雅)

美观是在功能正确实现的基础上怎么写的有层次感,让人赏心悦目,这个和写作文一样,哪怕是同样的内容,写字好看的总会比写字不好看的多一点分

端口信号保证每行一个信号,逗号紧跟在端口声明之后

	module rs_code(input clk,input rst_n,input data_in,output data_out); 	//写法不推荐

	//推荐写法
	module rs_code(
		input     	clk,
		input		rst_n,
		input		data_in,
		output		data_out
	);
	

尽量使用 begin + end 的方式保证执行语句间的层叠关系。begin 与关键字同行,end 另起一行。

例如,always 语句块使用时,或条件语句只有一条执行语句时,都可以省略 begin + end 关键字。但为保证结构的完整性,以及后续代码的调试与修改,还是建议加入此类关键字。


   always @(posedge dout_clk or negedge rstn) begin
      if (!rstn) begin
         dout_en_r       <= 1'b0 ;
      end
      else begin
         dout_en_r       <= rd_en_wir ;
      end
   end

模块例化时,端口信号尽量与连接信号隔开,并各自对齐。连接信号为向量时指明其位宽,方便阅读、调试。


   ram   u_ram(
        .CLK_WR          (clk),
        .WR_EN           (wren), //写满时禁止写
        .ADDR_WR         (addr),
        .D               (wdata[9:0]),
        .Q               (rdata[31:0])
        );

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值