清霜一梦

mul16

0
阅读(1608)

设计思想:乘法运算本身就可以看做是一个移位相加的过程
               1 1 0 1 0     = 26
*              1 0 1 1 1    = 23                   
   -----------------------------       23*26 = 598
               1 1 0 1 0
            1 1 0 1 0
         1 1 0 1 0
      0 0 0 0 0
  1 1  0 1 0
----------------------------
10 0 1  0 1 0 1 1 0        = 598

核心是这个操作
                   result_reg <= {  {   ( 16 - clock_counter ){1'd0}},                         // 31 - (clock_counter+14) -1 
                                             {   result_reg[clock_counter+14 : clock_counter-1]  +  a_reg   },  
                                            {    result_reg[clock_counter-2 : 0]}
                                         };
因为clock_counter <2 的时候,拼接操作 result_reg [clock_counter-2 : 0] 要成立
       clock_counter>16 的时候,拼接操作{   ( 16 - clock_counter ){1'd0}} 要成立,(中间的那一部分相加是17bit,第31bit不应该补零)
所以要将他们单独拿出来讨论。

就以上思想进行设计,悲剧发生了

复制代码

 1 //date :2013/6/16 2 //designer :pengxiaoen 3 //function : unsigned 16 bit multiplication 4  5  6 module mul16 ( 7               clock,reset, 8                   a_in,b_in, 9                   status_mul16,10                    result_mul1611                   );12                   13 input clock,reset;14 input [15:0] a_in ,b_in;15 output reg status_mul16;16 output [31:0]result_mul16;17 18 reg [4:0] clock_counter;19 //--------------------------------------------20 always @ (posedge clock or negedge reset)21 if (!reset)22   clock_counter <= 5'd0;23 else if(clock_counter == 5'd17)24        clock_counter <= 5'd0;25       else 26         clock_counter <= clock_counter + 1;27          28          29 //-----------------------------------------------                  30 always @ (posedge clock or negedge reset)31 if(!reset) 
32   status_mul16 <= 1'd0;33 else if (clock_counter == 5'd17)34   status_mul16 <= 1'd1;35        else status_mul16 <= 1'd0;  36 37 38 reg [31:0] result_reg;39 reg [15:0] a_reg,b_reg;                  
40 //------------------------------------------------41 always @ (posedge clock or negedge reset)42 if (!reset)43    begin 44         a_reg <= 16'd0;45          b_reg <= 16'd0;46          result_reg <= 32'd0;47     end 48 else if (clock_counter == 5'd0)49          begin 50                 a_reg <= a_in;51                  b_reg <= b_in;52           end     53         else  if ((clock_counter >= 5'd1) && (clock_counter <= 5'd16))54                  begin 55                           if(b_reg [clock_counter -1])56                                if(clock_counter == 5'd1) 57                                     result_reg <= result_reg + a_reg;58                                  else if ((clock_counter >= 5'd2)  &  (clock_counter <= 5'd15))59                                      result_reg <= {{(16 - clock_counter ){1'd0}},       // 31 - (clock_counter+14) -1 60                                                     {result_reg[clock_counter+14 : clock_counter-1]  +  a_reg},  
61                                                           {result_reg[clock_counter-2 : 0]}62                                                          };63                                        else if(clock_counter == 5'd16) 64                                                 result_reg <= {result_reg[30:15] + a_reg,  result_reg[14:0]};65                             else result_reg <= result_reg << 1;66                    end  67                      68 assign result_mul16 = result_reg;69          70 endmodule

复制代码



编译产生的结果是:
图片
因为错误提示是因为这个{ } 内部只能是常数,这个是因为语法约束导致的设计失败,那么我很想知道如果我采用门级建模是不是就避开了这个语法约束而实现呢?,但是门级建模,哎,头痛并且浩大的工作量啊。现在懒,不想搞门级建模
修正中..................

 

复制代码

 1 //date :2013/6/17 2 //designer :pengxiaoen 3 //function : unsigned 16 bit multiplication  4  5  6 module mul16 ( 7               clock,reset, 8                   a_in,b_in, 9                   data_in_en,        //1 :data input enable   0:data input unenable10                   status_mul16,  //1 :finish.   0:calculating11                   result_mul1612                   );13                   14 input clock,reset;15 input [15:0] a_in ,b_in;16 output reg data_in_en;17 output reg status_mul16;18 output [31:0]result_mul16;19 20 reg [4:0] clock_counter;21 //--------------------------------------------22 always @ (posedge clock or negedge reset)23 if (!reset)24   clock_counter <= 5'd0;25 else if(clock_counter >= 5'd17)26        clock_counter <= 5'd0;27       else 28         clock_counter <= clock_counter + 1;29                   30 //-----------------------------------------------                  31 always @ (posedge clock or negedge reset)32 if(!reset) 
33     begin34          status_mul16 <= 1'd0;35           data_in_en   <= 1'd0;36      end 37   38 else case (clock_counter)39          0        : data_in_en <= 1'd1;40             17       : status_mul16 <= 1'd1;41             default  : begin 42                            data_in_en<= 1'd0;43                                 status_mul16 <= 1'd0;44                        end 45       endcase 46     47 48 49 reg [31:0] result_reg;50 reg [15:0] a_reg,b_reg;                  
51 //------------------------------------------------52 always @ (posedge clock or negedge reset)53 if (!reset)54    begin 55         a_reg <= 16'd0;56          b_reg <= 16'd0;57          result_reg <= 32'd0;58     end 59 else if (clock_counter == 5'd0)60          begin 61                 a_reg <= a_in;62                  b_reg <= b_in;63           end     64         else  if ((clock_counter >= 5'd1) && (clock_counter <= 5'd15))65                  begin 66                          if(b_reg[clock_counter -1])67                               result_reg <= {1'b0,68                                                result_reg [30:15] + a_reg,69                                                     result_reg [14:1]70                                                     };71                           else result_reg <= result_reg >> 1;72                    end  73                 else if ((b_reg[15])  &&  (clock_counter == 5'd16))74                          result_reg [31: 16]  <= {result_reg [31: 16]  +  a_reg};75                      76 assign result_mul16 = result_reg;77          78 endmodule

复制代码


计算精华部分

复制代码

64         else  if ((clock_counter >= 5'd1) && (clock_counter <= 5'd15))65                  begin 66                          if(b_reg[clock_counter -1])67                               result_reg <= {1'b0,68                                                result_reg [30:15] + a_reg,69                                                     result_reg [14:1]70                                                     };71                           else result_reg <= result_reg >> 1;72                    end  73                 else if ((b_reg[15])  &&  (clock_counter == 5'd16))74                          result_reg [31: 16]  <= {result_reg [31: 16]  +  a_reg};

复制代码

 

先运算reg中的[30:15] 部分,相加运算之后右移。最后第一个bit不就右移到最后去了嘛,为什么我当时就一定要在低位相加呢,不能倒过来呢,嘿嘿。自己愚钝了。

如果b_reg的当前bit是0 只需要右移
最后一个bit不需要移动,直接加到最高的 [31 :16 ] 就可以了。