diff --git a/techlibs/intel_le/common/arith_le_map.v b/techlibs/intel_le/common/arith_le_map.v index 8515eeb56..1a177de85 100644 --- a/techlibs/intel_le/common/arith_le_map.v +++ b/techlibs/intel_le/common/arith_le_map.v @@ -30,7 +30,8 @@ wire [Y_WIDTH-1:0] AA = A_buf; wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; (* force_downto *) wire [Y_WIDTH-1:0] BX = B_buf; -wire [Y_WIDTH:0] ALM_CARRY; +wire [Y_WIDTH-1:0] BSUM; +wire [Y_WIDTH:0] LE_CARRY; // Start of carry chain generate @@ -53,15 +54,23 @@ genvar i; generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice // TODO: mwk suggests that a pass could merge pre-adder logic into this. MISTRAL_ALUT_ARITH #( - .LUT0(16'b1010_1010_1010_1010), // Q = A - .LUT1(16'b1100_0011_1100_0011), // Q = C ? B : ~B (LUT1's input to the adder is inverted) + .LUT0(16'b0110_0110_0110_0110) // Q = A ? ~B : B ) alm_i ( - .A(AA[i]), .B(BX[i]), .C(BI), .D0(1'b1), .D1(1'b1), - .CI(ALM_CARRY[i]), - .SO(Y[i]), - .CO(ALM_CARRY[i+1]) + .A(BI), .B(BX[i]), .C(1'b0), .D(1'b0), + .CI(1'b0), + .SO(BSUM[i]), + .CO() ); - + MISTRAL_ALUT_ARITH #( + .LUT0(16'b1010_1010_1010_1010), // SUM = A xor B xor CI + // CARRYi+1 = A and B or A and CI or B and CI + .sum_lutc_input("cin") + ) alm_start ( + .A(AA[i]), .B(BX[i]), .C(1'b1), .D(1'b1), + .CI(LE_CARRY), + .SO(Y[i]), + .CO(ALM_CARRY[i+1]) + ); // ALM carry chain is not directly accessible, so calculate the carry through soft logic if really needed. assign CO[i] = (AA[i] && BB[i]) || ((Y[i] ^ AA[i] ^ BB[i]) && (AA[i] || BB[i])); end endgenerate diff --git a/techlibs/intel_le/common/le_sim.v b/techlibs/intel_le/common/le_sim.v index 1cd955362..6c6c8b9b9 100644 --- a/techlibs/intel_le/common/le_sim.v +++ b/techlibs/intel_le/common/le_sim.v @@ -231,11 +231,10 @@ assign Q = ~A; endmodule (* abc9_box, lib_whitebox *) -module MISTRAL_ALUT_ARITH(input A, B, C, D0, D1, (* abc9_carry *) input CI, output SO, (* abc9_carry *) output CO); - -parameter LUT0 = 16'h0000; -parameter LUT1 = 16'h0000; +module MISTRAL_ALUT_ARITH(input A, B, C, D, (* abc9_carry *) input CI, output , (* abc9_carry *) output CO); +parameter LUT = 16'h0000; +parameter sum_lutc_input = "cin"; `ifdef cycloneiv specify (A => SO) = 1342; @@ -253,30 +252,15 @@ specify (CI => CO) = 36; // Divided by 2 to account for there being two ALUT_ARITHs in an ALM) endspecify `endif -`ifdef cyclone10gx -specify - (A => SO) = 644; - (B => SO) = 477; - (C => SO) = 416; - (D0 => SO) = 380; - (D1 => SO) = 431; - (CI => SO) = 276; - - (A => CO) = 525; - (B => CO) = 433; - (C => CO) = 712; - (D0 => CO) = 653; - (D1 => CO) = 593; - (CI => CO) = 16; -endspecify -`endif wire q0, q1; -assign q0 = LUT0 >> {D0, C, B, A}; -assign q1 = LUT1 >> {D1, C, B, A}; +assign q0 = LUT0 >> sum_lutc_input == "cin" : {D, CI, B, A},{D, C, B, A}; +assign q1 = LUT0 >> sum_lutc_input == "cin" : {'b0, CI, B, A},{'b0, C, B, A}; -assign {CO, SO} = q0 + !q1 + CI; +assign SO = D ? q1 : q0; + +assign CO = q0; endmodule diff --git a/techlibs/intel_le/cycloneiv/cells_sim.v b/techlibs/intel_le/cycloneiv/cells_sim.v index 60824ef03..343648ee2 100644 --- a/techlibs/intel_le/cycloneiv/cells_sim.v +++ b/techlibs/intel_le/cycloneiv/cells_sim.v @@ -38,22 +38,19 @@ module cycloneiv_io_obuf assign oe = oe; endmodule // cycloneiv_io_obuf -/* Altera Cyclone V LUT Primitive */ +/* Altera Cyclone IV LUT Primitive */ module cycloneiv_lcell_comb - (output combout, cout, sumout, shareout, + (output combout, cout, input dataa, datab, datac, datad, - input datae, dataf, datag, cin, - input sharein); + input datae, dataf, datag, cin); - parameter lut_mask = 64'hFFFFFFFFFFFFFFFF; + parameter lut_mask = 16'hFFFF; parameter dont_touch = "off"; parameter lpm_type = "cycloneiv_lcell_comb"; - parameter shared_arith = "off"; - parameter extended_lut = "off"; + // Internal variables - // Sub mask for fragmented LUTs - wire [15:0] mask_a, mask_b, mask_c, mask_d; + // Independent output for fragmented LUTs wire output_0, output_1, output_2, output_3; // Extended mode uses mux to define the output @@ -104,23 +101,7 @@ module cycloneiv_lcell_comb endfunction // lut6 assign {mask_a, mask_b, mask_c, mask_d} = {lut_mask[15:0], lut_mask[31:16], lut_mask[47:32], lut_mask[63:48]}; -`ifdef ADVANCED_ALM - always @(*) begin - if(extended_lut == "on") - shared_lut_alm = datag; - else - shared_lut_alm = datac; - // Build the ALM behaviour - out_0 = lut4(mask_a, dataa, datab, datac, datad); - out_1 = lut4(mask_b, dataa, datab, shared_lut_alm, datad); - out_2 = lut4(mask_c, dataa, datab, datac, datad); - out_3 = lut4(mask_d, dataa, datab, shared_lut_alm, datad); - end -`else - `ifdef DEBUG - initial $display("Advanced ALM lut combine is not implemented yet"); - `endif -`endif + endmodule // cycloneiv_lcell_comb