概述
之前写过一个算数右移的实现,今天又发现了两种:
版本一:
module shift_2(d,sa,right,arith,sh);
input [31:0] d;
input [4:0] sa;
input right,arith;
output [31:0] sh;
wire [31:0] t0,t1,t2,t3,t4,s1,s2,s3,s4;
wire a = d[31] & arith; //judge whether need arithmetic shift
wire [15:0] e = {16{a}};
wire [15:0] z = {16{1'b0}};
wire [31:0] sld4,sdr4,sld3,sdr3,sld2,sdr2,sld1,sdr1,sld0,sdr0;
assign sld4 = {d[15:0],z};
assign sdr4 = {e,d[31:16]};
mux32 m4_right(sld4,sdr4,right,t4); //mux32(a0,a1,s,y);y = s?a1:a0;
mux32 m4_shift(d,t4,sa[4],s4);
assign sld3 = {s4[23:0],z[7:0]};
assign sdr3 = {e[7:0],s4[31:8]};
mux32 m3_right(sld3,sdr3,right,t3);
mux32 m3_shift(s4,t3,sa[3],s3);
assign sld2 = {s3[27:0],z[3:0]};
assign sdr2 = {e[3:0],d[31:4]};
mux32 m2_right(sld2,sdr2,right,t2);
mux32 m2_shift(s3,t2,sa[2],s2);
assign sld1 = {s2[29:0],z[1:0]};
assign sdr1 = {e[1:0],d[31:2]};
mux32 m1_right(sld1,sdr1,right,t1);
mux32 m1_shift(s2,t1,sa[1],s1);
assign sld0 = {s1[30:0],z[0]};
assign sdr0 = {e[0],d[31:1]};
mux32 m0_right(sld0,sdr0,right,t0);
mux32 m0_shift(s1,t0,sa[0],sh);
endmodule
module mux32(a0,a1,s,y);
input [31:0] a0,a1;
input s;
output [31:0] y;
assign y = s?a1:a0;
endmodule
版本二:
module shift(d,sa,right,arith,sh);
input [31:0] d;
input [4:0] sa;
input right,arith;
output [31:0] sh;
reg [31:0] sh;
always@(*) begin
if(!right)
sh = d << sa;
else
if(!arith)
sh = d >> sa;
else
sh = $signed(d) >>> sa;
end
endmodule
这两种方法下面的更简单,上面那个用来增强对组合电路的理解。第一种方法的延时还是比我之前写的那个更大,不过用到的硬件资源更多。
some tips:
1、一个数比如是32'bf000,那么不够的0会补充在高位。等于32'b0000f000。
2、使用$signed(d)可以得到一个number的sign。$signed(d) >>> sa;可以实现算数右移。
3、模块调用:
shift uut (
.d(dd),
.sa(sa),
.right(right),
.arith(arith),
.sh(sh)
);
这次一定要记住,括号里面的是当前模块的,外面加点的就是被调用模块的。
4、在仿真的时候,可以同时写多个initial。
最后
以上就是虚拟飞鸟为你收集整理的数字电路设计之移位器设计2的全部内容,希望文章能够帮你解决数字电路设计之移位器设计2所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复