/// EE 4755 - Digital Design Using HDLs // /// Classroom Code Examples // // Sequential Shifter // Order-d Sequential Shifter // // For lecture slides, including diagrams: // https://www.ece.lsu.edu/v/2019/lsli-syn-seq.pdf /// Left Shift Using Operator // module shift_lt_behav_1 #( int wid_lg = 4, int wid = 1 << wid_lg ) ( output [wid-1:0] shifted, input [wid-1:0] unshifted, input [wid_lg-1:0] amt ); assign shifted = unshifted << amt; endmodule /// Left Shift Moving Bits // // Disadvantage is large number of multiplexors. // module shift_lt_behav #( int wid_lg = 4, int wid = 1 << wid_lg ) ( output logic [wid-1:0] shifted, input uwire [wid-1:0] unshifted, input uwire [wid_lg-1:0] amt ); always_comb for ( int i=0; i= amt ? unshifted[i-amt] : 0; endmodule /// w-bit Left Shift Using lg w Stages // module shift_fixed #( int wid_lg = 4, int amt = 1, int wid = 1 << wid_lg ) ( output uwire [wid-1:0] shifted, input uwire [wid-1:0] unshifted, input uwire shift ); assign shifted = shift ? unshifted << amt : unshifted; endmodule module shift_lt_comb #( int wid_lg = 4, int wid = 1 << wid_lg ) ( output [wid-1:0] shifted, input [wid-1:0] unshifted, input [wid_lg-1:0] amt ); uwire [wid-1:0] step[wid_lg-1:-1]; assign step[-1] = unshifted; assign shifted = step[wid_lg-1]; for ( genvar i=0; i 0 ) begin shifted = shifted << 1; cnt--; end else begin shifted = shifted; cnt = cnt; end end assign ready = cnt == 0; endmodule /// Unoptimized: // :Image:40em: syn-seq-sh.plain.svg /// Optimized: // :Image:40em: syn-seq-sh-opt.plain.svg module shift_lt_seq_alt #( int wid_lg = 4, int wid = 1 << wid_lg ) ( output logic [wid-1:0] shifted, output uwire ready, input uwire [wid-1:0] unshifted, input uwire [wid_lg-1:0] amt, input uwire start, input uwire clk ); logic [wid_lg-1:0] cnt; uwire [wid-1:0] sf_out; shift_fixed #(wid_lg,1) sf( sf_out, shifted, 1'b1 ); always_ff @( posedge clk ) if ( start == 1 ) begin shifted = unshifted; end else if ( cnt > 0 ) begin shifted = sf_out; end always_ff @( posedge clk ) if ( start == 1 ) begin cnt <= amt; end else if ( cnt > 0 ) begin cnt <= cnt-1; end assign ready = cnt == 0; endmodule module shift_lt_seq_d #( int wid_lg = 4, int num_shifters = 2, int wid = 1 << wid_lg ) ( output logic [wid-1:0] shifted, output uwire ready, input uwire [wid-1:0] unshifted, input uwire [wid_lg-1:0] amt, input uwire start, input uwire clk ); localparam int cnt_bits = ( wid_lg + num_shifters - 1 ) / num_shifters; logic [num_shifters-1:0][cnt_bits-1:0] cnt; uwire [wid-1:0] inter_sh[num_shifters-1:-1]; assign inter_sh[-1] = shifted; for ( genvar i = 0; i < num_shifters; i++ ) begin localparam int shift_amt = 1 << i * cnt_bits; uwire shift = cnt[i] != 0; shift_fixed #(wid_lg,shift_amt) sf( inter_sh[i], inter_sh[i-1], shift ); end always_ff @( posedge clk ) if ( start == 1 ) begin shifted = unshifted; cnt = amt; end else if ( cnt > 0 ) begin shifted = inter_sh[num_shifters-1]; for ( int i=0; i