lm32_shifter.v

Sun, 04 Apr 2010 22:05:07 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sun, 04 Apr 2010 22:05:07 +0100
changeset 3
b153470d41c5
parent 0
cd0b58aa6f83
child 26
73de224304c1
permissions
-rw-r--r--

remove more Lattice-specific fluff

Code now synthesizes properly on Altera Quartus 9.0 build 235

philpem@0 1 // =============================================================================
philpem@0 2 // COPYRIGHT NOTICE
philpem@0 3 // Copyright 2006 (c) Lattice Semiconductor Corporation
philpem@0 4 // ALL RIGHTS RESERVED
philpem@0 5 // This confidential and proprietary software may be used only as authorised by
philpem@0 6 // a licensing agreement from Lattice Semiconductor Corporation.
philpem@0 7 // The entire notice above must be reproduced on all authorized copies and
philpem@0 8 // copies may only be made to the extent permitted by a licensing agreement from
philpem@0 9 // Lattice Semiconductor Corporation.
philpem@0 10 //
philpem@0 11 // Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada)
philpem@0 12 // 5555 NE Moore Court 408-826-6000 (other locations)
philpem@0 13 // Hillsboro, OR 97124 web : http://www.latticesemi.com/
philpem@0 14 // U.S.A email: techsupport@latticesemi.com
philpem@0 15 // =============================================================================/
philpem@0 16 // FILE DETAILS
philpem@0 17 // Project : LatticeMico32
philpem@0 18 // File : lm32_shifter.v
philpem@0 19 // Title : Barrel shifter
philpem@0 20 // Dependencies : lm32_include.v
philpem@0 21 // Version : 6.1.17
philpem@0 22 // : Initial Release
philpem@0 23 // Version : 7.0SP2, 3.0
philpem@0 24 // : No Change
philpem@0 25 // Version : 3.1
philpem@0 26 // : No Change
philpem@0 27 // =============================================================================
philpem@0 28
philpem@0 29 `include "lm32_include.v"
philpem@0 30
philpem@0 31 /////////////////////////////////////////////////////
philpem@0 32 // Module interface
philpem@0 33 /////////////////////////////////////////////////////
philpem@0 34
philpem@0 35 module lm32_shifter (
philpem@0 36 // ----- Inputs -------
philpem@0 37 clk_i,
philpem@0 38 rst_i,
philpem@0 39 stall_x,
philpem@0 40 direction_x,
philpem@0 41 sign_extend_x,
philpem@0 42 operand_0_x,
philpem@0 43 operand_1_x,
philpem@0 44 // ----- Outputs -------
philpem@0 45 shifter_result_m
philpem@0 46 );
philpem@0 47
philpem@0 48 /////////////////////////////////////////////////////
philpem@0 49 // Inputs
philpem@0 50 /////////////////////////////////////////////////////
philpem@0 51
philpem@0 52 input clk_i; // Clock
philpem@0 53 input rst_i; // Reset
philpem@0 54 input stall_x; // Stall instruction in X stage
philpem@0 55 input direction_x; // Direction to shift
philpem@0 56 input sign_extend_x; // Whether shift is arithmetic (1'b1) or logical (1'b0)
philpem@0 57 input [`LM32_WORD_RNG] operand_0_x; // Operand to shift
philpem@0 58 input [`LM32_WORD_RNG] operand_1_x; // Operand that specifies how many bits to shift by
philpem@0 59
philpem@0 60 /////////////////////////////////////////////////////
philpem@0 61 // Outputs
philpem@0 62 /////////////////////////////////////////////////////
philpem@0 63
philpem@0 64 output [`LM32_WORD_RNG] shifter_result_m; // Result of shift
philpem@0 65 wire [`LM32_WORD_RNG] shifter_result_m;
philpem@0 66
philpem@0 67 /////////////////////////////////////////////////////
philpem@0 68 // Internal nets and registers
philpem@0 69 /////////////////////////////////////////////////////
philpem@0 70
philpem@0 71 reg direction_m;
philpem@0 72 reg [`LM32_WORD_RNG] left_shift_result;
philpem@0 73 reg [`LM32_WORD_RNG] right_shift_result;
philpem@0 74 reg [`LM32_WORD_RNG] left_shift_operand;
philpem@0 75 wire [`LM32_WORD_RNG] right_shift_operand;
philpem@0 76 wire fill_value;
philpem@0 77 wire [`LM32_WORD_RNG] right_shift_in;
philpem@0 78
philpem@0 79 integer shift_idx_0;
philpem@0 80 integer shift_idx_1;
philpem@0 81
philpem@0 82 /////////////////////////////////////////////////////
philpem@0 83 // Combinational Logic
philpem@0 84 /////////////////////////////////////////////////////
philpem@0 85
philpem@0 86 // Select operands - To perform a left shift, we reverse the bits and perform a right shift
philpem@0 87 always @(*)
philpem@0 88 begin
philpem@0 89 for (shift_idx_0 = 0; shift_idx_0 < `LM32_WORD_WIDTH; shift_idx_0 = shift_idx_0 + 1)
philpem@0 90 left_shift_operand[`LM32_WORD_WIDTH-1-shift_idx_0] = operand_0_x[shift_idx_0];
philpem@0 91 end
philpem@0 92 assign right_shift_operand = direction_x == `LM32_SHIFT_OP_LEFT ? left_shift_operand : operand_0_x;
philpem@0 93
philpem@0 94 // Determine fill value for right shift - Sign bit for arithmetic shift, or zero for logical shift
philpem@0 95 assign fill_value = (sign_extend_x == `TRUE) && (direction_x == `LM32_SHIFT_OP_RIGHT)
philpem@0 96 ? operand_0_x[`LM32_WORD_WIDTH-1]
philpem@0 97 : 1'b0;
philpem@0 98
philpem@0 99 // Determine bits to shift in for right shift or rotate
philpem@0 100 assign right_shift_in = {`LM32_WORD_WIDTH{fill_value}};
philpem@0 101
philpem@0 102 // Reverse bits to get left shift result
philpem@0 103 always @(*)
philpem@0 104 begin
philpem@0 105 for (shift_idx_1 = 0; shift_idx_1 < `LM32_WORD_WIDTH; shift_idx_1 = shift_idx_1 + 1)
philpem@0 106 left_shift_result[`LM32_WORD_WIDTH-1-shift_idx_1] = right_shift_result[shift_idx_1];
philpem@0 107 end
philpem@0 108
philpem@0 109 // Select result
philpem@0 110 assign shifter_result_m = direction_m == `LM32_SHIFT_OP_LEFT ? left_shift_result : right_shift_result;
philpem@0 111
philpem@0 112 /////////////////////////////////////////////////////
philpem@0 113 // Sequential Logic
philpem@0 114 /////////////////////////////////////////////////////
philpem@0 115
philpem@0 116 // Perform right shift
philpem@0 117 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
philpem@0 118 begin
philpem@0 119 if (rst_i == `TRUE)
philpem@0 120 begin
philpem@0 121 right_shift_result <= {`LM32_WORD_WIDTH{1'b0}};
philpem@0 122 direction_m <= `FALSE;
philpem@0 123 end
philpem@0 124 else
philpem@0 125 begin
philpem@0 126 if (stall_x == `FALSE)
philpem@0 127 begin
philpem@0 128 right_shift_result <= {right_shift_in, right_shift_operand} >> operand_1_x[`LM32_SHIFT_RNG];
philpem@0 129 direction_m <= direction_x;
philpem@0 130 end
philpem@0 131 end
philpem@0 132 end
philpem@0 133
philpem@0 134 endmodule