| // ================================================================== |
| // >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<< |
| // ------------------------------------------------------------------ |
| // Copyright (c) 2006-2011 by Lattice Semiconductor Corporation |
| // ALL RIGHTS RESERVED |
| // ------------------------------------------------------------------ |
| // |
| // IMPORTANT: THIS FILE IS AUTO-GENERATED BY THE LATTICEMICO SYSTEM. |
| // |
| // Permission: |
| // |
| // Lattice Semiconductor grants permission to use this code |
| // pursuant to the terms of the Lattice Semiconductor Corporation |
| // Open Source License Agreement. |
| // |
| // Disclaimer: |
| // |
| // Lattice Semiconductor provides no warranty regarding the use or |
| // functionality of this code. It is the user's responsibility to |
| // verify the user's design for consistency and functionality through |
| // the use of formal verification methods. |
| // |
| // -------------------------------------------------------------------- |
| // |
| // Lattice Semiconductor Corporation |
| // 5555 NE Moore Court |
| // Hillsboro, OR 97214 |
| // U.S.A |
| // |
| // TEL: 1-800-Lattice (USA and Canada) |
| // 503-286-8001 (other locations) |
| // |
| // web: http://www.latticesemi.com/ |
| // email: techsupport@latticesemi.com |
| // |
| // -------------------------------------------------------------------- |
| // FILE DETAILS |
| // Project : LatticeMico32 |
| // File : lm32_shifter.v |
| // Title : Barrel shifter |
| // Dependencies : lm32_include.v |
| // Version : 6.1.17 |
| // : Initial Release |
| // Version : 7.0SP2, 3.0 |
| // : No Change |
| // Version : 3.1 |
| // : No Change |
| // ============================================================================= |
| |
| `include "lm32_include.v" |
| |
| ///////////////////////////////////////////////////// |
| // Module interface |
| ///////////////////////////////////////////////////// |
| |
| module lm32_shifter ( |
| // ----- Inputs ------- |
| clk_i, |
| rst_i, |
| stall_x, |
| direction_x, |
| sign_extend_x, |
| operand_0_x, |
| operand_1_x, |
| // ----- Outputs ------- |
| shifter_result_m |
| ); |
| |
| ///////////////////////////////////////////////////// |
| // Inputs |
| ///////////////////////////////////////////////////// |
| |
| input clk_i; // Clock |
| input rst_i; // Reset |
| input stall_x; // Stall instruction in X stage |
| input direction_x; // Direction to shift |
| input sign_extend_x; // Whether shift is arithmetic (1'b1) or logical (1'b0) |
| input [`LM32_WORD_RNG] operand_0_x; // Operand to shift |
| input [`LM32_WORD_RNG] operand_1_x; // Operand that specifies how many bits to shift by |
| |
| ///////////////////////////////////////////////////// |
| // Outputs |
| ///////////////////////////////////////////////////// |
| |
| output [`LM32_WORD_RNG] shifter_result_m; // Result of shift |
| wire [`LM32_WORD_RNG] shifter_result_m; |
| |
| ///////////////////////////////////////////////////// |
| // Internal nets and registers |
| ///////////////////////////////////////////////////// |
| |
| reg direction_m; |
| reg [`LM32_WORD_RNG] left_shift_result; |
| reg [`LM32_WORD_RNG] right_shift_result; |
| reg [`LM32_WORD_RNG] left_shift_operand; |
| wire [`LM32_WORD_RNG] right_shift_operand; |
| wire fill_value; |
| wire [`LM32_WORD_RNG] right_shift_in; |
| |
| integer shift_idx_0; |
| integer shift_idx_1; |
| |
| ///////////////////////////////////////////////////// |
| // Combinational Logic |
| ///////////////////////////////////////////////////// |
| |
| // Select operands - To perform a left shift, we reverse the bits and perform a right shift |
| always @(*) |
| begin |
| for (shift_idx_0 = 0; shift_idx_0 < `LM32_WORD_WIDTH; shift_idx_0 = shift_idx_0 + 1) |
| left_shift_operand[`LM32_WORD_WIDTH-1-shift_idx_0] = operand_0_x[shift_idx_0]; |
| end |
| assign right_shift_operand = direction_x == `LM32_SHIFT_OP_LEFT ? left_shift_operand : operand_0_x; |
| |
| // Determine fill value for right shift - Sign bit for arithmetic shift, or zero for logical shift |
| assign fill_value = (sign_extend_x == `TRUE) && (direction_x == `LM32_SHIFT_OP_RIGHT) |
| ? operand_0_x[`LM32_WORD_WIDTH-1] |
| : 1'b0; |
| |
| // Determine bits to shift in for right shift or rotate |
| assign right_shift_in = {`LM32_WORD_WIDTH{fill_value}}; |
| |
| // Reverse bits to get left shift result |
| always @(*) |
| begin |
| for (shift_idx_1 = 0; shift_idx_1 < `LM32_WORD_WIDTH; shift_idx_1 = shift_idx_1 + 1) |
| left_shift_result[`LM32_WORD_WIDTH-1-shift_idx_1] = right_shift_result[shift_idx_1]; |
| end |
| |
| // Select result |
| assign shifter_result_m = direction_m == `LM32_SHIFT_OP_LEFT ? left_shift_result : right_shift_result; |
| |
| ///////////////////////////////////////////////////// |
| // Sequential Logic |
| ///////////////////////////////////////////////////// |
| |
| // Perform right shift |
| always @(posedge clk_i `CFG_RESET_SENSITIVITY) |
| begin |
| if (rst_i == `TRUE) |
| begin |
| right_shift_result <= {`LM32_WORD_WIDTH{1'b0}}; |
| direction_m <= `FALSE; |
| end |
| else |
| begin |
| if (stall_x == `FALSE) |
| begin |
| right_shift_result <= {right_shift_in, right_shift_operand} >> operand_1_x[`LM32_SHIFT_RNG]; |
| direction_m <= direction_x; |
| end |
| end |
| end |
| |
| endmodule |