1- // shift_reg.v - bidirectional shift register with optional parallel load
1+ // shift_reg.v - shift register with optional parallel load
22
33`default_nettype none
44
@@ -9,27 +9,30 @@ module shift_reg
99 input wire rstn, // active-low synchronous reset
1010 input wire en, // 1 -> perform load/shift
1111 input wire load, // 1 -> parallel load, 0 -> shift
12- input wire dir, // 0 -> shift left, 1 -> shift right
1312 input wire serial_in, // bit entering during a shift
1413 input wire [WIDTH- 1 :0 ] parallel_in, // data for parallel load
15- output reg [WIDTH- 1 :0 ] q, // register contents
16- output wire serial_out // bit exiting during a shift
14+ output reg [WIDTH- 1 :0 ] q // register contents
1715);
1816
17+ reg [$clog2(WIDTH)- 1 :0 ] bit_index;
18+
1919 // next-state datapath
2020 wire [WIDTH- 1 :0 ] next_q =
21- load ? parallel_in : // parallel load
22- (dir == 1'b0 ) ? {q[WIDTH- 2 :0 ], serial_in} : // shift left
23- {serial_in, q[WIDTH- 1 :1 ]}; // shift right
21+ load ? parallel_in : {serial_in, q[WIDTH- 1 :1 ]};
2422
25- // sequential part
26- always @(posedge clk)
27- if (! rstn)
23+ always @(posedge clk or negedge rstn) begin
24+ if (! rstn) begin
2825 q <= {WIDTH{1'b0 }}; // synchronous clear
29- else if (en)
30- q <= next_q; // load or shift
31-
32- // bit shifted out on this cycle
33- assign serial_out = dir ? q[0 ] : q[WIDTH- 1 ];
26+ bit_index <= 0 ;
27+ end else if (en) begin
28+ if (load) begin
29+ q[WIDTH- 1 :0 ] <= parallel_in;
30+ bit_index <= 0 ;
31+ end else begin
32+ q[bit_index] <= serial_in;
33+ bit_index <= bit_index + 1 ; // increment bit index each cycle
34+ end
35+ end
36+ end
3437
3538endmodule
0 commit comments