mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 19:52:31 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			331 lines
		
	
	
	
		
			8.5 KiB
		
	
	
	
		
			Verilog
		
	
	
	
	
	
			
		
		
	
	
			331 lines
		
	
	
	
		
			8.5 KiB
		
	
	
	
		
			Verilog
		
	
	
	
	
	
| `timescale 1ns / 1ps
 | |
| 
 | |
| module testbench;
 | |
| 	parameter integer A0REG = 1;
 | |
| 	parameter integer A1REG = 1;
 | |
| 	parameter integer B0REG = 1;
 | |
| 	parameter integer B1REG = 1;
 | |
| 	parameter integer CREG = 1;
 | |
| 	parameter integer DREG = 1;
 | |
| 	parameter integer MREG = 1;
 | |
| 	parameter integer PREG = 1;
 | |
| 	parameter integer CARRYINREG = 1;
 | |
| 	parameter integer CARRYOUTREG = 1;
 | |
| 	parameter integer OPMODEREG = 1;
 | |
| 	parameter CARRYINSEL = "OPMODE5";
 | |
| 	parameter RSTTYPE = "SYNC";
 | |
| 
 | |
| 	reg CLK;
 | |
| 	reg CEA, CEB, CEC, CED, CEM, CEP, CECARRYIN, CEOPMODE;
 | |
| 	reg RSTA, RSTB, RSTC, RSTD, RSTM, RSTP, RSTCARRYIN, RSTOPMODE;
 | |
| 	reg [17:0] A;
 | |
| 	reg [17:0] B;
 | |
| 	reg [47:0] C;
 | |
| 	reg [17:0] D;
 | |
| 	reg [47:0] PCIN;
 | |
| 	reg [7:0] OPMODE;
 | |
| 	reg CARRYIN;
 | |
| 
 | |
| 	output CARRYOUTF, REF_CARRYOUTF;
 | |
| 	output CARRYOUT, REF_CARRYOUT, REF_OLD_CARRYOUT;
 | |
| 	output [35:0] M, REF_M;
 | |
| 	output [47:0] P, REF_P, REF_OLD_P;
 | |
| 	output [17:0] BCOUT, REF_BCOUT, REF_OLD_BCOUT;
 | |
| 	output [47:0] PCOUT, REF_PCOUT, REF_OLD_PCOUT;
 | |
| 
 | |
| 	integer errcount = 0;
 | |
| 
 | |
| 	reg ERROR_FLAG = 0;
 | |
| 
 | |
| 	task clkcycle;
 | |
| 		begin
 | |
| 			#5;
 | |
| 			CLK = ~CLK;
 | |
| 			#10;
 | |
| 			CLK = ~CLK;
 | |
| 			#2;
 | |
| 			ERROR_FLAG = 0;
 | |
| 			if (REF_BCOUT !== BCOUT || REF_OLD_BCOUT != BCOUT) begin
 | |
| 				$display("ERROR at %1t: REF_BCOUT=%b REF_OLD_BCOUT=%b UUT_BCOUT=%b DIFF=%b", $time, REF_BCOUT, REF_OLD_BCOUT, BCOUT, REF_BCOUT ^ BCOUT);
 | |
| 				errcount = errcount + 1;
 | |
| 				ERROR_FLAG = 1;
 | |
| 			end
 | |
| 			if (REF_M !== M) begin
 | |
| 				$display("ERROR at %1t: REF_M=%b UUT_M=%b DIFF=%b", $time, REF_M, M, REF_M ^ M);
 | |
| 				errcount = errcount + 1;
 | |
| 				ERROR_FLAG = 1;
 | |
| 			end
 | |
| 			if (REF_P !== P || REF_OLD_P != P) begin
 | |
| 				$display("ERROR at %1t: REF_P=%b REF_OLD_P=%b UUT_P=%b DIFF=%b", $time, REF_P, REF_OLD_P, P, REF_P ^ P);
 | |
| 				errcount = errcount + 1;
 | |
| 				ERROR_FLAG = 1;
 | |
| 			end
 | |
| 			if (REF_PCOUT !== PCOUT || REF_OLD_PCOUT != PCOUT) begin
 | |
| 				$display("ERROR at %1t: REF_PCOUT=%b REF_OLD_PCOUT=%b UUT_PCOUT=%b DIFF=%b", $time, REF_PCOUT, REF_OLD_PCOUT, PCOUT, REF_PCOUT ^ PCOUT);
 | |
| 				errcount = errcount + 1;
 | |
| 				ERROR_FLAG = 1;
 | |
| 			end
 | |
| 			if (REF_CARRYOUT !== CARRYOUT || (REF_OLD_CARRYOUT != CARRYOUT && !CARRYOUTREG)) begin
 | |
| 				$display("ERROR at %1t: REF_CARRYOUT=%b REF_OLD_CARRYOUT=%b UUT_CARRYOUT=%b DIFF=%b", $time, REF_CARRYOUT, REF_OLD_CARRYOUT, CARRYOUT, REF_CARRYOUT ^ CARRYOUT);
 | |
| 				errcount = errcount + 1;
 | |
| 				ERROR_FLAG = 1;
 | |
| 			end
 | |
| 			if (REF_CARRYOUTF !== CARRYOUTF) begin
 | |
| 				$display("ERROR at %1t: REF_CARRYOUTF=%b UUT_CARRYOUTF=%b", $time, REF_CARRYOUTF, CARRYOUTF);
 | |
| 				errcount = errcount + 1;
 | |
| 				ERROR_FLAG = 1;
 | |
| 			end
 | |
| 			#3;
 | |
| 		end
 | |
| 	endtask
 | |
| 
 | |
| 	reg config_valid = 0;
 | |
| 	task drc;
 | |
| 		begin
 | |
| 			config_valid = 1;
 | |
| 
 | |
| 			if (OPMODE[1:0] == 2'b10 && PREG != 1) config_valid = 0;
 | |
| 			if (OPMODE[3:2] == 2'b10 && PREG != 1) config_valid = 0;
 | |
| 		end
 | |
| 	endtask
 | |
| 
 | |
| 	initial begin
 | |
| 		$dumpfile("test_dsp48a1_model.vcd");
 | |
| 		$dumpvars(0, testbench);
 | |
| 
 | |
| 		#2;
 | |
| 		CLK = 1'b0;
 | |
| 		{CEA, CEB, CEC, CED, CEM, CEP, CECARRYIN, CEOPMODE} = 8'b11111111;
 | |
| 		{A, B, C, D, PCIN, OPMODE, CARRYIN} = 0;
 | |
| 		{RSTA, RSTB, RSTC, RSTD, RSTM, RSTP, RSTCARRYIN, RSTOPMODE} = 8'b11111111;
 | |
| 		repeat (10) begin
 | |
| 			#10;
 | |
| 			CLK = 1'b1;
 | |
| 			#10;
 | |
| 			CLK = 1'b0;
 | |
| 			#10;
 | |
| 			CLK = 1'b1;
 | |
| 			#10;
 | |
| 			CLK = 1'b0;
 | |
| 		end
 | |
| 		{RSTA, RSTB, RSTC, RSTD, RSTM, RSTP, RSTCARRYIN, RSTOPMODE} = 0;
 | |
| 
 | |
| 		repeat (10000) begin
 | |
| 			clkcycle;
 | |
| 			config_valid = 0;
 | |
| 			while (!config_valid) begin
 | |
| 				A = $urandom;
 | |
| 				B = $urandom;
 | |
| 				C = {$urandom, $urandom};
 | |
| 				D = $urandom;
 | |
| 				PCIN = {$urandom, $urandom};
 | |
| 
 | |
| 				{CEA, CEB, CEC, CED, CEM, CEP, CECARRYIN, CEOPMODE} = $urandom | $urandom | $urandom;
 | |
| 				{RSTA, RSTB, RSTC, RSTD, RSTM, RSTP, RSTCARRYIN, RSTOPMODE} = $urandom & $urandom & $urandom & $urandom & $urandom & $urandom;
 | |
| 				{CARRYIN, OPMODE} = $urandom;
 | |
| 
 | |
| 				drc;
 | |
| 			end
 | |
| 		end
 | |
| 
 | |
| 		if (errcount == 0) begin
 | |
| 			$display("All tests passed.");
 | |
| 			$finish;
 | |
| 		end else begin
 | |
| 			$display("Caught %1d errors.", errcount);
 | |
| 			$stop;
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	DSP48A #(
 | |
| 		.A0REG              (A0REG),
 | |
| 		.A1REG              (A1REG),
 | |
| 		.B0REG              (B0REG),
 | |
| 		.B1REG              (B1REG),
 | |
| 		.CREG               (CREG),
 | |
| 		.DREG               (DREG),
 | |
| 		.MREG               (MREG),
 | |
| 		.PREG               (PREG),
 | |
| 		.CARRYINREG         (CARRYINREG),
 | |
| 		.OPMODEREG          (OPMODEREG),
 | |
| 		.CARRYINSEL         (CARRYINSEL),
 | |
| 		.RSTTYPE            (RSTTYPE)
 | |
| 	) ref_old (
 | |
| 		.A             (A),
 | |
| 		.B             (B),
 | |
| 		.C             (C),
 | |
| 		.D             (D),
 | |
| 		.PCIN          (PCIN),
 | |
| 		.CARRYIN       (CARRYIN),
 | |
| 		.OPMODE        (OPMODE),
 | |
| 		.BCOUT         (REF_OLD_BCOUT),
 | |
| 		.CARRYOUT      (REF_OLD_CARRYOUT),
 | |
| 		.P             (REF_OLD_P),
 | |
| 		.PCOUT         (REF_OLD_PCOUT),
 | |
| 		.CEA           (CEA),
 | |
| 		.CEB           (CEB),
 | |
| 		.CEC           (CEC),
 | |
| 		.CED           (CED),
 | |
| 		.CEM           (CEM),
 | |
| 		.CEP           (CEP),
 | |
| 		.CECARRYIN     (CECARRYIN),
 | |
| 		.CEOPMODE      (CEOPMODE),
 | |
| 		.CLK           (CLK),
 | |
| 		.RSTA          (RSTA),
 | |
| 		.RSTB          (RSTB),
 | |
| 		.RSTC          (RSTC),
 | |
| 		.RSTD          (RSTD),
 | |
| 		.RSTM          (RSTM),
 | |
| 		.RSTP          (RSTP),
 | |
| 		.RSTCARRYIN    (RSTCARRYIN),
 | |
| 		.RSTOPMODE     (RSTOPMODE)
 | |
| 	);
 | |
| 
 | |
| 	DSP48A1 #(
 | |
| 		.A0REG              (A0REG),
 | |
| 		.A1REG              (A1REG),
 | |
| 		.B0REG              (B0REG),
 | |
| 		.B1REG              (B1REG),
 | |
| 		.CREG               (CREG),
 | |
| 		.DREG               (DREG),
 | |
| 		.MREG               (MREG),
 | |
| 		.PREG               (PREG),
 | |
| 		.CARRYINREG         (CARRYINREG),
 | |
| 		.CARRYOUTREG        (CARRYOUTREG),
 | |
| 		.OPMODEREG          (OPMODEREG),
 | |
| 		.CARRYINSEL         (CARRYINSEL),
 | |
| 		.RSTTYPE            (RSTTYPE)
 | |
| 	) ref (
 | |
| 		.A             (A),
 | |
| 		.B             (B),
 | |
| 		.C             (C),
 | |
| 		.D             (D),
 | |
| 		.PCIN          (PCIN),
 | |
| 		.CARRYIN       (CARRYIN),
 | |
| 		.OPMODE        (OPMODE),
 | |
| 		.BCOUT         (REF_BCOUT),
 | |
| 		.CARRYOUTF     (REF_CARRYOUTF),
 | |
| 		.CARRYOUT      (REF_CARRYOUT),
 | |
| 		.P             (REF_P),
 | |
| 		.M             (REF_M),
 | |
| 		.PCOUT         (REF_PCOUT),
 | |
| 		.CEA           (CEA),
 | |
| 		.CEB           (CEB),
 | |
| 		.CEC           (CEC),
 | |
| 		.CED           (CED),
 | |
| 		.CEM           (CEM),
 | |
| 		.CEP           (CEP),
 | |
| 		.CECARRYIN     (CECARRYIN),
 | |
| 		.CEOPMODE      (CEOPMODE),
 | |
| 		.CLK           (CLK),
 | |
| 		.RSTA          (RSTA),
 | |
| 		.RSTB          (RSTB),
 | |
| 		.RSTC          (RSTC),
 | |
| 		.RSTD          (RSTD),
 | |
| 		.RSTM          (RSTM),
 | |
| 		.RSTP          (RSTP),
 | |
| 		.RSTCARRYIN    (RSTCARRYIN),
 | |
| 		.RSTOPMODE     (RSTOPMODE)
 | |
| 	);
 | |
| 
 | |
| 	DSP48A1_UUT #(
 | |
| 		.A0REG              (A0REG),
 | |
| 		.A1REG              (A1REG),
 | |
| 		.B0REG              (B0REG),
 | |
| 		.B1REG              (B1REG),
 | |
| 		.CREG               (CREG),
 | |
| 		.DREG               (DREG),
 | |
| 		.MREG               (MREG),
 | |
| 		.PREG               (PREG),
 | |
| 		.CARRYINREG         (CARRYINREG),
 | |
| 		.CARRYOUTREG        (CARRYOUTREG),
 | |
| 		.OPMODEREG          (OPMODEREG),
 | |
| 		.CARRYINSEL         (CARRYINSEL),
 | |
| 		.RSTTYPE            (RSTTYPE)
 | |
| 	) uut (
 | |
| 		.A             (A),
 | |
| 		.B             (B),
 | |
| 		.C             (C),
 | |
| 		.D             (D),
 | |
| 		.PCIN          (PCIN),
 | |
| 		.CARRYIN       (CARRYIN),
 | |
| 		.OPMODE        (OPMODE),
 | |
| 		.BCOUT         (BCOUT),
 | |
| 		.CARRYOUTF     (CARRYOUTF),
 | |
| 		.CARRYOUT      (CARRYOUT),
 | |
| 		.P             (P),
 | |
| 		.M             (M),
 | |
| 		.PCOUT         (PCOUT),
 | |
| 		.CEA           (CEA),
 | |
| 		.CEB           (CEB),
 | |
| 		.CEC           (CEC),
 | |
| 		.CED           (CED),
 | |
| 		.CEM           (CEM),
 | |
| 		.CEP           (CEP),
 | |
| 		.CECARRYIN     (CECARRYIN),
 | |
| 		.CEOPMODE      (CEOPMODE),
 | |
| 		.CLK           (CLK),
 | |
| 		.RSTA          (RSTA),
 | |
| 		.RSTB          (RSTB),
 | |
| 		.RSTC          (RSTC),
 | |
| 		.RSTD          (RSTD),
 | |
| 		.RSTM          (RSTM),
 | |
| 		.RSTP          (RSTP),
 | |
| 		.RSTCARRYIN    (RSTCARRYIN),
 | |
| 		.RSTOPMODE     (RSTOPMODE)
 | |
| 	);
 | |
| endmodule
 | |
| 
 | |
| module mult_noreg;
 | |
| 	testbench #(
 | |
| 		.A0REG              (0),
 | |
| 		.A1REG              (0),
 | |
| 		.B0REG              (0),
 | |
| 		.B1REG              (0),
 | |
| 		.CREG               (0),
 | |
| 		.DREG               (0),
 | |
| 		.MREG               (0),
 | |
| 		.PREG               (0),
 | |
| 		.CARRYINREG         (0),
 | |
| 		.CARRYOUTREG        (0),
 | |
| 		.OPMODEREG          (0),
 | |
| 		.CARRYINSEL         ("CARRYIN"),
 | |
| 		.RSTTYPE            ("SYNC")
 | |
| 	) testbench ();
 | |
| endmodule
 | |
| 
 | |
| module mult_allreg;
 | |
| 	testbench #(
 | |
| 		.A0REG              (1),
 | |
| 		.A1REG              (1),
 | |
| 		.B0REG              (1),
 | |
| 		.B1REG              (1),
 | |
| 		.CREG               (1),
 | |
| 		.DREG               (1),
 | |
| 		.MREG               (1),
 | |
| 		.PREG               (1),
 | |
| 		.CARRYINREG         (1),
 | |
| 		.CARRYOUTREG        (1),
 | |
| 		.OPMODEREG          (1),
 | |
| 		.CARRYINSEL         ("OPMODE5"),
 | |
| 		.RSTTYPE            ("SYNC")
 | |
| 	) testbench ();
 | |
| endmodule
 | |
| 
 | |
| module mult_inreg;
 | |
| 	testbench #(
 | |
| 		.A0REG              (1),
 | |
| 		.A1REG              (1),
 | |
| 		.B0REG              (1),
 | |
| 		.B1REG              (1),
 | |
| 		.CREG               (1),
 | |
| 		.DREG               (1),
 | |
| 		.MREG               (0),
 | |
| 		.PREG               (0),
 | |
| 		.CARRYINREG         (1),
 | |
| 		.CARRYOUTREG        (0),
 | |
| 		.OPMODEREG          (0),
 | |
| 		.CARRYINSEL         ("CARRYIN"),
 | |
| 		.RSTTYPE            ("SYNC")
 | |
| 	) testbench ();
 | |
| endmodule
 |