DSP48E2 仿真代码:
测试的功能为 P i = ( A + D ) ∗ B + P i − 1 P_{i} = (A+D) * B + P_{i-1} Pi=(A+D)∗B+Pi−1
verilog
`timescale 1ns / 1ns
module dsp_tb;
// 输入
reg CLK;
reg CE;
reg SCLR;
reg signed [26:0] A, D;
reg signed [17:0] B;
// 输出
wire signed [47:0] P;
parameter period = 5; // 100MHz
parameter num_test = 104;// 测试轮数
always #period CLK=!CLK;
// DSP 初始化
initial begin
CLK = 0;
CE = 0;
SCLR = 1;
A = 0;
B = 0;
D = 0;
#(period*2);
CE = 1;
SCLR = 0;
end
// 测试激励生成
integer i=0;
always #10 begin
//A = (1 << 26) - 1;
//D = 0;
//B = (1 << 16) - 1;
A = $random % (1 << 18);
D = $random % (1 << 8);
B = $random % (1 << 8);
if(i==num_test+1)begin
#period $stop;
end else begin
i=i+1;
end
end
reg signed [26:0] A_4r, D_4r, A_3r, D_3r, A_2r, D_2r, A_r, D_r;
reg signed [17:0] B_r, B_2r, B_3r, B_4r;
integer num_correct=0, num_error=0; // 记录正确个数和错误个数
wire signed [47:0] P_ref;
reg signed [47:0] P_ref_r;
wire result;
// 参考结果生成
assign P_ref=(i<4)?0: (A_4r + D_4r)* B_4r + P_ref_r;
assign result=(P_ref!=P);
// 打印测试log
always@(posedge CLK)
if(SCLR)begin
{A_4r,D_4r, B_4r, A_3r,D_3r, B_3r, A_2r,D_2r, B_2r, A_r,D_r, B_r}<=0;
P_ref_r <= 0;
num_correct <= 0;
num_error <= 0;
end else
begin
// 打拍同步延迟
{A_4r,D_4r,B_4r}<={A_3r, D_3r, B_3r};
{A_3r,D_3r,B_3r}<={A_2r, D_2r, B_2r};
{A_2r, D_2r, B_2r}<={A_r, D_r, B_r};
{A_r, D_r, B_r}<={A, D, B};
P_ref_r <= P_ref;
// 结果比对和打印
if(i>=5 && i<=num_test)begin // 前四个输出P和P_ref的时序未同步,故不算
$write("[%d]: (%d + %d)* %d + %d = %d, P_ref:%d, ",i-5,A_4r, D_4r, B_4r, P_ref_r, P, P_ref);
if(result==1'b0)begin
$display("Pass :)");
num_correct <= num_correct + 1;
end else begin
$display("Fail :(");
num_error <= num_error + 1;
end
end else begin
$display("Accuracy:%d/%d=%d%%", num_correct,num_test-4,num_correct*100/(num_test-4));
end
end
// 实例化待测模块
dsp_macro_0 uut(
.CLK(CLK),
.CE(CE),
.SCLR(SCLR),
.A(A),
.B(B),
.D(D),
.P(P)
);
endmodule