resources needed on how to build a synthesizable pipeline in verilog - Page 1
Forum section: electronics / general

author: Dmeads
author_rank: Regular Contributor
timestamp: January 06, 2020, 05:44:57 am
content: I have spent the night doing some research, and I cant find a lot on synthesizable pipelines.Im not trying to make anything complex, jut trying to put together some combo logic with registers in between like a pipeline uses.Problem is, the verilog example code and videos I am finding use things like #2 to model a 2ns delay between stages and things like that. See last module in this link:https://www.edaplayground.com/x/6LXJI get the concept, but i dont think code like this can be synthesized.Anyone know of any good papers or books or example code that can show how to code a simple synthesizable pipeline of any kind (adder, multiplier, etc..)I would like to be able to acutally put my pipeline on my FPGA board rather than just simulate it.thanks.

author: hamster_nz
author_rank: Super Contributor
timestamp: January 06, 2020, 06:11:14 am
content: The key concept you might be missing is what a clock signal is.I am pretty sure no synthizable code will have a "# (however many ns' in it.

author: Dmeads
author_rank: Regular Contributor
timestamp: January 06, 2020, 06:21:15 am
content: Yes i know that no synthesizable code will have a # in it, (learned that the hard way haha) which is why i am having trouble. Im trying to write some code to acutally put on my fpga, but the pipeline examples I have found have this # in them.

author: hamster_nz
author_rank: Super Contributor
timestamp: January 06, 2020, 06:42:56 am
content: Here's an example of a pipelined complex multiplier:Code:module cmult # (parameter AWIDTH = 16, BWIDTH = 18)(input clk,input signed [AWIDTH-1:0] ar, ai,input signed [BWIDTH-1:0] br, bi,output signed [AWIDTH+BWIDTH:0] pr, pi);reg signed [AWIDTH-1:0] ai_d, ai_dd, ai_ddd, ai_dddd ;reg signed [AWIDTH-1:0] ar_d, ar_dd, ar_ddd, ar_dddd ;reg signed [BWIDTH-1:0] bi_d, bi_dd, bi_ddd, br_d, br_dd, br_ddd ;reg signed [AWIDTH:0] addcommon ;reg signed [BWIDTH:0] addr, addi ;reg signed [AWIDTH+BWIDTH:0] mult0, multr, multi, pr_int, pi_int ;reg signed [AWIDTH+BWIDTH:0] common, commonr1, commonr2 ;always @(posedge clk)beginar_d <= ar;ar_dd <= ar_d;ai_d <= ai;ai_dd <= ai_d;br_d <= br;br_dd <= br_d;br_ddd <= br_dd;bi_d <= bi;bi_dd <= bi_d;bi_ddd <= bi_dd;end// Common factor (ar ai) x bi, shared for the calculations of the real and imaginaryfinal products//always @(posedge clk)beginaddcommon <= ar_d - ai_d;mult0 <= addcommon * bi_dd;common <= mult0;end// Real product//always @(posedge clk)beginar_ddd <= ar_dd;ar_dddd <= ar_ddd;addr <= br_ddd - bi_ddd;multr <= addr * ar_dddd;commonr1 <= common;pr_int <= multr + commonr1;end// Imaginary product//always @(posedge clk)beginai_ddd <= ai_dd;ai_dddd <= ai_ddd;addi <= br_ddd + bi_ddd;multi <= addi * ai_dddd;commonr2 <= common;pi_int <= multi + commonr2;endassign pr = pr_int;assign pi = pi_int;endmodule // cmultFrom page 86-87 ofhttps://www.xilinx.com/support/documentation/sw_manuals/xilinx2017_1/ug901-vivado-synthesis.pdf

author: Dmeads
author_rank: Regular Contributor
timestamp: January 06, 2020, 06:47:20 am
content: thanks a bunch!I can totally work with thatalso I just found this article :https://drive.google.com/file/d/1YEHioiFETJDe6KvkG1CX2-houGAPt7NM/viewwhat do you think of section 8 where it describes pipelining?Is this still good practice? (it is an old paper)

author: hamster_nz
author_rank: Super Contributor
timestamp: January 06, 2020, 06:56:42 am
content: Quote from: Dmeads on January 06, 2020, 06:47:20 amHeading into style-wars territory. If you follow one style dogmatically one day somebody will use a different style and confuse the heck out of you. IMO better off experimenting with different styles and see what works for you rather than following dogma.It is mixing styles that kills you. (e.g. Using blocking and nonblocking assignments in the same process).

author: NorthGuy
author_rank: Super Contributor
timestamp: January 06, 2020, 11:32:24 pm
content: Quote from: Dmeads on January 06, 2020, 06:47:20 amI think it describes a shift register, not a pipeline. I don't think think the text is interesting. Not because it's old, but because the author is talking about insignificant things and lacks the substance.Shift register is not really a pipeline. You certainly can look at the shift register as a rudimentary pipeline which has no logic. However, this is unlikely to help to understand what the pipelining is.Pipelineing is where you have some sort of combinatorial logic, and you split it in stages by inserting registers. The registers split your logic into stages. Each stage executes in parallel. Since each stage contains less logic than the whole thing, this lets you increase clock speed and thereby increase the throughput. However, each stage takes a full clock cycle to execute. Thus you'll need several clock cycles to get the result, which increases latency.For example, if you haveCode:x <= a + b + c + d;you can make it into a pipeline by inserting two intermediary registersCode:x <= a_plus_b + c_plus_d;a_plus_b <= a + b;c_plus_d <= c + d;This produces 2 stages. At the first stage, a_plus_b and b_plus_c are calculated. On the second stage they're used to calculate x.Or you can do it this way:Code:x <= a_plus_b_plus_c + d_plus;a_plus_b_plus_c <= a + b + c;d_plus <= d;Which creates an unbalanced pipeline - first stage takes longer than the second one. This diminishes the benefits of pipelining.But you cannot do it this way:Code:x <= a_plus_b_plus_c + d;a_plus_b_plus_c <= a + b + c;which will mess up totally everything. If you can explain why, you understand how the pipelines work.Edit: Discaimer: All the code above should be located inside a clocked processCode:always @(posedge clk) ...