NV_NVDLA_HLS_shiftrightss.v 2.85 KB
Newer Older
sakundu committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
// ================================================================
// NVDLA Open Source Project
//
// Copyright(c) 2016 - 2017 NVIDIA Corporation. Licensed under the
// NVDLA Open Hardware License; Check "LICENSE" which comes with
// this distribution for more information.
// ================================================================
// File Name: NV_NVDLA_HLS_shiftrightss.v
module NV_NVDLA_HLS_shiftrightss (
   data_in
  ,shift_num
  ,data_out
  );
parameter IN_WIDTH = 49;
parameter OUT_WIDTH = 32;
parameter SHIFT_WIDTH = 6;
parameter SHIFT_MAX = 1<<(SHIFT_WIDTH-1);
parameter HIGH_WIDTH = SHIFT_MAX+IN_WIDTH-OUT_WIDTH;
input [IN_WIDTH-1:0] data_in; //signed 
input [SHIFT_WIDTH-1:0] shift_num; //signed
output [OUT_WIDTH-1:0] data_out;
wire [OUT_WIDTH-1:0] data_shift_l;
wire [HIGH_WIDTH-1:0] data_high;
wire [IN_WIDTH-1:0] data_highr;
wire [IN_WIDTH-1:0] data_shift_rt;
wire [IN_WIDTH-1:0] data_shift_r;
wire [IN_WIDTH-2:0] stick;
wire [OUT_WIDTH-1:0] data_max;
wire [OUT_WIDTH-1:0] data_round;
wire shift_sign;
wire data_sign;
wire guide;
wire point5;
wire mon_round_c;
wire left_shift_sat;
wire right_shift_sat;
wire [5:0] shift_num_abs;
// synoff nets
// monitor nets
// debug nets
// tie high nets
// tie low nets
// no connect nets
// not all bits used nets
// todo nets
assign data_sign = data_in[IN_WIDTH-1];
assign shift_sign = shift_num[SHIFT_WIDTH-1];
//shift left
assign shift_num_abs[SHIFT_WIDTH-1:0] = ~shift_num[SHIFT_WIDTH-1:0] + 1;
assign {data_high[((HIGH_WIDTH) - 1):0],data_shift_l[((OUT_WIDTH) - 1):0]} = {{SHIFT_MAX{data_sign}},data_in} << shift_num_abs[((SHIFT_WIDTH) - 1):0];
assign left_shift_sat = shift_sign & {data_high,data_shift_l[OUT_WIDTH-1]} != {(HIGH_WIDTH+1){data_sign}};
//shift right
assign {data_highr[((IN_WIDTH) - 1):0],data_shift_rt[((IN_WIDTH) - 1):0], guide, stick[((IN_WIDTH-1) - 1):0]} = {{IN_WIDTH{data_sign}},data_in,{IN_WIDTH{1'b0}}} >> shift_num[((SHIFT_WIDTH) - 1):0];
//assign {data_shift_rt[::range(IN_WIDTH)], guide, stick[::range(IN_WIDTH-1)]} = ($signed({data_in,{IN_WIDTH{1'b0}}}) >>> shift_num[::range(SHIFT_WIDTH)]);
assign data_shift_r[((IN_WIDTH) - 1):0] = shift_num >= IN_WIDTH ? {IN_WIDTH{1'b0}} : data_shift_rt[((IN_WIDTH) - 1):0];
assign point5 = shift_num >= IN_WIDTH ? 1'b0 : guide & (~data_sign | (|stick));
assign {mon_round_c,data_round[((OUT_WIDTH) - 1):0]} = data_shift_r[((OUT_WIDTH) - 1):0] + point5;
assign right_shift_sat = !shift_sign &
                        (( data_sign & ~(&data_shift_r[IN_WIDTH-2:OUT_WIDTH-1])) |
                         (~data_sign & (|data_shift_r[IN_WIDTH-2:OUT_WIDTH-1])) |
                         (~data_sign & (&{data_shift_r[((OUT_WIDTH-1) - 1):0], point5})));
assign data_max = data_sign ? {1'b1, {(OUT_WIDTH-1){1'b0}}} : ~{1'b1, {(OUT_WIDTH-1){1'b0}}};
assign data_out = (left_shift_sat | right_shift_sat) ? data_max : shift_sign ? data_shift_l : data_round;
endmodule // NV_NVDLA_HLS_shiftrightss