lm32_mc_arithmetic.v

changeset 24
c336e674a37e
parent 23
252df75c8f67
child 25
7422134cbfea
     1.1 diff -r 252df75c8f67 -r c336e674a37e lm32_mc_arithmetic.v
     1.2 --- a/lm32_mc_arithmetic.v	Sun Mar 06 21:17:31 2011 +0000
     1.3 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.4 @@ -1,288 +0,0 @@
     1.5 -// =============================================================================
     1.6 -//                           COPYRIGHT NOTICE
     1.7 -// Copyright 2006 (c) Lattice Semiconductor Corporation
     1.8 -// ALL RIGHTS RESERVED
     1.9 -// This confidential and proprietary software may be used only as authorised by
    1.10 -// a licensing agreement from Lattice Semiconductor Corporation.
    1.11 -// The entire notice above must be reproduced on all authorized copies and
    1.12 -// copies may only be made to the extent permitted by a licensing agreement from
    1.13 -// Lattice Semiconductor Corporation.
    1.14 -//
    1.15 -// Lattice Semiconductor Corporation        TEL : 1-800-Lattice (USA and Canada)
    1.16 -// 5555 NE Moore Court                            408-826-6000 (other locations)
    1.17 -// Hillsboro, OR 97124                     web  : http://www.latticesemi.com/
    1.18 -// U.S.A                                   email: techsupport@latticesemi.com
    1.19 -// =============================================================================/
    1.20 -//                         FILE DETAILS
    1.21 -// Project          : LatticeMico32
    1.22 -// File             : lm_mc_arithmetic.v
    1.23 -// Title            : Multi-cycle arithmetic unit.
    1.24 -// Dependencies     : lm32_include.v
    1.25 -// Version          : 6.1.17
    1.26 -//                  : Initial Release
    1.27 -// Version          : 7.0SP2, 3.0
    1.28 -//                  : No Change
    1.29 -// Version          : 3.1
    1.30 -//                  : No Change
    1.31 -// =============================================================================
    1.32 -
    1.33 -`include "lm32_include.v"
    1.34 -           
    1.35 -`define LM32_MC_STATE_RNG         2:0
    1.36 -`define LM32_MC_STATE_IDLE        3'b000
    1.37 -`define LM32_MC_STATE_MULTIPLY    3'b001
    1.38 -`define LM32_MC_STATE_MODULUS     3'b010   
    1.39 -`define LM32_MC_STATE_DIVIDE      3'b011 
    1.40 -`define LM32_MC_STATE_SHIFT_LEFT  3'b100
    1.41 -`define LM32_MC_STATE_SHIFT_RIGHT 3'b101
    1.42 -
    1.43 -/////////////////////////////////////////////////////
    1.44 -// Module interface
    1.45 -/////////////////////////////////////////////////////
    1.46 -
    1.47 -module lm32_mc_arithmetic (
    1.48 -    // ----- Inputs -----
    1.49 -    clk_i,
    1.50 -    rst_i,
    1.51 -    stall_d,
    1.52 -    kill_x,
    1.53 -`ifdef CFG_MC_DIVIDE_ENABLED
    1.54 -    divide_d,
    1.55 -    modulus_d,
    1.56 -`endif
    1.57 -`ifdef CFG_MC_MULTIPLY_ENABLED
    1.58 -    multiply_d,
    1.59 -`endif
    1.60 -`ifdef CFG_MC_BARREL_SHIFT_ENABLED
    1.61 -    shift_left_d,
    1.62 -    shift_right_d,
    1.63 -    sign_extend_d,
    1.64 -`endif
    1.65 -    operand_0_d,
    1.66 -    operand_1_d,
    1.67 -    // ----- Ouputs -----
    1.68 -    result_x,
    1.69 -`ifdef CFG_MC_DIVIDE_ENABLED
    1.70 -    divide_by_zero_x,
    1.71 -`endif
    1.72 -    stall_request_x
    1.73 -    );
    1.74 -
    1.75 -/////////////////////////////////////////////////////
    1.76 -// Inputs
    1.77 -/////////////////////////////////////////////////////
    1.78 -
    1.79 -input clk_i;                                    // Clock
    1.80 -input rst_i;                                    // Reset
    1.81 -input stall_d;                                  // Stall instruction in D stage
    1.82 -input kill_x;                                   // Kill instruction in X stage
    1.83 -`ifdef CFG_MC_DIVIDE_ENABLED
    1.84 -input divide_d;                                 // Perform divide
    1.85 -input modulus_d;                                // Perform modulus
    1.86 -`endif
    1.87 -`ifdef CFG_MC_MULTIPLY_ENABLED
    1.88 -input multiply_d;                               // Perform multiply
    1.89 -`endif
    1.90 -`ifdef CFG_MC_BARREL_SHIFT_ENABLED
    1.91 -input shift_left_d;                             // Perform left shift
    1.92 -input shift_right_d;                            // Perform right shift
    1.93 -input sign_extend_d;                            // Whether to sign-extend (arithmetic) or zero-extend (logical)
    1.94 -`endif
    1.95 -input [`LM32_WORD_RNG] operand_0_d;
    1.96 -input [`LM32_WORD_RNG] operand_1_d;
    1.97 -
    1.98 -/////////////////////////////////////////////////////
    1.99 -// Outputs
   1.100 -/////////////////////////////////////////////////////
   1.101 -
   1.102 -output [`LM32_WORD_RNG] result_x;               // Result of operation
   1.103 -reg    [`LM32_WORD_RNG] result_x;
   1.104 -`ifdef CFG_MC_DIVIDE_ENABLED
   1.105 -output divide_by_zero_x;                        // A divide by zero was attempted
   1.106 -reg    divide_by_zero_x;
   1.107 -`endif
   1.108 -output stall_request_x;                         // Request to stall pipeline from X stage back
   1.109 -wire   stall_request_x;
   1.110 -
   1.111 -/////////////////////////////////////////////////////
   1.112 -// Internal nets and registers 
   1.113 -/////////////////////////////////////////////////////
   1.114 -
   1.115 -reg [`LM32_WORD_RNG] p;                         // Temporary registers
   1.116 -reg [`LM32_WORD_RNG] a;
   1.117 -reg [`LM32_WORD_RNG] b;
   1.118 -`ifdef CFG_MC_DIVIDE_ENABLED
   1.119 -wire [32:0] t;
   1.120 -`endif
   1.121 -
   1.122 -reg [`LM32_MC_STATE_RNG] state;                 // Current state of FSM
   1.123 -reg [5:0] cycles;                               // Number of cycles remaining in the operation
   1.124 -
   1.125 -`ifdef CFG_MC_BARREL_SHIFT_ENABLED
   1.126 -reg sign_extend_x;                              // Whether to sign extend of zero extend right shifts
   1.127 -wire fill_value;                                // Value to fill with for right barrel-shifts
   1.128 -`endif
   1.129 -
   1.130 -/////////////////////////////////////////////////////
   1.131 -// Combinational logic
   1.132 -/////////////////////////////////////////////////////
   1.133 -
   1.134 -// Stall pipeline while any operation is being performed
   1.135 -assign stall_request_x = state != `LM32_MC_STATE_IDLE;
   1.136 -
   1.137 -`ifdef CFG_MC_DIVIDE_ENABLED
   1.138 -// Subtraction
   1.139 -assign t = {p[`LM32_WORD_WIDTH-2:0], a[`LM32_WORD_WIDTH-1]} - b;
   1.140 -`endif
   1.141 -
   1.142 -`ifdef CFG_MC_BARREL_SHIFT_ENABLED
   1.143 -// Determine fill value for right shift - Sign bit for arithmetic shift, or zero for logical shift
   1.144 -assign fill_value = (sign_extend_x == `TRUE) & b[`LM32_WORD_WIDTH-1];
   1.145 -`endif
   1.146 -
   1.147 -/////////////////////////////////////////////////////
   1.148 -// Sequential logic
   1.149 -/////////////////////////////////////////////////////
   1.150 -
   1.151 -// Perform right shift
   1.152 -always @(posedge clk_i `CFG_RESET_SENSITIVITY)
   1.153 -begin
   1.154 -    if (rst_i == `TRUE)
   1.155 -    begin
   1.156 -        cycles <= {6{1'b0}};
   1.157 -        p <= {`LM32_WORD_WIDTH{1'b0}};
   1.158 -        a <= {`LM32_WORD_WIDTH{1'b0}};
   1.159 -        b <= {`LM32_WORD_WIDTH{1'b0}};
   1.160 -`ifdef CFG_MC_BARREL_SHIFT_ENABLED
   1.161 -        sign_extend_x <= 1'b0;
   1.162 -`endif
   1.163 -`ifdef CFG_MC_DIVIDE_ENABLED
   1.164 -        divide_by_zero_x <= `FALSE;
   1.165 -`endif
   1.166 -        result_x <= {`LM32_WORD_WIDTH{1'b0}};
   1.167 -        state <= `LM32_MC_STATE_IDLE;
   1.168 -    end
   1.169 -    else
   1.170 -    begin
   1.171 -`ifdef CFG_MC_DIVIDE_ENABLED
   1.172 -        divide_by_zero_x <= `FALSE;
   1.173 -`endif
   1.174 -        case (state)
   1.175 -        `LM32_MC_STATE_IDLE:
   1.176 -        begin
   1.177 -            if (stall_d == `FALSE)                 
   1.178 -            begin          
   1.179 -                cycles <= `LM32_WORD_WIDTH;
   1.180 -                p <= 32'b0;
   1.181 -                a <= operand_0_d;
   1.182 -                b <= operand_1_d;                    
   1.183 -`ifdef CFG_MC_DIVIDE_ENABLED
   1.184 -                if (divide_d == `TRUE)
   1.185 -                    state <= `LM32_MC_STATE_DIVIDE;
   1.186 -                if (modulus_d == `TRUE)
   1.187 -                    state <= `LM32_MC_STATE_MODULUS;
   1.188 -`endif                    
   1.189 -`ifdef CFG_MC_MULTIPLY_ENABLED
   1.190 -                if (multiply_d == `TRUE)
   1.191 -                    state <= `LM32_MC_STATE_MULTIPLY;
   1.192 -`endif
   1.193 -`ifdef CFG_MC_BARREL_SHIFT_ENABLED
   1.194 -                if (shift_left_d == `TRUE)
   1.195 -                begin
   1.196 -                    state <= `LM32_MC_STATE_SHIFT_LEFT;
   1.197 -                    sign_extend_x <= sign_extend_d;
   1.198 -                    cycles <= operand_1_d[4:0];
   1.199 -                    a <= operand_0_d;
   1.200 -                    b <= operand_0_d;
   1.201 -                end
   1.202 -                if (shift_right_d == `TRUE)
   1.203 -                begin
   1.204 -                    state <= `LM32_MC_STATE_SHIFT_RIGHT;
   1.205 -                    sign_extend_x <= sign_extend_d;
   1.206 -                    cycles <= operand_1_d[4:0];
   1.207 -                    a <= operand_0_d;
   1.208 -                    b <= operand_0_d;
   1.209 -                end
   1.210 -`endif
   1.211 -            end            
   1.212 -        end
   1.213 -`ifdef CFG_MC_DIVIDE_ENABLED
   1.214 -        `LM32_MC_STATE_DIVIDE:
   1.215 -        begin
   1.216 -            if (t[32] == 1'b0)
   1.217 -            begin
   1.218 -                p <= t[31:0];
   1.219 -                a <= {a[`LM32_WORD_WIDTH-2:0], 1'b1};
   1.220 -            end
   1.221 -            else 
   1.222 -            begin
   1.223 -                p <= {p[`LM32_WORD_WIDTH-2:0], a[`LM32_WORD_WIDTH-1]};
   1.224 -                a <= {a[`LM32_WORD_WIDTH-2:0], 1'b0};
   1.225 -            end
   1.226 -            result_x <= a;
   1.227 -            if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE))
   1.228 -            begin
   1.229 -                // Check for divide by zero
   1.230 -                divide_by_zero_x <= b == {`LM32_WORD_WIDTH{1'b0}};
   1.231 -                state <= `LM32_MC_STATE_IDLE;
   1.232 -            end
   1.233 -            cycles <= cycles - 1'b1;
   1.234 -        end
   1.235 -        `LM32_MC_STATE_MODULUS:
   1.236 -        begin
   1.237 -            if (t[32] == 1'b0)
   1.238 -            begin
   1.239 -                p <= t[31:0];
   1.240 -                a <= {a[`LM32_WORD_WIDTH-2:0], 1'b1};
   1.241 -            end
   1.242 -            else 
   1.243 -            begin
   1.244 -                p <= {p[`LM32_WORD_WIDTH-2:0], a[`LM32_WORD_WIDTH-1]};
   1.245 -                a <= {a[`LM32_WORD_WIDTH-2:0], 1'b0};
   1.246 -            end
   1.247 -            result_x <= p;
   1.248 -            if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE))
   1.249 -            begin
   1.250 -                // Check for divide by zero
   1.251 -                divide_by_zero_x <= b == {`LM32_WORD_WIDTH{1'b0}};
   1.252 -                state <= `LM32_MC_STATE_IDLE;
   1.253 -            end
   1.254 -            cycles <= cycles - 1'b1;
   1.255 -        end
   1.256 -`endif        
   1.257 -`ifdef CFG_MC_MULTIPLY_ENABLED
   1.258 -        `LM32_MC_STATE_MULTIPLY:
   1.259 -        begin
   1.260 -            if (b[0] == 1'b1)
   1.261 -                p <= p + a;
   1.262 -            b <= {1'b0, b[`LM32_WORD_WIDTH-1:1]};
   1.263 -            a <= {a[`LM32_WORD_WIDTH-2:0], 1'b0};
   1.264 -            result_x <= p;
   1.265 -            if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE))
   1.266 -                state <= `LM32_MC_STATE_IDLE;
   1.267 -            cycles <= cycles - 1'b1;
   1.268 -        end
   1.269 -`endif     
   1.270 -`ifdef CFG_MC_BARREL_SHIFT_ENABLED
   1.271 -        `LM32_MC_STATE_SHIFT_LEFT:
   1.272 -        begin       
   1.273 -            a <= {a[`LM32_WORD_WIDTH-2:0], 1'b0};
   1.274 -            result_x <= a;
   1.275 -            if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE))
   1.276 -                state <= `LM32_MC_STATE_IDLE;
   1.277 -            cycles <= cycles - 1'b1;
   1.278 -        end
   1.279 -        `LM32_MC_STATE_SHIFT_RIGHT:
   1.280 -        begin       
   1.281 -            b <= {fill_value, b[`LM32_WORD_WIDTH-1:1]};
   1.282 -            result_x <= b;
   1.283 -            if ((cycles == `LM32_WORD_WIDTH'd0) || (kill_x == `TRUE))
   1.284 -                state <= `LM32_MC_STATE_IDLE;
   1.285 -            cycles <= cycles - 1'b1;
   1.286 -        end
   1.287 -`endif   
   1.288 -        endcase
   1.289 -    end
   1.290 -end 
   1.291 -
   1.292 -endmodule