mul16

 

设计思想:乘法运算本身就可以看做是一个移位相加的过程
               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_mul16
11                   );
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 unenable
10                   status_mul16,  //1 :finish.   0:calculating
11                   result_mul16
12                   );
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     begin
34          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 ] 就可以了。

 

 

posted on 2013-06-17 22:23  清霜一梦  阅读(308)  评论(0编辑  收藏  举报