// Regs B and D
reg [15:0] rB, rD;
- always @(posedge clock, posedge IRSTTOP) begin
+ always @(posedge clock, posedge IRSTBOT) begin
if (IRSTBOT) begin
rB <= 0;
rD <= 0;
// Multiplier Stage
wire [15:0] p_Ah_Bh, p_Al_Bh, p_Ah_Bl, p_Al_Bl;
wire [15:0] Ah, Al, Bh, Bl;
- assign Ah = A_SIGNED ? {{8{iA[15]}}, iA[15: 8]} : iA[15: 8];
- assign Al = A_SIGNED ? {{8{iA[ 7]}}, iA[ 7: 0]} : iA[15: 8];
- assign Bh = B_SIGNED ? {{8{iB[15]}}, iB[15: 8]} : iB[15: 8];
- assign Bl = B_SIGNED ? {{8{iB[ 7]}}, iB[ 7: 0]} : iB[15: 8];
+ assign Ah = {A_SIGNED ? {8{iA[15]}} : 8'b0, iA[15: 8]};
+ assign Al = {A_SIGNED ? {8{iA[ 7]}} : 8'b0, iA[ 7: 0]};
+ assign Bh = {B_SIGNED ? {8{iB[15]}} : 8'b0, iB[15: 8]};
+ assign Bl = {B_SIGNED ? {8{iB[ 7]}} : 8'b0, iB[ 7: 0]};
assign p_Ah_Bh = Ah * Bh;
assign p_Al_Bh = Al * Bh;
assign p_Ah_Bl = Ah * Bl;
assign iG = BOT_8x8_MULT_REG ? rG : p_Al_Bl;
// Adder Stage
- reg [31:0] P;
- always @* begin
- P = iG[7:0];
- P = P + (iG[15:8] + iK[7:0]) << 8;
- P = P + (iK[15:8] + iJ[7:0]) << 16;
- P = P + (iJ[15:8] + iF[7:0]) << 24;
- end
- assign iL = P;
+ assign iL = iG + (iK << 8) + (iJ << 8) + (iF << 16);
// Reg H
- reg [15:0] rH;
+ reg [31:0] rH;
always @(posedge clock, posedge IRSTBOT) begin
if (IRSTBOT) begin
rH <= 0;
// Hi Output Stage
wire [15:0] XW, Oh;
reg [15:0] rQ;
- assign iW = TOPADDSUB_UPPERINPUT ? iC : iQ[31:16];
+ assign iW = TOPADDSUB_UPPERINPUT ? iC : iQ;
assign iX = (TOPADDSUB_LOWERINPUT == 0) ? iA : (TOPADDSUB_LOWERINPUT == 1) ? iF : (TOPADDSUB_LOWERINPUT == 2) ? iH[31:16] : {16{iZ[15]}};
assign {ACCUMCO, XW} = iX + (iW ^ {16{ADDSUBTOP}}) + HCI;
assign CO = ACCUMCO ^ ADDSUBTOP;
// Lo Output Stage
wire [15:0] YZ, Ol;
reg [15:0] rS;
- assign iY = BOTADDSUB_UPPERINPUT ? iD : iQ[15:0];
+ assign iY = BOTADDSUB_UPPERINPUT ? iD : iS;
assign iZ = (BOTADDSUB_LOWERINPUT == 0) ? iB : (BOTADDSUB_LOWERINPUT == 1) ? iG : (BOTADDSUB_LOWERINPUT == 2) ? iH[15:0] : {16{SIGNEXTIN}};
assign {LCO, YZ} = iZ + (iY ^ {16{ADDSUBBOT}}) + LCI;
assign iR = OLOADBOT ? iD : YZ ^ {16{ADDSUBBOT}};
if (ORSTBOT) begin
rS <= 0;
end else if (CE) begin
- if (!OHOLDTOP) rS <= iR;
+ if (!OHOLDBOT) rS <= iR;
end
end
assign iS = rS;
parameter [0:0] PIPELINE_16x16_MULT_REG1 = 0;
parameter [0:0] PIPELINE_16x16_MULT_REG2 = 0;
parameter [1:0] TOPOUTPUT_SELECT = 0;
- parameter [1:0] TOPADDSUB_LOWERINPUT = 2;
+ parameter [1:0] TOPADDSUB_LOWERINPUT = 0;
parameter [0:0] TOPADDSUB_UPPERINPUT = 1;
- parameter [1:0] TOPADDSUB_CARRYSELECT = 2;
+ parameter [1:0] TOPADDSUB_CARRYSELECT = 0;
parameter [1:0] BOTOUTPUT_SELECT = 0;
- parameter [1:0] BOTADDSUB_LOWERINPUT = 2;
+ parameter [1:0] BOTADDSUB_LOWERINPUT = 0;
parameter [0:0] BOTADDSUB_UPPERINPUT = 1;
- parameter [1:0] BOTADDSUB_CARRYSELECT = 2;
+ parameter [1:0] BOTADDSUB_CARRYSELECT = 0;
parameter [0:0] MODE_8x8 = 0;
parameter [0:0] A_SIGNED = 0;
parameter [0:0] B_SIGNED = 0;
CLK = ~CLK;
#2;
if (REF_O !== UUT_O) begin
- $display("ERROR at %1t: REF_O=%b UUT_O=%b", $time, REF_O, UUT_O);
+ $display("ERROR at %1t: REF_O=%b UUT_O=%b DIFF=%b", $time, REF_O, UUT_O, REF_O ^ UUT_O);
errcount = errcount + 1;
end
if (REF_CO !== UUT_CO) begin
$dumpfile("test_dsp_model.vcd");
$dumpvars(0, testbench);
- #5;
+ #2;
CLK = NEG_TRIGGER;
CE = 1;
{C, A, B, D} = 0;
{AHOLD, BHOLD, CHOLD, DHOLD} = 0;
- {IRSTTOP, IRSTBOT} = 0;
- {ORSTTOP, ORSTBOT} = 0;
{OLOADTOP, OLOADBOT} = 0;
{ADDSUBTOP, ADDSUBBOT} = 0;
{OHOLDTOP, OHOLDBOT} = 0;
{CI, ACCUMCI, SIGNEXTIN} = 0;
- // C = 10;
- // A = 15;
- // B = 22;
- // D = 27;
+ {IRSTTOP, IRSTBOT} = ~0;
+ {ORSTTOP, ORSTBOT} = ~0;
+
+ #3;
+ {IRSTTOP, IRSTBOT} = 0;
+ {ORSTTOP, ORSTBOT} = 0;
+
+ repeat (300) begin
+ clkcycle;
+
+ A = $urandom;
+ B = $urandom;
+ C = $urandom;
+ D = $urandom;
- repeat (10) clkcycle;
+ {AHOLD, BHOLD, CHOLD, DHOLD} = $urandom & $urandom & $urandom;
+ {OLOADTOP, OLOADBOT} = $urandom & $urandom & $urandom;
+ {ADDSUBTOP, ADDSUBBOT} = $urandom & $urandom & $urandom;
+ {OHOLDTOP, OHOLDBOT} = $urandom & $urandom & $urandom;
+ {CI, ACCUMCI, SIGNEXTIN} = $urandom & $urandom & $urandom;
+
+ {IRSTTOP, IRSTBOT} = $urandom & $urandom & $urandom;
+ {ORSTTOP, ORSTBOT} = $urandom & $urandom & $urandom;
+ end
if (errcount == 0) begin
$display("All tests passed.");
+ $finish;
end else begin
$display("Caught %1d errors.", errcount);
+ $stop;
end
end
.SIGNEXTOUT (UUT_SIGNEXTOUT)
);
endmodule
+
+module testbench_comb_8x8_A;
+ testbench #(
+ .NEG_TRIGGER (0),
+ .C_REG (0),
+ .A_REG (0),
+ .B_REG (0),
+ .D_REG (0),
+ .TOP_8x8_MULT_REG (0),
+ .BOT_8x8_MULT_REG (0),
+ .PIPELINE_16x16_MULT_REG1 (0),
+ .PIPELINE_16x16_MULT_REG2 (0),
+ .TOPOUTPUT_SELECT (2), // 0=P, 1=Q, 2=8x8, 3=16x16
+ .TOPADDSUB_LOWERINPUT (0), // 0=A, 1=8x8, 2=16x16, 3=S-EXT
+ .TOPADDSUB_UPPERINPUT (0), // 0=Q, 1=C
+ .TOPADDSUB_CARRYSELECT (0), // 0=0, 1=1, 2=ACI, 3=CI
+ .BOTOUTPUT_SELECT (2), // 0=R, 1=S, 2=8x8, 3=16x16
+ .BOTADDSUB_LOWERINPUT (0), // 0=B, 1=8x8, 2=16x16, 3=S-EXT
+ .BOTADDSUB_UPPERINPUT (0), // 0=S, 1=D
+ .BOTADDSUB_CARRYSELECT (0), // 0=0, 1=1, 2=ACI, 3=CI
+ .MODE_8x8 (0),
+ .A_SIGNED (0),
+ .B_SIGNED (0)
+ ) testbench ();
+endmodule
+
+module testbench_comb_8x8_B;
+ testbench #(
+ .NEG_TRIGGER (0),
+ .C_REG (0),
+ .A_REG (0),
+ .B_REG (0),
+ .D_REG (0),
+ .TOP_8x8_MULT_REG (0),
+ .BOT_8x8_MULT_REG (0),
+ .PIPELINE_16x16_MULT_REG1 (0),
+ .PIPELINE_16x16_MULT_REG2 (0),
+ .TOPOUTPUT_SELECT (0), // 0=P, 1=Q, 2=8x8, 3=16x16
+ .TOPADDSUB_LOWERINPUT (1), // 0=A, 1=8x8, 2=16x16, 3=S-EXT
+ .TOPADDSUB_UPPERINPUT (1), // 0=Q, 1=C
+ .TOPADDSUB_CARRYSELECT (0), // 0=0, 1=1, 2=ACI, 3=CI
+ .BOTOUTPUT_SELECT (0), // 0=R, 1=S, 2=8x8, 3=16x16
+ .BOTADDSUB_LOWERINPUT (1), // 0=B, 1=8x8, 2=16x16, 3=S-EXT
+ .BOTADDSUB_UPPERINPUT (1), // 0=S, 1=D
+ .BOTADDSUB_CARRYSELECT (0), // 0=0, 1=1, 2=ACI, 3=CI
+ .MODE_8x8 (0),
+ .A_SIGNED (0),
+ .B_SIGNED (0)
+ ) testbench ();
+endmodule
+
+module testbench_comb_16x16;
+ testbench #(
+ .NEG_TRIGGER (0),
+ .C_REG (0),
+ .A_REG (0),
+ .B_REG (0),
+ .D_REG (0),
+ .TOP_8x8_MULT_REG (0),
+ .BOT_8x8_MULT_REG (0),
+ .PIPELINE_16x16_MULT_REG1 (0),
+ .PIPELINE_16x16_MULT_REG2 (0),
+ .TOPOUTPUT_SELECT (0), // 0=P, 1=Q, 2=8x8, 3=16x16
+ .TOPADDSUB_LOWERINPUT (2), // 0=A, 1=8x8, 2=16x16, 3=S-EXT
+ .TOPADDSUB_UPPERINPUT (1), // 0=Q, 1=C
+ .TOPADDSUB_CARRYSELECT (2), // 0=0, 1=1, 2=ACI, 3=CI
+ .BOTOUTPUT_SELECT (0), // 0=R, 1=S, 2=8x8, 3=16x16
+ .BOTADDSUB_LOWERINPUT (2), // 0=B, 1=8x8, 2=16x16, 3=S-EXT
+ .BOTADDSUB_UPPERINPUT (1), // 0=S, 1=D
+ .BOTADDSUB_CARRYSELECT (2), // 0=0, 1=1, 2=ACI, 3=CI
+ .MODE_8x8 (0),
+ .A_SIGNED (0),
+ .B_SIGNED (0)
+ ) testbench ();
+endmodule
+
+module testbench_seq_16x16_A;
+ testbench #(
+ .NEG_TRIGGER (0),
+ .C_REG (1),
+ .A_REG (1),
+ .B_REG (1),
+ .D_REG (1),
+ .TOP_8x8_MULT_REG (1),
+ .BOT_8x8_MULT_REG (1),
+ .PIPELINE_16x16_MULT_REG1 (1),
+ .PIPELINE_16x16_MULT_REG2 (1),
+ .TOPOUTPUT_SELECT (0), // 0=P, 1=Q, 2=8x8, 3=16x16
+ .TOPADDSUB_LOWERINPUT (2), // 0=A, 1=8x8, 2=16x16, 3=S-EXT
+ .TOPADDSUB_UPPERINPUT (1), // 0=Q, 1=C
+ .TOPADDSUB_CARRYSELECT (2), // 0=0, 1=1, 2=ACI, 3=CI
+ .BOTOUTPUT_SELECT (0), // 0=R, 1=S, 2=8x8, 3=16x16
+ .BOTADDSUB_LOWERINPUT (2), // 0=B, 1=8x8, 2=16x16, 3=S-EXT
+ .BOTADDSUB_UPPERINPUT (1), // 0=S, 1=D
+ .BOTADDSUB_CARRYSELECT (2), // 0=0, 1=1, 2=ACI, 3=CI
+ .MODE_8x8 (0),
+ .A_SIGNED (0),
+ .B_SIGNED (0)
+ ) testbench ();
+endmodule
+
+module testbench_seq_16x16_B;
+ testbench #(
+ .NEG_TRIGGER (0),
+ .C_REG (1),
+ .A_REG (1),
+ .B_REG (1),
+ .D_REG (1),
+ .TOP_8x8_MULT_REG (1),
+ .BOT_8x8_MULT_REG (1),
+ .PIPELINE_16x16_MULT_REG1 (1),
+ .PIPELINE_16x16_MULT_REG2 (0),
+ .TOPOUTPUT_SELECT (1), // 0=P, 1=Q, 2=8x8, 3=16x16
+ .TOPADDSUB_LOWERINPUT (2), // 0=A, 1=8x8, 2=16x16, 3=S-EXT
+ .TOPADDSUB_UPPERINPUT (0), // 0=Q, 1=C
+ .TOPADDSUB_CARRYSELECT (2), // 0=0, 1=1, 2=ACI, 3=CI
+ .BOTOUTPUT_SELECT (1), // 0=R, 1=S, 2=8x8, 3=16x16
+ .BOTADDSUB_LOWERINPUT (2), // 0=B, 1=8x8, 2=16x16, 3=S-EXT
+ .BOTADDSUB_UPPERINPUT (0), // 0=S, 1=D
+ .BOTADDSUB_CARRYSELECT (2), // 0=0, 1=1, 2=ACI, 3=CI
+ .MODE_8x8 (0),
+ .A_SIGNED (0),
+ .B_SIGNED (0)
+ ) testbench ();
+endmodule