Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Pipelining 32 Bit Multiplier in Verilog

Status
Not open for further replies.

AlinParcalab

Newbie level 4
Joined
Mar 27, 2019
Messages
5
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
83
Here is my Verilog Code, I am tring to make a 32x32 sequential multiplier, 32 stages, here is one of the verision I have tried the other has the comblogic made out of always blocs and each odd stage is on negedge and the others are on posedge


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
module mul_piped
#(parameter word = 32, parameter double = 64)
(
input signed [31:0] Multiplicand, 
input signed [31:0] Multiplier,
input clk,
 
output signed [double-1:0] Pord 
); 
    reg [word-1:0] St1_Muld,St2_Muld,St3_Muld,St4_Muld;
    reg [word-1:0] St5_Muld,St6_Muld,St7_Muld,St8_Muld;
    
    reg [word-1:0] St1_Muli,St2_Muli,St3_Muli,St4_Muli;
    reg [word-1:0] St5_Muli,St6_Muli,St7_Muli,St8_Muli;
    
    reg [word-1:0] St9_Muld,St10_Muld,St11_Muld,St12_Muld;
    reg [word-1:0] St13_Muld,St14_Muld,St15_Muld,St16_Muld;
 
    reg [word-1:0] St9_Muli,St10_Muli,St11_Muli,St12_Muli;
    reg [word-1:0] St13_Muli,St14_Muli,St15_Muli,St16_Muli;  
      
    reg [word-1:0] St17_Muld,St18_Muld,St19_Muld,St20_Muld;
    reg [word-1:0] St21_Muld,St22_Muld,St23_Muld,St24_Muld;
    
    reg [word-1:0] St17_Muli,St18_Muli,St19_Muli,St20_Muli;
    reg [word-1:0] St21_Muli,St22_Muli,St23_Muli,St24_Muli;
    
    reg [word-1:0] St25_Muld,St26_Muld,St27_Muld,St28_Muld;
    reg [word-1:0] St29_Muld,St30_Muld,St31_Muld,St32_Muld;
    
    reg [word-1:0] St25_Muli,St26_Muli,St27_Muli,St28_Muli;
    reg [word-1:0] St29_Muli,St30_Muli,St31_Muli,St32_Muli; 
    
    reg [double-1:0] St1_Ac = 0;
    reg [double-1:0] St2_Ac,St3_Ac,St4_Ac,St5_Ac,St6_Ac,St7_Ac;
    
    reg [double-1:0] St8_Ac,St9_Ac,St10_Ac,St11_Ac,St12_Ac,St13_Ac;
    reg [double-1:0] St14_Ac,St15_Ac,St16_Ac,St17_Ac,St18_Ac,St19_Ac;
    
    reg [double-1:0] St20_Ac,St21_Ac,St22_Ac,St23_Ac,St24_Ac,St25_Ac;
    reg [double-1:0] St26_Ac,St27_Ac,St28_Ac,St29_Ac,St30_Ac,St31_Ac,St32_Ac;
 
    reg [double-1:0] St1_Ac_Bus,St2_Ac_Bus,St3_Ac_Bus;  
 
    wire [word-1:0] drive_multiplicand;
    wire [word-1:0] drive_multiplier;
    
    assign drive_multiplicand = Multiplicand;
    assign drive_multiplier   = Multiplier;
    
    
    always @ (posedge clk)
    begin
        St1_Muld <= drive_multiplicand;
        St1_Muli <= drive_multiplier;            
    
        if (St1_Muli[0] == 1) begin
            St1_Ac [double-1:32] =  St1_Ac [double-1:32] + St1_Muld;
        end else begin
            St1_Ac [double-1:32] = St1_Ac [double-1:32] + 0;
        end
        St1_Ac = St1_Ac >> 1;
 
        St2_Muld <= St1_Muld ;
        St2_Muli <= St1_Muli;
        St2_Ac    = St1_Ac;
  
        if (St2_Muli[1] == 1) begin
             St2_Ac [double-1:32] =  St2_Ac [double-1:32] + St2_Muld;
        end else begin
             St2_Ac [double-1:32] =  St2_Ac [double-1:32] + 0;
        end     
        St2_Ac  = St2_Ac >> 1;
        
        St3_Muld <= St2_Muld ;
        St3_Muli <= St2_Muli;
        St3_Ac    = St2_Ac;
        
       if (St3_Muli[2] == 1) begin
             St3_Ac [double-1:32] =  St3_Ac [double-1:32] + St3_Muld;
        end else begin
             St3_Ac [double-1:32] =  St3_Ac [double-1:32] + 0;
        end     
        St3_Ac  = St3_Ac >> 1;
        
        St4_Muld <= St3_Muld ;
        St4_Muli <= St3_Muli;
        St4_Ac    = St3_Ac;
        
       if (St4_Muli[3] == 1) begin
              St4_Ac [double-1:32] =  St4_Ac [double-1:32] + St4_Muld;
         end else begin
              St4_Ac [double-1:32] =  St4_Ac [double-1:32] + 0;
         end     
         St4_Ac  = St4_Ac >> 1;
         
         St5_Muld <= St4_Muld ;
         St5_Muli <= St4_Muli;
         St5_Ac    = St4_Ac;
         
         if (St5_Muli[4] == 1) begin
              St5_Ac [double-1:32] =  St5_Ac [double-1:32] + St5_Muld;
         end else begin
              St5_Ac [double-1:32] =  St5_Ac [double-1:32] + 0;
         end     
         St5_Ac  = St5_Ac >> 1;
           
         St6_Muld <= St5_Muld ;
         St6_Muli <= St5_Muli;
         St6_Ac    = St5_Ac;
         
         
         if (St6_Muli[5] == 1) begin
              St6_Ac [double-1:32] =  St6_Ac [double-1:32] + St6_Muld;
         end else begin
              St6_Ac [double-1:32] =  St6_Ac [double-1:32] + 0;
         end     
         St6_Ac  = St6_Ac >> 1;
           
         St7_Muld <= St6_Muld ;
         St7_Muli <= St6_Muli;
         St7_Ac    = St6_Ac; 
         
         if (St7_Muli[6] == 1) begin
              St7_Ac [double-1:32] =  St7_Ac [double-1:32] + St7_Muld;
         end else begin
              St7_Ac [double-1:32] =  St7_Ac [double-1:32] + 0;
         end     
         St7_Ac  = St7_Ac >> 1;
           
         St8_Muld <= St7_Muld ;
         St8_Muli <= St7_Muli;
         St8_Ac    = St7_Ac; 
    end
    
    // and so on, I dont understand why this way of pipelining is not working Ill post the errors below
 
