3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-20 07:36:39 +00:00
This commit is contained in:
Atl 2025-04-16 17:20:09 +02:00 committed by GitHub
commit 8ee74430ca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 1736 additions and 0 deletions

View file

@ -0,0 +1,22 @@
OBJS += techlibs/intel_le/synth_intel_le.o
# Techmap
$(eval $(call add_share_file,share/intel_le/common,techlibs/intel_le/common/abc9_map.v))
$(eval $(call add_share_file,share/intel_le/common,techlibs/intel_le/common/abc9_unmap.v))
$(eval $(call add_share_file,share/intel_le/common,techlibs/intel_le/common/abc9_model.v))
$(eval $(call add_share_file,share/intel_le/common,techlibs/intel_le/common/le_map.v))
$(eval $(call add_share_file,share/intel_le/common,techlibs/intel_le/common/le_sim.v))
$(eval $(call add_share_file,share/intel_le/common,techlibs/intel_le/common/arith_le_map.v))
$(eval $(call add_share_file,share/intel_le/common,techlibs/intel_le/common/dff_map.v))
$(eval $(call add_share_file,share/intel_le/common,techlibs/intel_le/common/dff_sim.v))
$(eval $(call add_share_file,share/intel_le/common,techlibs/intel_le/common/mem_sim.v))
$(eval $(call add_share_file,share/intel_le/cycloneiv,techlibs/intel_le/cycloneiv/cells_sim.v))
# RAM
$(eval $(call add_share_file,share/intel_le/common,techlibs/intel_le/common/bram_m9k.txt))
# Miscellaneous
$(eval $(call add_share_file,share/intel_le/common,techlibs/intel_le/common/megafunction_bb.v))
$(eval $(call add_share_file,share/intel_le/common,techlibs/intel_le/common/quartus_rename.v))

View file

