一、verilog中有关代码复用的语法
1、连接符“{}”
{4{1'b1}} 或者 {5'd6, 5'd8}
2、参数(Parameter)型常量定义
parameter 参数名=表达式; 或者 localparam 参数名=表达式;
parameter DATA_WIDTH = 20;
3、function函数定义
函数内部语句只能写组合逻辑。
function [7:0] adder;
input [6:0] a;
input [6:0] b;
begin
adder = a + b;
end
endfunction
4、for语句
for(表达式1;表达式2;表达式3) 语句
genvar i;
for(i=0; i<10; i=i+1)
5、generate-for语句
(1) 必须使用genvar定义一个正整数变量;
(2) for里面的内嵌语句,必须写在begin_end里面;
(3) begin_end需要定义名字。
genvar i;
generate for(i=0; i<10; i=i+1)
begin
语句;
end
endgenerate
二、代码复用示例
1、使用函数定义
module test(
input wire [6:0] a,
input wire [6:0] b,
input wire [6:0] c,
input wire [6:0] d,
output reg [7:0] ab,
output reg [7:0] bc,
output reg [7:0] cd;
);
function [7:0] caler;
input [6:0] a;
input [6:0] b;
begin
adder = {a, 1'b0} + b;
end
endfunction
always(posedge clk) begin
if(reset) begin
{ab,bc,cd} <= 'b0;
end else begin
ab <= caler(a,b);
bc<= caler(b,c);
cd <= caler(c,d);
end
end
endmodule
2、使用generate示例
(1)语句复用
parameter DATA_WIDTH = 7;
reg [DATA_WIDTH*10-1:0] a;
reg [DATA_WIDTH*10-1:0] b;
reg [DATA_WIDTH*10-1:0] c;
genvar i;
generate for(i=0; i<10; i=i+1)
begin
always(posedge clk) begin
if(reset) begin
c[(i+1)*DATA_WIDTH-1:i*DATA_WIDTH] <= 'b0;
end else begin
c[(i+1)*DATA_WIDTH-1:i*DATA_WIDTH] <= a[(i+1)*DATA_WIDTH-1:i*DATA_WIDTH] + b[(i+1)*DATA_WIDTH-1:i*DATA_WIDTH];
end
end
end
endgenerate
(2)模块复用
parameter IN_WIDTH = 7;
parameter OUT_WIDTH = 8;
reg [IN_WIDTH*10-1:0] a;
reg [IN_WIDTH*10-1:0] b;
reg [IN_WIDTH*10-1:0] c;
reg [IN_WIDTH*10-1:0] d;
wire [OUT_WIDTH *10-1:0] ab;
wire [OUT_WIDTH *10-1:0] bc;
wire [OUT_WIDTH *10-1:0] cd;
genvar i;
generate for(i=0; i<10; i=i+1)
begin
test(
.clk(clk),
.reset(reset),
.a(a[(i+1)*IN_WIDTH-1:i*IN_WIDTH]),
.b(b[(i+1)*IN_WIDTH-1:i*IN_WIDTH]),
.c(c[(i+1)*IN_WIDTH-1:i*IN_WIDTH]),
.d(d[(i+1)*IN_WIDTH-1:i*IN_WIDTH]),
.ab(ab[(i+1)*OUT_WIDTH-1:i*OUT_WIDTH]),
.bc(bc[(i+1)*OUT_WIDTH-1:i*OUT_WIDTH]),
.cd(cd[(i+1)*OUT_WIDTH-1:i*OUT_WIDTH])
);
end
endgenerate
总的来说,使用generate确实对代码的整体结构,以及调试提供了很大的方便,各位可以在编写代码的过程中多多使用。