diff options
Diffstat (limited to 'testsuite/ghdl-issues/issue1309')
| -rw-r--r-- | testsuite/ghdl-issues/issue1309/axis_squarer.sby | 34 | ||||
| -rw-r--r-- | testsuite/ghdl-issues/issue1309/axis_squarer.vhd | 114 | ||||
| -rw-r--r-- | testsuite/ghdl-issues/issue1309/faxis_master.v | 230 | ||||
| -rw-r--r-- | testsuite/ghdl-issues/issue1309/faxis_slave.v | 230 | ||||
| -rw-r--r-- | testsuite/ghdl-issues/issue1309/tb_formal_top.v | 131 | ||||
| -rwxr-xr-x | testsuite/ghdl-issues/issue1309/testsuite.sh | 10 | 
6 files changed, 749 insertions, 0 deletions
diff --git a/testsuite/ghdl-issues/issue1309/axis_squarer.sby b/testsuite/ghdl-issues/issue1309/axis_squarer.sby new file mode 100644 index 0000000..c72c50d --- /dev/null +++ b/testsuite/ghdl-issues/issue1309/axis_squarer.sby @@ -0,0 +1,34 @@ +[tasks] +verify_bmc +prove +cover + +[options] +verify_bmc: mode bmc +verify_bmc: depth 40 +prove: mode prove +prove: depth 20 +cover: mode cover +cover: depth 40 + +[engines] +smtbmc z3 parallel.enable=true + +[script] +ghdl axis_squarer.vhd -e axis_squarer +read_verilog -formal faxis_master.v +read_verilog -formal faxis_slave.v +read_verilog -formal tb_formal_top.v +--pycode-begin-- +cmd = "hierarchy -top tb_formal_top" +if "cover" in tags: +    cmd += " -chparam no_backpressure 1" +output(cmd); +--pycode-end-- +prep -top tb_formal_top + +[files] +axis_squarer.vhd +faxis_master.v +faxis_slave.v +tb_formal_top.v diff --git a/testsuite/ghdl-issues/issue1309/axis_squarer.vhd b/testsuite/ghdl-issues/issue1309/axis_squarer.vhd new file mode 100644 index 0000000..49cb1fa --- /dev/null +++ b/testsuite/ghdl-issues/issue1309/axis_squarer.vhd @@ -0,0 +1,114 @@ +---------------------------------------------------------------------------------- +-- Company:  +-- Engineer:  +--  +-- Create Date: 04/08/2020 11:41:37 AM +-- Design Name:  +-- Module Name: axis_squarer - Behavioral +-- Project Name:  +-- Target Devices:  +-- Tool Versions:  +-- Description:  +--  +-- Dependencies:  +--  +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +--  +---------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity axis_squarer is +    Port ( clk : in STD_LOGIC; +           aresetn : in STD_LOGIC; +           s_axis_tdata : in STD_LOGIC_VECTOR (31 downto 0); +           s_axis_tlast : in STD_LOGIC; +           s_axis_tvalid : in STD_LOGIC; +           s_axis_tready : out STD_LOGIC; +            +           m_axis_tdata : out STD_LOGIC_VECTOR (31 downto 0); +           m_axis_tlast : out STD_LOGIC; +           m_axis_tvalid : out STD_LOGIC; +           m_axis_tready : in STD_LOGIC); +end axis_squarer; + +architecture Behavioral of axis_squarer is +    signal idle_counter: UNSIGNED(7 downto 0) := (others => '0'); +    signal counter_start_long: UNSIGNED(3 downto 0) := (others => '0'); +    type FSM_STATES is (IDLE, TX_RESULT, LONG_COMPUTATION); +    signal fsm: FSM_STATES := IDLE; +begin +    fsm_main: process(clk) is +    begin +        if rising_edge(clk) then +            if aresetn = '0' then +                fsm <= IDLE; +                -- Reset stuff added below in response to fv +                m_axis_tlast <= '0'; +                counter_start_long <= (others => '0'); +            else +                case fsm is +                when IDLE => +                    -- Wait for input valid, then put data onto output bus +                    if s_axis_tvalid = '1' then +                        m_axis_tdata <= not s_axis_tdata; +                        if s_axis_tlast = '1' or counter_start_long = 2 then +                            m_axis_tlast <= '1'; +                        else +                            m_axis_tlast <= '0'; +                        end if; +                        fsm <= TX_RESULT; +                    end if; +                when TX_RESULT => +                    -- Wait for output ready +                    -- Do 8 fast returns before a single slow return +                    if m_axis_tready = '1' then +                        m_axis_tlast <= '0'; +                        counter_start_long <= counter_start_long+1; +                        if counter_start_long = 2 then +                            fsm <= LONG_COMPUTATION; +                            counter_start_long <= (others => '0'); +                        else +                            fsm <= IDLE; +                        end if; +                    end if; +                when LONG_COMPUTATION => +                    -- Wait for 16 cycles +                    -- In actuality a longer computation goes here but simplify by reducing it to a wait +                    idle_counter <= idle_counter + 1; +                    if idle_counter = 5 then +                        fsm <= IDLE; +                    end if; +                end case; +            end if; +        end if; +    end process; +     +    fsm_axis_handshake_outputs: process(fsm,aresetn) is +    begin +        case fsm is +            when IDLE => +                s_axis_tready <= aresetn; -- Ready when not reset +                m_axis_tvalid <= '0'; +            when TX_RESULT => +                s_axis_tready <= '0'; +                m_axis_tvalid <= '1'; +            when LONG_COMPUTATION => +                s_axis_tready <= '0'; +                m_axis_tvalid <= '0'; +        end case; +    end process; +end Behavioral; diff --git a/testsuite/ghdl-issues/issue1309/faxis_master.v b/testsuite/ghdl-issues/issue1309/faxis_master.v new file mode 100644 index 0000000..ae31735 --- /dev/null +++ b/testsuite/ghdl-issues/issue1309/faxis_master.v @@ -0,0 +1,230 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Filename: 	faxis_master.v +// +// Project:	WB2AXIPSP: bus bridges and other odds and ends +// +// Purpose:	Formal properties for verifying the proper functionality of an +//		AXI Stream master. +// +// Creator:	Dan Gisselquist, Ph.D. +//		Gisselquist Technology, LLC +// +//////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2019-2020, Gisselquist Technology, LLC +// +// This file is part of the WB2AXIP project. +// +// The WB2AXIP project contains free software and gateware, licensed under the +// Apache License, Version 2.0 (the "License").  You may not use this project, +// or this file, except in compliance with the License.  You may obtain a copy +// of the License at +// +//	http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the +// License for the specific language governing permissions and limitations +// under the License. +// +//////////////////////////////////////////////////////////////////////////////// +// +// +`default_nettype none +// +module	faxis_master #( +	parameter	F_MAX_PACKET = 0, +	parameter	F_MIN_PACKET = 0, +	parameter	F_MAX_STALL  = 0, +	parameter	C_S_AXI_DATA_WIDTH  = 32, +	parameter	C_S_AXI_ID_WIDTH = 1, +	parameter	C_S_AXI_ADDR_WIDTH = 1, +	parameter	C_S_AXI_USER_WIDTH = 1, +	parameter [0:0]	OPT_ASYNC_RESET = 1'b0, +	// +	// F_LGDEPTH is the number of bits necessary to represent a packets +	// length +	parameter	F_LGDEPTH = 32, +	// +	localparam	AW  = C_S_AXI_ADDR_WIDTH, +	localparam	DW  = C_S_AXI_DATA_WIDTH, +	localparam	IDW  = C_S_AXI_ID_WIDTH, +	localparam	UW  = C_S_AXI_USER_WIDTH +	// +	) ( +	// +	input	wire			i_aclk, i_aresetn, +	input	wire			i_tvalid, +	input	wire			i_tready = 1, +	input	wire	[DW-1:0]	i_tdata, +	input	wire	[DW/8-1:0]	i_tstrb = {(DW/8){1'b1}}, +	input	wire	[DW/8-1:0]	i_tkeep = {(DW/8){1'b1}}, +	input	wire			i_tlast, +	input	wire	[(IDW>0?IDW:1)-1:0]	i_tid = {(IDW){1'b0}}, +	input	wire	[(AW>0?AW:1)-1:0]	i_tdest = {(AW){1'b0}}, +	input	wire	[(UW>0?UW:1)-1:0]	i_tuser = {(UW){1'b0}}, +	// +	output	reg	[F_LGDEPTH-1:0]	f_bytecount, +	//(* anyconst *) output	reg	[AW+IDW-1:0]	f_routecheck +	); + +`define	SLAVE_ASSUME	assert +`define	SLAVE_ASSERT	assume + +	localparam	F_STALLBITS	= (F_MAX_STALL <= 1) +						? 1 : $clog2(F_MAX_STALL+2); +	reg				f_past_valid; +	reg	[F_LGDEPTH-1:0]		f_vbytes; +	reg	[F_STALLBITS-1:0]	f_stall_count; +	integer	iB; +	genvar	k; + +	// +	// f_past_valid is used to make certain that temporal assertions +	// depending upon past values depend upon *valid* past values. +	// It is true for all clocks other than the first clock. +	initial	f_past_valid = 1'b0; +	always @(posedge i_aclk) +		f_past_valid <= 1'b1; + +	// +	// Reset should always be active (low) initially +	always @(posedge i_aclk) +	if (!f_past_valid) +		`SLAVE_ASSUME(!i_aresetn); + +	// +	// During and following a reset, TVALID should be deasserted +	always @(posedge i_aclk) +	if ((!f_past_valid)||(!i_aresetn && OPT_ASYNC_RESET)||($past(!i_aresetn))) +		`SLAVE_ASSUME(!i_tvalid); + +	// +	// If TVALID but not TREADY, then the master isn't allowed to change +	// anything until the slave asserts TREADY. +	always @(posedge i_aclk) +	if ((f_past_valid)&&($past(i_aresetn))&&(!OPT_ASYNC_RESET || i_aresetn) +		&&($past(i_tvalid))&&(!$past(i_tready))) +	begin +		`SLAVE_ASSUME(i_tvalid); +		`SLAVE_ASSUME($stable(i_tstrb)); +		`SLAVE_ASSUME($stable(i_tkeep)); +		`SLAVE_ASSUME($stable(i_tlast)); +		//`SLAVE_ASSUME($stable(i_tid)); +		//`SLAVE_ASSUME($stable(i_tdest)); +		//`SLAVE_ASSUME($stable(i_tuser)); +	end + +	generate for(k=0; k<DW/8; k=k+1) +	begin : CHECK_PARTIAL_DATA + +		// If TVALID && !TREADY, only those TDATA values with TKEEP +		// high are required to maintain their values until TREADY +		// becomes true. +		always @(posedge i_aclk) +		if ((f_past_valid)&&($past(i_aresetn)) +			&&(!OPT_ASYNC_RESET || i_aresetn) +			&&($past(i_tvalid))&&(!$past(i_tready))) +		begin +			if (i_tkeep[k]) +				`SLAVE_ASSUME($stable(i_tdata[k*8 +: 8])); +			// else this is a null (don't care) byte, with +			// no data within it +			// +		end + +	end endgenerate + +	// +	// TKEEP == LOW and TSTRB == HIGH is reserved per the spec, and +	// must not be used +	always @(posedge i_aclk) +	if (i_tvalid) +		`SLAVE_ASSUME((~i_tkeep & i_tstrb)==0); + +	// +	// f_vbytes is the number of valid bytes contained in the current beat +	// It is used for counting packet lengths below. +	always @(*) +	if (!i_tvalid) +		f_vbytes = 0; +	else begin +		f_vbytes = 0; +		for(iB=0; iB < DW/8; iB=iB+1) +		if (i_tkeep[iB] && i_tstrb[iB]) +			f_vbytes = f_vbytes + 1; +	end + +	// +	// f_bytecount is the number of bytes that have taken place so far in +	// the current packet transmission.  Note that we are *only* counting +	// our location within the stream if the TUSER and TDEST fields match +	// our (solver chosen) ROUTECHECK.  That way we don't have to check +	// *EVERY POSSIBLE* TUSER and TDEST combination. +	initial	f_bytecount = 0; +	always @(posedge i_aclk) +	if (!i_aresetn) +		f_bytecount <= 0; +	else if (i_tready && i_tvalid /*&& ({ i_tuser, i_tdest } == f_routecheck)*/) +	begin +		if (i_tlast) +			f_bytecount <= 0; +		else +			f_bytecount <= f_bytecount + f_vbytes; +	end + +	// +	// Count the number of clock cycles between ready's.  We'll use this in +	// a bit to insist on an (optional) minimum transfer speed. +	initial	f_stall_count = 0; +	always @(posedge i_aclk) +	if (!i_aresetn || !i_tvalid || i_tready) +		f_stall_count <= 0; +	else if (!(&f_stall_count)) +		f_stall_count <= f_stall_count + 1; + +	// +	// F_MAX_PACKET +	// +	// An optional check, to make certain packets don't exceed some maximum +	// length +	generate if (F_MAX_PACKET > 0) +	begin : MAX_PACKET + +		always @(*) +			`SLAVE_ASSUME(f_bytecount + f_vbytes <= F_MAX_PACKET); + +	end endgenerate + +	// +	// F_MIN_PACKET +	// +	// An optoinal check, forcing a minimum packet length +	generate if (F_MIN_PACKET > 0) +	begin : MIN_PACKET + +		always @(*) +		if (i_tvalid && i_tlast) +			`SLAVE_ASSUME(f_bytecount + f_vbytes >= F_MIN_PACKET); + +	end endgenerate + +	// +	// F_MAX_STALL +	// +	// Another optional check, this time insisting that the READY flag can +	// only be low for up to F_MAX_STALL clocks. +	// +	generate if (F_MAX_STALL > 0) +	begin : MAX_STALL_CHECK + +		always @(*) +			`SLAVE_ASSERT(f_stall_count < F_MAX_STALL); + +	end endgenerate +endmodule +`undef	SLAVE_ASSUME +`undef	SLAVE_ASSERT + diff --git a/testsuite/ghdl-issues/issue1309/faxis_slave.v b/testsuite/ghdl-issues/issue1309/faxis_slave.v new file mode 100644 index 0000000..c350e8b --- /dev/null +++ b/testsuite/ghdl-issues/issue1309/faxis_slave.v @@ -0,0 +1,230 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Filename: 	faxis_slave.v +// +// Project:	WB2AXIPSP: bus bridges and other odds and ends +// +// Purpose:	Formal properties for verifying the proper functionality of an +//		AXI Stream slave. +// +// Creator:	Dan Gisselquist, Ph.D. +//		Gisselquist Technology, LLC +// +//////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2019-2020, Gisselquist Technology, LLC +// +// This file is part of the WB2AXIP project. +// +// The WB2AXIP project contains free software and gateware, licensed under the +// Apache License, Version 2.0 (the "License").  You may not use this project, +// or this file, except in compliance with the License.  You may obtain a copy +// of the License at +// +//	http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the +// License for the specific language governing permissions and limitations +// under the License. +// +//////////////////////////////////////////////////////////////////////////////// +// +// +`default_nettype none +// +module	faxis_slave #( +	parameter	F_MAX_PACKET = 0, +	parameter	F_MIN_PACKET = 0, +	parameter	F_MAX_STALL  = 0, +	parameter	C_S_AXI_DATA_WIDTH  = 32, +	parameter	C_S_AXI_ID_WIDTH = 1, +	parameter	C_S_AXI_ADDR_WIDTH = 1, +	parameter	C_S_AXI_USER_WIDTH = 1, +	parameter [0:0]	OPT_ASYNC_RESET = 1'b0, +	// +	// F_LGDEPTH is the number of bits necessary to represent a packets +	// length +	parameter	F_LGDEPTH = 32, +	// +	localparam	AW  = C_S_AXI_ADDR_WIDTH, +	localparam	DW  = C_S_AXI_DATA_WIDTH, +	localparam	IDW  = C_S_AXI_ID_WIDTH, +	localparam	UW  = C_S_AXI_USER_WIDTH +	// +	) ( +	// +	input	wire			i_aclk, i_aresetn, +	input	wire			i_tvalid, +	input	wire			i_tready = 1, +	input	wire	[DW-1:0]	i_tdata, +	input	wire	[DW/8-1:0]	i_tstrb = {(DW/8){1'b1}}, +	input	wire	[DW/8-1:0]	i_tkeep = {(DW/8){1'b1}}, +	input	wire			i_tlast, +	input	wire	[(IDW>0?IDW:1)-1:0]	i_tid = {(IDW){1'b0}}, +	input	wire	[(AW>0?AW:1)-1:0]	i_tdest = {(AW){1'b0}}, +	input	wire	[(UW>0?UW:1)-1:0]	i_tuser = {(UW){1'b0}}, +	// +	output	reg	[F_LGDEPTH-1:0]	f_bytecount, +	//(* anyconst *) output	reg	[AW+IDW-1:0]	f_routecheck +	); + +`define	SLAVE_ASSUME	assume +`define	SLAVE_ASSERT	assert + +	localparam	F_STALLBITS	= (F_MAX_STALL <= 1) +						? 1 : $clog2(F_MAX_STALL+2); +	reg				f_past_valid; +	reg	[F_LGDEPTH-1:0]		f_vbytes; +	reg	[F_STALLBITS-1:0]	f_stall_count; +	integer	iB; +	genvar	k; + +	// +	// f_past_valid is used to make certain that temporal assertions +	// depending upon past values depend upon *valid* past values. +	// It is true for all clocks other than the first clock. +	initial	f_past_valid = 1'b0; +	always @(posedge i_aclk) +		f_past_valid <= 1'b1; + +	// +	// Reset should always be active (low) initially +	always @(posedge i_aclk) +	if (!f_past_valid) +		`SLAVE_ASSUME(!i_aresetn); + +	// +	// During and following a reset, TVALID should be deasserted +	always @(posedge i_aclk) +	if ((!f_past_valid)||(!i_aresetn && OPT_ASYNC_RESET)||($past(!i_aresetn))) +		`SLAVE_ASSUME(!i_tvalid); + +	// +	// If TVALID but not TREADY, then the master isn't allowed to change +	// anything until the slave asserts TREADY. +	always @(posedge i_aclk) +	if ((f_past_valid)&&($past(i_aresetn))&&(!OPT_ASYNC_RESET || i_aresetn) +		&&($past(i_tvalid))&&(!$past(i_tready))) +	begin +		`SLAVE_ASSUME(i_tvalid); +		`SLAVE_ASSUME($stable(i_tstrb)); +		`SLAVE_ASSUME($stable(i_tkeep)); +		`SLAVE_ASSUME($stable(i_tlast)); +		`SLAVE_ASSUME($stable(i_tid)); +		`SLAVE_ASSUME($stable(i_tdest)); +		`SLAVE_ASSUME($stable(i_tuser)); +	end + +	generate for(k=0; k<DW/8; k=k+1) +	begin : CHECK_PARTIAL_DATA + +		// If TVALID && !TREADY, only those TDATA values with TKEEP +		// high are required to maintain their values until TREADY +		// becomes true. +		always @(posedge i_aclk) +		if ((f_past_valid)&&($past(i_aresetn)) +			&&(!OPT_ASYNC_RESET || i_aresetn) +			&&($past(i_tvalid))&&(!$past(i_tready))) +		begin +			if (i_tkeep[k]) +				`SLAVE_ASSUME($stable(i_tdata[k*8 +: 8])); +			// else this is a null (don't care) byte, with +			// no data within it +			// +		end + +	end endgenerate + +	// +	// TKEEP == LOW and TSTRB == HIGH is reserved per the spec, and +	// must not be used +	always @(posedge i_aclk) +	if (i_tvalid) +		`SLAVE_ASSUME((~i_tkeep & i_tstrb)==0); + +	// +	// f_vbytes is the number of valid bytes contained in the current beat +	// It is used for counting packet lengths below. +	always @(*) +	if (!i_tvalid) +		f_vbytes = 0; +	else begin +		f_vbytes = 0; +		for(iB=0; iB < DW/8; iB=iB+1) +		if (i_tkeep[iB] && i_tstrb[iB]) +			f_vbytes = f_vbytes + 1; +	end + +	// +	// f_bytecount is the number of bytes that have taken place so far in +	// the current packet transmission.  Note that we are *only* counting +	// our location within the stream if the TUSER and TDEST fields match +	// our (solver chosen) ROUTECHECK.  That way we don't have to check +	// *EVERY POSSIBLE* TUSER and TDEST combination. +	initial	f_bytecount = 0; +	always @(posedge i_aclk) +	if (!i_aresetn) +		f_bytecount <= 0; +	else if (i_tready && i_tvalid /*&& ({ i_tuser, i_tdest } == f_routecheck)*/) +	begin +		if (i_tlast) +			f_bytecount <= 0; +		else +			f_bytecount <= f_bytecount + f_vbytes; +	end + +	// +	// Count the number of clock cycles between ready's.  We'll use this in +	// a bit to insist on an (optional) minimum transfer speed. +	initial	f_stall_count = 0; +	always @(posedge i_aclk) +	if (!i_aresetn || !i_tvalid || i_tready) +		f_stall_count <= 0; +	else if (!(&f_stall_count)) +		f_stall_count <= f_stall_count + 1; + +	// +	// F_MAX_PACKET +	// +	// An optional check, to make certain packets don't exceed some maximum +	// length +	generate if (F_MAX_PACKET > 0) +	begin : MAX_PACKET + +		always @(*) +			`SLAVE_ASSUME(f_bytecount + f_vbytes <= F_MAX_PACKET); + +	end endgenerate + +	// +	// F_MIN_PACKET +	// +	// An optoinal check, forcing a minimum packet length +	generate if (F_MIN_PACKET > 0) +	begin : MIN_PACKET + +		always @(*) +		if (i_tvalid && i_tlast) +			`SLAVE_ASSUME(f_bytecount + f_vbytes >= F_MIN_PACKET); + +	end endgenerate + +	// +	// F_MAX_STALL +	// +	// Another optional check, this time insisting that the READY flag can +	// only be low for up to F_MAX_STALL clocks. +	// +	generate if (F_MAX_STALL > 0) +	begin : MAX_STALL_CHECK + +		always @(*) +			`SLAVE_ASSERT(f_stall_count < F_MAX_STALL); + +	end endgenerate +endmodule +`undef	SLAVE_ASSUME +`undef	SLAVE_ASSERT + diff --git a/testsuite/ghdl-issues/issue1309/tb_formal_top.v b/testsuite/ghdl-issues/issue1309/tb_formal_top.v new file mode 100644 index 0000000..1bbc87e --- /dev/null +++ b/testsuite/ghdl-issues/issue1309/tb_formal_top.v @@ -0,0 +1,131 @@ +`default_nettype none +module tb_formal_top #( +	parameter no_backpressure = 0 +) ( +	input wire clk, +	input wire aresetn, + +	input wire [31:0] s_axis_tdata, +	input wire s_axis_tlast, +	input wire s_axis_tvalid, +	output wire s_axis_tready, + +	output wire [31:0] m_axis_tdata, +	output wire m_axis_tlast, +	output wire m_axis_tvalid, +	input wire m_axis_tready, + +	output wire signed [31:0] discrepancy +); + +	reg [31:0] input_byte_count; +	reg [31:0] output_byte_count; +	//reg [0+0-1:0] input_routecheck; +	//reg [0+0-1:0] output_routecheck; + +	reg f_past_valid; +	wire signed [31:0] byte_count_discrepancy; +	reg packet_end; + +faxis_slave #( +	.F_MAX_PACKET(0), +	.F_MIN_PACKET(0), +	.F_MAX_STALL(0), +	.C_S_AXI_DATA_WIDTH(32), +	.C_S_AXI_ID_WIDTH(0), +	.C_S_AXI_ADDR_WIDTH(0), +	.C_S_AXI_USER_WIDTH(0), +	.OPT_ASYNC_RESET(1'b0) +) axis_slave_formal_properties ( +	.i_aclk(clk), +	.i_aresetn(aresetn), +	.i_tvalid(s_axis_tvalid), +	.i_tready(s_axis_tready), +	.i_tdata(s_axis_tdata), +	.i_tlast(s_axis_tlast), +	.f_bytecount(input_byte_count) +	//.f_routecheck(input_routecheck) +); + +faxis_master #( +	.F_MAX_PACKET(0), +	.F_MIN_PACKET(0), +	.F_MAX_STALL(0), +	.C_S_AXI_DATA_WIDTH(32), +	.C_S_AXI_ID_WIDTH(0), +	.C_S_AXI_ADDR_WIDTH(0), +	.C_S_AXI_USER_WIDTH(0), +	.OPT_ASYNC_RESET(1'b0) +) axis_master_formal_properties ( +	.i_aclk(clk), +	.i_aresetn(aresetn), +	.i_tvalid(m_axis_tvalid), +	.i_tready(m_axis_tready), +	.i_tdata(m_axis_tdata), +	.i_tlast(m_axis_tlast), +	.f_bytecount(output_byte_count) +	//.f_routecheck(output_routecheck) +); + +axis_squarer axis_dut ( +	.clk(clk), +	.aresetn(aresetn), +	.s_axis_tdata(s_axis_tdata), +	.s_axis_tvalid(s_axis_tvalid), +	.s_axis_tready(s_axis_tready), +	.s_axis_tlast(s_axis_tlast), +	.m_axis_tdata(m_axis_tdata), +	.m_axis_tvalid(m_axis_tvalid), +	.m_axis_tready(m_axis_tready), +	.m_axis_tlast(m_axis_tlast) +); + +// f_past_valid is used to make certain that temporal assertions +// depending upon past values depend upon *valid* past values. +// It is true for all clocks other than the first clock. +initial	f_past_valid = 1'b0; +always @(posedge clk) +	f_past_valid <= 1'b1; + +always @(*) +begin +	assert(input_byte_count%4==0); +	assert(output_byte_count%4==0); +	byte_count_discrepancy = input_byte_count-output_byte_count; +	discrepancy <= byte_count_discrepancy; +	assume(input_byte_count<=32'h7fffffff); +	assert(output_byte_count<=32'h20); +	if (aresetn == 1) begin +		//assert(byte_count_discrepancy>=-36); +		/*assert(byte_count_discrepancy%32 == 0 +			|| byte_count_discrepancy%32 == 4 +			|| byte_count_discrepancy%32 == -4);*/ +	end +	// Hints below are only for the cover property +	//assume(aresetn == f_past_valid); +	//assume(s_axis_tvalid == 1'b1); +	//assume(m_axis_tready == 1'b1); +	//assume(input_byte_count & 32'hFFFF0000 == 0); +	//cover(byte_count_discrepancy < -4); +	//cover(output_byte_count==16); +end + +always @(posedge clk) +begin +	if (f_past_valid && $past(aresetn)==1 && aresetn ==1) begin +		if ($past(s_axis_tvalid) == 1'b1 && $past(s_axis_tready) == 1'b1) begin +			assert(m_axis_tvalid == 1'b1); +			assert(~$past(s_axis_tdata)==m_axis_tdata); +		end +	end +	if (no_backpressure==1) begin +		assume(m_axis_tready==1); +		assume(s_axis_tlast==0); +	end +	cover(f_past_valid && $past(aresetn)==1 && aresetn==1 +		&& $past(s_axis_tready)==1'b0 && $past(m_axis_tvalid)==1'b0 +		&& s_axis_tready==1'b1 && m_axis_tvalid==1'b0); +	//cover(output_byte_count==16'h10); +end + +endmodule diff --git a/testsuite/ghdl-issues/issue1309/testsuite.sh b/testsuite/ghdl-issues/issue1309/testsuite.sh new file mode 100755 index 0000000..a50cfc8 --- /dev/null +++ b/testsuite/ghdl-issues/issue1309/testsuite.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +topdir=../.. +. $topdir/testenv.sh + +#formal axis_squarer +run_symbiyosys axis_squarer.sby cover + +clean +echo OK  | 
