mirror of
https://github.com/YosysHQ/yosys
synced 2025-10-06 16:01:57 +00:00
Add first draft of functional SB_MAC16 model
Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
parent
5a853ed46c
commit
62493c91b2
4 changed files with 467 additions and 53 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,178 @@ 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 IRSTTOP) 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]}}, 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 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
|
||||
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;
|
||||
|
||||
// Reg H
|
||||
reg [15: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[31:16];
|
||||
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 : iQ[15:0];
|
||||
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 (!OHOLDTOP) 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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue