From af7bdd598e017b0e8887d893c901ae93935d20b2 Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Mon, 21 Oct 2019 12:00:27 +0200 Subject: [PATCH] use ADDSUB ALU mode to remove inverters --- techlibs/gowin/arith_map.v | 6 +-- techlibs/gowin/cells_sim.v | 78 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 77 insertions(+), 7 deletions(-) diff --git a/techlibs/gowin/arith_map.v b/techlibs/gowin/arith_map.v index af805b254..b6f9e8c38 100644 --- a/techlibs/gowin/arith_map.v +++ b/techlibs/gowin/arith_map.v @@ -40,15 +40,15 @@ module _80_gw1n_alu(A, B, CI, BI, X, Y, CO); \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); wire [Y_WIDTH-1:0] AA = A_buf; - wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; + wire [Y_WIDTH-1:0] BB = B_buf; wire [Y_WIDTH-1:0] C = {CO, CI}; genvar i; generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice - ALU #(.ALU_MODE(0)) + ALU #(.ALU_MODE(2)) // ADDSUB I3 ? add : sub alu(.I0(AA[i]), .I1(BB[i]), - .I3(1'b0), + .I3(~BI), .CIN(C[i]), .COUT(CO[i]), .SUM(Y[i]) diff --git a/techlibs/gowin/cells_sim.v b/techlibs/gowin/cells_sim.v index de0cfa9f3..a392f5580 100644 --- a/techlibs/gowin/cells_sim.v +++ b/techlibs/gowin/cells_sim.v @@ -166,10 +166,80 @@ module GSR (input GSRI); wire GSRO = GSRI; endmodule -module ALU (input I0, input I1, input I3, input CIN, output COUT, output SUM); - parameter [3:0] ALU_MODE = 0; // default 0 = ADD - assign {COUT, SUM} = CIN + I1 + I0; -endmodule // alu +module ALU (SUM, COUT, I0, I1, I3, CIN); + +input I0; +input I1; +input I3; +input CIN; +output SUM; +output COUT; + +parameter ADD = 0; +parameter SUB = 1; +parameter ADDSUB = 2; +parameter NE = 3; +parameter GE = 4; +parameter LE = 5; +parameter CUP = 6; +parameter CDN = 7; +parameter CUPCDN = 8; +parameter MULT = 9; + +parameter ALU_MODE = 0; + +reg S, C; + +assign SUM = S ^ CIN; +assign COUT = S? CIN : C; + +always @(I0, I1, I3,CIN) begin + case (ALU_MODE) + ADD: begin + S = I0 ^ I1; + C = I0; + end + SUB: begin + S = I0 ^ ~I1; + C = I0; + end + ADDSUB: begin + S = I3? I0 ^ I1 : I0 ^ ~I1; + C = I0; + end + NE: begin + S = I0 ^ ~I1; + C = 1'b1; + end + GE: begin + S = I0 ^ ~I1; + C = I0; + end + LE: begin + S = ~I0 ^ I1; + C = I1; + end + CUP: begin + S = I0; + C = 1'b0; + end + CDN: begin + S = ~I0; + C = 1'b1; + end + CUPCDN: begin + S = I3? I0 : ~I0; + C = I0; + end + MULT: begin + S = I0 & I1; + C = I0 & I1; + end + endcase +end + +endmodule + module RAM16S4 (DO, DI, AD, WRE, CLK); parameter WIDTH = 4; -- 2.30.2