aboutsummaryrefslogtreecommitdiffstats
path: root/tests/arch
diff options
context:
space:
mode:
Diffstat (limited to 'tests/arch')
-rw-r--r--tests/arch/gowin/adffs.ys5
-rw-r--r--tests/arch/gowin/init.v224
-rw-r--r--tests/arch/gowin/init.ys74
-rw-r--r--tests/arch/ice40/ice40_opt.ys83
-rw-r--r--tests/arch/ice40/ice40_wrapcarry.ys54
-rw-r--r--tests/arch/ice40/wrapcarry.ys22
-rw-r--r--tests/arch/xilinx/dsp_fastfir.ys69
-rw-r--r--tests/arch/xilinx/macc.sh2
8 files changed, 507 insertions, 26 deletions
diff --git a/tests/arch/gowin/adffs.ys b/tests/arch/gowin/adffs.ys
index fc7ee01f2..87fba83a6 100644
--- a/tests/arch/gowin/adffs.ys
+++ b/tests/arch/gowin/adffs.ys
@@ -34,11 +34,12 @@ proc
equiv_opt -async2sync -assert -map +/gowin/cells_sim.v synth_gowin # 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:DFFS
+select -assert-count 1 t:DFF
+select -assert-count 1 t:LUT2
select -assert-count 4 t:IBUF
select -assert-count 1 t:OBUF
-select -assert-none t:DFFS t:IBUF t:OBUF %% t:* %D
+select -assert-none t:DFF t:LUT2 t:IBUF t:OBUF %% t:* %D
design -load read
diff --git a/tests/arch/gowin/init.v b/tests/arch/gowin/init.v
new file mode 100644
index 000000000..3c30f602d
--- /dev/null
+++ b/tests/arch/gowin/init.v
@@ -0,0 +1,224 @@
+module myDFF (output reg Q, input CLK, D);
+ parameter [0:0] INIT = 1'b0;
+ initial Q = INIT;
+ always @(posedge CLK)
+ Q <= D;
+endmodule
+
+module myDFFE (output reg Q, input D, CLK, CE);
+ parameter [0:0] INIT = 1'b0;
+ initial Q = INIT;
+ always @(posedge CLK) begin
+ if (CE)
+ Q <= D;
+ end
+endmodule // DFFE (positive clock edge; clock enable)
+
+
+module myDFFS (output reg Q, input D, CLK, SET);
+ parameter [0:0] INIT = 1'b1;
+ initial Q = INIT;
+ always @(posedge CLK) begin
+ if (SET)
+ Q <= 1'b1;
+ else
+ Q <= D;
+ end
+endmodule // DFFS (positive clock edge; synchronous set)
+
+
+module myDFFSE (output reg Q, input D, CLK, CE, SET);
+ parameter [0:0] INIT = 1'b1;
+ initial Q = INIT;
+ always @(posedge CLK) begin
+ if (SET)
+ Q <= 1'b1;
+ else if (CE)
+ Q <= D;
+end
+endmodule // DFFSE (positive clock edge; synchronous set takes precedence over clock enable)
+
+
+module myDFFR (output reg Q, input D, CLK, RESET);
+ parameter [0:0] INIT = 1'b0;
+ initial Q = INIT;
+ always @(posedge CLK) begin
+ if (RESET)
+ Q <= 1'b0;
+ else
+ Q <= D;
+ end
+endmodule // DFFR (positive clock edge; synchronous reset)
+
+
+module myDFFRE (output reg Q, input D, CLK, CE, RESET);
+ parameter [0:0] INIT = 1'b0;
+ initial Q = INIT;
+ always @(posedge CLK) begin
+ if (RESET)
+ Q <= 1'b0;
+ else if (CE)
+ Q <= D;
+ end
+endmodule // DFFRE (positive clock edge; synchronous reset takes precedence over clock enable)
+
+
+module myDFFP (output reg Q, input D, CLK, PRESET);
+ parameter [0:0] INIT = 1'b1;
+ initial Q = INIT;
+ always @(posedge CLK or posedge PRESET) begin
+ if(PRESET)
+ Q <= 1'b1;
+ else
+ Q <= D;
+ end
+endmodule // DFFP (positive clock edge; asynchronous preset)
+
+
+module myDFFPE (output reg Q, input D, CLK, CE, PRESET);
+ parameter [0:0] INIT = 1'b1;
+ initial Q = INIT;
+ always @(posedge CLK or posedge PRESET) begin
+ if(PRESET)
+ Q <= 1'b1;
+ else if (CE)
+ Q <= D;
+ end
+endmodule // DFFPE (positive clock edge; asynchronous preset; clock enable)
+
+
+module myDFFC (output reg Q, input D, CLK, CLEAR);
+ parameter [0:0] INIT = 1'b0;
+ initial Q = INIT;
+ always @(posedge CLK or posedge CLEAR) begin
+ if(CLEAR)
+ Q <= 1'b0;
+ else
+ Q <= D;
+ end
+endmodule // DFFC (positive clock edge; asynchronous clear)
+
+
+module myDFFCE (output reg Q, input D, CLK, CE, CLEAR);
+ parameter [0:0] INIT = 1'b0;
+ initial Q = INIT;
+ always @(posedge CLK or posedge CLEAR) begin
+ if(CLEAR)
+ Q <= 1'b0;
+ else if (CE)
+ Q <= D;
+ end
+endmodule // DFFCE (positive clock edge; asynchronous clear; clock enable)
+
+
+module myDFFN (output reg Q, input CLK, D);
+ parameter [0:0] INIT = 1'b0;
+ initial Q = INIT;
+ always @(negedge CLK)
+ Q <= D;
+endmodule
+
+module myDFFNE (output reg Q, input D, CLK, CE);
+ parameter [0:0] INIT = 1'b0;
+ initial Q = INIT;
+ always @(negedge CLK) begin
+ if (CE)
+ Q <= D;
+ end
+endmodule // DFFNE (negative clock edge; clock enable)
+
+
+module myDFFNS (output reg Q, input D, CLK, SET);
+ parameter [0:0] INIT = 1'b1;
+ initial Q = INIT;
+ always @(negedge CLK) begin
+ if (SET)
+ Q <= 1'b1;
+ else
+ Q <= D;
+ end
+endmodule // DFFNS (negative clock edge; synchronous set)
+
+
+module myDFFNSE (output reg Q, input D, CLK, CE, SET);
+ parameter [0:0] INIT = 1'b1;
+ initial Q = INIT;
+ always @(negedge CLK) begin
+ if (SET)
+ Q <= 1'b1;
+ else if (CE)
+ Q <= D;
+end
+endmodule // DFFNSE (negative clock edge; synchronous set takes precedence over clock enable)
+
+
+module myDFFNR (output reg Q, input D, CLK, RESET);
+ parameter [0:0] INIT = 1'b0;
+ initial Q = INIT;
+ always @(negedge CLK) begin
+ if (RESET)
+ Q <= 1'b0;
+ else
+ Q <= D;
+ end
+endmodule // DFFNR (negative clock edge; synchronous reset)
+
+
+module myDFFNRE (output reg Q, input D, CLK, CE, RESET);
+ parameter [0:0] INIT = 1'b0;
+ initial Q = INIT;
+ always @(negedge CLK) begin
+ if (RESET)
+ Q <= 1'b0;
+ else if (CE)
+ Q <= D;
+ end
+endmodule // DFFNRE (negative clock edge; synchronous reset takes precedence over clock enable)
+
+
+module myDFFNP (output reg Q, input D, CLK, PRESET);
+ parameter [0:0] INIT = 1'b1;
+ initial Q = INIT;
+ always @(negedge CLK or posedge PRESET) begin
+ if(PRESET)
+ Q <= 1'b1;
+ else
+ Q <= D;
+ end
+endmodule // DFFNP (negative clock edge; asynchronous preset)
+
+
+module myDFFNPE (output reg Q, input D, CLK, CE, PRESET);
+ parameter [0:0] INIT = 1'b1;
+ initial Q = INIT;
+ always @(negedge CLK or posedge PRESET) begin
+ if(PRESET)
+ Q <= 1'b1;
+ else if (CE)
+ Q <= D;
+ end
+endmodule // DFFNPE (negative clock edge; asynchronous preset; clock enable)
+
+
+module myDFFNC (output reg Q, input D, CLK, CLEAR);
+ parameter [0:0] INIT = 1'b0;
+ initial Q = INIT;
+ always @(negedge CLK or posedge CLEAR) begin
+ if(CLEAR)
+ Q <= 1'b0;
+ else
+ Q <= D;
+ end
+endmodule // DFFNC (negative clock edge; asynchronous clear)
+
+
+module myDFFNCE (output reg Q, input D, CLK, CE, CLEAR);
+ parameter [0:0] INIT = 1'b0;
+ initial Q = INIT;
+ always @(negedge CLK or posedge CLEAR) begin
+ if(CLEAR)
+ Q <= 1'b0;
+ else if (CE)
+ Q <= D;
+ end
+endmodule // DFFNCE (negative clock edge; asynchronous clear; clock enable)
diff --git a/tests/arch/gowin/init.ys b/tests/arch/gowin/init.ys
new file mode 100644
index 000000000..ddc0e4757
--- /dev/null
+++ b/tests/arch/gowin/init.ys
@@ -0,0 +1,74 @@
+read_verilog init.v
+read_verilog -lib +/gowin/cells_sim.v
+design -save read
+
+proc
+flatten
+synth_gowin -run coarse:
+
+# check if all init values are handled
+check -assert -noinit
+# check if every flop mapped correctly
+select -assert-count 1 t:DFF
+select -assert-count 1 t:DFFC
+select -assert-count 1 t:DFFCE
+select -assert-count 1 t:DFFE
+select -assert-count 1 t:DFFN
+select -assert-count 1 t:DFFNC
+select -assert-count 1 t:DFFNCE
+select -assert-count 1 t:DFFNE
+select -assert-count 1 t:DFFNP
+select -assert-count 1 t:DFFNPE
+select -assert-count 1 t:DFFNR
+select -assert-count 1 t:DFFNRE
+select -assert-count 1 t:DFFNS
+select -assert-count 1 t:DFFNSE
+select -assert-count 1 t:DFFP
+select -assert-count 1 t:DFFPE
+select -assert-count 1 t:DFFR
+select -assert-count 1 t:DFFRE
+select -assert-count 1 t:DFFS
+select -assert-count 1 t:DFFSE
+
+delete
+design -load read
+
+# these should synth to a flop with reset
+chparam -set INIT 1 myDFF myDFFN myDFFE myDFFNE
+
+# async should give a warning
+# sync should synth to a mux
+chparam -set INIT 0 myDFF*S* myDFF*P*
+chparam -set INIT 1 myDFF*R* myDFF*C*
+
+proc
+flatten
+synth_gowin -run coarse:
+
+# check the flops mapped as expected
+select -assert-count 1 t:DFF
+select -assert-count 1 t:DFFC
+select -assert-count 1 t:DFFCE
+select -assert-count 1 t:DFFE
+select -assert-count 1 t:DFFN
+select -assert-count 1 t:DFFNC
+select -assert-count 1 t:DFFNCE
+select -assert-count 1 t:DFFNE
+select -assert-count 1 t:DFFNP
+select -assert-count 1 t:DFFNPE
+select -assert-count 0 t:DFFNR
+select -assert-count 0 t:DFFNRE
+select -assert-count 2 t:DFFNS
+select -assert-count 2 t:DFFNSE
+select -assert-count 1 t:DFFP
+select -assert-count 1 t:DFFPE
+select -assert-count 0 t:DFFR
+select -assert-count 0 t:DFFRE
+select -assert-count 2 t:DFFS
+select -assert-count 2 t:DFFSE
+select -assert-count 12 t:LUT2
+
+# check the expected leftover init values
+# this would happen if your reset value is not the initial value
+# which would be weird
+select -assert-count 8 a:init
diff --git a/tests/arch/ice40/ice40_opt.ys b/tests/arch/ice40/ice40_opt.ys
index b17c69c91..5186d4800 100644
--- a/tests/arch/ice40/ice40_opt.ys
+++ b/tests/arch/ice40/ice40_opt.ys
@@ -1,4 +1,24 @@
read_verilog -icells -formal <<EOT
+module \$__ICE40_CARRY_WRAPPER (output CO, O, input A, B, CI, I0, I3);
+ parameter LUT = 0;
+ SB_CARRY carry (
+ .I0(A),
+ .I1(B),
+ .CI(CI),
+ .CO(CO)
+ );
+ \$lut #(
+ .WIDTH(4),
+ .LUT(LUT)
+ ) lut (
+ .A({I0,A,B,I3}),
+ .Y(O)
+ );
+endmodule
+EOT
+design -stash unmap
+
+read_verilog -icells -formal <<EOT
module top(input CI, I0, output [1:0] CO, output O);
wire A = 1'b0, B = 1'b0;
\$__ICE40_CARRY_WRAPPER #(
@@ -20,7 +40,68 @@ module top(input CI, I0, output [1:0] CO, output O);
endmodule
EOT
-equiv_opt -assert -map +/ice40/cells_map.v -map +/ice40/cells_sim.v ice40_opt
+equiv_opt -assert -map %unmap -map +/ice40/cells_sim.v ice40_opt
design -load postopt
select -assert-count 1 t:*
select -assert-count 1 t:$lut
+
+# https://github.com/YosysHQ/yosys/issues/1543
+design -reset
+read_verilog <<EOT
+module delay_element (input wire clk, input wire reset, input wire enable,
+ input wire chainin, output wire chainout, output reg latch);
+
+
+ reg const_zero = 0;
+ reg const_one = 1;
+
+ wire delay_tap;
+
+
+ //carry logic
+ (* keep *) SB_CARRY carry ( .CO(chainout), .I0(const_zero),
+ .I1(const_one), .CI(chainin));
+
+
+ //flip flop latch
+ (* keep *) SB_DFFER flipflop( .Q(latch), .C(clk), .E(enable),
+ .D(delay_tap), .R(reset));
+
+
+ //LUT table
+ // the LUT should just echo the carry in (I3)
+ // carry I0 = LUT I1
+ // carry I1 = LUT I2
+ // carry in = LUT I3
+ // LUT_INIT[0] = 0
+ // LUT_INIT[1] = 0
+ // LUT_INIT[2] = 0
+ // LUT_INIT[3] = 0
+ // LUT_INIT[4] = 0
+ // LUT_INIT[5] = 0
+ // LUT_INIT[6] = 0
+ // LUT_INIT[7] = 0
+ // LUT_INIT[8] = 1
+ // LUT_INIT[9] = 1
+ // LUT_INIT[10] = 1
+ // LUT_INIT[11] = 1
+ // LUT_INIT[12] = 1
+ // LUT_INIT[13] = 1
+ // LUT_INIT[14] = 1
+ // LUT_INIT[15] = 1
+
+ (* keep *) SB_LUT4 lut( .O(delay_tap), .I0(const_zero), .I1(const_zero),
+ .I2(const_one), .I3(chainin));
+
+ //TODO: is this the right way round??
+ defparam lut.LUT_INIT=16'hFF00;
+
+
+endmodule // delay_element
+EOT
+
+synth_ice40
+select -assert-count 1 t:SB_LUT4
+select -assert-count 1 t:SB_CARRY
+select -assert-count 1 t:SB_CARRY a:keep %i
+select -assert-count 1 t:SB_CARRY c:carry %i
diff --git a/tests/arch/ice40/ice40_wrapcarry.ys b/tests/arch/ice40/ice40_wrapcarry.ys
new file mode 100644
index 000000000..fb9fccc3a
--- /dev/null
+++ b/tests/arch/ice40/ice40_wrapcarry.ys
@@ -0,0 +1,54 @@
+read_verilog <<EOT
+module top(input A, B, CI, output O, CO);
+ SB_CARRY carry (
+ .I0(A),
+ .I1(B),
+ .CI(CI),
+ .CO(CO)
+ );
+ SB_LUT4 #(
+ .LUT_INIT(16'b 0110_1001_1001_0110)
+ ) adder (
+ .I0(1'b0),
+ .I1(A),
+ .I2(B),
+ .I3(1'b0),
+ .O(O)
+ );
+endmodule
+EOT
+
+ice40_wrapcarry
+select -assert-count 1 t:$__ICE40_CARRY_WRAPPER
+
+design -reset
+read_verilog <<EOT
+module top(input A, B, CI, output O, CO);
+ (* foo = "bar", answer = 42, keep=0 *)
+ SB_CARRY carry (
+ .I0(A),
+ .I1(B),
+ .CI(CI),
+ .CO(CO)
+ );
+ (* keep, blah="blah", answer = 43 *)
+ SB_LUT4 #(
+ .LUT_INIT(16'b 0110_1001_1001_0110)
+ ) adder (
+ .I0(1'b0),
+ .I1(A),
+ .I2(B),
+ .I3(1'b0),
+ .O(O)
+ );
+endmodule
+EOT
+
+ice40_wrapcarry
+select -assert-count 1 t:$__ICE40_CARRY_WRAPPER
+select -assert-count 0 t:* t:$__ICE40_CARRY_WRAPPER %d
+select -assert-count 1 a:keep=1 a:SB_CARRY.\foo=bar %i a:SB_CARRY.\answer=42 %i a:SB_LUT4.\blah=blah %i a:SB_LUT4.\answer=43 %i
+
+ice40_wrapcarry -unwrap
+select -assert-count 1 c:carry a:src=<<EOT:3 %i a:keep=0 %i a:foo=bar %i a:answer=42 %i
+select -assert-count 1 c:adder a:src=<<EOT:10 %i a:keep=1 %i a:blah=blah %i a:answer=43 %i
diff --git a/tests/arch/ice40/wrapcarry.ys b/tests/arch/ice40/wrapcarry.ys
deleted file mode 100644
index 10c029e68..000000000
--- a/tests/arch/ice40/wrapcarry.ys
+++ /dev/null
@@ -1,22 +0,0 @@
-read_verilog <<EOT
-module top(input A, B, CI, output O, CO);
- SB_CARRY carry (
- .I0(A),
- .I1(B),
- .CI(CI),
- .CO(CO)
- );
- SB_LUT4 #(
- .LUT_INIT(16'b 0110_1001_1001_0110)
- ) adder (
- .I0(1'b0),
- .I1(A),
- .I2(B),
- .I3(1'b0),
- .O(O)
- );
-endmodule
-EOT
-
-ice40_wrapcarry
-select -assert-count 1 t:$__ICE40_CARRY_WRAPPER
diff --git a/tests/arch/xilinx/dsp_fastfir.ys b/tests/arch/xilinx/dsp_fastfir.ys
new file mode 100644
index 000000000..0067a822b
--- /dev/null
+++ b/tests/arch/xilinx/dsp_fastfir.ys
@@ -0,0 +1,69 @@
+read_verilog <<EOT
+// Citation https://github.com/ZipCPU/dspfilters/blob/master/rtl/fastfir.v
+module fastfir_dynamictaps(i_clk, i_reset, i_tap_wr, i_tap, i_ce, i_sample, o_result);
+ wire [30:0] _00_;
+ wire [23:0] _01_;
+ wire [11:0] _02_;
+ wire [30:0] _03_;
+ wire [23:0] _04_;
+ wire [30:0] _05_;
+ wire [23:0] _06_;
+ wire [30:0] _07_;
+ wire [23:0] _08_;
+ wire [11:0] _09_;
+ wire [30:0] _10_;
+ wire [23:0] _11_;
+ wire [30:0] _12_;
+ wire [23:0] _13_;
+ wire [11:0] \fir.FILTER[0].tapk.delayed_sample ;
+ reg [30:0] \fir.FILTER[0].tapk.o_acc = 31'h00000000;
+ wire [11:0] \fir.FILTER[0].tapk.o_sample ;
+ reg [23:0] \fir.FILTER[0].tapk.product ;
+ reg [11:0] \fir.FILTER[0].tapk.tap = 12'h000;
+ wire [11:0] \fir.FILTER[1].tapk.delayed_sample ;
+ wire [30:0] \fir.FILTER[1].tapk.o_acc ;
+ wire [11:0] \fir.FILTER[1].tapk.o_sample ;
+ reg [23:0] \fir.FILTER[1].tapk.product ;
+ reg [11:0] \fir.FILTER[1].tapk.tap = 12'h000;
+ input i_ce;
+ input i_clk;
+ input i_reset;
+ input [11:0] i_sample;
+ input [11:0] i_tap;
+ input i_tap_wr;
+ output [30:0] o_result;
+ reg [30:0] o_result;
+ assign _03_ = 31'h00000000 + { \fir.FILTER[0].tapk.product [23], \fir.FILTER[0].tapk.product [23], \fir.FILTER[0].tapk.product [23], \fir.FILTER[0].tapk.product [23], \fir.FILTER[0].tapk.product [23], \fir.FILTER[0].tapk.product [23], \fir.FILTER[0].tapk.product [23], \fir.FILTER[0].tapk.product };
+ assign _04_ = $signed(\fir.FILTER[0].tapk.tap ) * $signed(i_sample);
+ always @(posedge i_clk)
+ \fir.FILTER[0].tapk.tap <= _02_;
+ always @(posedge i_clk)
+ \fir.FILTER[0].tapk.o_acc <= _00_;
+ always @(posedge i_clk)
+ \fir.FILTER[0].tapk.product <= _01_;
+ assign _02_ = i_tap_wr ? i_tap : \fir.FILTER[0].tapk.tap ;
+ assign _05_ = i_ce ? _03_ : \fir.FILTER[0].tapk.o_acc ;
+ assign _00_ = i_reset ? 31'h00000000 : _05_;
+ assign _06_ = i_ce ? _04_ : \fir.FILTER[0].tapk.product ;
+ assign _01_ = i_reset ? 24'h000000 : _06_;
+ assign _10_ = \fir.FILTER[0].tapk.o_acc + { \fir.FILTER[1].tapk.product [23], \fir.FILTER[1].tapk.product [23], \fir.FILTER[1].tapk.product [23], \fir.FILTER[1].tapk.product [23], \fir.FILTER[1].tapk.product [23], \fir.FILTER[1].tapk.product [23], \fir.FILTER[1].tapk.product [23], \fir.FILTER[1].tapk.product };
+ assign _11_ = $signed(\fir.FILTER[1].tapk.tap ) * $signed(i_sample);
+ always @(posedge i_clk)
+ \fir.FILTER[1].tapk.tap <= _09_;
+ always @(posedge i_clk)
+ o_result <= _07_;
+ always @(posedge i_clk)
+ \fir.FILTER[1].tapk.product <= _08_;
+ assign _09_ = i_tap_wr ? \fir.FILTER[0].tapk.tap : \fir.FILTER[1].tapk.tap ;
+ assign _12_ = i_ce ? _10_ : o_result;
+ assign _07_ = i_reset ? 31'h00000000 : _12_;
+ assign _13_ = i_ce ? _11_ : \fir.FILTER[1].tapk.product ;
+ assign _08_ = i_reset ? 24'h000000 : _13_;
+ assign \fir.FILTER[1].tapk.o_acc = o_result;
+endmodule
+EOT
+
+synth_xilinx
+cd fastfir_dynamictaps
+select -assert-count 2 t:DSP48E1
+select -assert-none t:* t:DSP48E1 %d t:BUFG %d
diff --git a/tests/arch/xilinx/macc.sh b/tests/arch/xilinx/macc.sh
index 2272679ee..154a29848 100644
--- a/tests/arch/xilinx/macc.sh
+++ b/tests/arch/xilinx/macc.sh
@@ -1,3 +1,3 @@
-../../../yosys -qp "synth_xilinx -top macc2; rename -top macc2_uut" macc.v -o macc_uut.v
+../../../yosys -qp "synth_xilinx -top macc2; rename -top macc2_uut" -o macc_uut.v macc.v
iverilog -o test_macc macc_tb.v macc_uut.v macc.v ../../../techlibs/xilinx/cells_sim.v
vvp -N ./test_macc