Created
August 22, 2025 12:31
-
-
Save neilzheng/b717eebab8607460700e2e2366877f26 to your computer and use it in GitHub Desktop.
dshift.sv
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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