diff --git a/techlibs/intel_alm/Makefile.inc b/techlibs/intel_alm/Makefile.inc index b5f279a921c..b8a6abe91e9 100644 --- a/techlibs/intel_alm/Makefile.inc +++ b/techlibs/intel_alm/Makefile.inc @@ -20,8 +20,6 @@ $(eval $(call add_share_file,share/intel_alm/cyclonev,techlibs/intel_alm/cyclone # RAM $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_m10k.txt)) $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_m10k_map.v)) -$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_m20k.txt)) -$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_m20k_map.v)) $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/lutram_mlab.txt)) # Miscellaneous diff --git a/techlibs/intel_alm/common/alm_sim.v b/techlibs/intel_alm/common/alm_sim.v index d3bd673903f..858e43c76cc 100644 --- a/techlibs/intel_alm/common/alm_sim.v +++ b/techlibs/intel_alm/common/alm_sim.v @@ -1,4 +1,4 @@ -// The core logic primitive of the Cyclone V/10GX is the Adaptive Logic Module +// The core logic primitive of the Cyclone V is the Adaptive Logic Module // (ALM). Each ALM is made up of an 8-input, 2-output look-up table, covered // in this file, connected to combinational outputs, a carry chain, and four // D flip-flops (which are covered as MISTRAL_FF in dff_sim.v). @@ -77,14 +77,6 @@ // SUMOUT 368 1342 1323 887 927 - 785 - // CARRYOUT 71 1082 1062 866 813 - 1198 - -// Arria V LUT output timings (picoseconds): -// -// CARRY A B C D E F G -// COMBOUT - 387 375 316 317 - 76 319 (LUT6) -// COMBOUT - 387 375 316 317 218 76 319 (LUT7) -// SUMOUT 249 744 732 562 576 - 511 - -// CARRYOUT 19 629 623 530 514 - 696 - - (* abc9_lut=2, lib_whitebox *) module MISTRAL_ALUT6(input A, B, C, D, E, F, output Q); @@ -100,26 +92,6 @@ specify (F => Q) = 97; endspecify `endif -`ifdef arriav -specify - (A => Q) = 387; - (B => Q) = 375; - (C => Q) = 316; - (D => Q) = 317; - (E => Q) = 319; - (F => Q) = 76; -endspecify -`endif -`ifdef cyclone10gx -specify - (A => Q) = 275; - (B => Q) = 272; - (C => Q) = 175; - (D => Q) = 165; - (E => Q) = 162; - (F => Q) = 53; -endspecify -`endif assign Q = LUT >> {F, E, D, C, B, A}; @@ -140,24 +112,6 @@ specify (E => Q) = 97; endspecify `endif -`ifdef arriav -specify - (A => Q) = 375; - (B => Q) = 316; - (C => Q) = 317; - (D => Q) = 319; - (E => Q) = 76; -endspecify -`endif -`ifdef cyclone10gx -specify - (A => Q) = 272; - (B => Q) = 175; - (C => Q) = 165; - (D => Q) = 162; - (E => Q) = 53; -endspecify -`endif assign Q = LUT >> {E, D, C, B, A}; @@ -177,22 +131,6 @@ specify (D => Q) = 97; endspecify `endif -`ifdef arriav -specify - (A => Q) = 316; - (B => Q) = 317; - (C => Q) = 319; - (D => Q) = 76; -endspecify -`endif -`ifdef cyclone10gx -specify - (A => Q) = 175; - (B => Q) = 165; - (C => Q) = 162; - (D => Q) = 53; -endspecify -`endif assign Q = LUT >> {D, C, B, A}; @@ -211,20 +149,6 @@ specify (C => Q) = 97; endspecify `endif -`ifdef arriav -specify - (A => Q) = 316; - (B => Q) = 317; - (C => Q) = 76; -endspecify -`endif -`ifdef cyclone10gx -specify - (A => Q) = 165; - (B => Q) = 162; - (C => Q) = 53; -endspecify -`endif assign Q = LUT >> {C, B, A}; @@ -242,18 +166,6 @@ specify (B => Q) = 97; endspecify `endif -`ifdef arriav -specify - (A => Q) = 316; - (B => Q) = 76; -endspecify -`endif -`ifdef cyclone10gx -specify - (A => Q) = 162; - (B => Q) = 53; -endspecify -`endif assign Q = LUT >> {B, A}; @@ -268,16 +180,6 @@ specify (A => Q) = 97; endspecify `endif -`ifdef arriav -specify - (A => Q) = 76; -endspecify -`endif -`ifdef cyclone10gx -specify - (A => Q) = 53; -endspecify -`endif assign Q = ~A; @@ -306,40 +208,6 @@ specify (CI => CO) = 36; // Divided by 2 to account for there being two ALUT_ARITHs in an ALM) endspecify `endif -`ifdef arriav -specify - (A => SO) = 744; - (B => SO) = 732; - (C => SO) = 562; - (D0 => SO) = 576; - (D1 => SO) = 511; - (CI => SO) = 249; - - (A => CO) = 629; - (B => CO) = 623; - (C => CO) = 530; - (D0 => CO) = 514; - (D1 => CO) = 696; - (CI => CO) = 10; // 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; @@ -349,283 +217,3 @@ assign q1 = LUT1 >> {D1, C, B, A}; assign {CO, SO} = q0 + !q1 + CI; endmodule - - -/* -// A, B, C0, C1, E0, E1, F0, F1: data inputs -// CARRYIN: carry input -// SHAREIN: shared-arithmetic input -// CLK0, CLK1, CLK2: clock inputs -// -// COMB0, COMB1: combinational outputs -// FF0, FF1, FF2, FF3: DFF outputs -// SUM0, SUM1: adder outputs -// CARRYOUT: carry output -// SHAREOUT: shared-arithmetic output -module MISTRAL_ALM( - input A, B, C0, C1, E0, E1, F0, F1, CARRYIN, SHAREIN, // LUT path - input CLK0, CLK1, CLK2, AC0, AC1, // FF path - output COMB0, COMB1, SUM0, SUM1, CARRYOUT, SHAREOUT, - output FF0, FF1, FF2, FF3 -); - -parameter LUT0 = 16'b0000; -parameter LUT1 = 16'b0000; -parameter LUT2 = 16'b0000; -parameter LUT3 = 16'b0000; - -parameter INIT0 = 1'b0; -parameter INIT1 = 1'b0; -parameter INIT2 = 1'b0; -parameter INIT3 = 1'b0; - -parameter C0_MUX = "C0"; -parameter C1_MUX = "C1"; - -parameter F0_MUX = "VCC"; -parameter F1_MUX = "GND"; - -parameter FEEDBACK0 = "FF0"; -parameter FEEDBACK1 = "FF2"; - -parameter ADD_MUX = "LUT"; - -parameter DFF01_DATA_MUX = "COMB"; -parameter DFF23_DATA_MUX = "COMB"; - -parameter DFF0_CLK = "CLK0"; -parameter DFF1_CLK = "CLK0"; -parameter DFF2_CLK = "CLK0"; -parameter DFF3_CLK = "CLK0"; - -parameter DFF0_AC = "AC0"; -parameter DFF1_AC = "AC0"; -parameter DFF2_AC = "AC0"; -parameter DFF3_AC = "AC0"; - -// Feedback muxes from the flip-flop outputs. -wire ff_feedback_mux0, ff_feedback_mux1; - -// C-input muxes which can be set to also use the F-input. -wire c0_input_mux, c1_input_mux; - -// F-input muxes which can be set to a constant to allow LUT5 use. -wire f0_input_mux, f1_input_mux; - -// Adder input muxes to select between shared-arithmetic mode and arithmetic mode. -wire add0_input_mux, add1_input_mux; - -// Combinational-output muxes for LUT #1 and LUT #3 -wire lut1_comb_mux, lut3_comb_mux; - -// Sum-output muxes for LUT #1 and LUT #3 -wire lut1_sum_mux, lut3_sum_mux; - -// DFF data-input muxes -wire dff01_data_mux, dff23_data_mux; - -// DFF clock selectors -wire dff0_clk, dff1_clk, dff2_clk, dff3_clk; - -// DFF asynchronous-clear selectors -wire dff0_ac, dff1_ac, dff2_ac, dff3_ac; - -// LUT, DFF and adder output wires for routing. -wire lut0_out, lut1a_out, lut1b_out, lut2_out, lut3a_out, lut3b_out; -wire dff0_out, dff1_out, dff2_out, dff3_out; -wire add0_sum, add1_sum, add0_carry, add1_carry; - -generate - if (FEEDBACK0 === "FF0") - assign ff_feedback_mux0 = dff0_out; - else if (FEEDBACK0 === "FF1") - assign ff_feedback_mux0 = dff1_out; - else - $error("Invalid FEEDBACK0 setting!"); - - if (FEEDBACK1 == "FF2") - assign ff_feedback_mux1 = dff2_out; - else if (FEEDBACK1 == "FF3") - assign ff_feedback_mux1 = dff3_out; - else - $error("Invalid FEEDBACK1 setting!"); - - if (C0_MUX === "C0") - assign c0_input_mux = C0; - else if (C0_MUX === "F1") - assign c0_input_mux = F1; - else if (C0_MUX === "FEEDBACK1") - assign c0_input_mux = ff_feedback_mux1; - else - $error("Invalid C0_MUX setting!"); - - if (C1_MUX === "C1") - assign c1_input_mux = C1; - else if (C1_MUX === "F0") - assign c1_input_mux = F0; - else if (C1_MUX === "FEEDBACK0") - assign c1_input_mux = ff_feedback_mux0; - else - $error("Invalid C1_MUX setting!"); - - // F0 == VCC is LUT5 - // F0 == F0 is LUT6 - // F0 == FEEDBACK is unknown - if (F0_MUX === "VCC") - assign f0_input_mux = 1'b1; - else if (F0_MUX === "F0") - assign f0_input_mux = F0; - else if (F0_MUX === "FEEDBACK0") - assign f0_input_mux = ff_feedback_mux0; - else - $error("Invalid F0_MUX setting!"); - - // F1 == GND is LUT5 - // F1 == F1 is LUT6 - // F1 == FEEDBACK is unknown - if (F1_MUX === "GND") - assign f1_input_mux = 1'b0; - else if (F1_MUX === "F1") - assign f1_input_mux = F1; - else if (F1_MUX === "FEEDBACK1") - assign f1_input_mux = ff_feedback_mux1; - else - $error("Invalid F1_MUX setting!"); - - if (ADD_MUX === "LUT") begin - assign add0_input_mux = ~lut1_sum_mux; - assign add1_input_mux = ~lut3_sum_mux; - end else if (ADD_MUX === "SHARE") begin - assign add0_input_mux = SHAREIN; - assign add1_input_mux = lut1_comb_mux; - end else - $error("Invalid ADD_MUX setting!"); - - if (DFF01_DATA_MUX === "COMB") - assign dff01_data_mux = COMB0; - else if (DFF01_DATA_MUX === "SUM") - assign dff01_data_mux = SUM0; - else - $error("Invalid DFF01_DATA_MUX setting!"); - - if (DFF23_DATA_MUX === "COMB") - assign dff23_data_mux = COMB0; - else if (DFF23_DATA_MUX === "SUM") - assign dff23_data_mux = SUM0; - else - $error("Invalid DFF23_DATA_MUX setting!"); - - if (DFF0_CLK === "CLK0") - assign dff0_clk = CLK0; - else if (DFF0_CLK === "CLK1") - assign dff0_clk = CLK1; - else if (DFF0_CLK === "CLK2") - assign dff0_clk = CLK2; - else - $error("Invalid DFF0_CLK setting!"); - - if (DFF1_CLK === "CLK0") - assign dff1_clk = CLK0; - else if (DFF1_CLK === "CLK1") - assign dff1_clk = CLK1; - else if (DFF1_CLK === "CLK2") - assign dff1_clk = CLK2; - else - $error("Invalid DFF1_CLK setting!"); - - if (DFF2_CLK === "CLK0") - assign dff2_clk = CLK0; - else if (DFF2_CLK === "CLK1") - assign dff2_clk = CLK1; - else if (DFF2_CLK === "CLK2") - assign dff2_clk = CLK2; - else - $error("Invalid DFF2_CLK setting!"); - - if (DFF3_CLK === "CLK0") - assign dff3_clk = CLK0; - else if (DFF3_CLK === "CLK1") - assign dff3_clk = CLK1; - else if (DFF3_CLK === "CLK2") - assign dff3_clk = CLK2; - else - $error("Invalid DFF3_CLK setting!"); - - if (DFF0_AC === "AC0") - assign dff0_ac = AC0; - else if (DFF0_AC === "AC1") - assign dff0_ac = AC1; - else - $error("Invalid DFF0_AC setting!"); - - if (DFF1_AC === "AC0") - assign dff1_ac = AC0; - else if (DFF1_AC === "AC1") - assign dff1_ac = AC1; - else - $error("Invalid DFF1_AC setting!"); - - if (DFF2_AC === "AC0") - assign dff2_ac = AC0; - else if (DFF2_AC === "AC1") - assign dff2_ac = AC1; - else - $error("Invalid DFF2_AC setting!"); - - if (DFF3_AC === "AC0") - assign dff3_ac = AC0; - else if (DFF3_AC === "AC1") - assign dff3_ac = AC1; - else - $error("Invalid DFF3_AC setting!"); - -endgenerate - -// F0 on the Quartus diagram -MISTRAL_ALUT4 #(.LUT(LUT0)) lut0 (.A(A), .B(B), .C(C0), .D(c1_input_mux), .Q(lut0_out)); - -// F2 on the Quartus diagram -MISTRAL_ALUT4 #(.LUT(LUT1)) lut1_comb (.A(A), .B(B), .C(C0), .D(c1_input_mux), .Q(lut1_comb_mux)); -MISTRAL_ALUT4 #(.LUT(LUT1)) lut1_sum (.A(A), .B(B), .C(C0), .D(E0), .Q(lut1_sum_mux)); - -// F1 on the Quartus diagram -MISTRAL_ALUT4 #(.LUT(LUT2)) lut2 (.A(A), .B(B), .C(C1), .D(c0_input_mux), .Q(lut2_out)); - -// F3 on the Quartus diagram -MISTRAL_ALUT4 #(.LUT(LUT3)) lut3_comb (.A(A), .B(B), .C(C1), .D(c0_input_mux), .Q(lut3_comb_mux)); -MISTRAL_ALUT4 #(.LUT(LUT3)) lut3_sum (.A(A), .B(B), .C(C1), .D(E1), .Q(lut3_sum_mux)); - -MISTRAL_FF #(.INIT(INIT0)) dff0 (.D(dff01_data_mux), .CLK(dff0_clk), .ACn(dff0_ac), .Q(dff0_out)); -MISTRAL_FF #(.INIT(INIT1)) dff1 (.D(dff01_data_mux), .CLK(dff1_clk), .ACn(dff1_ac), .Q(dff1_out)); -MISTRAL_FF #(.INIT(INIT2)) dff2 (.D(dff23_data_mux), .CLK(dff2_clk), .ACn(dff2_ac), .Q(dff2_out)); -MISTRAL_FF #(.INIT(INIT3)) dff3 (.D(dff23_data_mux), .CLK(dff3_clk), .ACn(dff3_ac), .Q(dff3_out)); - -// Adders -assign {add0_carry, add0_sum} = CARRYIN + lut0_out + lut1_sum_mux; -assign {add1_carry, add1_sum} = add0_carry + lut2_out + lut3_sum_mux; - -// COMBOUT outputs on the Quartus diagram -assign COMB0 = E0 ? (f0_input_mux ? lut3_comb_mux : lut1_comb_mux) - : (f0_input_mux ? lut2_out : lut0_out); - -assign COMB1 = E1 ? (f1_input_mux ? lut3_comb_mux : lut1_comb_mux) - : (f1_input_mux ? lut2_out : lut0_out); - -// SUMOUT output on the Quartus diagram -assign SUM0 = add0_sum; -assign SUM1 = add1_sum; - -// COUT output on the Quartus diagram -assign CARRYOUT = add1_carry; - -// SHAREOUT output on the Quartus diagram -assign SHAREOUT = lut3_comb_mux; - -// REGOUT outputs on the Quartus diagram -assign FF0 = dff0_out; -assign FF1 = dff1_out; -assign FF2 = dff2_out; -assign FF3 = dff3_out; - -endmodule -*/ diff --git a/techlibs/intel_alm/common/bram_m20k.txt b/techlibs/intel_alm/common/bram_m20k.txt deleted file mode 100644 index b4c5a537287..00000000000 --- a/techlibs/intel_alm/common/bram_m20k.txt +++ /dev/null @@ -1,33 +0,0 @@ -bram __MISTRAL_M20K_SDP - init 1 # TODO: Re-enable when I figure out how BRAM init works - abits 14 @D16384x1 - dbits 1 @D16384x1 - abits 13 @D8192x2 - dbits 2 @D8192x2 - abits 12 @D4096x4 @D4096x5 - dbits 4 @D4096x4 - dbits 5 @D4096x5 - abits 11 @D2048x8 @D2048x10 - dbits 8 @D2048x8 - dbits 10 @D2048x10 - abits 10 @D1024x16 @D1024x20 - dbits 16 @D1024x16 - dbits 20 @D1024x20 - abits 9 @D512x32 @D512x40 - dbits 32 @D512x32 - dbits 40 @D512x40 - groups 2 - ports 1 1 - wrmode 1 0 - # read enable; write enable + byte enables (only for multiples of 8) - enable 1 1 - transp 0 0 - clocks 1 1 - clkpol 1 1 -endbram - - -match __MISTRAL_M20K_SDP - min efficiency 5 - make_transp -endmatch diff --git a/techlibs/intel_alm/common/bram_m20k_map.v b/techlibs/intel_alm/common/bram_m20k_map.v deleted file mode 100644 index 15739d66a2e..00000000000 --- a/techlibs/intel_alm/common/bram_m20k_map.v +++ /dev/null @@ -1,31 +0,0 @@ -module __MISTRAL_M20K_SDP(CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); - -parameter CFG_ABITS = 10; -parameter CFG_DBITS = 20; -parameter CFG_ENABLE_A = 1; -parameter CFG_ENABLE_B = 1; - -input CLK1; -input [CFG_ABITS-1:0] A1ADDR, B1ADDR; -input [CFG_DBITS-1:0] A1DATA; -output [CFG_DBITS-1:0] B1DATA; -input [CFG_ENABLE_A-1:0] A1EN, B1EN; - -altsyncram #( - .operation_mode("dual_port"), - .ram_block_type("m20k"), - .widthad_a(CFG_ABITS), - .width_a(CFG_DBITS), - .widthad_b(CFG_ABITS), - .width_b(CFG_DBITS), -) _TECHMAP_REPLACE_ ( - .address_a(A1ADDR), - .data_a(A1DATA), - .wren_a(A1EN), - .address_b(B1ADDR), - .q_b(B1DATA), - .clock0(CLK1), - .clock1(CLK1) -); - -endmodule diff --git a/techlibs/intel_alm/common/dff_sim.v b/techlibs/intel_alm/common/dff_sim.v index 8d58bf61485..a558973f9fd 100644 --- a/techlibs/intel_alm/common/dff_sim.v +++ b/techlibs/intel_alm/common/dff_sim.v @@ -77,38 +77,6 @@ specify if (ACLR === 1'b0) (ACLR => Q) = 282; endspecify `endif -`ifdef arriav -specify - if (ENA && ACLR !== 1'b0 && !SCLR && !SLOAD) (posedge CLK => (Q : DATAIN)) = 470; - if (ENA && SCLR) (posedge CLK => (Q : 1'b0)) = 633; - if (ENA && !SCLR && SLOAD) (posedge CLK => (Q : SDATA)) = 439; - - $setup(DATAIN, posedge CLK, /* -170 */ 0); - $setup(ENA, posedge CLK, /* -170 */ 0); - $setup(SCLR, posedge CLK, /* -170 */ 0); - $setup(SLOAD, posedge CLK, /* -170 */ 0); - $setup(SDATA, posedge CLK, /* -170 */ 0); - - if (ACLR === 1'b0) (ACLR => Q) = 215; -endspecify -`endif -`ifdef cyclone10gx -specify - // TODO (long-term): investigate these numbers. - // It seems relying on the Quartus Timing Analyzer was not the best idea; it's too fiddly. - if (ENA && ACLR !== 1'b0 && !SCLR && !SLOAD) (posedge CLK => (Q : DATAIN)) = 219; - if (ENA && SCLR) (posedge CLK => (Q : 1'b0)) = 219; - if (ENA && !SCLR && SLOAD) (posedge CLK => (Q : SDATA)) = 219; - - $setup(DATAIN, posedge CLK, 268); - $setup(ENA, posedge CLK, 268); - $setup(SCLR, posedge CLK, 268); - $setup(SLOAD, posedge CLK, 268); - $setup(SDATA, posedge CLK, 268); - - if (ACLR === 1'b0) (ACLR => Q) = 0; -endspecify -`endif initial begin // Altera flops initialise to zero. diff --git a/techlibs/intel_alm/common/mem_sim.v b/techlibs/intel_alm/common/mem_sim.v index 563f1d2413e..5ab1b73261f 100644 --- a/techlibs/intel_alm/common/mem_sim.v +++ b/techlibs/intel_alm/common/mem_sim.v @@ -1,7 +1,7 @@ // The MLAB // -------- // In addition to Logic Array Blocks (LABs) that contain ten Adaptive Logic -// Modules (ALMs, see alm_sim.v), the Cyclone V/10GX also contain +// Modules (ALMs, see alm_sim.v), the Cyclone V also contains // Memory/Logic Array Blocks (MLABs) that can act as either ten ALMs, or utilise // the memory the ALM uses to store the look-up table data for general usage, // producing a 32 address by 20-bit block of memory. MLABs are spread out @@ -14,11 +14,8 @@ // or shift registers (by using the output of the Nth bit as input for the N+1th // bit). // -// Oddly, instead of providing a block 32 address by 20-bit cell, Quartus asks -// synthesis tools to build MLABs out of 32 address by 1-bit cells, and tries -// to put these cells in the same MLAB during cell placement. Because of this -// a MISTRAL_MLAB cell represents one of these 32 address by 1-bit cells, and -// 20 of them represent a physical MLAB. +// For historical reasons a MISTRAL_MLAB cell represents a 32 address by 1-bit cell, +// and 20 of them represent a physical MLAB. // // How the MLAB works // ------------------ @@ -28,10 +25,7 @@ // by the Yosys `memory_bram` pass, and it doesn't make sense to me to use // `techmap` just for the sake of renaming the cell ports. // -// The MLAB can be initialised to any value, but unfortunately Quartus only -// allows memory initialisation from a file. Since Yosys doesn't preserve input -// file information, or write the contents of an `initial` block to a file, -// Yosys can't currently initialise the MLAB in a way Quartus will accept. +// The MLAB can be initialised to any value. // // The MLAB takes in data from A1DATA at the rising edge of CLK1, and if A1EN // is high, writes it to the address in A1ADDR. A1EN can therefore be used to @@ -39,9 +33,7 @@ // // Simultaneously, the MLAB reads data from B1ADDR, and outputs it to B1DATA, // asynchronous to CLK1 and ignoring A1EN. If a synchronous read is needed -// then the output can be fed to embedded flops. Presently, Yosys assumes -// Quartus will pack external flops into the MLAB, but this is an assumption -// that needs testing. +// then the output can be fed to embedded flops. // The vendor sim model outputs 'x for a very short period (a few // combinational delta cycles) after each write. This has been omitted from @@ -69,33 +61,6 @@ specify (B1ADDR[4] => B1DATA) = 96; endspecify `endif -`ifdef arriav -specify - $setup(A1ADDR, posedge CLK1, 62); - $setup(A1DATA, posedge CLK1, 62); - $setup(A1EN, posedge CLK1, 62); - - (B1ADDR[0] => B1DATA) = 370; - (B1ADDR[1] => B1DATA) = 292; - (B1ADDR[2] => B1DATA) = 218; - (B1ADDR[3] => B1DATA) = 74; - (B1ADDR[4] => B1DATA) = 177; -endspecify -`endif -`ifdef cyclone10gx -// TODO: Cyclone 10 GX timings; the below timings are for Cyclone V -specify - $setup(A1ADDR, posedge CLK1, 86); - $setup(A1DATA, posedge CLK1, 86); - $setup(A1EN, posedge CLK1, 86); - - (B1ADDR[0] => B1DATA) = 487; - (B1ADDR[1] => B1DATA) = 475; - (B1ADDR[2] => B1DATA) = 382; - (B1ADDR[3] => B1DATA) = 284; - (B1ADDR[4] => B1DATA) = 96; -endspecify -`endif always @(posedge CLK1) if (A1EN) mem[A1ADDR] <= A1DATA; @@ -134,17 +99,6 @@ specify if (B1EN) (posedge CLK1 => (B1DATA : A1DATA)) = 1004; endspecify `endif -`ifdef arriav -specify - $setup(A1ADDR, posedge CLK1, 97); - $setup(A1DATA, posedge CLK1, 74); - $setup(A1EN, posedge CLK1, 109); - $setup(B1ADDR, posedge CLK1, 97); - $setup(B1EN, posedge CLK1, 126); - - if (B1EN) (posedge CLK1 => (B1DATA : A1DATA)) = 787; -endspecify -`endif always @(posedge CLK1) begin if (!A1EN) diff --git a/techlibs/intel_alm/common/quartus_rename.v b/techlibs/intel_alm/common/quartus_rename.v deleted file mode 100644 index 217dc5de98b..00000000000 --- a/techlibs/intel_alm/common/quartus_rename.v +++ /dev/null @@ -1,311 +0,0 @@ -`ifdef cyclonev -`define LCELL cyclonev_lcell_comb -`define MAC cyclonev_mac -`define MLAB cyclonev_mlab_cell -`define RAM_BLOCK cyclonev_ram_block -`define IBUF cyclonev_io_ibuf -`define OBUF cyclonev_io_obuf -`define CLKENA cyclonev_clkena -`endif -`ifdef arriav -`define LCELL arriav_lcell_comb -`define MAC arriav_mac -`define MLAB arriav_mlab_cell -`define RAM_BLOCK arriav_ram_block -`define IBUF arriav_io_ibuf -`define OBUF arriav_io_obuf -`define CLKENA arriav_clkena -`endif -`ifdef cyclone10gx -`define LCELL cyclone10gx_lcell_comb -`define MAC cyclone10gx_mac -`define MLAB cyclone10gx_mlab_cell -`define RAM_BLOCK cyclone10gx_ram_block -`define IBUF cyclone10gx_io_ibuf -`define OBUF cyclone10gx_io_obuf -`define CLKENA cyclone10gx_clkena -`endif - -module __MISTRAL_VCC(output Q); - -MISTRAL_ALUT2 #(.LUT(4'b1111)) _TECHMAP_REPLACE_ (.A(1'b1), .B(1'b1), .Q(Q)); - -endmodule - - -module __MISTRAL_GND(output Q); - -MISTRAL_ALUT2 #(.LUT(4'b0000)) _TECHMAP_REPLACE_ (.A(1'b1), .B(1'b1), .Q(Q)); - -endmodule - - -module MISTRAL_FF(input DATAIN, CLK, ACLR, ENA, SCLR, SLOAD, SDATA, output reg Q); - -dffeas #(.power_up("low"), .is_wysiwyg("true")) _TECHMAP_REPLACE_ (.d(DATAIN), .clk(CLK), .clrn(ACLR), .ena(ENA), .sclr(SCLR), .sload(SLOAD), .asdata(SDATA), .q(Q)); - -endmodule - - -module MISTRAL_ALUT6(input A, B, C, D, E, F, output Q); -parameter [63:0] LUT = 64'h0000_0000_0000_0000; - -`LCELL #(.lut_mask(LUT)) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .datad(D), .datae(E), .dataf(F), .combout(Q)); - -endmodule - - -module MISTRAL_ALUT5(input A, B, C, D, E, output Q); -parameter [31:0] LUT = 32'h0000_0000; - -`LCELL #(.lut_mask({2{LUT}})) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .datad(D), .datae(E), .combout(Q)); - -endmodule - - -module MISTRAL_ALUT4(input A, B, C, D, output Q); -parameter [15:0] LUT = 16'h0000; - -`LCELL #(.lut_mask({4{LUT}})) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .datad(D), .combout(Q)); - -endmodule - - -module MISTRAL_ALUT3(input A, B, C, output Q); -parameter [7:0] LUT = 8'h00; - -`LCELL #(.lut_mask({8{LUT}})) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .combout(Q)); - -endmodule - - -module MISTRAL_ALUT2(input A, B, output Q); -parameter [3:0] LUT = 4'h0; - -`LCELL #(.lut_mask({16{LUT}})) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .combout(Q)); - -endmodule - - -module MISTRAL_NOT(input A, output Q); - -NOT _TECHMAP_REPLACE_ (.IN(A), .OUT(Q)); - -endmodule - - -module MISTRAL_ALUT_ARITH(input A, B, C, D0, D1, CI, output SO, CO); -parameter LUT0 = 16'h0000; -parameter LUT1 = 16'h0000; - -`LCELL #(.lut_mask({16'h0, LUT1, 16'h0, LUT0})) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .datad(D0), .dataf(D1), .cin(CI), .sumout(SO), .cout(CO)); - -endmodule - - -module MISTRAL_MLAB(input [4:0] A1ADDR, input A1DATA, A1EN, CLK1, input [4:0] B1ADDR, output B1DATA); - -parameter _TECHMAP_CELLNAME_ = ""; - -// Here we get to an unfortunate situation. The cell has a mem_init0 parameter, -// which takes in a hexadecimal string that could be used to initialise RAM. -// In the vendor simulation models, this appears to work fine, but Quartus, -// either intentionally or not, forgets about this parameter and initialises the -// RAM to zero. -// -// Because of this, RAM initialisation is presently disabled, but the source -// used to generate mem_init0 is kept (commented out) in case this gets fixed -// or an undocumented way to get Quartus to initialise from mem_init0 is found. - -`MLAB #( - .logical_ram_name(_TECHMAP_CELLNAME_), - .logical_ram_depth(32), - .logical_ram_width(1), - .mixed_port_feed_through_mode("Dont Care"), - .first_bit_number(0), - .first_address(0), - .last_address(31), - .address_width(5), - .data_width(1), - .byte_enable_mask_width(1), - .port_b_data_out_clock("NONE"), - // .mem_init0($sformatf("%08x", INIT)) -) _TECHMAP_REPLACE_ ( - .portaaddr(A1ADDR), - .portadatain(A1DATA), - .portbaddr(B1ADDR), - .portbdataout(B1DATA), - .ena0(A1EN), - .clk0(CLK1) -); - -endmodule - - -module MISTRAL_M10K(A1ADDR, A1DATA, A1EN, CLK1, B1ADDR, B1DATA, B1EN); - -parameter CFG_ABITS = 10; -parameter CFG_DBITS = 10; - -parameter _TECHMAP_CELLNAME_ = ""; - -input [CFG_ABITS-1:0] A1ADDR, B1ADDR; -input [CFG_DBITS-1:0] A1DATA; -input CLK1, A1EN, B1EN; -output [CFG_DBITS-1:0] B1DATA; - -// Much like the MLAB, the M10K has mem_init[01234] parameters which would let -// you initialise the RAM cell via hex literals. If they were implemented. - -// Since the MISTRAL_M10K block has an inverted write-enable (like the real hardware) -// but the Quartus primitive expects a normal write-enable, we add an inverter. -wire A1EN_N; -NOT wren_inv (.IN(A1EN), .OUT(A1EN_N)); - -`RAM_BLOCK #( - .operation_mode("dual_port"), - .logical_ram_name(_TECHMAP_CELLNAME_), - .port_a_address_width(CFG_ABITS), - .port_a_data_width(CFG_DBITS), - .port_a_logical_ram_depth(2**CFG_ABITS), - .port_a_logical_ram_width(CFG_DBITS), - .port_a_first_address(0), - .port_a_last_address(2**CFG_ABITS - 1), - .port_a_first_bit_number(0), - .port_b_address_width(CFG_ABITS), - .port_b_data_width(CFG_DBITS), - .port_b_logical_ram_depth(2**CFG_ABITS), - .port_b_logical_ram_width(CFG_DBITS), - .port_b_first_address(0), - .port_b_last_address(2**CFG_ABITS - 1), - .port_b_first_bit_number(0), - .port_b_address_clock("clock0"), - .port_b_read_enable_clock("clock0") -) ram_block ( - .portaaddr(A1ADDR), - .portadatain(A1DATA), - .portawe(A1EN_N), - .portbaddr(B1ADDR), - .portbdataout(B1DATA), - .portbre(B1EN), - .clk0(CLK1) -); - -endmodule - - -module MISTRAL_MUL27X27(input [26:0] A, B, output [53:0] Y); - -parameter A_SIGNED = 1; -parameter B_SIGNED = 1; - -`MAC #( - .ax_width(27), - .signed_max(A_SIGNED ? "true" : "false"), - .ay_scan_in_width(27), - .signed_may(B_SIGNED ? "true" : "false"), - .result_a_width(54), - .operation_mode("M27x27") -) _TECHMAP_REPLACE_ ( - .ax(A), - .ay(B), - .resulta(Y) -); - -endmodule - - -module MISTRAL_MUL18X18(input [17:0] A, B, output [35:0] Y); - -parameter A_SIGNED = 1; -parameter B_SIGNED = 1; - -`MAC #( - .ax_width(18), - .signed_max(A_SIGNED ? "true" : "false"), - .ay_scan_in_width(18), - .signed_may(B_SIGNED ? "true" : "false"), - .result_a_width(36), - .operation_mode("M18x18_FULL") -) _TECHMAP_REPLACE_ ( - .ax(A), - .ay(B), - .resulta(Y) -); - -endmodule - - -module MISTRAL_MUL9X9(input [8:0] A, B, output [17:0] Y); - -parameter A_SIGNED = 1; -parameter B_SIGNED = 1; - -`MAC #( - .ax_width(9), - .signed_max(A_SIGNED ? "true" : "false"), - .ay_scan_in_width(9), - .signed_may(B_SIGNED ? "true" : "false"), - .result_a_width(18), - .operation_mode("M9x9") -) _TECHMAP_REPLACE_ ( - .ax(A), - .ay(B), - .resulta(Y) -); - -endmodule - -module MISTRAL_IB(input PAD, output O); -`IBUF #( - .bus_hold("false"), - .differential_mode("false") -) _TECHMAP_REPLACE_ ( - .i(PAD), - .o(O) -); -endmodule - -module MISTRAL_OB(output PAD, input I, OE); -`OBUF #( - .bus_hold("false"), - .differential_mode("false") -) _TECHMAP_REPLACE_ ( - .i(I), - .o(PAD), - .oe(OE) -); -endmodule - -module MISTRAL_IO(output PAD, input I, OE, output O); -`IBUF #( - .bus_hold("false"), - .differential_mode("false") -) ibuf ( - .i(PAD), - .o(O) -); - -`OBUF #( - .bus_hold("false"), - .differential_mode("false") -) obuf ( - .i(I), - .o(PAD), - .oe(OE) -); -endmodule - -module MISTRAL_CLKBUF (input A, output Q); -`CLKENA #( - .clock_type("auto"), - .ena_register_mode("always enabled"), - .ena_register_power_up("high"), - .disable_mode("low"), - .test_syn("high") -) _TECHMAP_REPLACE_ ( - .inclk(A), - .ena(1'b1), - .outclk(Q) -); -endmodule diff --git a/techlibs/intel_alm/synth_intel_alm.cc b/techlibs/intel_alm/synth_intel_alm.cc index c33eb43bf35..cdae9586eb0 100644 --- a/techlibs/intel_alm/synth_intel_alm.cc +++ b/techlibs/intel_alm/synth_intel_alm.cc @@ -2,7 +2,7 @@ * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Claire Xenia Wolf - * Copyright (C) 2019 Dan Ravensloft + * Copyright (C) 2019 Hannah Ravensloft * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -43,21 +43,11 @@ struct SynthIntelALMPass : public ScriptPass { log(" -family \n"); log(" target one of:\n"); log(" \"cyclonev\" - Cyclone V (default)\n"); - log(" \"arriav\" - Arria V (non-GZ)\n"); - log(" \"cyclone10gx\" - Cyclone 10GX\n"); - log("\n"); - log(" -vqm \n"); - log(" write the design to the specified Verilog Quartus Mapping File. Writing\n"); - log(" of an output file is omitted if this parameter is not specified. Implies\n"); - log(" -quartus.\n"); log("\n"); log(" -noflatten\n"); log(" do not flatten design before synthesis; useful for per-module area\n"); log(" statistics\n"); log("\n"); - log(" -quartus\n"); - log(" output a netlist using Quartus cells instead of MISTRAL_* cells\n"); - log("\n"); log(" -dff\n"); log(" pass DFFs to ABC to perform sequential logic optimisations\n"); log(" (EXPERIMENTAL)\n"); @@ -87,17 +77,15 @@ struct SynthIntelALMPass : public ScriptPass { log("\n"); } - string top_opt, family_opt, bram_type, vout_file; - bool flatten, quartus, nolutram, nobram, dff, nodsp, noiopad, noclkbuf; + string top_opt, family_opt, bram_type; + bool flatten, nolutram, nobram, dff, nodsp, noiopad, noclkbuf; void clear_flags() override { top_opt = "-auto-top"; family_opt = "cyclonev"; bram_type = "m10k"; - vout_file = ""; flatten = true; - quartus = false; nolutram = false; nobram = false; dff = false; @@ -121,11 +109,6 @@ struct SynthIntelALMPass : public ScriptPass { top_opt = "-top " + args[++argidx]; continue; } - if (args[argidx] == "-vqm" && argidx + 1 < args.size()) { - quartus = true; - vout_file = args[++argidx]; - continue; - } if (args[argidx] == "-run" && argidx + 1 < args.size()) { size_t pos = args[argidx + 1].find(':'); if (pos == std::string::npos) @@ -134,10 +117,6 @@ struct SynthIntelALMPass : public ScriptPass { run_to = args[argidx].substr(pos + 1); continue; } - if (args[argidx] == "-quartus") { - quartus = true; - continue; - } if (args[argidx] == "-nolutram") { nolutram = true; continue; @@ -173,18 +152,6 @@ struct SynthIntelALMPass : public ScriptPass { if (!design->full_selection()) log_cmd_error("This command only operates on fully selected designs!\n"); - if (family_opt == "cyclonev" || family_opt == "arriav") { - bram_type = "m10k"; - } else if (family_opt == "cyclone10gx") { - bram_type = "m20k"; - } else if (family_opt == "arriva") { - // I have typoed "arriav" as "arriva" (a local bus company) - // so many times I thought it would be funny to have an easter egg. - log_cmd_error("synth_intel_alm cannot synthesize for bus companies. (did you mean '-family arriav'?)\n"); - } else { - log_cmd_error("Invalid family specified: '%s'\n", family_opt.c_str()); - } - log_header(design, "Executing SYNTH_INTEL_ALM pass.\n"); log_push(); @@ -237,22 +204,16 @@ struct SynthIntelALMPass : public ScriptPass { if (help_mode) { run("techmap -map +/mul2dsp.v [...]", "(unless -nodsp)"); } else if (!nodsp) { - // Cyclone V/Arria V supports 9x9 multiplication, Cyclone 10 GX does not. run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=27 -D DSP_B_MAXWIDTH=27 -D DSP_A_MINWIDTH=19 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL27X27"); run("chtype -set $mul t:$__soft_mul"); run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=27 -D DSP_B_MAXWIDTH=27 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=19 -D DSP_NAME=__MUL27X27"); run("chtype -set $mul t:$__soft_mul"); - if (family_opt == "cyclonev" || family_opt == "arriav") { - run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=10 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL18X18"); - run("chtype -set $mul t:$__soft_mul"); - run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=10 -D DSP_NAME=__MUL18X18"); - run("chtype -set $mul t:$__soft_mul"); - run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=9 -D DSP_B_MAXWIDTH=9 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL9X9"); - run("chtype -set $mul t:$__soft_mul"); - } else if (family_opt == "cyclone10gx") { - run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL18X18"); - run("chtype -set $mul t:$__soft_mul"); - } + run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=10 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL18X18"); + run("chtype -set $mul t:$__soft_mul"); + run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=10 -D DSP_NAME=__MUL18X18"); + run("chtype -set $mul t:$__soft_mul"); + run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=9 -D DSP_B_MAXWIDTH=9 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL9X9"); + run("chtype -set $mul t:$__soft_mul"); } run("alumacc"); if (!noiopad) @@ -269,7 +230,7 @@ struct SynthIntelALMPass : public ScriptPass { } if (!nolutram && check_label("map_lutram", "(skip if -nolutram)")) { - run("memory_bram -rules +/intel_alm/common/lutram_mlab.txt", "(for Cyclone V / Cyclone 10GX)"); + run("memory_bram -rules +/intel_alm/common/lutram_mlab.txt", "(for Cyclone V)"); } if (check_label("map_ffram")) { @@ -303,28 +264,6 @@ struct SynthIntelALMPass : public ScriptPass { run("check"); run("blackbox =A:whitebox"); } - - if (check_label("quartus")) { - if (quartus || help_mode) { - // Quartus ICEs if you have a wire which has `[]` in its name, - // which Yosys produces when building memories out of flops. - run("rename -hide w:*[* w:*]*"); - // VQM mode does not support 'x, so replace those with zero. - run("setundef -zero"); - // VQM mode does not support multi-bit constant assignments - // (e.g. 2'b00 is an error), so as a workaround use references - // to constant driver cells, which Quartus accepts. - run("hilomap -singleton -hicell __MISTRAL_VCC Q -locell __MISTRAL_GND Q"); - // Rename from Yosys-internal MISTRAL_* cells to Quartus cells. - run(stringf("techmap -D %s -map +/intel_alm/common/quartus_rename.v", family_opt.c_str())); - } - } - - if (check_label("vqm")) { - if (!vout_file.empty() || help_mode) { - run(stringf("write_verilog -attr2comment -defparam -nohex -decimal %s", help_mode ? "" : vout_file.c_str())); - } - } } } SynthIntelALMPass;