lm32_shifter.v

Sat, 06 Aug 2011 01:26:56 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sat, 06 Aug 2011 01:26:56 +0100
changeset 27
d6c693415d59
parent 26
73de224304c1
permissions
-rwxr-xr-x

remove synthesis delay entities to ease merge

philpem@26 1 // ==================================================================
philpem@26 2 // >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
philpem@26 3 // ------------------------------------------------------------------
philpem@26 4 // Copyright (c) 2006-2011 by Lattice Semiconductor Corporation
philpem@26 5 // ALL RIGHTS RESERVED
philpem@26 6 // ------------------------------------------------------------------
philpem@26 7 //
philpem@26 8 // IMPORTANT: THIS FILE IS AUTO-GENERATED BY THE LATTICEMICO SYSTEM.
philpem@26 9 //
philpem@26 10 // Permission:
philpem@26 11 //
philpem@26 12 // Lattice Semiconductor grants permission to use this code
philpem@26 13 // pursuant to the terms of the Lattice Semiconductor Corporation
philpem@26 14 // Open Source License Agreement.
philpem@26 15 //
philpem@26 16 // Disclaimer:
philpem@0 17 //
philpem@26 18 // Lattice Semiconductor provides no warranty regarding the use or
philpem@26 19 // functionality of this code. It is the user's responsibility to
philpem@26 20 // verify the userís design for consistency and functionality through
philpem@26 21 // the use of formal verification methods.
philpem@26 22 //
philpem@26 23 // --------------------------------------------------------------------
philpem@26 24 //
philpem@26 25 // Lattice Semiconductor Corporation
philpem@26 26 // 5555 NE Moore Court
philpem@26 27 // Hillsboro, OR 97214
philpem@26 28 // U.S.A
philpem@26 29 //
philpem@26 30 // TEL: 1-800-Lattice (USA and Canada)
philpem@26 31 // 503-286-8001 (other locations)
philpem@26 32 //
philpem@26 33 // web: http://www.latticesemi.com/
philpem@26 34 // email: techsupport@latticesemi.com
philpem@26 35 //
philpem@26 36 // --------------------------------------------------------------------
philpem@0 37 // FILE DETAILS
philpem@0 38 // Project : LatticeMico32
philpem@0 39 // File : lm32_shifter.v
philpem@0 40 // Title : Barrel shifter
philpem@0 41 // Dependencies : lm32_include.v
philpem@0 42 // Version : 6.1.17
philpem@0 43 // : Initial Release
philpem@0 44 // Version : 7.0SP2, 3.0
philpem@0 45 // : No Change
philpem@0 46 // Version : 3.1
philpem@0 47 // : No Change
philpem@0 48 // =============================================================================
philpem@0 49
philpem@0 50 `include "lm32_include.v"
philpem@0 51
philpem@0 52 /////////////////////////////////////////////////////
philpem@0 53 // Module interface
philpem@0 54 /////////////////////////////////////////////////////
philpem@0 55
philpem@0 56 module lm32_shifter (
philpem@0 57 // ----- Inputs -------
philpem@0 58 clk_i,
philpem@0 59 rst_i,
philpem@0 60 stall_x,
philpem@0 61 direction_x,
philpem@0 62 sign_extend_x,
philpem@0 63 operand_0_x,
philpem@0 64 operand_1_x,
philpem@0 65 // ----- Outputs -------
philpem@0 66 shifter_result_m
philpem@0 67 );
philpem@0 68
philpem@0 69 /////////////////////////////////////////////////////
philpem@0 70 // Inputs
philpem@0 71 /////////////////////////////////////////////////////
philpem@0 72
philpem@0 73 input clk_i; // Clock
philpem@0 74 input rst_i; // Reset
philpem@0 75 input stall_x; // Stall instruction in X stage
philpem@0 76 input direction_x; // Direction to shift
philpem@0 77 input sign_extend_x; // Whether shift is arithmetic (1'b1) or logical (1'b0)
philpem@0 78 input [`LM32_WORD_RNG] operand_0_x; // Operand to shift
philpem@0 79 input [`LM32_WORD_RNG] operand_1_x; // Operand that specifies how many bits to shift by
philpem@0 80
philpem@0 81 /////////////////////////////////////////////////////
philpem@0 82 // Outputs
philpem@0 83 /////////////////////////////////////////////////////
philpem@0 84
philpem@0 85 output [`LM32_WORD_RNG] shifter_result_m; // Result of shift
philpem@0 86 wire [`LM32_WORD_RNG] shifter_result_m;
philpem@0 87
philpem@0 88 /////////////////////////////////////////////////////
philpem@0 89 // Internal nets and registers
philpem@0 90 /////////////////////////////////////////////////////
philpem@0 91
philpem@0 92 reg direction_m;
philpem@0 93 reg [`LM32_WORD_RNG] left_shift_result;
philpem@0 94 reg [`LM32_WORD_RNG] right_shift_result;
philpem@0 95 reg [`LM32_WORD_RNG] left_shift_operand;
philpem@0 96 wire [`LM32_WORD_RNG] right_shift_operand;
philpem@0 97 wire fill_value;
philpem@0 98 wire [`LM32_WORD_RNG] right_shift_in;
philpem@0 99
philpem@0 100 integer shift_idx_0;
philpem@0 101 integer shift_idx_1;
philpem@0 102
philpem@0 103 /////////////////////////////////////////////////////
philpem@0 104 // Combinational Logic
philpem@0 105 /////////////////////////////////////////////////////
philpem@0 106
philpem@0 107 // Select operands - To perform a left shift, we reverse the bits and perform a right shift
philpem@0 108 always @(*)
philpem@0 109 begin
philpem@0 110 for (shift_idx_0 = 0; shift_idx_0 < `LM32_WORD_WIDTH; shift_idx_0 = shift_idx_0 + 1)
philpem@0 111 left_shift_operand[`LM32_WORD_WIDTH-1-shift_idx_0] = operand_0_x[shift_idx_0];
philpem@0 112 end
philpem@0 113 assign right_shift_operand = direction_x == `LM32_SHIFT_OP_LEFT ? left_shift_operand : operand_0_x;
philpem@0 114
philpem@0 115 // Determine fill value for right shift - Sign bit for arithmetic shift, or zero for logical shift
philpem@0 116 assign fill_value = (sign_extend_x == `TRUE) && (direction_x == `LM32_SHIFT_OP_RIGHT)
philpem@0 117 ? operand_0_x[`LM32_WORD_WIDTH-1]
philpem@0 118 : 1'b0;
philpem@0 119
philpem@0 120 // Determine bits to shift in for right shift or rotate
philpem@0 121 assign right_shift_in = {`LM32_WORD_WIDTH{fill_value}};
philpem@0 122
philpem@0 123 // Reverse bits to get left shift result
philpem@0 124 always @(*)
philpem@0 125 begin
philpem@0 126 for (shift_idx_1 = 0; shift_idx_1 < `LM32_WORD_WIDTH; shift_idx_1 = shift_idx_1 + 1)
philpem@0 127 left_shift_result[`LM32_WORD_WIDTH-1-shift_idx_1] = right_shift_result[shift_idx_1];
philpem@0 128 end
philpem@0 129
philpem@0 130 // Select result
philpem@0 131 assign shifter_result_m = direction_m == `LM32_SHIFT_OP_LEFT ? left_shift_result : right_shift_result;
philpem@0 132
philpem@0 133 /////////////////////////////////////////////////////
philpem@0 134 // Sequential Logic
philpem@0 135 /////////////////////////////////////////////////////
philpem@0 136
philpem@0 137 // Perform right shift
philpem@0 138 always @(posedge clk_i `CFG_RESET_SENSITIVITY)
philpem@0 139 begin
philpem@0 140 if (rst_i == `TRUE)
philpem@0 141 begin
philpem@27 142 right_shift_result <= {`LM32_WORD_WIDTH{1'b0}};
philpem@27 143 direction_m <= `FALSE;
philpem@0 144 end
philpem@0 145 else
philpem@0 146 begin
philpem@0 147 if (stall_x == `FALSE)
philpem@0 148 begin
philpem@27 149 right_shift_result <= {right_shift_in, right_shift_operand} >> operand_1_x[`LM32_SHIFT_RNG];
philpem@27 150 direction_m <= direction_x;
philpem@0 151 end
philpem@0 152 end
philpem@0 153 end
philpem@0 154
philpem@0 155 endmodule