Estoy escribiendo un código verilog para el multiplicador complejo 18x18 utilizando la implementación de un solo segmento DSP48 en Vertex 4. Aquí está mi código
module SS_CM_18x18(Areal,Aimag,Breal,Bimag,Clk,Rst,Preal,Pimag);
input Clk,Rst;
input [17:0]Areal,Aimag,Breal,Bimag;
output [47:0]Preal,Pimag;
reg [47:0]Preal,Pimag;
reg [17:0]Areal_Reg,Aimag_Reg,Breal_Reg,Bimag_Reg;
wire [17:0]Areal_Wire,Aimag_Wire,Breal_Wire,Bimag_Wire;
reg [17:0]I,Q;
wire [47:0]POut;
reg [47:0]POut_Reg1;
reg [1:0]Count;
reg [6:0]OPMODE;
reg Subtract;
always @(posedge Clk or posedge Rst)
begin
if (Rst)
Count<=2'b11;
else if (Count<2'b11)
Count<=Count+1;
else
Count<=2'b0;
end
always @(posedge Clk or posedge Rst)
begin
if (Rst)
begin
Areal_Reg<=18'b0;
Aimag_Reg<=18'b0;
Breal_Reg<=18'b0;
Aimag_Reg<=18'b0;
end
else if(Count==2'b00)
begin
Areal_Reg<=Areal;
Aimag_Reg<=Aimag;
Breal_Reg<=Breal;
Aimag_Reg<=Bimag;
end
else
begin
Areal_Reg<=Areal_Reg;
Aimag_Reg<=Aimag_Reg;
Breal_Reg<=Breal_Reg;
Aimag_Reg<=Bimag_Reg;
end
end
assign Areal_Wire=Areal_Reg;
assign Aimag_Wire=Aimag_Reg;
assign Breal_Wire=Breal_Reg;
assign Bimag_Wire=Bimag_Reg;
always @(posedge Clk or posedge Rst)
begin
if (Rst)
begin
I<=18'b0;
Q<=18'b0;
OPMODE<=7'b0;
Subtract<=1'b0;
end
else
begin
case(Count)
2'd0: begin
I<=Areal_Wire;
Q<=Breal_Wire;
OPMODE<=7'b0000101;
Subtract<=1'b0;
end
2'd1: begin
I<=Aimag_Wire;
Q<=Bimag_Wire;
OPMODE<=7'b0100101;
Subtract<=1'b1;
end
2'd2: begin
I<=Areal_Wire;
Q<=Bimag_Wire;
OPMODE<=7'b0000101;
Subtract<=1'b0;
end
2'd3: begin
I<=Aimag_Wire;
Q<=Breal_Wire;
OPMODE<=7'b0100101;
Subtract<=1'b0;
end
endcase
end
end
// DSP48: DSP Function Block
// Virtex-4
// Xilinx HDL Language Template, version 13.4
DSP48 #(
.AREG(0), // Number of pipeline registers on the A input, 0, 1 or 2
.BREG(0), // Number of pipeline registers on the B input, 0, 1 or 2
.B_INPUT("DIRECT"), // B input DIRECT from fabric or CASCADE from another DSP48
.CARRYINREG(0), // Number of pipeline registers for the CARRYIN input, 0 or 1
.CARRYINSELREG(0), // Number of pipeline registers for the CARRYINSEL, 0 or 1
.CREG(0), // Number of pipeline registers on the C input, 0 or 1
.LEGACY_MODE("MULT18X18"), // Backward compatibility, NONE, MULT18X18 or MULT18X18S
.MREG(0), // Number of multiplier pipeline registers, 0 or 1
.OPMODEREG(0), // Number of pipeline regsiters on OPMODE input, 0 or 1
.PREG(1), // Number of pipeline registers on the P output, 0 or 1
.SUBTRACTREG(0) // Number of pipeline registers on the SUBTRACT input, 0 or 1
)
DSP48_inst1 (
.BCOUT(), // 18-bit B cascade output
.P(POut), // 48-bit product output
.PCOUT(), // 48-bit cascade output
.A(I), // 18-bit A data input
.B(Q), // 18-bit B data input
.BCIN(18'd0), // 18-bit B cascade input
.C(48'd0), // 48-bit cascade input
.CARRYIN(1'd0), // Carry input signal
.CARRYINSEL(2'd0), // 2-bit carry input select
.CEA(1'b1), // A data clock enable input
.CEB(1'b1), // B data clock enable input
.CEC(1'b0), // C data clock enable input
.CECARRYIN(1'b0), // CARRYIN clock enable input
.CECINSUB(1'b1), // CINSUB clock enable input
.CECTRL(1'b0), // Clock Enable input for CTRL regsiters
.CEM(1'b1), // Clock Enable input for multiplier regsiters
.CEP(1'b1), // Clock Enable input for P regsiters
.CLK(Clk), // Clock input
.OPMODE(OPMODE), // 7-bit operation mode input
.PCIN(48'b0), // 48-bit PCIN input
.RSTA(Rst), // Reset input for A pipeline registers
.RSTB(Rst), // Reset input for B pipeline registers
.RSTC(Rst), // Reset input for C pipeline registers
.RSTCARRYIN(Rst), // Reset input for CARRYIN registers
.RSTCTRL(Rst), // Reset input for CTRL registers
.RSTM(Rst), // Reset input for multiplier registers
.RSTP(Rst), // Reset input for P pipeline registers
.SUBTRACT(Subtract) // SUBTRACT input
);
// End of DSP48_inst instantiation
always @(posedge Clk or posedge Rst)
begin
if (Rst)
POut_Reg1<=48'b0;
else
POut_Reg1<=POut;
end
always @(posedge Clk or posedge Rst)
begin
if (Rst)
begin
Preal<=48'b0;
Pimag<=48'b0;
end
else if (Count==2'b00)
Preal<=POut_Reg1;
else if (Count==2'd10)
Pimag<=POut_Reg1;
else
begin
Preal<=Preal;
Pimag<=Pimag;
end
end
endmodule
El banco de pruebas para el programa es
module Test_SS_CM_18x18;
// Inputs
reg [17:0] Areal;
reg [17:0] Aimag;
reg [17:0] Breal;
reg [17:0] Bimag;
reg Clk;
reg Rst;
// Outputs
wire [47:0] Preal;
wire [47:0] Pimag;
// Instantiate the Unit Under Test (UUT)
SS_CM_18x18 uut1 (
.Areal(Areal),
.Aimag(Aimag),
.Breal(Breal),
.Bimag(Bimag),
.Clk(Clk),
.Rst(Rst),
.Preal(Preal),
.Pimag(Pimag)
);
initial begin
// Initialize Inputs
Areal = 0;
Aimag = 0;
Breal = 0;
Bimag = 0;
Clk = 0;
Rst = 0;
// Wait 100 ns for global reset to finish
#105;
Rst=1;
#10 Rst = 0;
// Add stimulus here
Areal=18'd1;
Aimag=18'd1;
Breal=18'd1;
Bimag=18'd1;
end
always #5 Clk=~Clk;
endmodule
No obtengo la salida correcta. ¿Alguien puede decirme dónde estoy cometiendo un error en código / concepto? La salida va a 0 después de 3 clk ciclos & luego 3 ciclos de clk después de restablecer, pasa al estado de alta impedancia