diff options
Diffstat (limited to 'tests/arch')
-rw-r--r-- | tests/arch/gowin/adffs.ys | 5 | ||||
-rw-r--r-- | tests/arch/gowin/init.v | 224 | ||||
-rw-r--r-- | tests/arch/gowin/init.ys | 74 | ||||
-rw-r--r-- | tests/arch/ice40/ice40_opt.ys | 83 | ||||
-rw-r--r-- | tests/arch/ice40/ice40_wrapcarry.ys | 54 | ||||
-rw-r--r-- | tests/arch/ice40/wrapcarry.ys | 22 | ||||
-rw-r--r-- | tests/arch/xilinx/dsp_fastfir.ys | 69 | ||||
-rw-r--r-- | tests/arch/xilinx/macc.sh | 2 |
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 |