OpenCores
URL https://opencores.org/ocsvn/zipcpu/zipcpu/trunk

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [bench/] [formal/] [abs_mpy.v] - Rev 209

Compare with Previous | Blame | View Log

////////////////////////////////////////////////////////////////////////////////
//
// Filename:	abs_mpy.v
//
// Project:	Zip CPU -- a small, lightweight, RISC CPU soft core
//
// Purpose:	This code has been modified from the mpyop.v file so as to
//		abstract the multiply that formal methods struggle so hard to
//	deal with.  It also simplifies the interface so that (if enabled)
//	the multiply will return in 1-6 clocks, rather than the specified
//	number for the given architecture.
//
//
// Creator:	Dan Gisselquist, Ph.D.
//		Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015-2019, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of  the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
// target there if the PDF file isn't present.)  If not, see
// <http://www.gnu.org/licenses/> for a copy.
//
// License:	GPL, v3, as defined and found on www.gnu.org,
//		http://www.gnu.org/licenses/gpl.html
//
//
////////////////////////////////////////////////////////////////////////////////
//
//
`default_nettype	none
//
module	abs_mpy(i_clk,i_reset, i_stb, i_op, i_a, i_b, o_valid, o_busy, o_result, o_hi);
	// The following parameter selects which multiply algorithm we use.
	// Timing performance is strictly dependent upon it.
	parameter	IMPLEMENT_MPY = 1;
	parameter	MAXDELAY = 3;
	input	wire		i_clk, i_reset, i_stb;
	input	wire	[1:0]	i_op; // 2'b00=MPY, 2'b10=MPYUHI, 2'b11=MPYSHI
	input	wire	[31:0]	i_a, i_b;
	output	reg		o_valid; // True if we'll be valid on the next clock;
	output	wire		o_busy; // The multiply is busy if true
	output	wire	[63:0]	o_result; // Where we dump the multiply result
	output	reg		o_hi;	// Return the high half of the multiply
 
`define	ASSERT	assert
// i_stb instead of this_is_a_multiply_op
// o_result
// o_busy
// o_done
	generate
	if (IMPLEMENT_MPY == 0)
	begin // No multiply support.
 
		assign	o_result   = 64'h00;
		assign	o_busy     = 1'b0;
		always @(*)
			o_valid    = i_stb;
		always @(*) o_hi = 1'b0; // Not needed
 
	end else begin // Our single clock option (no extra clocks)
 
		(* anyseq *) reg	[2:0]	next_delay_to_valid;
		(* anyseq *) reg	[63:0]	any_result;
 
		assign	o_result = any_result;
 
		reg	[2:0]	delay_to_valid;
		reg		r_busy;
 
		always @(*)
		assume((MAXDELAY == 0)
			||(next_delay_to_valid < MAXDELAY));
 
		// always @(*)
		// if (IMPLEMENT_MPY == 1)
			// assume(next_delay_to_valid == 0);
		always @(*)
		if (IMPLEMENT_MPY>0)
			assume(next_delay_to_valid == IMPLEMENT_MPY-1);
 
		initial	delay_to_valid = 3'h0;
		always @(posedge i_clk)
		if (i_reset)
			delay_to_valid <= 0;
		else if ((i_stb)&&(next_delay_to_valid != 0))
			delay_to_valid <= next_delay_to_valid;
		else if (delay_to_valid > 0)
			delay_to_valid <= delay_to_valid - 1'b1;
 
		initial	r_busy = 1'b0;
		always @(posedge i_clk)
		if (i_reset)
			r_busy <= 1'b0;
		else if (i_stb)
			r_busy <= (next_delay_to_valid != 0);
		else if (r_busy)
			r_busy <= (delay_to_valid != 3'h1);
 
		initial	o_valid = 0;
		always @(posedge i_clk)
		if (i_reset)
			o_valid <= 1'b0;
		else if ((i_stb)&&(next_delay_to_valid == 0))
			o_valid <= 1'b1;
		else
			o_valid <= (o_busy)&&(delay_to_valid == 3'h1);
 
		always @(posedge i_clk)
		if (i_stb)
			o_hi <= i_op[1];
 
		assign	o_busy = r_busy;
	end
	endgenerate // All possible multiply results have been determined
 
endmodule
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2021 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.