Verilog学习之路

1.冒号前后同时出现变量

在已知所需位宽的情况下,可使用":-“或”:+"代替;比如我们有一个变量i,我们需要取出从i×8+7到i×8这8位数据,直接写[i×8+7:i×8]是会报错的。正确的写法是:
[8×i+7 -: 8]

2.模块接口写法

// msg_generator.v
`timescale 1ns/1ns
`include "head.v"
module msg_generator #(
    parameter   VLAN_FLAG  = 1'b1,          // 指定是否Vlan
    parameter   PORT_TYPE  = `PORT_GMII,    // 指定接口类型(对应不同输出位宽 PORT_TYPE 和 msg_vaild 的不同含义)
    parameter   MSG_LEN    = 11'd100,       // 指定报文体总长度(E1588无效)(64:1:1518, 1600:64~1518随机)
    parameter   MSG_NUM    = 32'd1,         // 指定连续发送报文总数(0:32'hFFFF_FFFF包)
    parameter   PREOK_RATE = 7'd100,        // 指定前导码完整概率(少字节数随机)(100:必完整, 0:必缺)
    parameter   CRCOK_RATE = 7'd100,        // 指定CRC正确概率(fake_crc=actual_crc+1)(100:必正确, 0:必错)
    parameter   ALIGN_RATE = 7'd100         // 指定按DW对齐的概率(MSG_LEN 未对齐时上浮对齐)(100:必对齐, 0:忽略)
)
(
    input                                   clock,
    input                                   reset,
    input       [`LIST_MAX*`CODE_WIDE-1:0]  msg_list,       // 指定类型列表(参见head.v)(首包写在高位)
    input       [9:0]                       interval,       // 指定报文发送间隔(单位:byte)(流量测试)
    output reg  [PORT_TYPE-1:0]             msg_out,
    output                                  msg_vaild,      // TX_EN, SMII: SYNC
    output                                  msg_over,       // 单包结束标志
    output                                  all_finish,     // 指定包数发完标志
    output      [31:0]                      info_msgcnt,    // 当前已发包数
    output      [7:0]                       info_type,      // 当前包报文类型
    output      [3:0]                       info_prelen,    // 当前包前导码字节数
    output      [15:0]                      info_msglen     // 当前包的实际长度(bytes)
);

例化调用:

// tb.v
localparam   PORT_TYPE     = `PORT_GMII;
wire   		 [PORT_TYPE-1:0] msg_q;

always @(posedge msg_over or posedge reset) begin
    rand_int <= 7+{$random}%6;  //报文间隔 7-12
end

reg     [200:0]     msg_list={
                        `MSG_PDELAY_RESP,
                        `MSG_RESP_FOLLOW_UP
                    };
// 例化格式:
// input、output、parameter都没有要求必须写全
msg_generator #(
    .VLAN_FLAG      (1),
    .PORT_TYPE      (PORT_TYPE),
    .MSG_LEN        (64),
    .MSG_NUM        (20)
    )gen_case(
    .clock          (clk125m),
    .reset          (reset),
    .msg_list       (msg_list),
    .interval       (12),
    .msg_out        (msg_q),
    .msg_vaild      (msg_vaild),
    .msg_over       (msg_over),
    .all_finish     (),
    .info_msgcnt    (),
    .info_type      (),
    .info_prelen    (),
    .info_msglen    ()
    );

2.1 parameter 、 localparam、`define

  1. parameter区别于localparamparameter写在模块接口中,在例化时更改,而localparam则用于内部常量的定义;
  2. parameter应提供默认值,在例化时即使没有“实参”与之对应,模块也能正常输出;
  3. parameter在例化之初就被赋值,而inputoutput变量则是在例化初始化之后(如模块内的initial块结束)才有值;
  4. 因为parameter在例化时可以更改,而在reginputoutputinoutwire定义的时候须通过常量指定位宽,因此可用parameter定义的常量来更改位宽以适应不同的例化需求;
  5. define即宏定义,可定义各类常量(如数值、字符串等),一般单独写在一个head.v文件中:
// GOOSE SV
`define         GO_APPID                16'h00
`define         SV_APPID                16'h40
// TYPE STRING
`define         S_NONE_NAMED            ("Undefine Name String       ")
`define         S_GOOSE                 ("GOOSE                      ")
`define         S_SV                    ("SV                         ")

在需要使用到该文件中定义的值时使用 :

`include "head.v"

其中元素的调用:

localparam  TICK_SET    = (PORT_TYPE==`PORT_SMII)?10:(8/PORT_TYPE);

// 报文实际类型
always @(reset or msg_cnt) begin
    // 求余取type, 并调整次序
    msg_type = msg_list[(list_deep-msg_cnt%list_deep)*`CODE_WIDE-1-:`CODE_WIDE];
end
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值