本篇内容来源于中国大学mooc《计算机组成与CPU设计实验》 (江苏大学)中的课程视频、PPT等相关资料。
本篇内容为《计算机组成与CPU设计实验》——移位寄存器
参考视频:
移位寄存器
移位寄存器是什么?
将若干个D触发器串接级联在一起构成的具有移位功能的寄存器。
4位右移移位寄存器
原来输出 Q0 Q1 Q2 Q3
CLK上升沿到来
输出 Q0=DSI Q1=Q0 Q2=Q1 Q3=Q2
输出右移一位
注意: 为了和图一致,把输出写成 Q[0:3]
在逻辑电路中,习惯从左到右这种表达方法,在计算机中是低位0,高位3
高位——>低位 (Q0 Q3 )
Verilog描述
module RightShifter(
input DSI,
input CLK,Reset,
output reg [0:3] Q //高位Q0,低位Q3
);
always@(posedge CLK)
begin
Q[0] <= DSI;
Q[1] <= Q[0];
Q[2] <= Q[1];
Q[3] <= Q[2];
//Q[3:0]={DSI,Q[0:2]};
end
endmodule
4位左移移位寄存器
原来输出 Q3 Q2 Q1 Q30
CLK上升沿到来
输出 Q3=Q2 Q2=Q1 Q1=Q0 Q0=DSI
输出左移一位
module LeftShifter(
input DSI,
input CLK,Reset,
output reg [3:0] Q
);
always@(posedge CLk or posedge Reset)
if(Reset)
Q<=0;
else
Q[3:0]<={Q[2:0],DSI};
endmodule
循环移位寄存器(环形计数器)
DSO(Q3)与Dn相连
先通过RESET置初始数据Q0 Q1 Q2 Q3=1000
在CLK脉冲用下,Q0 Q1 Q2 Q3将依次为1000→0100→0010>0001→1000一→>......
高电平“1"沿环形路径在触发器中传递,每个触发器经过4个时钟周期输出一个高电平脉冲。
module LoopShifter(
input CLK,Reset,
output reg [0:3] Q
);
always@(posedge CLk or posedge Reset)
if(Reset)
Q<=1000;
else
begin
Q[0] <= Q[3];
Q[1] <= Q[0];
Q[2] <= Q[1];
Q[3] <= Q[2];
end
endmodule
可预置数的右移移位寄存器
输入端 D连接两个不同的数据源
- 当Load = 0 时,实现右移移位操作
- 当Load = 1 时,In3~In0并行装入移位寄存器
寄存器的使能控制习惯上称为装入 (Load )
Verilog描述
module Shifter(
input DSI,
input [0:3] In
input CLK,load,
output reg [0:3] Q //高位Q0,低位Q3
);
always@(posedge CLK)
if(load == 0)
Q[0:3]<={DSI,Q[0:2]};
else
Q<=In;
endmodule
移位运算符
逻辑移位
- << 逻辑左移 (低位补0)
- >> 逻辑右移 (高位补0)
例子:
logic [3:0] m,n;
assign m = 4'b1011;
assign n = m>>2;
//则n=0010
- <<< (算术左移)(低位补0)
- >>>(算术右移)符号位复制
例子:
logic signed[3:0] m,n;
assign m = 4'b1011;
assign n = m>>>2;
//则n=1110
//前面两个1是符号位复制
算术移位
算术移位仅对带符号数有效
logic [3:0] m,n;m,n都是无符号变量
assign m = 4'b1011;
assign n = m>>>2;
//则n=0010
可用$signed()将无符号数强制转换为带符号数
logic [3:0] m,n;m,n都是无符号变量
assign m = 4'b1011;
assign n = $signed(m)>>>2;
//则n=1110