取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
maolinj
Xilinx Employee
Xilinx Employee
144 次查看
注册日期: ‎05-09-2018

【分享】verilog function的使用

verilog编程时,使用function可以将可被复用的组合逻辑功能提取出来,使代码易于参数化,也便于维护。

举例如下:
PRBS通过一个生成多项式产生伪随机数据,生成过程中,数据进行移位及异或操作,适合FPGA处理。
通过function,可并行实现一定数据位宽的PRBS运算,简化了实现过程,并且function内循环的次数由外部参数配置,模块可被复用。

//***********************************************************
module prbs_gen
#(
parameter C_DWIDTH     = 16                       ,
parameter C_PRIMPOLY   = 17'b1_0001_0000_0000_1011,
parameter C_POLY_WIDTH = 16
)
(
input                         I_clk     ,
input      [C_POLY_WIDTH-1:0] I_init    ,
input                         I_init_v  ,
input                         I_prbs_en ,
output reg [C_DWIDTH-1:0]     O_prbs    ,
output reg                    O_prbs_v
);

//-------------generation table----------------
//4:  X^4+X^1+1
//5:  X^5+X^2+1
//6:  X^6+X^1+1
//7:  X^7+X^3+1
//8:  X^8+X^4+X^3+X^2+1
//9:  X^9+X^4+1
//10: X^10+X^3+1
//11: X^11+X^2+1
//12: X^12+X^6+X^4+X^1+1
//13: X^13+X^4+X^3+X^1+1
//14: X^14+X^10+X^6+X^1+1
//15: X^15+X^1+1
//16: X^16+X^12+X^3+X^1+1
//----------------------------------------------
reg [C_POLY_WIDTH-1:0] S_prbs_reg;
wire [C_POLY_WIDTH-1:0] S_reg_sel;

assign S_reg_sel = I_init_v ? I_init : S_prbs_reg;

always @(posedge I_clk)
begin
    if(I_prbs_en)
    begin
        S_prbs_reg <= F_prbs_reg(S_reg_sel);
        O_prbs <= S_reg_sel;
    end
    O_prbs_v <= I_prbs_en;
end

function [C_POLY_WIDTH-1:0] F_prbs_reg;
input [C_POLY_WIDTH-1:0] S_cal_init;
integer F_i;
begin
    F_prbs_reg = S_cal_init;
    for(F_i=0;F_i<C_DWIDTH;F_i=F_i+1)
        F_prbs_reg = {^(F_prbs_reg & C_PRIMPOLY[C_POLY_WIDTH-1:0]),F_prbs_reg[C_POLY_WIDTH-1:1]};
end
endfunction

endmodule
//***********************************************************

 

0 回复数