Skip to content

Instantly share code, notes, and snippets.

@neilzheng
Created August 22, 2025 12:31
Show Gist options
  • Select an option

  • Save neilzheng/b717eebab8607460700e2e2366877f26 to your computer and use it in GitHub Desktop.

Select an option

Save neilzheng/b717eebab8607460700e2e2366877f26 to your computer and use it in GitHub Desktop.
dshift.sv
// shift use dsp multiply
module dshift
import cpu_defines::*;
(
input logic [15:0] i_in, // 16-bit input data
input logic [3:0] i_shift_amount, // 4-bit shift amount
input shift_ops_t i_function, // Shift function (SLL_OP, SRL_OP, SRA_OP, ROR_OP)
input logic i_direction, // early decoded direction
output logic [15:0] o_out, // 16-bit output data
output logic o_carry_out, // Carry output
output logic o_overflow_out
);
// Internal signals
logic [3:0] shift_amount; // Shift amount
logic [16:0] mul_amount;
logic direction; // Shift direction
logic shift_rotate; // ror
logic shift_signed; // sra
logic [15:0] sra_mask; // sign mask for sra
logic [15:0] result;
logic [15:0] sresult;
logic [16:0] mul_amount_l;
logic [16:0] mul_amount_r;
logic [15:0] mul_lo;
logic [15:0] mul_hi;
assign direction = i_direction;
assign shift_amount = i_shift_amount;
// ror sra decoding
always_comb begin
shift_signed = 1'b0;
shift_rotate = 1'b0;
case (i_function)
SRA_OP: begin
shift_signed = 1'b1;
end
ROR_OP: begin
shift_rotate = 1'b1;
end
default:;
endcase
end
// left shift
always_comb begin
case (shift_amount)
4'h0: mul_amount_l = 17'h0001;
4'h1: mul_amount_l = 17'h0002;
4'h2: mul_amount_l = 17'h0004;
4'h3: mul_amount_l = 17'h0008;
4'h4: mul_amount_l = 17'h0010;
4'h5: mul_amount_l = 17'h0020;
4'h6: mul_amount_l = 17'h0040;
4'h7: mul_amount_l = 17'h0080;
4'h8: mul_amount_l = 17'h0100;
4'h9: mul_amount_l = 17'h0200;
4'ha: mul_amount_l = 17'h0400;
4'hb: mul_amount_l = 17'h0800;
4'hc: mul_amount_l = 17'h1000;
4'hd: mul_amount_l = 17'h2000;
4'he: mul_amount_l = 17'h4000;
4'hf: mul_amount_l = 17'h8000;
default: mul_amount_l = '0;
endcase
end
// right shift
always_comb begin
case (shift_amount)
4'h0: mul_amount_r = 17'h10000;
4'h1: mul_amount_r = 17'h8000;
4'h2: mul_amount_r = 17'h4000;
4'h3: mul_amount_r = 17'h2000;
4'h4: mul_amount_r = 17'h1000;
4'h5: mul_amount_r = 17'h0800;
4'h6: mul_amount_r = 17'h0400;
4'h7: mul_amount_r = 17'h0200;
4'h8: mul_amount_r = 17'h0100;
4'h9: mul_amount_r = 17'h0080;
4'ha: mul_amount_r = 17'h0040;
4'hb: mul_amount_r = 17'h0020;
4'hc: mul_amount_r = 17'h0010;
4'hd: mul_amount_r = 17'h0008;
4'he: mul_amount_r = 17'h0004;
4'hf: mul_amount_r = 17'h0002;
default: mul_amount_r = '0;
endcase
end
assign mul_amount = direction ? mul_amount_r : mul_amount_l;
// use multiply to get shift result
assign {mul_hi, mul_lo} = i_in * mul_amount;
// 16 lut4
always_comb begin
case (shift_amount)
4'b0000: sra_mask = 16'h0000;
4'b0001: sra_mask = {{1{i_in[15]}}, {15'b0}};
4'b0010: sra_mask = {{2{i_in[15]}}, {14'b0}};
4'b0011: sra_mask = {{3{i_in[15]}}, {13'b0}};
4'b0100: sra_mask = {{4{i_in[15]}}, {12'b0}};
4'b0101: sra_mask = {{5{i_in[15]}}, {11'b0}};
4'b0110: sra_mask = {{6{i_in[15]}}, {10'b0}};
4'b0111: sra_mask = {{7{i_in[15]}}, {9'b0}};
4'b1000: sra_mask = {{8{i_in[15]}}, {8'b0}};
4'b1001: sra_mask = {{9{i_in[15]}}, {7'b0}};
4'b1010: sra_mask = {{10{i_in[15]}}, {6'b0}};
4'b1011: sra_mask = {{11{i_in[15]}}, {5'b0}};
4'b1100: sra_mask = {{12{i_in[15]}}, {4'b0}};
4'b1101: sra_mask = {{13{i_in[15]}}, {3'b0}};
4'b1110: sra_mask = {{14{i_in[15]}}, {2'b0}};
4'b1111: sra_mask = {{15{i_in[15]}}, {1'b0}};
default: sra_mask = 16'h0000;
endcase
end
generate
for (genvar i=0; i<16; i++) begin
always_comb begin
result[i] =
// left
(mul_lo[i] & (~direction | shift_rotate)) |
// right
(mul_hi[i] & (direction | shift_rotate));
end
end
endgenerate
generate
for (genvar i = 0; i<16; i++) begin
always_comb begin
sresult[i] = result[i] | (sra_mask[i] & shift_signed);
end
end
endgenerate
assign o_out = sresult;
// early test, carry/overflow can be computed parallel
assign o_carry_out = 0;
assign o_overflow_out = 0;
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment