mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-24 01:25:33 +00:00
Merge remote-tracking branch 'origin/master' into xaig
This commit is contained in:
commit
a8803a1519
16 changed files with 1874 additions and 63 deletions
|
@ -886,59 +886,6 @@ module SB_WARMBOOT (
|
|||
);
|
||||
endmodule
|
||||
|
||||
// UltraPlus feature cells
|
||||
(* blackbox *)
|
||||
module SB_MAC16 (
|
||||
input CLK,
|
||||
input CE,
|
||||
input [15:0] C,
|
||||
input [15:0] A,
|
||||
input [15:0] B,
|
||||
input [15:0] D,
|
||||
input AHOLD,
|
||||
input BHOLD,
|
||||
input CHOLD,
|
||||
input DHOLD,
|
||||
input IRSTTOP,
|
||||
input IRSTBOT,
|
||||
input ORSTTOP,
|
||||
input ORSTBOT,
|
||||
input OLOADTOP,
|
||||
input OLOADBOT,
|
||||
input ADDSUBTOP,
|
||||
input ADDSUBBOT,
|
||||
input OHOLDTOP,
|
||||
input OHOLDBOT,
|
||||
input CI,
|
||||
input ACCUMCI,
|
||||
input SIGNEXTIN,
|
||||
output [31:0] O,
|
||||
output CO,
|
||||
output ACCUMCO,
|
||||
output SIGNEXTOUT
|
||||
);
|
||||
parameter NEG_TRIGGER = 1'b0;
|
||||
parameter C_REG = 1'b0;
|
||||
parameter A_REG = 1'b0;
|
||||
parameter B_REG = 1'b0;
|
||||
parameter D_REG = 1'b0;
|
||||
parameter TOP_8x8_MULT_REG = 1'b0;
|
||||
parameter BOT_8x8_MULT_REG = 1'b0;
|
||||
parameter PIPELINE_16x16_MULT_REG1 = 1'b0;
|
||||
parameter PIPELINE_16x16_MULT_REG2 = 1'b0;
|
||||
parameter TOPOUTPUT_SELECT = 2'b00;
|
||||
parameter TOPADDSUB_LOWERINPUT = 2'b00;
|
||||
parameter TOPADDSUB_UPPERINPUT = 1'b0;
|
||||
parameter TOPADDSUB_CARRYSELECT = 2'b00;
|
||||
parameter BOTOUTPUT_SELECT = 2'b00;
|
||||
parameter BOTADDSUB_LOWERINPUT = 2'b00;
|
||||
parameter BOTADDSUB_UPPERINPUT = 1'b0;
|
||||
parameter BOTADDSUB_CARRYSELECT = 2'b00;
|
||||
parameter MODE_8x8 = 1'b0;
|
||||
parameter A_SIGNED = 1'b0;
|
||||
parameter B_SIGNED = 1'b0;
|
||||
endmodule
|
||||
|
||||
module SB_SPRAM256KA (
|
||||
input [13:0] ADDRESS,
|
||||
input [15:0] DATAIN,
|
||||
|
@ -1273,3 +1220,171 @@ module SB_IO_OD (
|
|||
endgenerate
|
||||
`endif
|
||||
endmodule
|
||||
|
||||
module SB_MAC16 (
|
||||
input CLK, CE,
|
||||
input [15:0] C, A, B, D,
|
||||
input AHOLD, BHOLD, CHOLD, DHOLD,
|
||||
input IRSTTOP, IRSTBOT,
|
||||
input ORSTTOP, ORSTBOT,
|
||||
input OLOADTOP, OLOADBOT,
|
||||
input ADDSUBTOP, ADDSUBBOT,
|
||||
input OHOLDTOP, OHOLDBOT,
|
||||
input CI, ACCUMCI, SIGNEXTIN,
|
||||
output [31:0] O,
|
||||
output CO, ACCUMCO, SIGNEXTOUT
|
||||
);
|
||||
parameter [0:0] NEG_TRIGGER = 0;
|
||||
parameter [0:0] C_REG = 0;
|
||||
parameter [0:0] A_REG = 0;
|
||||
parameter [0:0] B_REG = 0;
|
||||
parameter [0:0] D_REG = 0;
|
||||
parameter [0:0] TOP_8x8_MULT_REG = 0;
|
||||
parameter [0:0] BOT_8x8_MULT_REG = 0;
|
||||
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 = 0;
|
||||
parameter [0:0] TOPADDSUB_UPPERINPUT = 0;
|
||||
parameter [1:0] TOPADDSUB_CARRYSELECT = 0;
|
||||
parameter [1:0] BOTOUTPUT_SELECT = 0;
|
||||
parameter [1:0] BOTADDSUB_LOWERINPUT = 0;
|
||||
parameter [0:0] BOTADDSUB_UPPERINPUT = 0;
|
||||
parameter [1:0] BOTADDSUB_CARRYSELECT = 0;
|
||||
parameter [0:0] MODE_8x8 = 0;
|
||||
parameter [0:0] A_SIGNED = 0;
|
||||
parameter [0:0] B_SIGNED = 0;
|
||||
|
||||
wire clock = CLK ^ NEG_TRIGGER;
|
||||
|
||||
// internal wires, compare Figure on page 133 of ICE Technology Library 3.0 and Fig 2 on page 2 of Lattice TN1295-DSP
|
||||
// http://www.latticesemi.com/~/media/LatticeSemi/Documents/TechnicalBriefs/SBTICETechnologyLibrary201608.pdf
|
||||
// https://www.latticesemi.com/-/media/LatticeSemi/Documents/ApplicationNotes/AD/DSPFunctionUsageGuideforICE40Devices.ashx
|
||||
wire [15:0] iA, iB, iC, iD;
|
||||
wire [15:0] iF, iJ, iK, iG;
|
||||
wire [31:0] iL, iH;
|
||||
wire [15:0] iW, iX, iP, iQ;
|
||||
wire [15:0] iY, iZ, iR, iS;
|
||||
wire HCI, LCI, LCO;
|
||||
|
||||
// Regs C and A
|
||||
reg [15:0] rC, rA;
|
||||
always @(posedge clock, posedge IRSTTOP) begin
|
||||
if (IRSTTOP) begin
|
||||
rC <= 0;
|
||||
rA <= 0;
|
||||
end else if (CE) begin
|
||||
if (!CHOLD) rC <= C;
|
||||
if (!AHOLD) rA <= A;
|
||||
end
|
||||
end
|
||||
assign iC = C_REG ? rC : C;
|
||||
assign iA = A_REG ? rA : A;
|
||||
|
||||
// Regs B and D
|
||||
reg [15:0] rB, rD;
|
||||
always @(posedge clock, posedge IRSTBOT) begin
|
||||
if (IRSTBOT) begin
|
||||
rB <= 0;
|
||||
rD <= 0;
|
||||
end else if (CE) begin
|
||||
if (!BHOLD) rB <= B;
|
||||
if (!DHOLD) rD <= D;
|
||||
end
|
||||
end
|
||||
assign iB = B_REG ? rB : B;
|
||||
assign iD = D_REG ? rD : D;
|
||||
|
||||
// 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]}} : 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 p_Al_Bl = Al * Bl;
|
||||
|
||||
// Regs F and J
|
||||
reg [15:0] rF, rJ;
|
||||
always @(posedge clock, posedge IRSTTOP) begin
|
||||
if (IRSTTOP) begin
|
||||
rF <= 0;
|
||||
rJ <= 0;
|
||||
end else if (CE) begin
|
||||
rF <= p_Ah_Bh;
|
||||
if (!MODE_8x8) rJ <= p_Al_Bh;
|
||||
end
|
||||
end
|
||||
assign iF = TOP_8x8_MULT_REG ? rF : p_Ah_Bh;
|
||||
assign iJ = PIPELINE_16x16_MULT_REG1 ? rJ : p_Al_Bh;
|
||||
|
||||
// Regs K and G
|
||||
reg [15:0] rK, rG;
|
||||
always @(posedge clock, posedge IRSTBOT) begin
|
||||
if (IRSTBOT) begin
|
||||
rK <= 0;
|
||||
rG <= 0;
|
||||
end else if (CE) begin
|
||||
if (!MODE_8x8) rK <= p_Ah_Bl;
|
||||
rG <= p_Al_Bl;
|
||||
end
|
||||
end
|
||||
assign iK = PIPELINE_16x16_MULT_REG1 ? rK : p_Ah_Bl;
|
||||
assign iG = BOT_8x8_MULT_REG ? rG : p_Al_Bl;
|
||||
|
||||
// Adder Stage
|
||||
assign iL = iG + (iK << 8) + (iJ << 8) + (iF << 16);
|
||||
|
||||
// Reg H
|
||||
reg [31:0] rH;
|
||||
always @(posedge clock, posedge IRSTBOT) begin
|
||||
if (IRSTBOT) begin
|
||||
rH <= 0;
|
||||
end else if (CE) begin
|
||||
if (!MODE_8x8) rH <= iL;
|
||||
end
|
||||
end
|
||||
assign iH = PIPELINE_16x16_MULT_REG2 ? rH : iL;
|
||||
|
||||
// Hi Output Stage
|
||||
wire [15:0] XW, Oh;
|
||||
reg [15:0] rQ;
|
||||
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;
|
||||
assign iP = OLOADTOP ? iC : XW ^ {16{ADDSUBTOP}};
|
||||
always @(posedge clock, posedge ORSTTOP) begin
|
||||
if (ORSTTOP) begin
|
||||
rQ <= 0;
|
||||
end else if (CE) begin
|
||||
if (!OHOLDTOP) rQ <= iP;
|
||||
end
|
||||
end
|
||||
assign iQ = rQ;
|
||||
assign Oh = (TOPOUTPUT_SELECT == 0) ? iP : (TOPOUTPUT_SELECT == 1) ? iQ : (TOPOUTPUT_SELECT == 2) ? iF : iH[31:16];
|
||||
assign HCI = (TOPADDSUB_CARRYSELECT == 0) ? 1'b0 : (TOPADDSUB_CARRYSELECT == 1) ? 1'b1 : (TOPADDSUB_CARRYSELECT == 2) ? LCO : LCO ^ ADDSUBBOT;
|
||||
assign SIGNEXTOUT = iX[15];
|
||||
|
||||
// Lo Output Stage
|
||||
wire [15:0] YZ, Ol;
|
||||
reg [15:0] rS;
|
||||
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}};
|
||||
always @(posedge clock, posedge ORSTBOT) begin
|
||||
if (ORSTBOT) begin
|
||||
rS <= 0;
|
||||
end else if (CE) begin
|
||||
if (!OHOLDBOT) rS <= iR;
|
||||
end
|
||||
end
|
||||
assign iS = rS;
|
||||
assign Ol = (BOTOUTPUT_SELECT == 0) ? iR : (BOTOUTPUT_SELECT == 1) ? iS : (BOTOUTPUT_SELECT == 2) ? iG : iH[15:0];
|
||||
assign LCI = (BOTADDSUB_CARRYSELECT == 0) ? 1'b0 : (BOTADDSUB_CARRYSELECT == 1) ? 1'b1 : (BOTADDSUB_CARRYSELECT == 2) ? ACCUMCI : CI;
|
||||
assign O = {Oh, Ol};
|
||||
endmodule
|
||||
|
|
|
@ -79,6 +79,9 @@ struct SynthIce40Pass : public ScriptPass
|
|||
log(" -nobram\n");
|
||||
log(" do not use SB_RAM40_4K* cells in output netlist\n");
|
||||
log("\n");
|
||||
log(" -dsp\n");
|
||||
log(" use iCE40 UltraPlus DSP cells for large arithmetic\n");
|
||||
log("\n");
|
||||
log(" -noabc\n");
|
||||
log(" use built-in Yosys LUT techmapping instead of abc\n");
|
||||
log("\n");
|
||||
|
@ -98,8 +101,9 @@ struct SynthIce40Pass : public ScriptPass
|
|||
log("\n");
|
||||
}
|
||||
|
||||
|
||||
string top_opt, blif_file, edif_file, json_file, abc;
|
||||
bool nocarry, nodffe, nobram, flatten, retime, relut, noabc, abc2, vpr;
|
||||
bool nocarry, nodffe, nobram, dsp, flatten, retime, relut, noabc, abc2, vpr;
|
||||
int min_ce_use;
|
||||
|
||||
void clear_flags() YS_OVERRIDE
|
||||
|
@ -112,6 +116,7 @@ struct SynthIce40Pass : public ScriptPass
|
|||
nodffe = false;
|
||||
min_ce_use = -1;
|
||||
nobram = false;
|
||||
dsp = false;
|
||||
flatten = true;
|
||||
retime = false;
|
||||
relut = false;
|
||||
|
@ -185,6 +190,10 @@ struct SynthIce40Pass : public ScriptPass
|
|||
nobram = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-dsp") {
|
||||
dsp = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-noabc") {
|
||||
noabc = true;
|
||||
continue;
|
||||
|
@ -222,11 +231,11 @@ struct SynthIce40Pass : public ScriptPass
|
|||
{
|
||||
run("read_verilog -lib +/ice40/cells_sim.v");
|
||||
run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
|
||||
run("proc");
|
||||
}
|
||||
|
||||
if (flatten && check_label("flatten", "(unless -noflatten)"))
|
||||
{
|
||||
run("proc");
|
||||
run("flatten");
|
||||
run("tribuf -logic");
|
||||
run("deminout");
|
||||
|
@ -234,7 +243,23 @@ struct SynthIce40Pass : public ScriptPass
|
|||
|
||||
if (check_label("coarse"))
|
||||
{
|
||||
run("synth -lut 4 -run coarse");
|
||||
run("opt_expr");
|
||||
run("opt_clean");
|
||||
run("check");
|
||||
run("opt");
|
||||
run("wreduce");
|
||||
run("share");
|
||||
run("techmap -map +/cmp2lut.v -D LUT_WIDTH=4");
|
||||
run("opt_expr");
|
||||
run("opt_clean");
|
||||
if (help_mode || dsp)
|
||||
run("ice40_dsp", "(if -dsp)");
|
||||
run("alumacc");
|
||||
run("opt");
|
||||
run("fsm");
|
||||
run("opt -fast");
|
||||
run("memory -nomap");
|
||||
run("opt_clean");
|
||||
}
|
||||
|
||||
if (!nobram && check_label("bram", "(skip if -nobram)"))
|
||||
|
|
13
techlibs/ice40/tests/.gitignore
vendored
13
techlibs/ice40/tests/.gitignore
vendored
|
@ -1,2 +1,11 @@
|
|||
test_ffs_[01][01][01][01][01]_*
|
||||
test_bram_[0-9]*
|
||||
/test_ffs_[01][01][01][01][01]_*
|
||||
/test_bram_[0-9]*
|
||||
/test_dsp_model
|
||||
/test_dsp_model.vcd
|
||||
/test_dsp_model_ref.v
|
||||
/test_dsp_model_uut.v
|
||||
/test_dsp_map
|
||||
/test_dsp_map.vcd
|
||||
/test_dsp_map_tb.v
|
||||
/test_dsp_map_top.v
|
||||
/test_dsp_map_syn.v
|
||||
|
|
107
techlibs/ice40/tests/test_dsp_map.sh
Normal file
107
techlibs/ice40/tests/test_dsp_map.sh
Normal file
|
@ -0,0 +1,107 @@
|
|||
#!/bin/bash
|
||||
set -ex
|
||||
|
||||
for iter in {1..100}
|
||||
do
|
||||
SZA=$(( 3 + $RANDOM % 13 ))
|
||||
SZB=$(( 3 + $RANDOM % 13 ))
|
||||
SZO=$(( 3 + $RANDOM % 29 ))
|
||||
|
||||
C0=clk$(( $RANDOM & 1))
|
||||
C1=clk$(( $RANDOM & 1))
|
||||
C2=clk$(( $RANDOM & 1))
|
||||
C3=clk$(( $RANDOM & 1))
|
||||
|
||||
E0=$( test $(( $RANDOM & 1 )) -eq 0 && echo posedge || echo negedge )
|
||||
E1=$( test $(( $RANDOM & 1 )) -eq 0 && echo posedge || echo negedge )
|
||||
E2=$( test $(( $RANDOM & 1 )) -eq 0 && echo posedge || echo negedge )
|
||||
E3=$( test $(( $RANDOM & 1 )) -eq 0 && echo posedge || echo negedge )
|
||||
|
||||
SP=$( test $(( $RANDOM & 1 )) -eq 0 && echo S || echo P )
|
||||
|
||||
RC=$( test $(( $RANDOM & 1 )) -eq 0 && echo "reset" || echo "!reset" )
|
||||
RV="32'h$( echo $RANDOM | md5sum | cut -c1-8 )"
|
||||
|
||||
cat > test_dsp_map_top.v << EOT
|
||||
module top (
|
||||
input clk0, clk1, reset,
|
||||
input [$SZA:0] A,
|
||||
input [$SZB:0] B,
|
||||
output [$SZO:0] O
|
||||
);
|
||||
reg [15:0] AA, BB;
|
||||
reg [31:0] P, S;
|
||||
|
||||
always @($E0 $C0) AA <= A;
|
||||
always @($E1 $C1) BB <= B;
|
||||
always @($E2 $C2) P <= AA * BB;
|
||||
always @($E3 $C3) S <= $RC ? $RV : S + P;
|
||||
assign O = $SP;
|
||||
endmodule
|
||||
EOT
|
||||
|
||||
cat > test_dsp_map_tb.v << EOT
|
||||
\`timescale 1ns / 1ps
|
||||
module testbench;
|
||||
reg clk1, clk0, reset;
|
||||
reg [$SZA:0] A;
|
||||
reg [$SZB:0] B;
|
||||
|
||||
wire [$SZO:0] O_top, O_syn;
|
||||
|
||||
top top_inst (.clk0(clk0), .clk1(clk1), .reset(reset), .A(A), .B(B), .O(O_top));
|
||||
syn syn_inst (.clk0(clk0), .clk1(clk1), .reset(reset), .A(A), .B(B), .O(O_syn));
|
||||
|
||||
initial begin
|
||||
// \$dumpfile("test_dsp_map.vcd");
|
||||
// \$dumpvars(0, testbench);
|
||||
|
||||
#2;
|
||||
clk0 = 0;
|
||||
clk1 = 0;
|
||||
reset = 1;
|
||||
reset = $RC;
|
||||
A = 0;
|
||||
B = 0;
|
||||
|
||||
repeat (3) begin
|
||||
#2; clk0 = ~clk0;
|
||||
#2; clk0 = ~clk0;
|
||||
#2; clk1 = ~clk1;
|
||||
#2; clk1 = ~clk1;
|
||||
end
|
||||
|
||||
repeat (100) begin
|
||||
#2;
|
||||
A = \$urandom;
|
||||
B = \$urandom;
|
||||
reset = \$urandom & \$urandom & \$urandom & \$urandom;
|
||||
if (\$urandom & 1) begin
|
||||
#2; clk0 = ~clk0;
|
||||
#2; clk0 = ~clk0;
|
||||
end else begin
|
||||
#2; clk1 = ~clk1;
|
||||
#2; clk1 = ~clk1;
|
||||
end
|
||||
#2;
|
||||
if (O_top !== O_syn) begin
|
||||
\$display("ERROR: O_top=%b O_syn=%b", O_top, O_syn);
|
||||
\$stop;
|
||||
end
|
||||
// \$display("OK O_top=O_syn=%b", O_top);
|
||||
end
|
||||
|
||||
\$display("Test passed.");
|
||||
\$finish;
|
||||
end
|
||||
endmodule
|
||||
EOT
|
||||
|
||||
../../../yosys -p 'read_verilog test_dsp_map_top.v; synth_ice40 -dsp; rename top syn; write_verilog test_dsp_map_syn.v'
|
||||
iverilog -o test_dsp_map -s testbench test_dsp_map_tb.v test_dsp_map_top.v test_dsp_map_syn.v ../cells_sim.v
|
||||
vvp -N test_dsp_map
|
||||
done
|
||||
|
||||
: ""
|
||||
: "#### All tests passed. ####"
|
||||
: ""
|
11
techlibs/ice40/tests/test_dsp_model.sh
Normal file
11
techlibs/ice40/tests/test_dsp_model.sh
Normal file
|
@ -0,0 +1,11 @@
|
|||
#!/bin/bash
|
||||
set -ex
|
||||
sed 's/SB_MAC16/SB_MAC16_UUT/; /SB_MAC16_UUT/,/endmodule/ p; d;' < ../cells_sim.v > test_dsp_model_uut.v
|
||||
cat /opt/lscc/iCEcube2.2017.01/verilog/sb_ice_syn.v > test_dsp_model_ref.v
|
||||
for tb in testbench \
|
||||
testbench_comb_8x8_A testbench_comb_8x8_B testbench_comb_16x16 \
|
||||
testbench_seq_16x16_A testbench_seq_16x16_B
|
||||
do
|
||||
iverilog -s $tb -o test_dsp_model test_dsp_model.v test_dsp_model_uut.v test_dsp_model_ref.v
|
||||
vvp -N ./test_dsp_model
|
||||
done
|
342
techlibs/ice40/tests/test_dsp_model.v
Normal file
342
techlibs/ice40/tests/test_dsp_model.v
Normal file
|
@ -0,0 +1,342 @@
|
|||
`timescale 1ns / 1ps
|
||||
|
||||
module testbench;
|
||||
parameter [0:0] NEG_TRIGGER = 0;
|
||||
parameter [0:0] C_REG = 0;
|
||||
parameter [0:0] A_REG = 0;
|
||||
parameter [0:0] B_REG = 0;
|
||||
parameter [0:0] D_REG = 0;
|
||||
parameter [0:0] TOP_8x8_MULT_REG = 0;
|
||||
parameter [0:0] BOT_8x8_MULT_REG = 0;
|
||||
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 = 0;
|
||||
parameter [0:0] TOPADDSUB_UPPERINPUT = 1;
|
||||
parameter [1:0] TOPADDSUB_CARRYSELECT = 0;
|
||||
parameter [1:0] BOTOUTPUT_SELECT = 0;
|
||||
parameter [1:0] BOTADDSUB_LOWERINPUT = 0;
|
||||
parameter [0:0] BOTADDSUB_UPPERINPUT = 1;
|
||||
parameter [1:0] BOTADDSUB_CARRYSELECT = 0;
|
||||
parameter [0:0] MODE_8x8 = 0;
|
||||
parameter [0:0] A_SIGNED = 0;
|
||||
parameter [0:0] B_SIGNED = 0;
|
||||
|
||||
reg CLK, CE;
|
||||
reg [15:0] C, A, B, D;
|
||||
reg AHOLD, BHOLD, CHOLD, DHOLD;
|
||||
reg IRSTTOP, IRSTBOT;
|
||||
reg ORSTTOP, ORSTBOT;
|
||||
reg OLOADTOP, OLOADBOT;
|
||||
reg ADDSUBTOP, ADDSUBBOT;
|
||||
reg OHOLDTOP, OHOLDBOT;
|
||||
reg CI, ACCUMCI, SIGNEXTIN;
|
||||
|
||||
output [31:0] REF_O, UUT_O;
|
||||
output REF_CO, REF_ACCUMCO, REF_SIGNEXTOUT;
|
||||
output UUT_CO, UUT_ACCUMCO, UUT_SIGNEXTOUT;
|
||||
|
||||
integer errcount = 0;
|
||||
|
||||
task clkcycle;
|
||||
begin
|
||||
#5;
|
||||
CLK = ~CLK;
|
||||
#10;
|
||||
CLK = ~CLK;
|
||||
#2;
|
||||
if (REF_O !== UUT_O) begin
|
||||
$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
|
||||
$display("ERROR at %1t: REF_CO=%b UUT_CO=%b", $time, REF_CO, UUT_CO);
|
||||
errcount = errcount + 1;
|
||||
end
|
||||
if (REF_ACCUMCO !== UUT_ACCUMCO) begin
|
||||
$display("ERROR at %1t: REF_ACCUMCO=%b UUT_ACCUMCO=%b", $time, REF_ACCUMCO, UUT_ACCUMCO);
|
||||
errcount = errcount + 1;
|
||||
end
|
||||
if (REF_SIGNEXTOUT !== UUT_SIGNEXTOUT) begin
|
||||
$display("ERROR at %1t: REF_SIGNEXTOUT=%b UUT_SIGNEXTOUT=%b", $time, REF_SIGNEXTOUT, UUT_SIGNEXTOUT);
|
||||
errcount = errcount + 1;
|
||||
end
|
||||
#3;
|
||||
end
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
$dumpfile("test_dsp_model.vcd");
|
||||
$dumpvars(0, testbench);
|
||||
|
||||
#2;
|
||||
CLK = NEG_TRIGGER;
|
||||
CE = 1;
|
||||
{C, A, B, D} = 0;
|
||||
{AHOLD, BHOLD, CHOLD, DHOLD} = 0;
|
||||
{OLOADTOP, OLOADBOT} = 0;
|
||||
{ADDSUBTOP, ADDSUBBOT} = 0;
|
||||
{OHOLDTOP, OHOLDBOT} = 0;
|
||||
{CI, ACCUMCI, SIGNEXTIN} = 0;
|
||||
|
||||
{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;
|
||||
|
||||
{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
|
||||
|
||||
SB_MAC16 #(
|
||||
.NEG_TRIGGER (NEG_TRIGGER ),
|
||||
.C_REG (C_REG ),
|
||||
.A_REG (A_REG ),
|
||||
.B_REG (B_REG ),
|
||||
.D_REG (D_REG ),
|
||||
.TOP_8x8_MULT_REG (TOP_8x8_MULT_REG ),
|
||||
.BOT_8x8_MULT_REG (BOT_8x8_MULT_REG ),
|
||||
.PIPELINE_16x16_MULT_REG1 (PIPELINE_16x16_MULT_REG1),
|
||||
.PIPELINE_16x16_MULT_REG2 (PIPELINE_16x16_MULT_REG2),
|
||||
.TOPOUTPUT_SELECT (TOPOUTPUT_SELECT ),
|
||||
.TOPADDSUB_LOWERINPUT (TOPADDSUB_LOWERINPUT ),
|
||||
.TOPADDSUB_UPPERINPUT (TOPADDSUB_UPPERINPUT ),
|
||||
.TOPADDSUB_CARRYSELECT (TOPADDSUB_CARRYSELECT ),
|
||||
.BOTOUTPUT_SELECT (BOTOUTPUT_SELECT ),
|
||||
.BOTADDSUB_LOWERINPUT (BOTADDSUB_LOWERINPUT ),
|
||||
.BOTADDSUB_UPPERINPUT (BOTADDSUB_UPPERINPUT ),
|
||||
.BOTADDSUB_CARRYSELECT (BOTADDSUB_CARRYSELECT ),
|
||||
.MODE_8x8 (MODE_8x8 ),
|
||||
.A_SIGNED (A_SIGNED ),
|
||||
.B_SIGNED (B_SIGNED )
|
||||
) ref (
|
||||
.CLK (CLK ),
|
||||
.CE (CE ),
|
||||
.C (C ),
|
||||
.A (A ),
|
||||
.B (B ),
|
||||
.D (D ),
|
||||
.AHOLD (AHOLD ),
|
||||
.BHOLD (BHOLD ),
|
||||
.CHOLD (CHOLD ),
|
||||
.DHOLD (DHOLD ),
|
||||
.IRSTTOP (IRSTTOP ),
|
||||
.IRSTBOT (IRSTBOT ),
|
||||
.ORSTTOP (ORSTTOP ),
|
||||
.ORSTBOT (ORSTBOT ),
|
||||
.OLOADTOP (OLOADTOP ),
|
||||
.OLOADBOT (OLOADBOT ),
|
||||
.ADDSUBTOP (ADDSUBTOP ),
|
||||
.ADDSUBBOT (ADDSUBBOT ),
|
||||
.OHOLDTOP (OHOLDTOP ),
|
||||
.OHOLDBOT (OHOLDBOT ),
|
||||
.CI (CI ),
|
||||
.ACCUMCI (ACCUMCI ),
|
||||
.SIGNEXTIN (SIGNEXTIN ),
|
||||
.O (REF_O ),
|
||||
.CO (REF_CO ),
|
||||
.ACCUMCO (REF_ACCUMCO ),
|
||||
.SIGNEXTOUT (REF_SIGNEXTOUT)
|
||||
);
|
||||
|
||||
SB_MAC16_UUT #(
|
||||
.NEG_TRIGGER (NEG_TRIGGER ),
|
||||
.C_REG (C_REG ),
|
||||
.A_REG (A_REG ),
|
||||
.B_REG (B_REG ),
|
||||
.D_REG (D_REG ),
|
||||
.TOP_8x8_MULT_REG (TOP_8x8_MULT_REG ),
|
||||
.BOT_8x8_MULT_REG (BOT_8x8_MULT_REG ),
|
||||
.PIPELINE_16x16_MULT_REG1 (PIPELINE_16x16_MULT_REG1),
|
||||
.PIPELINE_16x16_MULT_REG2 (PIPELINE_16x16_MULT_REG2),
|
||||
.TOPOUTPUT_SELECT (TOPOUTPUT_SELECT ),
|
||||
.TOPADDSUB_LOWERINPUT (TOPADDSUB_LOWERINPUT ),
|
||||
.TOPADDSUB_UPPERINPUT (TOPADDSUB_UPPERINPUT ),
|
||||
.TOPADDSUB_CARRYSELECT (TOPADDSUB_CARRYSELECT ),
|
||||
.BOTOUTPUT_SELECT (BOTOUTPUT_SELECT ),
|
||||
.BOTADDSUB_LOWERINPUT (BOTADDSUB_LOWERINPUT ),
|
||||
.BOTADDSUB_UPPERINPUT (BOTADDSUB_UPPERINPUT ),
|
||||
.BOTADDSUB_CARRYSELECT (BOTADDSUB_CARRYSELECT ),
|
||||
.MODE_8x8 (MODE_8x8 ),
|
||||
.A_SIGNED (A_SIGNED ),
|
||||
.B_SIGNED (B_SIGNED )
|
||||
) uut (
|
||||
.CLK (CLK ),
|
||||
.CE (CE ),
|
||||
.C (C ),
|
||||
.A (A ),
|
||||
.B (B ),
|
||||
.D (D ),
|
||||
.AHOLD (AHOLD ),
|
||||
.BHOLD (BHOLD ),
|
||||
.CHOLD (CHOLD ),
|
||||
.DHOLD (DHOLD ),
|
||||
.IRSTTOP (IRSTTOP ),
|
||||
.IRSTBOT (IRSTBOT ),
|
||||
.ORSTTOP (ORSTTOP ),
|
||||
.ORSTBOT (ORSTBOT ),
|
||||
.OLOADTOP (OLOADTOP ),
|
||||
.OLOADBOT (OLOADBOT ),
|
||||
.ADDSUBTOP (ADDSUBTOP ),
|
||||
.ADDSUBBOT (ADDSUBBOT ),
|
||||
.OHOLDTOP (OHOLDTOP ),
|
||||
.OHOLDBOT (OHOLDBOT ),
|
||||
.CI (CI ),
|
||||
.ACCUMCI (ACCUMCI ),
|
||||
.SIGNEXTIN (SIGNEXTIN ),
|
||||
.O (UUT_O ),
|
||||
.CO (UUT_CO ),
|
||||
.ACCUMCO (UUT_ACCUMCO ),
|
||||
.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
|
Loading…
Add table
Add a link
Reference in a new issue