lm32_mc_arithmetic.v

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