use ADDSUB ALU mode to remove inverters
authorPepijn de Vos <pepijndevos@gmail.com>
Mon, 21 Oct 2019 10:00:27 +0000 (12:00 +0200)
committerPepijn de Vos <pepijndevos@gmail.com>
Mon, 21 Oct 2019 10:00:27 +0000 (12:00 +0200)
techlibs/gowin/arith_map.v
techlibs/gowin/cells_sim.v

index af805b254703a8641ca3b378a447126304c0c041..b6f9e8c38625c5692e40bce866e53f1c007726a6 100644 (file)
@@ -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])
index de0cfa9f3d9a457b23a00c8d3f0c6d787a6706b9..a392f5580c38fe88d34163c1409342d169f0f6ad 100644 (file)
@@ -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;