Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

- Community Forums
- :
- Forums
- :
- Hardware Development
- :
- AI Engine, DSP IP and Tools
- :
- Re: Verilog: How to implement a pipeline multiplie...

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

phytebunk

Observer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-15-2021 12:41 AM

332 Views

Registered:
03-26-2019

Verilog: How to implement a pipeline multiplier?

Hey,

I'd like to implement a 31 * 32-bit signed multiplier using Verilog. My platform is a Zynq 7010-based Red Pitaya. The multiplier should run at 125 MHz while samples that need to be multiplied arrive at 1 MHz. So there is a valid signal based detection to figure out when the next multiplication should start. Currently there are timing issues with the multiplication although I reduced the clock frequency to 100 MHz. (Worst path has 2.2 ns slack) The delay results mostly from the logic (>70%) where 4 ns are related to the DSP48E. There are three DSP48E in series within this path.

To solve this timing issue I want Vivado to use a pipelined multiplication. But it seems like Vivado doesn't understand the option of pipelining. AR#8657.html explains how to implement a pipelined multiplier in Verilog. Unfortunately my try to use this technique didn't lead to pipelining. (Made the timing even worse.)

I would be really glad about a hint how to get my pipelining work.

Thanks!

module phase_controller( input i_clk, input i_reset, input i_enable, input signed[64-1:0] i_phase, input i_phase_valid, input signed[32-1:0] i_gain_i, output reg o_is_armed, output [32-1:0] o_frequency, output reg o_frequency_valid ); reg signed[32-1:0] gain_i_buffer; reg signed [63-1:0] error_gain_product[16]; reg signed [33-1:0] frequency_sign_extended; //parameter signed [64-1:0] UPPER_PHASE_SATURATION = 64'sd1073741823; parameter signed [31-1:0] UPPER_PHASE_SATURATION = 31'sd1073741823; reg signed [33-1:0] freq_offset = 33'sd42949673; reg [3:0] prog_cntr; integer i; reg [4-1:0] counter = 4'd1; always @(posedge i_clk) begin if (i_reset) begin end else begin case(prog_cntr) 4'd0: begin if(i_enable) prog_cntr <= prog_cntr + 4'd1; end 4'd1: begin frequency_sign_extended <= freq_offset; o_is_armed <= 1'b1; gain_i_buffer <= i_gain_i; prog_cntr <= prog_cntr + 4'd1; end 4'd2: begin if(i_phase_valid) begin if(i_phase > UPPER_PHASE_SATURATION) begin error_gain_product[0] <= (-UPPER_PHASE_SATURATION * gain_i_buffer); end else if(i_phase < -UPPER_PHASE_SATURATION) begin error_gain_product[0] <= (UPPER_PHASE_SATURATION * gain_i_buffer); end else begin error_gain_product[0] <= (-{i_phase[64-1], i_phase[30-1:0]} * gain_i_buffer); end prog_cntr <= prog_cntr + 4'd1; end end 4'd3: begin if (counter == 4'd15) begin prog_cntr <= prog_cntr + 4'd1; counter <= 4'd1; end else begin counter <= counter + 4'd1; end for(i =1;i <16;i =i +1) <<<<<<============= PIPELINING ?? error_gain_product [i] <= error_gain_product [i-1]; end 4'd4: begin frequency_sign_extended <= freq_offset + (error_gain_product[15]>>> 40); o_frequency_valid <= 1'b1; prog_cntr <= prog_cntr + 4'd1; end 4'd5: begin o_frequency_valid <= 1'b0; gain_i_buffer <= i_gain_i; prog_cntr <= 4'd2; end endcase end end assign o_frequency = frequency_sign_extended[32-1:0]; endmodule

2 Replies

gopal_1921ee16

Participant

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-15-2021 02:25 AM

314 Views

Registered:
01-14-2020

I think you can use multiplier IP available in Vivado, instantiate in your design to make 32 bit multiplier.

Gopal_krishna

dgisselq

Scholar

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-15-2021 09:38 AM

271 Views

Registered:
05-21-2015

It can be a challenge to get Vivado to recognize the multiplier in your logic and do the right thing with it. I recommend, therefore, that multiplies be isolated from the logic around them so that multiplication blocks are no more complicated than:

```
always @(posedge clk)
if (condition)
mpy_result <= a * b;
```

Were I to try pipelining this, I'd recommend something instead like:

```
always @(posedge clk)
if (condition)
mpy_pipe <= a * b;
always @(posedge clk)
mpy_result <= mpy_pipe;
```

I'm not sure how complex Vivado's optimizer is in order to recognize things, but these should at least be recognizable.

Dan