|  | // adapts single bit memory to parallel inputs and outputs | 
|  | module RAM_SHIFTER #( | 
|  | parameter IO_WIDTH = 16, | 
|  | parameter ADDR_WIDTH = 4, | 
|  | parameter PHASE_SHIFT = 2 | 
|  | ) ( | 
|  | input                       clk, | 
|  |  | 
|  | // parallel I/O | 
|  | input [IO_WIDTH-1:0]        in, | 
|  | output reg [IO_WIDTH-1:0]   out, | 
|  |  | 
|  | // memory interface | 
|  | output reg [ADDR_WIDTH-1:0] addr, | 
|  | input                       ram_out, | 
|  | output                      ram_in | 
|  | ); | 
|  |  | 
|  | // shift registers | 
|  | reg [IO_WIDTH-1:0]          shift_in; | 
|  | reg [IO_WIDTH-1:0]          shift_out; | 
|  |  | 
|  | assign ram_in = shift_in[0]; | 
|  |  | 
|  | initial begin | 
|  | out       <= 0; | 
|  | addr      <= 0; | 
|  | shift_in  <= 0; | 
|  | shift_out <= 0; | 
|  | end | 
|  |  | 
|  | always @(posedge clk) begin | 
|  | if(addr == 0) | 
|  | begin // shift registers are aligned with I/O | 
|  | // write output shift register, which is a little out of phase | 
|  | out <= {shift_out[IO_WIDTH-PHASE_SHIFT-1:0], shift_out[IO_WIDTH-1:IO_WIDTH-PHASE_SHIFT]}; | 
|  |  | 
|  | // input shift register is aligned with input, so sample it | 
|  | shift_in <= in; | 
|  | end | 
|  | else | 
|  | begin | 
|  | // rotate the input | 
|  | shift_in <= {shift_in[IO_WIDTH-2:0], shift_in[IO_WIDTH-1]}; | 
|  | end | 
|  |  | 
|  | // insert a new bit on the right and push everything to the left | 
|  | shift_out <= {shift_out[IO_WIDTH-2:0], ram_out}; | 
|  |  | 
|  | addr <= addr + 1; | 
|  | end | 
|  | endmodule |