本文主要讨论在Verilog XL平台上提高仿真效率的代码风格。
1、尽量使用case语句而不是复杂的if-else结构
方法一:使用case语句
module CaseMux8 (y, i, sel);
output y;
input [7:0] i;
input [2:0] sel;
reg y;
wire [7:0] i;
wire [2:0] sel;
always @(i or sel)
case (sel)
3'd0: y = i[0];
3'd1: y = i[1];
3'd2: y = i[2];
3'd3: y = i[3];
3'd4: y = i[4];
3'd5: y = i[5];
3'd6: y = i[6];
3'd7: y = i[7];
endcase
endmodule
方法二:使用if-else结构:
module IfMux8 (y, i, sel);
output y;
input [7:0] i;
input [2:0] sel;
reg y;
wire [7:0] i;
wire [2:0] sel;
always @(i or sel)
if (sel == 3'd0) y = i[0];
else if (sel == 3'd1) y = i[1];
else if (sel == 3'd2) y = i[2];
else if (sel == 3'd3) y = i[3];
else if (sel == 3'd4) y = i[4];
else if (sel == 3'd5) y = i[5];
else if (sel == 3'd6) y = i[6];
else if (sel == 3'd7) y = i[7];endmodule
2、尽量少的使用不必要的begin-end
方法一:不使用多余的begin-end
module dff (q, d, clk, rst);
output q;
input d, clk, rst;
reg q;
always @(posedge clk or posedge rst)
if (rst == 1) q = 0;
else q = d;
endmodule
方法二:使用不必要的begin-end
module dff (q, d, clk, rst);
output q;
input d, clk, rst;
reg q;
always @(posedge clk or posedge rst)
begin
if (rst == 1) begin
q = 0;
end
else begin
q = d;
end
end
endmodule
3、不要有意将本在一个always中完成的语句分到多个always中去写
`define ICNT 10000000
`define cycle 100
`timescale 1ns / 100ps
module AlwaysGroup;
reg clk;
reg [7:0] a, b, c, d, e;
initial begin
clk = 0;
forever #(`cycle) clk = ~clk;
end
initial begin
a = 8'haa;
forever @(negedge clk) a = ~ a;
end
initial begin
repeat(`ICNT) @(posedge clk);
`ifdef RUN @(posedge clk) $finish(2);
`else @(posedge clk) $stop(2);
`endif
end
`ifdef GROUP4 // Group of four always blocks
always @(posedge clk) begin
b <= a;
end
always @(posedge clk) begin
c <= b;
end
always @(posedge clk) begin
d <= c;
end
always @(posedge clk) begin
e <= d;
end
`else // Four assignments grouped into a
// single always block
always @(posedge clk) begin
b <= a;
c <= b;
d <= c;
e <= d;
end
`endif
endmodule
4、module定义时对输入输出做明确定义
`ifdef NOPORTS
module PortModels;
reg [15:0] q;
reg [15:0] d;
reg clk, rstN;
always @(posedge clk or negedge rstN)
if (rstN == 0) q <= 0;
else q <= d;
endmodule
`else
module PortModels (q, d, clk, rstN);
output [15:0] q;
input [15:0] d;
input clk, rstN;
reg [15:0] q;
always @(posedge clk or negedge rstN)
if (rstN == 0) q <= 0;
else q <= d;
endmodule
`endif
5、时钟定义时尽量使用always或者forever
`define ICNT 100_000
`define cycle 100
`timescale 1ns / 1ns
module Clocks;
reg d, rstN;
`ifdef ALWAYS
reg clk; // driven by a procedural block
initial clk = 0;
always // free running behave clk #1
#(`cycle/2) clk = ~clk;
`endif
`ifdef FOREVER
reg clk; // driven by a procedural block
initial begin
clk = 0;
forever #(`cycle/2) clk = ~clk;
end
`endif
`ifdef GATE // free running clk #3 (gate)
reg start;
wire clk; // driven by a gate
initial begin
start = 0; #(`cycle/2) start = 1;
end
nand #(`cycle/2) (clk, clk, start);
`endif
dff d1 (q, d, clk, rstN);
initial begin
rstN = 0; d = 1;
@(negedge clk) rstN = 1;
repeat(`ICNT) @(posedge clk);
`ifdef RUN @(posedge clk) $finish(2);
`else @(posedge clk) $stop(2);
`endif
end
// Veritools Undertow-dumpfile option
`ifdef UT
initial begin
$dumpfile(dump.ut); $vtDumpvars;
end
`endif
endmodule
参考文献:
【1】VERILOG CODING STYLES FOR IMPROVED SIMULATION EFFICIENCY Clifford E. Cummings
【2】IEEE Standard Hardware Description Language Based on the Verilog Hardware Description
Language, IEEE Computer Society, IEEE Std 1364-2001