endmodule



Code:
Errors: 

[Synth 8-6014] Unused sequential element St2_Ac_reg was removed. 
[Synth 8-3936] Found unconnected internal register 'St7_Muli_reg' and it is trimmed from '32' to '7' bits
[Synth 8-3331] design mul_piped has unconnected port Multiplier[31]
[Synth 8-3332] Sequential element (St1_Ac_reg[63]) is unused and will be removed from module mul_piped.
Help please
 
Last edited by a moderator:

Your report is incorrect, none of the messages is an error, all are only warnings.
 

Your report is incorrect, none of the messages is an error, all are only warnings.

My bad, my point was, how can I fix these warrning, why are they there?

- - - Updated - - -

My bad, my point was, how can I fix these warnings, why are they there? Is is because synthesis too is an FPGA tool, will it compile and work just fine with Cadence synthesis tool for Asics? I am working on a Microcontroller 32 bit Rsic-V which will have to be connected with a TDC whitin same chip and I want to make sure everything is working fine no warnings no errors, Help please
 

Part of the warnings may be generated by design, I didn't look into the details.

I suggest to check the correct operation of your design in a simulator. There you also trace the individual signals and see why some are removed in synthesis.
 
As suggested above, you must take each Warning and look into the corresponding RTL. If it makes sense and does not affect your design, the Warning can stay. Else you have to change your RTL accordingly.

Is is because synthesis too is an FPGA tool, will it compile and work just fine with Cadence synthesis tool for Asics?
The synth engine for Xilinx and ASIC(Cadence) is different. The libraries there would be different and you might get different warnings too. If your target design is for ASIC implementation you should start with Cadence tools (unless you are doing ASIC prototyping work).
 
I understand, at the moment I do not have acces to Cadence tool, the target was to buy them afther I have design which works and have a working RTL.

But let's say and warning like this "Unused sequential element St2_Ac_reg was removed." from my point of view is clearly not good since if I look at the code the reg is used, my question is Why is this worning present, am I missing something?
 

But let's say and warning like this "Unused sequential element St2_Ac_reg was removed." from my point of view is clearly not good since if I look at the code the reg is used, my question is Why is this worning present, am I missing something?

I can only give you hints, this work requires in depth analysis of the multiplier code. It was in 2015 I had last worked with Verilog. But having taken a quick look, searching for the St2_Ac, I see that you have mixed blocking and non-blocking assignments in the same process block. I guess that is not a recommended procedure. Please verify this.

Also the most common reason for logic/reg removal by synth tools is because they are non-toggling/unconnected.

Did you try to simulate your multiplier? If not first do that to be on the safe side. Write a good test bench and see what is happening to the St2_Ac for various inputs.
 
