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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [bench/] [formal/] [abs_mpy.v] - Blame information for rev 209

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 209 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    abs_mpy.v
4
//
5
// Project:     Zip CPU -- a small, lightweight, RISC CPU soft core
6
//
7
// Purpose:     This code has been modified from the mpyop.v file so as to
8
//              abstract the multiply that formal methods struggle so hard to
9
//      deal with.  It also simplifies the interface so that (if enabled)
10
//      the multiply will return in 1-6 clocks, rather than the specified
11
//      number for the given architecture.
12
//
13
//
14
// Creator:     Dan Gisselquist, Ph.D.
15
//              Gisselquist Technology, LLC
16
//
17
////////////////////////////////////////////////////////////////////////////////
18
//
19
// Copyright (C) 2015-2019, Gisselquist Technology, LLC
20
//
21
// This program is free software (firmware): you can redistribute it and/or
22
// modify it under the terms of  the GNU General Public License as published
23
// by the Free Software Foundation, either version 3 of the License, or (at
24
// your option) any later version.
25
//
26
// This program is distributed in the hope that it will be useful, but WITHOUT
27
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
28
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
29
// for more details.
30
//
31
// You should have received a copy of the GNU General Public License along
32
// with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
33
// target there if the PDF file isn't present.)  If not, see
34
// <http://www.gnu.org/licenses/> for a copy.
35
//
36
// License:     GPL, v3, as defined and found on www.gnu.org,
37
//              http://www.gnu.org/licenses/gpl.html
38
//
39
//
40
////////////////////////////////////////////////////////////////////////////////
41
//
42
//
43
`default_nettype        none
44
//
45
module  abs_mpy(i_clk,i_reset, i_stb, i_op, i_a, i_b, o_valid, o_busy, o_result, o_hi);
46
        // The following parameter selects which multiply algorithm we use.
47
        // Timing performance is strictly dependent upon it.
48
        parameter       IMPLEMENT_MPY = 1;
49
        parameter       MAXDELAY = 3;
50
        input   wire            i_clk, i_reset, i_stb;
51
        input   wire    [1:0]    i_op; // 2'b00=MPY, 2'b10=MPYUHI, 2'b11=MPYSHI
52
        input   wire    [31:0]   i_a, i_b;
53
        output  reg             o_valid; // True if we'll be valid on the next clock;
54
        output  wire            o_busy; // The multiply is busy if true
55
        output  wire    [63:0]   o_result; // Where we dump the multiply result
56
        output  reg             o_hi;   // Return the high half of the multiply
57
 
58
`define ASSERT  assert
59
// i_stb instead of this_is_a_multiply_op
60
// o_result
61
// o_busy
62
// o_done
63
        generate
64
        if (IMPLEMENT_MPY == 0)
65
        begin // No multiply support.
66
 
67
                assign  o_result   = 64'h00;
68
                assign  o_busy     = 1'b0;
69
                always @(*)
70
                        o_valid    = i_stb;
71
                always @(*) o_hi = 1'b0; // Not needed
72
 
73
        end else begin // Our single clock option (no extra clocks)
74
 
75
                (* anyseq *) reg        [2:0]    next_delay_to_valid;
76
                (* anyseq *) reg        [63:0]   any_result;
77
 
78
                assign  o_result = any_result;
79
 
80
                reg     [2:0]    delay_to_valid;
81
                reg             r_busy;
82
 
83
                always @(*)
84
                assume((MAXDELAY == 0)
85
                        ||(next_delay_to_valid < MAXDELAY));
86
 
87
                // always @(*)
88
                // if (IMPLEMENT_MPY == 1)
89
                        // assume(next_delay_to_valid == 0);
90
                always @(*)
91
                if (IMPLEMENT_MPY>0)
92
                        assume(next_delay_to_valid == IMPLEMENT_MPY-1);
93
 
94
                initial delay_to_valid = 3'h0;
95
                always @(posedge i_clk)
96
                if (i_reset)
97
                        delay_to_valid <= 0;
98
                else if ((i_stb)&&(next_delay_to_valid != 0))
99
                        delay_to_valid <= next_delay_to_valid;
100
                else if (delay_to_valid > 0)
101
                        delay_to_valid <= delay_to_valid - 1'b1;
102
 
103
                initial r_busy = 1'b0;
104
                always @(posedge i_clk)
105
                if (i_reset)
106
                        r_busy <= 1'b0;
107
                else if (i_stb)
108
                        r_busy <= (next_delay_to_valid != 0);
109
                else if (r_busy)
110
                        r_busy <= (delay_to_valid != 3'h1);
111
 
112
                initial o_valid = 0;
113
                always @(posedge i_clk)
114
                if (i_reset)
115
                        o_valid <= 1'b0;
116
                else if ((i_stb)&&(next_delay_to_valid == 0))
117
                        o_valid <= 1'b1;
118
                else
119
                        o_valid <= (o_busy)&&(delay_to_valid == 3'h1);
120
 
121
                always @(posedge i_clk)
122
                if (i_stb)
123
                        o_hi <= i_op[1];
124
 
125
                assign  o_busy = r_busy;
126
        end
127
        endgenerate // All possible multiply results have been determined
128
 
129
endmodule

powered by: WebSVN 2.1.0

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