数字电路设计之移位器设计2

来源:互联网 发布:同呼软件下载 编辑:程序博客网 时间:2024/05/03 17:59

           之前写过一个算数右移的实现,今天又发现了两种:

           版本一:

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@(*) beginif(!right) sh = d << sa;else if(!arith)sh = d >> sa;elsesh = $signed(d) >>> sa;endendmodule

         这两种方法下面的更简单,上面那个用来增强对组合电路的理解。第一种方法的延时还是比我之前写的那个更大,不过用到的硬件资源更多。


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。

0 0
原创粉丝点击