[文档].艾米电子 - 移位寄存器,Verilog
对读者的假设
已经掌握:
内容
free-running移位寄存器
自由运行移位寄存器,即在每一个时钟周期内,寄存器的内容会被左移或右移一位。该寄存器没有其他的控制信号。
代码1 free-running移位寄存器
module free_run_shift_reg #(parameter N=8) ( // global clock and asyn reset input clk, input rst_n, // serial I/O interface input s_in, output s_out ); // signal declaration reg [N-1:0] r_reg; wire [N-1:0] r_next; // body // register always@(posedge clk, negedge rst_n) if(!rst_n) r_reg <= 0; else r_reg <= r_next; // next-state logic assign r_next = {s_in, r_reg[N-1:1]}; // output logic assign s_out = r_reg[0]; endmodule
次态(next-state)逻辑是一位移位器,作用是将r_reg右移一个位置,然后在最高位(MSB)插入串型输入s_in。由于1位移位器仅需要重新连接输入和输出信号,因此不需要任何实际的逻辑电路。
Universa shift register
通用移位寄存器可以载入并行数据,然后左移或者右移,抑或保持原有状态。它可实现并串操作(先载入并行输入,然后移位输出),或者串并转换(先移位输入,然后一并输出)。
代码2 万用移位寄存器
module univ_shift_reg #(parameter N=8) ( // global clk and asyn reset input clk, input rst_n, // serial I/O interface input [1:0] ctrl, input [N-1:0] d, output [N-1:0] q ); // signal declaration reg [N-1:0] r_reg, r_next; // body // register always@(posedge clk, negedge rst_n) if(!rst_n) r_reg <= 0; else r_reg <= r_next; // next-state logic always@* case(ctrl) 2'b00: r_next = r_reg; // no operation 2'b01: r_next = {r_reg[N-2:0], d[0]}; // shift left 2'b10: r_next = {d[N-1], r_reg[N-1:1]};// shift right defaut: r_next = d; endcase // output logic assign q = r_reg; endmodule
次态逻辑使用了一个4选1的多路选择器来选择寄存器所需的次态值。注意:d的最低位和最高位(d[0]和d[N-1)被用作左移操作和右移操作的串型输入。
参考
1 Pong P. Chu.FPGA Prototyping By Verilog Examples: Xilinx Spartan-3 Version.Wiley