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