@ -0,0 +1,18 @@
// This file exists to map purely-synchronous flops to ABC9 flops, while
// mapping flops with asynchronous-clear as boxes, this is because ABC9
// doesn't support asynchronous-clear flops in sequential synthesis.
module MISTRAL_FF(
input DATAIN, CLK, ACLR, ENA, SCLR, SLOAD, SDATA,
output reg Q
);
parameter _TECHMAP_CONSTMSK_ACLR_ = 1'b0;
// If the async-clear is constant, we assume it's disabled.
if (_TECHMAP_CONSTMSK_ACLR_ != 1'b0)
$__MISTRAL_FF_SYNCONLY _TECHMAP_REPLACE_ (.DATAIN(DATAIN), .CLK(CLK), .ENA(ENA), .SCLR(SCLR), .SLOAD(SLOAD), .SDATA(SDATA), .Q(Q));
else
wire _TECHMAP_FAIL_ = 1;
endmodule

View file

@ -0,0 +1,10 @@
// This is a purely-synchronous flop, that ABC9 can use for sequential synthesis.
(* abc9_flop, lib_whitebox *)
module $__MISTRAL_FF_SYNCONLY (
input DATAIN, CLK, ENA, SCLR, SLOAD, SDATA,
output reg Q
);
MISTRAL_FF ff (.DATAIN(DATAIN), .CLK(CLK), .ENA(ENA), .ACLR(1'b1), .SCLR(SCLR), .SLOAD(SLOAD), .SDATA(SDATA), .Q(Q));
endmodule

View file

@ -0,0 +1,11 @@
// After performing sequential synthesis, map the synchronous flops back to
// standard MISTRAL_FF flops.
module $__MISTRAL_FF_SYNCONLY (
input DATAIN, CLK, ENA, SCLR, SLOAD, SDATA,
output reg Q
);
MISTRAL_FF _TECHMAP_REPLACE_ (.DATAIN(DATAIN), .CLK(CLK), .ACLR(1'b1), .ENA(ENA), .SCLR(SCLR), .SLOAD(SLOAD), .SDATA(SDATA), .Q(Q));
endmodule

View file

@ -0,0 +1,66 @@
`default_nettype none
module \$alu (A, B, CI, BI, X, Y, CO);
parameter A_SIGNED = 0;
parameter B_SIGNED = 0;
parameter A_WIDTH = 1;
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
parameter _TECHMAP_CONSTMSK_CI_ = 0;
parameter _TECHMAP_CONSTVAL_CI_ = 0;
(* force_downto *)
input [A_WIDTH-1:0] A;
(* force_downto *)
input [B_WIDTH-1:0] B;
input CI, BI;
(* force_downto *)
output [Y_WIDTH-1:0] X, Y, CO;
(* force_downto *)
wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
(* force_downto *)
wire [Y_WIDTH-1:0] AA = A_buf;
(* force_downto *)
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
(* force_downto *)
wire [Y_WIDTH-1:0] BX = B_buf;
wire [Y_WIDTH-1:0] BTOADDER;
wire [Y_WIDTH:0] LE_CARRY;
// Start of carry chain
generate
if (_TECHMAP_CONSTMSK_CI_ == 1) begin
assign LE_CARRY[0] = _TECHMAP_CONSTVAL_CI_;
end else begin
assign LE_CARRY[0] = CI;
end
endgenerate
// Carry chain
genvar i;
generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice
MISTRAL_ALUT_ARITH #(
.LUT(16'b1001_0110_1110_1000), // SUM = A xor B xor CI
// CARRYi+1 = A and B or A and CI or B and CI
) le_i (
.A(AA[i]), .B(BB[i]), .C(1'b1), .D(1'b1),
.CI(LE_CARRY[i]),
.SO(Y[i]),
.CO(LE_CARRY[i+1])
);
end endgenerate
assign X = AA ^ BB;
endmodule

View file

@ -0,0 +1,32 @@
bram MISTRAL_M9K
init 0 # TODO: Re-enable when I figure out how BRAM init works
abits 13 @D8192x1
dbits 1 @D8192x1
abits 12 @D4096x2
dbits 2 @D4096x2
abits 11 @D2048x4
dbits 4 @D2048x4
abits 10 @D1024x8 @D1024x9
dbits 8 @D1024x8
dbits 9 @D1024x9
abits 9 @D512x16 @D512x18
dbits 16 @D512x16
dbits 18 @D512x18
abits 8 @D256x32 @D256x36
dbits 32 @D256x32
dbits 36 @D256x36
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_M9K
min efficiency 5
make_transp
endmatch

View file

@ -0,0 +1,13 @@
`default_nettype none
// D flip-flop with async reset and enable
module \$_DFFE_PN0P_ (input D, C, R, E, output Q);
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(R), .ENA(E), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
endmodule
// D flip-flop with sync reset and enable (enable has priority)
module \$_SDFFCE_PP0P_ (input D, C, R, E, output Q);
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(1'b1), .ENA(E), .SCLR(R), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
endmodule

View file

@ -0,0 +1,90 @@
// What the flops can do
// ---------------------
// The core flop acts as a single-bit memory that initialises to zero at chip
// reset. It takes in data on the rising edge of CLK if ENA is high,
// and outputs it to Q. The ENA (clock enable) pin can therefore be used to
// capture the input only if a condition is true.
//
// The data itself is zero if SCLR (synchronous clear) is high, else it comes
// from SDATA (synchronous data) if SLOAD (synchronous load) is high, or DATAIN
// if SLOAD is low.
//
// If ACLR (asynchronous clear) is low then Q is forced to zero, regardless of
// the synchronous inputs or CLK edge. This is most often used for an FPGA-wide
// power-on reset.
//
// An asynchronous set that sets Q to one can be emulated by inverting the input
// and output of the flop, resulting in ACLR forcing Q to zero, which then gets
// inverted to produce one. Likewise, logic can operate on the falling edge of
// CLK if CLK is inverted before being passed as an input.
//
// What the flops *can't* do
// -------------------------
// The trickiest part of the above capabilities is the lack of configurable
// initialisation state. For example, it isn't possible to implement a flop with
// asynchronous clear that initialises to one, because the hardware initialises
// to zero. Likewise, you can't emulate a flop with asynchronous set that
// initialises to zero, because the inverters mean the flop initialises to one.
//
// If the input design requires one of these cells (which appears to be rare
// in practice) then synth_intel_alm will fail to synthesize the design where
// other Yosys synthesis scripts might succeed.
//
// This stands in notable contrast to e.g. Xilinx flip-flops, which have
// configurable initialisation state and native synchronous/asynchronous
// set/clear (although not at the same time), which means they can generally
// implement a much wider variety of logic.
// DATAIN: synchronous data input
// CLK: clock input (positive edge)
// ACLR: asynchronous clear (negative-true)
// ENA: clock-enable
// SCLR: synchronous clear
// SLOAD: synchronous load
// SDATA: synchronous load data
//
// Q: data output
//
// Note: the DFFEAS primitive is mostly emulated; it does not reflect what the hardware implements.
(* abc9_box, lib_whitebox *)
module MISTRAL_FF(
input DATAIN, CLK, ACLR, ENA, SCLR, SLOAD, SDATA,
output reg Q
);
`ifdef cycloneiv
specify
if (ENA && ACLR !== 1'b0 && !SCLR && !SLOAD) (posedge CLK => (Q : DATAIN)) = 731;
if (ENA && SCLR) (posedge CLK => (Q : 1'b0)) = 890;
if (ENA && !SCLR && SLOAD) (posedge CLK => (Q : SDATA)) = 618;
$setup(DATAIN, posedge CLK, /* -196 */ 0);
$setup(ENA, posedge CLK, /* -196 */ 0);
$setup(SCLR, posedge CLK, /* -196 */ 0);
$setup(SLOAD, posedge CLK, /* -196 */ 0);
$setup(SDATA, posedge CLK, /* -196 */ 0);
if (ACLR === 1'b0) (ACLR => Q) = 282;
endspecify
`endif
initial begin
// Altera flops initialise to zero.
Q = 0;
end
always @(posedge CLK, negedge ACLR) begin
// Asynchronous clear
if (!ACLR) Q <= 0;
// Clock-enable
else if (ENA) begin
// Synchronous clear
if (SCLR) Q <= 0;
// Synchronous load
else if (SLOAD) Q <= SDATA;
else Q <= DATAIN;
end
end
endmodule

View file

@ -0,0 +1,47 @@
module \$lut (A, Y);
parameter WIDTH = 1;
parameter LUT = 0;
(* force_downto *)
input [WIDTH-1:0] A;
output Y;
generate
if (WIDTH == 1) begin
generate
if (LUT == 2'b00) begin
assign Y = 1'b0;
end
else if (LUT == 2'b01) begin
MISTRAL_NOT _TECHMAP_REPLACE_(
.A(A[0]), .Q(Y)
);
end
else if (LUT == 2'b10) begin
assign Y = A;
end
else if (LUT == 2'b11) begin
assign Y = 1'b1;
end
endgenerate
end else
if (WIDTH == 2) begin
MISTRAL_ALUT2 #(.LUT(LUT)) _TECHMAP_REPLACE_(
.A(A[0]), .B(A[1]), .Q(Y)
);
end else
if (WIDTH == 3) begin
MISTRAL_ALUT3 #(.LUT(LUT)) _TECHMAP_REPLACE_(
.A(A[0]), .B(A[1]), .C(A[2]), .Q(Y)
);
end else
if (WIDTH == 4) begin
MISTRAL_ALUT4 #(.LUT(LUT)) _TECHMAP_REPLACE_(
.A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]), .Q(Y)
);
end else begin
wire _TECHMAP_FAIL_ = 1'b1;
end
endgenerate
endmodule

View file

@ -0,0 +1,127 @@
// The core logic primitive of the Cyclone IVE/IVGX is the Logic Element
// (LE). Each LE is made up of an 4-input, 1-output look-up table, covered
// in this file, connected to combinational outputs, a carry chain, and one
// D flip-flop (which are covered as MISTRAL_FF in dff_sim.v).
//
// LEs are have two modes of operation
//
// Normal (combinational) mode
// ---------------------------
// The LE can implement:
// - a single 4-input(or less) function
//
// Normal-mode functions are represented as MISTRAL_ALUTN cells with N inputs.
//
// Arithmetic mode
// ---------------
// In arithmetic mode, LE implements two bit adder and carry chain
// It can drive either registered or unregistered output.
//
// The cell for an arithmetic-mode is MISTRAL_ALM_ARITH.
//
`default_nettype none
// Cyclone V LUT output timings (picoseconds):
//
// CARRY A B C D
// COMBOUT ?408? 332 337 220 119
// CARRYOUT 200 376 385 ? -
(* abc9_lut=1, lib_whitebox *)
module MISTRAL_ALUT4(input A, B, C, D, output Q);
parameter [15:0] LUT = 16'h0000;
`ifdef cycloneiv
specify
(A => Q) = 337;
(B => Q) = 332;
(C => Q) = 220;
(D => Q) = 119;
endspecify
`endif
assign Q = LUT >> {D, C, B, A};
endmodule
(* abc9_lut=1, lib_whitebox *)
module MISTRAL_ALUT3(input A, B, C, output Q);
parameter [7:0] LUT = 8'h00;
`ifdef cycloneiv
specify
(A => Q) = 332;
(B => Q) = 220;
(C => Q) = 119;
endspecify
`endif
assign Q = LUT >> {C, B, A};
endmodule
(* abc9_lut=1, lib_whitebox *)
module MISTRAL_ALUT2(input A, B, output Q);
parameter [3:0] LUT = 4'h0;
`ifdef cycloneiv
specify
(A => Q) = 220;
(B => Q) = 119;
endspecify
`endif
assign Q = LUT >> {B, A};
endmodule
(* abc9_lut=1, lib_whitebox *)
module MISTRAL_NOT(input A, output Q);
`ifdef cycloneiv
specify
(A => Q) = 119;
endspecify
`endif
assign Q = ~A;
endmodule
(* abc9_box, lib_whitebox *)
module MISTRAL_ALUT_ARITH(input A, B, C, D, (* abc9_carry *) input CI, output SO, (* abc9_carry *) output CO);
parameter LUT = 16'h0000;
`ifdef cycloneiv
specify
(A => SO) = 337;
(B => SO) = 332;
(C => SO) = 220;
(D => SO) = 119;
(CI => SO) = 08;
(A => CO) = 385;
(B => CO) = 376;
(CI => CO) = 200;
endspecify
`endif
wire q0, q1;
assign q0 = LUT >> {'b0, CI, B, A};
assign q1 = LUT >> {D, CI, B, A};
assign SO = q1;
assign CO = q0;
endmodule

View file

@ -0,0 +1,592 @@
// Intel megafunction declarations, to avoid Yosys complaining.
`default_nettype none
(* blackbox *)
module altera_pll
#(
parameter reference_clock_frequency = "0 ps",
parameter fractional_vco_multiplier = "false",
parameter pll_type = "General",
parameter pll_subtype = "General",
parameter number_of_clocks = 1,
parameter operation_mode = "internal feedback",
parameter deserialization_factor = 4,
parameter data_rate = 0,
parameter sim_additional_refclk_cycles_to_lock = 0,
parameter output_clock_frequency0 = "0 ps",
parameter phase_shift0 = "0 ps",
parameter duty_cycle0 = 50,
parameter output_clock_frequency1 = "0 ps",
parameter phase_shift1 = "0 ps",
parameter duty_cycle1 = 50,
parameter output_clock_frequency2 = "0 ps",
parameter phase_shift2 = "0 ps",
parameter duty_cycle2 = 50,
parameter output_clock_frequency3 = "0 ps",
parameter phase_shift3 = "0 ps",
parameter duty_cycle3 = 50,
parameter output_clock_frequency4 = "0 ps",
parameter phase_shift4 = "0 ps",
parameter duty_cycle4 = 50,
parameter output_clock_frequency5 = "0 ps",
parameter phase_shift5 = "0 ps",
parameter duty_cycle5 = 50,
parameter output_clock_frequency6 = "0 ps",
parameter phase_shift6 = "0 ps",
parameter duty_cycle6 = 50,
parameter output_clock_frequency7 = "0 ps",
parameter phase_shift7 = "0 ps",
parameter duty_cycle7 = 50,
parameter output_clock_frequency8 = "0 ps",
parameter phase_shift8 = "0 ps",
parameter duty_cycle8 = 50,
parameter output_clock_frequency9 = "0 ps",
parameter phase_shift9 = "0 ps",
parameter duty_cycle9 = 50,
parameter output_clock_frequency10 = "0 ps",
parameter phase_shift10 = "0 ps",
parameter duty_cycle10 = 50,
parameter output_clock_frequency11 = "0 ps",
parameter phase_shift11 = "0 ps",
parameter duty_cycle11 = 50,
parameter output_clock_frequency12 = "0 ps",
parameter phase_shift12 = "0 ps",
parameter duty_cycle12 = 50,
parameter output_clock_frequency13 = "0 ps",
parameter phase_shift13 = "0 ps",
parameter duty_cycle13 = 50,
parameter output_clock_frequency14 = "0 ps",
parameter phase_shift14 = "0 ps",
parameter duty_cycle14 = 50,
parameter output_clock_frequency15 = "0 ps",
parameter phase_shift15 = "0 ps",
parameter duty_cycle15 = 50,
parameter output_clock_frequency16 = "0 ps",
parameter phase_shift16 = "0 ps",
parameter duty_cycle16 = 50,
parameter output_clock_frequency17 = "0 ps",
parameter phase_shift17 = "0 ps",
parameter duty_cycle17 = 50,
parameter clock_name_0 = "",
parameter clock_name_1 = "",
parameter clock_name_2 = "",
parameter clock_name_3 = "",
parameter clock_name_4 = "",
parameter clock_name_5 = "",
parameter clock_name_6 = "",
parameter clock_name_7 = "",
parameter clock_name_8 = "",
parameter clock_name_global_0 = "false",
parameter clock_name_global_1 = "false",
parameter clock_name_global_2 = "false",
parameter clock_name_global_3 = "false",
parameter clock_name_global_4 = "false",
parameter clock_name_global_5 = "false",
parameter clock_name_global_6 = "false",
parameter clock_name_global_7 = "false",
parameter clock_name_global_8 = "false",
parameter m_cnt_hi_div = 1,
parameter m_cnt_lo_div = 1,
parameter m_cnt_bypass_en = "false",
parameter m_cnt_odd_div_duty_en = "false",
parameter n_cnt_hi_div = 1,
parameter n_cnt_lo_div = 1,
parameter n_cnt_bypass_en = "false",
parameter n_cnt_odd_div_duty_en = "false",
parameter c_cnt_hi_div0 = 1,
parameter c_cnt_lo_div0 = 1,
parameter c_cnt_bypass_en0 = "false",
parameter c_cnt_in_src0 = "ph_mux_clk",
parameter c_cnt_odd_div_duty_en0 = "false",
parameter c_cnt_prst0 = 1,
parameter c_cnt_ph_mux_prst0 = 0,
parameter c_cnt_hi_div1 = 1,
parameter c_cnt_lo_div1 = 1,
parameter c_cnt_bypass_en1 = "false",
parameter c_cnt_in_src1 = "ph_mux_clk",
parameter c_cnt_odd_div_duty_en1 = "false",
parameter c_cnt_prst1 = 1,
parameter c_cnt_ph_mux_prst1 = 0,
parameter c_cnt_hi_div2 = 1,
parameter c_cnt_lo_div2 = 1,
parameter c_cnt_bypass_en2 = "false",
parameter c_cnt_in_src2 = "ph_mux_clk",
parameter c_cnt_odd_div_duty_en2 = "false",
parameter c_cnt_prst2 = 1,
parameter c_cnt_ph_mux_prst2 = 0,
parameter c_cnt_hi_div3 = 1,
parameter c_cnt_lo_div3 = 1,
parameter c_cnt_bypass_en3 = "false",
parameter c_cnt_in_src3 = "ph_mux_clk",
parameter c_cnt_odd_div_duty_en3 = "false",
parameter c_cnt_prst3 = 1,
parameter c_cnt_ph_mux_prst3 = 0,
parameter c_cnt_hi_div4 = 1,
parameter c_cnt_lo_div4 = 1,
parameter c_cnt_bypass_en4 = "false",
parameter c_cnt_in_src4 = "ph_mux_clk",
parameter c_cnt_odd_div_duty_en4 = "false",
parameter c_cnt_prst4 = 1,
parameter c_cnt_ph_mux_prst4 = 0,
parameter c_cnt_hi_div5 = 1,
parameter c_cnt_lo_div5 = 1,
parameter c_cnt_bypass_en5 = "false",
parameter c_cnt_in_src5 = "ph_mux_clk",
parameter c_cnt_odd_div_duty_en5 = "false",
parameter c_cnt_prst5 = 1,
parameter c_cnt_ph_mux_prst5 = 0,
parameter c_cnt_hi_div6 = 1,
parameter c_cnt_lo_div6 = 1,
parameter c_cnt_bypass_en6 = "false",
parameter c_cnt_in_src6 = "ph_mux_clk",
parameter c_cnt_odd_div_duty_en6 = "false",
parameter c_cnt_prst6 = 1,
parameter c_cnt_ph_mux_prst6 = 0,
parameter c_cnt_hi_div7 = 1,
parameter c_cnt_lo_div7 = 1,
parameter c_cnt_bypass_en7 = "false",
parameter c_cnt_in_src7 = "ph_mux_clk",
parameter c_cnt_odd_div_duty_en7 = "false",
parameter c_cnt_prst7 = 1,
parameter c_cnt_ph_mux_prst7 = 0,
parameter c_cnt_hi_div8 = 1,
parameter c_cnt_lo_div8 = 1,
parameter c_cnt_bypass_en8 = "false",
parameter c_cnt_in_src8 = "ph_mux_clk",
parameter c_cnt_odd_div_duty_en8 = "false",
parameter c_cnt_prst8 = 1,
parameter c_cnt_ph_mux_prst8 = 0,
parameter c_cnt_hi_div9 = 1,
parameter c_cnt_lo_div9 = 1,
parameter c_cnt_bypass_en9 = "false",
parameter c_cnt_in_src9 = "ph_mux_clk",
parameter c_cnt_odd_div_duty_en9 = "false",
parameter c_cnt_prst9 = 1,
parameter c_cnt_ph_mux_prst9 = 0,
parameter c_cnt_hi_div10 = 1,
parameter c_cnt_lo_div10 = 1,
parameter c_cnt_bypass_en10 = "false",
parameter c_cnt_in_src10 = "ph_mux_clk",
parameter c_cnt_odd_div_duty_en10 = "false",
parameter c_cnt_prst10 = 1,
parameter c_cnt_ph_mux_prst10 = 0,
parameter c_cnt_hi_div11 = 1,
parameter c_cnt_lo_div11 = 1,
parameter c_cnt_bypass_en11 = "false",
parameter c_cnt_in_src11 = "ph_mux_clk",
parameter c_cnt_odd_div_duty_en11 = "false",
parameter c_cnt_prst11 = 1,
parameter c_cnt_ph_mux_prst11 = 0,
parameter c_cnt_hi_div12 = 1,
parameter c_cnt_lo_div12 = 1,
parameter c_cnt_bypass_en12 = "false",
parameter c_cnt_in_src12 = "ph_mux_clk",
parameter c_cnt_odd_div_duty_en12 = "false",
parameter c_cnt_prst12 = 1,
parameter c_cnt_ph_mux_prst12 = 0,
parameter c_cnt_hi_div13 = 1,
parameter c_cnt_lo_div13 = 1,
parameter c_cnt_bypass_en13 = "false",
parameter c_cnt_in_src13 = "ph_mux_clk",
parameter c_cnt_odd_div_duty_en13 = "false",
parameter c_cnt_prst13 = 1,
parameter c_cnt_ph_mux_prst13 = 0,
parameter c_cnt_hi_div14 = 1,
parameter c_cnt_lo_div14 = 1,
parameter c_cnt_bypass_en14 = "false",
parameter c_cnt_in_src14 = "ph_mux_clk",
parameter c_cnt_odd_div_duty_en14 = "false",
parameter c_cnt_prst14 = 1,
parameter c_cnt_ph_mux_prst14 = 0,
parameter c_cnt_hi_div15 = 1,
parameter c_cnt_lo_div15 = 1,
parameter c_cnt_bypass_en15 = "false",
parameter c_cnt_in_src15 = "ph_mux_clk",
parameter c_cnt_odd_div_duty_en15 = "false",
parameter c_cnt_prst15 = 1,
parameter c_cnt_ph_mux_prst15 = 0,
parameter c_cnt_hi_div16 = 1,
parameter c_cnt_lo_div16 = 1,
parameter c_cnt_bypass_en16 = "false",
parameter c_cnt_in_src16 = "ph_mux_clk",
parameter c_cnt_odd_div_duty_en16 = "false",
parameter c_cnt_prst16 = 1,
parameter c_cnt_ph_mux_prst16 = 0,
parameter c_cnt_hi_div17 = 1,
parameter c_cnt_lo_div17 = 1,
parameter c_cnt_bypass_en17 = "false",
parameter c_cnt_in_src17 = "ph_mux_clk",
parameter c_cnt_odd_div_duty_en17 = "false",
parameter c_cnt_prst17 = 1,
parameter c_cnt_ph_mux_prst17 = 0,
parameter pll_vco_div = 1,
parameter pll_slf_rst = "false",
parameter pll_bw_sel = "low",
parameter pll_output_clk_frequency = "0 MHz",
parameter pll_cp_current = 0,
parameter pll_bwctrl = 0,
parameter pll_fractional_division = 1,
parameter pll_fractional_cout = 24,
parameter pll_dsm_out_sel = "1st_order",
parameter mimic_fbclk_type = "gclk",
parameter pll_fbclk_mux_1 = "glb",
parameter pll_fbclk_mux_2 = "fb_1",
parameter pll_m_cnt_in_src = "ph_mux_clk",
parameter pll_vcoph_div = 1,
parameter refclk1_frequency = "0 MHz",
parameter pll_clkin_0_src = "clk_0",
parameter pll_clkin_1_src = "clk_0",
parameter pll_clk_loss_sw_en = "false",
parameter pll_auto_clk_sw_en = "false",
parameter pll_manu_clk_sw_en = "false",
parameter pll_clk_sw_dly = 0,
parameter pll_extclk_0_cnt_src = "pll_extclk_cnt_src_vss",
parameter pll_extclk_1_cnt_src = "pll_extclk_cnt_src_vss"
) (
//input
input refclk,
input refclk1,
input fbclk,
input rst,
input phase_en,
input updn,
input [2:0] num_phase_shifts,
input scanclk,
input [4:0] cntsel,
input [63:0] reconfig_to_pll,
input extswitch,
input adjpllin,
input cclk,
//output
output [ number_of_clocks -1 : 0] outclk,
output fboutclk,
output locked,
output phase_done,
output [63:0] reconfig_from_pll,
output activeclk,
output [1:0] clkbad,
output [7:0] phout,
output [1:0] lvds_clk,
output [1:0] loaden,
output [1:0] extclk_out,
output [ number_of_clocks -1 : 0] cascade_out,
//inout
inout zdbfbclk
);
endmodule
(* blackbox *)
module altera_std_synchronizer(clk, din, dout, reset_n);
parameter depth = 2;
input clk;
input reset_n;
input din;
output dout;
endmodule
(* blackbox *)
module altddio_in (
datain, // required port, DDR input data
inclock, // required port, input reference clock to sample data by
inclocken, // enable data clock
aset, // asynchronous set
aclr, // asynchronous clear
sset, // synchronous set
sclr, // synchronous clear
dataout_h, // data sampled at the rising edge of inclock
dataout_l // data sampled at the falling edge of inclock
);
parameter width = 1;
parameter power_up_high = "OFF";
parameter invert_input_clocks = "OFF";
parameter intended_device_family = "Stratix";
parameter lpm_type = "altddio_in";
parameter lpm_hint = "UNUSED";
input [width-1:0] datain;
input inclock;
input inclocken;
input aset;
input aclr;
input sset;
input sclr;
output [width-1:0] dataout_h;
output [width-1:0] dataout_l;
endmodule
(* blackbox *)
module altddio_out (
datain_h,
datain_l,
outclock,
outclocken,
aset,
aclr,
sset,
sclr,
oe,
dataout,
oe_out
);
parameter width = 1;
parameter power_up_high = "OFF";
parameter oe_reg = "UNUSED";
parameter extend_oe_disable = "UNUSED";
parameter intended_device_family = "Stratix";
parameter invert_output = "OFF";
parameter lpm_type = "altddio_out";
parameter lpm_hint = "UNUSED";
input [width-1:0] datain_h;
input [width-1:0] datain_l;
input outclock;
input outclocken;
input aset;
input aclr;
input sset;
input sclr;
input oe;
output [width-1:0] dataout;
output [width-1:0] oe_out;
endmodule
(* blackbox *)
module altddio_bidir (
datain_h,
datain_l,
inclock,
inclocken,
outclock,
outclocken,
aset,
aclr,
sset,
sclr,
oe,
dataout_h,
dataout_l,
combout,
oe_out,
dqsundelayedout,
padio
);
// GLOBAL PARAMETER DECLARATION
parameter width = 1; // required parameter
parameter power_up_high = "OFF";
parameter oe_reg = "UNUSED";
parameter extend_oe_disable = "UNUSED";
parameter implement_input_in_lcell = "UNUSED";
parameter invert_output = "OFF";
parameter intended_device_family = "Stratix";
parameter lpm_type = "altddio_bidir";
parameter lpm_hint = "UNUSED";
// INPUT PORT DECLARATION
input [width-1:0] datain_h;
input [width-1:0] datain_l;
input inclock;
input inclocken;
input outclock;
input outclocken;
input aset;
input aclr;
input sset;
input sclr;
input oe;
// OUTPUT PORT DECLARATION
output [width-1:0] dataout_h;
output [width-1:0] dataout_l;
output [width-1:0] combout;
output [width-1:0] oe_out;
output [width-1:0] dqsundelayedout;
// BIDIRECTIONAL PORT DECLARATION
inout [width-1:0] padio;
endmodule
(* blackbox *)
module altiobuf_in(datain, dataout);
parameter enable_bus_hold = "FALSE";
parameter use_differential_mode = "FALSE";
parameter number_of_channels = 1;
input [number_of_channels-1:0] datain;
output [number_of_channels-1:0] dataout;
endmodule
(* blackbox *)
module altiobuf_out(datain, dataout);
parameter enable_bus_hold = "FALSE";
parameter use_differential_mode = "FALSE";
parameter use_oe = "FALSE";
parameter number_of_channels = 1;
input [number_of_channels-1:0] datain;
output [number_of_channels-1:0] dataout;
endmodule
(* blackbox *)
module altiobuf_bidir(dataio, oe, datain, dataout);
parameter number_of_channels = 1;
parameter enable_bus_hold = "OFF";
inout [number_of_channels-1:0] dataio;
input [number_of_channels-1:0] datain;
output [number_of_channels-1:0] dataout;
input [number_of_channels-1:0] oe;
endmodule
(* blackbox *)
module altsyncram(clock0, clock1, address_a, data_a, rden_a, wren_a, byteena_a, q_a, addressstall_a, address_b, data_b, rden_b, wren_b, byteena_b, q_b, addressstall_b, clocken0, clocken1, clocken2, clocken3, aclr0, aclr1, eccstatus);
parameter lpm_type = "altsyncram";
parameter operation_mode = "dual_port";
parameter ram_block_type = "auto";
parameter intended_device_family = "auto";
parameter power_up_uninitialized = "false";
parameter read_during_write_mode_mixed_ports = "dontcare";
parameter byte_size = 8;
parameter widthad_a = 1;
parameter width_a = 1;
parameter width_byteena_a = 1;
parameter numwords_a = 1;
parameter clock_enable_input_a = "clocken0";
parameter widthad_b = 1;
parameter width_b = 1;
parameter numwords_b = 1;
parameter address_aclr_b = "aclr0";
parameter address_reg_b = "";
parameter outdata_aclr_b = "aclr0";
parameter outdata_reg_b = "";
parameter clock_enable_input_b = "clocken0";
parameter clock_enable_output_b = "clocken0";
input clock0, clock1;
input [widthad_a-1:0] address_a;
input [width_a-1:0] data_a;
input rden_a;
input wren_a;
input [(width_a/8)-1:0] byteena_a;
input addressstall_a;
output [width_a-1:0] q_a;
input wren_b;
input rden_b;
input [widthad_b-1:0] address_b;
input [width_b-1:0] data_b;
input [(width_b/8)-1:0] byteena_b;
input addressstall_b;
output [width_b-1:0] q_b;
input clocken0;
input clocken1;
input clocken2;
input clocken3;
input aclr0;
input aclr1;
output eccstatus;
endmodule
(* blackbox *)
module cycloneiv_mac(ax, ay, resulta);
parameter ax_width = 9;
parameter signed_max = "true";
parameter ay_scan_in_width = 9;
parameter signed_may = "true";
parameter result_a_width = 18;
parameter operation_mode = "M9x9";
input [ax_width-1:0] ax;
input [ay_scan_in_width-1:0] ay;
output [result_a_width-1:0] resulta;
endmodule
(* blackbox *)
module cycloneiv_ram_block(portaaddr, portadatain, portawe, portbaddr, portbdataout, portbre, clk0);
parameter operation_mode = "dual_port";
parameter logical_ram_name = "";
parameter port_a_address_width = 10;
parameter port_a_data_width = 10;
parameter port_a_logical_ram_depth = 1024;
parameter port_a_logical_ram_width = 10;
parameter port_a_first_address = 0;
parameter port_a_last_address = 1023;
parameter port_a_first_bit_number = 0;
parameter port_b_address_width = 10;
parameter port_b_data_width = 10;
parameter port_b_logical_ram_depth = 1024;
parameter port_b_logical_ram_width = 10;
parameter port_b_first_address = 0;
parameter port_b_last_address = 1023;
parameter port_b_first_bit_number = 0;
parameter port_b_address_clock = "clock0";
parameter port_b_read_enable_clock = "clock0";
parameter mem_init0 = "";
parameter mem_init1 = "";
parameter mem_init2 = "";
parameter mem_init3 = "";
parameter mem_init4 = "";
input [port_a_address_width-1:0] portaaddr;
input [port_b_address_width-1:0] portbaddr;
input [port_a_data_width-1:0] portadatain;
output [port_b_data_width-1:0] portbdataout;
input clk0, portawe, portbre;
endmodule

View file

@ -0,0 +1,34 @@
// The M9K
// --------
// TODO
module MISTRAL_M9K(CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter CFG_ABITS = 9;
parameter CFG_DBITS = 9;
input CLK1;
input [CFG_ABITS-1:0] A1ADDR, B1ADDR;
input [CFG_DBITS-1:0] A1DATA;
input A1EN, B1EN;
output reg [CFG_DBITS-1:0] B1DATA;
reg [2**CFG_ABITS * CFG_DBITS - 1 : 0] mem = 0;
specify
$setup(A1ADDR, posedge CLK1, 0);
$setup(A1DATA, posedge CLK1, 0);
if (B1EN) (posedge CLK1 => (B1DATA : A1DATA)) = 0;
endspecify
always @(posedge CLK1) begin
if (A1EN)
mem[(A1ADDR + 1) * CFG_DBITS - 1 : A1ADDR * CFG_DBITS] <= A1DATA;
if (B1EN)
B1DATA <= mem[(B1ADDR + 1) * CFG_DBITS - 1 : B1ADDR * CFG_DBITS];
end
endmodule

View file

@ -0,0 +1,116 @@
`ifdef cycloneiv
`define LCELL cycloneiv_lcell_comb
`define M9K cycloneiv_ram_block
`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_ALUT4(input A, B, C, D, output Q);
parameter [15:0] LUT = 16'h0000;
`LCELL #(.lut_mask(LUT),.sum_lutc_input("datac")) _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({2{LUT}}),.sum_lutc_input("datac")) _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({4{LUT}}),.sum_lutc_input("datac")) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .combout(Q));
endmodule
module MISTRAL_NOT(input A, output Q);
//NOT _TECHMAP_REPLACE_ (.IN(A), .OUT(Q));
assign Q = ~A;
endmodule
module MISTRAL_LE_LUT_ARITH(input A, B, C, D, CI, output SO, CO);
parameter LUT = 16'h0000;
`LCELL #(.lut_mask({LUT}),.sum_lutc_input("cin")) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .datad(D), .cin(CI), .combout(SO), .cout(CO));
endmodule
module MISTRAL_M9K(A1ADDR, A1DATA, A1EN, CLK1, B1ADDR, B1DATA, B1EN);
parameter CFG_ABITS = 9;
parameter CFG_DBITS = 9;
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;
// The M9K has mem_init[01234] parameters which would let
// you initialise the RAM cell via hex literals. If they were implemented.
`M9K #(
.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")
) _TECHMAP_REPLACE_ (
.portaaddr(A1ADDR),
.portadatain(A1DATA),
.portawe(A1EN),
.portbaddr(B1ADDR),
.portbdataout(B1DATA),
.portbre(B1EN),
.clk0(CLK1)
);
endmodule

View file

@ -0,0 +1,61 @@
module VCC (output V);
assign V = 1'b1;
endmodule // VCC
module GND (output G);
assign G = 1'b0;
endmodule // GND
/* Altera Cyclone IV devices Input Buffer Primitive */
module cycloneiv_io_ibuf
(output o, input i, input ibar);
assign ibar = ibar;
assign o = i;
endmodule // cycloneiv_io_ibuf
/* Altera Cyclone IV devices Output Buffer Primitive */
module cycloneiv_io_obuf
(output o, input i, input oe);
assign o = i;
assign oe = oe;
endmodule // cycloneiv_io_obuf
/* Altera Cyclone IV LUT Primitive */
module cycloneiv_lcell_comb
(output combout, cout,
input dataa, datab, datac, datad, cin);
parameter lut_mask = 16'hFFFF;
parameter dont_touch = "off";
parameter lpm_type = "cycloneiv_lcell_comb";
parameter sum_lutc_input = "datac";
endmodule // cycloneiv_lcell_comb
/* Altera D Flip-Flop Primitive */
module dffeas
(output q,
input d, clk, clrn, prn, ena,
input asdata, aload, sclr, sload);
// Timing simulation is not covered
parameter power_up="dontcare";
parameter is_wysiwyg="false";
reg q_tmp;
wire reset;
reg [7:0] debug_net;
assign reset = (prn && sclr && ~clrn && ena);
assign q = q_tmp & 1'b1;
always @(posedge clk, posedge aload) begin
if(reset) q_tmp <= 0;
else q_tmp <= d;
end
assign q = q_tmp;
endmodule // dffeas

View file

@ -0,0 +1,265 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Claire Wolf <claire@symbioticeda.com>
* Copyright (C) 2019 Dan Ravensloft <dan.ravensloft@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include "kernel/celltypes.h"
#include "kernel/log.h"
#include "kernel/register.h"
#include "kernel/rtlil.h"
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
struct SynthIntelLEPass : public ScriptPass {
SynthIntelLEPass() : ScriptPass("synth_intel_le", "synthesis for LE-based Intel (Altera) FPGAs.") {}
void help() override
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" synth_intel_le [options]\n");
log("\n");
log("This command runs synthesis for LE-based Intel FPGAs.\n");
log("\n");
log(" -top <module>\n");
log(" use the specified module as top module\n");
log("\n");
log(" -family <family>\n");
log(" target one of:\n");
log(" \"cycloneiv\" - Cyclone IV (default)\n");
log("\n");
log(" -vqm <file>\n");
log(" write the design to the specified Verilog Quartus Mapping File. Writing of an\n");
log(" output file is omitted if this parameter is not specified. Implies -quartus.\n");
log("\n");
log(" -noflatten\n");
log(" do not flatten design before synthesis; useful for per-module area 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 (EXPERIMENTAL)\n");
log("\n");
log(" -run <from_label>:<to_label>\n");
log(" only run the commands between the labels (see below). an empty\n");
log(" from label is synonymous to 'begin', and empty to label is\n");
log(" synonymous to the end of the command list.\n");
log("\n");
log(" -nobram\n");
log(" do not use block RAM cells in output netlist\n");
log("\n");
log(" -nodsp\n");
log(" do not map multipliers to MISTRAL_MUL cells\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
log("\n");
}
string top_opt, family_opt, bram_type, vout_file;
bool flatten, quartus, nobram, dff, nodsp;
void clear_flags() override
{
top_opt = "-auto-top";
family_opt = "cycloneiv";
bram_type = "m9k";
vout_file = "";
flatten = true;
quartus = false;
nobram = false;
dff = false;
nodsp = false;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
string run_from, run_to;
clear_flags();
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) {
if (args[argidx] == "-family" && argidx + 1 < args.size()) {
family_opt = args[++argidx];
continue;
}
if (args[argidx] == "-top" && argidx + 1 < args.size()) {
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)
break;
run_from = args[++argidx].substr(0, pos);
run_to = args[argidx].substr(pos + 1);
continue;
}
if (args[argidx] == "-quartus") {
quartus = true;
continue;
}
if (args[argidx] == "-nobram") {
nobram = true;
continue;
}
if (args[argidx] == "-nodsp") {
nodsp = true;
continue;
}
if (args[argidx] == "-noflatten") {
flatten = false;
continue;
}
if (args[argidx] == "-dff") {
dff = true;
continue;
}
break;
}
extra_args(args, argidx, design);
if (!design->full_selection())
log_cmd_error("This command only operates on fully selected designs!\n");
if (family_opt == "cycloneiv") {
bram_type = "m9k";
} else {
log_cmd_error("Invalid family specified: '%s'\n", family_opt.c_str());
}
log_header(design, "Executing SYNTH_intel_le pass.\n");
log_push();
run_script(design, run_from, run_to);
log_pop();
}
void script() override
{
if (help_mode) {
family_opt = "<family>";
bram_type = "<bram_type>";
}
if (check_label("begin")) {
if (family_opt == "cycloneiv")
run(stringf("read_verilog -sv -lib +/intel_le/cycloneiv/cells_sim.v"));
run(stringf("read_verilog -specify -lib -D %s +/intel_le/common/le_sim.v", family_opt.c_str()));
run(stringf("read_verilog -specify -lib -D %s +/intel_le/common/dff_sim.v", family_opt.c_str()));
run(stringf("read_verilog -specify -lib -D %s +/intel_le/common/mem_sim.v", family_opt.c_str()));
run(stringf("read_verilog -specify -lib -D %s -icells +/intel_le/common/abc9_model.v", family_opt.c_str()));
// Misc and common cells
run("read_verilog -lib +/intel/common/altpll_bb.v");
run("read_verilog -lib +/intel_le/common/megafunction_bb.v");
run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
}
if (check_label("coarse")) {
run("proc");
if (flatten || help_mode)
run("flatten", "(skip if -noflatten)");
run("tribuf -logic");
run("deminout");
run("opt_expr");
run("opt_clean");
run("check");
run("opt -nodffe -nosdff");
run("fsm");
run("opt");
run("wreduce");
run("peepopt");
run("opt_clean");
run("share");
run("techmap -map +/cmp2lut.v -D LUT_WIDTH=4");
run("opt_expr");
run("opt_clean");
run("alumacc");
run("techmap -map +/intel_le/common/arith_le_map.v");
run("opt");
run("memory -nomap");
run("opt_clean");
}
if (!nobram && check_label("map_bram", "(skip if -nobram)")) {
run(stringf("memory_bram -rules +/intel_le/common/bram_%s.txt", bram_type.c_str()));
}
if (check_label("map_ffram")) {
run("memory_map");
run("opt -full");
}
if (check_label("map_ffs")) {
run("techmap");
run("dfflegalize -cell $_DFFE_PN0P_ 0 -cell $_SDFFCE_PP0P_ 0");
run("techmap -map +/intel_le/common/dff_map.v");
run("opt -full -undriven -mux_undef");
run("clean -purge");
}
if (check_label("map_luts")) {
run("techmap -map +/intel_le/common/abc9_map.v");
run(stringf("abc9 %s -maxlut 4 -W 400", help_mode ? "[-dff]" : dff ? "-dff" : ""));
run("techmap -map +/intel_le/common/abc9_unmap.v");
run("techmap -map +/intel_le/common/le_map.v");
run("opt -fast");
run("autoname");
run("clean");
}
if (check_label("check")) {
run("hierarchy -check");
run("stat");
run("check");
}
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_le/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 ? "<file-name>" : vout_file.c_str()));
}
}
}
} SynthIntelLEPass;
PRIVATE_NAMESPACE_END

View file

@ -0,0 +1,12 @@
read_verilog ../common/add_sub.v
hierarchy -top top
equiv_opt -assert -map +/intel_le/common/le_sim.v synth_intel_le -family cycloneiv # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
stat
select -assert-count 8 t:MISTRAL_ALUT_ARITH
select -assert-count 4 t:MISTRAL_NOT
select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT_ARITH %% t:* %D
design -reset

View file

@ -0,0 +1,49 @@
read_verilog ../common/adffs.v
design -save read
hierarchy -top adff
proc
equiv_opt -async2sync -assert -map +/intel_le/common/le_sim.v -map +/intel_le/common/dff_sim.v synth_intel_le -family cycloneiv # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd adff # Constrain all select calls below inside the top module
select -assert-count 1 t:MISTRAL_FF
select -assert-count 1 t:MISTRAL_NOT
select -assert-none t:MISTRAL_FF t:MISTRAL_NOT %% t:* %D
design -load read
hierarchy -top adffn
proc
equiv_opt -async2sync -assert -map +/intel_le/common/le_sim.v -map +/intel_le/common/dff_sim.v synth_intel_le -family cycloneiv # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd adffn # Constrain all select calls below inside the top module
select -assert-count 1 t:MISTRAL_FF
select -assert-none t:MISTRAL_FF %% t:* %D
design -load read
hierarchy -top dffs
proc
equiv_opt -async2sync -assert -map +/intel_le/common/le_sim.v -map +/intel_le/common/dff_sim.v synth_intel_le -family cycloneiv # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd dffs # Constrain all select calls below inside the top module
select -assert-count 1 t:MISTRAL_FF
select -assert-count 1 t:MISTRAL_ALUT2
select -assert-none t:MISTRAL_FF t:MISTRAL_ALUT2 %% t:* %D
design -load read
hierarchy -top ndffnr
proc
equiv_opt -async2sync -assert -map +/intel_le/common/le_sim.v -map +/intel_le/common/dff_sim.v synth_intel_le -family cycloneiv # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd ndffnr # Constrain all select calls below inside the top module
select -assert-count 1 t:MISTRAL_FF
select -assert-count 2 t:MISTRAL_NOT
select -assert-none t:MISTRAL_FF t:MISTRAL_NOT %% t:* %D

View file

@ -0,0 +1,6 @@
read_verilog ../common/blockram.v
chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 9 sync_ram_sdp
synth_intel_le -family cycloneiv
cd sync_ram_sdp
select -assert-count 1 t:MISTRAL_M9K
select -assert-none t:MISTRAL_M9K %% t:* %D

View file

@ -0,0 +1,16 @@
read_verilog ../common/counter.v
hierarchy -top top
proc
flatten
equiv_opt -async2sync -map +/intel_le/common/le_sim.v -map +/intel_le/common/dff_sim.v synth_intel_le -family cycloneiv # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
select -assert-count 2 t:MISTRAL_NOT
select -assert-count 8 t:MISTRAL_ALUT_ARITH
select -assert-count 8 t:MISTRAL_FF
select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT_ARITH t:MISTRAL_FF %% t:* %D
design -reset

View file

@ -0,0 +1,24 @@
read_verilog ../common/dffs.v
design -save read
hierarchy -top dff
proc
equiv_opt -async2sync -assert -map +/intel_le/common/le_sim.v -map +/intel_le/common/dff_sim.v synth_intel_le -family cycloneiv # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd dff # Constrain all select calls below inside the top module
select -assert-count 1 t:MISTRAL_FF
select -assert-none t:MISTRAL_FF %% t:* %D
design -load read
hierarchy -top dffe
proc
equiv_opt -async2sync -assert -map +/intel_le/common/le_sim.v -map +/intel_le/common/dff_sim.v synth_intel_le -family cycloneiv # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd dffe # Constrain all select calls below inside the top module
select -assert-count 1 t:MISTRAL_FF
select -assert-none t:MISTRAL_FF %% t:* %D

View file

@ -0,0 +1,21 @@
read_verilog ../common/fsm.v
hierarchy -top fsm
proc
flatten
equiv_opt -run :prove -map +/intel_le/common/le_sim.v -map +/intel_le/common/dff_sim.v synth_intel_le -family cycloneiv
async2sync
miter -equiv -make_assert -flatten gold gate miter
sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd fsm # Constrain all select calls below inside the top module
select -assert-count 6 t:MISTRAL_FF
select -assert-max 1 t:MISTRAL_NOT
select -assert-max 5 t:MISTRAL_ALUT2 #
select -assert-max 1 t:MISTRAL_ALUT3
select -assert-max 9 t:MISTRAL_ALUT4 #
select -assert-none t:MISTRAL_FF t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT3 t:MISTRAL_ALUT4 %% t:* %D
design -reset

View file

@ -0,0 +1,14 @@
read_verilog ../common/logic.v
hierarchy -top top
proc
equiv_opt -assert -map +/intel_le/common/le_sim.v synth_intel_le -family cycloneiv # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
select -assert-count 1 t:MISTRAL_NOT
select -assert-count 6 t:MISTRAL_ALUT2
select -assert-count 2 t:MISTRAL_ALUT4
select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT4 %% t:* %D
design -reset

View file

@ -0,0 +1,45 @@
read_verilog ../common/mux.v
design -save read
hierarchy -top mux2
proc
equiv_opt -assert -map +/intel_le/common/le_sim.v synth_intel_le -family cycloneiv # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd mux2 # Constrain all select calls below inside the top module
select -assert-count 1 t:MISTRAL_ALUT3
select -assert-none t:MISTRAL_ALUT3 %% t:* %D
design -load read
hierarchy -top mux4
proc
equiv_opt -assert -map +/intel_le/common/le_sim.v synth_intel_le -family cycloneiv # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd mux4 # Constrain all select calls below inside the top module
select -assert-count 3 t:MISTRAL_ALUT3
select -assert-none t:MISTRAL_ALUT3 %% t:* %D
design -load read
hierarchy -top mux8
proc
equiv_opt -assert -map +/intel_le/common/le_sim.v synth_intel_le -family cycloneiv # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd mux8 # Constrain all select calls below inside the top module
select -assert-count 3 t:MISTRAL_ALUT2
select -assert-count 5 t:MISTRAL_ALUT4
select -assert-none t:MISTRAL_ALUT2 t:MISTRAL_ALUT4 %% t:* %D
design -load read
hierarchy -top mux16
proc
equiv_opt -assert -map +/intel_le/common/le_sim.v synth_intel_le -family cycloneiv # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd mux16 # Constrain all select calls below inside the top module
select -assert-max 3 t:MISTRAL_ALUT3
select -assert-max 10 t:MISTRAL_ALUT4
select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT4 %% t:* %D

View file

@ -0,0 +1,14 @@
read_verilog <<EOT
// Verilog has syntax for raw identifiers, where you start it with \ and end it with a space.
// This test crashes Quartus due to it parsing \a[10] as a wire slice and not a raw identifier.
module top();
(* keep *) wire [31:0] \a[10] ;
(* keep *) wire b;
assign b = \a[10] [31];
endmodule
EOT
synth_intel_le -family cycloneiv -quartus
select -assert-none w:*[* w:*]*
design -reset

View file

@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -eu
source ../../gen-tests-makefile.sh
run_tests --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'"

View file

@ -0,0 +1,12 @@
read_verilog ../common/shifter.v
hierarchy -top top
proc
flatten
equiv_opt -async2sync -assert -map +/intel_le/common/le_sim.v -map +/intel_le/common/dff_sim.v synth_intel_le -family cycloneiv # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
select -assert-count 8 t:MISTRAL_FF
select -assert-none t:MISTRAL_FF %% t:* %D
design -reset

View file

@ -0,0 +1,15 @@
read_verilog ../common/tribuf.v
hierarchy -top tristate
proc
tribuf
flatten
synth
equiv_opt -assert -map +/simcells.v synth_intel_le -family cycloneiv # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd tristate # Constrain all select calls below inside the top module
#Internal cell type used. Need support it.
select -assert-count 1 t:$_TBUF_
select -assert-none t:$_TBUF_ %% t:* %D
design -reset