mirror of https://github.com/YosysHQ/yosys.git
DSP48E1 sim model: seq test working
Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
parent
f6605c7dc0
commit
e7dbe7bb3d
|
@ -547,7 +547,7 @@ module DSP48E1 (
|
||||||
end
|
end
|
||||||
|
|
||||||
// C and D registers
|
// C and D registers
|
||||||
if (CREG == 1) begin always @(posedge CLK) if (RSTC) Cr <= 48'b0; else if (CEC) Cr <= D; end
|
if (CREG == 1) begin always @(posedge CLK) if (RSTC) Cr <= 48'b0; else if (CEC) Cr <= C; end
|
||||||
else always @* Cr <= C;
|
else always @* Cr <= C;
|
||||||
|
|
||||||
if (DREG == 1) begin always @(posedge CLK) if (RSTD) Dr <= 25'b0; else if (CED) Dr <= D; end
|
if (DREG == 1) begin always @(posedge CLK) if (RSTD) Dr <= 25'b0; else if (CED) Dr <= D; end
|
||||||
|
@ -608,7 +608,7 @@ module DSP48E1 (
|
||||||
// X multiplexer
|
// X multiplexer
|
||||||
case (OPMODEr[1:0])
|
case (OPMODEr[1:0])
|
||||||
2'b00: X = 48'b0;
|
2'b00: X = 48'b0;
|
||||||
2'b01: begin X = $signed(M);
|
2'b01: begin X = $signed(Mr);
|
||||||
`ifdef __ICARUS__
|
`ifdef __ICARUS__
|
||||||
if (OPMODEr[3:2] != 2'b01) $fatal(1, "OPMODEr[3:2] must be 2'b01 when OPMODEr[1:0] is 2'b01");
|
if (OPMODEr[3:2] != 2'b01) $fatal(1, "OPMODEr[3:2] must be 2'b01 when OPMODEr[1:0] is 2'b01");
|
||||||
`endif
|
`endif
|
||||||
|
@ -631,7 +631,7 @@ module DSP48E1 (
|
||||||
`endif
|
`endif
|
||||||
end
|
end
|
||||||
2'b10: Y = {48{1'b1}};
|
2'b10: Y = {48{1'b1}};
|
||||||
2'b11: Y = C;
|
2'b11: Y = Cr;
|
||||||
default: Y = 48'bx;
|
default: Y = 48'bx;
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
|
@ -644,7 +644,7 @@ module DSP48E1 (
|
||||||
if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[6:4] i0s 3'b010");
|
if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[6:4] i0s 3'b010");
|
||||||
`endif
|
`endif
|
||||||
end
|
end
|
||||||
3'b011: Z = C;
|
3'b011: Z = Cr;
|
||||||
3'b100: begin Z = P;
|
3'b100: begin Z = P;
|
||||||
`ifdef __ICARUS__
|
`ifdef __ICARUS__
|
||||||
if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[6:4] is 3'b100");
|
if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[6:4] is 3'b100");
|
||||||
|
@ -659,7 +659,7 @@ module DSP48E1 (
|
||||||
|
|
||||||
// Carry in
|
// Carry in
|
||||||
wire A24_xnor_B17d = A_MULT[24] ~^ B_MULT[17];
|
wire A24_xnor_B17d = A_MULT[24] ~^ B_MULT[17];
|
||||||
reg CARRYINr, A24_xnor_B17;
|
reg CARRYINr = 1'b0, A24_xnor_B17 = 1'b0;
|
||||||
generate
|
generate
|
||||||
if (CARRYINREG == 1) begin always @(posedge CLK) if (RSTALLCARRYIN) CARRYINr <= 1'b0; else if (CECARRYIN) CARRYINr <= CARRYIN; end
|
if (CARRYINREG == 1) begin always @(posedge CLK) if (RSTALLCARRYIN) CARRYINr <= 1'b0; else if (CECARRYIN) CARRYINr <= CARRYIN; end
|
||||||
else always @* CARRYINr = CARRYIN;
|
else always @* CARRYINr = CARRYIN;
|
||||||
|
@ -698,6 +698,7 @@ module DSP48E1 (
|
||||||
wire [3:0] int_carry_in, int_carry_out, ext_carry_out;
|
wire [3:0] int_carry_in, int_carry_out, ext_carry_out;
|
||||||
wire [47:0] alu_sum;
|
wire [47:0] alu_sum;
|
||||||
assign int_carry_in[0] = 1'b0;
|
assign int_carry_in[0] = 1'b0;
|
||||||
|
wire [3:0] carryout_reset;
|
||||||
|
|
||||||
generate
|
generate
|
||||||
if (USE_SIMD == "FOUR12") begin
|
if (USE_SIMD == "FOUR12") begin
|
||||||
|
@ -715,6 +716,7 @@ module DSP48E1 (
|
||||||
maj_xyz_gated[23] ^ int_carry_out[1],
|
maj_xyz_gated[23] ^ int_carry_out[1],
|
||||||
maj_xyz_gated[11] ^ int_carry_out[0]
|
maj_xyz_gated[11] ^ int_carry_out[0]
|
||||||
};
|
};
|
||||||
|
assign carryout_reset = 4'b0000;
|
||||||
end else if (USE_SIMD == "TWO24") begin
|
end else if (USE_SIMD == "TWO24") begin
|
||||||
assign maj_xyz_simd_gated = {
|
assign maj_xyz_simd_gated = {
|
||||||
maj_xyz_gated[47:24],
|
maj_xyz_gated[47:24],
|
||||||
|
@ -728,6 +730,7 @@ module DSP48E1 (
|
||||||
maj_xyz_gated[23] ^ int_carry_out[1],
|
maj_xyz_gated[23] ^ int_carry_out[1],
|
||||||
1'bx
|
1'bx
|
||||||
};
|
};
|
||||||
|
assign carryout_reset = 4'b0x0x;
|
||||||
end else begin
|
end else begin
|
||||||
assign maj_xyz_simd_gated = {maj_xyz_gated, alu_cin};
|
assign maj_xyz_simd_gated = {maj_xyz_gated, alu_cin};
|
||||||
assign int_carry_in[3:1] = int_carry_out[2:0];
|
assign int_carry_in[3:1] = int_carry_out[2:0];
|
||||||
|
@ -735,6 +738,7 @@ module DSP48E1 (
|
||||||
int_carry_out[3],
|
int_carry_out[3],
|
||||||
3'bxxx
|
3'bxxx
|
||||||
};
|
};
|
||||||
|
assign carryout_reset = 4'b0xxx;
|
||||||
end
|
end
|
||||||
|
|
||||||
genvar i;
|
genvar i;
|
||||||
|
@ -745,6 +749,9 @@ module DSP48E1 (
|
||||||
|
|
||||||
wire signed [47:0] Pd = ALUMODEr[1] ? ~alu_sum : alu_sum;
|
wire signed [47:0] Pd = ALUMODEr[1] ? ~alu_sum : alu_sum;
|
||||||
initial P = 48'b0;
|
initial P = 48'b0;
|
||||||
|
initial CARRYOUT = carryout_reset;
|
||||||
|
initial CARRYCASCOUT = 1'b0;
|
||||||
|
initial MULTSIGNOUT = 1'b0;
|
||||||
wire [3:0] CARRYOUTd = (OPMODEr[3:0] == 4'b0101 || ALUMODEr[3:2] != 2'b00) ? 4'bxxxx :
|
wire [3:0] CARRYOUTd = (OPMODEr[3:0] == 4'b0101 || ALUMODEr[3:2] != 2'b00) ? 4'bxxxx :
|
||||||
((ALUMODEr[0] & ALUMODEr[1]) ? ~ext_carry_out : ext_carry_out);
|
((ALUMODEr[0] & ALUMODEr[1]) ? ~ext_carry_out : ext_carry_out);
|
||||||
wire CARRYCASCOUTd = ext_carry_out[3];
|
wire CARRYCASCOUTd = ext_carry_out[3];
|
||||||
|
@ -755,7 +762,7 @@ module DSP48E1 (
|
||||||
always @(posedge CLK)
|
always @(posedge CLK)
|
||||||
if (RSTP) begin
|
if (RSTP) begin
|
||||||
P <= 48'b0;
|
P <= 48'b0;
|
||||||
CARRYOUT <= 4'b0;
|
CARRYOUT <= carryout_reset;
|
||||||
CARRYCASCOUT <= 1'b0;
|
CARRYCASCOUT <= 1'b0;
|
||||||
MULTSIGNOUT <= 1'b0;
|
MULTSIGNOUT <= 1'b0;
|
||||||
end else if (CEP) begin
|
end else if (CEP) begin
|
||||||
|
|
|
@ -4,7 +4,7 @@ sed 's/DSP48E1/DSP48E1_UUT/; /DSP48E1_UUT/,/endmodule/ p; d;' < ../cells_sim.v >
|
||||||
if [ ! -f "test_dsp_model_ref.v" ]; then
|
if [ ! -f "test_dsp_model_ref.v" ]; then
|
||||||
cat /opt/Xilinx/Vivado/2019.1/data/verilog/src/unisims/DSP48E1.v > test_dsp_model_ref.v
|
cat /opt/Xilinx/Vivado/2019.1/data/verilog/src/unisims/DSP48E1.v > test_dsp_model_ref.v
|
||||||
fi
|
fi
|
||||||
for tb in mult_noreg_nopreadd_nocasc
|
for tb in mult_allreg_nopreadd_nocasc mult_noreg_nopreadd_nocasc
|
||||||
do
|
do
|
||||||
iverilog -s $tb -s glbl -o test_dsp_model test_dsp_model.v test_dsp_model_uut.v test_dsp_model_ref.v /opt/Xilinx/Vivado/2019.1/data/verilog/src/glbl.v
|
iverilog -s $tb -s glbl -o test_dsp_model test_dsp_model.v test_dsp_model_uut.v test_dsp_model_ref.v /opt/Xilinx/Vivado/2019.1/data/verilog/src/glbl.v
|
||||||
vvp -N ./test_dsp_model
|
vvp -N ./test_dsp_model
|
||||||
|
|
|
@ -94,7 +94,7 @@ module testbench;
|
||||||
if (OPMODE[1:0] == 2'b10 && PREG != 1) config_valid = 0;
|
if (OPMODE[1:0] == 2'b10 && PREG != 1) config_valid = 0;
|
||||||
if ((OPMODE[3:2] == 2'b01) ^ (OPMODE[1:0] == 2'b01) == 1'b1) config_valid = 0;
|
if ((OPMODE[3:2] == 2'b01) ^ (OPMODE[1:0] == 2'b01) == 1'b1) config_valid = 0;
|
||||||
if ((OPMODE[6:4] == 3'b010 || OPMODE[6:4] == 3'b110) && PREG != 1) config_valid = 0;
|
if ((OPMODE[6:4] == 3'b010 || OPMODE[6:4] == 3'b110) && PREG != 1) config_valid = 0;
|
||||||
if ((OPMODE[6:4] == 3'b100) && (PREG != 1 || OPMODE[3:0] != 4'b1000)) config_valid = 0;
|
if ((OPMODE[6:4] == 3'b100) && (PREG != 1 || OPMODE[3:0] != 4'b1000 || ALUMODE[3:2] == 2'b01 || ALUMODE[3:2] == 2'b11)) config_valid = 0;
|
||||||
if ((CARRYINSEL == 3'b100 || CARRYINSEL == 3'b101 || CARRYINSEL == 3'b111) && (PREG != 1)) config_valid = 0;
|
if ((CARRYINSEL == 3'b100 || CARRYINSEL == 3'b101 || CARRYINSEL == 3'b111) && (PREG != 1)) config_valid = 0;
|
||||||
if (OPMODE[6:4] == 3'b111) config_valid = 0;
|
if (OPMODE[6:4] == 3'b111) config_valid = 0;
|
||||||
if ((ALUMODE[3:2] == 2'b01 || ALUMODE[3:2] == 2'b11) && OPMODE[3:2] != 2'b00 && OPMODE[3:2] != 2'b10) config_valid = 0;
|
if ((ALUMODE[3:2] == 2'b01 || ALUMODE[3:2] == 2'b11) && OPMODE[3:2] != 2'b00 && OPMODE[3:2] != 2'b10) config_valid = 0;
|
||||||
|
@ -119,14 +119,16 @@ module testbench;
|
||||||
{OPMODE, CARRYCASCIN, CARRYIN, MULTSIGNIN} = 0;
|
{OPMODE, CARRYCASCIN, CARRYIN, MULTSIGNIN} = 0;
|
||||||
|
|
||||||
{RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = ~0;
|
{RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = ~0;
|
||||||
#5;
|
repeat (10) begin
|
||||||
CLK = 1'b1;
|
#10;
|
||||||
#10;
|
CLK = 1'b1;
|
||||||
CLK = 1'b0;
|
#10;
|
||||||
#5;
|
CLK = 1'b0;
|
||||||
CLK = 1'b1;
|
#10;
|
||||||
#10;
|
CLK = 1'b1;
|
||||||
CLK = 1'b0;
|
#10;
|
||||||
|
CLK = 1'b0;
|
||||||
|
end
|
||||||
{RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = 0;
|
{RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = 0;
|
||||||
|
|
||||||
repeat (300) begin
|
repeat (300) begin
|
||||||
|
@ -358,4 +360,39 @@ module mult_noreg_nopreadd_nocasc;
|
||||||
.IS_INMODE_INVERTED (5'b0),
|
.IS_INMODE_INVERTED (5'b0),
|
||||||
.IS_OPMODE_INVERTED (7'b0)
|
.IS_OPMODE_INVERTED (7'b0)
|
||||||
) testbench ();
|
) testbench ();
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module mult_allreg_nopreadd_nocasc;
|
||||||
|
testbench #(
|
||||||
|
.ACASCREG (1),
|
||||||
|
.ADREG (1),
|
||||||
|
.ALUMODEREG (1),
|
||||||
|
.AREG (2),
|
||||||
|
.AUTORESET_PATDET ("NO_RESET"),
|
||||||
|
.A_INPUT ("DIRECT"),
|
||||||
|
.BCASCREG (1),
|
||||||
|
.BREG (2),
|
||||||
|
.B_INPUT ("DIRECT"),
|
||||||
|
.CARRYINREG (1),
|
||||||
|
.CARRYINSELREG (1),
|
||||||
|
.CREG (1),
|
||||||
|
.DREG (1),
|
||||||
|
.INMODEREG (1),
|
||||||
|
.MREG (1),
|
||||||
|
.OPMODEREG (1),
|
||||||
|
.PREG (1),
|
||||||
|
.SEL_MASK ("MASK"),
|
||||||
|
.SEL_PATTERN ("PATTERN"),
|
||||||
|
.USE_DPORT ("FALSE"),
|
||||||
|
.USE_MULT ("DYNAMIC"),
|
||||||
|
.USE_PATTERN_DETECT ("NO_PATDET"),
|
||||||
|
.USE_SIMD ("ONE48"),
|
||||||
|
.MASK (48'h3FFFFFFFFFFF),
|
||||||
|
.PATTERN (48'h000000000000),
|
||||||
|
.IS_ALUMODE_INVERTED(4'b0),
|
||||||
|
.IS_CARRYIN_INVERTED(1'b0),
|
||||||
|
.IS_CLK_INVERTED (1'b0),
|
||||||
|
.IS_INMODE_INVERTED (5'b0),
|
||||||
|
.IS_OPMODE_INVERTED (7'b0)
|
||||||
|
) testbench ();
|
||||||
endmodule
|
endmodule
|
Loading…
Reference in New Issue