But having taken a quick look, searching for the St2_Ac, I see that you have mixed blocking and non-blocking assignments in the same process block. I guess that is not a recommended procedure. Please verify this.
Yes, the unconditional blocking assignment St3_Ac = St2_Ac; turns St2_ac into a St3_ac alias register. Recommended procedure or not, you need to be aware of the effects for the synthesis of your design. Obviously you aren't yet.
 

I understand, at the moment I do not have acces to Cadence tool, the target was to buy them afther I have design which works and have a working RTL.

But let's say and warning like this "Unused sequential element St2_Ac_reg was removed." from my point of view is clearly not good since if I look at the code the reg is used, my question is Why is this worning present, am I missing something?

do not focus on the ASIC x FPGA dilemma. As of now, your code is logically flawed and does not adhere to good coding principles. You need to understand verilog a little bit better at this point, perhaps spend some time learning about FSM templates. That would surely help you.
 
I have rewritten everything, but the total delay on 32 B I think will really big.
About the coding style, if could you give me some hints, and about that FSM since you have spoken about it I have a question, how could I pipeline the FSM I am thinking about it since a while already because a single cycle core is not what I am really looking for, if you could give me I hint?


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
module mul_piped
#(
parameter word = 4, 
parameter double = 8, 
parameter depth = 8
)(
input signed [3:0] Multiplicand, 
input signed [3:0] Multiplier,
input clk,
 
output [double-1:0] Prod 
);
 
    reg  [word-1:0] St_Muld[3:0];
    reg  [double:0] St_Ac  [4:0];
 
    wire [double:0] St0_Ac_Bus;
    wire [double:0] St1_Ac_Bus;
    wire [double:0] St2_Ac_Bus;
    wire [double:0] St3_Ac_Bus;
 
    wire [double:0] St0_Ac_Busx;
    wire [double:0] St1_Ac_Busx;
    wire [double:0] St2_Ac_Busx;
    wire [double:0] St3_Ac_Busx;
 
    wire [word:0] add0;    
    wire [word:0] add1;
    wire [word:0] add2;
    wire [word:0] add3;
 
    wire [double:0]movemulti;
    wire [word-1:0]movemultd;
 
    assign movemulti[double:0] = {5'b00000,Multiplier[word-1:0]};
    assign movemultd[word-1:0] = Multiplicand[word-1:0];
 
    always @ (posedge clk) begin
     
          St_Muld[0]  <=  movemultd;
          St_Muld[1]  <=  St_Muld[0];
          St_Muld[2]  <=  St_Muld[1];
          St_Muld[3]  <=  St_Muld[2];
 
          St_Ac[0]  <=  movemulti;  
          St_Ac[1]  <=  St0_Ac_Busx[double:0];  
          St_Ac[2]  <=  St1_Ac_Busx[double:0];  
          St_Ac[3]  <=  St2_Ac_Busx[double:0];
          St_Ac[4]  <=  St3_Ac_Busx[double:0];
    end  
    
    assign  add0 =  St_Ac [0][double:4] + St_Muld[0] [word-1:0]; 
    assign  St0_Ac_Bus  [double:0] = (St_Ac[0][0] == 1) ? {add0,St_Ac[0][3:0]} : St_Ac[0][double:0];
    assign  St0_Ac_Busx [double:0] =  St0_Ac_Bus[double:0] >> 1;
    
    assign  add1 =  St_Ac[1][double:4] + St_Muld[1][word-1:0];
    assign  St1_Ac_Bus  [double:0] = (St_Ac[1][0] == 1) ? {add1,St_Ac[1][3:0]} : St_Ac[1][double:0];
    assign  St1_Ac_Busx [double:0] =  St1_Ac_Bus [double:0] >> 1;
    
    assign  add2 =  St_Ac[2][double:4] + St_Muld[2][word-1:0];
    assign  St2_Ac_Bus  [double:0] = (St_Ac[2][0] == 1) ? {add2,St_Ac[2][3:0]} : St_Ac[2][double:0];
    assign  St2_Ac_Busx [double:0] =  St2_Ac_Bus [double:0] >> 1;
    
    assign  add3 =  St_Ac[3][double:4] + St_Muld[3][word-1:0];
    assign  St3_Ac_Bus  [double:0] = (St_Ac[3][0] == 1) ? {add3,St_Ac[3][3:0]} : St_Ac[3][double:0];
    assign  St3_Ac_Busx [double:0] =  St3_Ac_Bus [double:0] >> 1;
        
    assign Prod = St_Ac[4][double-1:0];    
    
endmodule

 
Last edited by a moderator:

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top